@@ -4,167 +4,38 @@ const { register_anonimous } = require('./main')
44const { cookieToJson, generateRandomChineseIP } = require ( './util/index' )
55const { getXeapiPublicKey } = require ( './util/xeapiKey' )
66const tmpPath = require ( 'os' ) . tmpdir ( )
7- const logger = require ( './util/logger' )
87
9- const MAX_RETRIES = 3
10- const RETRY_DELAY_MS = 1000
11-
12- function sleep ( ms ) {
13- return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) )
14- }
15-
16- function isRetryableError ( err ) {
17- const msg = ( err && err . message ) || ''
18- const status =
19- ( err && err . status ) || ( err && err . response && err . response . status )
20- if (
21- msg . includes ( 'ETIMEDOUT' ) ||
22- msg . includes ( 'ECONNRESET' ) ||
23- msg . includes ( 'ECONNREFUSED' ) ||
24- msg . includes ( 'socket hang up' ) ||
25- msg . includes ( 'request timeout' ) ||
26- msg . includes ( 'timeout' ) ||
27- msg . includes ( 'network' ) ||
28- msg . includes ( 'Network' )
29- ) {
30- return true
31- }
32- if ( status && status >= 500 ) {
33- return true
34- }
35- return false
36- }
37-
38- /** @returns {{ success: boolean, error?: Error } } */
39- async function fetchAnonymousToken ( ) {
40- for ( let attempt = 1 ; attempt <= MAX_RETRIES ; attempt ++ ) {
41- try {
42- const res = await register_anonimous ( )
43- const cookie = res . body . cookie
44- if ( cookie ) {
45- const cookieObj = cookieToJson ( cookie )
46- fs . writeFileSync (
47- path . resolve ( tmpPath , 'anonymous_token' ) ,
48- cookieObj . MUSIC_A ,
49- 'utf-8' ,
50- )
51- logger . success ( '[generateConfig] 匿名 token 注册成功' )
52- return { success : true }
53- }
54- // 返回了但没有 cookie,视为异常但不再重试
55- logger . warn (
56- `[generateConfig] 匿名注册返回了空 cookie (attempt ${ attempt } )` ,
57- )
58- return {
59- success : false ,
60- error : new Error ( 'empty cookie from anonymous register' ) ,
61- }
62- } catch ( err ) {
63- if ( isRetryableError ( err ) && attempt < MAX_RETRIES ) {
64- const delay = RETRY_DELAY_MS * Math . pow ( 2 , attempt - 1 )
65- logger . warn (
66- `[generateConfig] 获取匿名 token 失败 (attempt ${ attempt } /${ MAX_RETRIES } ), ${ delay } ms 后重试...` ,
67- )
68- await sleep ( delay )
69- continue
70- }
71- // 不可重试 或 已达最大次数
72- if ( attempt >= MAX_RETRIES ) {
73- logger . error (
74- `[generateConfig] 获取匿名 token 已达最大重试次数 (${ MAX_RETRIES } ):` ,
75- err . message ,
76- )
77- } else {
78- logger . error (
79- `[generateConfig] 获取匿名 token 失败 (不可重试):` ,
80- err . message ,
81- )
82- }
83- return { success : false , error : err }
84- }
85- }
86- return { success : false , error : new Error ( 'unreachable' ) }
87- }
88-
89- /**
90- * 获取 xeapi public key,带重试
91- * @returns {{ success: boolean, error?: Error } }
92- */
93- async function fetchXeapiPublicKey ( ) {
94- for ( let attempt = 1 ; attempt <= MAX_RETRIES ; attempt ++ ) {
95- try {
96- let currentPublicKey = { }
97- try {
98- currentPublicKey = JSON . parse (
99- fs . readFileSync ( path . resolve ( tmpPath , 'xeapi_public_key' ) , 'utf-8' ) ,
100- )
101- } catch ( _ ) {
102- // 本地无缓存文件,用空对象正常请求
103- }
104- const publicKey = await getXeapiPublicKey (
105- currentPublicKey ,
106- global . deviceId ,
107- )
8+ async function generateConfig ( ) {
9+ global . cnIp = generateRandomChineseIP ( )
10+ try {
11+ const res = await register_anonimous ( )
12+ const cookie = res . body . cookie
13+ if ( cookie ) {
14+ const cookieObj = cookieToJson ( cookie )
10815 fs . writeFileSync (
109- path . resolve ( tmpPath , 'xeapi_public_key ' ) ,
110- JSON . stringify ( publicKey ) ,
16+ path . resolve ( tmpPath , 'anonymous_token ' ) ,
17+ cookieObj . MUSIC_A ,
11118 'utf-8' ,
11219 )
113- logger . success ( '[generateConfig] xeapi public key 获取成功' )
114- return { success : true }
115- } catch ( err ) {
116- if ( isRetryableError ( err ) && attempt < MAX_RETRIES ) {
117- const delay = RETRY_DELAY_MS * Math . pow ( 2 , attempt - 1 )
118- logger . warn (
119- `[generateConfig] 获取 xeapi public key 失败 (attempt ${ attempt } /${ MAX_RETRIES } ), ${ delay } ms 后重试...` ,
120- )
121- await sleep ( delay )
122- continue
123- }
124- if ( attempt >= MAX_RETRIES ) {
125- logger . error (
126- `[generateConfig] 获取 xeapi public key 已达最大重试次数 (${ MAX_RETRIES } ):` ,
127- err . message ,
128- )
129- } else {
130- logger . error (
131- `[generateConfig] 获取 xeapi public key 失败 (不可重试):` ,
132- err . message ,
133- )
134- }
135- return { success : false , error : err }
13620 }
21+ } catch ( error ) {
22+ console . log ( error )
13723 }
138- return { success : false , error : new Error ( 'unreachable' ) }
139- }
140-
141- /**
142- * 生成配置(匿名 token + xeapi public key),带容错重试
143- * @returns {{ tokenOk: boolean, keyOk: boolean } }
144- */
145- async function generateConfig ( ) {
146- global . cnIp = generateRandomChineseIP ( )
147-
148- // 两个任务并行执行,互不影响喵~
149- const [ tokenResult , keyResult ] = await Promise . all ( [
150- fetchAnonymousToken ( ) ,
151- fetchXeapiPublicKey ( ) ,
152- ] )
153-
154- if ( ! tokenResult . success ) {
155- logger . warn ( '[generateConfig] 匿名 token 获取失败' )
156- }
157- if ( ! keyResult . success ) {
158- logger . warn ( '[generateConfig] xeapi public key 获取失败' )
159- }
160-
161- if ( tokenResult . success && keyResult . success ) {
162- logger . success ( '[generateConfig] 配置初始化完成' )
163- }
164-
165- return {
166- tokenOk : tokenResult . success ,
167- keyOk : keyResult . success ,
24+ try {
25+ let currentPublicKey = { }
26+ try {
27+ currentPublicKey = JSON . parse (
28+ fs . readFileSync ( path . resolve ( tmpPath , 'xeapi_public_key' ) , 'utf-8' ) ,
29+ )
30+ } catch ( _ ) { }
31+ const publicKey = await getXeapiPublicKey ( currentPublicKey , global . deviceId )
32+ fs . writeFileSync (
33+ path . resolve ( tmpPath , 'xeapi_public_key' ) ,
34+ JSON . stringify ( publicKey ) ,
35+ 'utf-8' ,
36+ )
37+ } catch ( error ) {
38+ console . log ( error )
16839 }
16940}
17041module . exports = generateConfig
0 commit comments