1
1
/**
2
2
*
3
3
* 特别提醒: 仍然处于测试阶段, 更新频率可能比较高
4
- *
4
+ *
5
5
* 使用方法:打开掌上飞车APP, 点击咨询栏的签到(每日福利)即可,无需点击签到,然后点击下方游戏栏,最后点击掌飞商城即可获取所需商城数据。
6
6
* 注意事项:1、每月需手动打开一次掌上飞车APP并进入签到页面,以重新抓包更新礼包数据,为此需要每日运行两次脚本;2、如果账号信息没有发生根本性变化的话,抓取 Cookie 等信息的脚本就不会被执行;3、如需购买掌飞商店中的指定商品,请订阅boxjs链接,并在掌上飞车应用中填写在售商品的完整名称
7
7
*
8
8
* boxjs订阅地址:https://raw.githubusercontent.com/chiupam/surge/main/boxjs/chiupam.boxjs.json
9
9
*
10
10
*
11
- * hostname: comm.ams.game.qq.com
11
+ * hostname: comm.ams.game.qq.com, bang.qq.com
12
12
*
13
13
* type: http-request
14
14
* regex: ^https?://(comm\.ams\.game\.qq\.com/ams/ame/amesvr*|bang\.qq\.com/app/speed/mall/main2\?*)
@@ -67,12 +67,12 @@ const isRequest = typeof $request !== 'undefined';
67
67
'zsfc_accessToken' : matchParam ( cookie , 'accessToken' ) ,
68
68
'zsfc_openid' : matchParam ( cookie , 'openId' )
69
69
} ;
70
-
70
+
71
71
// 将请求数据写入内存
72
72
Object . entries ( cookieToWrite ) . forEach ( ( [ key , value ] ) => $ . write ( value , key ) ) ;
73
73
74
74
// 发起请求检验 iActivityId 和 iFlowId 是否为需要的值
75
- if ( ! ( await getTotalSignInDays ( ) ) ) return ;
75
+ if ( await getTotalSignInDays ( ) === - 1 ) return ;
76
76
77
77
// 解码 tokenParams 端内容
78
78
const decodeTokenParams = decodeURIComponent ( matchParam ( cookie , 'tokenParams' ) ) ;
@@ -84,7 +84,6 @@ const isRequest = typeof $request !== 'undefined';
84
84
'zsfc_areaId' : matchParam ( decodeTokenParams , 'areaId' ) ,
85
85
'zsfc_iActivityId' : ( $ . iActivityId ) . toString ( ) ,
86
86
'zsfc_iFlowId' : ( $ . iFlowId ) . toString ( ) ,
87
- // 'zsfc_month': (new Date().getMonth() + 1).toString() // 5月改版后不清楚是否需要删除
88
87
}
89
88
90
89
// 如果所有键值都与内存中的值相同,则立即终止程序
@@ -96,7 +95,7 @@ const isRequest = typeof $request !== 'undefined';
96
95
97
96
// 显示获取结果通知
98
97
$ . notice ( `🏎️ 掌上飞车` , `✅ 获取签到数据成功!` , `流水ID:${ $ . iFlowId } ,活动ID:${ $ . iActivityId } ` ) ;
99
-
98
+
100
99
// 检查并设置青龙相关变量
101
100
if ( $ . read ( `ql_url` ) && $ . read ( `ql_client_id` ) && $ . read ( `ql_client_secret` ) && $ . toObj ( $ . read ( `zsfc_upload_id` ) ) ) {
102
101
const qlUrlCache = $ . read ( `ql_url` ) ;
@@ -167,22 +166,14 @@ const isRequest = typeof $request !== 'undefined';
167
166
* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 以下进行签到阶段 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
168
167
*/
169
168
170
- // todo 检查用户本月是否打开过签到页面, 5月改版后不清楚是否需要删除
171
- // const month = (new Date().getMonth() + 1).toString();
172
- // if (month != $.read(`zsfc_month`)) return $.notice(`🏎️ 掌上飞车`, `❌ 本月未打开过掌上飞车APP`, `每月需打开一次掌上飞车APP并进到签到页面`);
173
-
174
169
// 获取会员状态
175
170
$ . isVip = await checkIsVip ( ) ;
176
171
if ( $ . isVip ) $ . log ( `💎 尊贵的会员用户` ) ;
177
-
178
- /**
179
- * todo 每日签到需要抓包去解决, 但是需要测试几天
180
- */
181
-
182
- // 定义流水ID词典, 不清楚是否是周周更新或者月月更新
172
+
173
+ // todo 定义流水ID词典, 不清楚是否是周周更新或者月月更新
183
174
idItems = {
184
175
dailyReward : {
185
- 7 : { iFlowId : "1028286" , IdName : "周日签到" } , // 周日签到
176
+ 0 : { iFlowId : "1028286" , IdName : "周日签到" } , // 周日签到
186
177
1 : { iFlowId : "1028292" , IdName : "周一签到" } , // 周一签到
187
178
2 : { iFlowId : "1028291" , IdName : "周二签到" } , // 周二签到
188
179
3 : { iFlowId : "1028290" , IdName : "周三签到" } , // 周三签到
@@ -200,24 +191,28 @@ const isRequest = typeof $request !== 'undefined';
200
191
} ,
201
192
dailyTask : {
202
193
1 : { iFlowId : "1028557" , IdName : "查看动态" } , // 任务1
203
- 2 : { iFlowId : "1028556" , IdName : "浏览背包" } , // 任务2
194
+ 2 : { iFlowId : "1028556" , IdName : "浏览背包" } , // 任务2, 只有浏览背包可以完成
204
195
3 : { iFlowId : "1028555" , IdName : "游戏活跃" } // 任务3
205
196
} ,
206
- matchTask : { iFlowId : "1028554" , IdName : "进行游戏" } , // 任务4
207
- consumptionTask : { iFlowId : "1028553" , IdName : "花费点券" } // 任务5
208
- }
197
+ weeklyTask : {
198
+ 1 : { iFlowId : "1028554" , IdName : "进行游戏" } , // 任务4
199
+ 2 : { iFlowId : "1028553" , IdName : "花费点券" } // 任务5
200
+ }
201
+ } ;
209
202
210
- // 获取当天星期数并签到
211
- const today = new Date ( ) . getDay ( ) ;
212
- var { iFlowId, IdName } = idItems . dailyReward [ today ] ;
213
- await claimGift ( iFlowId , IdName )
203
+ // 每日签到
204
+ var { iFlowId, IdName } = idItems . dailyReward [ new Date ( ) . getDay ( ) ] ;
205
+ await claimGift ( iFlowId , IdName ) ;
214
206
215
207
// 获取本月累签天数并判断是否有累签奖励
216
208
const totalSignInDay = await getTotalSignInDays ( ) ;
217
209
if ( idItems . accumulative [ totalSignInDay ] ) {
218
210
var { iFlowId, IdName } = idItems . accumulative [ totalSignInDay ] ;
219
211
await claimGift ( iFlowId , IdName ) ;
220
212
}
213
+
214
+ // 浏览背包
215
+ await openBackpack ( ) ;
221
216
222
217
// 领取每日任务奖励
223
218
for ( var key in idItems . dailyTask ) {
@@ -226,17 +221,20 @@ const isRequest = typeof $request !== 'undefined';
226
221
}
227
222
228
223
// 判断为周末时领取每周对局任务奖励
229
- if ( today === 6 ) {
230
- var { iFlowId, IdName } = idItems . matchTask ;
231
- await claimGift ( iFlowId , IdName ) ;
224
+ if ( new Date ( ) . getDay ( ) === 6 || new Date ( ) . getDay ( ) === 7 ) {
225
+ for ( var key in idItems . weeklyTask ) {
226
+ var { iFlowId, IdName } = idItems . weeklyTask [ key ] ;
227
+ await claimGift ( iFlowId , IdName ) ;
228
+ }
232
229
}
233
230
231
+ // 显示签到结果通知
232
+ if ( $ . checkInMsg && $ . toObj ( $ . read ( `zsfc_treasure_log` ) || `true` ) ) $ . notice ( `🏎️ 掌上飞车` , $ . subtitle , $ . checkInMsg , `` ) ;
233
+
234
234
/**
235
235
* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 以下进行购物阶段 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
236
236
*/
237
237
238
- if ( new Date ( ) . getHours ( ) < 16 ) return $ . log ( `⭕ 每天16点后再执行购物操作` ) ;
239
-
240
238
// 读取到设置不进行购物
241
239
if ( ! $ . toObj ( $ . read ( `zsfc_shop` ) ) ) return $ . log ( `⭕ 设置为不执行购物` ) ;
242
240
@@ -249,6 +247,12 @@ const isRequest = typeof $request !== 'undefined';
249
247
// Cookie 已过期,程序终止
250
248
if ( ! packBefore ) return $ . log ( `❌ Cookie 已过期,请重新获取` ) , $ . notice ( `🏎️ 掌飞购物` , `❌ Cookie 已过期` , `打开掌上飞车,点击游戏并进入掌上商城` ) ;
251
249
250
+ // 获取当前余额
251
+ const beforeLog = `✅ 当前共有${ packBefore . money } 点券,${ packBefore . coupons } 消费券` ;
252
+ $ . log ( beforeLog ) ;
253
+ if ( new Date ( ) . getHours ( ) < 16 ) return $ . log ( `🕒 每天16点后再执行购物操作` ) ;
254
+ $ . subtitle = beforeLog ;
255
+
252
256
// 判断当天是否为本月月尾2天以内
253
257
$ . lastDayOfMonth = checkLastDayOfMonth ( 2 ) ;
254
258
@@ -259,11 +263,6 @@ const isRequest = typeof $request !== 'undefined';
259
263
// 无法在掌上商城中搜索到相关商品时终止程序
260
264
if ( ! Object . keys ( shopIdArray ) . length ) return $ . notice ( `🏎️ 掌飞购物` , `❌ ${ shopName } 未在商店中售卖` , `请在掌上商城中认真核对商品名称` ) ;
261
265
262
- // 获取当前余额
263
- const beforeLog = `✅ 当前共有${ packBefore . money } 点券,${ packBefore . coupons } 消费券` ;
264
- $ . log ( beforeLog ) ;
265
- $ . subtitle = beforeLog ;
266
-
267
266
// 获取购物包
268
267
const [ shopArray , totalCount , unit ] = getShopItems ( shopIdArray , packBefore ) ;
269
268
@@ -284,21 +283,6 @@ const isRequest = typeof $request !== 'undefined';
284
283
successBuyCounts += await purchaseItem ( shopName , count , id , idx ) ;
285
284
}
286
285
287
- /**
288
- * ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 每周消费任务在这里执行 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
289
- */
290
-
291
- // 判断领取消费任务奖励, $.successfulForcedConsumption 在 getShopItems 函数里面写
292
- if ( $ . successfulForcedConsumption || checkLastDayOfMonth ( 2 ) ) {
293
- var { iFlowId, IdName } = idItems . consumptionTask ;
294
- await claimGift ( iFlowId , IdName ) ;
295
- $ . write ( `0` , `zsfc_weeklyConsumptionAmount` ) ; // 重置每周消费点券为 0 点券
296
- }
297
-
298
- /**
299
- * ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 每周消费任务在这里执行 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
300
- */
301
-
302
286
if ( successBuyCounts > 0 ) {
303
287
// 购买永久道具后为避免重复购买自动禁用购买脚本并重置道具名称
304
288
if ( totalCount === 999 ) $ . write ( `false` , `zsfc_shop` ) , $ . write ( `` , `zsfc_bang_shopname` ) ;
@@ -344,7 +328,7 @@ function checkLastDayOfMonth(N) {
344
328
345
329
// 获取当前月份的最后一天的日期
346
330
let day = new Date ( today . getFullYear ( ) , today . getMonth ( ) + 1 , 0 ) . getDate ( ) ;
347
-
331
+
348
332
return ( day - today . getDate ( ) ) < N ; // 月底最后3天的计算方式是小于N而不能有等于
349
333
}
350
334
@@ -404,7 +388,7 @@ function getShopItems(shopInfo, overage) {
404
388
405
389
// 根据价格排序道具数据
406
390
const sortedData = shopInfo . szPrices . map ( ( price , index ) => ( {
407
- price : parseInt ( price . SuperMoneyPrice ) * iMemeberRebate ,
391
+ price : parseInt ( price . SuperMoneyPrice ) * iMemeberRebate ,
408
392
count : numArray [ index ] , idx : index
409
393
} ) ) . sort ( ( a , b ) => b . count - a . count ) ;
410
394
@@ -416,20 +400,7 @@ function getShopItems(shopInfo, overage) {
416
400
// 初始化购买总数、物品数组和投入金额
417
401
let totalCount = 0 ;
418
402
let purchasedItemsList = [ ] ;
419
- // todo 这里要改一下, 如果开启了强制消费就是另一种计算方式了
420
- if ( $ . lastDayOfMonth ) {
421
- var remMoney = overage . money + overage . coupons ;
422
- } else if (
423
- new Date ( ) . getDay ( ) === 6 && // 周六
424
- Number ( $ . read ( `zsfc_weeklyConsumptionAmount` ) ) < 5000 && // 本周点券消费小于5000
425
- $ . toObj ( $ . read ( `zsfc_forcedConsumption` ) ) && // 开启了强制消费
426
- overage . money >= 5000 - Number ( $ . read ( `zsfc_weeklyConsumptionAmount` ) ) // 当前点券余额大于等于需要补充消费点券的部分
427
- ) {
428
- var remMoney = 5000 - Number ( $ . read ( `zsfc_weeklyConsumptionAmount` ) ) + overage . coupons ;
429
- $ . successfulForcedConsumption = true ;
430
- } else {
431
- var remMoney = overage . coupons ;
432
- }
403
+ let remMoney = $ . lastDayOfMonth ? overage . money + overage . coupons : overage . coupons ; y = overage . coupons ;
433
404
434
405
// 定义商品数据、最便宜商品序列(最便宜商品序列一定是列表最后一个)
435
406
const itemData = info . data ;
@@ -456,9 +427,9 @@ function getShopItems(shopInfo, overage) {
456
427
// 将购买的物品加入数组
457
428
for ( let n = 0 ; n < maxPurchasableItems ; n ++ ) {
458
429
purchasedItemsList . push ( {
459
- "count" : itemData [ m ] . count ,
460
- "id" : info . Id ,
461
- "idx" : itemData [ m ] . idx ,
430
+ "count" : itemData [ m ] . count ,
431
+ "id" : info . Id ,
432
+ "idx" : itemData [ m ] . idx ,
462
433
} ) ;
463
434
pushCounts += 1 ;
464
435
}
@@ -471,23 +442,21 @@ function getShopItems(shopInfo, overage) {
471
442
// 如果满足阈值条件,且消费券加点券的和大于最便宜一个道具的价格
472
443
if ( meetsThreshold && canAffordLastItem ) {
473
444
purchasedItemsList . push ( {
474
- "count" : itemData [ cheapestItemIndex ] . count ,
475
- "id" : info . Id ,
476
- "idx" : itemData [ cheapestItemIndex ] . idx ,
445
+ "count" : itemData [ cheapestItemIndex ] . count ,
446
+ "id" : info . Id ,
447
+ "idx" : itemData [ cheapestItemIndex ] . idx ,
477
448
} ) ;
478
- moneyCost = itemData [ cheapestItemIndex ] . price - remMoney ; // 这个应该是强制消费的点券数量
479
- $ . write ( ( Number ( $ . read ( `zsfc_weeklyConsumptionAmount` ) ) + moneyCost ) . toString ( ) , `zsfc_weeklyConsumptionAmount` ) ; // 更新本周消费点券数据
480
449
thisTimeCost += itemData [ cheapestItemIndex ] . price ;
481
450
totalCount += itemData [ cheapestItemIndex ] . count ;
482
451
pushCounts += 1 ;
483
452
}
484
-
453
+
485
454
// 本轮花费大于0且本轮消费等于倒数第二阶梯的消费价格时,清空本轮添加的购买包
486
455
if ( thisTimeCost && thisTimeCost === itemData [ cheapestItemIndex - 1 ] . price ) {
487
456
// 计算需要保留的元素数量、新的元素序列
488
457
const itemsToKeep = purchasedItemsList . length - pushCounts ;
489
458
const newIndex = cheapestItemIndex - 1 ;
490
-
459
+
491
460
// 使用 slice 创建一个新数组,仅保留需要的元素,并添加新元素到数组末尾
492
461
purchasedItemsList = purchasedItemsList . slice ( 0 , itemsToKeep ) ;
493
462
purchasedItemsList . push ( {
@@ -528,8 +497,7 @@ async function getTotalSignInDays() {
528
497
} ,
529
498
body : $ . queryStr ( {
530
499
"iActivityId" : isRequest ? $ . iActivityId : $ . read ( `zsfc_iActivityId` ) ,
531
- // "sServiceType": "speed", // 这个数据不需要传
532
- "iFlowId" : Number ( isRequest ? $ . iFlowId : $ . read ( `zsfc_iFlowId` ) ) ,
500
+ "iFlowId" : isRequest ? $ . iFlowId : $ . read ( `zsfc_iFlowId` ) ,
533
501
"g_tk" : "1842395457" ,
534
502
"witchDay" : "1" , // 不知道为什么需要传一个 witchDay 参数, 键值 1 也不清楚是什么意思
535
503
} )
@@ -541,8 +509,7 @@ async function getTotalSignInDays() {
541
509
$ . post ( options , ( err , resp , data ) => {
542
510
if ( data ) {
543
511
try {
544
- // todo 目前暂定为 sOutValue5 因为猜测 sOutValue4 是本周签到天数
545
- // todo 可能还需要分析 sOutValue2 漏签的情况, 以及 sOutValue7 是否可补签
512
+ // todo 目前暂定为 sOutValue5 因为猜测 sOutValue4 是本周签到天数, 可能还需要分析 sOutValue2 漏签的情况, 以及 sOutValue7 是否可补签
546
513
totalSignInDays = $ . toObj ( data ) . modRet . sOutValue5 ;
547
514
548
515
if ( ! isRequest ) {
@@ -554,7 +521,7 @@ async function getTotalSignInDays() {
554
521
$ . log ( `❌ 获取累签天数时发生错误` ) ;
555
522
$ . log ( $ . toStr ( err ) ) ;
556
523
}
557
- resolve ( ! isNaN ( totalSignInDays ) ? Number ( totalSignInDays ) : false ) ;
524
+ resolve ( ! isNaN ( totalSignInDays ) ? Number ( totalSignInDays ) : - 1 ) ;
558
525
} ) ;
559
526
} ) ;
560
527
}
@@ -581,54 +548,67 @@ async function claimGift(giftId, giftName) {
581
548
} ,
582
549
body : $ . queryStr ( {
583
550
"iActivityId" : $ . read ( `zsfc_iActivityId` ) ,
584
- // "sServiceType": "speed", // 这个数据不需要传
585
- "iFlowId" : giftId ,
551
+ "iFlowId" : giftId ,
586
552
"g_tk" : "1842395457"
587
553
} )
588
554
} ;
589
555
590
- $ . log ( `🧑💻 准备领取${ giftName } 奖励` ) ;
591
-
592
556
// 返回一个 Promise 对象,用于异步操作
593
557
return new Promise ( resolve => {
594
558
// 发送 POST 请求,获取领取结果
595
559
$ . post ( options , ( err , resp , data ) => {
596
560
if ( data ) {
597
561
let body = $ . toObj ( data . replace ( / \r | \n / ig, `` ) ) ;
598
562
if ( body . msg . includes ( `已经` ) ) {
599
- $ . log ( `✅ 领取结果 : 已经领取` ) ;
563
+ $ . log ( `✅ ${ giftName } : 已经领取` ) ;
600
564
// $.checkInMsg += `, ${giftName}`;
601
565
} else if ( body . msg . includes ( `不满足` ) ) {
602
- $ . log ( `⭕ 领取失败 : ${ body . flowRet . sMsg } ` ) ;
566
+ $ . log ( `⭕ ${ giftName } : ${ body . flowRet . sMsg } ` ) ;
603
567
} else {
604
568
const sPackageName = body . modRet . sPackageName . replace ( / [ , , ] / g, ", " ) ;
605
- $ . log ( `✅ 领取结果: 获得 ${ sPackageName } ` ) ;
569
+ $ . log ( `✅ ${ giftName } : ${ sPackageName } ` ) ;
606
570
if ( $ . checkInMsg ) {
607
571
$ . checkInMsg += `,${ sPackageName } ` ;
608
572
} else {
609
573
$ . checkInMsg = `领取结果: 获得${ sPackageName } `
610
574
}
611
575
}
612
576
} else {
613
- $ . log ( `❌ 领取 ${ giftName } 时发生错误 ` ) ;
577
+ $ . log ( `❌ ${ giftName } : 发生错误 ` ) ;
614
578
$ . log ( $ . toStr ( err ) ) ;
615
579
}
616
580
resolve ( ) ;
617
581
} ) ;
618
582
} ) ;
619
583
}
620
584
621
- // todo 查看动态的请求, 不过好像需要用到 base64, 可能无法完成
622
- /**
623
- * @description 掌飞签到相关函数,查看动态
624
- * @returns {Promise<object> } 包含会员状态的 Promise 对象。
625
- */
626
-
627
- // todo 浏览背包的请求, 不过好像需要用到 base64, 可能无法完成
628
585
/**
629
586
* @description 掌飞签到相关函数,浏览背包
630
- * @returns {Promise<object> } 包含会员状态的 Promise 对象。
587
+ * @returns {Promise<object> } 返回空的 Promise 对象。
631
588
*/
589
+ async function openBackpack ( ) {
590
+ // 构建请求体
591
+ const options = {
592
+ url : `https://mwegame.qq.com/yoyo/dnf/phpgameproxypass` ,
593
+ body : $ . queryStr ( {
594
+ uin : $ . read ( `zsfc_uin` ) ,
595
+ areaId : $ . read ( `zsfc_areaId` ) ,
596
+ userId : $ . read ( `zsfc_userId` ) ,
597
+ token : $ . read ( `zsfc_token` ) ,
598
+ service : `dnf_getspeedknapsack` ,
599
+ cGameId : `1003` // 必须传入这个参数才可以完成任务
600
+ } )
601
+ } ;
602
+
603
+ // 返回一个 Promise 对象,用于异步操作
604
+ return new Promise ( resolve => {
605
+ // 发送 POST 请求
606
+ $ . post ( options , ( error , response , data ) => {
607
+ // 只需要发送请求即可, 不进行任何处理
608
+ resolve ( ) ;
609
+ } ) ;
610
+ } ) ;
611
+ }
632
612
633
613
/**
634
614
* @description 掌飞购物相关函数,判断用户是否为会员用户。
@@ -993,4 +973,4 @@ function Env(name) {
993
973
994
974
// 返回包含所有方法的对象
995
975
return { name, read, write, notice, get, post, put, toObj, toStr, queryStr, cookieStr, log, done } ;
996
- }
976
+ }
0 commit comments