@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,1418 @@
1
+ // import get from '../model/getdata.js'
2
+ import common from "../components/common.js"
3
+ import Config from '../components/Config.js'
4
+ import send from '../model/render/send.js'
5
+ import getInfo from '../model/game/getInfo.js'
6
+ import getPic from '../model/render/getPic.js'
7
+ import picmodle from '../model/render/picmodle.js'
8
+ import fCompute from '../model/game/fCompute.js'
9
+ import getBanGroup from '../model/user/getBanGroup.js';
10
+ import { allLevel, Level, LevelNum } from '../model/game/constNum.js'
11
+ import getComment from '../model/game/getComment.js'
12
+ import getSave from '../model/save/getSave.js'
13
+ import { UserCredentials } from '../model/user/userCredentials.js'
14
+ import Version from '../components/Version.js'
15
+ import makeRequest from '../model/api/makeRequest.js'
16
+ import phiPluginBase from '../components/baseClass.js'
17
+ import logger from '../components/Logger.js'
18
+ import SongsInfo from '../model/game/SongsInfo.js'
19
+ import Chart from "../model/game/Chart.js"
20
+ import getNotes from "../model/user/getNotes.js"
21
+ import { canUseApi } from '../model/user/apiPermission.js'
22
+ import TapInfo from "../model/integrations/getInfoFromTap.js"
23
+
24
+ /**@import {botEvent} from '../components/baseClass.js' */
25
+
26
+ /**
27
+ * @type {{ [x: string]: string | number; }}
28
+ */
29
+ let wait_to_del_list
30
+ /**
31
+ * @type {string | number}
32
+ */
33
+ let wait_to_del_nick
34
+
35
+ export class phisong extends phiPluginBase {
36
+ constructor() {
37
+ super({
38
+ name: 'phi-图鉴',
39
+ dsc: 'phigros图鉴',
40
+ event: 'message',
41
+ priority: 1000,
42
+ rule: [
43
+ {
44
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(曲|song).*$`,
45
+ fnc: 'song'
46
+ },
47
+ {
48
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(查找|检索|search).*$`,
49
+ fnc: 'search'
50
+ },
51
+ {
52
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(设置别名|setnic(k?)).*$`,
53
+ fnc: 'setnick'
54
+ },
55
+ // {
56
+ // reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(删除别名|delnic(k?)).*$`,
57
+ // fnc: 'delnick'
58
+ // },
59
+ {
60
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(曲绘|ill|Ill).*$`,
61
+ fnc: 'ill'
62
+ },
63
+ {
64
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)randclg.*$`,
65
+ fnc: 'randClg'
66
+ },
67
+ {
68
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(随机|rand(om)?).*$`,
69
+ fnc: 'randmic'
70
+ },
71
+ {
72
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)alias.*$`,
73
+ fnc: 'alias'
74
+ },
75
+ {
76
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(com|计算).*$`,
77
+ fnc: 'comrks'
78
+ },
79
+ {
80
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)tips$`,
81
+ fnc: 'tips'
82
+ },
83
+ {
84
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)newlog$`,
85
+ fnc: 'newSong'
86
+ },
87
+ {
88
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)live$`,
89
+ fnc: 'live'
90
+ },
91
+ {
92
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(table|定数表)\\s*[0-9]+\\s*(-v\\s*\\S*)?$`,
93
+ fnc: 'table'
94
+ },
95
+ {
96
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(dif[Hh]is(tory)?|历史定数).*$`,
97
+ fnc: 'difHis'
98
+ },
99
+ {
100
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(comment|cmt|评论|评价)[\\s\\S]*$`,
101
+ fnc: 'comment'
102
+ },
103
+ {
104
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(recmt).*$`,
105
+ fnc: 'recallComment'
106
+ },
107
+ {
108
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(mycmt).*$`,
109
+ fnc: 'myComment'
110
+ },
111
+ // {
112
+ // reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(chart).*$`,
113
+ // fnc: 'chart'
114
+ // },
115
+ {
116
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)(addtag|subtag|retag).*$`,
117
+ fnc: 'addtag'
118
+ },
119
+ {
120
+ reg: `^[#/](${Config.getUserCfg('config', 'cmdhead')})(\\s*)newnotice$`,
121
+ fnc: 'newNotice'
122
+ }
123
+ ]
124
+ })
125
+
126
+ }
127
+
128
+
129
+ /**
130
+ * 歌曲图鉴
131
+ * @param {botEvent} e
132
+ */
133
+ async song(e) {
134
+
135
+ if (await getBanGroup.get(e, 'song')) {
136
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
137
+ return false
138
+ }
139
+
140
+ let msg = e.msg.replace(/[#/](.*?)(曲|song)(\s*)/, "")
141
+ let addComment = msg.match(/\s+-comment/)?.[0] ? true : false;
142
+ if (addComment) msg = msg.replace(/\s+-comment/, "")
143
+ let page = msg.match(/\s+-p\s+([0-9]+)/)?.[1] ? Number(msg.match(/\s+-p\s+([0-9]+)/)?.[1]) : 0;
144
+ msg = msg.replace(/\s+-p\s+([0-9]+)/, "")
145
+ if (!msg) {
146
+ send.send_with_At(e, `请指定曲名哦!\n格式:/${Config.getUserCfg('config', 'cmdhead')} song <曲名>`)
147
+ return true
148
+ }
149
+ let ids = getInfo.fuzzysongsnick(msg)
150
+ if (ids[0]) {
151
+ if (!ids[1]) {
152
+ send.send_with_At(e, await songInfo(page, addComment, ids[0], e))
153
+ } else {
154
+ this.choseMutiNick(e, ids, { page, addComment }, async (e, id, options) => {
155
+ send.send_with_At(e, await songInfo(options.page, options.addComment, id, e));
156
+ })
157
+ }
158
+ } else {
159
+ send.send_with_At(e, `未找到${msg}的相关曲目信息QAQ\n如果想要提供别名的话请访问 /phihelp 中的别名投稿链接嗷!`)
160
+ }
161
+ return true
162
+ }
163
+
164
+ /**
165
+ *
166
+ * @param {botEvent} e
167
+ * @returns
168
+ */
169
+ async search(e) {
170
+
171
+ if (await getBanGroup.get(e, 'search')) {
172
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
173
+ return false
174
+ }
175
+
176
+ let msg = e.msg.replace(/[#/](.*?)(查找|检索|search)(\s*)/g, "").toLowerCase()
177
+
178
+ /**
179
+ * @type {Record<string, {regex: RegExp, predicate: (item: any, bottom: number, top: number) => boolean}>}
180
+ */
181
+ const patterns = {
182
+ 'bpm': {
183
+ 'regex': /bpm([\s::,,/|~是为]*)([0-9]+(\s*-\s*[0-9]+)?)/,
184
+ 'predicate': (item, bottom, top) => {
185
+ // 优先使用 bpmList(变速曲目)
186
+ if (item?.['bpmList'] && Array.isArray(item['bpmList']) && item['bpmList'].length) {
187
+ return item['bpmList'].some(bpm => bottom <= bpm && bpm <= top);
188
+ }
189
+ // 回退到原来的单值 bpm
190
+ return item?.['bpm'] ? bottom <= item['bpm'] && item['bpm'] <= top : false;
191
+ }
192
+ },
193
+ 'difficulty': {
194
+ 'regex': /(difficulty|dif|定数|难度|定级)([\s::,,/|~是为]*)([0-9.]+(\s*-\s*[0-9.]+)?)/,
195
+ 'predicate': (item, bottom, top) => (item?.['chart'] ? Object.values(item['chart']).some(level => bottom <= level['difficulty'] && level['difficulty'] <= top) : false)
196
+ },
197
+ 'combo': {
198
+ 'regex': /(combo|cmb|物量|连击)([\s::,,/|~是为]*)([0-9]+(\s*-\s*[0-9]+)?)/,
199
+ 'predicate': (item, bottom, top) => (item?.['chart'] ? Object.values(item['chart']).some(level => bottom <= level['combo'] && level['combo'] <= top) : false)
200
+ }
201
+ }
202
+
203
+ /**@type {Partial<Record<idString, SongsInfo>>} */
204
+ let remain = getInfo.all_info()
205
+ /**@type {Partial<Record<idString, SongsInfo>>} */
206
+ let result = {}
207
+ /**
208
+ * @type {{ [x: string]: [number, number]; }} filters
209
+ */
210
+ let filters = {}
211
+
212
+ for (let key in patterns) {
213
+ let { regex, predicate } = patterns[key]
214
+ let match = msg.match(regex)
215
+ if (match) {
216
+ let matchStr = match[0].replace(/((bpm|difficulty|dif|难度|定级|定数|combo|cmb|物量|连击)([\s::,,/|~是为]*))(\d)/g, '$1 $4')
217
+ matchStr = matchStr.replace(/((bpm|difficulty|dif|难度|定级|定数|combo|cmb|物量|连击)([\s::,,/|~是为]*))|\s/g, '')
218
+ let [bottom, top] = matchStr.includes('-') ? matchStr.split('-').sort((a, b) => Number(a) - Number(b)) : [matchStr, matchStr]
219
+ let bottomNum = Number(bottom)
220
+ let topNum = Number(top)
221
+ if (key === 'difficulty' && !matchStr.includes('.0') && topNum % 1 === 0) {
222
+ topNum += 0.9
223
+ }
224
+ filters[key] = [bottomNum, topNum]
225
+ for (let id of fCompute.objectKeys(remain)) {
226
+ if (predicate(remain[id], bottomNum, topNum)) {
227
+ result[id] = remain[id]
228
+ }
229
+ }
230
+ remain = result
231
+ result = {}
232
+ }
233
+ }
234
+
235
+ if (Config.getUserCfg('config', 'isGuild')) {
236
+ let Resmsg = []
237
+ let tot = 0
238
+ let count = 1
239
+ let single = `当前筛选:${filters.bpm ? `BPM:${filters.bpm[0]}${filters.bpm[1] ? `-${filters.bpm[1]}` : ''}` : ''}${filters.difficulty ? `定级:${filters.difficulty[0]}${filters.difficulty[1] ? `-${filters.difficulty[1]}` : ''} ` : ''}${filters.combo ? ` 物量:${filters.combo[0]}${filters.combo[1] ? `-${filters.combo[1]}` : ''} ` : ''}`
240
+ for (let id of fCompute.objectKeys(remain)) {
241
+ let songInfo = remain[id]
242
+ if (!songInfo) continue;
243
+ let msg
244
+ if (count) {
245
+ msg = `\n${id} BPM:${songInfo.bpm}`
246
+ } else {
247
+ msg = `${id} BPM:${songInfo.bpm}`
248
+ }
249
+ for (let level of fCompute.objectKeys(songInfo.chart)) {
250
+ msg += `<${level}> ${songInfo.chart[level]?.difficulty} ${songInfo.chart[level]?.combo}`
251
+ }
252
+ single += msg
253
+ ++tot
254
+ ++count
255
+ /**每条消息10行 */
256
+ if (count == 10) {
257
+ Resmsg.push(single)
258
+ single = ''
259
+ count = 0
260
+ }
261
+ }
262
+ if (count) {
263
+ Resmsg.push(single)
264
+ count = 0
265
+ }
266
+ if (e.isGroup) {
267
+ send.send_with_At(e, `找到了${tot}个结果,自动转为私聊发送喵~`, true)
268
+ send.pick_send(e, await common.makeForwardMsg(e, Resmsg, `找到了${tot}个结果喵!`))
269
+
270
+ } else {
271
+ send.reply(e, await common.makeForwardMsg(e, Resmsg, `找到了${tot}个结果喵!`))
272
+ }
273
+ } else {
274
+ let Resmsg = [`当前筛选:${filters.bpm ? `\nBPM:${filters.bpm[0]}${filters.bpm[1] ? `-${filters.bpm[1]}` : ''}` : ''}${filters.difficulty ? `\n定级:${filters.difficulty[0]}${filters.difficulty[1] ? `-${filters.difficulty[1]}` : ''} ` : ''}${filters.combo ? `\n物量:${filters.combo[0]}${filters.combo[1] ? `-${filters.combo[1]}` : ''} ` : ''}`]
275
+ for (let id of fCompute.objectKeys(remain)) {
276
+ let songInfo = remain[id]
277
+ if (!songInfo) continue;
278
+ let msg = `${id}\nBPM:${songInfo.bpm}`
279
+ for (let level of fCompute.objectKeys(songInfo.chart)) {
280
+ msg += `\n${level} ${songInfo.chart[level]?.difficulty} ${songInfo.chart[level]?.combo}`
281
+ }
282
+ Resmsg.push(msg)
283
+ }
284
+ send.reply(e, await common.makeForwardMsg(e, Resmsg, `找到了${Resmsg.length - 1}首曲目喵!`))
285
+ }
286
+
287
+ }
288
+
289
+
290
+ /**
291
+ * 设置别名
292
+ * @param {botEvent} e
293
+ */
294
+ async setnick(e) {
295
+ if (!(e.is_admin || e.isMaster)) {
296
+ send.reply(e, "只有管理员可以设置别名哦!")
297
+ return true
298
+ }
299
+ let msg = e.msg.replace(/[#/](.*?)(设置别名|setnic(k?))(\s*)/g, "")
300
+ /**@type {string[]} */
301
+ let parts = []
302
+ if (msg.includes("--->")) {
303
+ msg = msg.replace(/(\s*)--->(\s*)/g, " ---> ")
304
+ parts = msg.split(" ---> ")
305
+ } else if (msg.includes("\n")) {
306
+ parts = msg.split("\n")
307
+ }
308
+ if (parts[1]) {
309
+ let P0Ids = getInfo.fuzzysongsnick(parts[0], 1)
310
+ let P0Id = ''
311
+ if (P0Ids[0]) {
312
+ P0Id = P0Ids[0]
313
+ } else {
314
+ send.reply(e, `输入有误哦!没有找到“${msg[0]}”这首曲子呢!`)
315
+ return true
316
+ }
317
+ if (P0Id in getInfo.fuzzysongsnick(parts[1], 1)) {
318
+ /**已经添加过该别名 */
319
+ send.reply(e, `${P0Id} 已经有 ${parts[1]} 这个别名了哦!`)
320
+ return true
321
+ } else {
322
+ getInfo.setnick(P0Id, parts[1])
323
+ send.reply(e, "设置完成!")
324
+ }
325
+ } else {
326
+ send.reply(e, `输入有误哦!请按照\n原名(或已有别名) ---> 别名\n的格式发送哦!`)
327
+ }
328
+ return true
329
+ }
330
+
331
+ /**
332
+ * 获取曲绘
333
+ * @param {botEvent} e
334
+ */
335
+ async ill(e) {
336
+
337
+ if (await getBanGroup.get(e, 'ill')) {
338
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
339
+ return false
340
+ }
341
+
342
+ let msg = e.msg.replace(/[#/](.*?)(曲绘|ill|Ill)(\s*)/, "")
343
+ if (!msg) {
344
+ send.send_with_At(e, `请指定曲名哦!\n格式:/${Config.getUserCfg('config', 'cmdhead')} ill <曲名>`)
345
+ return true
346
+ }
347
+ let ids = getInfo.fuzzysongsnick(msg)
348
+ if (ids[0]) {
349
+ let msgRes
350
+
351
+ if (!ids[1]) {
352
+ send.send_with_At(e, await getPic.GetSongsIllAtlas(e, ids[0]))
353
+ } else {
354
+ this.choseMutiNick(e, ids, {}, async (e, id) => {
355
+ send.send_with_At(e, await getPic.GetSongsIllAtlas(e, id));
356
+ })
357
+ }
358
+ } else {
359
+ send.send_with_At(e, `未找到${msg}的相关曲目信息QAQ`)
360
+ return false
361
+ }
362
+ return true
363
+
364
+ }
365
+
366
+ /**
367
+ * 随机定级范围内曲目
368
+ * @param {botEvent} e
369
+ */
370
+ async randmic(e) {
371
+
372
+ if (await getBanGroup.get(e, 'randmic')) {
373
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
374
+ return false
375
+ }
376
+
377
+ let msg = e.msg.replace(/^[#/](.*?)(随机|rand)(\s*)/, "")
378
+ let isask = [1, 1, 1, 1]
379
+
380
+ msg = msg.toUpperCase()
381
+ if (msg.includes('AT') || msg.includes('IN') || msg.includes('HD') || msg.includes('EZ')) {
382
+ isask = [0, 0, 0, 0]
383
+ if (msg.includes('EZ')) { isask[0] = 1 }
384
+ if (msg.includes('HD')) { isask[1] = 1 }
385
+ if (msg.includes('IN')) { isask[2] = 1 }
386
+ if (msg.includes('AT')) { isask[3] = 1 }
387
+ }
388
+ msg = msg.replace(/((\s*)|AT|IN|HD|EZ)*/g, "")
389
+ let rank = msg.split('-')
390
+ let top
391
+ let bottom
392
+
393
+ /**是否指定范围 */
394
+ if (rank[0]) {
395
+ if (rank[0].includes('+')) {
396
+ if (rank[1]) {
397
+ send.send_with_At(e, `含有 '+' 的难度不支持指定范围哦!\n/${Config.getUserCfg('config', 'cmdhead')} rand <定数>+ <难度(可多选)>`, true)
398
+ return true
399
+ } else {
400
+ bottom = Number(rank[0].replace('+', ''))
401
+ top = 100
402
+ }
403
+ } else if (rank[0].includes('-') && !rank[1]) {
404
+ const tb = Number(rank[0].replace('-', ''))
405
+ if (isNaN(tb)) {
406
+ send.send_with_At(e, `${rank[0]} 不是一个定级哦\n#/${Config.getUserCfg('config', 'cmdhead')} rand <定数>- <难度(可多选)>`, true)
407
+ return true
408
+ } else {
409
+ bottom = 0
410
+ top = tb
411
+ }
412
+ } else {
413
+ const tb = Number(rank[0])
414
+ if (rank[1]) {
415
+ const tt = Number(rank[1])
416
+ if (isNaN(tb) || isNaN(tt)) {
417
+ send.send_with_At(e, `${rank[0]} - ${rank[1]} 不是一个定级范围哦\n/${Config.getUserCfg('config', 'cmdhead')} rand <定数1> - <定数2> <难度(可多选)>`, true)
418
+ return true
419
+ }
420
+ top = Math.max(tb, tt)
421
+ bottom = Math.min(tb, tt)
422
+ } else {
423
+ if (isNaN(tb)) {
424
+ send.send_with_At(e, `${rank[0]} 不是一个定级哦\n#/${Config.getUserCfg('config', 'cmdhead')} rand <定数> <难度(可多选)>`, true)
425
+ return true
426
+ } else {
427
+ top = bottom = tb
428
+ }
429
+ }
430
+ }
431
+ } else {
432
+ top = 100
433
+ bottom = 0
434
+ }
435
+
436
+ if (top % 1 == 0 && !msg.includes(".0")) top += 0.9
437
+
438
+ let songsname = []
439
+ for (let id of fCompute.objectKeys(getInfo.ori_info)) {
440
+ if (!getInfo.ori_info[id]?.chart) continue;
441
+ for (let level of Level) {
442
+ if (isask[LevelNum[level]] && getInfo.ori_info[id].chart[level]) {
443
+ let difficulty = getInfo.ori_info[id].chart[level].difficulty
444
+ if (difficulty >= bottom && difficulty <= top) {
445
+ songsname.push({
446
+ ...getInfo.ori_info[id].chart[level],
447
+ rank: level,
448
+ illustration: getInfo.getill(id),
449
+ song: getInfo.ori_info[id].song,
450
+ illustrator: getInfo.ori_info[id].illustrator,
451
+ composer: getInfo.ori_info[id].composer,
452
+ })
453
+ }
454
+ }
455
+ }
456
+ }
457
+
458
+ if (!songsname[0]) {
459
+ send.send_with_At(e, `未找到 ${bottom} - ${top} 的 ${isask[0] ? `${Level[0]} ` : ''}${isask[1] ? `${Level[1]} ` : ''}${isask[2] ? `${Level[2]} ` : ''}${isask[3] ? `${Level[3]} ` : ''}谱面QAQ!`)
460
+ return true
461
+ }
462
+
463
+ let result = songsname[randbt(songsname.length - 1)]
464
+
465
+ send.send_with_At(e, await picmodle.rand(e, result))
466
+ return true
467
+ }
468
+
469
+ /**
470
+ * 查询歌曲别名
471
+ * @param {botEvent} e
472
+ */
473
+ async alias(e) {
474
+
475
+ if (await getBanGroup.get(e, 'alias')) {
476
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
477
+ return false
478
+ }
479
+
480
+ let msg = e.msg.replace(/[#/](.*?)alias(\s*)/, "")
481
+ let id = getInfo.info(/**@type {idString} */(msg))?.id;
482
+ let ids = id ? [id] : getInfo.fuzzysongsnick(msg);
483
+
484
+ /**
485
+ * @param {botEvent} e
486
+ * @param {idString} id
487
+ */
488
+ function makeNickMsg(e, id) {
489
+ let info = getInfo.info(id)
490
+ let nicks = ['======================\n已有别名:']
491
+ const usernick = Config.getUserCfg('nickconfig')
492
+ for (let nick of fCompute.objectKeys(usernick)) {
493
+ if (usernick[nick].includes(id)) {
494
+ nicks.push(`${nick}`)
495
+ }
496
+ }
497
+ if (getInfo?.nicklist?.[id]) {
498
+ nicks = nicks.concat(getInfo.nicklist[id])
499
+ }
500
+ // console.info(getInfo.nicklist)
501
+ // console.info(info.song)
502
+ send.send_with_At(e, [getPic.getIll(id), `\nname: ${info?.song}\nid: ${id}\n` + nicks.join('\n')])
503
+ }
504
+
505
+ if (ids[0]) {
506
+ if (!ids[1]) {
507
+ makeNickMsg(e, ids[0])
508
+ } else {
509
+ this.choseMutiNick(e, ids, {}, (e, id) => makeNickMsg(e, id));
510
+ }
511
+ } else {
512
+ send.send_with_At(e, `未找到${msg}的相关曲目信息QAQ!如果想要提供别名的话请访问 /phihelp 中的别名投稿链接嗷!`, true)
513
+ }
514
+ }
515
+
516
+ /**
517
+ * 计算等效rks
518
+ * @param {botEvent} e
519
+ */
520
+ async comrks(e) {
521
+
522
+ if (await getBanGroup.get(e, 'comrks')) {
523
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
524
+ return false
525
+ }
526
+
527
+ let msg = e.msg.replace(/^[#/].*(com|计算)\s*/, '')
528
+ let data = msg.split(' ')
529
+ let data0 = Number(data[0])
530
+ let data1 = Number(data[1])
531
+ if (data && data1 && data0 > 0 && data0 <= 18 && data1 > 0 && data1 <= 100) {
532
+ send.send_with_At(e, `dif: ${data0} acc: ${data1}\n计算结果:${fCompute.rks(Number(data1), Number(data0))}`, true)
533
+ return true
534
+ } else {
535
+ send.send_with_At(e, `格式错误QAQ!\n格式:${Config.getUserCfg('config', 'cmdhead')} com <定数> <acc>`)
536
+ return false
537
+ }
538
+ }
539
+
540
+ /**
541
+ * 随机tips
542
+ * @param {botEvent} e
543
+ */
544
+ async tips(e) {
545
+
546
+ if (await getBanGroup.get(e, 'tips')) {
547
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
548
+ return false
549
+ }
550
+
551
+ send.send_with_At(e, getInfo.tips[fCompute.randInt(0, getInfo.tips.length - 1)])
552
+ }
553
+
554
+ /**
555
+ *
556
+ * @param {botEvent} e
557
+ * @returns
558
+ */
559
+ async randClg(e) {
560
+ if (await getBanGroup.get(e, 'randClg')) {
561
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
562
+ return false
563
+ }
564
+
565
+ let songReg = /[\((].*[\))]/
566
+ let arg = e.msg.replace(/^.*?randClg\s*/i, '')
567
+ let songReq = arg.match(songReg)?.[0].replace(/[\(\)()]/g, "") ?? ""
568
+ arg = arg.replace(arg.match(songReg)?.[0] ?? "", "")
569
+
570
+ let songAsk = fCompute.match_request(songReq)
571
+
572
+ // console.info(songAsk, songReq)
573
+
574
+ let { isask, range } = fCompute.match_request(arg, 51)
575
+
576
+ let NumList = []
577
+ for (let i = range[0]; i <= range[1]; i++) {
578
+ NumList.push(i)
579
+ }
580
+
581
+ /**@type {Record<number, Chart[]>} */
582
+ let chartList = {}
583
+ for (let dif of fCompute.objectKeys(getInfo.info_by_difficulty)) {
584
+ if (Number(dif) < range[1]) {
585
+ for (let i in getInfo.info_by_difficulty[dif]) {
586
+ let chart = getInfo.info_by_difficulty[dif][i]
587
+ if (!chart) continue;
588
+ let difficulty = Math.floor(chart.difficulty)
589
+ if (isask[LevelNum[chart.rank]] && chartMatchReq(songAsk, chart)) {
590
+ if (chartList[difficulty]) {
591
+ chartList[difficulty].push(chart)
592
+ } else {
593
+ chartList[difficulty] = [chart]
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+
600
+ NumList = fCompute.randArray(NumList)
601
+
602
+ let shiftNum = NumList.shift()
603
+ if (!shiftNum) {
604
+ send.send_with_At(e, `未找到符合条件的谱面QAQ!`)
605
+ return true;
606
+ }
607
+ let res = undefined;
608
+ while (!res && shiftNum) {
609
+ res = randClg(shiftNum, { ...chartList })
610
+ shiftNum = NumList.shift()
611
+ }
612
+ // console.info(res)
613
+ if (res) {
614
+
615
+ let songs = []
616
+
617
+ let plugin_data = await getNotes.getNotesData(e.user_id)
618
+
619
+ for (let i in res) {
620
+ let info = getInfo.info(res[i].id)
621
+ if (!info) continue;
622
+ songs.push({
623
+ id: info.id,
624
+ song: info.song,
625
+ rank: res[i].rank,
626
+ difficulty: res[i].difficulty,
627
+ illustration: getInfo.getill(info.id),
628
+ ...info.chart[res[i].rank]
629
+ })
630
+ }
631
+
632
+ send.send_with_At(e, await picmodle.common(e, 'clg', {
633
+ songs,
634
+ tot_clg: Math.floor(res[0].difficulty) + Math.floor(res[1].difficulty) + Math.floor(res[2].difficulty),
635
+ background: getInfo.getill(getInfo.illlist[Number((Math.random() * (getInfo.illlist.length - 1)).toFixed(0))], 'blur'),
636
+ theme: plugin_data?.theme || 'star',
637
+ }))
638
+
639
+ // ans += `${getInfo.idgetsong(res[0].id)} ${res[0].rank} ${res[0].difficulty}\n`
640
+ // ans += `${getInfo.idgetsong(res[1].id)} ${res[1].rank} ${res[1].difficulty}\n`
641
+ // ans += `${getInfo.idgetsong(res[2].id)} ${res[2].rank} ${res[2].difficulty}\n`
642
+ // ans += `difficulty: ${Math.floor(res[0].difficulty) + Math.floor(res[1].difficulty) + Math.floor(res[2].difficulty)}`
643
+ } else {
644
+ send.send_with_At(e, `未找到符合条件的谱面QAQ!`)
645
+ }
646
+
647
+ return true;
648
+ }
649
+
650
+ /**
651
+ *
652
+ * @param {botEvent} e
653
+ * @returns
654
+ */
655
+ async newSong(e) {
656
+
657
+ if (await getBanGroup.get(e, 'newSong')) {
658
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
659
+ return false
660
+ }
661
+ /**
662
+ * @type {{ cnt: any; col?: number; row?: number; color?: string; bkg?: string; }[][]}
663
+ */
664
+ const ans = []
665
+ let msg = ''
666
+ try {
667
+ let info = await TapInfo.PgrUpdateInfo();
668
+ msg += `最新版本:${info?.[0]?.version}\n更新信息:\n${info?.[0]?.rawHtml?.replace(/<\/?div>/g, '')?.replace(/<br\/>/g, '\n')}\n`
669
+ } catch (e) { }
670
+ msg += `信息文件版本:${Version.phigros}\n`
671
+ ans.push([{ cnt: '新曲速递', col: 4 }]);
672
+ ans.push([{ cnt: '曲名' }, { cnt: '难度' }, { cnt: '定数' }, { cnt: '物量' }])
673
+ for (let id of getInfo.updatedSong) {
674
+ let info = getInfo.info(id)
675
+ if (!info) continue;
676
+ for (let j of Level) {
677
+ if (Level.indexOf(j) === -1) continue;
678
+ if (!info.chart[j]) continue;
679
+ const bkg = levelColor(j)
680
+ ans.push([{ cnt: info.song }, { cnt: j, bkg }, { cnt: info.chart[j].difficulty, bkg }, { cnt: info.chart[j].combo, bkg }])
681
+ }
682
+ }
683
+
684
+ ans.push([{ cnt: '定数&谱面修改', col: 4 }])
685
+ ans.push([{ cnt: '曲名' }, { cnt: '难度' }, { cnt: '条目' }, { cnt: '情况' }])
686
+ for (let id of fCompute.objectKeys(getInfo.updatedChart)) {
687
+ let tem = getInfo.updatedChart[id]
688
+ for (let level of Level) {
689
+ if (!tem[level]) continue;
690
+ if (tem[level].isNew) {
691
+ delete tem[level].isNew
692
+ for (let objKey of fCompute.objectKeys(tem[level])) {
693
+ const bkg = levelColor(level)
694
+ ans.push([{ cnt: id }, { cnt: level, bkg }, { cnt: objKey.replace('difficulty', '定数'), bkg }, { cnt: tem[level][objKey], bkg }])
695
+ }
696
+ } else {
697
+ for (let objKey of fCompute.objectKeys(tem[level])) {
698
+ if (!Array.isArray(tem[level][objKey])) continue;
699
+ const incr = tem[level][objKey][0] < tem[level][objKey][1]
700
+ const bkg = levelColor(level)
701
+ ans.push([
702
+ { cnt: id },
703
+ { cnt: level, bkg },
704
+ { cnt: objKey.replace('difficulty', '定数'), bkg },
705
+ {
706
+ cnt: `${tem[level][objKey][0]} (${incr ? '+' : '-'}) ${tem[level][objKey][1]}`,
707
+ color: incr ? 'red' : 'green',
708
+ bkg
709
+ }
710
+ ])
711
+ }
712
+ }
713
+ }
714
+ }
715
+
716
+ for (let i = 0; i < ans.length; ++i) {
717
+ for (let j = 0; j <= 0 && j < ans[i].length; ++j) {
718
+
719
+ if (ans[i][j].cnt == ans[i + 1]?.[j]?.cnt && ans[i][j].row !== 0) {
720
+ let k = i;
721
+ while (ans[i][j].cnt == ans[k]?.[j]?.cnt) {
722
+ ans[k][j].row = 0;
723
+ ++k;
724
+ }
725
+ ans[i][j].row = k - i;
726
+ }
727
+ }
728
+ }
729
+
730
+ const newSongImg = await picmodle.common(e, 'newSong', {
731
+ ans,
732
+ background: getInfo.getill(getInfo.illlist[Number((Math.random() * (getInfo.illlist.length - 1)).toFixed(0))], 'blur')
733
+ });
734
+ send.send_with_At(e, [newSongImg, msg]);
735
+ }
736
+
737
+ /**
738
+ *
739
+ * @param {botEvent} e
740
+ * @returns
741
+ */
742
+ async live(e) {
743
+
744
+ if (await getBanGroup.get(e, 'newSong')) {
745
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
746
+ return false
747
+ }
748
+ let ans = '直播速递:\n'
749
+ const info = await makeRequest.liveInfo({ event: e })
750
+ if (info) {
751
+ ans += info;
752
+ } else {
753
+ ans += '发生错误,请稍后再试。'
754
+ }
755
+
756
+ send.send_with_At(e, ans)
757
+ }
758
+
759
+ /**
760
+ *
761
+ * @param {botEvent} e
762
+ * @returns
763
+ */
764
+ async table(e) {
765
+
766
+ if (await getBanGroup.get(e, 'table')) {
767
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
768
+ return false
769
+ }
770
+
771
+ let dif = Number(e.msg.match(/[0-9]+/)?.[0])
772
+
773
+ if (!dif) {
774
+ send.send_with_At(e, `请输入定数嗷!\n/格式:${Config.getUserCfg('config', 'cmdhead')} table <定数>`, true)
775
+ return false
776
+ }
777
+
778
+ if (dif > getInfo.MAX_DIFFICULTY) {
779
+ send.send_with_At(e, `定数已经超过最高的定数${getInfo.MAX_DIFFICULTY}了QAQ!`)
780
+ return false
781
+ }
782
+
783
+ if (dif < 1) {
784
+ send.send_with_At(e, `定数不能小于 1 QAQ!`)
785
+ return false
786
+ }
787
+
788
+ let matchVersion = e.msg.match(/-v\s*(\S+)/i)?.[1];
789
+ let matchVerCode = 0;
790
+ if (matchVersion) {
791
+ if (matchVersion.includes('.')) {
792
+ if (!getInfo.versionInfoByLabel[matchVersion]) {
793
+ send.send_with_At(e, `未找到版本 ${matchVersion} 的相关信息QAQ!`)
794
+ return true
795
+ }
796
+ matchVerCode = getInfo.versionInfoByLabel[matchVersion].version_code
797
+ } else {
798
+ let verCodeNum = Number(matchVersion)
799
+ if (!getInfo.versionInfoByCode[verCodeNum]) {
800
+ send.send_with_At(e, `未找到版本 ${matchVersion} 的相关信息QAQ!`)
801
+ return true
802
+ }
803
+ matchVerCode = verCodeNum
804
+ }
805
+ } else {
806
+ matchVerCode = Version.phigrosVerNum
807
+ }
808
+
809
+ const versionInfo = getInfo.versionInfoByCode[matchVerCode]
810
+ if (!versionInfo) {
811
+ console.error(`[phi-plugin] 版本信息获取失败,versionCode: ${matchVerCode}`);
812
+ send.send_with_At(e, `发生未知错误QAQ!请回报管理员!`)
813
+ return true
814
+ }
815
+
816
+ let pluginData = await getNotes.getNotesData(e.user_id)
817
+ const data = {
818
+ title: {
819
+ difficulty: dif,
820
+ total: 0,
821
+ version: versionInfo.version_label
822
+ },
823
+ /**@type {{difficulty: string, songs: {rank: string, illustration: string}[]}[]} */
824
+ table: [],
825
+ background: getInfo.getill(getInfo.illlist[Math.floor((Math.random() * (getInfo.illlist.length - 1)))], 'blur'),
826
+ theme: pluginData?.theme || 'star'
827
+ }
828
+
829
+ const info_by_difficulty = getInfo.historyDifficultyByVerDifficulty[versionInfo.version_code];
830
+ for (let i = 0; i < 10; ++i) {
831
+ const difStr = Math.round((dif + i * 0.1) * 10) / 10;
832
+ if (!info_by_difficulty[difStr.toFixed(1)]) continue;
833
+ data.title.total += info_by_difficulty[difStr.toFixed(1)].length;
834
+ data.table.push({
835
+ difficulty: difStr.toFixed(1),
836
+ songs: info_by_difficulty[difStr.toFixed(1)]?.map(chart => ({
837
+ rank: chart.rank,
838
+ illustration: getInfo.getill(chart.id, 'low'),
839
+ })) || []
840
+ })
841
+
842
+ }
843
+
844
+ send.send_with_At(e, await picmodle.common(e, 'table', data));
845
+
846
+ }
847
+
848
+ /**
849
+ * /difhis(tory) <song>
850
+ * @param {botEvent} e
851
+ * @returns
852
+ */
853
+ async difHis(e) {
854
+ if (await getBanGroup.get(e, 'table')) {
855
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
856
+ return false
857
+ }
858
+ const songstr = e.msg.replace(fCompute.getRexWithCmdHead('difhis(tory)?'), '')
859
+ this.choseMutiNick(e, getInfo.fuzzysongsnick(songstr), {}, async (e, id) => {
860
+ const difhistory = getInfo.historyDifficultyBySongId[id];
861
+ const verinfo = getInfo.versionInfoByCode;
862
+ if (!difhistory) {
863
+ send.send_with_At(e, `未找到 ${songstr} 的相关历史定数信息QAQ!`)
864
+ return
865
+ }
866
+
867
+ let minDateNum = Infinity;
868
+ let minDateInfo = null;
869
+
870
+ /**@type {Record<levelKind, {version: string, date: string, dateNum: number, difficulty: number }[]>} */
871
+ const hisData = { AT: [], IN: [], HD: [], EZ: [] };
872
+
873
+ for (let v of fCompute.objectKeys(difhistory)) {
874
+ const vinfo = verinfo[v];
875
+ const vdata = difhistory[v];
876
+ if (!vinfo || !vdata) continue;
877
+ for (let l of fCompute.objectKeys(vdata)) {
878
+ hisData[l].push({
879
+ version: vinfo.version_label,
880
+ date: fCompute.formatDate(vinfo.update_date * 1000, 'YYYY-MM-DD'),
881
+ dateNum: vinfo.update_date,
882
+ difficulty: vdata[l],
883
+ })
884
+ if (vinfo.update_date < minDateNum) {
885
+ minDateNum = vinfo.update_date;
886
+ minDateInfo = vinfo;
887
+ }
888
+ }
889
+ }
890
+ /**
891
+ * 折线图数据
892
+ * @type {{color: string, data: {x: number, y: number}[]}[]}
893
+ */
894
+ const lineData = []
895
+
896
+ for (let l of Level) {
897
+ if (!hisData[l].length) continue;
898
+ hisData[l] = hisData[l].sort((a, b) => b.dateNum - a.dateNum);
899
+
900
+ for (let i = hisData[l].length - 1; i > 0; --i) {
901
+ if (i < hisData[l].length - 1 && hisData[l][i].difficulty === hisData[l][i + 1].difficulty) {
902
+ hisData[l].splice(i, 1);
903
+ ++i;
904
+ }
905
+ }
906
+ lineData.push({
907
+ color: levelColor(l).replace('33', ''),
908
+ data: hisData[l].map(d => ({
909
+ x: d.dateNum,
910
+ y: d.difficulty,
911
+ xLabel: 'v' + d.version,
912
+ yLabel: d.difficulty.toFixed(1),
913
+ visX: true,
914
+ visY: true,
915
+ }))
916
+ })
917
+ }
918
+
919
+ const picData = {
920
+ illustration: getInfo.getill(id),
921
+ song: getInfo.info(id)?.song || id,
922
+ updateDate: fCompute.formatDate(minDateNum * 1000, 'YYYY-MM-DD'),
923
+ updateLable: minDateInfo?.version_label || '',
924
+ hisData,
925
+ lineData: JSON.stringify(lineData),
926
+ theme: (await getNotes.getNotesData(e.user_id))?.theme || 'star',
927
+ }
928
+
929
+ send.send_with_At(e, await picmodle.common(e, 'difficultyHistory', picData));
930
+ })
931
+ }
932
+
933
+ /**
934
+ *
935
+ * @param {botEvent} e
936
+ * @returns
937
+ */
938
+ async comment(e) {
939
+
940
+ const credentials = UserCredentials.fromEvent(e)
941
+
942
+ if (await getBanGroup.get(e, 'comment') || !(await Config.getUserCfg('config', 'allowComment'))) {
943
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
944
+ return false
945
+ }
946
+
947
+ let save = await send.getsave_result(e);
948
+
949
+ if (!save) {
950
+ return true
951
+ }
952
+
953
+ const sessionToken = await credentials.getSessionToken()
954
+
955
+ if (!sessionToken) {
956
+ send.send_with_At(e, `请先绑定sessionToken哦!`)
957
+ return true
958
+ }
959
+
960
+ let msg = e.msg.replace(/[#/](.*?)(comment|cmt|评论|评价)(\s*)/, "");
961
+ if (!msg) {
962
+ send.send_with_At(e, `请指定曲名哦!\n格式:\n/${Config.getUserCfg('config', 'cmdhead')} cmt <曲名> <难度?>(换行)\n<内容>`)
963
+ return true
964
+ }
965
+
966
+
967
+ let rankKind =/**@type {any} */(msg.match(/ (EZ|HD|IN|AT|LEGACY)\s*\n/i)?.[1] || '')
968
+ rankKind = rankKind.toUpperCase()
969
+ let rankNum = 0;
970
+ switch (rankKind) {
971
+ case 'EZ':
972
+ rankNum = 0;
973
+ break;
974
+ case 'HD':
975
+ rankNum = 1;
976
+ break;
977
+ case 'IN':
978
+ rankNum = 2;
979
+ break;
980
+ case 'AT':
981
+ rankNum = 3;
982
+ break;
983
+ case 'LGC':
984
+ case 'LEGACY':
985
+ rankNum = 4;
986
+ break;
987
+ default:
988
+ rankNum = -1;
989
+ }
990
+
991
+ let nickname = msg.replace(/( (EZ|HD|IN|AT|LEGACY))?\s*\n[\s\S]*?$/i, '')
992
+
993
+ let id = getInfo.fuzzysongsnick(nickname)?.[0]
994
+
995
+ if (!id) {
996
+ send.send_with_At(e, `未找到${nickname}的相关曲目信息QAQ\n如果想要提供别名的话请访问 /phihelp 中的别名投稿链接嗷!`, true)
997
+ return true;
998
+ }
999
+ let songInfo = getInfo.info(id)
1000
+ if (!songInfo) {
1001
+ logger.error(`[phi-plugin] 评论时获取曲目信息失败,id: ${id}`);
1002
+ send.send_with_At(e, `发生未知错误QAQ!请回报管理员`);
1003
+ return true;
1004
+ }
1005
+ if (!songInfo.sp_vis) {
1006
+ if (!rankKind) {
1007
+ rankKind = 'IN';
1008
+ rankNum = 2;
1009
+ } else if (rankNum == -1) {
1010
+ send.send_with_At(e, `${rankKind} 不是一个难度QAQ!`);
1011
+ return true;
1012
+ } else if (!songInfo.chart?.[allLevel[rankNum]]) {
1013
+ send.send_with_At(e, `${id} 没有 ${allLevel[rankNum]} 这个难度QAQ!`);
1014
+ return true;
1015
+ }
1016
+ } else {
1017
+ rankKind = 'IN';
1018
+ }
1019
+ /** @type {string | undefined} */
1020
+ let comment = msg.match(/\n([\s\S]*)/)?.[1];
1021
+ if (!comment) {
1022
+ send.send_with_At(e, `不可发送空白内容w(゚Д゚)w!`)
1023
+ return true
1024
+ }
1025
+ if (comment.length > 1000) {
1026
+ send.send_with_At(e, `太长了吧!你想干嘛w(゚Д゚)w!`)
1027
+ return true
1028
+ }
1029
+
1030
+ let songId = songInfo.id;
1031
+
1032
+ if (save.apiId && await canUseApi(e)) {
1033
+ const apiUserId = save.apiId
1034
+ /**@type {import("../model/api/makeRequest.js").APIUpdateCommentObject} */
1035
+ let cmtobj = {
1036
+ songId: songInfo.id,
1037
+ rank: rankKind,
1038
+ apiUserId,
1039
+ rks: save.saveInfo.summary.rankingScore,
1040
+ score: 0,
1041
+ acc: 0,
1042
+ fc: false,
1043
+ challenge: save.saveInfo.summary.challengeModeRank,
1044
+ time: new Date().toISOString(),
1045
+ comment: comment
1046
+ };
1047
+ let songRecord = save.getSongsRecord(songId);
1048
+ const record = songRecord?.[rankNum];
1049
+ if (!songInfo.sp_vis && record?.score) {
1050
+ let { phi, b19_list } = await save.getB19(e, 27)
1051
+ let spInfo = '';
1052
+
1053
+ for (let i = 0; i < phi.length; ++i) {
1054
+ const x = phi[i];
1055
+ if (!x) continue;
1056
+ if (x.id == songId && x.rank == rankKind) {
1057
+ spInfo = `Perfect ${i + 1}`;
1058
+ break;
1059
+ }
1060
+ }
1061
+ if (!spInfo && record.score == 1000000) {
1062
+ spInfo = 'All Perfect';
1063
+ }
1064
+ for (let i = 0; i < b19_list.length; ++i) {
1065
+ if (b19_list[i].id == songId && b19_list[i].rank == rankKind) {
1066
+ spInfo = spInfo ? spInfo + ` & Best ${i + 1}` : `Best ${i + 1}`;
1067
+ break;
1068
+ }
1069
+ }
1070
+ cmtobj = {
1071
+ ...cmtobj,
1072
+ score: record.score,
1073
+ acc: record.acc,
1074
+ fc: record.fc,
1075
+ spInfo,
1076
+ }
1077
+ };
1078
+ const apiAddResult = await credentials.addComment(cmtobj)
1079
+ if (apiAddResult) {
1080
+ send.send_with_At(e, `在线评论成功!φ(゜▽゜*)♪`);
1081
+ return true;
1082
+ }
1083
+ }
1084
+ /**@type {import("../model/game/getComment.js").commentObject} */
1085
+ let cmtobj = {
1086
+ sessionToken: save.session,
1087
+ userObjectId: save.saveInfo.objectId,
1088
+ rks: save.saveInfo.summary.rankingScore,
1089
+ rank: rankKind,
1090
+ score: 0,
1091
+ acc: 0,
1092
+ fc: false,
1093
+ challenge: save.saveInfo.summary.challengeModeRank,
1094
+ time: new Date(),
1095
+ comment: comment,
1096
+ spInfo: '',
1097
+ };
1098
+ let songRecord = save.getSongsRecord(songId);
1099
+ const record = songRecord?.[rankNum];
1100
+ if (!songInfo.sp_vis && record?.score) {
1101
+ let { phi, b19_list } = await save.getB19(e, 27)
1102
+ let spInfo = '';
1103
+
1104
+ for (let i = 0; i < phi.length; ++i) {
1105
+ const x = phi[i];
1106
+ if (!x) continue;
1107
+ if (x.id == songId && x.rank == rankKind) {
1108
+ spInfo = `Perfect ${i + 1}`;
1109
+ break;
1110
+ }
1111
+ }
1112
+ if (!spInfo && record.score == 1000000) {
1113
+ spInfo = 'All Perfect';
1114
+ }
1115
+ for (let i = 0; i < b19_list.length; ++i) {
1116
+ if (b19_list[i].id == songId && b19_list[i].rank == rankKind) {
1117
+ spInfo = spInfo ? spInfo + ` & Best ${i + 1}` : `Best ${i + 1}`;
1118
+ break;
1119
+ }
1120
+ }
1121
+ cmtobj = {
1122
+ ...cmtobj,
1123
+ score: record.score,
1124
+ acc: record.acc,
1125
+ fc: record.fc,
1126
+ spInfo,
1127
+ }
1128
+ };
1129
+ if (getComment.add(songId, cmtobj)) {
1130
+ send.send_with_At(e, `评论成功!φ(゜▽゜*)♪`);
1131
+ } else {
1132
+ send.send_with_At(e, `遇到未知错误QAQ!`);
1133
+ }
1134
+
1135
+ return true;
1136
+ }
1137
+
1138
+ /**
1139
+ *
1140
+ * @param {botEvent} e
1141
+ * @returns
1142
+ */
1143
+ async recallComment(e) {
1144
+ const credentials = UserCredentials.fromEvent(e)
1145
+ if (await getBanGroup.get(e, 'recallComment') || !(await Config.getUserCfg('config', 'allowComment'))) {
1146
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
1147
+ return false
1148
+ }
1149
+ let save;
1150
+ const sessionToken = await credentials.getSessionToken()
1151
+ if (!e.isMaster) {
1152
+ save = await send.getsave_result(e);
1153
+ if (!save) {
1154
+ return true;
1155
+ }
1156
+
1157
+ if (!sessionToken) {
1158
+ send.send_with_At(e, `请先绑定sessionToken哦!`)
1159
+ return true
1160
+ }
1161
+ }
1162
+
1163
+ let commentId = e.msg.match(/[0-9]+/)?.[0];
1164
+
1165
+ if (!commentId) {
1166
+ send.send_with_At(e, `请输入评论ID嗷!\n格式:/${Config.getUserCfg('config', 'cmdhead')} recmt <评论ID>`);
1167
+ return true;
1168
+ }
1169
+
1170
+ let comment = getComment.getByCommentId(commentId)
1171
+ if (!comment) {
1172
+ if (await canUseApi(e)) {
1173
+ const delResult = await credentials.deleteComment(commentId)
1174
+ if (delResult) {
1175
+ send.send_with_At(e, `删除在线评论成功!φ(゜▽゜*)♪`);
1176
+ return true;
1177
+ }
1178
+ }
1179
+ send.send_with_At(e, `没有找到ID为${commentId}的评论QAQ!`);
1180
+ return true;
1181
+ }
1182
+
1183
+ if (!e.isMaster && !(comment.sessionToken == sessionToken || comment.userObjectId == save?.saveInfo.objectId)) {
1184
+ send.send_with_At(e, `您没有权限操作这条评论捏(。﹏。)`);
1185
+ return true;
1186
+ }
1187
+
1188
+ getComment.del(commentId) ?
1189
+ send.send_with_At(e, `删除成功!`) :
1190
+ send.send_with_At(e, `删除失败QAQ!`);
1191
+ }
1192
+
1193
+ /**
1194
+ *
1195
+ * @param {botEvent} e
1196
+ * @returns
1197
+ */
1198
+ async myComment(e) {
1199
+ const credentials = UserCredentials.fromEvent(e)
1200
+ if (await getBanGroup.get(e, 'myComment')) {
1201
+ send.send_with_At(e, '这里被管理员禁止使用这个功能了呐QAQ!')
1202
+ return false
1203
+ }
1204
+
1205
+ let save = await send.getsave_result(e);
1206
+
1207
+ if (!save) {
1208
+ return true
1209
+ }
1210
+
1211
+ if ((save.session || save.apiId) && await canUseApi(e)) {
1212
+ const comments = await credentials.getCommentsByUserId()
1213
+ if (comments) {
1214
+
1215
+ if (comments && comments.length > 0) {
1216
+ let msg = `您的评论列表:\nID | 曲目 | 难度 | 内容 | 时间\n`;
1217
+ for (let comment of comments) {
1218
+ msg += `${comment.id} | ${comment.songId} | ${comment.rank} | ${comment.comment} | ${fCompute.formatDate(comment.time)}\n`
1219
+ }
1220
+ send.send_with_At(e, msg);
1221
+ } else {
1222
+ send.send_with_At(e, `您还没有评论哦!`);
1223
+ }
1224
+ return true;
1225
+ }
1226
+ }
1227
+ return false;
1228
+ }
1229
+
1230
+ /**
1231
+ * 获取Phigros最新公告
1232
+ * @param {*} e BotEvent
1233
+ */
1234
+ async newNotice(e) {
1235
+ const info = await TapInfo.PgrTapNotice(1);
1236
+ if (info) {
1237
+ const img = await picmodle.common(e, 'newnotice', info);
1238
+ send.send_with_At(e, img);
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+ /**
1244
+ * 获取歌曲信息图片
1245
+ * @param {number} page
1246
+ * @param {boolean} addComment
1247
+ * @param {idString} id
1248
+ * @param {botEvent} e
1249
+ * @returns
1250
+ */
1251
+ async function songInfo(page, addComment, id, e) {
1252
+ let infoData = getInfo.info(id);
1253
+ /**@type {any} */
1254
+ let data = {
1255
+ ...infoData,
1256
+ comment: undefined,
1257
+ };
1258
+ if (!infoData) {
1259
+ logger.error(`[phi-plugin] songInfo: 未找到id为${id}的歌曲信息`);
1260
+ return `发生未知错误QAQ!请回报管理员!`;
1261
+ }
1262
+ if (await Config.getUserCfg('config', 'allowComment') && (addComment || page)) {
1263
+ /** @type {any[]} */
1264
+ let commentData = [];
1265
+ if (await canUseApi(e)) {
1266
+ commentData = (await makeRequest.getCommentsBySongId(
1267
+ { song_id: infoData.id },
1268
+ { event: e },
1269
+ )) || [];
1270
+ for (const item of commentData) {
1271
+ item.PlayerId = (item.PlayerId && item.PlayerId.length > 15) ? item.PlayerId.slice(0, 12) + '...' : item.PlayerId;
1272
+ item.avatar = getInfo.idgetavatar(item.avatar || '');
1273
+ item.comment = fCompute.convertRichText(item.comment);
1274
+ item.time = fCompute.formatDate(item.time);
1275
+ // @ts-ignore
1276
+ item.thisId = item.thisId || item.id;
1277
+ }
1278
+ } else {
1279
+ commentData = getComment.get(infoData.id);
1280
+ for (let item of commentData) {
1281
+ let save = item.sessionToken ? await getSave.getSaveBySessionToken(item.sessionToken) : null;
1282
+ if (!save) {
1283
+ item.thisId && getComment.del(`${item.thisId}`);
1284
+ commentData.splice(commentData.indexOf(item), 1);
1285
+ continue;
1286
+ }
1287
+ item.PlayerId = save.saveInfo.PlayerId.length > 15 ? save.saveInfo.PlayerId.slice(0, 12) + '...' : save.saveInfo.PlayerId;
1288
+ item.avatar = getInfo.idgetavatar(save.gameuser.avatar);
1289
+ item.comment = fCompute.convertRichText(item.comment);
1290
+ // @ts-ignore
1291
+ item.time = fCompute.formatDate(item.time);
1292
+ }
1293
+ }
1294
+ commentData.sort((a, b) => {
1295
+ return new Date(b.time).getTime() - new Date(a.time).getTime();
1296
+ });
1297
+ if (!page) page = 1
1298
+ let commentsAPage = Config.getUserCfg('config', 'commentsAPage') || 1
1299
+ let maxPage = Math.ceil(commentData.length / commentsAPage)
1300
+ page = Math.max(Math.min(page, maxPage), 1)
1301
+ data = {
1302
+ ...infoData,
1303
+ comment: {
1304
+ command: `当前共有${commentData.length}条评论,第${Math.min(page, maxPage)}页,共${maxPage}页,发送/${Config.getUserCfg('config', 'cmdhead')} cmt <曲名> <定级?>(换行)<内容> 进行评论,-p <页码> 选择页数`,
1305
+ // @ts-ignore
1306
+ list: commentData.slice((commentsAPage * (page - 1)), commentsAPage * page - 1)
1307
+ }
1308
+ };
1309
+ }
1310
+ return await picmodle.common(e, 'atlas', data);
1311
+ }
1312
+
1313
+ /**
1314
+ * RandBetween
1315
+ * @param {number} top 随机值上界
1316
+ */
1317
+ function randbt(top, bottom = 0) {
1318
+ return Math.floor((Math.random() * (top - bottom + 1))) + bottom
1319
+ }
1320
+
1321
+ /**
1322
+ *
1323
+ * @param {number} clgNum
1324
+ * @param {Record<number, Chart[]>} chartList
1325
+ * @returns
1326
+ */
1327
+ function randClg(clgNum, chartList) {
1328
+ let difList = null;
1329
+ let rand1 = [], rand2 = []
1330
+ // console.info(getInfo.MAX_DIFFICULTY)
1331
+ for (let i = 1; i <= Math.min(getInfo.MAX_DIFFICULTY, clgNum - 2); i++) {
1332
+ // console.info(i, chartList[i])
1333
+ if (chartList[i]) {
1334
+ rand1.push(i)
1335
+ rand2.push(i)
1336
+ }
1337
+ }
1338
+ rand1 = fCompute.randArray(rand1);
1339
+ rand2 = fCompute.randArray(rand2);
1340
+ // console.info(clgNum, rand1, rand2)
1341
+ for (let i in rand1) {
1342
+ // console.info(rand1[i])
1343
+ for (let j in rand2) {
1344
+ let a = rand1[i]
1345
+ let b = rand2[j]
1346
+ if (a + b >= clgNum) continue
1347
+ let c = clgNum - a - b
1348
+ /** @type {Record<number, number>} */
1349
+ let tem = {}
1350
+ tem[a] = 1
1351
+ tem[b] ? ++tem[b] : tem[b] = 1
1352
+ tem[c] ? ++tem[c] : tem[c] = 1
1353
+ let flag = false
1354
+ for (let i in tem) {
1355
+ if (!chartList[i] || tem[i] > chartList[i].length) {
1356
+ flag = true
1357
+ break
1358
+ }
1359
+ }
1360
+ if (flag) continue
1361
+ difList = [a, b, c]
1362
+ break;
1363
+ }
1364
+ if (difList) break;
1365
+ }
1366
+ if (!difList) {
1367
+ return;
1368
+ }
1369
+ // console.info(difList)
1370
+ let ans = []
1371
+ for (let i in difList) {
1372
+ if (!chartList[difList[i]]) {
1373
+ logger.error(difList[i], chartList)
1374
+ }
1375
+ let tem = chartList[difList[i]].splice(fCompute.randInt(0, chartList[difList[i]].length - 1), 1)[0]
1376
+ ans.push(tem)
1377
+ }
1378
+ // console.info(clgNum, ans)
1379
+ return ans;
1380
+ }
1381
+
1382
+ /**
1383
+ *
1384
+ * @param {any} ask
1385
+ * @param {Chart} chart
1386
+ * @returns
1387
+ */
1388
+ function chartMatchReq(ask, chart) {
1389
+ if (ask.isask[LevelNum[chart.rank]]) {
1390
+ if (chart.difficulty >= ask.range[0] && chart.difficulty <= ask.range[1]) {
1391
+ return true
1392
+ }
1393
+ }
1394
+ // console.info(ask, chart)
1395
+ return false
1396
+ }
1397
+
1398
+ /**
1399
+ *
1400
+ * @param {levelKind} level
1401
+ * @returns
1402
+ */
1403
+ function levelColor(level) {
1404
+ switch (level) {
1405
+ case 'EZ': {
1406
+ return '#57a80033'
1407
+ }
1408
+ case 'HD': {
1409
+ return '#007fad33'
1410
+ }
1411
+ case 'IN': {
1412
+ return '#ff000033'
1413
+ }
1414
+ case 'AT': {
1415
+ return '#45454533'
1416
+ }
1417
+ }
1418
+ }