@neteasecloudmusicapienhanced/api 4.29.11

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 (412) hide show
  1. package/LICENSE +21 -0
  2. package/README.MD +178 -0
  3. package/app.js +18 -0
  4. package/data/deviceid.txt +24641 -0
  5. package/generateConfig.js +24 -0
  6. package/interface.d.ts +1834 -0
  7. package/main.js +63 -0
  8. package/module/activate_init_profile.js +9 -0
  9. package/module/aidj_content_rcmd.js +28 -0
  10. package/module/album.js +6 -0
  11. package/module/album_detail.js +12 -0
  12. package/module/album_detail_dynamic.js +12 -0
  13. package/module/album_list.js +16 -0
  14. package/module/album_list_style.js +15 -0
  15. package/module/album_new.js +11 -0
  16. package/module/album_newest.js +6 -0
  17. package/module/album_privilege.js +9 -0
  18. package/module/album_songsaleboard.js +19 -0
  19. package/module/album_sub.js +10 -0
  20. package/module/album_sublist.js +11 -0
  21. package/module/api.js +21 -0
  22. package/module/artist_album.js +15 -0
  23. package/module/artist_desc.js +9 -0
  24. package/module/artist_detail.js +10 -0
  25. package/module/artist_detail_dynamic.js +9 -0
  26. package/module/artist_fans.js +11 -0
  27. package/module/artist_follow_count.js +13 -0
  28. package/module/artist_list.js +33 -0
  29. package/module/artist_mv.js +12 -0
  30. package/module/artist_new_mv.js +12 -0
  31. package/module/artist_new_song.js +12 -0
  32. package/module/artist_songs.js +12 -0
  33. package/module/artist_sub.js +11 -0
  34. package/module/artist_sublist.js +11 -0
  35. package/module/artist_top_song.js +8 -0
  36. package/module/artist_video.js +15 -0
  37. package/module/artists.js +6 -0
  38. package/module/audio_match.js +19 -0
  39. package/module/avatar_upload.js +22 -0
  40. package/module/banner.js +16 -0
  41. package/module/batch.js +12 -0
  42. package/module/broadcast_category_region_get.js +11 -0
  43. package/module/broadcast_channel_collect_list.js +12 -0
  44. package/module/broadcast_channel_currentinfo.js +13 -0
  45. package/module/broadcast_channel_list.js +13 -0
  46. package/module/broadcast_sub.js +12 -0
  47. package/module/calendar.js +8 -0
  48. package/module/captcha_sent.js +11 -0
  49. package/module/captcha_verify.js +11 -0
  50. package/module/cellphone_existence_check.js +10 -0
  51. package/module/check_music.js +30 -0
  52. package/module/cloud.js +146 -0
  53. package/module/cloud_import.js +39 -0
  54. package/module/cloud_match.js +13 -0
  55. package/module/cloudsearch.js +13 -0
  56. package/module/comment.js +30 -0
  57. package/module/comment_album.js +16 -0
  58. package/module/comment_dj.js +16 -0
  59. package/module/comment_event.js +15 -0
  60. package/module/comment_floor.js +16 -0
  61. package/module/comment_hot.js +18 -0
  62. package/module/comment_hug_list.js +20 -0
  63. package/module/comment_like.js +20 -0
  64. package/module/comment_music.js +16 -0
  65. package/module/comment_mv.js +16 -0
  66. package/module/comment_new.js +37 -0
  67. package/module/comment_playlist.js +16 -0
  68. package/module/comment_video.js +16 -0
  69. package/module/countries_code_list.js +6 -0
  70. package/module/creator_authinfo_get.js +6 -0
  71. package/module/daily_signin.js +16 -0
  72. package/module/digitalAlbum_detail.js +13 -0
  73. package/module/digitalAlbum_ordering.js +22 -0
  74. package/module/digitalAlbum_purchased.js +15 -0
  75. package/module/digitalAlbum_sales.js +13 -0
  76. package/module/djRadio_top.js +15 -0
  77. package/module/dj_banner.js +6 -0
  78. package/module/dj_category_excludehot.js +10 -0
  79. package/module/dj_category_recommend.js +10 -0
  80. package/module/dj_catelist.js +6 -0
  81. package/module/dj_detail.js +9 -0
  82. package/module/dj_hot.js +10 -0
  83. package/module/dj_paygift.js +15 -0
  84. package/module/dj_personalize_recommend.js +12 -0
  85. package/module/dj_program.js +12 -0
  86. package/module/dj_program_detail.js +9 -0
  87. package/module/dj_program_toplist.js +10 -0
  88. package/module/dj_program_toplist_hours.js +13 -0
  89. package/module/dj_radio_hot.js +11 -0
  90. package/module/dj_recommend.js +6 -0
  91. package/module/dj_recommend_type.js +32 -0
  92. package/module/dj_sub.js +10 -0
  93. package/module/dj_sublist.js +11 -0
  94. package/module/dj_subscriber.js +12 -0
  95. package/module/dj_today_perfered.js +13 -0
  96. package/module/dj_toplist.js +14 -0
  97. package/module/dj_toplist_hours.js +10 -0
  98. package/module/dj_toplist_newcomer.js +9 -0
  99. package/module/dj_toplist_pay.js +9 -0
  100. package/module/dj_toplist_popular.js +10 -0
  101. package/module/eapi_decrypt.js +27 -0
  102. package/module/event.js +10 -0
  103. package/module/event_del.js +9 -0
  104. package/module/event_forward.js +11 -0
  105. package/module/fanscenter_basicinfo_age_get.js +6 -0
  106. package/module/fanscenter_basicinfo_gender_get.js +10 -0
  107. package/module/fanscenter_basicinfo_province_get.js +10 -0
  108. package/module/fanscenter_overview_get.js +6 -0
  109. package/module/fanscenter_trend_list.js +10 -0
  110. package/module/fm_trash.js +11 -0
  111. package/module/follow.js +11 -0
  112. package/module/get_userids.js +7 -0
  113. package/module/history_recommend_songs.js +11 -0
  114. package/module/history_recommend_songs_detail.js +13 -0
  115. package/module/homepage_block_page.js +8 -0
  116. package/module/homepage_dragon_ball.js +10 -0
  117. package/module/hot_topic.js +10 -0
  118. package/module/hug_comment.js +16 -0
  119. package/module/inner_version.js +16 -0
  120. package/module/like.js +13 -0
  121. package/module/likelist.js +9 -0
  122. package/module/listen_data_realtime_report.js +11 -0
  123. package/module/listen_data_report.js +12 -0
  124. package/module/listen_data_today_song.js +9 -0
  125. package/module/listen_data_total.js +9 -0
  126. package/module/listen_data_year_report.js +9 -0
  127. package/module/listentogether_accept.js +13 -0
  128. package/module/listentogether_end.js +9 -0
  129. package/module/listentogether_heatbeat.js +12 -0
  130. package/module/listentogether_play_command.js +21 -0
  131. package/module/listentogether_room_check.js +9 -0
  132. package/module/listentogether_room_create.js +9 -0
  133. package/module/listentogether_status.js +10 -0
  134. package/module/listentogether_sync_list_command.js +26 -0
  135. package/module/listentogether_sync_playlist_get.js +13 -0
  136. package/module/login.js +41 -0
  137. package/module/login_cellphone.js +40 -0
  138. package/module/login_qr_check.js +29 -0
  139. package/module/login_qr_create.js +30 -0
  140. package/module/login_qr_key.js +19 -0
  141. package/module/login_refresh.js +21 -0
  142. package/module/login_status.js +21 -0
  143. package/module/logout.js +6 -0
  144. package/module/lyric.js +14 -0
  145. package/module/lyric_new.js +17 -0
  146. package/module/mlog_music_rcmd.js +13 -0
  147. package/module/mlog_to_video.js +13 -0
  148. package/module/mlog_url.js +11 -0
  149. package/module/msg_comments.js +17 -0
  150. package/module/msg_forwards.js +11 -0
  151. package/module/msg_notices.js +10 -0
  152. package/module/msg_private.js +11 -0
  153. package/module/msg_private_history.js +12 -0
  154. package/module/msg_recentcontact.js +11 -0
  155. package/module/music_first_listen_info.js +13 -0
  156. package/module/musician_cloudbean.js +7 -0
  157. package/module/musician_cloudbean_obtain.js +14 -0
  158. package/module/musician_data_overview.js +11 -0
  159. package/module/musician_play_trend.js +14 -0
  160. package/module/musician_sign.js +7 -0
  161. package/module/musician_tasks.js +11 -0
  162. package/module/musician_tasks_new.js +11 -0
  163. package/module/mv_all.js +16 -0
  164. package/module/mv_detail.js +9 -0
  165. package/module/mv_detail_info.js +14 -0
  166. package/module/mv_exclusive_rcmd.js +10 -0
  167. package/module/mv_first.js +12 -0
  168. package/module/mv_sub.js +11 -0
  169. package/module/mv_sublist.js +15 -0
  170. package/module/mv_url.js +14 -0
  171. package/module/nickname_check.js +7 -0
  172. package/module/personal_fm.js +6 -0
  173. package/module/personal_fm_mode.js +14 -0
  174. package/module/personalized.js +16 -0
  175. package/module/personalized_djprogram.js +10 -0
  176. package/module/personalized_mv.js +6 -0
  177. package/module/personalized_newsong.js +15 -0
  178. package/module/personalized_privatecontent.js +10 -0
  179. package/module/personalized_privatecontent_list.js +15 -0
  180. package/module/pl_count.js +6 -0
  181. package/module/playlist_category_list.js +11 -0
  182. package/module/playlist_catlist.js +6 -0
  183. package/module/playlist_cover_update.js +32 -0
  184. package/module/playlist_create.js +11 -0
  185. package/module/playlist_delete.js +9 -0
  186. package/module/playlist_desc_update.js +10 -0
  187. package/module/playlist_detail.js +11 -0
  188. package/module/playlist_detail_dynamic.js +11 -0
  189. package/module/playlist_detail_rcmd_get.js +11 -0
  190. package/module/playlist_highquality_tags.js +10 -0
  191. package/module/playlist_hot.js +6 -0
  192. package/module/playlist_import_name_task_create.js +62 -0
  193. package/module/playlist_import_task_status.js +11 -0
  194. package/module/playlist_mylike.js +12 -0
  195. package/module/playlist_name_update.js +10 -0
  196. package/module/playlist_order_update.js +13 -0
  197. package/module/playlist_privacy.js +10 -0
  198. package/module/playlist_subscribe.js +14 -0
  199. package/module/playlist_subscribers.js +11 -0
  200. package/module/playlist_tags_update.js +10 -0
  201. package/module/playlist_track_add.js +16 -0
  202. package/module/playlist_track_all.js +31 -0
  203. package/module/playlist_track_delete.js +20 -0
  204. package/module/playlist_tracks.js +45 -0
  205. package/module/playlist_update.js +13 -0
  206. package/module/playlist_update_playcount.js +9 -0
  207. package/module/playlist_video_recent.js +9 -0
  208. package/module/playmode_intelligence_list.js +13 -0
  209. package/module/playmode_song_vector.js +8 -0
  210. package/module/program_recommend.js +15 -0
  211. package/module/rebind.js +16 -0
  212. package/module/recent_listen_list.js +7 -0
  213. package/module/recommend_resource.js +10 -0
  214. package/module/recommend_songs.js +11 -0
  215. package/module/recommend_songs_dislike.js +14 -0
  216. package/module/record_recent_album.js +11 -0
  217. package/module/record_recent_dj.js +11 -0
  218. package/module/record_recent_playlist.js +11 -0
  219. package/module/record_recent_song.js +11 -0
  220. package/module/record_recent_video.js +11 -0
  221. package/module/record_recent_voice.js +11 -0
  222. package/module/register_anonimous.js +52 -0
  223. package/module/register_cellphone.js +15 -0
  224. package/module/related_allvideo.js +14 -0
  225. package/module/related_playlist.js +32 -0
  226. package/module/resource_like.js +14 -0
  227. package/module/scrobble.js +26 -0
  228. package/module/search.js +21 -0
  229. package/module/search_default.js +6 -0
  230. package/module/search_hot.js +9 -0
  231. package/module/search_hot_detail.js +6 -0
  232. package/module/search_match.js +18 -0
  233. package/module/search_multimatch.js +14 -0
  234. package/module/search_suggest.js +14 -0
  235. package/module/send_album.js +12 -0
  236. package/module/send_playlist.js +12 -0
  237. package/module/send_song.js +12 -0
  238. package/module/send_text.js +11 -0
  239. package/module/setting.js +7 -0
  240. package/module/share_resource.js +11 -0
  241. package/module/sheet_list.js +9 -0
  242. package/module/sheet_preview.js +8 -0
  243. package/module/sign_happy_info.js +5 -0
  244. package/module/signin_progress.js +13 -0
  245. package/module/simi_artist.js +12 -0
  246. package/module/simi_mv.js +9 -0
  247. package/module/simi_playlist.js +15 -0
  248. package/module/simi_song.js +15 -0
  249. package/module/simi_user.js +11 -0
  250. package/module/song_chorus.js +11 -0
  251. package/module/song_detail.js +11 -0
  252. package/module/song_downlist.js +11 -0
  253. package/module/song_download_url.js +10 -0
  254. package/module/song_download_url_v1.js +13 -0
  255. package/module/song_dynamic_cover.js +9 -0
  256. package/module/song_like_check.js +9 -0
  257. package/module/song_lyrics_mark.js +9 -0
  258. package/module/song_lyrics_mark_add.js +12 -0
  259. package/module/song_lyrics_mark_del.js +9 -0
  260. package/module/song_lyrics_mark_user_page.js +14 -0
  261. package/module/song_monthdownlist.js +11 -0
  262. package/module/song_music_detail.js +9 -0
  263. package/module/song_order_update.js +12 -0
  264. package/module/song_purchased.js +14 -0
  265. package/module/song_red_count.js +9 -0
  266. package/module/song_singledownlist.js +11 -0
  267. package/module/song_url.js +26 -0
  268. package/module/song_url_match.js +35 -0
  269. package/module/song_url_ncmget.js +75 -0
  270. package/module/song_url_unblock.js +35 -0
  271. package/module/song_url_v1.js +54 -0
  272. package/module/song_wiki_summary.js +8 -0
  273. package/module/starpick_comments_summary.js +12 -0
  274. package/module/style_album.js +16 -0
  275. package/module/style_artist.js +16 -0
  276. package/module/style_detail.js +9 -0
  277. package/module/style_list.js +7 -0
  278. package/module/style_playlist.js +16 -0
  279. package/module/style_preference.js +11 -0
  280. package/module/style_song.js +12 -0
  281. package/module/summary_annual.js +12 -0
  282. package/module/threshold_detail_get.js +10 -0
  283. package/module/top_album.js +22 -0
  284. package/module/top_artists.js +11 -0
  285. package/module/top_list.js +20 -0
  286. package/module/top_mv.js +12 -0
  287. package/module/top_playlist.js +22 -0
  288. package/module/top_playlist_highquality.js +16 -0
  289. package/module/top_song.js +16 -0
  290. package/module/topic_detail.js +7 -0
  291. package/module/topic_detail_event_hot.js +7 -0
  292. package/module/topic_sublist.js +11 -0
  293. package/module/toplist.js +6 -0
  294. package/module/toplist_artist.js +12 -0
  295. package/module/toplist_detail.js +6 -0
  296. package/module/toplist_detail_v2.js +6 -0
  297. package/module/ugc_album_get.js +8 -0
  298. package/module/ugc_artist_get.js +8 -0
  299. package/module/ugc_artist_search.js +10 -0
  300. package/module/ugc_detail.js +17 -0
  301. package/module/ugc_mv_get.js +8 -0
  302. package/module/ugc_song_get.js +8 -0
  303. package/module/ugc_user_devote.js +6 -0
  304. package/module/user_account.js +5 -0
  305. package/module/user_audio.js +9 -0
  306. package/module/user_binding.js +9 -0
  307. package/module/user_bindingcellphone.js +15 -0
  308. package/module/user_cloud.js +10 -0
  309. package/module/user_cloud_del.js +9 -0
  310. package/module/user_cloud_detail.js +10 -0
  311. package/module/user_comment_history.js +15 -0
  312. package/module/user_detail.js +15 -0
  313. package/module/user_detail_new.js +20 -0
  314. package/module/user_dj.js +14 -0
  315. package/module/user_event.js +12 -0
  316. package/module/user_follow_mixed.js +23 -0
  317. package/module/user_followeds.js +17 -0
  318. package/module/user_follows.js +15 -0
  319. package/module/user_level.js +7 -0
  320. package/module/user_medal.js +11 -0
  321. package/module/user_mutualfollow_get.js +9 -0
  322. package/module/user_playlist.js +12 -0
  323. package/module/user_record.js +10 -0
  324. package/module/user_replacephone.js +14 -0
  325. package/module/user_social_status.js +11 -0
  326. package/module/user_social_status_edit.js +16 -0
  327. package/module/user_social_status_rcmd.js +5 -0
  328. package/module/user_social_status_support.js +5 -0
  329. package/module/user_subcount.js +6 -0
  330. package/module/user_update.js +15 -0
  331. package/module/verify_getQr.js +39 -0
  332. package/module/verify_qrcodestatus.js +12 -0
  333. package/module/video_category_list.js +15 -0
  334. package/module/video_detail.js +13 -0
  335. package/module/video_detail_info.js +14 -0
  336. package/module/video_group.js +16 -0
  337. package/module/video_group_list.js +11 -0
  338. package/module/video_sub.js +14 -0
  339. package/module/video_timeline_all.js +17 -0
  340. package/module/video_timeline_recommend.js +13 -0
  341. package/module/video_url.js +10 -0
  342. package/module/vip_growthpoint.js +11 -0
  343. package/module/vip_growthpoint_details.js +14 -0
  344. package/module/vip_growthpoint_get.js +13 -0
  345. package/module/vip_info.js +12 -0
  346. package/module/vip_info_v2.js +12 -0
  347. package/module/vip_tasks.js +11 -0
  348. package/module/vip_timemachine.js +17 -0
  349. package/module/voice_delete.js +7 -0
  350. package/module/voice_detail.js +7 -0
  351. package/module/voice_lyric.js +7 -0
  352. package/module/voice_upload.js +186 -0
  353. package/module/voicelist_detail.js +11 -0
  354. package/module/voicelist_list.js +13 -0
  355. package/module/voicelist_list_search.js +14 -0
  356. package/module/voicelist_search.js +14 -0
  357. package/module/voicelist_trans.js +15 -0
  358. package/module/weblog.js +10 -0
  359. package/module/yunbei.js +6 -0
  360. package/module/yunbei_expense.js +8 -0
  361. package/module/yunbei_info.js +5 -0
  362. package/module/yunbei_rcmd_song.js +17 -0
  363. package/module/yunbei_rcmd_song_history.js +16 -0
  364. package/module/yunbei_receipt.js +8 -0
  365. package/module/yunbei_sign.js +5 -0
  366. package/module/yunbei_task_finish.js +12 -0
  367. package/module/yunbei_tasks.js +9 -0
  368. package/module/yunbei_tasks_todo.js +9 -0
  369. package/module/yunbei_today.js +5 -0
  370. package/package.json +104 -0
  371. package/plugins/songUpload.js +61 -0
  372. package/plugins/upload.js +37 -0
  373. package/public/api.html +127 -0
  374. package/public/audio_match_demo/afp.js +1627 -0
  375. package/public/audio_match_demo/afp.wasm.js +5 -0
  376. package/public/audio_match_demo/index.html +199 -0
  377. package/public/audio_match_demo/rec.js +49 -0
  378. package/public/avatar_update.html +73 -0
  379. package/public/cloud.html +104 -0
  380. package/public/docs/.nojekyll +0 -0
  381. package/public/docs/_coverpage.md +13 -0
  382. package/public/docs/favicon.ico +0 -0
  383. package/public/docs/home.md +4857 -0
  384. package/public/docs/icon.png +0 -0
  385. package/public/docs/index.html +47 -0
  386. package/public/docs/ncmapireborn.png +0 -0
  387. package/public/docs/sw.js +90 -0
  388. package/public/eapi_decrypt.html +77 -0
  389. package/public/home.html +41 -0
  390. package/public/index.html +313 -0
  391. package/public/listen_together_host.html +324 -0
  392. package/public/login.html +47 -0
  393. package/public/playlist_cover_update.html +77 -0
  394. package/public/playlist_import.html +262 -0
  395. package/public/qrlogin-nocookie.html +72 -0
  396. package/public/qrlogin.html +71 -0
  397. package/public/static/docs.png +0 -0
  398. package/public/static/eapi_params.png +0 -0
  399. package/public/static/eapi_response.png +0 -0
  400. package/public/static/screenshot1.png +0 -0
  401. package/public/unblock_test.html +123 -0
  402. package/public/voice_upload.html +128 -0
  403. package/server.js +366 -0
  404. package/util/apicache.js +833 -0
  405. package/util/client-sign.js +169 -0
  406. package/util/config.json +20 -0
  407. package/util/crypto.js +135 -0
  408. package/util/index.js +159 -0
  409. package/util/logger.js +29 -0
  410. package/util/memory-cache.js +71 -0
  411. package/util/option.js +14 -0
  412. package/util/request.js +364 -0
@@ -0,0 +1,169 @@
1
+ const crypto = require("crypto");
2
+ const os = require("os");
3
+
4
+ class AdvancedClientSignGenerator {
5
+ /**
6
+ * 获取本机MAC地址
7
+ */
8
+ static getRealMacAddress() {
9
+ try {
10
+ const interfaces = os.networkInterfaces();
11
+ for (let interfaceName in interfaces) {
12
+ const interface = interfaces[interfaceName];
13
+ for (let i = 0; i < interface.length; i++) {
14
+ const alias = interface[i];
15
+ // 排除内部地址和无效地址
16
+ if (
17
+ alias.mac &&
18
+ alias.mac !== "00:00:00:00:00:00" &&
19
+ !alias.internal
20
+ ) {
21
+ return alias.mac.toUpperCase();
22
+ }
23
+ }
24
+ }
25
+ return null;
26
+ } catch (error) {
27
+ console.warn("获取MAC地址失败:", error.message);
28
+ return null;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * 生成随机MAC地址
34
+ */
35
+ static generateRandomMac() {
36
+ const chars = "0123456789ABCDEF";
37
+ let mac = "";
38
+ for (let i = 0; i < 6; i++) {
39
+ if (i > 0) mac += ":";
40
+ mac +=
41
+ chars[Math.floor(Math.random() * 16)] +
42
+ chars[Math.floor(Math.random() * 16)];
43
+ }
44
+ // 确保第一个字节是单播地址(最低位为0)
45
+ const firstByte = parseInt(mac.substring(0, 2), 16);
46
+ const unicastFirstByte = (firstByte & 0xfe)
47
+ .toString(16)
48
+ .padStart(2, "0")
49
+ .toUpperCase();
50
+ return unicastFirstByte + mac.substring(2);
51
+ }
52
+
53
+ /**
54
+ * 获取MAC地址(优先真实,否则随机)
55
+ */
56
+ static getMacAddress() {
57
+ const realMac = this.getRealMacAddress();
58
+ if (realMac) {
59
+ return realMac;
60
+ }
61
+ console.warn("无法获取真实MAC地址,使用随机生成");
62
+ return this.generateRandomMac();
63
+ }
64
+
65
+ /**
66
+ * 字符串转HEX编码
67
+ */
68
+ static stringToHex(str) {
69
+ return Buffer.from(str, "utf8").toString("hex").toUpperCase();
70
+ }
71
+
72
+ /**
73
+ * SHA-256哈希
74
+ */
75
+ static sha256(data) {
76
+ return crypto.createHash("sha256").update(data, "utf8").digest("hex");
77
+ }
78
+
79
+ /**
80
+ * 生成随机设备ID
81
+ */
82
+ static generateRandomDeviceId() {
83
+ const partLengths = [4, 4, 4, 4, 4, 4, 4, 5]; // 各部分长度
84
+ const chars = "0123456789ABCDEF";
85
+
86
+ const parts = partLengths.map((length) => {
87
+ let part = "";
88
+ for (let i = 0; i < length; i++) {
89
+ part += chars[Math.floor(Math.random() * 16)];
90
+ }
91
+ return part;
92
+ });
93
+
94
+ return parts.join("_");
95
+ }
96
+
97
+ /**
98
+ * 生成随机clientSign(优先使用真实MAC,否则随机)
99
+ */
100
+ static generateRandomClientSign(secretKey = "") {
101
+ // 获取MAC地址(优先真实,否则随机)
102
+ const macAddress = this.getMacAddress();
103
+
104
+ // 生成随机设备ID
105
+ const deviceId = this.generateRandomDeviceId();
106
+
107
+ // 转换设备ID为HEX
108
+ const hexDeviceId = this.stringToHex(deviceId);
109
+
110
+ // 构造签名字符串
111
+ const signString = `${macAddress}@@@${hexDeviceId}`;
112
+
113
+ // 生成哈希
114
+ const hash = this.sha256(signString + secretKey);
115
+
116
+ return `${signString}@@@@@@${hash}`;
117
+ }
118
+
119
+ /**
120
+ * 批量生成多个随机签名
121
+ */
122
+ static generateMultipleRandomSigns(count, secretKey = "") {
123
+ const signs = [];
124
+ for (let i = 0; i < count; i++) {
125
+ signs.push(this.generateRandomClientSign(secretKey));
126
+ }
127
+ return signs;
128
+ }
129
+
130
+ /**
131
+ * 使用指定参数生成签名
132
+ */
133
+ static generateWithCustomDeviceId(macAddress, deviceId, secretKey = "") {
134
+ const hexDeviceId = this.stringToHex(deviceId);
135
+ const signString = `${macAddress}@@@${hexDeviceId}`;
136
+ const hash = this.sha256(signString + secretKey);
137
+ return `${signString}@@@@@@${hash}`;
138
+ }
139
+
140
+ /**
141
+ * 验证签名格式是否正确
142
+ */
143
+ static validateClientSign(clientSign) {
144
+ try {
145
+ const parts = clientSign.split("@@@@@@");
146
+ if (parts.length !== 2) return false;
147
+
148
+ const [infoPart, hash] = parts;
149
+ const infoParts = infoPart.split("@@@");
150
+ if (infoParts.length !== 2) return false;
151
+
152
+ const [mac, hexDeviceId] = infoParts;
153
+
154
+ // 验证MAC地址格式
155
+ const macRegex = /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/;
156
+ if (!macRegex.test(mac)) return false;
157
+
158
+ // 验证哈希格式
159
+ const hashRegex = /^[0-9a-f]{64}$/;
160
+ if (!hashRegex.test(hash)) return false;
161
+
162
+ return true;
163
+ } catch (error) {
164
+ return false;
165
+ }
166
+ }
167
+ }
168
+
169
+ module.exports = AdvancedClientSignGenerator;
@@ -0,0 +1,20 @@
1
+ {
2
+ "resourceTypeMap": {
3
+ "0": "R_SO_4_",
4
+ "1": "R_MV_5_",
5
+ "2": "A_PL_0_",
6
+ "3": "R_AL_3_",
7
+ "4": "A_DJ_1_",
8
+ "5": "R_VI_62_",
9
+ "6": "A_EV_2_",
10
+ "7": "A_DR_14_"
11
+ },
12
+ "APP_CONF": {
13
+ "apiDomain": "https://interface.music.163.com",
14
+ "domain": "https://music.163.com",
15
+ "encrypt": true,
16
+ "encryptResponse": false,
17
+ "clientSign": "18:C0:4D:B9:8F:FE@@@453832335F384641365F424635335F303030315F303031425F343434415F343643365F333638332@@@@@@6ff673ef74955b38bce2fa8562d95c976ed4758b1227c4e9ee345987cee17bc9",
18
+ "checkToken": "9ca17ae2e6ffcda170e2e6ee8af14fbabdb988f225b3868eb2c15a879b9a83d274a790ac8ff54a97b889d5d42af0feaec3b92af58cff99c470a7eafd88f75e839a9ea7c14e909da883e83fb692a3abdb6b92adee9e"
19
+ }
20
+ }
package/util/crypto.js ADDED
@@ -0,0 +1,135 @@
1
+ const CryptoJS = require('crypto-js')
2
+ const forge = require('node-forge')
3
+ const iv = '0102030405060708'
4
+ const presetKey = '0CoJUm6Qyw8W8jud'
5
+ const linuxapiKey = 'rFgB&h#%2?^eDg:Q'
6
+ const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
7
+ const publicKey = `-----BEGIN PUBLIC KEY-----
8
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB
9
+ -----END PUBLIC KEY-----`
10
+ const eapiKey = 'e82ckenh8dichen8'
11
+
12
+ const aesEncrypt = (text, mode, key, iv, format = 'base64') => {
13
+ let encrypted = CryptoJS.AES.encrypt(
14
+ CryptoJS.enc.Utf8.parse(text),
15
+ CryptoJS.enc.Utf8.parse(key),
16
+ {
17
+ iv: CryptoJS.enc.Utf8.parse(iv),
18
+ mode: CryptoJS.mode[mode.toUpperCase()],
19
+ padding: CryptoJS.pad.Pkcs7,
20
+ },
21
+ )
22
+ if (format === 'base64') {
23
+ return encrypted.toString()
24
+ }
25
+
26
+ return encrypted.ciphertext.toString().toUpperCase()
27
+ }
28
+ const aesDecrypt = (ciphertext, key, iv, format = 'base64') => {
29
+ let bytes
30
+ if (format === 'base64') {
31
+ bytes = CryptoJS.AES.decrypt(ciphertext, CryptoJS.enc.Utf8.parse(key), {
32
+ iv: CryptoJS.enc.Utf8.parse(iv),
33
+ mode: CryptoJS.mode.ECB,
34
+ padding: CryptoJS.pad.Pkcs7,
35
+ })
36
+ } else {
37
+ bytes = CryptoJS.AES.decrypt(
38
+ { ciphertext: CryptoJS.enc.Hex.parse(ciphertext) },
39
+ CryptoJS.enc.Utf8.parse(key),
40
+ {
41
+ iv: CryptoJS.enc.Utf8.parse(iv),
42
+ mode: CryptoJS.mode.ECB,
43
+ padding: CryptoJS.pad.Pkcs7,
44
+ },
45
+ )
46
+ }
47
+ return bytes.toString(CryptoJS.enc.Utf8)
48
+ }
49
+ const rsaEncrypt = (str, key) => {
50
+ const forgePublicKey = forge.pki.publicKeyFromPem(key)
51
+ const encrypted = forgePublicKey.encrypt(str, 'NONE')
52
+ return forge.util.bytesToHex(encrypted)
53
+ }
54
+
55
+ const weapi = (object) => {
56
+ const text = JSON.stringify(object)
57
+ let secretKey = ''
58
+ for (let i = 0; i < 16; i++) {
59
+ secretKey += base62.charAt(Math.round(Math.random() * 61))
60
+ }
61
+ return {
62
+ params: aesEncrypt(
63
+ aesEncrypt(text, 'cbc', presetKey, iv),
64
+ 'cbc',
65
+ secretKey,
66
+ iv,
67
+ ),
68
+ encSecKey: rsaEncrypt(secretKey.split('').reverse().join(''), publicKey),
69
+ }
70
+ }
71
+
72
+ const linuxapi = (object) => {
73
+ const text = JSON.stringify(object)
74
+ return {
75
+ eparams: aesEncrypt(text, 'ecb', linuxapiKey, '', 'hex'),
76
+ }
77
+ }
78
+
79
+ const eapi = (url, object) => {
80
+ const text = typeof object === 'object' ? JSON.stringify(object) : object
81
+ const message = `nobody${url}use${text}md5forencrypt`
82
+ const digest = CryptoJS.MD5(message).toString()
83
+ const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}`
84
+ return {
85
+ params: aesEncrypt(data, 'ecb', eapiKey, '', 'hex'),
86
+ }
87
+ }
88
+ const eapiResDecrypt = (encryptedParams) => {
89
+ // 使用aesDecrypt解密参数
90
+ try {
91
+ const decryptedData = aesDecrypt(encryptedParams, eapiKey, '', 'hex')
92
+ return JSON.parse(decryptedData)
93
+ } catch (error) {
94
+ console.log('eapiResDecrypt error:', error)
95
+ return null
96
+ }
97
+ }
98
+ const eapiReqDecrypt = (encryptedParams) => {
99
+ // 使用aesDecrypt解密参数
100
+ const decryptedData = aesDecrypt(encryptedParams, eapiKey, '', 'hex')
101
+ // 使用正则表达式解析出URL和数据
102
+ const match = decryptedData.match(/(.*?)-36cd479b6b5-(.*?)-36cd479b6b5-(.*)/)
103
+ if (match) {
104
+ const url = match[1]
105
+ const data = JSON.parse(match[2])
106
+ return { url, data }
107
+ }
108
+
109
+ // 如果没有匹配到,返回null
110
+ return null
111
+ }
112
+ const decrypt = (cipher) => {
113
+ const decipher = CryptoJS.AES.decrypt(
114
+ {
115
+ ciphertext: CryptoJS.enc.Hex.parse(cipher),
116
+ },
117
+ eapiKey,
118
+ {
119
+ mode: CryptoJS.mode.ECB,
120
+ },
121
+ )
122
+ const decryptedBytes = CryptoJS.enc.Utf8.stringify(decipher)
123
+ return decryptedBytes
124
+ }
125
+
126
+ module.exports = {
127
+ weapi,
128
+ linuxapi,
129
+ eapi,
130
+ decrypt,
131
+ aesEncrypt,
132
+ aesDecrypt,
133
+ eapiReqDecrypt,
134
+ eapiResDecrypt,
135
+ }
package/util/index.js ADDED
@@ -0,0 +1,159 @@
1
+ const logger = require('./logger')
2
+ // 预先定义常量和函数引用
3
+ const chinaIPPrefixes = [
4
+ '116.25',
5
+ '116.76',
6
+ '116.77',
7
+ '116.78',
8
+ '116.79',
9
+ '116.80',
10
+ '116.81',
11
+ '116.82',
12
+ '116.83',
13
+ '116.84',
14
+ '116.85',
15
+ '116.86',
16
+ '116.87',
17
+ '116.88',
18
+ '116.89',
19
+ '116.90',
20
+ '116.91',
21
+ '116.92',
22
+ '116.93',
23
+ '116.94',
24
+ ]
25
+ const prefixesLength = chinaIPPrefixes.length
26
+ const floor = Math.floor
27
+ const random = Math.random
28
+ const keys = Object.keys
29
+
30
+ // 预编译encodeURIComponent以减少查找开销
31
+ const encode = encodeURIComponent
32
+
33
+ module.exports = {
34
+ toBoolean(val) {
35
+ if (typeof val === 'boolean') return val
36
+ if (val === '') return val
37
+ return val === 'true' || val == '1'
38
+ },
39
+
40
+ cookieToJson(cookie) {
41
+ if (!cookie) return {}
42
+ let cookieArr = cookie.split(';')
43
+ let obj = {}
44
+
45
+ // 优化:使用for循环替代forEach,性能更好
46
+ for (let i = 0, len = cookieArr.length; i < len; i++) {
47
+ let item = cookieArr[i]
48
+ let arr = item.split('=')
49
+ // 优化:使用严格等于
50
+ if (arr.length === 2) {
51
+ obj[arr[0].trim()] = arr[1].trim()
52
+ }
53
+ }
54
+ return obj
55
+ },
56
+
57
+ cookieObjToString(cookie) {
58
+ // 优化:使用预绑定的keys函数和for循环
59
+ const cookieKeys = keys(cookie)
60
+ const result = []
61
+
62
+ // 优化:使用for循环和预分配数组
63
+ for (let i = 0, len = cookieKeys.length; i < len; i++) {
64
+ const key = cookieKeys[i]
65
+ result[i] = `${encode(key)}=${encode(cookie[key])}`
66
+ }
67
+
68
+ return result.join('; ')
69
+ },
70
+
71
+ getRandom(num) {
72
+ // 优化:简化随机数生成逻辑
73
+ // 原逻辑看起来有问题,这里保持原意但优化性能
74
+ var randomValue = random()
75
+ var floorValue = floor(randomValue * 9 + 1)
76
+ var powValue = Math.pow(10, num - 1)
77
+ var randomNum = floor((randomValue + floorValue) * powValue)
78
+ return randomNum
79
+ },
80
+
81
+ generateRandomChineseIP() {
82
+ // 优化:使用预绑定的函数和常量
83
+ const randomPrefix = chinaIPPrefixes[floor(random() * prefixesLength)]
84
+ const returns = `${randomPrefix}.${generateIPSegment()}.${generateIPSegment()}`
85
+ logger.info('Generated Random Chinese IP:', returns)
86
+ return returns
87
+ },
88
+ // 生成chainId的函数
89
+ generateChainId(cookie) {
90
+ const version = 'v1'
91
+ const randomNum = Math.floor(Math.random() * 1e6)
92
+ const deviceId =
93
+ getCookieValue(cookie, 'sDeviceId') || 'unknown-' + randomNum
94
+ const platform = 'web'
95
+ const action = 'login'
96
+ const timestamp = Date.now()
97
+
98
+ return `${version}_${deviceId}_${platform}_${action}_${timestamp}`
99
+ },
100
+
101
+ generateDeviceId() {
102
+ const hexChars = '0123456789ABCDEF'
103
+ const chars = []
104
+ for (let i = 0; i < 52; i++) {
105
+ const randomIndex = Math.floor(Math.random() * hexChars.length)
106
+ chars.push(hexChars[randomIndex])
107
+ }
108
+ return chars.join('')
109
+ },
110
+ }
111
+
112
+ // 优化:预先绑定函数
113
+ function getRandomInt(min, max) {
114
+ // 优化:简化计算
115
+ return floor(random() * (max - min + 1)) + min
116
+ }
117
+
118
+ // 优化:预先绑定generateIPSegment函数引用
119
+ function generateIPSegment() {
120
+ // 优化:内联常量
121
+ return getRandomInt(1, 255)
122
+ }
123
+
124
+ // 进一步优化版本(如果需要更高性能):
125
+ /*
126
+ const cookieToJsonOptimized = (function() {
127
+ // 预编译trim函数
128
+ const trim = String.prototype.trim
129
+
130
+ return function(cookie) {
131
+ if (!cookie) return {}
132
+
133
+ const cookieArr = cookie.split(';')
134
+ const obj = {}
135
+
136
+ for (let i = 0, len = cookieArr.length; i < len; i++) {
137
+ const item = cookieArr[i]
138
+ const eqIndex = item.indexOf('=')
139
+
140
+ if (eqIndex > 0 && eqIndex < item.length - 1) {
141
+ const key = trim.call(item.substring(0, eqIndex))
142
+ const value = trim.call(item.substring(eqIndex + 1))
143
+ obj[key] = value
144
+ }
145
+ }
146
+ return obj
147
+ }
148
+ })()
149
+ */
150
+
151
+ // 用于从cookie字符串中获取指定值的辅助函数
152
+ function getCookieValue(cookieStr, name) {
153
+ if (!cookieStr) return ''
154
+
155
+ const cookies = '; ' + cookieStr
156
+ const parts = cookies.split('; ' + name + '=')
157
+ if (parts.length === 2) return parts.pop().split(';').shift()
158
+ return ''
159
+ }
package/util/logger.js ADDED
@@ -0,0 +1,29 @@
1
+ // ANSI 颜色代码
2
+ const colors = {
3
+ reset: '\x1b[0m',
4
+ bright: '\x1b[1m',
5
+ dim: '\x1b[2m',
6
+ black: '\x1b[30m',
7
+ red: '\x1b[31m',
8
+ green: '\x1b[32m',
9
+ yellow: '\x1b[33m',
10
+ blue: '\x1b[34m',
11
+ magenta: '\x1b[35m',
12
+ cyan: '\x1b[36m',
13
+ white: '\x1b[37m',
14
+ bgRed: '\x1b[41m',
15
+ bgGreen: '\x1b[42m',
16
+ bgYellow: '\x1b[43m'
17
+ };
18
+
19
+ const logger = {
20
+ debug: (msg, ...args) => console.info(`${colors.cyan}[DEBUG]${colors.reset}`, msg, ...args),
21
+ info: (msg, ...args) => console.info(`${colors.green}[INFO]${colors.reset}`, msg, ...args),
22
+ warn: (msg, ...args) => console.info(`${colors.yellow}[WARN]${colors.reset}`, msg, ...args),
23
+ error: (msg, ...args) => console.error(`${colors.red}[ERROR]${colors.reset}`, msg, ...args),
24
+ success: (msg, ...args) => console.log(`${colors.bright}${colors.green}[SUCCESS]${colors.reset}`, msg, ...args),
25
+ critical: (msg, ...args) => console.error(`${colors.bright}${colors.bgRed}[CRITICAL]${colors.reset}`, msg, ...args)
26
+ };
27
+
28
+ // 导出logger
29
+ module.exports = logger;
@@ -0,0 +1,71 @@
1
+ class MemoryCache {
2
+ constructor() {
3
+ this.cache = new Map()
4
+ this.size = 0
5
+ }
6
+
7
+ add(key, value, time, timeoutCallback) {
8
+ // 移除旧的条目(如果存在)
9
+ const old = this.cache.get(key)
10
+ if (old) {
11
+ clearTimeout(old.timeout)
12
+ }
13
+
14
+ // 创建新的缓存条目
15
+ const entry = {
16
+ value,
17
+ expire: time + Date.now(),
18
+ timeout: setTimeout(() => {
19
+ this.delete(key)
20
+ if (typeof timeoutCallback === 'function') {
21
+ timeoutCallback(value, key)
22
+ }
23
+ }, time),
24
+ }
25
+
26
+ this.cache.set(key, entry)
27
+ this.size = this.cache.size
28
+
29
+ return entry
30
+ }
31
+
32
+ delete(key) {
33
+ const entry = this.cache.get(key)
34
+ if (entry) {
35
+ clearTimeout(entry.timeout)
36
+ this.cache.delete(key)
37
+ this.size = this.cache.size
38
+ }
39
+ return null
40
+ }
41
+
42
+ get(key) {
43
+ return this.cache.get(key) || null
44
+ }
45
+
46
+ getValue(key) {
47
+ const entry = this.cache.get(key)
48
+ return entry ? entry.value : undefined
49
+ }
50
+
51
+ clear() {
52
+ this.cache.forEach((entry) => clearTimeout(entry.timeout))
53
+ this.cache.clear()
54
+ this.size = 0
55
+ return true
56
+ }
57
+
58
+ has(key) {
59
+ const entry = this.cache.get(key)
60
+ if (!entry) return false
61
+
62
+ if (Date.now() > entry.expire) {
63
+ this.delete(key)
64
+ return false
65
+ }
66
+
67
+ return true
68
+ }
69
+ }
70
+
71
+ module.exports = MemoryCache
package/util/option.js ADDED
@@ -0,0 +1,14 @@
1
+ const createOption = (query, crypto = '') => {
2
+ return {
3
+ crypto: query.crypto || crypto || '',
4
+ cookie: query.cookie || process.env.NETEASE_COOKIE,
5
+ ua: query.ua || '',
6
+ proxy: query.proxy,
7
+ realIP: query.realIP,
8
+ randomCNIP: query.randomCNIP || false,
9
+ e_r: query.e_r || undefined,
10
+ domain: query.domain || '',
11
+ checkToken: query.checkToken || false,
12
+ }
13
+ }
14
+ module.exports = createOption