@lf_maple/koishi-plugin-phi-plugin-full 0.1.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. package/LICENSE +22 -0
  2. package/core/.github/ISSUE_TEMPLATE/bug.yaml +133 -0
  3. package/core/.github/ISSUE_TEMPLATE/config.yml +1 -0
  4. package/core/.github/ISSUE_TEMPLATE/enhancement.yml +44 -0
  5. package/core/.vscode/c_cpp_properties.json +18 -0
  6. package/core/.vscode/launch.json +24 -0
  7. package/core/.vscode/settings.json +59 -0
  8. package/core/CHANGELOG.md +184 -0
  9. package/core/LICENSE +674 -0
  10. package/core/README.md +330 -0
  11. package/core/README_en.md +285 -0
  12. package/core/apps/Dan.js +129 -0
  13. package/core/apps/RankList.js +322 -0
  14. package/core/apps/aliasProposal.js +223 -0
  15. package/core/apps/apiSetting.js +592 -0
  16. package/core/apps/b19.js +1329 -0
  17. package/core/apps/botClient.js +64 -0
  18. package/core/apps/chart.js +692 -0
  19. package/core/apps/guessGame/guessIll.js +821 -0
  20. package/core/apps/guessGame/guessLetter.js +831 -0
  21. package/core/apps/guessGame/guessTips.js +254 -0
  22. package/core/apps/guessGame/letterGameUtils.js +74 -0
  23. package/core/apps/guessGame.js +214 -0
  24. package/core/apps/help.js +117 -0
  25. package/core/apps/manage.js +288 -0
  26. package/core/apps/market.js +243 -0
  27. package/core/apps/money.js +1064 -0
  28. package/core/apps/phisong.js +1418 -0
  29. package/core/apps/session.js +664 -0
  30. package/core/apps/setting.js +468 -0
  31. package/core/apps/update.js +541 -0
  32. package/core/apps/user.js +968 -0
  33. package/core/components/Config.js +249 -0
  34. package/core/components/Data.js +304 -0
  35. package/core/components/FileWatcherRegistry.js +102 -0
  36. package/core/components/Logger.js +11 -0
  37. package/core/components/ProcessCleanup.js +113 -0
  38. package/core/components/Version.js +56 -0
  39. package/core/components/YamlReader.js +157 -0
  40. package/core/components/baseClass.js +287 -0
  41. package/core/components/common.js +47 -0
  42. package/core/components/index.js +13 -0
  43. package/core/components/platform/index.js +79 -0
  44. package/core/components/platform/koishi.js +800 -0
  45. package/core/components/platform/koishiDatabaseRedis.js +391 -0
  46. package/core/components/platform/memoryRedis.js +209 -0
  47. package/core/components/platform/types.d.ts +272 -0
  48. package/core/components/platform/yunzai.js +604 -0
  49. package/core/components/segment.js +4 -0
  50. package/core/config/config//350/277/231/351/207/214/346/230/257/351/205/215/347/275/256/346/226/207/344/273/266/347/233/256/345/275/225.txt +0 -0
  51. package/core/config/default_config/banGroup.yaml +14 -0
  52. package/core/config/default_config/config.yaml +159 -0
  53. package/core/config/default_config/nickconfig.yaml +6 -0
  54. package/core/config/default_config/otherinfo.yaml +51 -0
  55. package/core/guoba.support.js +597 -0
  56. package/core/index.js +85 -0
  57. package/core/lib/AES.js +40 -0
  58. package/core/lib/Base64.js +22 -0
  59. package/core/lib/ByteReader.js +168 -0
  60. package/core/lib/GameProgress.js +37 -0
  61. package/core/lib/GameRecord.js +47 -0
  62. package/core/lib/GameSettings.js +24 -0
  63. package/core/lib/GameUser.js +19 -0
  64. package/core/lib/Level.js +6 -0
  65. package/core/lib/LevelRecord.js +9 -0
  66. package/core/lib/PhigrosUser.js +135 -0
  67. package/core/lib/SaveManager.js +117 -0
  68. package/core/lib/Summary.js +47 -0
  69. package/core/lib/TapTap/CompleteQRCodeData.js +27 -0
  70. package/core/lib/TapTap/LCHelper.js +81 -0
  71. package/core/lib/TapTap/TapTapHelper.js +170 -0
  72. package/core/lib/TapTap/getQRcode.js +61 -0
  73. package/core/lib/Util.js +30 -0
  74. package/core/lib/getQRcode.js +73 -0
  75. package/core/lib/http.js +105 -0
  76. package/core/model/README.md +3 -0
  77. package/core/model/api/aliasProposalService.js +151 -0
  78. package/core/model/api/apiVersion.js +67 -0
  79. package/core/model/api/autoSeekApi.js +165 -0
  80. package/core/model/api/botApiAuth.js +208 -0
  81. package/core/model/api/botSyncService.js +78 -0
  82. package/core/model/api/gameRecordPayload.js +24 -0
  83. package/core/model/api/makeRequest.js +1004 -0
  84. package/core/model/api/makeRequestFnc.js +17 -0
  85. package/core/model/api/phiApiClient.js +53 -0
  86. package/core/model/api/phiApiErrors.js +121 -0
  87. package/core/model/filesystem/getFile.js +256 -0
  88. package/core/model/filesystem/path.js +84 -0
  89. package/core/model/game/Chart.js +57 -0
  90. package/core/model/game/LevelRecordInfo.js +109 -0
  91. package/core/model/game/SongsInfo.js +46 -0
  92. package/core/model/game/b30Analysis.js +93 -0
  93. package/core/model/game/chartParser/Chart.js +23 -0
  94. package/core/model/game/chartParser/JudgeLine.js +38 -0
  95. package/core/model/game/chartParser/base/JudgeLineEvent.js +99 -0
  96. package/core/model/game/chartParser/base/Note.js +44 -0
  97. package/core/model/game/chartParser/base/SpeedEvent.js +25 -0
  98. package/core/model/game/chartParser/base/baseType.js +2 -0
  99. package/core/model/game/constNum.js +215 -0
  100. package/core/model/game/fCompute.js +711 -0
  101. package/core/model/game/getChartTag.js +140 -0
  102. package/core/model/game/getComment.js +132 -0
  103. package/core/model/game/getInfo.js +1069 -0
  104. package/core/model/game/getRksRank.js +77 -0
  105. package/core/model/game/markdown.js +77 -0
  106. package/core/model/integrations/Vika.js +103 -0
  107. package/core/model/integrations/getInfoFromTap.js +80 -0
  108. package/core/model/render/getPic.js +79 -0
  109. package/core/model/render/picmodle.js +496 -0
  110. package/core/model/render/progress-bar.js +44 -0
  111. package/core/model/render/puppeteer.js +431 -0
  112. package/core/model/render/renderPressureHistory.js +71 -0
  113. package/core/model/render/send.js +94 -0
  114. package/core/model/save/Save.js +953 -0
  115. package/core/model/save/analyzeSaveHistory.js +413 -0
  116. package/core/model/save/getBackup.js +328 -0
  117. package/core/model/save/getSave.js +90 -0
  118. package/core/model/save/getSaveFromApi.js +46 -0
  119. package/core/model/save/saveHistory.js +586 -0
  120. package/core/model/save/scoreHistory.js +101 -0
  121. package/core/model/theme/catalog.js +192 -0
  122. package/core/model/theme/installGuard.js +275 -0
  123. package/core/model/theme/installLock.js +174 -0
  124. package/core/model/theme/installer.js +398 -0
  125. package/core/model/theme/manager.js +408 -0
  126. package/core/model/theme/marketClient.js +294 -0
  127. package/core/model/theme/paths.js +42 -0
  128. package/core/model/theme/policy.js +54 -0
  129. package/core/model/theme/recovery.js +167 -0
  130. package/core/model/theme/useService.js +187 -0
  131. package/core/model/type/aliasProposal.d.ts +45 -0
  132. package/core/model/type/type.js +420 -0
  133. package/core/model/user/apiPermission.js +62 -0
  134. package/core/model/user/getBanGroup.js +120 -0
  135. package/core/model/user/getNotes.js +48 -0
  136. package/core/model/user/pluginData.js +101 -0
  137. package/core/model/user/userCredentialStore.js +154 -0
  138. package/core/model/user/userCredentials.js +860 -0
  139. package/core/package.json +60 -0
  140. package/core/resources/0608badSave/save.json +1 -0
  141. package/core/resources/LICENSE +201 -0
  142. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.art +220 -0
  143. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.css +345 -0
  144. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.html +434 -0
  145. package/core/resources/html/arcgrosB19/arcgros.png +0 -0
  146. package/core/resources/html/arcgrosB19/arcgrosB19-orz.html +276 -0
  147. package/core/resources/html/arcgrosB19/arcgrosB19.art +168 -0
  148. package/core/resources/html/arcgrosB19/arcgrosB19.css +637 -0
  149. package/core/resources/html/atlas/atlas-orz.html +313 -0
  150. package/core/resources/html/atlas/atlas.art +194 -0
  151. package/core/resources/html/atlas/atlas.css +695 -0
  152. package/core/resources/html/avatar/-SURREALISM-.png +0 -0
  153. package/core/resources/html/avatar/Alkaid.png +0 -0
  154. package/core/resources/html/avatar/Aphasia.png +0 -0
  155. package/core/resources/html/avatar/Artificial Existence.png +0 -0
  156. package/core/resources/html/avatar/Bonus Time.png +0 -0
  157. package/core/resources/html/avatar/Burn.png +0 -0
  158. package/core/resources/html/avatar/Cereris1.png +0 -0
  159. package/core/resources/html/avatar/Cereris2.png +0 -0
  160. package/core/resources/html/avatar/Cereris3.png +0 -0
  161. package/core/resources/html/avatar/Christmas -2019.png +0 -0
  162. package/core/resources/html/avatar/Cipher1.png +0 -0
  163. package/core/resources/html/avatar/Class Memories.png +0 -0
  164. package/core/resources/html/avatar/Credits.png +0 -0
  165. package/core/resources/html/avatar/Dash.png +0 -0
  166. package/core/resources/html/avatar/Dlyrotz.png +0 -0
  167. package/core/resources/html/avatar/Doppelganger1.png +0 -0
  168. package/core/resources/html/avatar/Doppelganger2.png +0 -0
  169. package/core/resources/html/avatar/Drop it.png +0 -0
  170. package/core/resources/html/avatar/Energy Synergy Matrix1.png +0 -0
  171. package/core/resources/html/avatar/Energy Synergy Matrix2.png +0 -0
  172. package/core/resources/html/avatar/Energy Synergy Matrix3.png +0 -0
  173. package/core/resources/html/avatar/Engine x Start!! (melody mix).png +0 -0
  174. package/core/resources/html/avatar/Engine x Start!! extra 1 -by cycats.png +0 -0
  175. package/core/resources/html/avatar/Eradication Catastrophe.png +0 -0
  176. package/core/resources/html/avatar/FULi AUTO SHOOTER extra 1 -by cycats.png +0 -0
  177. package/core/resources/html/avatar/FULi AUTO SHOOTER.png +0 -0
  178. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/264-Special1.png +0 -0
  179. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/264-Special2.png +0 -0
  180. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2641.png +0 -0
  181. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2642.png +0 -0
  182. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2643.png +0 -0
  183. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2644.png +0 -0
  184. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2645.png +0 -0
  185. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2646.png +0 -0
  186. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2647.png +0 -0
  187. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2648.png +0 -0
  188. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2649.png +0 -0
  189. package/core/resources/html/avatar/Find_Me.png +0 -0
  190. package/core/resources/html/avatar/Geopelia 1 -by cycats.png +0 -0
  191. package/core/resources/html/avatar/Geopelia 2 -by cycats.png +0 -0
  192. package/core/resources/html/avatar/Geopelia 3 -by /344/275/225/345/221/265.png +0 -0
  193. package/core/resources/html/avatar/Geopelia in WEPLAY -by /346/265/267/344/272/247.png +0 -0
  194. package/core/resources/html/avatar/Gino-AprilFool.png +0 -0
  195. package/core/resources/html/avatar/Glaciaxion.png +0 -0
  196. package/core/resources/html/avatar/HumaN.png +0 -0
  197. package/core/resources/html/avatar/Indelible Scar.png +0 -0
  198. package/core/resources/html/avatar/Introduction.png +0 -0
  199. package/core/resources/html/avatar/Khronostasis Katharsis.png +0 -0
  200. package/core/resources/html/avatar/MARENOL.png +0 -0
  201. package/core/resources/html/avatar/Marenol extra 1 -by /345/226/265n/350/221/265.png +0 -0
  202. package/core/resources/html/avatar/Non-Melodic Ragez (MUG Edit).png +0 -0
  203. package/core/resources/html/avatar/Non-Melodic Ragez extra 1 -by cycats.png +0 -0
  204. package/core/resources/html/avatar/Oblivion +0 -0
  205. package/core/resources/html/avatar/OblivionPHIN.png +0 -0
  206. package/core/resources/html/avatar/Para.png +0 -0
  207. package/core/resources/html/avatar/Pixel Rebelz1.png +0 -0
  208. package/core/resources/html/avatar/Pixel Rebelz2.png +0 -0
  209. package/core/resources/html/avatar/Pixel Rebelz3.png +0 -0
  210. package/core/resources/html/avatar/RIPPER extra 1 -by cycats.png +0 -0
  211. package/core/resources/html/avatar/RIPPER extra 2 -by /344/275/225/345/221/265.png +0 -0
  212. package/core/resources/html/avatar/Sein.png +0 -0
  213. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-Special.png +0 -0
  214. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-Special2.png +0 -0
  215. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-/346/231/256/351/200/232.png +0 -0
  216. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-/346/233/262/347/273/230Ver.png +0 -0
  217. package/core/resources/html/avatar/ShineAfter-/351/270/240-Special.png +0 -0
  218. package/core/resources/html/avatar/ShineAfter-/351/270/240-/346/231/256/351/200/232.png +0 -0
  219. package/core/resources/html/avatar/ShineAfter-/351/270/240-/346/233/262/347/273/230Ver.png +0 -0
  220. package/core/resources/html/avatar/ShineAfter-/351/270/240/345/222/214/346/260/264/351/235/222-Special.png +0 -0
  221. package/core/resources/html/avatar/Snow Desert.png +0 -0
  222. package/core/resources/html/avatar/Sparkle New Life.png +0 -0
  223. package/core/resources/html/avatar/Sultan Rage.png +0 -0
  224. package/core/resources/html/avatar/Winter /342/206/221cube/342/206/223.png +0 -0
  225. package/core/resources/html/avatar/Xenolith.png +0 -0
  226. package/core/resources/html/avatar/[PRAW].png +0 -0
  227. package/core/resources/html/avatar/dB doll.png +0 -0
  228. package/core/resources/html/avatar/ripper.png +0 -0
  229. package/core/resources/html/avatar//343/202/202/343/201/272/343/202/202/343/201/2721.png +0 -0
  230. package/core/resources/html/avatar//343/202/202/343/201/272/343/202/202/343/201/2722.png +0 -0
  231. package/core/resources/html/avatar//344/270/207/345/220/250/345/214/277/345/220/215/344/277/241.png +0 -0
  232. package/core/resources/html/avatar//344/272/221/345/245/263/345/255/251 extra 1 -by /345/276/241/345/235/202/346/236/234/345/255/220.png +0 -0
  233. package/core/resources/html/avatar//344/272/221/345/245/263/345/255/251.png +0 -0
  234. package/core/resources/html/avatar//345/205/211.png +0 -0
  235. package/core/resources/html/avatar//345/274/200/345/277/203/347/227/2051.png +0 -0
  236. package/core/resources/html/avatar//345/274/200/345/277/203/347/227/2052.png +0 -0
  237. package/core/resources/html/avatar//346/260/264/351/235/222-/344/270/200/345/221/250/345/271/264/347/233/270/350/201/232.png +0 -0
  238. package/core/resources/html/avatar//346/267/267/344/271/261-Confusion.png +0 -0
  239. package/core/resources/html/avatar//347/213/202/345/226/234/350/230/255/350/210/2361.png +0 -0
  240. package/core/resources/html/avatar//347/213/202/345/226/234/350/230/255/350/210/2362.png +0 -0
  241. package/core/resources/html/avatar//347/223/267/345/262/201-Special.png +0 -0
  242. package/core/resources/html/avatar//347/223/267/345/262/2011.png +0 -0
  243. package/core/resources/html/avatar//347/223/267/345/262/2012.png +0 -0
  244. package/core/resources/html/avatar//347/223/267/345/262/2013.png +0 -0
  245. package/core/resources/html/avatar//347/223/267/345/262/2014.png +0 -0
  246. package/core/resources/html/avatar//347/223/267/345/262/2015.png +0 -0
  247. package/core/resources/html/avatar//347/223/267/345/262/2016.png +0 -0
  248. package/core/resources/html/avatar//347/223/267/345/262/2017.png +0 -0
  249. package/core/resources/html/avatar//347/233/217/350/214/227-Special.png +0 -0
  250. package/core/resources/html/avatar//347/233/217/350/214/2271.png +0 -0
  251. package/core/resources/html/avatar//347/233/217/350/214/2272.png +0 -0
  252. package/core/resources/html/avatar//347/233/217/350/214/2273.png +0 -0
  253. package/core/resources/html/avatar//350/217/257/347/201/257/347/210/2611.png +0 -0
  254. package/core/resources/html/avatar//350/217/257/347/201/257/347/210/2612.png +0 -0
  255. package/core/resources/html/avatar//350/220/244/347/201/253/350/231/253/343/201/256/346/200/2501.png +0 -0
  256. package/core/resources/html/avatar//350/220/244/347/201/253/350/231/253/343/201/256/346/200/2502.png +0 -0
  257. package/core/resources/html/avatar//351/235/222/350/212/275-Special.png +0 -0
  258. package/core/resources/html/avatar//351/235/222/350/212/275.png +0 -0
  259. package/core/resources/html/avatar//351/243/216/345/261/277.png +0 -0
  260. package/core/resources/html/avatar//351/270/240-AprilFool.png +0 -0
  261. package/core/resources/html/avatar//351/270/240-/344/270/200/345/221/250/345/271/264/347/233/270/350/201/232.png +0 -0
  262. package/core/resources/html/b19/b19.art +490 -0
  263. package/core/resources/html/b19/b19.css +1261 -0
  264. package/core/resources/html/b19/b19666.art +350 -0
  265. package/core/resources/html/b19/b19666.css +1409 -0
  266. package/core/resources/html/b19/b19666.html +481 -0
  267. package/core/resources/html/b19/b19title.css +120 -0
  268. package/core/resources/html/b19/best19.html +853 -0
  269. package/core/resources/html/b19/dss2-orz.html +428 -0
  270. package/core/resources/html/b19/dss2.art +298 -0
  271. package/core/resources/html/b19/dss2.css +776 -0
  272. package/core/resources/html/b19/res/666.jpeg +0 -0
  273. package/core/resources/html/chap/chap-orz.html +93 -0
  274. package/core/resources/html/chap/chap.art +87 -0
  275. package/core/resources/html/chap/chap.css +365 -0
  276. package/core/resources/html/chartImg/chartImg.art +169 -0
  277. package/core/resources/html/chartImg/chartImg.css +439 -0
  278. package/core/resources/html/chartImg/echarts-wordcloud.min.js +3 -0
  279. package/core/resources/html/chartImg/echarts.js +85796 -0
  280. package/core/resources/html/chartImg/img/Drag.png +0 -0
  281. package/core/resources/html/chartImg/img/DragHL.png +0 -0
  282. package/core/resources/html/chartImg/img/Flick.png +0 -0
  283. package/core/resources/html/chartImg/img/FlickHL.png +0 -0
  284. package/core/resources/html/chartImg/img/Hold.png +0 -0
  285. package/core/resources/html/chartImg/img/HoldHL.png +0 -0
  286. package/core/resources/html/chartImg/img/Hold_End.png +0 -0
  287. package/core/resources/html/chartImg/img/Hold_Head.png +0 -0
  288. package/core/resources/html/chartImg/img/Hold_HeadHL.png +0 -0
  289. package/core/resources/html/chartImg/img/Tap.png +0 -0
  290. package/core/resources/html/chartImg/img/TapHL.png +0 -0
  291. package/core/resources/html/chartInfo/chartInfo-orz.html +250 -0
  292. package/core/resources/html/chartInfo/chartInfo.art +222 -0
  293. package/core/resources/html/chartInfo/chartInfo.css +265 -0
  294. package/core/resources/html/chartInfo/echarts-wordcloud.min.js +3 -0
  295. package/core/resources/html/chartInfo/echarts.js +85796 -0
  296. package/core/resources/html/clg/clg-orz.html +218 -0
  297. package/core/resources/html/clg/clg.art +88 -0
  298. package/core/resources/html/clg/clg.css +230 -0
  299. package/core/resources/html/clg/demo.jpg +0 -0
  300. package/core/resources/html/common/common.css +319 -0
  301. package/core/resources/html/common/css/playerInfo.css +136 -0
  302. package/core/resources/html/common/font/Aldrich-Regular.ttf +0 -0
  303. package/core/resources/html/common/font/HIMALAYA.TTF +0 -0
  304. package/core/resources/html/common/font/NotoColorEmoji-Regular.ttf +0 -0
  305. package/core/resources/html/common/font/NotoSans-Regular.ttf +0 -0
  306. package/core/resources/html/common/font/NotoSansArabic.ttf +0 -0
  307. package/core/resources/html/common/font/NotoSansCanadianAboriginal.ttf +0 -0
  308. package/core/resources/html/common/font/NotoSansJP.ttf +0 -0
  309. package/core/resources/html/common/font/NotoSansKannada.ttf +0 -0
  310. package/core/resources/html/common/font/NotoSansMath-Regular.ttf +0 -0
  311. package/core/resources/html/common/font/NotoSansSymbols2.ttf +0 -0
  312. package/core/resources/html/common/font/phi.ttf +0 -0
  313. package/core/resources/html/common/font//345/220/236/345/274/245/346/201/260/344/277/212.ttf +0 -0
  314. package/core/resources/html/common/layout/default.art +324 -0
  315. package/core/resources/html/common/layout/elem.art +21 -0
  316. package/core/resources/html/common/theme/snow/snow.css +17 -0
  317. package/core/resources/html/common/theme/snow/snow.js +19 -0
  318. package/core/resources/html/common/theme/star/star.js +201 -0
  319. package/core/resources/html/common/theme/topText/topText.css +15 -0
  320. package/core/resources/html/common/theme/topText/topText.js +30 -0
  321. package/core/resources/html/difficultyHistory/difficultyHistory-orz.html +361 -0
  322. package/core/resources/html/difficultyHistory/difficultyHistory.art +102 -0
  323. package/core/resources/html/difficultyHistory/difficultyHistory.css +205 -0
  324. package/core/resources/html/guess/guess-orz.html +50 -0
  325. package/core/resources/html/guess/guess.art +51 -0
  326. package/core/resources/html/guess/guess.css +33 -0
  327. package/core/resources/html/help/help-orz.html +73 -0
  328. package/core/resources/html/help/help.art +84 -0
  329. package/core/resources/html/help/help.css +266 -0
  330. package/core/resources/html/historyB30/historyB30-orz.html +168 -0
  331. package/core/resources/html/historyB30/historyB30.art +143 -0
  332. package/core/resources/html/historyB30/historyB30.css +270 -0
  333. package/core/resources/html/ill/ill-orz.html +21 -0
  334. package/core/resources/html/ill/ill.art +23 -0
  335. package/core/resources/html/ill/ill.css +79 -0
  336. package/core/resources/html/jrrp/ShineAfter.removebg.png +0 -0
  337. package/core/resources/html/jrrp/jrrp-orz.html +68 -0
  338. package/core/resources/html/jrrp/jrrp.art +58 -0
  339. package/core/resources/html/jrrp/jrrp.css +251 -0
  340. package/core/resources/html/list/list-orz.html +35 -0
  341. package/core/resources/html/list/list.art +67 -0
  342. package/core/resources/html/list/list.css +259 -0
  343. package/core/resources/html/lvsco/demo.jpg +0 -0
  344. package/core/resources/html/lvsco/lvsco-orz.html +334 -0
  345. package/core/resources/html/lvsco/lvsco.art +314 -0
  346. package/core/resources/html/lvsco/lvsco.css +706 -0
  347. package/core/resources/html/market/detail.art +44 -0
  348. package/core/resources/html/market/market.art +86 -0
  349. package/core/resources/html/market/market.css +64 -0
  350. package/core/resources/html/newSong/newSong.art +34 -0
  351. package/core/resources/html/newSong/newSong.css +48 -0
  352. package/core/resources/html/newSong/newSong.html +23 -0
  353. package/core/resources/html/newnotice/newnotice.art +47 -0
  354. package/core/resources/html/newnotice/newnotice.css +83 -0
  355. package/core/resources/html/otherimg/0.png +0 -0
  356. package/core/resources/html/otherimg/1.png +0 -0
  357. package/core/resources/html/otherimg/2.png +0 -0
  358. package/core/resources/html/otherimg/3.png +0 -0
  359. package/core/resources/html/otherimg/4.png +0 -0
  360. package/core/resources/html/otherimg/5.png +0 -0
  361. package/core/resources/html/otherimg/A.png +0 -0
  362. package/core/resources/html/otherimg/B.png +0 -0
  363. package/core/resources/html/otherimg/C.png +0 -0
  364. package/core/resources/html/otherimg/F.png +0 -0
  365. package/core/resources/html/otherimg/FC.png +0 -0
  366. package/core/resources/html/otherimg/NEW.png +0 -0
  367. package/core/resources/html/otherimg/Phigros_Icon_3.0.0.png +0 -0
  368. package/core/resources/html/otherimg/S.png +0 -0
  369. package/core/resources/html/otherimg/Star1.png +0 -0
  370. package/core/resources/html/otherimg/Star2.png +0 -0
  371. package/core/resources/html/otherimg/V.png +0 -0
  372. package/core/resources/html/otherimg/callback.png +0 -0
  373. package/core/resources/html/otherimg/chapHelp.png +0 -0
  374. package/core/resources/html/otherimg/dan_code.png +0 -0
  375. package/core/resources/html/otherimg/data.png +0 -0
  376. package/core/resources/html/otherimg/helpDoc.png +0 -0
  377. package/core/resources/html/otherimg/nickSuggest.png +0 -0
  378. package/core/resources/html/otherimg/phi.png +0 -0
  379. package/core/resources/html/otherimg/phigros.png +0 -0
  380. package/core/resources/html/otherimg/snow1.png +0 -0
  381. package/core/resources/html/otherimg/snow2.png +0 -0
  382. package/core/resources/html/otherimg/snow3.png +0 -0
  383. package/core/resources/html/otherimg/snow4.png +0 -0
  384. package/core/resources/html/otherimg/title.png +0 -0
  385. package/core/resources/html/rand/rand-orz.html +62 -0
  386. package/core/resources/html/rand/rand.art +59 -0
  387. package/core/resources/html/rand/rand.css +257 -0
  388. package/core/resources/html/rankingList/rankingList-orz.html +456 -0
  389. package/core/resources/html/rankingList/rankingList.art +171 -0
  390. package/core/resources/html/rankingList/rankingList.css +570 -0
  391. package/core/resources/html/rankingList-old/rankingList-orz.html +300 -0
  392. package/core/resources/html/rankingList-old/rankingList.art +89 -0
  393. package/core/resources/html/rankingList-old/rankingList.css +265 -0
  394. package/core/resources/html/score/score-orz.html +625 -0
  395. package/core/resources/html/score/score.art +249 -0
  396. package/core/resources/html/score/score.css +435 -0
  397. package/core/resources/html/score/scoreOld-orz.html +128 -0
  398. package/core/resources/html/score/scoreOld.art +230 -0
  399. package/core/resources/html/score/scoreOld.css +475 -0
  400. package/core/resources/html/score/scoreRankList-orz.html +613 -0
  401. package/core/resources/html/score/scoreRankList.art +231 -0
  402. package/core/resources/html/score/scoreRankList.css +197 -0
  403. package/core/resources/html/setting/setting-orz.html +123 -0
  404. package/core/resources/html/setting/setting.art +72 -0
  405. package/core/resources/html/setting/setting.css +170 -0
  406. package/core/resources/html/setting/userSetting-orz.html +132 -0
  407. package/core/resources/html/setting/userSetting.art +48 -0
  408. package/core/resources/html/setting/userSetting.css +160 -0
  409. package/core/resources/html/sign/sign-orz.html +262 -0
  410. package/core/resources/html/sign/sign.art +163 -0
  411. package/core/resources/html/sign/sign.css +706 -0
  412. package/core/resources/html/suggest/suggest.art +271 -0
  413. package/core/resources/html/suggest/suggest.css +300 -0
  414. package/core/resources/html/table/table-orz.html +228 -0
  415. package/core/resources/html/table/table.art +163 -0
  416. package/core/resources/html/table/table.css +401 -0
  417. package/core/resources/html/tasks/tasks-orz.html +83 -0
  418. package/core/resources/html/tasks/tasks.art +118 -0
  419. package/core/resources/html/tasks/tasks.css +334 -0
  420. package/core/resources/html/update/update-orz.html +735 -0
  421. package/core/resources/html/update/update.art +259 -0
  422. package/core/resources/html/update/update.css +676 -0
  423. package/core/resources/html/userinfo/userinfo-old-orz.html +408 -0
  424. package/core/resources/html/userinfo/userinfo-old.art +233 -0
  425. package/core/resources/html/userinfo/userinfo-old.css +466 -0
  426. package/core/resources/html/userinfo/userinfo-orz.html +543 -0
  427. package/core/resources/html/userinfo/userinfo.art +288 -0
  428. package/core/resources/html/userinfo/userinfo.css +757 -0
  429. package/core/resources/info/DLC/arc.json +412 -0
  430. package/core/resources/info/DLC/chunithm.json +1172 -0
  431. package/core/resources/info/DLC/dynamix.json +455 -0
  432. package/core/resources/info/DLC/fanshi.json +132 -0
  433. package/core/resources/info/DLC/lanota.json +412 -0
  434. package/core/resources/info/DLC/maimai.json +1110 -0
  435. package/core/resources/info/DLC/orz.json +158 -0
  436. package/core/resources/info/DLC/rizline.json +40 -0
  437. package/core/resources/info/DLC/rotaeno.json +159 -0
  438. package/core/resources/info/DLC/ryceam.json +53 -0
  439. package/core/resources/info/avatar.txt +109 -0
  440. package/core/resources/info/chaplist.yaml +102 -0
  441. package/core/resources/info/help/api.json +83 -0
  442. package/core/resources/info/help.json +436 -0
  443. package/core/resources/info/info.csv +315 -0
  444. package/core/resources/info/infolist.json +1758 -0
  445. package/core/resources/info/jrrp.json +92 -0
  446. package/core/resources/info/nicklist.yaml +2373 -0
  447. package/core/resources/info/notesInfo.json +1 -0
  448. package/core/resources/info/notice.json +11 -0
  449. package/core/resources/info/oldInfo/100/change.csv +218 -0
  450. package/core/resources/info/oldInfo/100/info.json +7 -0
  451. package/core/resources/info/oldInfo/101/change.csv +218 -0
  452. package/core/resources/info/oldInfo/101/info.json +7 -0
  453. package/core/resources/info/oldInfo/102/change.csv +223 -0
  454. package/core/resources/info/oldInfo/102/info.json +7 -0
  455. package/core/resources/info/oldInfo/103/change.csv +224 -0
  456. package/core/resources/info/oldInfo/103/info.json +7 -0
  457. package/core/resources/info/oldInfo/104/change.csv +225 -0
  458. package/core/resources/info/oldInfo/104/info.json +7 -0
  459. package/core/resources/info/oldInfo/105/change.csv +228 -0
  460. package/core/resources/info/oldInfo/105/info.json +7 -0
  461. package/core/resources/info/oldInfo/106/change.csv +229 -0
  462. package/core/resources/info/oldInfo/106/info.json +7 -0
  463. package/core/resources/info/oldInfo/108/change.csv +233 -0
  464. package/core/resources/info/oldInfo/108/info.json +7 -0
  465. package/core/resources/info/oldInfo/109/change.csv +235 -0
  466. package/core/resources/info/oldInfo/109/info.json +7 -0
  467. package/core/resources/info/oldInfo/110/change.csv +235 -0
  468. package/core/resources/info/oldInfo/110/info.json +7 -0
  469. package/core/resources/info/oldInfo/111/change.csv +242 -0
  470. package/core/resources/info/oldInfo/111/info.json +7 -0
  471. package/core/resources/info/oldInfo/112/change.csv +242 -0
  472. package/core/resources/info/oldInfo/112/info.json +7 -0
  473. package/core/resources/info/oldInfo/113/change.csv +244 -0
  474. package/core/resources/info/oldInfo/113/info.json +7 -0
  475. package/core/resources/info/oldInfo/115/change.csv +247 -0
  476. package/core/resources/info/oldInfo/115/info.json +7 -0
  477. package/core/resources/info/oldInfo/116/change.csv +249 -0
  478. package/core/resources/info/oldInfo/116/info.json +7 -0
  479. package/core/resources/info/oldInfo/118/change.csv +252 -0
  480. package/core/resources/info/oldInfo/118/info.json +7 -0
  481. package/core/resources/info/oldInfo/119/change.csv +255 -0
  482. package/core/resources/info/oldInfo/119/info.json +7 -0
  483. package/core/resources/info/oldInfo/120/change.csv +255 -0
  484. package/core/resources/info/oldInfo/120/info.json +7 -0
  485. package/core/resources/info/oldInfo/121/change.csv +257 -0
  486. package/core/resources/info/oldInfo/121/info.json +7 -0
  487. package/core/resources/info/oldInfo/122/change.csv +260 -0
  488. package/core/resources/info/oldInfo/122/info.json +7 -0
  489. package/core/resources/info/oldInfo/123/change.csv +260 -0
  490. package/core/resources/info/oldInfo/123/info.json +7 -0
  491. package/core/resources/info/oldInfo/124/change.csv +262 -0
  492. package/core/resources/info/oldInfo/124/info.json +7 -0
  493. package/core/resources/info/oldInfo/125/change.csv +266 -0
  494. package/core/resources/info/oldInfo/125/info.json +7 -0
  495. package/core/resources/info/oldInfo/126/change.csv +269 -0
  496. package/core/resources/info/oldInfo/126/info.json +7 -0
  497. package/core/resources/info/oldInfo/127/change.csv +270 -0
  498. package/core/resources/info/oldInfo/127/info.json +7 -0
  499. package/core/resources/info/oldInfo/128/change.csv +273 -0
  500. package/core/resources/info/oldInfo/128/info.json +7 -0
  501. package/core/resources/info/oldInfo/129/change.csv +274 -0
  502. package/core/resources/info/oldInfo/129/info.json +7 -0
  503. package/core/resources/info/oldInfo/130/change.csv +275 -0
  504. package/core/resources/info/oldInfo/130/info.json +7 -0
  505. package/core/resources/info/oldInfo/131/change.csv +278 -0
  506. package/core/resources/info/oldInfo/131/info.json +7 -0
  507. package/core/resources/info/oldInfo/132/change.csv +280 -0
  508. package/core/resources/info/oldInfo/132/info.json +7 -0
  509. package/core/resources/info/oldInfo/133/change.csv +284 -0
  510. package/core/resources/info/oldInfo/133/info.json +7 -0
  511. package/core/resources/info/oldInfo/134/change.csv +286 -0
  512. package/core/resources/info/oldInfo/134/info.json +7 -0
  513. package/core/resources/info/oldInfo/135/change.csv +290 -0
  514. package/core/resources/info/oldInfo/135/info.json +7 -0
  515. package/core/resources/info/oldInfo/136/change.csv +290 -0
  516. package/core/resources/info/oldInfo/136/info.json +7 -0
  517. package/core/resources/info/oldInfo/137/change.csv +293 -0
  518. package/core/resources/info/oldInfo/137/info.json +7 -0
  519. package/core/resources/info/oldInfo/138/change.csv +295 -0
  520. package/core/resources/info/oldInfo/138/info.json +7 -0
  521. package/core/resources/info/oldInfo/139/change.csv +295 -0
  522. package/core/resources/info/oldInfo/139/info.json +7 -0
  523. package/core/resources/info/oldInfo/140/change.csv +298 -0
  524. package/core/resources/info/oldInfo/140/info.json +7 -0
  525. package/core/resources/info/oldInfo/141/change.csv +300 -0
  526. package/core/resources/info/oldInfo/141/info.json +7 -0
  527. package/core/resources/info/oldInfo/142/change.csv +302 -0
  528. package/core/resources/info/oldInfo/142/info.json +7 -0
  529. package/core/resources/info/oldInfo/143/change.csv +303 -0
  530. package/core/resources/info/oldInfo/143/info.json +7 -0
  531. package/core/resources/info/oldInfo/144/change.csv +303 -0
  532. package/core/resources/info/oldInfo/144/info.json +7 -0
  533. package/core/resources/info/oldInfo/145/change.csv +305 -0
  534. package/core/resources/info/oldInfo/145/info.json +7 -0
  535. package/core/resources/info/oldInfo/146/change.csv +305 -0
  536. package/core/resources/info/oldInfo/146/info.json +7 -0
  537. package/core/resources/info/oldInfo/148/change.csv +307 -0
  538. package/core/resources/info/oldInfo/148/info.json +7 -0
  539. package/core/resources/info/oldInfo/149/change.csv +307 -0
  540. package/core/resources/info/oldInfo/149/info.json +7 -0
  541. package/core/resources/info/oldInfo/151/change.csv +309 -0
  542. package/core/resources/info/oldInfo/151/info.json +7 -0
  543. package/core/resources/info/oldInfo/152/change.csv +312 -0
  544. package/core/resources/info/oldInfo/152/info.json +7 -0
  545. package/core/resources/info/oldInfo/153/change.csv +313 -0
  546. package/core/resources/info/oldInfo/153/info.json +7 -0
  547. package/core/resources/info/oldInfo/154/change.csv +315 -0
  548. package/core/resources/info/oldInfo/154/info.json +7 -0
  549. package/core/resources/info/oldInfo/92/change.csv +204 -0
  550. package/core/resources/info/oldInfo/92/info.json +7 -0
  551. package/core/resources/info/oldInfo/93/change.csv +206 -0
  552. package/core/resources/info/oldInfo/93/info.json +7 -0
  553. package/core/resources/info/oldInfo/94/change.csv +209 -0
  554. package/core/resources/info/oldInfo/94/info.json +7 -0
  555. package/core/resources/info/oldInfo/95/change.csv +211 -0
  556. package/core/resources/info/oldInfo/95/info.json +7 -0
  557. package/core/resources/info/oldInfo/96/change.csv +216 -0
  558. package/core/resources/info/oldInfo/96/info.json +7 -0
  559. package/core/resources/info/oldInfo/98/change.csv +216 -0
  560. package/core/resources/info/oldInfo/98/info.json +7 -0
  561. package/core/resources/info/oldInfo/99/change.csv +217 -0
  562. package/core/resources/info/oldInfo/99/info.json +7 -0
  563. package/core/resources/info/oldNotesInfo.json +1 -0
  564. package/core/resources/info/sentences.json +1 -0
  565. package/core/resources/info/spinfo.json +362 -0
  566. package/core/resources/info/tips.txt +278 -0
  567. package/core/resources/otherill//351/233/252/351/231/215SP.png +0 -0
  568. package/core/resources/song-select.html +535 -0
  569. package/core/resources/themes/README.md +24 -0
  570. package/core/resources/themes/milthm/A.png +0 -0
  571. package/core/resources/themes/milthm/B.png +0 -0
  572. package/core/resources/themes/milthm/C.png +0 -0
  573. package/core/resources/themes/milthm/F.png +0 -0
  574. package/core/resources/themes/milthm/FC.png +0 -0
  575. package/core/resources/themes/milthm/S.png +0 -0
  576. package/core/resources/themes/milthm/V.png +0 -0
  577. package/core/resources/themes/milthm/arcgrosB19.css +36 -0
  578. package/core/resources/themes/milthm/b19.art +464 -0
  579. package/core/resources/themes/milthm/b19.css +1314 -0
  580. package/core/resources/themes/milthm/bg.png +0 -0
  581. package/core/resources/themes/milthm/clg.css +37 -0
  582. package/core/resources/themes/milthm/difficultyHistory.css +42 -0
  583. package/core/resources/themes/milthm/font.ttf +0 -0
  584. package/core/resources/themes/milthm/help.css +36 -0
  585. package/core/resources/themes/milthm/historyB30.css +48 -0
  586. package/core/resources/themes/milthm/info.yaml +45 -0
  587. package/core/resources/themes/milthm/list.css +39 -0
  588. package/core/resources/themes/milthm/phi.png +0 -0
  589. package/core/resources/themes/milthm/setting.css +37 -0
  590. package/core/resources/themes/milthm/sign.css +81 -0
  591. package/core/resources/themes/milthm/suggest.css +40 -0
  592. package/core/resources/themes/milthm/table.css +54 -0
  593. package/core/resources/themes/milthm/update.css +68 -0
  594. package/core/tests/aliasProposalService.test.js +82 -0
  595. package/core/tests/apiAccountDeletion.test.js +125 -0
  596. package/core/tests/apiPermission.test.js +44 -0
  597. package/core/tests/apiVersion.test.js +55 -0
  598. package/core/tests/b30Analysis.test.js +38 -0
  599. package/core/tests/backgroundIllustration.test.js +21 -0
  600. package/core/tests/botApiAuthRecovery.test.js +148 -0
  601. package/core/tests/botSyncService.test.js +42 -0
  602. package/core/tests/fileWatcherRegistry.test.js +44 -0
  603. package/core/tests/gameRecordPayload.test.js +34 -0
  604. package/core/tests/guessLetter.test.js +79 -0
  605. package/core/tests/makeRequestHandling.test.js +118 -0
  606. package/core/tests/marketOverflow.test.js +31 -0
  607. package/core/tests/platformTemplateCache.test.js +92 -0
  608. package/core/tests/pluginDataThemePreference.test.js +36 -0
  609. package/core/tests/processCleanup.test.js +58 -0
  610. package/core/tests/puppeteerShutdown.test.js +17 -0
  611. package/core/tests/renderPressureHistory.test.js +59 -0
  612. package/core/tests/saveStats.test.js +26 -0
  613. package/core/tests/themeInstallGuard.test.js +289 -0
  614. package/core/tests/themeManager.test.js +625 -0
  615. package/core/tests/themeManagerInit.test.js +11 -0
  616. package/core/tests/themeMarket.test.js +855 -0
  617. package/core/tests/themePageRouting.test.js +431 -0
  618. package/core/tests/themePolicy.test.js +28 -0
  619. package/core/tests/themeStorageRecovery.test.js +192 -0
  620. package/core/tests/userCredentialModuleBoundaries.test.js +41 -0
  621. package/core/tests/userCredentials.test.js +285 -0
  622. package/core/tsconfig.json +32 -0
  623. package/core/types/vendor.d.ts +14 -0
  624. package/lib/index.cjs +358 -0
  625. package/lib/index.d.cts +182 -0
  626. package/lib/index.d.ts +182 -0
  627. package/lib/index.js +320 -0
  628. package/package.json +74 -0
  629. package/readme.md +3 -0
@@ -0,0 +1,1004 @@
1
+ import saveHistory from '../save/saveHistory.js';
2
+ import phiApiClient from './phiApiClient.js';
3
+ import logger from '../../components/Logger.js';
4
+ import platform from '../../components/platform/index.js';
5
+ import { APII18NCN } from '../game/constNum.js';
6
+ import { getPhiApiUserMessage, hasPhiApiUserMessage } from './phiApiErrors.js';
7
+
8
+ /**
9
+ * API 请求的统一错误处理选项。
10
+ * @typedef {Object} ApiRequestOptions
11
+ * @property {string} [errorPrefix] 发送给用户的错误提示前缀
12
+ * @property {boolean} [notifyUser] 未命中内置用户提示时是否仍通知用户
13
+ * @property {string} [logTag] 错误日志标签;为空时不记录日志
14
+ * @property {'warn'|'error'} [loggerLevel] 错误日志级别
15
+ * @property {string[]} [ignoreMessages] 需要静默忽略的错误消息
16
+ * @property {string[]} [ignoreCodes] 需要静默忽略的稳定错误码
17
+ * @property {boolean} [ignoreUnboundError] 是否静默忽略“当前用户未绑定”错误
18
+ */
19
+
20
+ /**
21
+ * 具体接口函数的执行上下文。日志标签和级别由接口自身确定,不允许调用方覆盖。
22
+ * @typedef {Object} ApiRequestExecutionOptions
23
+ * @property {import('../../components/baseClass.js').botEvent} event 当前平台事件
24
+ * @property {boolean} [ignoreUnboundError] 是否静默忽略未绑定错误
25
+ * @property {boolean} [notifyUser] 是否通知用户
26
+ * @property {string} [errorPrefix] 用户提示前缀
27
+ */
28
+
29
+ /** @type {Record<string, {logTag: string, loggerLevel: 'warn'|'error'}>} */
30
+ const ENDPOINT_ERROR_LOGGING = {
31
+ '/bot/bindings/bind': { logTag: 'API错误 bind platform', loggerLevel: 'error' },
32
+ '/chartsTag/set/set': { logTag: 'setChartsTag', loggerLevel: 'error' },
33
+ '/setApiToken': { logTag: 'setApiToken', loggerLevel: 'error' },
34
+ '/clear': { logTag: 'clearApiAccount', loggerLevel: 'error' },
35
+ }
36
+
37
+ /** @param {string} path @returns {{logTag: string, loggerLevel: 'warn'|'error'}} */
38
+ function endpointErrorLogging(path) {
39
+ if (path.startsWith('/alias-proposals')) {
40
+ return { logTag: `API错误 alias proposal ${path}`, loggerLevel: 'warn' }
41
+ }
42
+ return ENDPOINT_ERROR_LOGGING[path] || { logTag: `API错误 ${path}`, loggerLevel: 'warn' }
43
+ }
44
+
45
+
46
+ /**
47
+ * @typedef {Object} platformAuth
48
+ * @property {string} platform 平台名称
49
+ * @property {string} platform_id 用户平台内id
50
+ * @property {string} _local_user_id Bot本地Redis用户键(API忽略)
51
+ */
52
+
53
+ /**
54
+ * @typedef {Object} apiAuth
55
+ * @property {string} api_user_id 用户api内id
56
+ */
57
+
58
+ /**
59
+ * @typedef {Object} tokenAuth
60
+ * @property {string} token PhigrosToken
61
+ */
62
+
63
+ /**
64
+ * @typedef {Object} apiTokenAuth
65
+ * @property {string} api_token 用户api token
66
+ */
67
+
68
+ /**
69
+ * 基础鉴权:(platform+platform_id | api_user_id) + (token | api_token)
70
+ * @typedef {(platformAuth | apiAuth | tokenAuth) & Partial<(tokenAuth | apiTokenAuth)>} baseAu
71
+ */
72
+
73
+ /**
74
+ * 高级鉴权:(platform+platform_id | api_user_id) + (token | api_token)
75
+ * @typedef {(platformAuth | apiAuth | tokenAuth) & (tokenAuth | apiTokenAuth)} highAu
76
+ */
77
+
78
+ /**
79
+ * @typedef {Object} BindSuccessResponse
80
+ * @property {string} message - Response message (e.g., "绑定成功")
81
+ * @property {Object} data - Response data
82
+ * @property {number} data.internal_id - 用户内部ID
83
+ * @property {boolean} data.have_api_token - 是否拥有API Token
84
+ * @property {boolean} [data.binding_cache_warning] - API绑定成功但本地凭据缓存需重试
85
+ */
86
+
87
+ /**
88
+ * @typedef {Object} PlatformDataItem
89
+ * @property {string} platform_name
90
+ * @property {string} platform_id
91
+ * @property {string} create_at
92
+ * @property {string} update_at
93
+ * @property {number} authentication - 认证状态
94
+ * @property {'bot'|'legacy'} [binding_type] 绑定来源
95
+ * @property {string} [binding_id] Bot独立绑定ID
96
+ * @property {string} [bot_client_id] Bot clientId
97
+ * @property {string} [bot_display_name] Bot展示名(含四位编号)
98
+ * @property {boolean} [bot_claimed] Bot是否已被认领
99
+ * @property {'active'|'revoked'} [bot_status] Bot状态
100
+ * @property {string} [authentication_label] 面向用户的认证状态
101
+ * @property {string|null} [migration_notice] 旧绑定更新提示
102
+ */
103
+
104
+ /**
105
+ * @typedef {Object} UserData
106
+ * @property {string} user_id
107
+ * @property {string} phigros_token
108
+ * @property {string} api_token
109
+ * @property {string} create_at
110
+ * @property {string} update_at
111
+ * @property {PlatformDataItem[]} platform_data
112
+ */
113
+
114
+ /**
115
+ * @typedef {Object} UserResponse
116
+ * @property {UserData} data
117
+ * @property {number} user_id - Reference to definition 168966427
118
+ * @property {string} phigros_token - Reference to definition 168966417
119
+ * @property {string} api_token - Reference to definition 168966428
120
+ * @property {string} create_at
121
+ * @property {string} update_at
122
+ * @property {PlatformDataItem[]} platform_data - Reference to definition 169006958
123
+ */
124
+
125
+ /**
126
+ * @typedef {Object} songInfoRequest
127
+ * @property {string} song_id - 歌曲ID
128
+ * @property {levelKind} difficulty - 难度
129
+ */
130
+
131
+ /**
132
+ * @typedef {Object} difficultyRecord
133
+ * @property {boolean} fc
134
+ * @property {number} score
135
+ * @property {number} acc
136
+ */
137
+
138
+ /**
139
+ * @typedef {Array<difficultyRecord | null>} songRecord
140
+ */
141
+
142
+ /**
143
+ * @typedef {Object} getCloudSongResponse
144
+ * @property {songRecord|difficultyRecord} data
145
+ */
146
+
147
+ /**
148
+ * 游戏用户基础信息
149
+ * @typedef {Object} GameUserBasic
150
+ * @property {string} background 背景图
151
+ * @property {string} [selfIntro] 自我介绍(仅me对象中存在)
152
+ */
153
+
154
+ /**
155
+ * 分数概要信息
156
+ * @typedef {Object} SummaryInfo
157
+ * @property {number} rankingScore 排名分数
158
+ * @property {number} challengeModeRank 挑战模式排名
159
+ * @property {string} [updatedAt] 更新时间(仅me对象中存在)
160
+ * @property {string} [avatar] 头像(仅me对象中存在)
161
+ */
162
+
163
+ /**
164
+ * 修改时间
165
+ * @typedef {Object} ModifiedTime
166
+ * @property {string} iso ISO时间戳
167
+ */
168
+
169
+ /**
170
+ * 存档信息
171
+ * @typedef {Object} SaveInfo
172
+ * @property {SummaryInfo} summary 分数概要
173
+ * @property {ModifiedTime} modifiedAt 修改时间
174
+ * @property {string} PlayerId 玩家ID
175
+ */
176
+
177
+ /**
178
+ * 挑战模式条目
179
+ * @typedef {Object} ChallengeListItem
180
+ * @property {number} ChallengeMode 挑战模式
181
+ * @property {number} ChallengeModeRank 挑战模式排名
182
+ * @property {string} date 日期
183
+ */
184
+
185
+ /**
186
+ * 用户条目
187
+ * @typedef {Object} UserItem
188
+ * @property {GameUserBasic} gameuser 基础信息(普通用户只有background)
189
+ * @property {SaveInfo} saveInfo 存档信息
190
+ * @property {number} index 用户索引
191
+ * @property {boolean} me 是否为当前用户
192
+ */
193
+
194
+ /**
195
+ * 当前用户数据
196
+ * @typedef {Object} MeData
197
+ * @property {oriSave} save 存档数据
198
+ * @property {saveHistoryObject} history 用户历史记录
199
+ */
200
+
201
+ /**
202
+ * ranklist响应数据主体
203
+ * @typedef {Object} ranklistResponseData
204
+ * @property {number} totDataNum 数据总数
205
+ * @property {UserItem[]} users 用户数组
206
+ * @property {MeData} me 当前用户扩展数据
207
+ */
208
+
209
+ /**
210
+ * scoreList用户对象
211
+ * @typedef {Object} ScoreListUserItem
212
+ * @property {number} index 用户排名
213
+ * @property {Object} gameuser 用户基础信息
214
+ * @property {string} gameuser.background 背景图
215
+ * @property {number} gameuser.rankingScore rks
216
+ * @property {number} gameuser.challengeModeRank 课题分
217
+ * @property {string} gameuser.avatar 头像
218
+ * @property {string} gameuser.modifiedAt 账户活跃时间
219
+ * @property {string} gameuser.PlayerId 玩家ID
220
+ * @property {Object} record 用户成绩记录
221
+ * @property {number} record.score 分数
222
+ * @property {number} record.acc 准确率
223
+ * @property {boolean} record.fc 是否FC
224
+ * @property {number} record.updated_at 成绩更新时间
225
+ */
226
+ /**
227
+ * scoreList响应数据主体
228
+ * @typedef {Object} ScoreListResponseData
229
+ * @property {number} totDataNum 数据总数
230
+ * @property {number} userRank 用户排名
231
+ * @property {ScoreListUserItem[]} users 用户数组
232
+ */
233
+
234
+ /**
235
+ * @typedef {object} liteScoreDetail
236
+ * @property {number} score 分数
237
+ * @property {number} acc 准确率
238
+ * @property {number} fc 是否FC
239
+ * @property {number} rksWhenInsert 插入时RKS
240
+ * @property {number} updated_at 更新时间戳
241
+ */
242
+
243
+ /**
244
+ * @typedef {object} apFcCountResult
245
+ * @property {number} total 总成绩数
246
+ * @property {number} fcCount FC数量
247
+ * @property {number} apCount AP数量
248
+ */
249
+
250
+ /**
251
+ * @typedef {Object} APIUpdateCommentObject 评论对象
252
+ * @property {string} songId 曲目ID
253
+ * @property {allLevelKind} rank 等级
254
+ * @property {apiUserId} apiUserId 用户ID
255
+ * @property {number} rks
256
+ * @property {number} score
257
+ * @property {number} acc
258
+ * @property {boolean} fc
259
+ * @property {string} [spInfo] FC AP
260
+ * @property {number} challenge
261
+ * @property {string} [time]
262
+ * @property {string} comment 评论内容
263
+ */
264
+
265
+ /**
266
+ * @typedef {Object} APICommentObject 评论对象
267
+ * @property {phigrosToken} [sessionToken] 仅在新建时添加
268
+ * @property {number} id 自增长ID
269
+ * @property {string} songId 曲目ID
270
+ * @property {allLevelKind} rank 等级
271
+ * @property {apiUserId} apiUserId 用户ID
272
+ * @property {number} rks
273
+ * @property {number} score
274
+ * @property {number} acc
275
+ * @property {boolean} fc
276
+ * @property {string} spInfo FC AP
277
+ * @property {number} challenge
278
+ * @property {string} time
279
+ * @property {string} comment 评论内容
280
+ * @property {?string} PlayerId 仅在查询时添加
281
+ * @property {?string} avatar 仅在查询时添加
282
+ */
283
+
284
+ /**
285
+ * @typedef {Object} userSetting
286
+ * @property {boolean} [allowDataCollection] 是否允许数据收集
287
+ * @property {boolean} [allowLeaderboard] 是否允许排行榜展示
288
+ * @property {boolean} [allowDataAggregation] 是否允许数据聚合
289
+ * @property {boolean} [allowPlayerIdSearch] 是否允许按PlayerId搜索
290
+ * @property {boolean} [allowUserIdSearch] 是否允许按UserId搜索
291
+ */
292
+
293
+ /**
294
+ * 谱面标签有效票数映射。分类标签的计数为其下细分标签数量/票数聚合,细分标签为实际投票项。
295
+ * @typedef {Record<chartsTagString, number>} chartsTagVoteCountMap
296
+ */
297
+
298
+ /**
299
+ * @typedef {object} chartsTagRequestData
300
+ * @property {idString} song_id 曲目ID
301
+ * @property {levelKind[]} [rank] 难度
302
+ */
303
+
304
+ /**
305
+ * 谱面标签树节点。
306
+ * parentId 为空时为分类标签;细分标签可通过 parentIds 同时归属多个分类。
307
+ * @typedef {object} ChartTagTreeNode
308
+ * @property {number} [id] 标签ID
309
+ * @property {chartsTagString} name 标签名
310
+ * @property {number | null} [parentId] 父标签ID,分类标签为空
311
+ * @property {number[]} [parentIds] 原始父标签ID列表,可包含多个分类
312
+ * @property {'category' | 'detail'} [kind] 标签节点类型
313
+ * @property {string | null} [description] 标签描述
314
+ * @property {string | null} [icon] 标签图标
315
+ * @property {number} [sortOrder] 排序权重
316
+ * @property {number} [status] 状态
317
+ * @property {number} voteCount 展示用有效票数
318
+ * @property {number} [primaryVoteCount] 主要票数量
319
+ * @property {number} [secondaryVoteCount] 次要票数量
320
+ * @property {ChartTagTreeNode[]} children 子标签
321
+ */
322
+
323
+ /**
324
+ * 谱面标签统计响应,data 为平铺有效票数,tree 为分类/细分树。
325
+ * @typedef {object} ChartTagSongRankResponse
326
+ * @property {chartsTagVoteCountMap} data 平铺有效票数
327
+ * @property {chartsTagVoteCountMap} [normalized] 每张选票总质量归一后的标签质量
328
+ * @property {chartsTagVoteCountMap} [support] 选择该标签的独立选票数
329
+ * @property {number} [ballotCount] 当前谱面的有效选票数
330
+ * @property {chartsTagVoteCountMap} [primary] 主要票统计
331
+ * @property {chartsTagVoteCountMap} [secondary] 次要票统计
332
+ * @property {ChartTagTreeNode[]} tree 标签树
333
+ */
334
+
335
+ /**
336
+ * @typedef {object} chartsTagResponseData
337
+ * @property {apiUserId} user_id 用户ID
338
+ * @property {idString} songId 曲目ID
339
+ * @property {levelKind} rank 难度
340
+ * @property {string} time 时间
341
+ * @property {chartsTagString[]} tags 标签内容,旧字段;没有区分主要/次要时使用
342
+ * @property {chartsTagString[]} [primaryTags] 主要票标签
343
+ * @property {chartsTagString[]} [secondaryTags] 次要票标签
344
+ */
345
+
346
+ /**
347
+ * 设置谱面标签投票请求。
348
+ * content 为旧字段;新版后端优先读取 primaryTags / secondaryTags。
349
+ * @typedef {highAu & {
350
+ * song_id: idString,
351
+ * rank: levelKind,
352
+ * content?: chartsTagString[],
353
+ * primaryTags?: chartsTagString[],
354
+ * secondaryTags?: chartsTagString[]
355
+ * }} setChartsTagParams
356
+ */
357
+
358
+ export default class makeRequest {
359
+
360
+ /**
361
+ * 从未知异常中提取可读错误消息。
362
+ * @param {any} error 捕获到的异常
363
+ * @returns {string} 规范化后的错误消息
364
+ */
365
+ static getErrorMessage(error) {
366
+ return String(error?.message || error?.cause || error?.code || error || '未知错误')
367
+ }
368
+
369
+ /**
370
+ * 判断异常是否命中调用方配置的静默规则。
371
+ * `ignoreUnboundError` 只匹配稳定错误码和旧版明确消息,不会吞掉其他 401/403。
372
+ * @param {any} error 捕获到的异常
373
+ * @param {ApiRequestOptions} [options] 错误处理策略
374
+ * @returns {boolean} 是否应静默忽略
375
+ */
376
+ static shouldIgnoreError(error, options = {}) {
377
+ const errorCode = String(error?.code || '')
378
+ const errorMessage = makeRequest.getErrorMessage(error)
379
+ if (options.ignoreCodes?.includes(errorCode)) return true
380
+ if (options.ignoreMessages?.includes(errorMessage)) return true
381
+ return options.ignoreUnboundError !== false && (
382
+ errorCode === 'binding_not_found'
383
+ || errorMessage === 'binding_not_found'
384
+ || errorMessage === APII18NCN.userNotFound
385
+ )
386
+ }
387
+
388
+ /**
389
+ * 统一处理 API 请求错误,包括用户提示、日志和静默规则。
390
+ * @param {import('../../components/baseClass.js').botEvent} event 当前平台事件
391
+ * @param {any} error 捕获到的异常
392
+ * @param {ApiRequestOptions} [options] 错误处理策略
393
+ * @returns {boolean} 是否已按静默规则忽略
394
+ */
395
+ static handleApiError(event, error, options = {}) {
396
+ if (makeRequest.shouldIgnoreError(error, options)) return true
397
+
398
+ const {
399
+ errorPrefix = '',
400
+ notifyUser = false,
401
+ logTag = '',
402
+ loggerLevel = 'warn',
403
+ } = options
404
+ const errorMessage = makeRequest.getErrorMessage(error)
405
+ let userMessage = hasPhiApiUserMessage(error) ? getPhiApiUserMessage(error) : null
406
+ const status = error?.status ?? (typeof error?.code === 'number' ? error.code : undefined)
407
+
408
+ if (status === 403 && !userMessage) {
409
+ userMessage = `API访问被拒绝。${errorMessage || '请检查你的设置是否正确启用了API访问权限。'}`
410
+ } else if (status >= 500 && !userMessage) {
411
+ userMessage = `API访问发生服务器错误。${errorMessage || '请稍后再试,或联系管理员。'}`
412
+ }
413
+
414
+ if (notifyUser && userMessage) {
415
+ const prefix = errorPrefix ? `${errorPrefix}\n` : ''
416
+ platform.sendWithAt(
417
+ platform.wrapEvent(event),
418
+ `${prefix}${userMessage || `错误信息:${errorMessage}`}`,
419
+ false,
420
+ {},
421
+ )
422
+ }
423
+ if (logTag) logger[loggerLevel](`[phi-plugin] ${logTag}`, error)
424
+ return false
425
+ }
426
+
427
+ /**
428
+ * 为当前 Bot 平台用户建立或迁移 API 绑定。
429
+ * Bot HMAC 由底层请求器负责,本方法统一管理该接口的日志和错误处理。
430
+ * @param {{platform: string, platformId: string, token?: phigrosToken, apiUserId?: apiUserId|string|number, isGlobal?: boolean}} params 绑定身份及用户凭证
431
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
432
+ * @returns {Promise<{bindingId: string, apiUserId: apiUserId} | null>} API 绑定结果
433
+ */
434
+ static async bindBotPlatform(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
435
+ return makeFetch('/bot/bindings/bind', params, 'POST', options)
436
+ }
437
+
438
+ /**
439
+ * 使用 sessionToken 创建曲目别名提案。
440
+ * @param {{token: phigrosToken, alias: string, songId: string, note?: string, source: 'bot'}} params 提案内容
441
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
442
+ * @returns {Promise<import('../type/aliasProposal.js').AliasProposalRecord | null>} 新提案
443
+ */
444
+ static async createAliasProposal(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
445
+ return makeFetch('/alias-proposals', params, 'POST', options)
446
+ }
447
+
448
+ /**
449
+ * 获取当前 sessionToken 用户提交的别名提案。
450
+ * @param {{token: phigrosToken, limit?: number, offset?: number}} params 分页参数
451
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
452
+ * @returns {Promise<import('../type/aliasProposal.js').AliasProposalRecord[]>} 提案列表
453
+ */
454
+ static async getAliasProposalsMine(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
455
+ return (await makeFetch('/alias-proposals/mine', params, 'POST', options))?.items ?? []
456
+ }
457
+
458
+ /**
459
+ * 获取当前公开投票,并附带 sessionToken 用户自己的投票。
460
+ * @param {{token: phigrosToken, limit?: number, offset?: number}} params 分页参数
461
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
462
+ * @returns {Promise<import('../type/aliasProposal.js').AliasProposalRecord[]>} 公开投票列表
463
+ */
464
+ static async getAliasPublicProposals(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
465
+ return (await makeFetch('/alias-proposals/public/list', params, 'POST', options))?.items ?? []
466
+ }
467
+
468
+ /**
469
+ * 为一次私密拒绝申请公开评审。
470
+ * @param {string} proposalId 提案 UUID
471
+ * @param {{token: phigrosToken, reason: string}} params 公审理由
472
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
473
+ * @returns {Promise<import('../type/aliasProposal.js').AliasProposalRecord | null>} 更新后的提案
474
+ */
475
+ static async requestAliasPublicReview(proposalId, params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
476
+ return makeFetch(`/alias-proposals/${encodeURIComponent(proposalId)}/public-review`, params, 'POST', options)
477
+ }
478
+
479
+ /**
480
+ * 设置、修改或撤回公开投票。
481
+ * @param {string} proposalId 提案 UUID
482
+ * @param {{token: phigrosToken, value: 1|-1|0}} params 投票内容
483
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
484
+ * @returns {Promise<import('../type/aliasProposal.js').AliasProposalRecord | null>} 更新后的提案
485
+ */
486
+ static async voteAliasProposal(proposalId, params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
487
+ return makeFetch(`/alias-proposals/${encodeURIComponent(proposalId)}/vote`, params, 'PUT', options)
488
+ }
489
+
490
+ /**
491
+ * 获取 Bot 使用的正式别名 JSON 快照。
492
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
493
+ * @returns {Promise<Record<string, string[]>>} 正式别名快照
494
+ */
495
+ static async getApprovedAliasSnapshot(/** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
496
+ return makeFetch('/alias-proposals/export/nicklist.json', undefined, 'GET', options)
497
+ }
498
+
499
+ /**
500
+ * 汇报 Bot 在线状态、可选绘图压力,并取得待私聊消息。
501
+ * @param {{
502
+ * pluginVersion: string,
503
+ * acknowledgedMessageIds: string[],
504
+ * renderPressure?: {
505
+ * windowStartedAt: string, capacity: number, active: number, queued: number,
506
+ * maxActive: number, maxQueued: number, completed: number, failed: number, timedOut: number,
507
+ * history: Array<{
508
+ * startedAt: string, endedAt: string, capacity: number, active: number, queued: number,
509
+ * maxActive: number, maxQueued: number, completed: number, failed: number, timedOut: number
510
+ * }>
511
+ * }
512
+ * }} params Bot 运行状态
513
+ * @returns {Promise<{
514
+ * ok: true, serverTime: string, nextSyncAfterSeconds: number,
515
+ * reporting: {renderPressure: boolean},
516
+ * themePolicy?: {mode:'blacklist'|'whitelist', entries:string[]},
517
+ * messages: {id:string,type:string,schemaVersion:number,target:{platform:string,platformId:string},text:string,payload:object,createdAt:string,expiresAt:string}[]
518
+ * }>}
519
+ */
520
+ static async syncBot(params) {
521
+ return makeFetch('/bot/sync', params, 'POST')
522
+ }
523
+
524
+ /**
525
+ * 以 Bot HMAC 向 phi-plugin-api 申请主题市场短期下载链接。
526
+ * 调用方负责使用同一 requestId 进行有限重试。
527
+ * @param {{requestId:string, themeId:string, version?:string}} params
528
+ */
529
+ static async requestThemeDownload(params) {
530
+ return phiApiClient.request('/bot/integrations/theme-store/download-url', params, 'POST', { timeout: 15_000 })
531
+ }
532
+
533
+ /** @returns {Promise<{ok:true,themes:any[]}>} 获取经当前 Bot 主题策略过滤后的市场主题列表。 */
534
+ static async getThemeMarketList() {
535
+ return phiApiClient.request('/bot/integrations/theme-store/themes', {}, 'GET', { timeout: 30_000 })
536
+ }
537
+
538
+ /** @param {string} themeId 获取经当前 Bot 主题策略过滤后的主题详情。 */
539
+ static async getThemeMarketDetail(themeId) {
540
+ return phiApiClient.request(`/bot/integrations/theme-store/themes/${encodeURIComponent(themeId)}`, {}, 'GET', { timeout: 15_000 })
541
+ }
542
+
543
+ /**
544
+ * 清空用户数据
545
+ * @param {highAu} params
546
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
547
+ * @returns {Promise<{message: string}>}
548
+ */
549
+ static async clear(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
550
+ return makeFetch('/clear', params, 'POST', options)
551
+ }
552
+
553
+ /**
554
+ * 设置或更新用户的 API Token
555
+ * @param {highAu & {token_new: string}} params
556
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
557
+ * @returns {Promise<{message: string}>}
558
+ */
559
+ static async setApiToken(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
560
+ return makeFetch('/setApiToken', params, 'POST', options)
561
+ }
562
+
563
+ /**
564
+ * 获取用户的 PgrToken
565
+ * @param {highAu | apiTokenAuth} params
566
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
567
+ * @returns {Promise<{apiId: apiUserId, token: phigrosToken}>}
568
+ */
569
+ static async getPgrToken(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
570
+ return (await makeFetch('/getPgrToken', params, 'POST', options))?.data ?? null
571
+ }
572
+
573
+ /**
574
+ * 获取用户已绑定的所有平台账号
575
+ * @param {highAu} params
576
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
577
+ * @returns {Promise<UserResponse>}
578
+ */
579
+ static async tokenList(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
580
+ return (await makeFetch('/token/list', params, 'POST', options))?.data ?? null
581
+ }
582
+
583
+ /**
584
+ * 获取用户云存档单曲数据
585
+ * @param {baseAu & songInfoRequest} params
586
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
587
+ * @returns {Promise<getCloudSongResponse>}
588
+ */
589
+ static async getCloudSong(params, options = undefined) {
590
+ return (await makeFetch(burl('/get/cloud/song'), params, 'POST', options)).data
591
+ }
592
+
593
+ /**
594
+ * 获取用户云存档数据
595
+ * @param {baseAu} params
596
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
597
+ * @returns {Promise<oriSave>}
598
+ */
599
+ static async getCloudSaves(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
600
+ return (await makeFetch(burl('/get/cloud/saves'), params, 'POST', options))?.data ?? null
601
+ }
602
+
603
+ /**
604
+ * 获取用户云存档saveInfo数据
605
+ * @param {baseAu} params
606
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
607
+ * @returns {Promise<saveInfo>}
608
+ */
609
+ static async getCloudSaveInfo(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
610
+ return (await makeFetch(burl('/get/cloud/saveInfo'), params, 'POST', options))?.data ?? null
611
+ }
612
+
613
+ /**
614
+ * 根据用户获取排行榜相关信息
615
+ * @param {baseAu} params
616
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
617
+ * @returns {Promise<ranklistResponseData>}
618
+ */
619
+ static async getRanklistUser(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
620
+ return (await makeFetch(burl('/get/ranklist/user'), params, 'POST', options))?.data ?? null
621
+ }
622
+
623
+ /**
624
+ * 根据名次获取排行榜相关信息
625
+ * @param {object} params
626
+ * @param {number} params.request_rank 请求的排名
627
+ * @returns {Promise<ranklistResponseData>}
628
+ */
629
+ static async getRanklistRank(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
630
+ return (await makeFetch(burl('/get/ranklist/rank'), params, 'POST', options))?.data ?? null
631
+ }
632
+
633
+ /**
634
+ * 获取rks大于目标值的用户数量
635
+ * @param {{request_rks: number}} params
636
+ * @returns {Promise<{rksRank: number, totNum: number}>}
637
+ */
638
+ static async getRanklistRks(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
639
+ return (await makeFetch(burl('/get/ranklist/rksRank'), params, 'POST', options))?.data ?? null
640
+ }
641
+
642
+ /**
643
+ * 获取用户歌曲分数排行列表
644
+ * @param {baseAu & {songId: idString, rank: levelKind, orderBy: 'acc'|'score'|'fc'|'update_at'}} params id+.0
645
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
646
+ * @returns {Promise<ScoreListResponseData>}
647
+ */
648
+ static async getScoreRanklistByUser(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
649
+ return (await makeFetch(burl('/get/scoreList/user'), params, 'POST', options))?.data ?? null
650
+ }
651
+
652
+ /**
653
+ * 获取谱面平均ACC
654
+ * @param {{songId: idString, rank: levelKind, minRks?: number, maxRks?: number}} params id+.0
655
+ * @returns {Promise<{accAvg: number, count: number}>}
656
+ */
657
+ static async getSongAccAvg(params) {
658
+ return (await makeFetch(burl('/get/scoreList/songAccAvg'), params)).data
659
+ }
660
+
661
+ /**
662
+ * 获取谱面所有成绩
663
+ * @param {{songId: idString, rank: levelKind, minRks?: number, maxRks?: number, requestField?: (keyof liteScoreDetail)[], numPrecision: number}} params id+.0
664
+ * @returns {Promise<(string[] | number[])[]>}
665
+ */
666
+ static async getSongAccList(params) {
667
+ return (await makeFetch(burl('/get/scoreList/songAccList'), params)).data
668
+ }
669
+
670
+ /**
671
+ * 获取谱面所有成绩AP FC数量
672
+ * @param {{songId: idString, rank?: levelKind[]}} params id+.0
673
+ * @returns {Promise<Record<levelKind, apFcCountResult>>}
674
+ */
675
+ static async getSongApFcCount(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
676
+ return (await makeFetch(burl('/get/scoreList/songApFcCount'), params, 'POST', options))?.data ?? null
677
+ }
678
+
679
+ /**
680
+ * 批量获取谱面所有成绩AP FC数量
681
+ * @param {{songId: idString[], rank?: levelKind[],rksRange?: {min: number, max: number}}} params id+.0
682
+ * @returns {Promise<Record<idString, Record<levelKind, apFcCountResult>>>}
683
+ */
684
+ static async getSongsApFcCount(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
685
+ return (await makeFetch(burl('/get/scoreList/songsApFcCount'), params, 'POST', options))?.data ?? null
686
+ }
687
+
688
+ /**
689
+ * 获取所有谱面平均ACC
690
+ * @param {{songIds?: idString[], minRks?: number, maxRks?: number}} params id+.0
691
+ * @returns {Promise<Record<idString, Record<levelKind, {accAvg: number | null, count: number}>>>}
692
+ */
693
+ static async getAllSongAccAvg(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
694
+ return (await makeFetch(burl('/get/scoreList/allAccAvg'), params, 'POST', options))?.data ?? null
695
+ }
696
+
697
+ /**
698
+ * 获取所有谱面平均ACC(B30版)
699
+ * @param {{songIds?: idString[], minRks?: number, maxRks?: number}} params id+.0
700
+ * @returns {Promise<Record<idString, Record<levelKind, {accAvg: number | null, count: number}>>>}
701
+ */
702
+ static async getAllSongAccAvgB30(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
703
+ return (await makeFetch(burl('/get/scoreList/allAccAvgB30'), params, 'POST', options))?.data ?? null
704
+ }
705
+
706
+ /**
707
+ * 获取所有谱面平均ACC(全部)
708
+ * @param {{songIds?: idString[], minRks?: number, maxRks?: number}} params id+.0
709
+ * @returns {Promise<Record<idString, Record<levelKind, {accAvg: number | null, count: number}>>>}
710
+ */
711
+ static async getAllSongAccAvgDual(params) {
712
+ return (await makeFetch(burl('/get/scoreList/allAccAvgDual'), params)).data
713
+ }
714
+
715
+ /**
716
+ * 获取所有谱面acc排行列表
717
+ * @param {{queries: {songId: idString, rank: levelKind, acc: number}[], dimension:("all" | "b30")[], minRks?: number, maxRks?: number}} params
718
+ * @returns {Promise<Record<"all" | "b30", {songId: idString, rank: levelKind, acc: number, topPercent: number, betterCount: number, totalCount: number}[]>>}
719
+ */
720
+ static async getAllSongAccRank(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
721
+ return (await makeFetch(burl('/get/scoreList/allAccRank'), params, 'POST', options))?.data ?? null
722
+ }
723
+
724
+ /**
725
+ * @overload
726
+ * @param {baseAu} params
727
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
728
+ * @returns {Promise<saveHistoryObject>}
729
+ */
730
+ /**
731
+ * @template {keyof saveHistoryObject} K
732
+ * @overload
733
+ * @param {baseAu & {request: K[]}} params
734
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
735
+ * @returns {Promise<Pick<saveHistoryObject, K> | null>}
736
+ */
737
+ /**
738
+ * 获取用户data历史记录
739
+ * @template {keyof saveHistoryObject} K
740
+ * @param {baseAu & {request?: K[]}} params
741
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
742
+ * @returns {Promise<Partial<saveHistoryObject> | null>}
743
+ */
744
+ static async getHistory(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
745
+ return (await makeFetch(burl('/get/history/history'), params, 'POST', options))?.data ?? null
746
+ }
747
+
748
+ /**
749
+ * @overload
750
+ * @param {baseAu} params
751
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
752
+ * @returns {Promise<{data: scoreHistoryObject}>}
753
+ */
754
+ /**
755
+ * @overload
756
+ * @param {baseAu & { song_id: idString }} params
757
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
758
+ * @returns {Promise<{ data: songRecordHistory }>}
759
+ */
760
+ /**
761
+ * @overload
762
+ * @param {baseAu & { song_id: idString, rank: levelKind }} params
763
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
764
+ * @returns {Promise<{ data: ScoreDetail[] }>}
765
+ */
766
+ /**
767
+ * 获取用户成绩历史记录
768
+ * @param {baseAu & {song_id?: idString, rank?: levelKind}} params
769
+ * @returns {Promise<{
770
+ * data: ScoreDetail[] | songRecordHistory | scoreHistoryObject
771
+ * }>}
772
+ */
773
+ static async getHistoryRecord(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
774
+ return (await makeFetch(burl('/get/history/record'), params, 'POST', options))?.data ?? null
775
+ }
776
+
777
+ /**
778
+ * 上传用户的历史记录
779
+ * @param {baseAu & {data: saveHistory}} params
780
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
781
+ * @returns {Promise<{message: string}>}
782
+ */
783
+ static async setHistory(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
784
+ return await makeFetch(burl('/set/history'), params, 'POST', options)
785
+ }
786
+
787
+ /**
788
+ * 上传用户tk
789
+ * @param {{data: phigrosToken[]}} params
790
+ * @returns {Promise<{message: string}>}
791
+ */
792
+ static async setUsersToken(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
793
+ return makeFetch('/set/usersToken', params, 'POST', options)
794
+ }
795
+
796
+ /**
797
+ * 查询用户是否被禁用
798
+ * @param {baseAu} params
799
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
800
+ * @returns {Promise<boolean>}
801
+ */
802
+ static async getUserBan(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
803
+ return (await makeFetch(burl('/get/banUser'), params, 'POST', options))?.data ?? null
804
+ }
805
+
806
+ /**
807
+ * 获取歌曲评论
808
+ * @param {{song_id: idString}} params
809
+ * @returns {Promise<APICommentObject[]>}
810
+ */
811
+ static async getCommentsBySongId(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
812
+ return (await makeFetch(burl('/comment/get/bySongId'), params, 'POST', options))?.data ?? null
813
+ }
814
+
815
+ /**
816
+ * 获取歌曲评论
817
+ * @param {baseAu} params
818
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
819
+ * @returns {Promise<APICommentObject[]>}
820
+ */
821
+ static async getCommentsByUserId(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
822
+ return (await makeFetch(burl('/comment/get/byUserId'), params, 'POST', options))?.data ?? null
823
+ }
824
+
825
+ /**
826
+ * 添加单条评论
827
+ * @param {highAu & {data: {comment: APIUpdateCommentObject}}} params
828
+ * @returns {Promise<{message: string}>}
829
+ */
830
+ static async addComment(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
831
+ return makeFetch(burl('/comment/add'), params, 'POST', options)
832
+ }
833
+
834
+ /**
835
+ * 删除单条评论
836
+ * @param {highAu & {comment_id: string}} params
837
+ * @returns {Promise<{message: string}>}
838
+ */
839
+ static async delComment(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
840
+ return makeFetch(burl('/comment/del'), params, 'POST', options)
841
+ }
842
+
843
+ /**
844
+ * 批量添加评论
845
+ * @param {{data: import('../game/getComment.js').commentObject[]}} params
846
+ * @returns {Promise<{message: string}>}
847
+ */
848
+ static async updateComments(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
849
+ return makeFetch(burl('/comment/update'), params, 'POST', options)
850
+ }
851
+
852
+ /**
853
+ * 获取谱面标签名称列表
854
+ * @returns {Promise<chartsTagString[]>}
855
+ */
856
+ static async getChartsTagsName() {
857
+ return (await makeFetch(burl('/chartsTag/get/tagNames'), {}, 'GET')).data
858
+ }
859
+
860
+ /**
861
+ * 获取谱面标签树
862
+ * @returns {Promise<ChartTagTreeNode[]>}
863
+ */
864
+ static async getChartsTagsTree(/** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
865
+ return (await makeFetch(burl('/chartsTag/get/tagTree'), {}, 'GET', options))?.data ?? null
866
+ }
867
+
868
+ /**
869
+ * 获取谱面标签信息
870
+ * @param {{song_id: idString, rank: levelKind}} params
871
+ * @returns {Promise<chartsTagVoteCountMap>}
872
+ */
873
+ static async getChartsTagbySongRank(params) {
874
+ return (await makeFetch(burl('/chartsTag/get/bySongRank'), params)).data
875
+ }
876
+
877
+ /**
878
+ * 获取谱面标签信息,包含分类计数树
879
+ * @param {{song_id: idString, rank: levelKind}} params
880
+ * @returns {Promise<ChartTagSongRankResponse>}
881
+ */
882
+ static async getChartsTagbySongRankWithTree(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
883
+ return makeFetch(burl('/chartsTag/get/bySongRank'), params, 'POST', options)
884
+ }
885
+
886
+ /**
887
+ * 批量获取谱面标签信息,按曲目和难度分别返回。
888
+ * @param {{data: {song_id: idString, rank?: levelKind[]}[], total?: boolean}} params
889
+ * @returns {Promise<{
890
+ * data: Record<idString, Record<levelKind, chartsTagVoteCountMap>>,
891
+ * normalized: Record<idString, Record<levelKind, chartsTagVoteCountMap>>,
892
+ * support: Record<idString, Record<levelKind, chartsTagVoteCountMap>>,
893
+ * ballotCounts: Record<idString, Record<levelKind, number>>,
894
+ * primary: Record<idString, Record<levelKind, chartsTagVoteCountMap>>,
895
+ * secondary: Record<idString, Record<levelKind, chartsTagVoteCountMap>>,
896
+ * tree: Record<idString, Record<levelKind, ChartTagTreeNode[]>>
897
+ * }>}
898
+ */
899
+ static async getChartsTagsBatch(params) {
900
+ return await makeFetch(burl('/chartsTag/get/chartsTags'), params)
901
+ }
902
+
903
+ /**
904
+ * 获取用户按动态 RKS 门槛计算的谱面实力分析(雷达图、擅长 tag 与薄弱 tag)。
905
+ * @param {baseAu | {gameRecord: gameRecord}} params
906
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
907
+ * @returns {Promise<{
908
+ * analysisMode: 'threshold_pool',
909
+ * threshold: number,
910
+ * minimumChartVoters: number,
911
+ * minimumTagSamples: number,
912
+ * recordCount: number,
913
+ * totalVotes: number,
914
+ * minimumVotes: number,
915
+ * averageRks: number,
916
+ * categories: {name: string, rks: number, votes: number, hasVotes: boolean}[],
917
+ * radar: {grids: string[], axes: {x: number, y: number}[], points: string, categories: object[]},
918
+ * strong: {name: string, rks: number, rawRks: number, votes: number, sampleCount: number, effectiveSampleSize: number, confidence: number}[],
919
+ * weak: {name: string, rks: number, rawRks: number, votes: number, sampleCount: number, effectiveSampleSize: number, confidence: number}[],
920
+ * insufficient: boolean
921
+ * }>}
922
+ */
923
+ static async getB30TagAnalysis(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
924
+ return (await makeFetch(burl('/chartsTag/get/b30Analysis'), params, 'POST', options))?.data ?? null
925
+ }
926
+
927
+
928
+ /**
929
+ * 获取用户对谱面标签的投票记录
930
+ * @param {baseAu & {data: chartsTagRequestData[]}} params
931
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文
932
+ * @returns {Promise<chartsTagResponseData[]>}
933
+ */
934
+ static async getChartsUsersVote(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
935
+ return (await makeFetch(burl('/chartsTag/get/usersVote'), params, 'POST', options))?.data ?? null
936
+ }
937
+
938
+ /**
939
+ * 用户设置谱面标签
940
+ * @param {setChartsTagParams} params
941
+ * @returns {Promise<{message: string}>}
942
+ */
943
+ static async setChartsTag(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
944
+ return makeFetch(burl('/chartsTag/set/set'), params, 'POST', options)
945
+ }
946
+
947
+ /**
948
+ * 获取用户设置
949
+ * @param {highAu} params
950
+ * @returns {Promise<userSetting>}
951
+ */
952
+ static async getUserSetting(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
953
+ return (await makeFetch(burl('/userSetting/get'), params, 'POST', options))?.data ?? null
954
+ }
955
+
956
+ /**
957
+ * 设置用户设置
958
+ * @param {highAu & {setting: userSetting}} params
959
+ * @returns {Promise<userSetting>}
960
+ */
961
+ static async setUserSetting(params, /** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
962
+ return (await makeFetch(burl('/userSetting/set'), params, 'POST', options))?.data ?? null
963
+ }
964
+
965
+ /**
966
+ * 设置用户设置
967
+ * @returns {Promise<string>}
968
+ */
969
+ static async liveInfo(/** @type {ApiRequestExecutionOptions | undefined} */ options = undefined) {
970
+ return (await makeFetch(burl('/live'), undefined, 'POST', options))?.data ?? null
971
+ }
972
+ }
973
+
974
+ /**
975
+ * @param {string} originalPath
976
+ * @param {any} [params]
977
+ * @param {'POST'|'GET'|'PUT'} [method='POST']
978
+ * @param {ApiRequestExecutionOptions} [options] 错误处理上下文;省略时向上抛出错误
979
+ * @returns {Promise<any>}
980
+ */
981
+ async function makeFetch(originalPath, params, method = 'POST', options = undefined) {
982
+ const execute = () => phiApiClient.request(originalPath, params, method)
983
+ if (!options) return execute()
984
+ try {
985
+ return await execute()
986
+ } catch (error) {
987
+ makeRequest.handleApiError(options.event, error, {
988
+ ...endpointErrorLogging(originalPath),
989
+ errorPrefix: options.errorPrefix,
990
+ notifyUser: options.notifyUser,
991
+ ignoreUnboundError: options.ignoreUnboundError,
992
+ })
993
+ return null
994
+ }
995
+ }
996
+
997
+ /**
998
+ * 拼接基础URL
999
+ * @param {string} path
1000
+ * @returns
1001
+ */
1002
+ function burl(path) {
1003
+ return path
1004
+ }