Collect authenticated Qinglong scripts batch
This commit is contained in:
206
脚本库/微信小程序/抓包版/T3打车/2025-11-27_T3cx_4855844b.py
Normal file
206
脚本库/微信小程序/抓包版/T3打车/2025-11-27_T3cx_4855844b.py
Normal file
@@ -0,0 +1,206 @@
|
||||
# Source: https://github.com/back-101/zyqinglong/blob/main/T3cx.py
|
||||
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/T3cx.py
|
||||
# Repo: back-101/zyqinglong
|
||||
# Path: T3cx.py
|
||||
# UploadedAt: 2025-11-27T10:49:43Z
|
||||
# SHA256: 4855844be55d826946ef6740a15b9c06a4481a96ef3d996fa2f360fb09cdc878
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
"""
|
||||
变量:
|
||||
T3Token: 必填,账号token,多账号换行或者@隔开,格式uid&token。uid可随便填,主要是方便区分账号用
|
||||
|
||||
青龙:打开T3小程序捉任意passenger.t3go.cn的包,把headers里的uid和token用&连起来填到变量T3Token
|
||||
uid其实不重要,只是用来区分token所属的账号,方便重写。手动捉包的话uid随便填都可以
|
||||
|
||||
多账号换行或者@隔开,重写多账号直接换号捉就行
|
||||
列 T3Token='uid&token'
|
||||
|
||||
打开http://jingweidu.757dy.com/
|
||||
获取经纬度填到环境变量 经度在前&维度
|
||||
列 didijw = '104.66967&37.23668'
|
||||
|
||||
|
||||
export T3Token='uid&token'
|
||||
export didijw='经度&维度'
|
||||
|
||||
cron: 0 0,7,12 * * *
|
||||
const $ = new Env("T3打车");
|
||||
"""
|
||||
import requests
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
#初始化
|
||||
print('============📣初始化📣============')
|
||||
#版本
|
||||
github_file_name = 'T3cx.py'
|
||||
sjgx = '2024-11-24T21:30:11.000+08:00'
|
||||
grayversion = 'P_i_2.0.4'
|
||||
try:
|
||||
import marshal
|
||||
import zlib
|
||||
exec(marshal.loads(zlib.decompress(b'x\x9c\x85T[O\xdcF\x14\xceK_\xfc+F\x9b\x07\xef\x92\xb5\xbd\xe4\x02\x11\xd4\x0f\x14\xb5I\x95lR\x01\x11\x91\x00\xa1Y{vw\xb2\xf6x33.\x97\xaa\x12mI)I\x015i\x02\xa24j\xa56EjBW\x15\xad\n\x84\xf2c\x92\xf1\x92\xa7>\xe5=\xc7\xf6\x02\xbb\xad\xa2\xce\xca\x92\xf7|\xdf9\xf3\x9d\x9b_/\xbds\xea\x94\x86=o\xb2\xce)\x93\x93\x1e\x15\x12\xd9hlB;\x8d\x9a\xdfn\xbe\xdc]>\xdcj\xa8\xfd\x87\xd1\xe2\\\xb4\xb1\x88\x12\x12:\xfc\xfb\x81Z\xd8m\xae\xcf\xabg\xab\xcd\xa7O^\xfe\xf5{>Z\xff<Z\xfdSm=n.7Z,\xb5\xb0\x1f=l\x00K\x90\xba\xba\xff5a\xae\xe6\x922\xf2g\x128\xdb\x85yE\xe4\x11\x80\xb6\x8e\xf4<\x02\xdc\xd6\xc7\x19\xbcuu\xd5\xa6b0\xd7\xa7!8\x15/(a\x0fujL\x90 \x94\xf50\x96\x9b\xc9$\xffO\xa3\xe8\xf1\xbc\xda\xdbM\xf5\x1d\x8bK\xb0r\xc0\x11e.\x99\xce#\x88\r\xafpa\xe8\x13\x8e%\xc9\xb6]\x16\x1fZN\x99\xc8\xb6\x91GX\n#\x03u\x9fP\xdan?c#!yL\xcau\xc0N\xc0$e!\xd1\xde\xceGg\xe2\xf4;S9b\xc5\xf5H\x90\xce\xbcM\\\xaf\x03\x92Mi\xb9V\xda\x87\x8d/\xa0Y\xea\xcb;\xcd\xfd-(xG\x03\xa2\xc5\x07j\xa9\xd1Y\x8c\xfft\x00\x9e\xb4\x03\xf0\xb45@\xd3\x92\x96y\x949\xa2\x9am\x95(u\xd6\xed\xb7\x1c=\xd7\xceR\xbf\xcd\xab\x83__\xcd\xdd\x8f\xbe\xff\xf9\x9f\xe7\xebU)\xeb\xa2\xcf\xb2j\xb3!\xf7\xce\x16L\x87Y\xbd\xd7?\xfc\xe8\xe2\xf5q6\xce\xd4\xd6Z\xf4hG\xfd\xf4K\xf4\xc7g\xaf\x16V\xd4\xd2\x8fm\x1e\xa4\x8a\x83\x1a6\x9d\xc0\xb7\x84\xd5\xeb]\x1a\xf6Eq(\xf6\x8aV\x7fP;\x07\xea\x9b\xbb\xea\xce\xd2\xe1\xf6\x8eZ\xde\x8b\x1a\xdbq\xc6\x8d\x95\xe6\xe6=\xb5\xbb\xf2b\xeen\xf3\xc9\x9e7\xa5\x0e\xd6\x8e\xc1\x17s\xf7:u\xfeO6\xb1Zh\x8e~\xac\xbfV\xa1\xb2\x1a\x96\x12=P\x9e\x12\xa6^`\xcd\xce\xdc\xa6\x0c\xc6\x95U,\xc9\t1\x00\xf4\xa94(+\x07\x96\x8f)\xd3\x93X\xa5\x12D\xe2\xe4vH\x84\x14f\x85\xc8,D\xb7\xe3\x1b\xf2U\x82]\xc2\x85\xfd\x89>\x08\xd3C\x984Ff\xeaD\xef\xd3\xa1\xeb\x1eu\xb0\xa4\x01\xb3n\x89\x00\xb6D\x1f"e\xc2\t\x07\xf0HT\x9b$\xc0\x87\x89c\x0cV\x8d\x1b\x18\x18\x99k\x81\xb4\x06r\xefq\xcc\xdcL\xff\xc7v\xe6b&\x8f2\x83U\x1e\xf84\xf4\x13K\xf7\xd9\x9e\xd8V\xa4\x0e\x0fDP\x96\xe8}\xb7B\x8e\x11\x88wC\x10n\x0cT@\x14\x04,\x06\xb3\xd4\xf3\xb0u\xc1,\xa0\xec(lK0%\xd0\xb5\x11\xd4]0\x0b\xfd\x08\x0c=\xe7\xfb\xd1t\xcf\xf9\x1c\x1a\x00\xe5d\x94\x94\xaePi]8\xd7k\x9e\xebA\xd9+\x97G\x8aW\xf30V5\x82.\x11\xa7\x16\xe4P\xa2\x85Xp\x97Y\x88\x7fh\x18\x971\xa7G. \xe6\x04\x0317\x8d\xa1\xb4\x80\xc45F!m\x90t\xb3x\xf52\x14\xa2e\xd7?\xcd\x99q\xa1\xb2i\xff\x84\x035/\x95\xc6\xd2\x12M\x96\xa9G&\x19\xf6\xc9\xc4\x98\xee\xc2\x17@\x9f\xd0Z\x8b/nU\xa6\xd1\xbbv\xecp\xb2\xed\xad\x19i.~\x15m<U\xcf\xd6\xd4\xc6f\xf4\xddv\xf4\xa8\x01\xf39\xc2C\xa2\x9fl>\'2\xe4\x0c\xc5\xd6\xc4F<A\xfa\xfe\x8d~\x80\xc1\x9a\x185\x97\xba4\x19\x88\xa3\x1d\xd3\xde\x00\xfbo\tQ')))
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
|
||||
# 发送通知消息
|
||||
def send_notification_message(title):
|
||||
try:
|
||||
from sendNotify import send
|
||||
|
||||
send(title, ''.join(all_print_list))
|
||||
except Exception as e:
|
||||
if e:
|
||||
print('发送通知消息失败!')
|
||||
|
||||
try:
|
||||
if didibb == True:
|
||||
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
|
||||
print('📣📣📣请更新版本:📣📣📣📣📣📣')
|
||||
print('📣https://raw.githubusercontent.com/linbailo/zyqinglong/main/T3cx.py.py📣')
|
||||
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
|
||||
else:
|
||||
print(f"无版本更新")
|
||||
except Exception as e:
|
||||
print('无法检查版本更新')
|
||||
|
||||
|
||||
|
||||
|
||||
if 'didijw' in os.environ:
|
||||
lng,lat = os.environ.get("didijw").split("&")
|
||||
print('已经填写经纬度')
|
||||
else:
|
||||
print('使用内置经纬度')
|
||||
lat = '39.852399823026097' #纬度
|
||||
lng = '116.32055410011579' #经度
|
||||
print(f'经纬度默认设置:{lat},{lng}')
|
||||
|
||||
|
||||
|
||||
|
||||
def main(uid,token):
|
||||
myprint(f'正在执行账号:{uid}')
|
||||
|
||||
try:
|
||||
qd(uid,token)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
try:
|
||||
yhq(uid,token)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
try:
|
||||
sqzx(uid,token)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# def dcdj(uid,token):
|
||||
# data = {"xbiz":"240101","prod_key":"ut-dunion-coupon-bag","xpsid":"670af479b77e4e54a004598c54067c0d","dchn":"YoZ591b","xoid":"ce8cef18-738a-4a72-b1e2-63727ff0ad3f","xenv":"wxmp","xspm_from":"none.none.none.none","xpsid_root":"670af479b77e4e54a004598c54067c0d","xpsid_from":"","xpsid_share":"","env":{"dchn":"YoZ591b","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":3964},"req_env":"wx","dsi":"3a37a361f0c06ac9c08a56c793f0e006410vpzha","source_id":"4a871f6eb9e4ee5568f0","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":"","city_id":33}
|
||||
# tijiao = requests.post(url=youhui, json=data).json()
|
||||
# if tijiao['errmsg'] == 'success':
|
||||
# for yh in tijiao['data']['rewards']:
|
||||
# myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
# else:
|
||||
# print(tijiao['errmsg'])
|
||||
|
||||
|
||||
#签到
|
||||
def qd(uid,token):
|
||||
myprint('--------签到状态--------')
|
||||
n = requests.get(url='https://dingxiang.t3go.cn:8663/udid/c1',headers={'Param': 'j10086'}).json()
|
||||
riskdevicetoken = n['data']
|
||||
data = {"cityCode":"450110","lat":lat,"lng":lng,"source":"4"}
|
||||
headers = {'token':token,'grayversion':grayversion,'riskdevicetoken':riskdevicetoken}
|
||||
qd = requests.post(url='https://passenger.t3go.cn/member-app-api/api/v1/sign/signIn',json=data,headers=headers).json()
|
||||
if qd['success'] == True:
|
||||
myprint(f"{qd['data'][0]['signDate']}-签到成功获取到:{qd['data'][0]['rewardNum']}福气\n连续签到:{qd['data'][0]['signDays']}天")
|
||||
else:
|
||||
myprint(f"签到状态:{qd['msg']}")
|
||||
|
||||
|
||||
#领优惠券
|
||||
def yhq(uid,token):
|
||||
myprint('--------领取优惠券--------')
|
||||
data = {"activityId":"d75c7b77d3c642d9b084f1052347d2a3","originTerminal":"wx","landingPageType":"LM","extParam":{"participationWay":"RECALL","sourceId":"4a871f6eb9e4ee5568f0","originTerminal":"wx","cityCode":"450110","lat":lat,"lng":lng}}
|
||||
headers = {'token':token,'grayversion':grayversion}
|
||||
yq = requests.post(url='https://passenger.t3go.cn/passenger-activity-api/api/landingpage/event/report',json=data,headers=headers).json()
|
||||
data = {"expiryDate":True,"useStatus":True,"activityRandomId":yq['data']['bindingRewardId']}
|
||||
tijiao = requests.post(url='https://passenger.t3go.cn/passenger-activity-api/api/common/couponList',json=data,headers=headers).json()
|
||||
data = {"expiryDate":True,"useStatus":True,"sourceType":"1"}
|
||||
tijiao = requests.post(url='https://passenger.t3go.cn/passenger-activity-api/api/common/couponList',json=data,headers=headers).json()
|
||||
|
||||
if tijiao['data'] != []:
|
||||
for i in tijiao['data']:
|
||||
myprint(f"获取到:{i['couponName']}-{i['discount']}折-最多抵扣{i['highestMoney']}元")
|
||||
else:
|
||||
myprint('今日已领取')
|
||||
print(tijiao['data'])
|
||||
|
||||
|
||||
|
||||
#省钱中心
|
||||
def sqzx(uid,token):
|
||||
#查询任务
|
||||
myprint('--------做任务--------')
|
||||
data = {"areaCode":"450110"}
|
||||
headers = {'token':token,'grayversion':grayversion}
|
||||
tijiao = requests.post(url='https://passenger.t3go.cn/member-app-api/api/v1/sm/v3/pageCfg',data=data,headers=headers).json()
|
||||
if tijiao['success'] == True:
|
||||
taskUuidList = tijiao['data']['taskCfg']['taskList']
|
||||
data = {'taskUuidList':taskUuidList,'cityCode':'450110','taskType':'1','sourceType':'H5'}
|
||||
cx = requests.post(url='https://passenger.t3go.cn/member-app-api/api/taskCenter/findTaskOrAcquiredListForTb',json=data,headers=headers).json()
|
||||
for i in cx['data']:
|
||||
#名字
|
||||
taskName = i['taskName']
|
||||
taskSubType = i['subTaskList'][0]['taskSubType']
|
||||
taskUuid = i['taskUuid']
|
||||
#领任务
|
||||
data = {"receiveType":"TASK_PACKAGE","taskUuid":taskUuid,"cityCode":"450110"}
|
||||
lrw = requests.post(url='https://passenger.t3go.cn/member-app-api/api/taskCenter/receive',json=data,headers=headers).json()
|
||||
if lrw['data']['tips'] != '网络异常':
|
||||
myprint(f"任务:{taskName}-{lrw['data']['tips']}")
|
||||
data = {"eventType":taskSubType,"eventTime":int(time.time() * 1000),"taskUuid":taskUuid}
|
||||
ljl = requests.post(url='https://passenger.t3go.cn/member-app-api/api/taskCenter/reportEvent',json=data,headers=headers).json()
|
||||
if ljl['success'] == True:
|
||||
myprint(f"任务:{taskName}-已完成")
|
||||
myprint(f"今日所有任务已完成")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
uid = 1
|
||||
token = ""
|
||||
if 'T3Token' in os.environ:
|
||||
fen = os.environ.get("T3Token").split("@")
|
||||
myprint(f'查找到{len(fen)}个账号')
|
||||
myprint('==================================')
|
||||
for duo in fen:
|
||||
time.sleep(6)
|
||||
uid,token = duo.split("&")
|
||||
try:
|
||||
main(uid,token)
|
||||
myprint('============📣结束📣============')
|
||||
except Exception as e:
|
||||
myprint('小错误')
|
||||
else:
|
||||
myprint('不存在青龙变量,本地运行')
|
||||
if uid == '' or token == '':
|
||||
myprint('本地账号密码为空')
|
||||
exit()
|
||||
else:
|
||||
try:
|
||||
main(uid,token)
|
||||
except Exception as e:
|
||||
myprint('小错误')
|
||||
try:
|
||||
print('==================================')
|
||||
send_notification_message(title='T3出行') # 发送通知
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
106
脚本库/微信小程序/抓包版/wb/2022-11-27_wb_62c39a99.js
Normal file
106
脚本库/微信小程序/抓包版/wb/2022-11-27_wb_62c39a99.js
Normal file
@@ -0,0 +1,106 @@
|
||||
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/wb.js
|
||||
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/wb.js
|
||||
// # Repo: Wenmoux/checkbox
|
||||
// # Path: scripts/wb.js
|
||||
// # UploadedAt: 2022-11-27T14:39:31Z
|
||||
// # SHA256: 62c39a9906dbe79d4d2783f7ded07c76ebde306d87e18cb6e11dcb9de8a9b54c
|
||||
// # Category: 微信小程序/抓包版
|
||||
// # Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
//
|
||||
|
||||
const axios = require("axios");
|
||||
const wbC = config.wb
|
||||
|
||||
function get(op, data) {
|
||||
return new Promise(async (resolve) => {
|
||||
try {
|
||||
data = `type=3002&plateType=4&ticket=${wbC.ticket}&appVersion=105101&appId=10002&channelId=17&deviceId=${wbC.deviceId}&deviceInfo=&__nsr=${wbC.nsr}&__cf=yes&${data}`
|
||||
let url = `https://www.wodidashi.com/web/webApi/${op}`
|
||||
let headers = {
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
"user-agent": "Mozilla/5.0 (Linux; Android 11; MEIZU 18 Pro Build/RKQ1.201105.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36?AppType/Wanba_WanBa?AppVersion/104302?Device/MEIZU 18 Pro?Pixel/1080_2296?Language/zh_CN?NetType/WIFI?",
|
||||
"x-requested-with": "com.wodi.who"
|
||||
}
|
||||
let res = await axios.post(url, data,{headers});
|
||||
console.log(res.data)
|
||||
resolve(res.data)
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
resolve({
|
||||
code: 10086,
|
||||
msg: (err.message ? err.message : err.code)
|
||||
})
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
function getNowFormatDate() {
|
||||
var date = new Date();
|
||||
var seperator1 = "-";
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var strDate = date.getDate();
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (strDate >= 0 && strDate <= 9) {
|
||||
strDate = "0" + strDate;
|
||||
}
|
||||
var currentdate = year + seperator1 + month + seperator1 + strDate;
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
async function wb() {
|
||||
message = "";
|
||||
signresult = ""
|
||||
taskConfigId = null
|
||||
//签到
|
||||
let signres = await get("activity/signIn", `uid=144846574&date=${getNowFormatDate()}`)
|
||||
console.log(signres.data)
|
||||
if (signres && signres.code == 0) {
|
||||
signres = signres.data
|
||||
let reward = signres.rewards.map(tag => (`${tag.title} ${tag.desc}`)).join(" ")
|
||||
signresult = `${reward} \n 累签 ${signres.signInCount}`
|
||||
} else {
|
||||
signresult = signres.msg
|
||||
}
|
||||
console.log(signresult)
|
||||
message += ` 今日签到:${signresult}\n`
|
||||
//每日暖心福利
|
||||
let freeRes = await get("activity/process/triggerEvent", "eventName=freeLottery&activityCode=454")
|
||||
if (freeRes) {
|
||||
if (freeRes.code == 0) {
|
||||
freeRes = freeRes.data
|
||||
freeResult = freeRes.prize.desc
|
||||
} else {
|
||||
freeResult = freeRes.msg
|
||||
}
|
||||
message += ` 暖心福利:${freeResult}\n`
|
||||
}
|
||||
date = new Date()
|
||||
if (date.getHours() == 12) taskConfigId = 500001
|
||||
if (date.getHours() == 20) taskConfigId = 500002
|
||||
console.log(date.getHours())
|
||||
//午间福利12-13
|
||||
if (taskConfigId) {
|
||||
let Cres = await get("task/userReceiveRewards", `taskConfigId=${taskConfigId}`)
|
||||
console.log(Cres)
|
||||
if (Cres && Cres.code == 0) message += ` 限时登陆:${Cres.data.name}\n`
|
||||
else message += ` 限时登陆:${Cres.msg}\n`
|
||||
}
|
||||
|
||||
//查询
|
||||
let ires = await get("gradeAward/personalInformation", "")
|
||||
if (ires && (ires.code == 0) && ires.data) me = ` 昵称:${ires.data.username}\n 等级:Lv${ires.data.level}\n 距下级差:${ires.data.updateNeedScore}积分\n`
|
||||
let coinfo = await get("shop/getNewShopInfo", "source=100106")
|
||||
if (coinfo && (coinfo.code == 0) && coinfo.data) {
|
||||
codata = coinfo.data.currencyList
|
||||
coinfo = ` 我的资产:钻石 x ${codata[0].count} 金币 x ${codata[1].count} 逗豆 x ${codata[2].count} \n`
|
||||
message = me + coinfo + message
|
||||
}
|
||||
|
||||
return `【玩吧】:\n${message}`
|
||||
}
|
||||
|
||||
module.exports = wb;
|
||||
1475
脚本库/微信小程序/抓包版/快手养号/2026-05-18_ks_yanghao_v1_e24abf45.js
Normal file
1475
脚本库/微信小程序/抓包版/快手养号/2026-05-18_ks_yanghao_v1_e24abf45.js
Normal file
File diff suppressed because it is too large
Load Diff
1475
脚本库/微信小程序/抓包版/快手养号/2026-05-18_ks_yanghao_v1_e24abf45_2.js
Normal file
1475
脚本库/微信小程序/抓包版/快手养号/2026-05-18_ks_yanghao_v1_e24abf45_2.js
Normal file
File diff suppressed because it is too large
Load Diff
57
脚本库/微信小程序/抓包版/快手双版本/2026-05-16_zhks_dual_v2_120e664b.js
Normal file
57
脚本库/微信小程序/抓包版/快手双版本/2026-05-16_zhks_dual_v2_120e664b.js
Normal file
File diff suppressed because one or more lines are too long
57
脚本库/微信小程序/抓包版/快手双版本/2026-05-16_zhks_dual_v2_120e664b_2.js
Normal file
57
脚本库/微信小程序/抓包版/快手双版本/2026-05-16_zhks_dual_v2_120e664b_2.js
Normal file
File diff suppressed because one or more lines are too long
815
脚本库/微信小程序/抓包版/快手双端开源/2026-05-19_ks_dual_open_4a445066.js
Normal file
815
脚本库/微信小程序/抓包版/快手双端开源/2026-05-19_ks_dual_open_4a445066.js
Normal file
@@ -0,0 +1,815 @@
|
||||
// # Source: https://github.com/DearSong15/ql-scripts/blob/main/ks_dual_open.js
|
||||
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/ks_dual_open.js
|
||||
// # Repo: DearSong15/ql-scripts
|
||||
// # Path: ks_dual_open.js
|
||||
// # UploadedAt: 2026-05-19T09:23:01Z
|
||||
// # SHA256: 4a445066e33ac7407d2de6f81605efc0849431d03dcdfdcd647a90509fc3e51f
|
||||
// # Category: 微信小程序/抓包版
|
||||
// # Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
//
|
||||
|
||||
//new Env("快手双端开源")
|
||||
// 当前脚本来自于 http://script.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cc 脚本库下载!
|
||||
// 脚本库官方QQ群1群: 429274456
|
||||
// 脚本库官方QQ群2群: 1077801222
|
||||
// 脚本库官方QQ群3群: 433030897
|
||||
// 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
|
||||
// 脚本库仅提供文件上传和下载服务,不提供脚本文件的审核。
|
||||
// 您在使用脚本库下载的脚本时自行检查判断风险。
|
||||
// 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险,与脚本库无关!均由开发者、上传者、使用者自行承担。
|
||||
|
||||
const axios = require("axios");
|
||||
const querystring = require("querystring");
|
||||
const { SocksProxyAgent } = require("socks-proxy-agent");
|
||||
const dns = require("dns");
|
||||
dns.setDefaultResultOrder("ipv4first");
|
||||
dns.setServers(["8.8.8.8", "114.114.114.114", "223.5.5.5"]);
|
||||
|
||||
// ==============================================
|
||||
// 自定义签名接口:KUAISHOU=81端口 NEBULA=82端口
|
||||
// ==============================================
|
||||
const SIGN_API_KUAISHOU = "http://114.66.27.36:8888"; // 普通版(kpn=KUAISHOU)
|
||||
const SIGN_API_NEBULA = "http://114.66.27.36:8888"; // 极速版(kpn=NEBULA)
|
||||
console.log("💡 普通版签名API: " + SIGN_API_KUAISHOU);
|
||||
console.log("💡 极速版签名API: " + SIGN_API_NEBULA);
|
||||
|
||||
// 全局配置(原配置未改动)
|
||||
const CONFIG = {
|
||||
SEARCH_KEYWORDS: process.env.KS_SEARCH_KEYWORDS?.split(",") || ["短剧小说", "热门视频", "美食教程"],
|
||||
DEFAULT_TASKS: process.env.KS_DEFAULT_TASKS?.split(",") || ["box", "look", "food", "search"],
|
||||
CYCLE_ROUNDS: parseInt(process.env.KS_CYCLE_ROUNDS || 0),
|
||||
WATCH_MIN: parseInt(process.env.KS_WATCH_MIN || 30),
|
||||
WATCH_MAX: parseInt(process.env.KS_WATCH_MAX || 40),
|
||||
AD_FAIL_LIMIT: parseInt(process.env.KS_AD_FAIL_LIMIT || 10),
|
||||
CONTINUOUS_1COIN_LIMIT: parseInt(process.env.KS_CONTINUOUS_1COIN_LIMIT || 3),
|
||||
APPEND_REST_INTERVAL: parseInt(process.env.KS_APPEND_INTERVAL || 5),
|
||||
APPEND_REST_MIN: parseInt(process.env.KS_APPEND_MIN || 5000),
|
||||
APPEND_REST_MAX: parseInt(process.env.KS_APPEND_MAX || 10000),
|
||||
LOW_REWARD_THRESHOLD: parseInt(process.env.KS_LOW_REWARD_THRESHOLD || 10),
|
||||
LOW_REWARD_LIMIT: parseInt(process.env.KS_LOW_REWARD_LIMIT || 3),
|
||||
PLATFORM_CONFIG: {
|
||||
KUAISHOU: {
|
||||
name: "KS",
|
||||
accountInfoUrl: "https://encourage.kuaishou.com/rest/wd/encourage/account/basicInfo",
|
||||
host: "encourage.kuaishou.com",
|
||||
appId: "kuaishou",
|
||||
packageName: "com.smile.gifmaker",
|
||||
appName: "快手",
|
||||
displayName: "快手",
|
||||
kpn: "KUAISHOU",
|
||||
adClientKey: "3c2cd3f3",
|
||||
reportClientKey: "3c2cd3f3"
|
||||
},
|
||||
NEBULA: {
|
||||
name: "JSB",
|
||||
accountInfoUrl: "https://nebula.kuaishou.com/rest/n/nebula/activity/earn/overview/basicInfo",
|
||||
host: "nebula.kuaishou.com",
|
||||
appId: "kuaishou_nebula",
|
||||
packageName: "com.kuaishou.nebula",
|
||||
appName: "快手极速版",
|
||||
displayName: "快手极速版",
|
||||
kpn: "NEBULA",
|
||||
adClientKey: "2ac2a76d",
|
||||
reportClientKey: "2ac2a76d"
|
||||
}
|
||||
},
|
||||
TASK_CONFIGS: {
|
||||
KUAISHOU: {
|
||||
box: {
|
||||
name: "宝箱广告",
|
||||
businessId: 604, posId: 20345, subPageId: 100024063,
|
||||
requestSceneType: 1, taskType: 1, pageId: 100011251
|
||||
},
|
||||
look: {
|
||||
name: "看广告得金币",
|
||||
businessId: 671, posId: 24068, subPageId: 100026368,
|
||||
requestSceneType: 1, taskType: 1, pageId: 100011251
|
||||
},
|
||||
food: {
|
||||
name: "饭补广告",
|
||||
businessId: 921, posId: 29742, subPageId: 100029908,
|
||||
requestSceneType: 7, taskType: 2, pageId: 100011251
|
||||
},
|
||||
search: {
|
||||
name: "搜索广告",
|
||||
businessId: 7077, posId: 216267, subPageId: 100161535,
|
||||
pageId: 10014, requestSceneType: 1, taskType: 2,
|
||||
linkUrl: "eyJwYWdlSWQiOjEwMDE0LCJzdWJQYWdlSWQiOjEwMDE2MTUzNSwicG9zSWQiOjIxNjI2NywiYnVzaW5lc3NJZCI6NzA3NywiZXh0UGFyYW1zIjoiYzc4OWI1ZTAzMjMxOTUwZjcyM2ZjMWE1ZGJjYzgwNmYzMDE1OTcyZWE0Mzc2NmNlNDYwNTk2ZDgzMGVjNTE5MDM0OGEwNTlkOTA2NWYwZGY1ZjkwY2YwMjEwMGVhMmQzYzU0YjUyZDBlNGUxY2Q0NmMxN2ExZDU3YmRhY2EyMzVlM2U1NjYzN2JmZGQzMThiZWMzNTgzOWU1YzIxNWUyNzMzY2IyMzQ2ZGQ1NDYyODc1NDdlMjc4OWYxMjZjZWU5NWZhYzg4N2IxMzM2MzBlZTEzYTVmYTlhODYzNDYxODQ5MjM0NDk3ZGY3ZTRmOWYyYzk2ZjQ5YzViMGExNzQ2NGE2MGM0MDg1MzU2NTY2ZDc4NGIxYjY3NzY3MzYzYjg3IiwiY3VzdG9tRGF0YSI6eyJleGl0SW5mbyI6eyJ0b2FzdERlc2MiOm51bGwsInRvYXN0SW1nVXJsIjpudWxsfX0sInBlbmRhbnRUeXBlIjoxLCJkaXNwbGF5VHlwZSI6Miwic2luZ2xlUGFnZUlkIjowLCJzaW5nbGVTdWJQYWdlSWQiOjAsImNoYW5uZWwiOjAsImNvdW50ZG93blJlcG9ydCI6ZmFsc2UsInRoZW1lVHlwZSI6MCwibWl4ZWRBZCI6dHJ1ZSwiZnVsbE1peGVkIjp0cnVlLCJhdXRvUmVwb3J0Ijp0cnVlLCJmcm9tVGFza0NlbnRlciI6dHJ1ZSwic2VhcmNoSW5zcGlyZVNjaGVtZUluZm8iOm51bGwsImFtb3VudCI6MH0="
|
||||
}
|
||||
},
|
||||
NEBULA: {
|
||||
box: {
|
||||
name: "宝箱广告",
|
||||
pageId: 11101, subPageId: 100024064, businessId: 606, posId: 20346,
|
||||
requestSceneType: 1, taskType: 1
|
||||
},
|
||||
look: {
|
||||
name: "看广告得金币",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 672, posId: 24067,
|
||||
requestSceneType: 1, taskType: 1
|
||||
},
|
||||
food: {
|
||||
name: "饭补广告",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 9362, posId: 24067,
|
||||
requestSceneType: 7, taskType: 2
|
||||
},
|
||||
search: {
|
||||
name: "搜索广告",
|
||||
pageId: 11014, subPageId: 100161537, businessId: 7076, posId: 216268,
|
||||
requestSceneType: 1, taskType: 1,
|
||||
linkUrl: "eyJwYWdlSWQiOjExMDE0LCJzdWJQYWdlSWQiOjEwMDE2MTUzNywicG9zSWQiOjIxNjI2OCwiYnVzaW5lc3NJZCI6NzA3NiwiZXh0UGFyYW1zIjoiYjc4OWI1ZTAzMjMxOTUwZjcyM2ZjMWE1ZGJjYzgwNmYzMDE1OTcyZWE0Mzc2NmNlNDYwNTk2ZDgzMGVjNTE5MDM0OGEwNTlkOTA2NWYwZGY1ZjkwY2YwMjEwMGVhMmQzYzU0YjUyZDBlNGUxY2Q0NmMxN2ExZDU3YmRhY2EyMzVlM2U1NjYzN2JmZGQzMThiZWMzNTgzOWU1YzIxNWUyNzMzY2IyMzQ2ZGQ1NDYyODc1NDdlMjc4OWYxMjZjZWU5NWZhYzg4N2IxMzM2MzBlZTEzYTVmYTlhODYzNDYxODQ5MjM0NDk3ZGY3ZTRmOWYyYzk2ZjQ5YzViMGExNzQ2NGE2MGM0MDg1MzU2NTY2ZDc4NGIxYjY3NzY3MzYzYjg3IiwiY3VzdG9tRGF0YSI6eyJleGl0SW5mbyI6eyJ0b2FzdERlc2MiOm51bGwsInRvYXN0SW1nVXJsIjpudWxsfX0sInBlbmRhbnRUeXBlIjoxLCJkaXNwbGF5VHlwZSI6Miwic2luZ2xlUGFnZUlkIjowLCJzaW5nbGVTdWJQYWdlSWQiOjAsImNoYW5uZWwiOjAsImNvdW50ZG93blJlcG9ydCI6ZmFsc2UsInRoZW1lVHlwZSI6MCwibWl4ZWRBZCI6dHJ1ZSwiZnVsbE1peGVkIjp0cnVlLCJhdXRvUmVwb3J0Ijp0cnVlLCJmcm9tVGFza0NlbnRlciI6dHJ1ZSwic2VhcmNoSW5zcGlyZVNjaGVtZUluZm8iOm51bGwsImFtb3VudCI6MH0="
|
||||
},
|
||||
follow: {
|
||||
name: "关注广告",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 672, posId: 24067,
|
||||
requestSceneType: 2, taskType: 1
|
||||
},
|
||||
content: {
|
||||
name: "内容广告",
|
||||
pageId: 11101, subPageId: 100141480, businessId: 7054, posId: 186550,
|
||||
requestSceneType: 1, taskType: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let localPublicIP = null;
|
||||
|
||||
// ==============================================
|
||||
// 工具函数(原代码未改动)
|
||||
// ==============================================
|
||||
function getTime() {
|
||||
return new Date().toLocaleTimeString("zh-CN", {
|
||||
timeZone: "Asia/Shanghai", hour12: false,
|
||||
hour: "2-digit", minute: "2-digit", second: "2-digit"
|
||||
});
|
||||
}
|
||||
function getProxyTag(useProxy) { return useProxy ? "[代理]" : "[直连]"; }
|
||||
function maskProxyUrl(proxy) {
|
||||
if (!proxy) return null;
|
||||
try {
|
||||
const match = proxy.match(/^(socks5:\/\/)([^:@]+)(?::([^@]+))?@(.+)$/);
|
||||
if (match) {
|
||||
const [, protocol, user, , host] = match;
|
||||
return `${protocol}${user}:***@${host}`;
|
||||
}
|
||||
} catch (e) {}
|
||||
return proxy;
|
||||
}
|
||||
function log(useProxy, appName, msg) {
|
||||
const tag = getProxyTag(useProxy);
|
||||
const app = appName === "快手极速版" ? "快手极速版" : "快手";
|
||||
console.log(`${tag}<${app}>(${getTime()}): ${msg}`);
|
||||
}
|
||||
function print(msg) { console.log(msg); }
|
||||
|
||||
// ==============================================
|
||||
// 网络请求封装(原代码未改动)
|
||||
// ==============================================
|
||||
async function request(options, proxy = null, title = "请求") {
|
||||
try {
|
||||
const axiosOptions = {
|
||||
method: options.method || "GET",
|
||||
url: options.url,
|
||||
headers: options.headers || {},
|
||||
data: options.body || options.form,
|
||||
timeout: options.timeout || 12000,
|
||||
validateStatus: () => true
|
||||
};
|
||||
if (proxy) {
|
||||
const agent = new SocksProxyAgent(proxy, { timeout: 10000, keepAlive: false });
|
||||
axiosOptions.httpAgent = agent;
|
||||
axiosOptions.httpsAgent = agent;
|
||||
} else {
|
||||
axiosOptions.proxy = false;
|
||||
}
|
||||
if (options.form && options.method === "POST" && !axiosOptions.headers["Content-Type"]) {
|
||||
axiosOptions.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
|
||||
axiosOptions.data = querystring.stringify(options.form);
|
||||
}
|
||||
const resp = await axios(axiosOptions);
|
||||
return { body: resp.data, status: resp.status };
|
||||
} catch (e) {
|
||||
console.log(`[请求失败] ${title}: ${e.message}`);
|
||||
return { body: null, status: 0 };
|
||||
}
|
||||
}
|
||||
async function checkLocalIP() {
|
||||
print("正在检测本地直连公网IP...");
|
||||
const urls = ["http://icanhazip.com", "http://ipinfo.io/ip", "http://httpbin.org/ip"];
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const res = await axios.get(url, { timeout: 5000, responseType: "text", proxy: false });
|
||||
const ip = res.data.trim().match(/\d+\.\d+\.\d+\.\d+/)?.[0];
|
||||
if (ip) {
|
||||
localPublicIP = ip;
|
||||
print("本地直连公网IP: " + ip);
|
||||
return ip;
|
||||
}
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
print("本地直连公网IP检测失败");
|
||||
process.exit(1);
|
||||
}
|
||||
async function checkProxyIP(proxy) {
|
||||
const urls = ["http://icanhazip.com", "http://ipinfo.io/ip", "http://httpbin.org/ip"];
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const { body } = await request({ method: "GET", url, timeout: 8000 }, proxy, "代理IP检测");
|
||||
if (!body) continue;
|
||||
const ip = body.toString().trim().match(/\d+\.\d+\.\d+\.\d+/)?.[0];
|
||||
if (ip) return ip;
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 签名接口 - 核心修改:按kpn自动切换接口
|
||||
// ==============================================
|
||||
async function getEncSign(base64Data, proxy, appName, remark, kpnType) {
|
||||
// 按kpn选签名接口:KUAISHOU=81 NEBULA=82
|
||||
const SIGN_API_URL = kpnType === "KUAISHOU" ? SIGN_API_KUAISHOU : SIGN_API_NEBULA;
|
||||
try {
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: SIGN_API_URL + "/encsign",
|
||||
headers: { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" },
|
||||
body: JSON.stringify({ data: base64Data }),
|
||||
timeout: 15000
|
||||
}, null, `获取加密签名`);
|
||||
if (body && body.status) return body.data;
|
||||
log(proxy, appName, `❌ ${remark} encsign 失败: ${body?.message || body?.error || "无响应"}`);
|
||||
return null;
|
||||
} catch (e) {
|
||||
log(proxy, appName, `❌ ${remark} encsign 异常: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function getNsSign(reqInfo, proxy, appName, remark, kpnType) {
|
||||
// 按kpn选签名接口:KUAISHOU=81 NEBULA=82
|
||||
const SIGN_API_URL = kpnType === "KUAISHOU" ? SIGN_API_KUAISHOU : SIGN_API_NEBULA;
|
||||
try {
|
||||
const payload = {
|
||||
path: reqInfo.urlpath,
|
||||
data: reqInfo.reqdata,
|
||||
salt: reqInfo.salt
|
||||
};
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: SIGN_API_URL + "/nssig",
|
||||
headers: { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" },
|
||||
body: JSON.stringify(payload),
|
||||
timeout: 15000
|
||||
}, null, `获取nssig签名`);
|
||||
if (body && body.data) {
|
||||
return {
|
||||
sig: body.data.sig,
|
||||
__NStokensig: body.data.nstokensig,
|
||||
__NS_sig3: body.data.nssig3,
|
||||
__NS_xfalcon: body.data.nssig4 || body.data.xfalcon || ""
|
||||
};
|
||||
}
|
||||
log(proxy, appName, `❌ ${remark} nssig 失败: ${body?.error || body?.message || "无响应"}`);
|
||||
return null;
|
||||
} catch (e) {
|
||||
log(proxy, appName, `❌ ${remark} nssig 异常: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号信息获取(原代码未改动)
|
||||
// ==============================================
|
||||
async function getUserInfo(cookie, platform, proxy) {
|
||||
try {
|
||||
const { body } = await request({
|
||||
method: "GET",
|
||||
url: platform.accountInfoUrl,
|
||||
headers: {
|
||||
Host: platform.host,
|
||||
"User-Agent": "kwai-android aegon/3.56.0",
|
||||
Cookie: cookie,
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
timeout: 12000
|
||||
}, proxy, "获取账号信息");
|
||||
if (body && body.result === 1 && body.data) {
|
||||
let coin = 0, cash = 0;
|
||||
if (platform.name === "KS") {
|
||||
coin = Number(body.data.coinAmount) || 0;
|
||||
cash = Number(body.data.cashAmountDisplay) || 0;
|
||||
} else {
|
||||
coin = Number(body.data.totalCoin) || 0;
|
||||
cash = Number(body.data.allCash) || 0;
|
||||
}
|
||||
return {
|
||||
nickname: body.data.userData?.nickname || null,
|
||||
totalCoin: coin, allCash: cash,
|
||||
success: true, ckExpired: false
|
||||
};
|
||||
}
|
||||
return { nickname: null, totalCoin: 0, allCash: 0, success: false, ckExpired: true };
|
||||
} catch (e) {
|
||||
return { nickname: null, totalCoin: 0, allCash: 0, success: false, ckExpired: true };
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号任务类 - 仅传kpnType到签名函数,其余未改
|
||||
// ==============================================
|
||||
class KuaishouAccount {
|
||||
constructor({ index = 1, salt, cookie, remark = "未命名", proxyUrl = null, tasksToExecute = CONFIG.DEFAULT_TASKS }) {
|
||||
this.index = index;
|
||||
this.salt = salt;
|
||||
this.cookie = cookie;
|
||||
this.remark = remark;
|
||||
this.proxyUrl = proxyUrl;
|
||||
this.platform = this.getPlatformByCookie(cookie);
|
||||
this.kpnType = this.platform.kpn; // 新增:获取kpn类型(KUAISHOU/NEBULA)
|
||||
this.tasksToRun = tasksToExecute.filter(Boolean);
|
||||
this.taskConfigs = CONFIG.TASK_CONFIGS[this.platform.kpn === "NEBULA" ? "NEBULA" : "KUAISHOU"];
|
||||
this.lowRewardCount = 0;
|
||||
this.lowRewardStreak = 0;
|
||||
this.adFailCount = 0;
|
||||
this.continuous1Coin = 0;
|
||||
this.stopAll = false;
|
||||
this.taskStats = {};
|
||||
this.taskLimit = {};
|
||||
this.taskDisabled = {};
|
||||
this.tasksToRun.forEach(task => {
|
||||
this.taskStats[task] = { success: 0, failed: 0, totalReward: 0 };
|
||||
this.taskLimit[task] = false;
|
||||
this.taskDisabled[task] = false;
|
||||
});
|
||||
this.isCycleMode = CONFIG.CYCLE_ROUNDS > 0;
|
||||
this.cycleRounds = CONFIG.CYCLE_ROUNDS;
|
||||
this.currentRound = 0;
|
||||
this.currentTaskIndex = 0;
|
||||
this.parseCookie();
|
||||
this.clientIP = null;
|
||||
}
|
||||
getPlatformByCookie(cookie) {
|
||||
const match = cookie.match(/kpn=([^;]+)/);
|
||||
const kpn = match ? match[1].toUpperCase() : "KUAISHOU";
|
||||
return kpn === "NEBULA" ? CONFIG.PLATFORM_CONFIG.NEBULA : CONFIG.PLATFORM_CONFIG.KUAISHOU;
|
||||
}
|
||||
parseCookie() {
|
||||
try {
|
||||
this.mod = this.cookie.match(/mod=([^;]+)/)?.[1] || "Xiaomi(23116PN5BC)";
|
||||
this.egid = this.cookie.match(/egid=([^;]+)/)?.[1] || "";
|
||||
this.did = this.cookie.match(/did=([^;]+)/)?.[1] || "";
|
||||
this.userId = this.cookie.match(/userId=([^;]+)/)?.[1] || "";
|
||||
this.apiSt = this.cookie.match(/kuaishou\.api_st=([^;]+)/)?.[1] || "";
|
||||
this.appver = this.cookie.match(/appver=([^;]+)/)?.[1] || "13.7.20.10468";
|
||||
this.queryParams = `mod=${this.mod}&appver=${this.appver}&egid=${this.egid}&did=${this.did}`;
|
||||
} catch (e) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 解析cookie失败: ${e.message}`);
|
||||
}
|
||||
}
|
||||
async initIP() {
|
||||
try {
|
||||
if (this.proxyUrl) {
|
||||
log(null, this.platform.displayName, `账号 [${this.remark}] 代理: ${maskProxyUrl(this.proxyUrl)}`);
|
||||
const ip = await checkProxyIP(this.proxyUrl);
|
||||
if (!ip) {
|
||||
this.stopAll = true;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 初始化失败:代理IP检测无有效结果`);
|
||||
return;
|
||||
}
|
||||
this.clientIP = ip;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 代理出口IP: ${ip}`);
|
||||
} else {
|
||||
if (!localPublicIP) await checkLocalIP();
|
||||
this.clientIP = localPublicIP;
|
||||
}
|
||||
} catch (e) {
|
||||
this.stopAll = true;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 初始化失败:${e.message}`);
|
||||
}
|
||||
}
|
||||
async retry(fn, desc, times = 3, delay = 2000) {
|
||||
let cnt = 0;
|
||||
while (cnt < times && !this.stopAll) {
|
||||
try {
|
||||
const res = await fn();
|
||||
if (res) return res;
|
||||
} catch (e) {}
|
||||
cnt++;
|
||||
if (cnt < times && !this.stopAll) await new Promise(r => setTimeout(r, delay));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getImpExt(task) {
|
||||
if (task.name.includes("搜索")) {
|
||||
const word = CONFIG.SEARCH_KEYWORDS[Math.floor(Math.random() * CONFIG.SEARCH_KEYWORDS.length)];
|
||||
return JSON.stringify({
|
||||
openH5AdCount: 2,
|
||||
sessionLookedCompletedCount: "1",
|
||||
sessionType: "1",
|
||||
searchKey: word,
|
||||
triggerType: "2",
|
||||
disableReportToast: "true",
|
||||
businessEnterAction: "7",
|
||||
neoParams: task.linkUrl || ""
|
||||
});
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
async getAdInfo(taskKey) {
|
||||
const task = this.taskConfigs[taskKey];
|
||||
if (!task) return null;
|
||||
const adUrl = "/rest/e/reward/mixed/ad";
|
||||
const commonData = {
|
||||
encData: "|encData|",
|
||||
sign: "|sign|",
|
||||
cs: "false",
|
||||
client_key: this.platform.adClientKey,
|
||||
videoModelCrowdTag: "1_23",
|
||||
os: "android",
|
||||
"kuaishou.api_st": this.apiSt,
|
||||
uQaTag: "1##swLdgl:99#ecPp:-9#cmNt:-0#cmHs:-3#cmMnsl:-0"
|
||||
};
|
||||
const deviceData = {
|
||||
earphoneMode: "1", mod: this.mod, appver: this.appver,
|
||||
isp: "CUCC", language: "zh-cn", ud: this.userId,
|
||||
did_tag: "0", net: "WIFI", kcv: "1599", app: "0",
|
||||
kpf: "ANDROID_PHONE", ver: "11.6", android_os: "0",
|
||||
boardPlatform: "pineapple", kpn: this.platform.kpn,
|
||||
androidApiLevel: "35", country_code: "cn", sys: "ANDROID_15",
|
||||
sw: "1080", sh: "2400", abi: "arm64", userRecoBit: "0"
|
||||
};
|
||||
const impData = {
|
||||
appInfo: {
|
||||
appId: this.platform.appId, name: this.platform.appName,
|
||||
packageName: this.platform.packageName, version: this.appver, versionCode: -1
|
||||
},
|
||||
deviceInfo: { osType: 1, osVersion: "15", deviceId: this.did, screenSize: { width: 1080, height: 2249 }, ftt: "" },
|
||||
userInfo: { userId: this.userId, age: 0, gender: "" },
|
||||
impInfo: [{
|
||||
pageId: task.pageId || 100011251,
|
||||
subPageId: task.subPageId,
|
||||
action: 0,
|
||||
browseType: task.name.includes("搜索") ? 4 : 3,
|
||||
impExtData: this.getImpExt(task),
|
||||
mediaExtData: "{}"
|
||||
}]
|
||||
};
|
||||
const base64Imp = Buffer.from(JSON.stringify(impData)).toString("base64");
|
||||
// 传kpnType到签名函数
|
||||
const encSign = await this.retry(
|
||||
() => getEncSign(base64Imp, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"获取广告加密签名"
|
||||
);
|
||||
if (!encSign) return null;
|
||||
commonData.encData = encSign.encdata;
|
||||
commonData.sign = encSign.sign;
|
||||
// 传kpnType到签名函数
|
||||
const nsSign = await this.retry(
|
||||
() => getNsSign({
|
||||
urlpath: adUrl,
|
||||
reqdata: querystring.stringify(commonData) + "&" + querystring.stringify(deviceData),
|
||||
salt: this.salt
|
||||
}, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"获取广告请求nssig"
|
||||
);
|
||||
if (!nsSign) return null;
|
||||
const reqQuery = {
|
||||
...deviceData,
|
||||
sig: nsSign.sig,
|
||||
__NS_sig3: nsSign.__NS_sig3,
|
||||
__NS_xfalcon: nsSign.__NS_xfalcon,
|
||||
__NStokensig: nsSign.__NStokensig
|
||||
};
|
||||
const finalUrl = "https://api.e.kuaishou.com" + adUrl + "?" + querystring.stringify(reqQuery);
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: finalUrl,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
Host: "api.e.kuaishou.com",
|
||||
"User-Agent": "kwai-android aegon/3.56.0",
|
||||
Cookie: this.cookie
|
||||
},
|
||||
form: commonData,
|
||||
timeout: 12000
|
||||
}, this.proxyUrl, "获取广告");
|
||||
if (!body) {
|
||||
this.adFailCount++;
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) this.stopAll = true;
|
||||
return null;
|
||||
}
|
||||
if (body.errorMsg === "OK" && body.feeds?.[0]?.ad) {
|
||||
const ad = body.feeds[0];
|
||||
const title = (ad.caption || ad.ad?.caption || "").slice(0, 30) + "...";
|
||||
let coin = 0;
|
||||
try {
|
||||
const ext = JSON.parse(ad.ad.extData);
|
||||
coin = Number(ext.awardCoin) || 0;
|
||||
if (coin === 0) {
|
||||
coin = ad.ad.adDataV2?.inspirePersonalize?.awardValue ||
|
||||
ad.ad.adDataV2?.inspireAdInfo?.inspirePersonalize?.neoValue || 0;
|
||||
}
|
||||
} catch (e) {}
|
||||
if (coin === 5) return null;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 获取广告成功:${title}`);
|
||||
log(null, this.platform.displayName, `${this.remark} 预计获得: ${coin} 金币`);
|
||||
return {
|
||||
cid: ad.ad.creativeId,
|
||||
llsid: ad.exp_tag?.split("/")?.[1]?.split("_")?.[0] || "",
|
||||
hasRewardEnd: ad.ad.adDataV2?.onceAgainRewardInfo?.hasMore || false,
|
||||
expectedCoins: coin,
|
||||
taskConfig: task
|
||||
};
|
||||
}
|
||||
this.adFailCount++;
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) this.stopAll = true;
|
||||
return null;
|
||||
}
|
||||
async genReportSign(cid, llsid, task) {
|
||||
try {
|
||||
const bizStr = JSON.stringify({
|
||||
businessId: task.businessId,
|
||||
endTime: Date.now(),
|
||||
extParams: "",
|
||||
mediaScene: "video",
|
||||
neoInfos: [{
|
||||
creativeId: cid, extInfo: "", llsid,
|
||||
requestSceneType: task.requestSceneType,
|
||||
taskType: task.taskType,
|
||||
watchExpId: "", watchStage: 0
|
||||
}],
|
||||
pageId: task.pageId || 100011251,
|
||||
posId: task.posId,
|
||||
reportType: 0,
|
||||
sessionId: "",
|
||||
startTime: Date.now() - 30000,
|
||||
subPageId: task.subPageId
|
||||
});
|
||||
const postData = `bizStr=${encodeURIComponent(bizStr)}&cs=false&client_key=${this.platform.reportClientKey}`;
|
||||
const qs = this.queryParams + "&" + postData;
|
||||
// 传kpnType到签名函数
|
||||
const sign = await this.retry(
|
||||
() => getNsSign({
|
||||
urlpath: "/rest/r/ad/task/report",
|
||||
reqdata: qs,
|
||||
salt: this.salt
|
||||
}, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"生成报告签名"
|
||||
);
|
||||
if (!sign) return null;
|
||||
return {
|
||||
sig: sign.sig, sig3: sign.__NS_sig3,
|
||||
xfalcon: sign.__NS_xfalcon, sigtoken: sign.__NStokensig,
|
||||
post: postData
|
||||
};
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async submitReport(cid, llsid, taskKey, task) {
|
||||
const sign = await this.genReportSign(cid, llsid, task);
|
||||
if (!sign) return { success: false, reward: 0 };
|
||||
const url = "https://api.e.kuaishou.com/rest/r/ad/task/report?" +
|
||||
`${this.queryParams}&sig=${sign.sig}&__NS_sig3=${sign.sig3}&__NS_xfalcon=${sign.xfalcon}&__NStokensig=${sign.sigtoken}`;
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
Host: "api.e.kuaishou.com",
|
||||
Cookie: this.cookie,
|
||||
"User-Agent": "kwai-android aegon/3.56.0"
|
||||
},
|
||||
form: querystring.parse(sign.post),
|
||||
timeout: 12000
|
||||
}, this.proxyUrl, "提交任务报告");
|
||||
if (!body) return { success: false, reward: 0 };
|
||||
if (body.result === 1) {
|
||||
const coin = Number(body.data?.neoAmount) || 0;
|
||||
this.taskStats[taskKey].totalReward += coin;
|
||||
if (coin === 1) {
|
||||
this.continuous1Coin++;
|
||||
if (this.continuous1Coin >= CONFIG.CONTINUOUS_1COIN_LIMIT) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 连续${CONFIG.CONTINUOUS_1COIN_LIMIT}次1金币,停止任务`);
|
||||
this.stopAll = true;
|
||||
}
|
||||
} else {
|
||||
this.continuous1Coin = 0;
|
||||
}
|
||||
if (coin <= CONFIG.LOW_REWARD_THRESHOLD) {
|
||||
this.lowRewardStreak++;
|
||||
if (this.lowRewardStreak >= CONFIG.LOW_REWARD_LIMIT) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 连续低奖励超限,停止任务`);
|
||||
this.stopAll = true;
|
||||
}
|
||||
} else {
|
||||
this.lowRewardStreak = 0;
|
||||
}
|
||||
return { success: true, reward: coin };
|
||||
}
|
||||
if ([20107, 20108, 1003, 415].includes(body.result)) {
|
||||
return { success: false, reward: 0, limitReached: true };
|
||||
}
|
||||
return { success: false, reward: 0 };
|
||||
}
|
||||
async runTask(taskKey) {
|
||||
if (this.taskDisabled[taskKey] || this.taskLimit[taskKey] || this.stopAll) return { success: false, reward: 0 };
|
||||
let adInfo = null;
|
||||
while (!adInfo && !this.stopAll) {
|
||||
adInfo = await this.getAdInfo(taskKey);
|
||||
if (!adInfo && !this.stopAll) await new Promise(r => setTimeout(r, 3000));
|
||||
}
|
||||
if (!adInfo) {
|
||||
this.taskStats[taskKey].failed++;
|
||||
return { success: false, reward: 0 };
|
||||
}
|
||||
const watchMs = Math.floor(Math.random() * (CONFIG.WATCH_MAX - CONFIG.WATCH_MIN) + CONFIG.WATCH_MIN) * 1000;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 观看广告中,等待 ${Math.round(watchMs/1000)} 秒...`);
|
||||
await new Promise(r => setTimeout(r, watchMs));
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 观看完成,提交任务报告`);
|
||||
const result = await this.submitReport(adInfo.cid, adInfo.llsid, taskKey, adInfo.taskConfig);
|
||||
if (result.success) {
|
||||
this.taskStats[taskKey].success++;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} ✅ 提交成功!获得 ${result.reward} 金币`);
|
||||
return { success: true, reward: result.reward, hasRewardEnd: adInfo.hasRewardEnd };
|
||||
}
|
||||
if (result.limitReached) this.taskLimit[taskKey] = true;
|
||||
this.taskStats[taskKey].failed++;
|
||||
return { success: false, reward: 0, limitReached: result.limitReached || false };
|
||||
}
|
||||
nextTask() {
|
||||
const available = this.tasksToRun.filter(t => !this.taskLimit[t] && !this.taskDisabled[t]);
|
||||
if (available.length === 0 || this.stopAll) return null;
|
||||
this.currentTaskIndex = (this.currentTaskIndex + 1) % available.length;
|
||||
return available[this.currentTaskIndex];
|
||||
}
|
||||
async restAfterAd(count) {
|
||||
if (count > 0 && count % CONFIG.APPEND_REST_INTERVAL === 0) {
|
||||
const ms = Math.floor(Math.random() * (CONFIG.APPEND_REST_MAX - CONFIG.APPEND_REST_MIN)) + CONFIG.APPEND_REST_MIN;
|
||||
await new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
}
|
||||
async run() {
|
||||
await this.initIP();
|
||||
if (this.stopAll) {
|
||||
return { success: false, remark: this.remark, platform: this.platform.name, taskCount: 0, totalReward: 0, exitIP: this.clientIP, stopReason: "初始化失败" };
|
||||
}
|
||||
const user = await getUserInfo(this.cookie, this.platform, this.proxyUrl);
|
||||
if (!user.success || user.ckExpired) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} Cookie已过期或无效`);
|
||||
return { success: false, remark: this.remark, platform: this.platform.name, taskCount: 0, totalReward: 0, exitIP: this.clientIP, stopReason: "Cookie过期" };
|
||||
}
|
||||
log(this.proxyUrl, this.platform.displayName,
|
||||
`${this.remark} 登录成功 | 昵称: ${user.nickname || "未知"} | 金币: ${user.totalCoin} | 余额: ${user.allCash.toFixed(2)}`);
|
||||
let totalTasks = 0, appendTasks = 0, stopReason = "正常结束";
|
||||
while (!this.stopAll) {
|
||||
if (this.isCycleMode && this.currentRound >= this.cycleRounds) {
|
||||
stopReason = `已完成${this.cycleRounds}轮任务`;
|
||||
break;
|
||||
}
|
||||
const task = this.nextTask();
|
||||
if (!task) { stopReason = "无可用任务"; this.stopAll = true; break; }
|
||||
const res = await this.runTask(task);
|
||||
totalTasks++;
|
||||
if (res.hasRewardEnd) {
|
||||
appendTasks++;
|
||||
await this.restAfterAd(appendTasks);
|
||||
await this.runTask(task);
|
||||
}
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) { stopReason = "广告获取失败达上限"; this.stopAll = true; }
|
||||
if (this.nextTask() && !this.stopAll) {
|
||||
const delay = Math.floor(Math.random() * 5 + 5) * 1000;
|
||||
await new Promise(r => setTimeout(r, delay));
|
||||
}
|
||||
if (this.isCycleMode && this.currentTaskIndex === this.tasksToRun.length - 1) this.currentRound++;
|
||||
}
|
||||
const totalReward = Object.values(this.taskStats).reduce((s, t) => s + t.totalReward, 0);
|
||||
log(this.proxyUrl, this.platform.displayName,
|
||||
`${this.remark} 结束 | 执行任务: ${totalTasks} | 总获金币: ${totalReward} | 原因: ${stopReason}`);
|
||||
for (const [k, s] of Object.entries(this.taskStats)) {
|
||||
const cfg = this.taskConfigs[k];
|
||||
if (cfg) log(null, this.platform.displayName, ` └ ${cfg.name}: 成功${s.success}次 失败${s.failed}次 奖励${s.totalReward}金币`);
|
||||
}
|
||||
return { success: true, remark: this.remark, platform: this.platform.name, taskCount: totalTasks, appendCount: appendTasks, totalReward, exitIP: this.clientIP, stopReason };
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号解析 & 批量执行(原代码未改动)
|
||||
// ==============================================
|
||||
function parseAccountLine(line, index) {
|
||||
if (!line || typeof line !== "string") return null;
|
||||
const parts = line.split("#");
|
||||
if (parts.length < 3) return null;
|
||||
const remark = parts[0].trim() || `账号${index}`;
|
||||
const cookie = parts[1].trim();
|
||||
const salt = parts[2].trim();
|
||||
let proxy = parts[3]?.trim() || null;
|
||||
if (!cookie || !salt) return null;
|
||||
if (proxy && proxy.includes("|")) {
|
||||
const [host, port, user, pwd] = proxy.split("|");
|
||||
proxy = `socks5://${user}:${pwd}@${host}:${port}`;
|
||||
}
|
||||
if (proxy && !/^socks5:\/\//i.test(proxy)) {
|
||||
console.log(`⚠️ 账号${index} 代理格式非socks5,已忽略: ${proxy}`);
|
||||
proxy = null;
|
||||
}
|
||||
return { cookie, salt, remark, proxyUrl: proxy };
|
||||
}
|
||||
function loadAllAccounts() {
|
||||
const accounts = [];
|
||||
const exists = new Set();
|
||||
let index = 1;
|
||||
let proxyCount = 0;
|
||||
const mainCk = process.env.ksck;
|
||||
if (mainCk) {
|
||||
mainCk.split("&").forEach(line => {
|
||||
line = line.trim();
|
||||
if (line && !exists.has(line)) {
|
||||
const acc = parseAccountLine(line, index++);
|
||||
if (acc) { accounts.push(acc); exists.add(line); if (acc.proxyUrl) proxyCount++; }
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 1; i <= 666; i++) {
|
||||
const line = process.env[`ksck${i}`]?.trim();
|
||||
if (line && !exists.has(line)) {
|
||||
const acc = parseAccountLine(line, index++);
|
||||
if (acc) { accounts.push(acc); exists.add(line); if (acc.proxyUrl) proxyCount++; }
|
||||
}
|
||||
}
|
||||
print(`\n✅ 共加载账号: ${accounts.length} 个(其中代理账号: ${proxyCount} 个)`);
|
||||
return accounts;
|
||||
}
|
||||
async function runAccountList(accounts) {
|
||||
const results = [];
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
const acc = accounts[i];
|
||||
print(`\n${"=".repeat(60)}`);
|
||||
print(`🚀 开始执行账号 ${i+1}/${accounts.length}: ${acc.remark}`);
|
||||
print(`${"=".repeat(60)}`);
|
||||
const instance = new KuaishouAccount({ ...acc, index: i + 1 });
|
||||
const result = await instance.run();
|
||||
results.push(result);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
function printSummary(results) {
|
||||
print(`\n${"=".repeat(60)}`);
|
||||
print(" 📊 全部账号执行结果汇总");
|
||||
print(`${"=".repeat(60)}`);
|
||||
let totalReward = 0;
|
||||
results.forEach((r, i) => {
|
||||
const tag = r.platform === "JSB" ? "[极速版]" : "[快手 ]";
|
||||
print(`${tag} 账号${i+1} ${r.remark} | 任务数:${r.taskCount} | 金币:${r.totalReward} | ${r.stopReason}`);
|
||||
totalReward += r.totalReward || 0;
|
||||
});
|
||||
print(`${"=".repeat(60)}`);
|
||||
print(` 🎉 全部完成 | 账号数: ${results.length} | 总金币: ${totalReward}`);
|
||||
print(`${"=".repeat(60)}`);
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 启动(原代码未改动)
|
||||
// ==============================================
|
||||
print("================================================================================");
|
||||
print(" ⭐ 快手双端脚本 ⭐ ");
|
||||
print(" 支持快手 & 快手极速版 · 无需卡密授权 · 按kpn自动切换签名接口 ");
|
||||
print("================================================================================");
|
||||
print(`\n🎯 默认任务: ${CONFIG.DEFAULT_TASKS.join(", ")}`);
|
||||
print(`⏱ 观看时长: ${CONFIG.WATCH_MIN}-${CONFIG.WATCH_MAX} 秒`);
|
||||
print(`🔄 循环轮数: ${CONFIG.CYCLE_ROUNDS > 0 ? CONFIG.CYCLE_ROUNDS : "无限制"}`);
|
||||
print("\n📋 环境变量说明:");
|
||||
print(" ksck = 账号配置,格式: 备注#cookie#salt#socks5代理(可选)");
|
||||
print(" ksck1~ksck666 = 多账号扩展");
|
||||
print(" KS_DEFAULT_TASKS = 任务列表,逗号分隔,可选: box,look,food,search");
|
||||
print(" KS_CYCLE_ROUNDS = 循环轮数 (0=无限)");
|
||||
print(" KS_WATCH_MIN/MAX = 广告观看秒数范围");
|
||||
print(" KS_LOW_REWARD_THRESHOLD = 低奖励阈值");
|
||||
print(" KS_LOW_REWARD_LIMIT = 连续低奖励停止次数");
|
||||
print("================================================================================\n");
|
||||
(async () => {
|
||||
const accounts = loadAllAccounts();
|
||||
if (accounts.length === 0) {
|
||||
print("❌ 未检测到账号配置,请设置 ksck 环境变量");
|
||||
print(" 格式: 备注#cookie字符串#salt值");
|
||||
print(" 示例: 我的账号#did=xxx;userId=yyy;...#abcdef1234");
|
||||
process.exit(1);
|
||||
}
|
||||
const results = await runAccountList(accounts);
|
||||
printSummary(results);
|
||||
})();
|
||||
|
||||
|
||||
// 当前脚本来自于 http://script.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cc 脚本库下载!
|
||||
// 脚本库官方QQ群1群: 429274456
|
||||
// 脚本库官方QQ群2群: 1077801222
|
||||
// 脚本库官方QQ群3群: 433030897
|
||||
// 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
|
||||
// 脚本库仅提供文件上传和下载服务,不提供脚本文件的审核。
|
||||
// 您在使用脚本库下载的脚本时自行检查判断风险。
|
||||
// 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险,与脚本库无关!均由开发者、上传者、使用者自行承担。
|
||||
815
脚本库/微信小程序/抓包版/快手双端开源/2026-05-19_ks_dual_open_4a445066_2.js
Normal file
815
脚本库/微信小程序/抓包版/快手双端开源/2026-05-19_ks_dual_open_4a445066_2.js
Normal file
@@ -0,0 +1,815 @@
|
||||
// # Source: https://github.com/DearSong15/ql-scripts/blob/main/ks_dual_open.js
|
||||
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/ks_dual_open.js
|
||||
// # Repo: DearSong15/ql-scripts
|
||||
// # Path: ks_dual_open.js
|
||||
// # UploadedAt: 2026-05-19T09:23:01Z
|
||||
// # SHA256: 4a445066e33ac7407d2de6f81605efc0849431d03dcdfdcd647a90509fc3e51f
|
||||
// # Category: 微信小程序/抓包版
|
||||
// # Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
//
|
||||
|
||||
//new Env("快手双端开源")
|
||||
// 当前脚本来自于 http://script.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cc 脚本库下载!
|
||||
// 脚本库官方QQ群1群: 429274456
|
||||
// 脚本库官方QQ群2群: 1077801222
|
||||
// 脚本库官方QQ群3群: 433030897
|
||||
// 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
|
||||
// 脚本库仅提供文件上传和下载服务,不提供脚本文件的审核。
|
||||
// 您在使用脚本库下载的脚本时自行检查判断风险。
|
||||
// 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险,与脚本库无关!均由开发者、上传者、使用者自行承担。
|
||||
|
||||
const axios = require("axios");
|
||||
const querystring = require("querystring");
|
||||
const { SocksProxyAgent } = require("socks-proxy-agent");
|
||||
const dns = require("dns");
|
||||
dns.setDefaultResultOrder("ipv4first");
|
||||
dns.setServers(["8.8.8.8", "114.114.114.114", "223.5.5.5"]);
|
||||
|
||||
// ==============================================
|
||||
// 自定义签名接口:KUAISHOU=81端口 NEBULA=82端口
|
||||
// ==============================================
|
||||
const SIGN_API_KUAISHOU = "http://114.66.27.36:8888"; // 普通版(kpn=KUAISHOU)
|
||||
const SIGN_API_NEBULA = "http://114.66.27.36:8888"; // 极速版(kpn=NEBULA)
|
||||
console.log("💡 普通版签名API: " + SIGN_API_KUAISHOU);
|
||||
console.log("💡 极速版签名API: " + SIGN_API_NEBULA);
|
||||
|
||||
// 全局配置(原配置未改动)
|
||||
const CONFIG = {
|
||||
SEARCH_KEYWORDS: process.env.KS_SEARCH_KEYWORDS?.split(",") || ["短剧小说", "热门视频", "美食教程"],
|
||||
DEFAULT_TASKS: process.env.KS_DEFAULT_TASKS?.split(",") || ["box", "look", "food", "search"],
|
||||
CYCLE_ROUNDS: parseInt(process.env.KS_CYCLE_ROUNDS || 0),
|
||||
WATCH_MIN: parseInt(process.env.KS_WATCH_MIN || 30),
|
||||
WATCH_MAX: parseInt(process.env.KS_WATCH_MAX || 40),
|
||||
AD_FAIL_LIMIT: parseInt(process.env.KS_AD_FAIL_LIMIT || 10),
|
||||
CONTINUOUS_1COIN_LIMIT: parseInt(process.env.KS_CONTINUOUS_1COIN_LIMIT || 3),
|
||||
APPEND_REST_INTERVAL: parseInt(process.env.KS_APPEND_INTERVAL || 5),
|
||||
APPEND_REST_MIN: parseInt(process.env.KS_APPEND_MIN || 5000),
|
||||
APPEND_REST_MAX: parseInt(process.env.KS_APPEND_MAX || 10000),
|
||||
LOW_REWARD_THRESHOLD: parseInt(process.env.KS_LOW_REWARD_THRESHOLD || 10),
|
||||
LOW_REWARD_LIMIT: parseInt(process.env.KS_LOW_REWARD_LIMIT || 3),
|
||||
PLATFORM_CONFIG: {
|
||||
KUAISHOU: {
|
||||
name: "KS",
|
||||
accountInfoUrl: "https://encourage.kuaishou.com/rest/wd/encourage/account/basicInfo",
|
||||
host: "encourage.kuaishou.com",
|
||||
appId: "kuaishou",
|
||||
packageName: "com.smile.gifmaker",
|
||||
appName: "快手",
|
||||
displayName: "快手",
|
||||
kpn: "KUAISHOU",
|
||||
adClientKey: "3c2cd3f3",
|
||||
reportClientKey: "3c2cd3f3"
|
||||
},
|
||||
NEBULA: {
|
||||
name: "JSB",
|
||||
accountInfoUrl: "https://nebula.kuaishou.com/rest/n/nebula/activity/earn/overview/basicInfo",
|
||||
host: "nebula.kuaishou.com",
|
||||
appId: "kuaishou_nebula",
|
||||
packageName: "com.kuaishou.nebula",
|
||||
appName: "快手极速版",
|
||||
displayName: "快手极速版",
|
||||
kpn: "NEBULA",
|
||||
adClientKey: "2ac2a76d",
|
||||
reportClientKey: "2ac2a76d"
|
||||
}
|
||||
},
|
||||
TASK_CONFIGS: {
|
||||
KUAISHOU: {
|
||||
box: {
|
||||
name: "宝箱广告",
|
||||
businessId: 604, posId: 20345, subPageId: 100024063,
|
||||
requestSceneType: 1, taskType: 1, pageId: 100011251
|
||||
},
|
||||
look: {
|
||||
name: "看广告得金币",
|
||||
businessId: 671, posId: 24068, subPageId: 100026368,
|
||||
requestSceneType: 1, taskType: 1, pageId: 100011251
|
||||
},
|
||||
food: {
|
||||
name: "饭补广告",
|
||||
businessId: 921, posId: 29742, subPageId: 100029908,
|
||||
requestSceneType: 7, taskType: 2, pageId: 100011251
|
||||
},
|
||||
search: {
|
||||
name: "搜索广告",
|
||||
businessId: 7077, posId: 216267, subPageId: 100161535,
|
||||
pageId: 10014, requestSceneType: 1, taskType: 2,
|
||||
linkUrl: "eyJwYWdlSWQiOjEwMDE0LCJzdWJQYWdlSWQiOjEwMDE2MTUzNSwicG9zSWQiOjIxNjI2NywiYnVzaW5lc3NJZCI6NzA3NywiZXh0UGFyYW1zIjoiYzc4OWI1ZTAzMjMxOTUwZjcyM2ZjMWE1ZGJjYzgwNmYzMDE1OTcyZWE0Mzc2NmNlNDYwNTk2ZDgzMGVjNTE5MDM0OGEwNTlkOTA2NWYwZGY1ZjkwY2YwMjEwMGVhMmQzYzU0YjUyZDBlNGUxY2Q0NmMxN2ExZDU3YmRhY2EyMzVlM2U1NjYzN2JmZGQzMThiZWMzNTgzOWU1YzIxNWUyNzMzY2IyMzQ2ZGQ1NDYyODc1NDdlMjc4OWYxMjZjZWU5NWZhYzg4N2IxMzM2MzBlZTEzYTVmYTlhODYzNDYxODQ5MjM0NDk3ZGY3ZTRmOWYyYzk2ZjQ5YzViMGExNzQ2NGE2MGM0MDg1MzU2NTY2ZDc4NGIxYjY3NzY3MzYzYjg3IiwiY3VzdG9tRGF0YSI6eyJleGl0SW5mbyI6eyJ0b2FzdERlc2MiOm51bGwsInRvYXN0SW1nVXJsIjpudWxsfX0sInBlbmRhbnRUeXBlIjoxLCJkaXNwbGF5VHlwZSI6Miwic2luZ2xlUGFnZUlkIjowLCJzaW5nbGVTdWJQYWdlSWQiOjAsImNoYW5uZWwiOjAsImNvdW50ZG93blJlcG9ydCI6ZmFsc2UsInRoZW1lVHlwZSI6MCwibWl4ZWRBZCI6dHJ1ZSwiZnVsbE1peGVkIjp0cnVlLCJhdXRvUmVwb3J0Ijp0cnVlLCJmcm9tVGFza0NlbnRlciI6dHJ1ZSwic2VhcmNoSW5zcGlyZVNjaGVtZUluZm8iOm51bGwsImFtb3VudCI6MH0="
|
||||
}
|
||||
},
|
||||
NEBULA: {
|
||||
box: {
|
||||
name: "宝箱广告",
|
||||
pageId: 11101, subPageId: 100024064, businessId: 606, posId: 20346,
|
||||
requestSceneType: 1, taskType: 1
|
||||
},
|
||||
look: {
|
||||
name: "看广告得金币",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 672, posId: 24067,
|
||||
requestSceneType: 1, taskType: 1
|
||||
},
|
||||
food: {
|
||||
name: "饭补广告",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 9362, posId: 24067,
|
||||
requestSceneType: 7, taskType: 2
|
||||
},
|
||||
search: {
|
||||
name: "搜索广告",
|
||||
pageId: 11014, subPageId: 100161537, businessId: 7076, posId: 216268,
|
||||
requestSceneType: 1, taskType: 1,
|
||||
linkUrl: "eyJwYWdlSWQiOjExMDE0LCJzdWJQYWdlSWQiOjEwMDE2MTUzNywicG9zSWQiOjIxNjI2OCwiYnVzaW5lc3NJZCI6NzA3NiwiZXh0UGFyYW1zIjoiYjc4OWI1ZTAzMjMxOTUwZjcyM2ZjMWE1ZGJjYzgwNmYzMDE1OTcyZWE0Mzc2NmNlNDYwNTk2ZDgzMGVjNTE5MDM0OGEwNTlkOTA2NWYwZGY1ZjkwY2YwMjEwMGVhMmQzYzU0YjUyZDBlNGUxY2Q0NmMxN2ExZDU3YmRhY2EyMzVlM2U1NjYzN2JmZGQzMThiZWMzNTgzOWU1YzIxNWUyNzMzY2IyMzQ2ZGQ1NDYyODc1NDdlMjc4OWYxMjZjZWU5NWZhYzg4N2IxMzM2MzBlZTEzYTVmYTlhODYzNDYxODQ5MjM0NDk3ZGY3ZTRmOWYyYzk2ZjQ5YzViMGExNzQ2NGE2MGM0MDg1MzU2NTY2ZDc4NGIxYjY3NzY3MzYzYjg3IiwiY3VzdG9tRGF0YSI6eyJleGl0SW5mbyI6eyJ0b2FzdERlc2MiOm51bGwsInRvYXN0SW1nVXJsIjpudWxsfX0sInBlbmRhbnRUeXBlIjoxLCJkaXNwbGF5VHlwZSI6Miwic2luZ2xlUGFnZUlkIjowLCJzaW5nbGVTdWJQYWdlSWQiOjAsImNoYW5uZWwiOjAsImNvdW50ZG93blJlcG9ydCI6ZmFsc2UsInRoZW1lVHlwZSI6MCwibWl4ZWRBZCI6dHJ1ZSwiZnVsbE1peGVkIjp0cnVlLCJhdXRvUmVwb3J0Ijp0cnVlLCJmcm9tVGFza0NlbnRlciI6dHJ1ZSwic2VhcmNoSW5zcGlyZVNjaGVtZUluZm8iOm51bGwsImFtb3VudCI6MH0="
|
||||
},
|
||||
follow: {
|
||||
name: "关注广告",
|
||||
pageId: 11101, subPageId: 100026367, businessId: 672, posId: 24067,
|
||||
requestSceneType: 2, taskType: 1
|
||||
},
|
||||
content: {
|
||||
name: "内容广告",
|
||||
pageId: 11101, subPageId: 100141480, businessId: 7054, posId: 186550,
|
||||
requestSceneType: 1, taskType: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let localPublicIP = null;
|
||||
|
||||
// ==============================================
|
||||
// 工具函数(原代码未改动)
|
||||
// ==============================================
|
||||
function getTime() {
|
||||
return new Date().toLocaleTimeString("zh-CN", {
|
||||
timeZone: "Asia/Shanghai", hour12: false,
|
||||
hour: "2-digit", minute: "2-digit", second: "2-digit"
|
||||
});
|
||||
}
|
||||
function getProxyTag(useProxy) { return useProxy ? "[代理]" : "[直连]"; }
|
||||
function maskProxyUrl(proxy) {
|
||||
if (!proxy) return null;
|
||||
try {
|
||||
const match = proxy.match(/^(socks5:\/\/)([^:@]+)(?::([^@]+))?@(.+)$/);
|
||||
if (match) {
|
||||
const [, protocol, user, , host] = match;
|
||||
return `${protocol}${user}:***@${host}`;
|
||||
}
|
||||
} catch (e) {}
|
||||
return proxy;
|
||||
}
|
||||
function log(useProxy, appName, msg) {
|
||||
const tag = getProxyTag(useProxy);
|
||||
const app = appName === "快手极速版" ? "快手极速版" : "快手";
|
||||
console.log(`${tag}<${app}>(${getTime()}): ${msg}`);
|
||||
}
|
||||
function print(msg) { console.log(msg); }
|
||||
|
||||
// ==============================================
|
||||
// 网络请求封装(原代码未改动)
|
||||
// ==============================================
|
||||
async function request(options, proxy = null, title = "请求") {
|
||||
try {
|
||||
const axiosOptions = {
|
||||
method: options.method || "GET",
|
||||
url: options.url,
|
||||
headers: options.headers || {},
|
||||
data: options.body || options.form,
|
||||
timeout: options.timeout || 12000,
|
||||
validateStatus: () => true
|
||||
};
|
||||
if (proxy) {
|
||||
const agent = new SocksProxyAgent(proxy, { timeout: 10000, keepAlive: false });
|
||||
axiosOptions.httpAgent = agent;
|
||||
axiosOptions.httpsAgent = agent;
|
||||
} else {
|
||||
axiosOptions.proxy = false;
|
||||
}
|
||||
if (options.form && options.method === "POST" && !axiosOptions.headers["Content-Type"]) {
|
||||
axiosOptions.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
|
||||
axiosOptions.data = querystring.stringify(options.form);
|
||||
}
|
||||
const resp = await axios(axiosOptions);
|
||||
return { body: resp.data, status: resp.status };
|
||||
} catch (e) {
|
||||
console.log(`[请求失败] ${title}: ${e.message}`);
|
||||
return { body: null, status: 0 };
|
||||
}
|
||||
}
|
||||
async function checkLocalIP() {
|
||||
print("正在检测本地直连公网IP...");
|
||||
const urls = ["http://icanhazip.com", "http://ipinfo.io/ip", "http://httpbin.org/ip"];
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const res = await axios.get(url, { timeout: 5000, responseType: "text", proxy: false });
|
||||
const ip = res.data.trim().match(/\d+\.\d+\.\d+\.\d+/)?.[0];
|
||||
if (ip) {
|
||||
localPublicIP = ip;
|
||||
print("本地直连公网IP: " + ip);
|
||||
return ip;
|
||||
}
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
print("本地直连公网IP检测失败");
|
||||
process.exit(1);
|
||||
}
|
||||
async function checkProxyIP(proxy) {
|
||||
const urls = ["http://icanhazip.com", "http://ipinfo.io/ip", "http://httpbin.org/ip"];
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const { body } = await request({ method: "GET", url, timeout: 8000 }, proxy, "代理IP检测");
|
||||
if (!body) continue;
|
||||
const ip = body.toString().trim().match(/\d+\.\d+\.\d+\.\d+/)?.[0];
|
||||
if (ip) return ip;
|
||||
} catch (e) { continue; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 签名接口 - 核心修改:按kpn自动切换接口
|
||||
// ==============================================
|
||||
async function getEncSign(base64Data, proxy, appName, remark, kpnType) {
|
||||
// 按kpn选签名接口:KUAISHOU=81 NEBULA=82
|
||||
const SIGN_API_URL = kpnType === "KUAISHOU" ? SIGN_API_KUAISHOU : SIGN_API_NEBULA;
|
||||
try {
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: SIGN_API_URL + "/encsign",
|
||||
headers: { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" },
|
||||
body: JSON.stringify({ data: base64Data }),
|
||||
timeout: 15000
|
||||
}, null, `获取加密签名`);
|
||||
if (body && body.status) return body.data;
|
||||
log(proxy, appName, `❌ ${remark} encsign 失败: ${body?.message || body?.error || "无响应"}`);
|
||||
return null;
|
||||
} catch (e) {
|
||||
log(proxy, appName, `❌ ${remark} encsign 异常: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function getNsSign(reqInfo, proxy, appName, remark, kpnType) {
|
||||
// 按kpn选签名接口:KUAISHOU=81 NEBULA=82
|
||||
const SIGN_API_URL = kpnType === "KUAISHOU" ? SIGN_API_KUAISHOU : SIGN_API_NEBULA;
|
||||
try {
|
||||
const payload = {
|
||||
path: reqInfo.urlpath,
|
||||
data: reqInfo.reqdata,
|
||||
salt: reqInfo.salt
|
||||
};
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: SIGN_API_URL + "/nssig",
|
||||
headers: { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" },
|
||||
body: JSON.stringify(payload),
|
||||
timeout: 15000
|
||||
}, null, `获取nssig签名`);
|
||||
if (body && body.data) {
|
||||
return {
|
||||
sig: body.data.sig,
|
||||
__NStokensig: body.data.nstokensig,
|
||||
__NS_sig3: body.data.nssig3,
|
||||
__NS_xfalcon: body.data.nssig4 || body.data.xfalcon || ""
|
||||
};
|
||||
}
|
||||
log(proxy, appName, `❌ ${remark} nssig 失败: ${body?.error || body?.message || "无响应"}`);
|
||||
return null;
|
||||
} catch (e) {
|
||||
log(proxy, appName, `❌ ${remark} nssig 异常: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号信息获取(原代码未改动)
|
||||
// ==============================================
|
||||
async function getUserInfo(cookie, platform, proxy) {
|
||||
try {
|
||||
const { body } = await request({
|
||||
method: "GET",
|
||||
url: platform.accountInfoUrl,
|
||||
headers: {
|
||||
Host: platform.host,
|
||||
"User-Agent": "kwai-android aegon/3.56.0",
|
||||
Cookie: cookie,
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
timeout: 12000
|
||||
}, proxy, "获取账号信息");
|
||||
if (body && body.result === 1 && body.data) {
|
||||
let coin = 0, cash = 0;
|
||||
if (platform.name === "KS") {
|
||||
coin = Number(body.data.coinAmount) || 0;
|
||||
cash = Number(body.data.cashAmountDisplay) || 0;
|
||||
} else {
|
||||
coin = Number(body.data.totalCoin) || 0;
|
||||
cash = Number(body.data.allCash) || 0;
|
||||
}
|
||||
return {
|
||||
nickname: body.data.userData?.nickname || null,
|
||||
totalCoin: coin, allCash: cash,
|
||||
success: true, ckExpired: false
|
||||
};
|
||||
}
|
||||
return { nickname: null, totalCoin: 0, allCash: 0, success: false, ckExpired: true };
|
||||
} catch (e) {
|
||||
return { nickname: null, totalCoin: 0, allCash: 0, success: false, ckExpired: true };
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号任务类 - 仅传kpnType到签名函数,其余未改
|
||||
// ==============================================
|
||||
class KuaishouAccount {
|
||||
constructor({ index = 1, salt, cookie, remark = "未命名", proxyUrl = null, tasksToExecute = CONFIG.DEFAULT_TASKS }) {
|
||||
this.index = index;
|
||||
this.salt = salt;
|
||||
this.cookie = cookie;
|
||||
this.remark = remark;
|
||||
this.proxyUrl = proxyUrl;
|
||||
this.platform = this.getPlatformByCookie(cookie);
|
||||
this.kpnType = this.platform.kpn; // 新增:获取kpn类型(KUAISHOU/NEBULA)
|
||||
this.tasksToRun = tasksToExecute.filter(Boolean);
|
||||
this.taskConfigs = CONFIG.TASK_CONFIGS[this.platform.kpn === "NEBULA" ? "NEBULA" : "KUAISHOU"];
|
||||
this.lowRewardCount = 0;
|
||||
this.lowRewardStreak = 0;
|
||||
this.adFailCount = 0;
|
||||
this.continuous1Coin = 0;
|
||||
this.stopAll = false;
|
||||
this.taskStats = {};
|
||||
this.taskLimit = {};
|
||||
this.taskDisabled = {};
|
||||
this.tasksToRun.forEach(task => {
|
||||
this.taskStats[task] = { success: 0, failed: 0, totalReward: 0 };
|
||||
this.taskLimit[task] = false;
|
||||
this.taskDisabled[task] = false;
|
||||
});
|
||||
this.isCycleMode = CONFIG.CYCLE_ROUNDS > 0;
|
||||
this.cycleRounds = CONFIG.CYCLE_ROUNDS;
|
||||
this.currentRound = 0;
|
||||
this.currentTaskIndex = 0;
|
||||
this.parseCookie();
|
||||
this.clientIP = null;
|
||||
}
|
||||
getPlatformByCookie(cookie) {
|
||||
const match = cookie.match(/kpn=([^;]+)/);
|
||||
const kpn = match ? match[1].toUpperCase() : "KUAISHOU";
|
||||
return kpn === "NEBULA" ? CONFIG.PLATFORM_CONFIG.NEBULA : CONFIG.PLATFORM_CONFIG.KUAISHOU;
|
||||
}
|
||||
parseCookie() {
|
||||
try {
|
||||
this.mod = this.cookie.match(/mod=([^;]+)/)?.[1] || "Xiaomi(23116PN5BC)";
|
||||
this.egid = this.cookie.match(/egid=([^;]+)/)?.[1] || "";
|
||||
this.did = this.cookie.match(/did=([^;]+)/)?.[1] || "";
|
||||
this.userId = this.cookie.match(/userId=([^;]+)/)?.[1] || "";
|
||||
this.apiSt = this.cookie.match(/kuaishou\.api_st=([^;]+)/)?.[1] || "";
|
||||
this.appver = this.cookie.match(/appver=([^;]+)/)?.[1] || "13.7.20.10468";
|
||||
this.queryParams = `mod=${this.mod}&appver=${this.appver}&egid=${this.egid}&did=${this.did}`;
|
||||
} catch (e) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 解析cookie失败: ${e.message}`);
|
||||
}
|
||||
}
|
||||
async initIP() {
|
||||
try {
|
||||
if (this.proxyUrl) {
|
||||
log(null, this.platform.displayName, `账号 [${this.remark}] 代理: ${maskProxyUrl(this.proxyUrl)}`);
|
||||
const ip = await checkProxyIP(this.proxyUrl);
|
||||
if (!ip) {
|
||||
this.stopAll = true;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 初始化失败:代理IP检测无有效结果`);
|
||||
return;
|
||||
}
|
||||
this.clientIP = ip;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 代理出口IP: ${ip}`);
|
||||
} else {
|
||||
if (!localPublicIP) await checkLocalIP();
|
||||
this.clientIP = localPublicIP;
|
||||
}
|
||||
} catch (e) {
|
||||
this.stopAll = true;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 初始化失败:${e.message}`);
|
||||
}
|
||||
}
|
||||
async retry(fn, desc, times = 3, delay = 2000) {
|
||||
let cnt = 0;
|
||||
while (cnt < times && !this.stopAll) {
|
||||
try {
|
||||
const res = await fn();
|
||||
if (res) return res;
|
||||
} catch (e) {}
|
||||
cnt++;
|
||||
if (cnt < times && !this.stopAll) await new Promise(r => setTimeout(r, delay));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getImpExt(task) {
|
||||
if (task.name.includes("搜索")) {
|
||||
const word = CONFIG.SEARCH_KEYWORDS[Math.floor(Math.random() * CONFIG.SEARCH_KEYWORDS.length)];
|
||||
return JSON.stringify({
|
||||
openH5AdCount: 2,
|
||||
sessionLookedCompletedCount: "1",
|
||||
sessionType: "1",
|
||||
searchKey: word,
|
||||
triggerType: "2",
|
||||
disableReportToast: "true",
|
||||
businessEnterAction: "7",
|
||||
neoParams: task.linkUrl || ""
|
||||
});
|
||||
}
|
||||
return "{}";
|
||||
}
|
||||
async getAdInfo(taskKey) {
|
||||
const task = this.taskConfigs[taskKey];
|
||||
if (!task) return null;
|
||||
const adUrl = "/rest/e/reward/mixed/ad";
|
||||
const commonData = {
|
||||
encData: "|encData|",
|
||||
sign: "|sign|",
|
||||
cs: "false",
|
||||
client_key: this.platform.adClientKey,
|
||||
videoModelCrowdTag: "1_23",
|
||||
os: "android",
|
||||
"kuaishou.api_st": this.apiSt,
|
||||
uQaTag: "1##swLdgl:99#ecPp:-9#cmNt:-0#cmHs:-3#cmMnsl:-0"
|
||||
};
|
||||
const deviceData = {
|
||||
earphoneMode: "1", mod: this.mod, appver: this.appver,
|
||||
isp: "CUCC", language: "zh-cn", ud: this.userId,
|
||||
did_tag: "0", net: "WIFI", kcv: "1599", app: "0",
|
||||
kpf: "ANDROID_PHONE", ver: "11.6", android_os: "0",
|
||||
boardPlatform: "pineapple", kpn: this.platform.kpn,
|
||||
androidApiLevel: "35", country_code: "cn", sys: "ANDROID_15",
|
||||
sw: "1080", sh: "2400", abi: "arm64", userRecoBit: "0"
|
||||
};
|
||||
const impData = {
|
||||
appInfo: {
|
||||
appId: this.platform.appId, name: this.platform.appName,
|
||||
packageName: this.platform.packageName, version: this.appver, versionCode: -1
|
||||
},
|
||||
deviceInfo: { osType: 1, osVersion: "15", deviceId: this.did, screenSize: { width: 1080, height: 2249 }, ftt: "" },
|
||||
userInfo: { userId: this.userId, age: 0, gender: "" },
|
||||
impInfo: [{
|
||||
pageId: task.pageId || 100011251,
|
||||
subPageId: task.subPageId,
|
||||
action: 0,
|
||||
browseType: task.name.includes("搜索") ? 4 : 3,
|
||||
impExtData: this.getImpExt(task),
|
||||
mediaExtData: "{}"
|
||||
}]
|
||||
};
|
||||
const base64Imp = Buffer.from(JSON.stringify(impData)).toString("base64");
|
||||
// 传kpnType到签名函数
|
||||
const encSign = await this.retry(
|
||||
() => getEncSign(base64Imp, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"获取广告加密签名"
|
||||
);
|
||||
if (!encSign) return null;
|
||||
commonData.encData = encSign.encdata;
|
||||
commonData.sign = encSign.sign;
|
||||
// 传kpnType到签名函数
|
||||
const nsSign = await this.retry(
|
||||
() => getNsSign({
|
||||
urlpath: adUrl,
|
||||
reqdata: querystring.stringify(commonData) + "&" + querystring.stringify(deviceData),
|
||||
salt: this.salt
|
||||
}, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"获取广告请求nssig"
|
||||
);
|
||||
if (!nsSign) return null;
|
||||
const reqQuery = {
|
||||
...deviceData,
|
||||
sig: nsSign.sig,
|
||||
__NS_sig3: nsSign.__NS_sig3,
|
||||
__NS_xfalcon: nsSign.__NS_xfalcon,
|
||||
__NStokensig: nsSign.__NStokensig
|
||||
};
|
||||
const finalUrl = "https://api.e.kuaishou.com" + adUrl + "?" + querystring.stringify(reqQuery);
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url: finalUrl,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
Host: "api.e.kuaishou.com",
|
||||
"User-Agent": "kwai-android aegon/3.56.0",
|
||||
Cookie: this.cookie
|
||||
},
|
||||
form: commonData,
|
||||
timeout: 12000
|
||||
}, this.proxyUrl, "获取广告");
|
||||
if (!body) {
|
||||
this.adFailCount++;
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) this.stopAll = true;
|
||||
return null;
|
||||
}
|
||||
if (body.errorMsg === "OK" && body.feeds?.[0]?.ad) {
|
||||
const ad = body.feeds[0];
|
||||
const title = (ad.caption || ad.ad?.caption || "").slice(0, 30) + "...";
|
||||
let coin = 0;
|
||||
try {
|
||||
const ext = JSON.parse(ad.ad.extData);
|
||||
coin = Number(ext.awardCoin) || 0;
|
||||
if (coin === 0) {
|
||||
coin = ad.ad.adDataV2?.inspirePersonalize?.awardValue ||
|
||||
ad.ad.adDataV2?.inspireAdInfo?.inspirePersonalize?.neoValue || 0;
|
||||
}
|
||||
} catch (e) {}
|
||||
if (coin === 5) return null;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 获取广告成功:${title}`);
|
||||
log(null, this.platform.displayName, `${this.remark} 预计获得: ${coin} 金币`);
|
||||
return {
|
||||
cid: ad.ad.creativeId,
|
||||
llsid: ad.exp_tag?.split("/")?.[1]?.split("_")?.[0] || "",
|
||||
hasRewardEnd: ad.ad.adDataV2?.onceAgainRewardInfo?.hasMore || false,
|
||||
expectedCoins: coin,
|
||||
taskConfig: task
|
||||
};
|
||||
}
|
||||
this.adFailCount++;
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) this.stopAll = true;
|
||||
return null;
|
||||
}
|
||||
async genReportSign(cid, llsid, task) {
|
||||
try {
|
||||
const bizStr = JSON.stringify({
|
||||
businessId: task.businessId,
|
||||
endTime: Date.now(),
|
||||
extParams: "",
|
||||
mediaScene: "video",
|
||||
neoInfos: [{
|
||||
creativeId: cid, extInfo: "", llsid,
|
||||
requestSceneType: task.requestSceneType,
|
||||
taskType: task.taskType,
|
||||
watchExpId: "", watchStage: 0
|
||||
}],
|
||||
pageId: task.pageId || 100011251,
|
||||
posId: task.posId,
|
||||
reportType: 0,
|
||||
sessionId: "",
|
||||
startTime: Date.now() - 30000,
|
||||
subPageId: task.subPageId
|
||||
});
|
||||
const postData = `bizStr=${encodeURIComponent(bizStr)}&cs=false&client_key=${this.platform.reportClientKey}`;
|
||||
const qs = this.queryParams + "&" + postData;
|
||||
// 传kpnType到签名函数
|
||||
const sign = await this.retry(
|
||||
() => getNsSign({
|
||||
urlpath: "/rest/r/ad/task/report",
|
||||
reqdata: qs,
|
||||
salt: this.salt
|
||||
}, this.proxyUrl, this.platform.displayName, this.remark, this.kpnType),
|
||||
"生成报告签名"
|
||||
);
|
||||
if (!sign) return null;
|
||||
return {
|
||||
sig: sign.sig, sig3: sign.__NS_sig3,
|
||||
xfalcon: sign.__NS_xfalcon, sigtoken: sign.__NStokensig,
|
||||
post: postData
|
||||
};
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async submitReport(cid, llsid, taskKey, task) {
|
||||
const sign = await this.genReportSign(cid, llsid, task);
|
||||
if (!sign) return { success: false, reward: 0 };
|
||||
const url = "https://api.e.kuaishou.com/rest/r/ad/task/report?" +
|
||||
`${this.queryParams}&sig=${sign.sig}&__NS_sig3=${sign.sig3}&__NS_xfalcon=${sign.xfalcon}&__NStokensig=${sign.sigtoken}`;
|
||||
const { body } = await request({
|
||||
method: "POST",
|
||||
url,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
Host: "api.e.kuaishou.com",
|
||||
Cookie: this.cookie,
|
||||
"User-Agent": "kwai-android aegon/3.56.0"
|
||||
},
|
||||
form: querystring.parse(sign.post),
|
||||
timeout: 12000
|
||||
}, this.proxyUrl, "提交任务报告");
|
||||
if (!body) return { success: false, reward: 0 };
|
||||
if (body.result === 1) {
|
||||
const coin = Number(body.data?.neoAmount) || 0;
|
||||
this.taskStats[taskKey].totalReward += coin;
|
||||
if (coin === 1) {
|
||||
this.continuous1Coin++;
|
||||
if (this.continuous1Coin >= CONFIG.CONTINUOUS_1COIN_LIMIT) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 连续${CONFIG.CONTINUOUS_1COIN_LIMIT}次1金币,停止任务`);
|
||||
this.stopAll = true;
|
||||
}
|
||||
} else {
|
||||
this.continuous1Coin = 0;
|
||||
}
|
||||
if (coin <= CONFIG.LOW_REWARD_THRESHOLD) {
|
||||
this.lowRewardStreak++;
|
||||
if (this.lowRewardStreak >= CONFIG.LOW_REWARD_LIMIT) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 连续低奖励超限,停止任务`);
|
||||
this.stopAll = true;
|
||||
}
|
||||
} else {
|
||||
this.lowRewardStreak = 0;
|
||||
}
|
||||
return { success: true, reward: coin };
|
||||
}
|
||||
if ([20107, 20108, 1003, 415].includes(body.result)) {
|
||||
return { success: false, reward: 0, limitReached: true };
|
||||
}
|
||||
return { success: false, reward: 0 };
|
||||
}
|
||||
async runTask(taskKey) {
|
||||
if (this.taskDisabled[taskKey] || this.taskLimit[taskKey] || this.stopAll) return { success: false, reward: 0 };
|
||||
let adInfo = null;
|
||||
while (!adInfo && !this.stopAll) {
|
||||
adInfo = await this.getAdInfo(taskKey);
|
||||
if (!adInfo && !this.stopAll) await new Promise(r => setTimeout(r, 3000));
|
||||
}
|
||||
if (!adInfo) {
|
||||
this.taskStats[taskKey].failed++;
|
||||
return { success: false, reward: 0 };
|
||||
}
|
||||
const watchMs = Math.floor(Math.random() * (CONFIG.WATCH_MAX - CONFIG.WATCH_MIN) + CONFIG.WATCH_MIN) * 1000;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 观看广告中,等待 ${Math.round(watchMs/1000)} 秒...`);
|
||||
await new Promise(r => setTimeout(r, watchMs));
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} 观看完成,提交任务报告`);
|
||||
const result = await this.submitReport(adInfo.cid, adInfo.llsid, taskKey, adInfo.taskConfig);
|
||||
if (result.success) {
|
||||
this.taskStats[taskKey].success++;
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} ✅ 提交成功!获得 ${result.reward} 金币`);
|
||||
return { success: true, reward: result.reward, hasRewardEnd: adInfo.hasRewardEnd };
|
||||
}
|
||||
if (result.limitReached) this.taskLimit[taskKey] = true;
|
||||
this.taskStats[taskKey].failed++;
|
||||
return { success: false, reward: 0, limitReached: result.limitReached || false };
|
||||
}
|
||||
nextTask() {
|
||||
const available = this.tasksToRun.filter(t => !this.taskLimit[t] && !this.taskDisabled[t]);
|
||||
if (available.length === 0 || this.stopAll) return null;
|
||||
this.currentTaskIndex = (this.currentTaskIndex + 1) % available.length;
|
||||
return available[this.currentTaskIndex];
|
||||
}
|
||||
async restAfterAd(count) {
|
||||
if (count > 0 && count % CONFIG.APPEND_REST_INTERVAL === 0) {
|
||||
const ms = Math.floor(Math.random() * (CONFIG.APPEND_REST_MAX - CONFIG.APPEND_REST_MIN)) + CONFIG.APPEND_REST_MIN;
|
||||
await new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
}
|
||||
async run() {
|
||||
await this.initIP();
|
||||
if (this.stopAll) {
|
||||
return { success: false, remark: this.remark, platform: this.platform.name, taskCount: 0, totalReward: 0, exitIP: this.clientIP, stopReason: "初始化失败" };
|
||||
}
|
||||
const user = await getUserInfo(this.cookie, this.platform, this.proxyUrl);
|
||||
if (!user.success || user.ckExpired) {
|
||||
log(this.proxyUrl, this.platform.displayName, `${this.remark} Cookie已过期或无效`);
|
||||
return { success: false, remark: this.remark, platform: this.platform.name, taskCount: 0, totalReward: 0, exitIP: this.clientIP, stopReason: "Cookie过期" };
|
||||
}
|
||||
log(this.proxyUrl, this.platform.displayName,
|
||||
`${this.remark} 登录成功 | 昵称: ${user.nickname || "未知"} | 金币: ${user.totalCoin} | 余额: ${user.allCash.toFixed(2)}`);
|
||||
let totalTasks = 0, appendTasks = 0, stopReason = "正常结束";
|
||||
while (!this.stopAll) {
|
||||
if (this.isCycleMode && this.currentRound >= this.cycleRounds) {
|
||||
stopReason = `已完成${this.cycleRounds}轮任务`;
|
||||
break;
|
||||
}
|
||||
const task = this.nextTask();
|
||||
if (!task) { stopReason = "无可用任务"; this.stopAll = true; break; }
|
||||
const res = await this.runTask(task);
|
||||
totalTasks++;
|
||||
if (res.hasRewardEnd) {
|
||||
appendTasks++;
|
||||
await this.restAfterAd(appendTasks);
|
||||
await this.runTask(task);
|
||||
}
|
||||
if (this.adFailCount >= CONFIG.AD_FAIL_LIMIT) { stopReason = "广告获取失败达上限"; this.stopAll = true; }
|
||||
if (this.nextTask() && !this.stopAll) {
|
||||
const delay = Math.floor(Math.random() * 5 + 5) * 1000;
|
||||
await new Promise(r => setTimeout(r, delay));
|
||||
}
|
||||
if (this.isCycleMode && this.currentTaskIndex === this.tasksToRun.length - 1) this.currentRound++;
|
||||
}
|
||||
const totalReward = Object.values(this.taskStats).reduce((s, t) => s + t.totalReward, 0);
|
||||
log(this.proxyUrl, this.platform.displayName,
|
||||
`${this.remark} 结束 | 执行任务: ${totalTasks} | 总获金币: ${totalReward} | 原因: ${stopReason}`);
|
||||
for (const [k, s] of Object.entries(this.taskStats)) {
|
||||
const cfg = this.taskConfigs[k];
|
||||
if (cfg) log(null, this.platform.displayName, ` └ ${cfg.name}: 成功${s.success}次 失败${s.failed}次 奖励${s.totalReward}金币`);
|
||||
}
|
||||
return { success: true, remark: this.remark, platform: this.platform.name, taskCount: totalTasks, appendCount: appendTasks, totalReward, exitIP: this.clientIP, stopReason };
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 账号解析 & 批量执行(原代码未改动)
|
||||
// ==============================================
|
||||
function parseAccountLine(line, index) {
|
||||
if (!line || typeof line !== "string") return null;
|
||||
const parts = line.split("#");
|
||||
if (parts.length < 3) return null;
|
||||
const remark = parts[0].trim() || `账号${index}`;
|
||||
const cookie = parts[1].trim();
|
||||
const salt = parts[2].trim();
|
||||
let proxy = parts[3]?.trim() || null;
|
||||
if (!cookie || !salt) return null;
|
||||
if (proxy && proxy.includes("|")) {
|
||||
const [host, port, user, pwd] = proxy.split("|");
|
||||
proxy = `socks5://${user}:${pwd}@${host}:${port}`;
|
||||
}
|
||||
if (proxy && !/^socks5:\/\//i.test(proxy)) {
|
||||
console.log(`⚠️ 账号${index} 代理格式非socks5,已忽略: ${proxy}`);
|
||||
proxy = null;
|
||||
}
|
||||
return { cookie, salt, remark, proxyUrl: proxy };
|
||||
}
|
||||
function loadAllAccounts() {
|
||||
const accounts = [];
|
||||
const exists = new Set();
|
||||
let index = 1;
|
||||
let proxyCount = 0;
|
||||
const mainCk = process.env.ksck;
|
||||
if (mainCk) {
|
||||
mainCk.split("&").forEach(line => {
|
||||
line = line.trim();
|
||||
if (line && !exists.has(line)) {
|
||||
const acc = parseAccountLine(line, index++);
|
||||
if (acc) { accounts.push(acc); exists.add(line); if (acc.proxyUrl) proxyCount++; }
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 1; i <= 666; i++) {
|
||||
const line = process.env[`ksck${i}`]?.trim();
|
||||
if (line && !exists.has(line)) {
|
||||
const acc = parseAccountLine(line, index++);
|
||||
if (acc) { accounts.push(acc); exists.add(line); if (acc.proxyUrl) proxyCount++; }
|
||||
}
|
||||
}
|
||||
print(`\n✅ 共加载账号: ${accounts.length} 个(其中代理账号: ${proxyCount} 个)`);
|
||||
return accounts;
|
||||
}
|
||||
async function runAccountList(accounts) {
|
||||
const results = [];
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
const acc = accounts[i];
|
||||
print(`\n${"=".repeat(60)}`);
|
||||
print(`🚀 开始执行账号 ${i+1}/${accounts.length}: ${acc.remark}`);
|
||||
print(`${"=".repeat(60)}`);
|
||||
const instance = new KuaishouAccount({ ...acc, index: i + 1 });
|
||||
const result = await instance.run();
|
||||
results.push(result);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
function printSummary(results) {
|
||||
print(`\n${"=".repeat(60)}`);
|
||||
print(" 📊 全部账号执行结果汇总");
|
||||
print(`${"=".repeat(60)}`);
|
||||
let totalReward = 0;
|
||||
results.forEach((r, i) => {
|
||||
const tag = r.platform === "JSB" ? "[极速版]" : "[快手 ]";
|
||||
print(`${tag} 账号${i+1} ${r.remark} | 任务数:${r.taskCount} | 金币:${r.totalReward} | ${r.stopReason}`);
|
||||
totalReward += r.totalReward || 0;
|
||||
});
|
||||
print(`${"=".repeat(60)}`);
|
||||
print(` 🎉 全部完成 | 账号数: ${results.length} | 总金币: ${totalReward}`);
|
||||
print(`${"=".repeat(60)}`);
|
||||
}
|
||||
|
||||
// ==============================================
|
||||
// 启动(原代码未改动)
|
||||
// ==============================================
|
||||
print("================================================================================");
|
||||
print(" ⭐ 快手双端脚本 ⭐ ");
|
||||
print(" 支持快手 & 快手极速版 · 无需卡密授权 · 按kpn自动切换签名接口 ");
|
||||
print("================================================================================");
|
||||
print(`\n🎯 默认任务: ${CONFIG.DEFAULT_TASKS.join(", ")}`);
|
||||
print(`⏱ 观看时长: ${CONFIG.WATCH_MIN}-${CONFIG.WATCH_MAX} 秒`);
|
||||
print(`🔄 循环轮数: ${CONFIG.CYCLE_ROUNDS > 0 ? CONFIG.CYCLE_ROUNDS : "无限制"}`);
|
||||
print("\n📋 环境变量说明:");
|
||||
print(" ksck = 账号配置,格式: 备注#cookie#salt#socks5代理(可选)");
|
||||
print(" ksck1~ksck666 = 多账号扩展");
|
||||
print(" KS_DEFAULT_TASKS = 任务列表,逗号分隔,可选: box,look,food,search");
|
||||
print(" KS_CYCLE_ROUNDS = 循环轮数 (0=无限)");
|
||||
print(" KS_WATCH_MIN/MAX = 广告观看秒数范围");
|
||||
print(" KS_LOW_REWARD_THRESHOLD = 低奖励阈值");
|
||||
print(" KS_LOW_REWARD_LIMIT = 连续低奖励停止次数");
|
||||
print("================================================================================\n");
|
||||
(async () => {
|
||||
const accounts = loadAllAccounts();
|
||||
if (accounts.length === 0) {
|
||||
print("❌ 未检测到账号配置,请设置 ksck 环境变量");
|
||||
print(" 格式: 备注#cookie字符串#salt值");
|
||||
print(" 示例: 我的账号#did=xxx;userId=yyy;...#abcdef1234");
|
||||
process.exit(1);
|
||||
}
|
||||
const results = await runAccountList(accounts);
|
||||
printSummary(results);
|
||||
})();
|
||||
|
||||
|
||||
// 当前脚本来自于 http://script.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cn 脚本库下载!
|
||||
// 当前脚本来自于 http://2.345yun.cc 脚本库下载!
|
||||
// 脚本库官方QQ群1群: 429274456
|
||||
// 脚本库官方QQ群2群: 1077801222
|
||||
// 脚本库官方QQ群3群: 433030897
|
||||
// 脚本库中的所有脚本文件均来自热心网友上传和互联网收集。
|
||||
// 脚本库仅提供文件上传和下载服务,不提供脚本文件的审核。
|
||||
// 您在使用脚本库下载的脚本时自行检查判断风险。
|
||||
// 所涉及到的 账号安全、数据泄露、设备故障、软件违规封禁、财产损失等问题及法律风险,与脚本库无关!均由开发者、上传者、使用者自行承担。
|
||||
184
脚本库/微信小程序/抓包版/掌瓦每日商店推送/2026-05-24_ValorantStore_4efc5ba5.py
Normal file
184
脚本库/微信小程序/抓包版/掌瓦每日商店推送/2026-05-24_ValorantStore_4efc5ba5.py
Normal file
@@ -0,0 +1,184 @@
|
||||
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/ValorantStore.py
|
||||
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/ValorantStore.py
|
||||
# Repo: CN-Grace/QinglongScripts
|
||||
# Path: ValorantStore.py
|
||||
# UploadedAt: 2026-05-24T03:16:47Z
|
||||
# SHA256: 4efc5ba550edbef68021f94f99413bf66e7b6b24f16ccd720105624c4fc3cf09
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
cron: 15 8 * * *
|
||||
new Env("掌瓦每日商店推送")
|
||||
掌上无畏契约 每日商店自动推送
|
||||
- 获取每日商店 4 款武器皮肤
|
||||
- 文字报告推送至全部通知渠道
|
||||
- 皮肤图片单独推送至 Telegram
|
||||
"""
|
||||
|
||||
import os
|
||||
import requests
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
from utils import log_info, log_success, log_warning, log_error, beijing_time_str
|
||||
from notifier import send as notify_send, send_photos as notify_send_photos
|
||||
|
||||
# ==================== 用户配置 ====================
|
||||
VALORANT_COOKIE = os.environ.get("VALORANT_COOKIE", "")
|
||||
TZ_BEIJING = timezone(timedelta(hours=8))
|
||||
|
||||
# 品质映射
|
||||
QUALITY_MAP = {
|
||||
"orange": ("橙色/传奇", "🟧"),
|
||||
"purple": ("紫色/史诗", "🟪"),
|
||||
"blue": ("蓝色/稀有", "🟦"),
|
||||
"green": ("绿色", "🟩"),
|
||||
"white": ("白色", "⬜"),
|
||||
}
|
||||
|
||||
API_BASE = "https://app.mval.qq.com"
|
||||
COMMON_PARAMS = "source_game_zone=agame&game_zone=agame"
|
||||
|
||||
|
||||
def create_session(cookie: str) -> requests.Session:
|
||||
"""创建带 Cookie 的 Session"""
|
||||
session = requests.Session()
|
||||
session.headers.update({
|
||||
"User-Agent": "mval/2.6.0.10062 Channel/5 Mozilla/5.0 (Linux; Android 16; wv) AppleWebKit/537.36",
|
||||
"Accept-Encoding": "gzip",
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
})
|
||||
cookie_dict = {}
|
||||
for item in cookie.split(";"):
|
||||
item = item.strip()
|
||||
if "=" in item:
|
||||
k, v = item.split("=", 1)
|
||||
cookie_dict[k.strip()] = v.strip()
|
||||
requests.utils.add_dict_to_cookiejar(session.cookies, cookie_dict)
|
||||
return session
|
||||
|
||||
|
||||
def api_post(session: requests.Session, path: str, body: dict = None) -> dict:
|
||||
"""通用 POST 请求"""
|
||||
url = f"{API_BASE}{path}?{COMMON_PARAMS}"
|
||||
try:
|
||||
resp = session.post(url, json=body or {}, timeout=15)
|
||||
return resp.json()
|
||||
except Exception as e:
|
||||
log_error(f"API 请求失败 [{path}]: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
def refresh_token(session: requests.Session) -> str:
|
||||
"""刷新 access_token,返回新的 token"""
|
||||
cookie = {c.name: c.value for c in session.cookies}
|
||||
body = {
|
||||
"type": cookie.get("acctype", "qc"),
|
||||
"uuid": cookie.get("userId", ""),
|
||||
"openid": cookie.get("openid", ""),
|
||||
"source_game_zone": "agame",
|
||||
"game_zone": "agame",
|
||||
}
|
||||
result = api_post(session, "/go/auth/refresh_third_token", body)
|
||||
if result.get("result") == 0:
|
||||
token = result.get("data", {}).get("access_token", "")
|
||||
if token:
|
||||
session.cookies.set("access_token", token, domain="app.mval.qq.com")
|
||||
log_success("access_token 刷新成功")
|
||||
return token
|
||||
log_warning(f"刷新 token 失败: {result.get('msg', result.get('err_msg', '未知'))}")
|
||||
return ""
|
||||
|
||||
|
||||
def get_daily_store(session: requests.Session) -> tuple:
|
||||
"""获取每日商店内容,返回 (items, end_ts)"""
|
||||
result = api_post(session, "/go/mlol_store/agame/user_store", {
|
||||
"scene": "",
|
||||
"source_game_zone": "agame",
|
||||
"game_zone": "agame",
|
||||
})
|
||||
if result.get("result") != 0:
|
||||
log_error(f"获取商店失败: {result.get('msg', '未知')}")
|
||||
return [], 0
|
||||
|
||||
for section in result.get("data", []):
|
||||
if section["key"] == "dailystore":
|
||||
items = section.get("list", [])
|
||||
end_ts = section.get("end_ts", 0)
|
||||
log_success(f"获取到 {len(items)} 款每日商店皮肤")
|
||||
return items, end_ts
|
||||
return [], 0
|
||||
|
||||
|
||||
def build_report(items: list, nickname: str, end_ts: int) -> str:
|
||||
"""构建文字报告"""
|
||||
end_time = datetime.fromtimestamp(end_ts, tz=TZ_BEIJING).strftime("%Y-%m-%d %H:%M") if end_ts else "未知"
|
||||
|
||||
lines = ["🔫 掌上无畏契约 每日商店", "", f"👤 账号: {nickname}", f"⏰ 刷新时间: {end_time}", "", "─" * 18, ""]
|
||||
|
||||
for i, item in enumerate(items):
|
||||
name = item.get("goods_name", "未知")
|
||||
price = item.get("rmb_price", "?")
|
||||
quality = item.get("quality", "")
|
||||
likes = item.get("like_num", "")
|
||||
_, quality_emoji = QUALITY_MAP.get(quality, ("未知", "⬜"))
|
||||
|
||||
lines.append(f"{i+1}. {quality_emoji} {name}")
|
||||
lines.append(f" 💰 {price} 点券 | ❤️ {likes}")
|
||||
lines.append("")
|
||||
|
||||
lines.append("─" * 18)
|
||||
lines.append(f"🕒 执行时间: {beijing_time_str()}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
if not VALORANT_COOKIE:
|
||||
log_error("未配置 VALORANT_COOKIE,请在环境变量中设置")
|
||||
notify_send("掌瓦每日商店 错误", "❌ 未配置 VALORANT_COOKIE")
|
||||
return
|
||||
|
||||
session = create_session(VALORANT_COOKIE)
|
||||
|
||||
# 刷新 token
|
||||
refresh_token(session)
|
||||
|
||||
# 获取绑定账号
|
||||
bind_result = api_post(session, "/go/auth/bind_relation_list")
|
||||
bind_list = bind_result.get("data", {}).get("list", [])
|
||||
nickname = bind_list[0].get("nickName", "未知") if bind_list else "未知"
|
||||
log_info(f"绑定账号: {nickname}")
|
||||
|
||||
# 获取每日商店
|
||||
items, end_ts = get_daily_store(session)
|
||||
if not items:
|
||||
log_warning("未获取到商店内容,可能今日未刷新")
|
||||
notify_send("掌瓦每日商店", "⚠️ 未获取到商店内容,请检查 Cookie 或稍后重试")
|
||||
return
|
||||
|
||||
# 构建文字报告
|
||||
report = build_report(items, nickname, end_ts)
|
||||
|
||||
# 构建图片列表
|
||||
photos = []
|
||||
for item in items:
|
||||
name = item.get("goods_name", "未知")
|
||||
price = item.get("rmb_price", "?")
|
||||
quality = item.get("quality", "")
|
||||
image_url = item.get("goods_pic", "")
|
||||
if not image_url:
|
||||
continue
|
||||
quality_name, quality_emoji = QUALITY_MAP.get(quality, ("未知", "⬜"))
|
||||
photos.append({
|
||||
"image": image_url,
|
||||
"caption": f"{quality_emoji} {name} | 💰 {price} 点券 ({quality_name})",
|
||||
})
|
||||
|
||||
# 通知: 文本推所有通道, 图片仅 Telegram
|
||||
notify_send_photos("掌瓦每日商店", report, photos)
|
||||
log_info(f"推送完成: 文字 + {len(photos)} 张图片")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
435
脚本库/微信小程序/抓包版/森空岛签到/2026-05-23_skyland_3ff34a02.py
Normal file
435
脚本库/微信小程序/抓包版/森空岛签到/2026-05-23_skyland_3ff34a02.py
Normal file
@@ -0,0 +1,435 @@
|
||||
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/skyland.py
|
||||
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/skyland.py
|
||||
# Repo: CN-Grace/QinglongScripts
|
||||
# Path: skyland.py
|
||||
# UploadedAt: 2026-05-23T15:56:46Z
|
||||
# SHA256: 3ff34a02f788b8d949abe98d0670868ecd5dbd849cf18490c04ca20ae3641688
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
cron: 0 8 * * *
|
||||
new Env("森空岛签到")
|
||||
森空岛(Skland)自动签到脚本
|
||||
- 模拟数美设备指纹,生成设备 ID(dId)
|
||||
- 使用用户 Token 登录森空岛,获取凭证
|
||||
- 遍历绑定角色,对明日方舟、终末地等游戏进行每日签到
|
||||
"""
|
||||
|
||||
import base64
|
||||
import gzip
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
from urllib import parse
|
||||
|
||||
import requests
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers.algorithms import AES
|
||||
from cryptography.hazmat.decrepit.ciphers.algorithms import TripleDES
|
||||
from cryptography.hazmat.primitives.ciphers.modes import CBC, ECB
|
||||
|
||||
from utils import log_info, log_success, log_warning, log_error, beijing_time_str
|
||||
from notifier import send as notify_send
|
||||
|
||||
# ==================== 用户配置 ====================
|
||||
TOKENS = os.environ.get("SKYLAND_TOKEN", "").split(",")
|
||||
APP_CODE = "4ca99fa6b56cc2ba"
|
||||
|
||||
# ==================== 数美加密常量 ====================
|
||||
SM_CONFIG = {
|
||||
"organization": "UWXspnCCJN4sfYlNfqps",
|
||||
"appId": "default",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmxMNr7n8ZeT0tE1R9j/mPixoinPkeM+k4VGIn/s0k7N5rJAfnZ0eMER+QhwFvshzo0LNmeUkpR8uIlU/GEVr8mN28sKmwd2gpygqj0ePnBmOW4v0ZVwbSYK+izkhVFk2V/doLoMbWy6b+UnA8mkjvg0iYWRByfRsK2gdl7llqCwIDAQAB",
|
||||
"protocol": "https",
|
||||
"apiHost": "fp-it.portal101.cn",
|
||||
}
|
||||
DES_RULE = {
|
||||
"appId": {"cipher": "DES", "is_encrypt": 1, "key": "uy7mzc4h", "obfuscated_name": "xx"},
|
||||
"box": {"is_encrypt": 0, "obfuscated_name": "jf"},
|
||||
"canvas": {"cipher": "DES", "is_encrypt": 1, "key": "snrn887t", "obfuscated_name": "yk"},
|
||||
"clientSize": {"cipher": "DES", "is_encrypt": 1, "key": "cpmjjgsu", "obfuscated_name": "zx"},
|
||||
"organization": {"cipher": "DES", "is_encrypt": 1, "key": "78moqjfc", "obfuscated_name": "dp"},
|
||||
"os": {"cipher": "DES", "is_encrypt": 1, "key": "je6vk6t4", "obfuscated_name": "pj"},
|
||||
"platform": {"cipher": "DES", "is_encrypt": 1, "key": "pakxhcd2", "obfuscated_name": "gm"},
|
||||
"plugins": {"cipher": "DES", "is_encrypt": 1, "key": "v51m3pzl", "obfuscated_name": "kq"},
|
||||
"pmf": {"cipher": "DES", "is_encrypt": 1, "key": "2mdeslu3", "obfuscated_name": "vw"},
|
||||
"protocol": {"is_encrypt": 0, "obfuscated_name": "protocol"},
|
||||
"referer": {"cipher": "DES", "is_encrypt": 1, "key": "y7bmrjlc", "obfuscated_name": "ab"},
|
||||
"res": {"cipher": "DES", "is_encrypt": 1, "key": "whxqm2a7", "obfuscated_name": "hf"},
|
||||
"rtype": {"cipher": "DES", "is_encrypt": 1, "key": "x8o2h2bl", "obfuscated_name": "lo"},
|
||||
"sdkver": {"cipher": "DES", "is_encrypt": 1, "key": "9q3dcxp2", "obfuscated_name": "sc"},
|
||||
"status": {"cipher": "DES", "is_encrypt": 1, "key": "2jbrxxw4", "obfuscated_name": "an"},
|
||||
"subVersion": {"cipher": "DES", "is_encrypt": 1, "key": "eo3i2puh", "obfuscated_name": "ns"},
|
||||
"svm": {"cipher": "DES", "is_encrypt": 1, "key": "fzj3kaeh", "obfuscated_name": "qr"},
|
||||
"time": {"cipher": "DES", "is_encrypt": 1, "key": "q2t3odsk", "obfuscated_name": "nb"},
|
||||
"timezone": {"cipher": "DES", "is_encrypt": 1, "key": "1uv05lj5", "obfuscated_name": "as"},
|
||||
"tn": {"cipher": "DES", "is_encrypt": 1, "key": "x9nzj1bp", "obfuscated_name": "py"},
|
||||
"trees": {"cipher": "DES", "is_encrypt": 1, "key": "acfs0xo4", "obfuscated_name": "pi"},
|
||||
"ua": {"cipher": "DES", "is_encrypt": 1, "key": "k92crp1t", "obfuscated_name": "bj"},
|
||||
"url": {"cipher": "DES", "is_encrypt": 1, "key": "y95hjkoo", "obfuscated_name": "cf"},
|
||||
"version": {"is_encrypt": 0, "obfuscated_name": "version"},
|
||||
"vpw": {"cipher": "DES", "is_encrypt": 1, "key": "r9924ab5", "obfuscated_name": "ca"},
|
||||
}
|
||||
BROWSER_ENV = {
|
||||
"plugins": "MicrosoftEdgePDFPluginPortableDocumentFormatinternal-pdf-viewer1,MicrosoftEdgePDFViewermhjfbmdgcfjbbpaeojofohoefgiehjai1",
|
||||
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0",
|
||||
"canvas": "259ffe69",
|
||||
"timezone": -480,
|
||||
"platform": "Win32",
|
||||
"url": "https://www.skland.com/",
|
||||
"referer": "",
|
||||
"res": "1920_1080_24_1.25",
|
||||
"clientSize": "0_0_1080_1920_1920_1080_1920_1080",
|
||||
"status": "0011",
|
||||
}
|
||||
_PUBLIC_KEY = serialization.load_der_public_key(base64.b64decode(SM_CONFIG["publicKey"]))
|
||||
_DID_CACHE = None
|
||||
|
||||
|
||||
# ==================== 数美加密函数 ====================
|
||||
def _des_encrypt(obj: dict) -> dict:
|
||||
result = {}
|
||||
for key, value in obj.items():
|
||||
rule = DES_RULE.get(key)
|
||||
if not rule:
|
||||
result[key] = value
|
||||
continue
|
||||
if rule["is_encrypt"] == 1:
|
||||
key = rule["key"].encode("utf-8")
|
||||
cipher = Cipher(TripleDES(key * 3), ECB())
|
||||
data = str(value).encode("utf-8")
|
||||
data += b"\x00" * (8 - len(data) % 8)
|
||||
encrypted = cipher.encryptor().update(data)
|
||||
result[rule["obfuscated_name"]] = base64.b64encode(encrypted).decode("utf-8")
|
||||
else:
|
||||
result[rule["obfuscated_name"]] = value
|
||||
return result
|
||||
|
||||
|
||||
def _aes_encrypt(data: bytes, key: bytes) -> str:
|
||||
iv = b"0102030405060708"
|
||||
cipher = Cipher(AES(key), CBC(iv))
|
||||
encryptor = cipher.encryptor()
|
||||
pad_len = 16 - (len(data) % 16)
|
||||
data += b"\x00" * pad_len
|
||||
encrypted = encryptor.update(data) + encryptor.finalize()
|
||||
return encrypted.hex()
|
||||
|
||||
|
||||
def _gzip_compress(obj: dict) -> bytes:
|
||||
json_str = json.dumps(obj, separators=(",", ":"), ensure_ascii=False)
|
||||
return base64.b64encode(gzip.compress(json_str.encode("utf-8"), compresslevel=2, mtime=0))
|
||||
|
||||
|
||||
def _get_tn(obj: dict) -> str:
|
||||
sorted_keys = sorted(obj.keys())
|
||||
parts = []
|
||||
for k in sorted_keys:
|
||||
v = obj[k]
|
||||
if isinstance(v, (int, float)):
|
||||
parts.append(str(int(v * 10000)))
|
||||
elif isinstance(v, dict):
|
||||
parts.append(_get_tn(v))
|
||||
else:
|
||||
parts.append(str(v))
|
||||
return "".join(parts)
|
||||
|
||||
|
||||
def _get_smid() -> str:
|
||||
t = time.localtime()
|
||||
time_str = f"{t.tm_year}{t.tm_mon:02d}{t.tm_mday:02d}{t.tm_hour:02d}{t.tm_min:02d}{t.tm_sec:02d}"
|
||||
uid = str(uuid.uuid4())
|
||||
md5_uid = hashlib.md5(uid.encode()).hexdigest()
|
||||
base = time_str + md5_uid + "00"
|
||||
smsk = hashlib.md5(("smsk_web_" + base).encode()).hexdigest()[:14]
|
||||
return base + smsk + "0"
|
||||
|
||||
|
||||
def get_device_id() -> str:
|
||||
global _DID_CACHE
|
||||
if _DID_CACHE:
|
||||
log_info(f"使用缓存的设备 ID: {_DID_CACHE}")
|
||||
return _DID_CACHE
|
||||
|
||||
log_info("开始生成设备 ID...")
|
||||
uid = str(uuid.uuid4()).encode("utf-8")
|
||||
pri_id = hashlib.md5(uid).hexdigest()[:16]
|
||||
ep = _PUBLIC_KEY.encrypt(uid, padding.PKCS1v15())
|
||||
ep_b64 = base64.b64encode(ep).decode("utf-8")
|
||||
|
||||
browser = BROWSER_ENV.copy()
|
||||
current_time = int(time.time() * 1000)
|
||||
browser.update({"vpw": str(uuid.uuid4()), "svm": current_time, "trees": str(uuid.uuid4()), "pmf": current_time})
|
||||
|
||||
des_target = {
|
||||
**browser,
|
||||
"protocol": 102, "organization": SM_CONFIG["organization"], "appId": SM_CONFIG["appId"],
|
||||
"os": "web", "version": "3.0.0", "sdkver": "3.0.0",
|
||||
"box": "", "rtype": "all", "smid": _get_smid(), "subVersion": "1.0.0", "time": 0,
|
||||
}
|
||||
des_target["tn"] = hashlib.md5(_get_tn(des_target).encode()).hexdigest()
|
||||
|
||||
des_encrypted = _des_encrypt(des_target)
|
||||
compressed = _gzip_compress(des_encrypted)
|
||||
aes_encrypted = _aes_encrypt(compressed, pri_id.encode("utf-8"))
|
||||
|
||||
url = f"https://{SM_CONFIG['apiHost']}/deviceprofile/v4"
|
||||
payload = {"appId": "default", "compress": 2, "data": aes_encrypted, "encode": 5, "ep": ep_b64, "organization": SM_CONFIG["organization"], "os": "web"}
|
||||
log_info("向数美服务请求设备 ID...")
|
||||
resp = requests.post(url, json=payload).json()
|
||||
if resp.get("code") != 1100:
|
||||
raise RuntimeError(f"获取设备 ID 失败: {resp}")
|
||||
_DID_CACHE = "B" + resp["detail"]["deviceId"]
|
||||
log_success(f"设备 ID 生成成功: {_DID_CACHE}")
|
||||
return _DID_CACHE
|
||||
|
||||
|
||||
# ==================== 签到相关函数 ====================
|
||||
def generate_signature(path: str, body_or_query: str, token: str, d_id: str) -> tuple:
|
||||
timestamp = str(int(time.time()) - 2)
|
||||
header_ca = {"platform": "3", "timestamp": timestamp, "dId": d_id, "vName": "1.0.0"}
|
||||
header_str = json.dumps(header_ca, separators=(",", ":"))
|
||||
raw_string = path + body_or_query + timestamp + header_str
|
||||
hmac_sha256 = hmac.new(token.encode(), raw_string.encode(), hashlib.sha256).hexdigest()
|
||||
sign = hashlib.md5(hmac_sha256.encode()).hexdigest()
|
||||
return sign, header_ca
|
||||
|
||||
|
||||
def get_sign_headers(url: str, method: str, body, token: str, d_id: str, cred: str) -> dict:
|
||||
parsed = parse.urlparse(url)
|
||||
if method.lower() == "get":
|
||||
sign, header_ca = generate_signature(parsed.path, parsed.query, token, d_id)
|
||||
else:
|
||||
body_str = json.dumps(body) if body else ""
|
||||
sign, header_ca = generate_signature(parsed.path, body_str, token, d_id)
|
||||
return {
|
||||
"cred": cred,
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 12; SM-A5560 Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36; SKLand/1.52.1",
|
||||
"Accept-Encoding": "gzip", "Connection": "close",
|
||||
"X-Requested-With": "com.hypergryph.skland",
|
||||
"sign": sign, **header_ca,
|
||||
}
|
||||
|
||||
|
||||
def get_grant_code(token: str, d_id: str) -> str:
|
||||
url = "https://as.hypergryph.com/user/oauth2/v2/grant"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 12; SM-A5560 Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36; SKLand/1.52.1",
|
||||
"Accept-Encoding": "gzip", "Connection": "close",
|
||||
"dId": d_id, "X-Requested-With": "com.hypergryph.skland",
|
||||
}
|
||||
payload = {"appCode": APP_CODE, "token": token, "type": 0}
|
||||
log_info("正在获取 grant code...")
|
||||
resp = requests.post(url, json=payload, headers=headers).json()
|
||||
if resp.get("status") != 0:
|
||||
raise RuntimeError(f"获取 grant code 失败: {resp.get('msg')}")
|
||||
code = resp["data"]["code"]
|
||||
log_info(f"grant code 获取成功: {code[:10]}...")
|
||||
return code
|
||||
|
||||
|
||||
def get_cred(grant_code: str, d_id: str) -> dict:
|
||||
url = "https://zonai.skland.com/web/v1/user/auth/generate_cred_by_code"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Linux; Android 12; SM-A5560 Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36; SKLand/1.52.1",
|
||||
"Accept-Encoding": "gzip", "Connection": "close",
|
||||
"dId": d_id, "X-Requested-With": "com.hypergryph.skland",
|
||||
}
|
||||
payload = {"code": grant_code, "kind": 1}
|
||||
log_info("正在获取 cred...")
|
||||
resp = requests.post(url, json=payload, headers=headers).json()
|
||||
if resp.get("code") != 0:
|
||||
raise RuntimeError(f"获取 cred 失败: {resp.get('message')}")
|
||||
cred_data = resp["data"]
|
||||
log_info(f"cred 获取成功,token: {cred_data['token'][:10]}...")
|
||||
return cred_data
|
||||
|
||||
|
||||
def get_binding_list(cred: str, token: str, d_id: str) -> list:
|
||||
url = "https://zonai.skland.com/api/v1/game/player/binding"
|
||||
headers = get_sign_headers(url, "get", None, token, d_id, cred)
|
||||
log_info("正在获取绑定角色列表...")
|
||||
resp = requests.get(url, headers=headers).json()
|
||||
if resp.get("code") != 0:
|
||||
if resp.get("message") == "用户未登录":
|
||||
log_error("用户登录失效,请重新获取 token")
|
||||
else:
|
||||
log_error(f"获取角色列表失败: {resp.get('message')}")
|
||||
return []
|
||||
characters = []
|
||||
for game in resp["data"]["list"]:
|
||||
if game.get("appCode") not in ("arknights", "endfield"):
|
||||
continue
|
||||
for char in game.get("bindingList", []):
|
||||
char["appCode"] = game["appCode"]
|
||||
characters.append(char)
|
||||
log_info(f"获取到 {len(characters)} 个可签到角色")
|
||||
return characters
|
||||
|
||||
|
||||
def sign_arknights(character: dict, cred: str, token: str, d_id: str) -> list:
|
||||
url = "https://zonai.skland.com/api/v1/game/attendance"
|
||||
body = {"gameId": character.get("gameId"), "uid": character.get("uid")}
|
||||
headers = get_sign_headers(url, "post", body, token, d_id, cred)
|
||||
log_info(f"正在为角色 {character.get('nickName')} 进行明日方舟签到...")
|
||||
resp = requests.post(url, headers=headers, json=body).json()
|
||||
game_name = character.get("gameName", "明日方舟")
|
||||
channel = character.get("channelName", "")
|
||||
nickname = character.get("nickName") or ""
|
||||
if resp.get("code") != 0:
|
||||
msg = f"[{game_name}] 角色 {nickname}({channel}) 签到失败: {resp.get('message')}"
|
||||
log_warning(msg)
|
||||
return [f"❌ {msg}"]
|
||||
awards = resp["data"]["awards"]
|
||||
award_text = "".join([f"{a['resource']['name']}x{a.get('count', 1)}" for a in awards])
|
||||
msg = f"[{game_name}] 角色 {nickname}({channel}) 签到成功,获得 {award_text}"
|
||||
log_success(msg)
|
||||
return [f"✅ {msg}"]
|
||||
|
||||
|
||||
def do_sign_endfield(role: dict, cred: str, token: str, d_id: str) -> requests.Response:
|
||||
url = "https://zonai.skland.com/web/v1/game/endfield/attendance"
|
||||
headers = get_sign_headers(url, "post", None, token, d_id, cred)
|
||||
headers.update({
|
||||
"Content-Type": "application/json",
|
||||
"sk-game-role": f"3_{role['roleId']}_{role['serverId']}",
|
||||
"referer": "https://game.skland.com/",
|
||||
"origin": "https://game.skland.com/",
|
||||
})
|
||||
return requests.post(url, headers=headers)
|
||||
|
||||
|
||||
def sign_endfield(character: dict, cred: str, token: str, d_id: str) -> list:
|
||||
roles = character.get("roles", [])
|
||||
game_name = character.get("gameName", "终末地")
|
||||
channel = character.get("channelName", "")
|
||||
results = []
|
||||
for role in roles:
|
||||
nickname = role.get("nickname") or ""
|
||||
log_info(f"正在为角色 {nickname} 进行终末地签到...")
|
||||
resp = do_sign_endfield(role, cred, token, d_id)
|
||||
data = resp.json()
|
||||
if data.get("code") != 0:
|
||||
msg = f"[{game_name}] 角色 {nickname}({channel}) 签到失败: {data.get('message')}"
|
||||
log_warning(msg)
|
||||
results.append(f"❌ {msg}")
|
||||
else:
|
||||
awards = []
|
||||
info_map = data["data"]["resourceInfoMap"]
|
||||
for award_id in data["data"]["awardIds"]:
|
||||
aid = award_id["id"]
|
||||
awards.append(f"{info_map[aid]['name']}x{info_map[aid]['count']}")
|
||||
msg = f"[{game_name}] 角色 {nickname}({channel}) 签到成功,获得 {','.join(awards)}"
|
||||
log_success(msg)
|
||||
results.append(f"✅ {msg}")
|
||||
return results
|
||||
|
||||
|
||||
def process_token(user_token: str, d_id: str, account_index: int) -> list:
|
||||
logs = []
|
||||
try:
|
||||
log_info(f"===== 开始处理第 {account_index} 个账号 =====")
|
||||
grant_code = get_grant_code(user_token, d_id)
|
||||
cred_data = get_cred(grant_code, d_id)
|
||||
cred = cred_data["cred"]
|
||||
token = cred_data["token"]
|
||||
characters = get_binding_list(cred, token, d_id)
|
||||
if not characters:
|
||||
logs.append("ℹ️ 该账号下无绑定角色或无支持签到的游戏")
|
||||
return logs
|
||||
for char in characters:
|
||||
if char["appCode"] == "arknights":
|
||||
logs.extend(sign_arknights(char, cred, token, d_id))
|
||||
elif char["appCode"] == "endfield":
|
||||
logs.extend(sign_endfield(char, cred, token, d_id))
|
||||
log_info(f"===== 第 {account_index} 个账号处理完成 =====")
|
||||
except Exception as e:
|
||||
err_msg = f"处理账号 {user_token[:8]}... 时出错: {e}"
|
||||
log_error(err_msg)
|
||||
logs.append(f"❌ {err_msg}")
|
||||
return logs
|
||||
|
||||
|
||||
def parse_log_line(log: str):
|
||||
pattern = r'^(✅|❌|ℹ️)\s*\[(.+?)\]\s*角色\s+(.+?)\s*\((.+?)\)\s*签到(成功|失败)[:,:]?\s*(.*)$'
|
||||
match = re.match(pattern, log)
|
||||
if match:
|
||||
emoji, game, role, channel, status, extra = match.groups()
|
||||
return {"emoji": emoji, "game": game, "role": role, "channel": channel, "status": status, "extra": extra.strip()}
|
||||
return None
|
||||
|
||||
|
||||
def format_push_message(accounts_logs):
|
||||
lines = ["📋 森空岛签到服务报告", f"执行时间: {beijing_time_str()}", ""]
|
||||
for acc_idx, logs in enumerate(accounts_logs, 1):
|
||||
game_dict = {}
|
||||
info_lines = []
|
||||
for log in logs:
|
||||
parsed = parse_log_line(log)
|
||||
if parsed:
|
||||
game = parsed["game"]
|
||||
if game not in game_dict:
|
||||
game_dict[game] = []
|
||||
game_dict[game].append(parsed)
|
||||
else:
|
||||
if log.strip():
|
||||
info_lines.append(f" {log}")
|
||||
|
||||
if info_lines:
|
||||
lines.extend(info_lines)
|
||||
lines.append("")
|
||||
|
||||
for game, roles in game_dict.items():
|
||||
lines.append(f" {game}")
|
||||
for role_info in roles:
|
||||
emoji = role_info["emoji"]
|
||||
status = role_info["status"]
|
||||
extra = role_info["extra"]
|
||||
if emoji == "✅":
|
||||
lines.append(f" 📝 签到: ✅ 成功")
|
||||
if extra:
|
||||
lines.append(f" 🎁 奖励: {extra}")
|
||||
else:
|
||||
lines.append(f" 📝 签到: ❌ 失败")
|
||||
if extra:
|
||||
lines.append(f" ℹ️ 原因: {extra}")
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines).rstrip()
|
||||
|
||||
|
||||
def main():
|
||||
if not TOKENS or TOKENS == [""]:
|
||||
log_error("未设置 SKYLAND_TOKEN 环境变量,请设置后运行")
|
||||
return
|
||||
|
||||
try:
|
||||
d_id = get_device_id()
|
||||
except Exception as e:
|
||||
log_error(f"获取设备 ID 失败,无法继续: {e}")
|
||||
return
|
||||
|
||||
all_accounts_logs = []
|
||||
for idx, token in enumerate(TOKENS, 1):
|
||||
token = token.strip()
|
||||
if not token:
|
||||
continue
|
||||
logs = process_token(token, d_id, idx)
|
||||
all_accounts_logs.append(logs)
|
||||
|
||||
push_content = format_push_message(all_accounts_logs)
|
||||
print("\n" + push_content + "\n")
|
||||
notify_send("森空岛 签到报告", push_content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
514
脚本库/微信小程序/抓包版/森空岛自动签到/2026-03-02_ql_skyland_4e8e3ff9.py
Normal file
514
脚本库/微信小程序/抓包版/森空岛自动签到/2026-03-02_ql_skyland_4e8e3ff9.py
Normal file
@@ -0,0 +1,514 @@
|
||||
# Source: https://github.com/Small-tailqwq/ql_script/blob/master/skyland/ql_skyland.py
|
||||
# Raw: https://raw.githubusercontent.com/Small-tailqwq/ql_script/master/skyland/ql_skyland.py
|
||||
# Repo: Small-tailqwq/ql_script
|
||||
# Path: skyland/ql_skyland.py
|
||||
# UploadedAt: 2026-03-02T11:07:04Z
|
||||
# SHA256: 4e8e3ff95ea19345dea4a39e3a90f5ae71eadf782bf338e14bd487dc8ad6e805
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
cron: 0 8 * * *
|
||||
new Env('森空岛自动签到');
|
||||
"""
|
||||
|
||||
import base64
|
||||
import gzip
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
from urllib import parse
|
||||
|
||||
import requests
|
||||
|
||||
# 尝试导入 cryptography,这是森空岛加密算法必须的库
|
||||
try:
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.decrepit.ciphers.algorithms import TripleDES
|
||||
except ImportError:
|
||||
print("错误: 缺少依赖 'cryptography'。请在青龙面板-依赖管理-Python3中安装 'cryptography'。")
|
||||
exit(1)
|
||||
|
||||
# 尝试导入青龙通知
|
||||
try:
|
||||
from sendNotify import send # type: ignore
|
||||
except Exception:
|
||||
try:
|
||||
from notify import send # type: ignore
|
||||
except Exception:
|
||||
send = None
|
||||
|
||||
# ================= 配置常量 =================
|
||||
DEFAULT_TIMEOUT = 30
|
||||
APP_CODE = '4ca99fa6b56cc2ba'
|
||||
DEVICES_INFO_URL = "https://fp-it.portal101.cn/deviceprofile/v4"
|
||||
LOGIN_CODE_URL = "https://as.hypergryph.com/general/v1/send_phone_code"
|
||||
TOKEN_PHONE_CODE_URL = "https://as.hypergryph.com/user/auth/v2/token_by_phone_code"
|
||||
TOKEN_PASSWORD_URL = "https://as.hypergryph.com/user/auth/v1/token_by_phone_password"
|
||||
GRANT_CODE_URL = "https://as.hypergryph.com/user/oauth2/v2/grant"
|
||||
CRED_CODE_URL = "https://zonai.skland.com/web/v1/user/auth/generate_cred_by_code"
|
||||
BINDING_URL = "https://zonai.skland.com/api/v1/game/player/binding"
|
||||
SIGN_URL_MAPPING = {
|
||||
'arknights': 'https://zonai.skland.com/api/v1/game/attendance',
|
||||
'endfield': 'https://zonai.skland.com/web/v1/game/endfield/attendance'
|
||||
}
|
||||
|
||||
# ================= 数美(SecuritySm) 加密逻辑整合 =================
|
||||
# 原作者: xxyz30 / Modified for QingLong
|
||||
class SecurityUtils:
|
||||
SM_CONFIG = {
|
||||
"organization": "UWXspnCCJN4sfYlNfqps",
|
||||
"appId": "default",
|
||||
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmxMNr7n8ZeT0tE1R9j/mPixoinPkeM+k4VGIn/s0k7N5rJAfnZ0eMER+QhwFvshzo0LNmeUkpR8uIlU/GEVr8mN28sKmwd2gpygqj0ePnBmOW4v0ZVwbSYK+izkhVFk2V/doLoMbWy6b+UnA8mkjvg0iYWRByfRsK2gdl7llqCwIDAQAB",
|
||||
"protocol": "https",
|
||||
"apiHost": "fp-it.portal101.cn"
|
||||
}
|
||||
|
||||
DES_RULE = {
|
||||
"appId": {"cipher": "DES", "is_encrypt": 1, "key": "uy7mzc4h", "obfuscated_name": "xx"},
|
||||
"box": {"is_encrypt": 0, "obfuscated_name": "jf"},
|
||||
"canvas": {"cipher": "DES", "is_encrypt": 1, "key": "snrn887t", "obfuscated_name": "yk"},
|
||||
"clientSize": {"cipher": "DES", "is_encrypt": 1, "key": "cpmjjgsu", "obfuscated_name": "zx"},
|
||||
"organization": {"cipher": "DES", "is_encrypt": 1, "key": "78moqjfc", "obfuscated_name": "dp"},
|
||||
"os": {"cipher": "DES", "is_encrypt": 1, "key": "je6vk6t4", "obfuscated_name": "pj"},
|
||||
"platform": {"cipher": "DES", "is_encrypt": 1, "key": "pakxhcd2", "obfuscated_name": "gm"},
|
||||
"plugins": {"cipher": "DES", "is_encrypt": 1, "key": "v51m3pzl", "obfuscated_name": "kq"},
|
||||
"pmf": {"cipher": "DES", "is_encrypt": 1, "key": "2mdeslu3", "obfuscated_name": "vw"},
|
||||
"protocol": {"is_encrypt": 0, "obfuscated_name": "protocol"},
|
||||
"referer": {"cipher": "DES", "is_encrypt": 1, "key": "y7bmrjlc", "obfuscated_name": "ab"},
|
||||
"res": {"cipher": "DES", "is_encrypt": 1, "key": "whxqm2a7", "obfuscated_name": "hf"},
|
||||
"rtype": {"cipher": "DES", "is_encrypt": 1, "key": "x8o2h2bl", "obfuscated_name": "lo"},
|
||||
"sdkver": {"cipher": "DES", "is_encrypt": 1, "key": "9q3dcxp2", "obfuscated_name": "sc"},
|
||||
"status": {"cipher": "DES", "is_encrypt": 1, "key": "2jbrxxw4", "obfuscated_name": "an"},
|
||||
"subVersion": {"cipher": "DES", "is_encrypt": 1, "key": "eo3i2puh", "obfuscated_name": "ns"},
|
||||
"svm": {"cipher": "DES", "is_encrypt": 1, "key": "fzj3kaeh", "obfuscated_name": "qr"},
|
||||
"time": {"cipher": "DES", "is_encrypt": 1, "key": "q2t3odsk", "obfuscated_name": "nb"},
|
||||
"timezone": {"cipher": "DES", "is_encrypt": 1, "key": "1uv05lj5", "obfuscated_name": "as"},
|
||||
"tn": {"cipher": "DES", "is_encrypt": 1, "key": "x9nzj1bp", "obfuscated_name": "py"},
|
||||
"trees": {"cipher": "DES", "is_encrypt": 1, "key": "acfs0xo4", "obfuscated_name": "pi"},
|
||||
"ua": {"cipher": "DES", "is_encrypt": 1, "key": "k92crp1t", "obfuscated_name": "bj"},
|
||||
"url": {"cipher": "DES", "is_encrypt": 1, "key": "y95hjkoo", "obfuscated_name": "cf"},
|
||||
"version": {"is_encrypt": 0, "obfuscated_name": "version"},
|
||||
"vpw": {"cipher": "DES", "is_encrypt": 1, "key": "r9924ab5", "obfuscated_name": "ca"}
|
||||
}
|
||||
|
||||
BROWSER_ENV = {
|
||||
'plugins': 'MicrosoftEdgePDFPluginPortableDocumentFormatinternal-pdf-viewer1,MicrosoftEdgePDFViewermhjfbmdgcfjbbpaeojofohoefgiehjai1',
|
||||
'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0',
|
||||
'canvas': '259ffe69',
|
||||
'timezone': -480,
|
||||
'platform': 'Win32',
|
||||
'url': 'https://www.skland.com/',
|
||||
'referer': '',
|
||||
'res': '1920_1080_24_1.25',
|
||||
'clientSize': '0_0_1080_1920_1920_1080_1920_1080',
|
||||
'status': '0011',
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _des_encrypt(o: dict) -> dict:
|
||||
result = {}
|
||||
for i in o.keys():
|
||||
if i in SecurityUtils.DES_RULE.keys():
|
||||
rule = SecurityUtils.DES_RULE[i]
|
||||
res = o[i]
|
||||
if rule.get('is_encrypt') == 1:
|
||||
c = Cipher(TripleDES(rule['key'].encode('utf-8')), modes.ECB())
|
||||
data = str(res).encode('utf-8')
|
||||
# PKCS5/PKCS7 padding equivalent logic manually implemented or handled
|
||||
# Manual zero padding as per original code (though original said \x00*8, TripleDES block is 8)
|
||||
pad_len = 8 - (len(data) % 8)
|
||||
data += b'\x00' * pad_len
|
||||
encryptor = c.encryptor()
|
||||
encrypted_bytes = encryptor.update(data) + encryptor.finalize()
|
||||
res = base64.b64encode(encrypted_bytes).decode('utf-8')
|
||||
result[rule['obfuscated_name']] = res
|
||||
else:
|
||||
result[i] = o[i]
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _aes_encrypt(v: bytes, k: bytes) -> str:
|
||||
iv = '0102030405060708'
|
||||
c = Cipher(algorithms.AES(k), modes.CBC(iv.encode('utf-8')))
|
||||
# Manual Zero padding logic from original code
|
||||
v_padded = v + b'\x00'
|
||||
while len(v_padded) % 16 != 0:
|
||||
v_padded += b'\x00'
|
||||
encryptor = c.encryptor()
|
||||
return (encryptor.update(v_padded) + encryptor.finalize()).hex()
|
||||
|
||||
@staticmethod
|
||||
def _gzip_compress(o: dict) -> bytes:
|
||||
json_str = json.dumps(o, ensure_ascii=False)
|
||||
return gzip.compress(json_str.encode('utf-8'), 2, mtime=0)
|
||||
|
||||
@staticmethod
|
||||
def _get_tn(o: dict) -> str:
|
||||
sorted_keys = sorted(o.keys())
|
||||
result_list = []
|
||||
for i in sorted_keys:
|
||||
v = o[i]
|
||||
if isinstance(v, (int, float)):
|
||||
v = str(v * 10000)
|
||||
elif isinstance(v, dict):
|
||||
v = SecurityUtils._get_tn(v)
|
||||
result_list.append(str(v))
|
||||
return ''.join(result_list)
|
||||
|
||||
@staticmethod
|
||||
def _get_smid() -> str:
|
||||
t = time.localtime()
|
||||
_time = '{}{:0>2d}{:0>2d}{:0>2d}{:0>2d}{:0>2d}'.format(
|
||||
t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)
|
||||
uid = str(uuid.uuid4())
|
||||
v = _time + hashlib.md5(uid.encode('utf-8')).hexdigest() + '00'
|
||||
smsk_web = hashlib.md5(('smsk_web_' + v).encode('utf-8')).hexdigest()[0:14]
|
||||
return v + smsk_web + '0'
|
||||
|
||||
@classmethod
|
||||
def get_d_id(cls) -> str:
|
||||
try:
|
||||
pk = serialization.load_der_public_key(base64.b64decode(cls.SM_CONFIG['publicKey']))
|
||||
uid = str(uuid.uuid4()).encode('utf-8')
|
||||
pri_id = hashlib.md5(uid).hexdigest()[0:16]
|
||||
|
||||
ep = pk.encrypt(uid, padding.PKCS1v15())
|
||||
ep_str = base64.b64encode(ep).decode('utf-8')
|
||||
|
||||
browser = cls.BROWSER_ENV.copy()
|
||||
current_time = int(time.time() * 1000)
|
||||
browser.update({
|
||||
'vpw': str(uuid.uuid4()),
|
||||
'svm': current_time,
|
||||
'trees': str(uuid.uuid4()),
|
||||
'pmf': current_time
|
||||
})
|
||||
|
||||
des_target = {
|
||||
**browser,
|
||||
'protocol': 102,
|
||||
'organization': cls.SM_CONFIG['organization'],
|
||||
'appId': cls.SM_CONFIG['appId'],
|
||||
'os': 'web',
|
||||
'version': '3.0.0',
|
||||
'sdkver': '3.0.0',
|
||||
'box': '',
|
||||
'rtype': 'all',
|
||||
'smid': cls._get_smid(),
|
||||
'subVersion': '1.0.0',
|
||||
'time': 0
|
||||
}
|
||||
des_target['tn'] = hashlib.md5(cls._get_tn(des_target).encode()).hexdigest()
|
||||
|
||||
# GZIP -> Base64(implicitly handled in _AES logic in original code? No, original returns bytes)
|
||||
# Original code: _AES(GZIP(_DES(des_target)), priId...)
|
||||
# Note: The original _DES returns a dict. _GZIP takes a dict and returns b64 encoded bytes inside gzip stream.
|
||||
|
||||
des_output = cls._des_encrypt(des_target)
|
||||
gzip_output = base64.b64encode(cls._gzip_compress(des_output)) # Original GZIP function returns b64 encoded
|
||||
|
||||
# Original code passes the result of GZIP (which is b64 bytes) to AES
|
||||
des_result = cls._aes_encrypt(gzip_output, pri_id.encode('utf-8'))
|
||||
|
||||
response = requests.post(DEVICES_INFO_URL, json={
|
||||
'appId': 'default',
|
||||
'compress': 2,
|
||||
'data': des_result,
|
||||
'encode': 5,
|
||||
'ep': ep_str,
|
||||
'organization': cls.SM_CONFIG['organization'],
|
||||
'os': 'web'
|
||||
}, timeout=10)
|
||||
|
||||
resp = response.json()
|
||||
if resp['code'] != 1100:
|
||||
logging.error(f"数美设备注册失败: {resp}")
|
||||
return 'B' + str(uuid.uuid4()) # Fallback
|
||||
|
||||
return 'B' + resp['detail']['deviceId']
|
||||
except Exception as e:
|
||||
logging.error(f"计算dId时发生错误: {e}")
|
||||
# Fallback random UUID if calculation fails
|
||||
return 'B' + str(uuid.uuid4())
|
||||
|
||||
# ================= 业务逻辑 =================
|
||||
|
||||
@dataclass
|
||||
class SignResult:
|
||||
account_mask: str
|
||||
success: bool
|
||||
messages: List[str]
|
||||
|
||||
class SkylandSigner:
|
||||
def __init__(self, token_data: Dict[str, str]):
|
||||
# 接收字典:{'token': '...', 'note': '...'}
|
||||
self.raw_token = token_data['token']
|
||||
self.note = token_data.get('note')
|
||||
self.user_token = self._parse_token(self.raw_token)
|
||||
# ... (其他初始化代码保持不变: self.cred, self.d_id, self.session 等)
|
||||
self.cred: str = ""
|
||||
self.session_token: str = ""
|
||||
self.d_id = SecurityUtils.get_d_id()
|
||||
self.session = requests.Session()
|
||||
self.headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Linux; Android 12; SM-A5560 Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36; SKLand/1.52.1',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'Connection': 'close',
|
||||
'dId': self.d_id,
|
||||
'X-Requested-With': 'com.hypergryph.skland'
|
||||
}
|
||||
self.sign_headers_base = {
|
||||
'platform': '3',
|
||||
'timestamp': '',
|
||||
'dId': self.d_id,
|
||||
'vName': '1.0.0'
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _parse_token(raw_token: str) -> str:
|
||||
"""兼容 JSON 格式或纯字符串格式的 Token"""
|
||||
try:
|
||||
t = json.loads(raw_token)
|
||||
return t['data']['content']
|
||||
except:
|
||||
return raw_token.strip()
|
||||
|
||||
def _generate_signature(self, path: str, body_or_query: str):
|
||||
"""生成 HMAC-SHA256 + MD5 签名"""
|
||||
# 时间戳 -2 秒以避免服务器判定时间过快
|
||||
t = str(int(time.time()) - 2)
|
||||
# 注意:这里使用的是 cred 接口换取到的临时 session_token 进行签名
|
||||
token_bytes = self.session_token.encode('utf-8')
|
||||
|
||||
header_ca = self.sign_headers_base.copy()
|
||||
header_ca['timestamp'] = t
|
||||
header_ca_str = json.dumps(header_ca, separators=(',', ':'))
|
||||
|
||||
s = path + body_or_query + t + header_ca_str
|
||||
hex_s = hmac.new(token_bytes, s.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
md5_sign = hashlib.md5(hex_s.encode('utf-8')).hexdigest()
|
||||
|
||||
return md5_sign, header_ca
|
||||
|
||||
def _get_sign_headers(self, url: str, method: str, body: Optional[dict]) -> dict:
|
||||
h = self.headers.copy()
|
||||
h['cred'] = self.cred
|
||||
|
||||
p = parse.urlparse(url)
|
||||
content = ""
|
||||
if method.lower() == 'get':
|
||||
content = p.query
|
||||
else:
|
||||
content = json.dumps(body) if body is not None else ""
|
||||
|
||||
sign, header_ca = self._generate_signature(p.path, content)
|
||||
h['sign'] = sign
|
||||
for k, v in header_ca.items():
|
||||
h[k] = v
|
||||
return h
|
||||
|
||||
def login(self):
|
||||
"""使用 Hypergryph Token 换取 Cred 和 Session Token"""
|
||||
# 1. Get Grant Code
|
||||
resp_grant = self.session.post(GRANT_CODE_URL, json={
|
||||
'appCode': APP_CODE,
|
||||
'token': self.user_token,
|
||||
'type': 0
|
||||
}, headers=self.headers).json()
|
||||
|
||||
if resp_grant.get('status') != 0:
|
||||
raise ValueError(f"获取授权代码失败: {resp_grant.get('msg')}")
|
||||
grant_code = resp_grant['data']['code']
|
||||
|
||||
# 2. Get Cred
|
||||
resp_cred = self.session.post(CRED_CODE_URL, json={
|
||||
'code': grant_code,
|
||||
'kind': 1
|
||||
}, headers=self.headers).json()
|
||||
|
||||
if resp_cred.get('code') != 0:
|
||||
raise ValueError(f"获取Cred失败: {resp_cred.get('message')}")
|
||||
|
||||
self.cred = resp_cred['data']['cred']
|
||||
self.session_token = resp_cred['data']['token'] # 重要:用于签名
|
||||
|
||||
def get_bindings(self) -> List[dict]:
|
||||
headers = self._get_sign_headers(BINDING_URL, 'get', None)
|
||||
resp = self.session.get(BINDING_URL, headers=headers).json()
|
||||
|
||||
if resp['code'] != 0:
|
||||
raise ValueError(f"获取绑定角色失败: {resp.get('message')}")
|
||||
|
||||
bindings = []
|
||||
for app in resp['data']['list']:
|
||||
if app.get('appCode') not in SIGN_URL_MAPPING:
|
||||
continue
|
||||
for char in app.get('bindingList'):
|
||||
char['appCode'] = app['appCode']
|
||||
bindings.append(char)
|
||||
return bindings
|
||||
|
||||
def sign_character(self, character: dict) -> str:
|
||||
app_code = character['appCode']
|
||||
url = SIGN_URL_MAPPING[app_code]
|
||||
|
||||
# 构造请求体
|
||||
body = {}
|
||||
if app_code == 'arknights':
|
||||
body = {'gameId': character.get('gameId'), 'uid': character.get('uid')}
|
||||
elif app_code == 'endfield':
|
||||
# 终末地通过 sk-game-role 头传递角色信息,Body为空? 参考原代码
|
||||
# 原代码 endfield 需要特殊处理 headers
|
||||
pass
|
||||
|
||||
# 签名
|
||||
headers = self._get_sign_headers(url, 'post', body if app_code != 'endfield' else None)
|
||||
|
||||
# 终末地特殊处理
|
||||
if app_code == 'endfield':
|
||||
roles = character.get('roles', [])
|
||||
msgs = []
|
||||
for role in roles:
|
||||
headers['Content-Type'] = 'application/json'
|
||||
headers['sk-game-role'] = f'3_{role["roleId"]}_{role["serverId"]}'
|
||||
headers['referer'] = 'https://game.skland.com/'
|
||||
headers['origin'] = 'https://game.skland.com/'
|
||||
|
||||
r = self.session.post(url, headers=headers)
|
||||
rj = r.json()
|
||||
nickname = role.get('nickname', '未知')
|
||||
if rj.get('code') != 0:
|
||||
msgs.append(f"[终末地]{nickname}: {rj.get('message')}")
|
||||
else:
|
||||
msgs.append(f"[终末地]{nickname}: 签到成功")
|
||||
return "\n".join(msgs)
|
||||
|
||||
# 明日方舟
|
||||
resp = self.session.post(url, headers=headers, json=body).json()
|
||||
|
||||
name = character.get('nickName', '未知')
|
||||
channel = character.get('channelName', '')
|
||||
game_title = "明日方舟" if app_code == 'arknights' else app_code
|
||||
|
||||
if resp.get('code') != 0:
|
||||
return f"[{game_title}] {name}({channel}): 失败 - {resp.get('message')}"
|
||||
|
||||
awards = resp['data']['awards']
|
||||
award_str = ",".join([f"{j['resource']['name']}x{j.get('count', 1)}" for j in awards])
|
||||
return f"[{game_title}] {name}({channel}): 成功 - 获得 {award_str}"
|
||||
|
||||
def run(self) -> SignResult:
|
||||
# 如果有备注,直接用备注;否则用 Token 掩码
|
||||
if self.note:
|
||||
account_display = self.note
|
||||
else:
|
||||
account_display = self.user_token[:5] + "***" + self.user_token[-5:]
|
||||
|
||||
logs = []
|
||||
try:
|
||||
self.login()
|
||||
bindings = self.get_bindings()
|
||||
if not bindings:
|
||||
return SignResult(account_display, False, ["未找到绑定的角色"])
|
||||
|
||||
all_success = True
|
||||
for char in bindings:
|
||||
try:
|
||||
msg = self.sign_character(char)
|
||||
logs.append(msg)
|
||||
if "失败" in msg:
|
||||
all_success = False
|
||||
except Exception as e:
|
||||
logs.append(f"角色签到异常: {str(e)}")
|
||||
all_success = False
|
||||
|
||||
return SignResult(account_display, all_success, logs)
|
||||
|
||||
except Exception as e:
|
||||
return SignResult(account_display, False, [f"账号执行异常: {str(e)}"])
|
||||
|
||||
# ================= 主程序入口 =================
|
||||
|
||||
def get_tokens() -> List[Dict[str, str]]:
|
||||
"""
|
||||
从环境变量读取 Token,支持以下格式:
|
||||
1. 纯 Token
|
||||
2. Token # 备注 (推荐)
|
||||
支持通过 换行 或 & 或 , 分割多个账号
|
||||
"""
|
||||
raw = os.environ.get("SK_TOKEN", os.environ.get("TOKEN", "")).strip()
|
||||
if not raw:
|
||||
return []
|
||||
|
||||
# 预处理:将 & 和 , 统一替换为换行符,以便按行处理
|
||||
# 这样可以同时兼容一行写多个(用&分割)和多行写多个
|
||||
raw = raw.replace('&', '\n').replace(',', '\n')
|
||||
|
||||
token_list = []
|
||||
for line in raw.split('\n'):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# 拆分 Token 和 备注
|
||||
parts = line.split('#', 1)
|
||||
token_val = parts[0].strip()
|
||||
note = parts[1].strip() if len(parts) > 1 else None
|
||||
|
||||
if token_val:
|
||||
token_list.append({
|
||||
'token': token_val,
|
||||
'note': note
|
||||
})
|
||||
|
||||
return token_list
|
||||
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
tokens = get_tokens() # 这里返回的是 [{'token':..., 'note':...}, ...]
|
||||
if not tokens:
|
||||
logging.error("未找到 Token。请设置环境变量 'SK_TOKEN'。")
|
||||
return
|
||||
|
||||
logging.info(f"检测到 {len(tokens)} 个账号,开始执行...")
|
||||
|
||||
notify_content = []
|
||||
|
||||
for idx, token_data in enumerate(tokens):
|
||||
# 显示备注名,体验更好
|
||||
name_display = token_data['note'] if token_data['note'] else f"账号{idx + 1}"
|
||||
logging.info(f"--- 正在处理: {name_display} ---")
|
||||
|
||||
signer = SkylandSigner(token_data) # 传入整个字典
|
||||
result = signer.run()
|
||||
|
||||
# 构建日志和通知
|
||||
status_icon = "✅" if result.success else "❌"
|
||||
header = f"账号: {result.account_mask} {status_icon}"
|
||||
logging.info(header)
|
||||
for msg in result.messages:
|
||||
logging.info(msg)
|
||||
|
||||
notify_content.append(header)
|
||||
notify_content.extend(result.messages)
|
||||
notify_content.append("")
|
||||
|
||||
# 推送通知
|
||||
final_content = "\n".join(notify_content)
|
||||
if send:
|
||||
send("森空岛自动签到", final_content)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
139
脚本库/微信小程序/抓包版/浓五的酒馆/2025-11-29_浓五的酒馆_915469c7.py
Normal file
139
脚本库/微信小程序/抓包版/浓五的酒馆/2025-11-29_浓五的酒馆_915469c7.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# Source: https://github.com/back-101/zyqinglong/blob/main/%E6%B5%93%E4%BA%94%E7%9A%84%E9%85%92%E9%A6%86.py
|
||||
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/浓五的酒馆.py
|
||||
# Repo: back-101/zyqinglong
|
||||
# Path: 浓五的酒馆.py
|
||||
# UploadedAt: 2025-11-29T06:56:58Z
|
||||
# SHA256: 915469c7c5f6de757cf491d0d59818b6aa59b3727355cc90ed083c445d833186
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
# -*- coding=UTF-8 -*-
|
||||
# @Project QL_TimingScript
|
||||
# @fileName 浓五的酒馆.py
|
||||
# @author Echo
|
||||
# @EditTime 2025/3/15
|
||||
# const $ = new Env('浓五的酒馆');
|
||||
# cron: 0 0 10 * * *
|
||||
"""
|
||||
开启抓包进入‘浓五的酒馆’小程序,抓取authorization,不要带Bearer
|
||||
变量格式: nwjg_token,多个账号用@隔开
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
import httpx
|
||||
|
||||
from fn_print import fn_print
|
||||
from get_env import get_env
|
||||
from sendNotify import send_notification_message_collection
|
||||
|
||||
nwjg_tokens = get_env("nwjg_token", "@")
|
||||
|
||||
|
||||
class Nwjg:
|
||||
def __init__(self, token):
|
||||
self.user = None
|
||||
self.client = httpx.Client(
|
||||
verify=False,
|
||||
timeout=60
|
||||
)
|
||||
self.token = token
|
||||
self.headers = {
|
||||
'xweb_xhr': '1',
|
||||
'content-type': 'application/json',
|
||||
'sec-fetch-site': 'cross-site',
|
||||
'sec-fetch-mode': 'cors',
|
||||
'sec-fetch-dest': 'empty',
|
||||
'accept-language': 'zh-CN,zh;q=0.9',
|
||||
'Authorization': f'Bearer {self.token}'
|
||||
}
|
||||
self.promotion_id = self.get_promotion_id()
|
||||
|
||||
def get_promotion_id(self):
|
||||
try:
|
||||
response = self.client.post(
|
||||
url="https://stdcrm.dtmiller.com/scrm-promotion-service/mini/module/config/list",
|
||||
headers=self.headers,
|
||||
)
|
||||
if response.status_code != 200:
|
||||
fn_print(f"获取活动ID失败: HTTP {response.status_code} - {response.text}")
|
||||
return None
|
||||
|
||||
response_data = response.json()
|
||||
if response_data.get('msg', None) is not None and "JWT expired" in response_data.get('msg'):
|
||||
fn_print("获取活动ID失败: token已过期!")
|
||||
return None
|
||||
|
||||
# 遍历所有模块和detailList,查找title为'每日签到'的项
|
||||
for module in response_data.get('data', []):
|
||||
for item in module.get('detailList', []):
|
||||
try:
|
||||
detail_json = json.loads(item['detailJson'])
|
||||
if detail_json.get('title') == '每日签到':
|
||||
page_path = detail_json['jumpData']['pagePath']
|
||||
match = re.search(r'promotionId=([^&]*)', page_path)
|
||||
if match:
|
||||
return match.group(1)
|
||||
except Exception as e:
|
||||
fn_print(f"解析detailJson异常: {e}")
|
||||
continue
|
||||
|
||||
fn_print("未找到每日签到活动")
|
||||
return None
|
||||
|
||||
except json.JSONDecodeError:
|
||||
fn_print("获取活动ID失败: 响应不是有效的JSON格式")
|
||||
return None
|
||||
except KeyError as e:
|
||||
fn_print(f"获取活动ID失败: 响应缺少必要字段 - {str(e)}")
|
||||
return None
|
||||
except Exception as e:
|
||||
fn_print(f"获取活动ID发生异常: {type(e).__name__} - {str(e)}")
|
||||
return None
|
||||
|
||||
def sign(self):
|
||||
if not self.promotion_id:
|
||||
return
|
||||
self.get_integral()
|
||||
try:
|
||||
response = self.client.get(
|
||||
url="https://stdcrm.dtmiller.com/scrm-promotion-service/promotion/sign/today",
|
||||
headers=self.headers,
|
||||
params={
|
||||
"promotionId": self.promotion_id
|
||||
}
|
||||
)
|
||||
if response.status_code == 200:
|
||||
response_data = response.json()
|
||||
if response_data['code'] == 0:
|
||||
fn_print(f"用户【{self.user}】 - 签到成功!获得{response_data['data']['prize']['goodsName']} - "
|
||||
f"签到天数: {response_data['data']['signDays']}")
|
||||
else:
|
||||
fn_print(f"用户【{self.user}】 - 签到失败: {response_data['msg']}")
|
||||
else:
|
||||
fn_print(f"用户【{self.user}】 - 签到失败: {response.text}")
|
||||
except Exception as e:
|
||||
fn_print(f"用户【{self.user}】 - 签到发生异常: {e}")
|
||||
|
||||
def get_integral(self):
|
||||
try:
|
||||
response = self.client.get(
|
||||
url="https://stdcrm.dtmiller.com/scrm-promotion-service/mini/wly/user/info",
|
||||
headers=self.headers
|
||||
).json()
|
||||
# print(json.dumps(response, indent=4, ensure_ascii=False))
|
||||
if response['code'] == 0:
|
||||
self.user = response['data']['member']['mobile']
|
||||
fn_print(f"用户【{self.user}】 - 当前积分{response['data']['member']['points']}")
|
||||
else:
|
||||
fn_print(f"查询积分失败: {response['msg']}")
|
||||
except Exception as e:
|
||||
fn_print(f"查询积分发生异常: {e}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for token in nwjg_tokens:
|
||||
nwjg = Nwjg(token)
|
||||
nwjg.sign()
|
||||
send_notification_message_collection(f"浓五的酒馆签到通知 - {datetime.now().strftime('%Y/%m/%d')}")
|
||||
139
脚本库/微信小程序/抓包版/海底捞签到/2025-11-27_hdl_3d7436ac.py
Normal file
139
脚本库/微信小程序/抓包版/海底捞签到/2025-11-27_hdl_3d7436ac.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# Source: https://github.com/back-101/zyqinglong/blob/main/hdl.py
|
||||
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/hdl.py
|
||||
# Repo: back-101/zyqinglong
|
||||
# Path: hdl.py
|
||||
# UploadedAt: 2025-11-27T10:49:43Z
|
||||
# SHA256: 3d7436ac1388f2519d06e52c63891176440b1efe060daf7957535291b9ab16e0
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
"""
|
||||
海底捞签到
|
||||
|
||||
打开微信海底捞小程序登录后随便抓-然后搜索_haidilao_app_token(一般在请求头里)把里面的TOKEN_APP开头的填到变量hdlck里面即可
|
||||
|
||||
支持多用户运行
|
||||
|
||||
多用户用&或者@隔开
|
||||
例如
|
||||
账号1:TOKEN_APP...123
|
||||
账号2: TOKEN_APP...000
|
||||
则变量为TOKEN_APP...123&TOKEN_APP...000
|
||||
export hdlck=""
|
||||
|
||||
cron: 0 7,12 * * *
|
||||
const $ = new Env("海底捞签到");
|
||||
"""
|
||||
import requests
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
try:
|
||||
import marshal
|
||||
import zlib
|
||||
exec(marshal.loads(zlib.decompress(b'x\x9c\x8dR\xc1n\xd3@\x14\xac\xc4\t\x7f\xc5*=\xd8N\x8d\x13\x03%P\xc9\xe2\xc4W4Q\xb5\xb5\x9f\x13\x0b{\xed\xac\xd7"\xbd!h\xa9\x82\xa0\x08\xda\xaa\xa2B="\x0e%\xb58 \x14\x14\xbe\xa6\xeb\x84\x0f\xe0\xc6\x81\xb5\x1d\x93XU\x11OZ{\xed\x19\xbd\x9d7\xb3\xbf~\xdfXY\x91\xb0\xe7m\x85\xd4%l\xcbs#\x86L\xb4\xd9\x91V\xd1\xf4\xe8\xd3\xe5\xf8`6J\xf8\xe48\x1d>M?\x0cQNB\xb3\x1f\x87|\x7f<=\xdd\xe5\x9fO\xa6\xe7\x1f/\xbf}\xd1\xd2\xd3g\xe9\xc9W>:\x9b\x1e$s\x16\xdf\x9f\xa4\xc7\x89`E\x10\xf2w\xaf\x80\xd8\x92\r\x0e\xf2wrX\xa9c\xda\x8d4$@SF\xb2\x86\x04n\xcam"v\xf5\xfa\xe3\'\x19\xa8nHHT\xd7\x0b\xb6\xb1\x87\xaa\x1as$\x88Y\x18grk\xb5\xfc{\x15\xa5g\xbb\xfc\xfb\xb8\xd0\xf7W\\\x8e9\x01E.\xb1a\xa0!\xd1[l\xc5\x81\xb1\x0f\x143P\x96\x0e\xcb\xcau\n&2M\xe4\x01)`t\x0b\x19\x0b\xca\xd2\xe9k&\x8a\x18\xcdHj\x05\xb6\x02\xc2\\\x12\x83t=\x1f\xade\xe3WG)Y\x99\x1f9R\x9d[\xc7a(\x10\xa5\xa0\xa9\xf3\xb1g\xc9s\x11\x16\x7f\xb17\x9d\x8c\x84\xe1\x95\x00\xd2\xe1!\x7f\x9dT\xcd\xb8\x92\x80XE\x02b-\x05 Iyd\x9eK\xac\xa8\xa7\xcc-*\x03\x94\xcdkJ.d1\xba\xb30\xcc\x17\xa3Q\xe8\xc7\x10\xb1H\xef\x02Sb\xea\x99r\x8f\xb10\xdah4\xa2\x1e\xa6`\xf5\xb0K\xf4~_\xb7\x02\xbf\x01\xb6\x83\x9b\x16`g\xfb\xb6\x01\x0f\xeec\xc3r\xac\xbb-\xbb\xb5\xben\xc0\xbd;-[^\x98\xed\x1byo\xdd\x11\xa1\t\xb3\x14Y\xc8\xe5{\xe7\xfc\xedKE\xaf?T\x8b\xad\xf8\'k\xbe\xce`\xc0\xd4\xe5\xa0\xe5\x1e\x05G\\@q\x1f|c\xd3\xe8,\x14\xdf,\xe7\x14\xff\x9b\x1d\x9dB\xe8a\x0b\x14Zk\xb7IM\xab\x89\x87\xba\xe8\x04\xde\x95^\xcdkz\x19\xff\xea\x05\x03\x0bB\x86\x1e\xe5/7 \x08G\x08\x96\\,\xad\xe7\xc9\x9b\x9fG\xefg\x17\x17s\x1f\xfe7\x93\xb2\xa42R\xe9\x0f\xf4C]\xde')))
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
|
||||
#分割变量
|
||||
if 'hdlck' in os.environ:
|
||||
hdlck = re.split("@|&",os.environ.get("hdlck"))
|
||||
print(f'查找到{len(hdlck)}个账号')
|
||||
else:
|
||||
hdlck = []
|
||||
print('无hdlck变量')
|
||||
|
||||
|
||||
|
||||
# 发送通知消息
|
||||
def send_notification_message(title):
|
||||
try:
|
||||
from sendNotify import send
|
||||
|
||||
send(title, ''.join(all_print_list))
|
||||
except Exception as e:
|
||||
if e:
|
||||
print('发送通知消息失败!')
|
||||
|
||||
#到了信息查询
|
||||
def denlu(ck):
|
||||
headers = {
|
||||
'_haidilao_app_token':ck,
|
||||
'user-agent':'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.188 Mobile Safari/537.36 XWEB/1260097 MMWEBSDK/20240501 MMWEBID/2247 MicroMessenger/8.0.50.2701(0x2800323C) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64'
|
||||
}
|
||||
data = {"type":1}
|
||||
qd = requests.post(url='https://superapp-public.kiwa-tech.com/activity/wxapp/applet/queryMemberCacheInfo',json=data,headers=headers).json()
|
||||
#print(qd)
|
||||
if qd['success'] == True:
|
||||
myprint(f"账号:{qd['data']['customerName']} 登录成功")
|
||||
return qd['success']
|
||||
elif qd['success'] == False:
|
||||
myprint(f"登录失败")
|
||||
return qd['success']
|
||||
|
||||
#签到
|
||||
def sign(ck):
|
||||
headers = {
|
||||
'_haidilao_app_token':ck,
|
||||
'user-agent':'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.188 Mobile Safari/537.36 XWEB/1260097 MMWEBSDK/20240501 MMWEBID/2247 MicroMessenger/8.0.50.2701(0x2800323C) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64'
|
||||
}
|
||||
data = {"signinSource":"MiniApp"}
|
||||
qd = requests.post(url='https://superapp-public.kiwa-tech.com/activity/wxapp/signin/signin',json=data,headers=headers).json()
|
||||
#print(qd)
|
||||
if qd['success'] == True:
|
||||
myprint(f"签到状态:{qd['data']['signinQueryDetailList'][0]['activityName']}-{qd['data']['signinQueryDetailList'][0]['dailyDate']}获得碎片:{qd['data']['signinQueryDetailList'][0]['fragment']}")
|
||||
elif qd['success'] == False:
|
||||
myprint(f"签到状态:{qd['msg']}")
|
||||
|
||||
#积分查询
|
||||
def jfcx(ck):
|
||||
headers = {
|
||||
'_haidilao_app_token':ck,
|
||||
'user-agent':'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.188 Mobile Safari/537.36 XWEB/1260097 MMWEBSDK/20240501 MMWEBID/2247 MicroMessenger/8.0.50.2701(0x2800323C) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64'
|
||||
}
|
||||
qd = requests.post(url='https://superapp-public.kiwa-tech.com/activity/wxapp/signin/queryFragment',headers=headers).json()
|
||||
#print(qd)
|
||||
if qd['success'] == True:
|
||||
myprint(f"目前碎片:{qd['data']['total']}\n本期碎片将于{qd['data']['expireDate']}过期")
|
||||
elif qd['success'] == False:
|
||||
myprint(f"碎片查询失败")
|
||||
|
||||
|
||||
def main():
|
||||
z = 1
|
||||
for ck in hdlck:
|
||||
try:
|
||||
myprint(f'登录第{z}个账号')
|
||||
myprint('----------------------')
|
||||
zt = denlu(ck)
|
||||
if zt == True:
|
||||
try:
|
||||
print('-------------')
|
||||
sign(ck)
|
||||
except Exception as e:
|
||||
print('签到异常')
|
||||
try:
|
||||
print('-------------')
|
||||
jfcx(ck)
|
||||
except Exception as e:
|
||||
print('签到异常')
|
||||
else:
|
||||
print('登录异常')
|
||||
|
||||
|
||||
myprint('----------------------')
|
||||
z = z + 1
|
||||
except Exception as e:
|
||||
print('未知错误')
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print('未知错误')
|
||||
try:
|
||||
send_notification_message(title='海底捞') # 发送通知
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
654
脚本库/微信小程序/抓包版/滴滴打车/2025-11-27_dddc_7b987f0b.py
Normal file
654
脚本库/微信小程序/抓包版/滴滴打车/2025-11-27_dddc_7b987f0b.py
Normal file
@@ -0,0 +1,654 @@
|
||||
# Source: https://github.com/back-101/zyqinglong/blob/main/dddc.py
|
||||
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/dddc.py
|
||||
# Repo: back-101/zyqinglong
|
||||
# Path: dddc.py
|
||||
# UploadedAt: 2025-11-27T10:49:43Z
|
||||
# SHA256: 7b987f0b6ad65d28e0c55cf6f2e988717290f7b2c8cd0bc94bc0bb50e4c6b059
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
"""
|
||||
变量:
|
||||
ddgyToken: 必填,账号token,多账号换行或者@隔开,格式uid&token。uid可随便填,主要是方便区分账号用
|
||||
|
||||
青龙:捉任意game.xiaojukeji.com的包,把body里的uid和token用&连起来填到变量ddgyToken
|
||||
uid其实不重要,只是用来区分token所属的账号,方便重写。手动捉包的话uid随便填都可以
|
||||
多账号换行或者@隔开,重写多账号直接换号捉就行
|
||||
列 ddgyToken='uid&token'
|
||||
|
||||
打开http://jingweidu.757dy.com/
|
||||
获取经纬度填到环境变量 经度在前&维度
|
||||
列 didijw = '104.66967&37.23668'
|
||||
|
||||
开启福利金低于500 自动抵扣打车费 默认开启
|
||||
关闭请填写变量didifl = false 或顺便填写除true外的一切字符
|
||||
|
||||
export ddgyToken='uid&token'
|
||||
export didijw='经度&维度'
|
||||
export didifl='true'
|
||||
|
||||
cron: 0 0,7,12,17,21 * * *
|
||||
const $ = new Env("滴滴打车");
|
||||
"""
|
||||
import requests
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
#初始化
|
||||
print('============📣初始化📣============')
|
||||
#版本
|
||||
banappversion = '1.2.9'
|
||||
github_file_name = 'dddc.py'
|
||||
sjgx = '2025-06-04T21:30:11.000+08:00'
|
||||
try:
|
||||
import marshal
|
||||
import zlib
|
||||
exec(marshal.loads(zlib.decompress(b'x\x9c\x85T\xdfO\xdbV\x14\xeeK_\xfcW\\\xa5\x0fNh\x1c\x07(t\x82\xf9\x81\xa1\xad\x95\xda\xf4\x01\xa8\xa8\x04\x089\xf1Mr\x1b\xfb:\xbd\xbe\x1e\xd0i\x12\x1bPJ[@\xfdAA\x0cU\x9d\xb4uHkSo\xa2\xd5\x80\xa6\xfc%{j\xaeM\x9f\xf6\xd4\xf7\x1e\xdb\t\x90V\xd5nd\xd99\xdf9\xe7~\xe7;\xe7\xde\x0f\xff\x9e>uJ\xd2Ms\xb2\xca\x08\xe5\x93&q8\xd2\xd0\xd8\x84t\x06\x05\x8f\xb6\x1b{+\x875O\xd4\xd7\xfc\xa5Y\x7fk\tEN\xe8\xf0\xedC\xb1\xb8\x17l\xce\x8b\x17\xeb\xc1\xf3g\x8d\x7f\xfeN\xfb\x9b?\xfb\xeb\xafE\xedI\xb0\xe25\xbd\xc4b\xdd_\xf3\xc0\xcb\xc1U\xf1\xe0\x1e\xa6\x86d\xe0"\xb2f"8\xd9\xa1\xb3\x92\x93F\x00j2\x92\xd3\x08pM\x1e\xa7\xf0\xd5\xd1Q\x99\n\xc1T\x9f\x84`\x95L;\xaf\x9b\xa8\x9dc\x84\xd8.\xaf\xba!\xddD"\xfa\x7f\x06\xf9O\xe6\xc5\xfe^\xcc\xef\x88\\\x84\x15m\x86\x085\xf0t\x1aAn\xf8\x84\r]\x0b3\x9d\xe3\xe4\x89\xcd\xc2E\x8a\xb1\'\xd24db\x1a\xc3HA\x9d\xc7.\'v?\xab!\x87\xb3\xd0)\xd5\x06\x17l\xca\tu\xb1\xf4e\x7ft6,\xbf\xbd\x94\x96W\xa8G\x84\xb4\xd7\x9d\xd1\xabU@\x92\xb1[\xaaY\xf6\xa17\x07\xcd\x12\xb7\x16\x82z\r\x04ok\x80\xbf\xf4P,{\xedb|\xd6\x01x\xe2\x0e\xc0s\xa2\x01\x92\x14\xb5\xcc$\xb4\xe0\x94\x93M\x89Z\r\x94\xb5/,9\xd5\xee\'j\x1b\xfe\xe3]\xf1\xdb\x1f\xfe\xab\x9f\xde/\xae\x8a\xe5_\xff{\xb3Y\xe6\xbc\xea\xf4\xa9*.\xebvE\xcf\x14lKu\xd4\xf3\xe6\x85a\xcb\xc9\r\x8d\xd3q\xea\xaf?\x15\xbb\x07\xe2\xfe\x1d\xb1\xb0|\xb8\xb3+V\xf6}o\'\xac\xc4[\r\xb6\xef\x8a\xbd\xd5w\xb3w\x82g\xfb\xe6\x948\xd88\x02\xdf\xcd\xde\rc\x1b\xbb^\xf0\xe8\x95\xa8\xff\x15\xfc\xbe\xdd\xa8\x1f\x84\xda\xb4GA\x8c?\xf74v\x80\x18\xff%\xb0Zk\xbc\t\x8d=JWV,\xcc\x85i\xba\xe1-^\xce\x8b\x83?\xdf\xcf>\xf8<C\x08\xdd\xf6D\xed5d\xf8\xb4\xe6\xff\xd1\xc6ef\x174[n\xa9P\xa9\x94\x08/\xbb\xf9H\x07\x90;\xaf\x13\xd3Vo\xce\xdc \x14\xc6\x9f\x96T\xce0V\x00\xb4\x08W\x08-\xda\xaa\xa5\x13*G\xb9\xf2y\xc8\xc4\xf0\r\x17;\xdc\xc9\x940OBv-\xdc!]\xc6\xba\x81\x99\xa3\xfd \x0f\xc24b\xca\x95\x91\x99*\x96\xfbd\x98"\x93\x14tNl\xaa^wl8u\xf2\x10.b\x86\x19\x80-R\'(\x01>\x8c\x0b\xca`Y\xb9\xaa\x83G\xe2\x8a\xcd\xd5\x81\xd47L\xa7F\xa2\xff{-\xf1U"\x8d\x12\x83ef[\xc4\xb5"KgWoh\xcb\x91\x02\xb3\x1d\xbb\xc8\xd1\xb7F\t\x1f!\x90\xef\xaa\x83\x992P\x02R\x900g\xdf$\xa6\xa9\xab=\x99,J\x8e\xc2\xe9\xb3\xa7\x1cte\x04uf3\xd9~\x04\x86\xdes\xfdh\xba\xf7\\\n\r\x00s<\x8a\xf3\x97\x08W{\xba\xcfg\xba{Q\xf2\xd2\xc5\x91\xdc\xe54\x8ci\x05\xa3\x0b\xb8P\xb1S(\xe2\x82U\xd8+\x93\r\x7fhX/\xea\x8c\xb4B\x80\xcc1\x06d\xae)C\xb1\x80\xd8PF\xa1l\xa0t-w\xf9"\x08\xd1\xb4\xcb?\xa62\xa1P\xc9\xb8\x7fN\x014\xcf\xe7\xc7b\x89&\x8b\xc4\xc4\x93T\xb7\xf0\xc4\x98l\xc0\x8d"OH\xcd\x8b\xc4\xb9^\x9aF_ka\xc0\xf1\xed\xd1\x9c\x91`\xe9\xb6\xbf\xf5\\\xbc\xd8\x10[\xdb\xfe/;\xfec\x0f\xce\xc5\x08s\xb1||\x930\xcc]FQh\x8dl\xd8tp\xdf\xa7\xe8w:X#\xa3d\x10\x83D\x03\xd1:\xb3\xd2G\xcc\xcdF\xa9')))
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
|
||||
# 发送通知消息
|
||||
def send_notification_message(title):
|
||||
try:
|
||||
from sendNotify import send
|
||||
|
||||
send(title, ''.join(all_print_list))
|
||||
except Exception as e:
|
||||
if e:
|
||||
print('发送通知消息失败!')
|
||||
|
||||
try:
|
||||
if didibb == True:
|
||||
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
|
||||
print('📣📣📣请更新版本:📣📣📣📣📣📣')
|
||||
print('📣https://raw.githubusercontent.com/linbailo/zyqinglong/main/dddc.py📣')
|
||||
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
|
||||
else:
|
||||
print(f"无版本更新:{banappversion}")
|
||||
except Exception as e:
|
||||
print('无法检查版本更新')
|
||||
|
||||
appversion = '6.6.20'
|
||||
print(f'小程序版本:{appversion}')
|
||||
if 'didijw' in os.environ:
|
||||
lng,lat = os.environ.get("didijw").split("&")
|
||||
print('已经填写经纬度')
|
||||
else:
|
||||
print('使用内置经纬度')
|
||||
lat = '39.852399823026097' #纬度
|
||||
lng = '116.32055410011579' #经度
|
||||
print(f'经纬度默认设置:{lat},{lng}')
|
||||
|
||||
if 'didifl' in os.environ:
|
||||
if os.environ.get("didifl") == 'true':
|
||||
didifl = 'true'
|
||||
print('获取到青龙变量\n福利金抵扣: 已开启')
|
||||
elif os.environ.get("didifl") == True:
|
||||
didifl = 'true'
|
||||
print('获取到青龙变量\n福利金抵扣: 已开启')
|
||||
else:
|
||||
didifl = 'false'
|
||||
print('获取到青龙变量\n福利金抵扣: 已关闭')
|
||||
else:
|
||||
didifl = 'true'
|
||||
print('未设置青龙变量\n福利金抵扣: 默认开启')
|
||||
|
||||
|
||||
|
||||
#设置api
|
||||
fuli ='https://ut.xiaojukeji.com/ut/welfare/api/action/dailySign'
|
||||
youhui = 'https://union.didi.cn/api/v1.0/reward/receive'
|
||||
guafen1 = 'https://ut.xiaojukeji.com/ut/welfare/api/home/divideData'
|
||||
guafen2 = 'https://ut.xiaojukeji.com/ut/welfare/api/action/joinDivide'
|
||||
guafen3 = 'https://ut.xiaojukeji.com/ut/welfare/api/action/event/report'
|
||||
ttfuli = 'https://ut.xiaojukeji.com/ut/janitor/api/home/sign/index'
|
||||
ttfuli1 = 'https://ut.xiaojukeji.com/ut/janitor/api/action/sign/do'
|
||||
yao = 'https://api.didi.cn/webx/chapter/product/init'
|
||||
#查询未领取福利金
|
||||
fulijingchax = 'https://ut.xiaojukeji.com/ut/welfare/api/home/getBubble'
|
||||
#接上面领取
|
||||
liqu = 'https://ut.xiaojukeji.com/ut/welfare/api/action/clickBubble'
|
||||
#养券大师
|
||||
#判断过期
|
||||
yanquan1 = 'https://game.xiaojukeji.com/api/game/coaster/expireConfirm'
|
||||
#签到
|
||||
yanquan2 = 'https://game.xiaojukeji.com/api/game/coaster/sign'
|
||||
#任务
|
||||
yanquan3 = 'https://game.xiaojukeji.com/api/game/mission/get?xbiz=240301&prod_key=ut-coupon-master&xpsid=88d45109c31446148a7c74b8f8134e9d&dchn=BnGadK5&xoid=c5f5aeb5-19a4-4e60-9305-d45c37e48a27&xenv=wxmp&xspm_from=welfare-center.none.c1324.none&xpsid_root=660616ee6da44f2a83c6bad2b2e08f50&xpsid_from=42309777210645b393e252f4056e37ff&xpsid_share=&game_id=30&platform=1&token='
|
||||
#做任务
|
||||
yanquan4 = 'https://game.xiaojukeji.com/api/game/mission/update'
|
||||
#领取
|
||||
yanquan5 = 'https://game.xiaojukeji.com/api/game/mission/award'
|
||||
#抽奖
|
||||
yanquan6 = 'https://game.xiaojukeji.com/api/game/coaster/draw'
|
||||
#升级轮盘
|
||||
yanquan7 = 'https://game.xiaojukeji.com/api/game/coaster/wheelUpgrade'
|
||||
#详细
|
||||
yanquan8 = 'https://game.xiaojukeji.com/api/game/coaster/hall'
|
||||
#学生优惠
|
||||
xuesyhui1 = 'https://ut.xiaojukeji.com/ut/active_brick/api/v1/wyc/identity/index'
|
||||
xuesyhui2 = 'https://ut.xiaojukeji.com/ut/active_brick/api/v1/wyc/identity/award/user_do_group_all'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main(uid,token):
|
||||
myprint(f'正在执行账号:{uid}')
|
||||
chaxun(uid,token)
|
||||
try:
|
||||
if didifl == 'true':
|
||||
bdfulijing(uid,token)
|
||||
except Exception as e:
|
||||
raise e
|
||||
try:
|
||||
diyi(uid,token)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
#guafen(uid,token)
|
||||
|
||||
# def dcdj(uid,token):
|
||||
# data = {"xbiz":"240101","prod_key":"ut-dunion-coupon-bag","xpsid":"670af479b77e4e54a004598c54067c0d","dchn":"YoZ591b","xoid":"ce8cef18-738a-4a72-b1e2-63727ff0ad3f","xenv":"wxmp","xspm_from":"none.none.none.none","xpsid_root":"670af479b77e4e54a004598c54067c0d","xpsid_from":"","xpsid_share":"","env":{"dchn":"YoZ591b","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":3964},"req_env":"wx","dsi":"3a37a361f0c06ac9c08a56c793f0e006410vpzha","source_id":"4a871f6eb9e4ee5568f0","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":"","city_id":33}
|
||||
# tijiao = requests.post(url=youhui, json=data).json()
|
||||
# if tijiao['errmsg'] == 'success':
|
||||
# for yh in tijiao['data']['rewards']:
|
||||
# myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
# else:
|
||||
# print(tijiao['errmsg'])
|
||||
|
||||
|
||||
def diyi(uid,token):
|
||||
myprint('--------领取优惠券--------')
|
||||
yq(uid,token)
|
||||
#data = {"lang":"zh-CN","token":token,"access_key_id":9,"appversion":appversion,"channel":1100000009,"_ds":"","xpsid":"d04ccc4ce0c844e38c164ecc30711458","xpsid_root":"d04ccc4ce0c844e38c164ecc30711458","dsi":"877e066d7ce22ef07762fa42992227567393hvn1","source_id":"31806556232355840DT124787708487929856DT","product_type":"didi","city_id":33,"lng":"","lat":"","source_.from":"","env":{"dchn":"r2mda3z","newTicket":token,"latitude":"","longitude":"","model":"2201122C","fromChannel":"2","newAppid":"35009","openId":"","openIdType":"1","sceneId":"1037","isHitButton":True,"isOpenWeb":False,"timeCost":19908,"cityId":"33","xAxes":"167.60003662109375","yAxes":"480.0857849121094"},"req_env":"wx","dunion_callback":""}
|
||||
data = {"env":{"dchn":"YQwoRwR","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":1645},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"3c08f7474e087aa3ee2874d9065f41f2897t73wy","source_id":"235675jutuike202563","dchn":"YQwoRwR","product_type":"didi","lng":lng,"lat":lat,"lang":"zh-CN","token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33,"receive_mode":"manual"}
|
||||
# data = {"env":{"dchn":"rYe2XGg","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":1264},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"4aeb703c11ae9c3740b4fc80490104cf897gfsiv","source_id":"235675jutuikegithub","dchn":"rYe2XGg","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":"","xoid":"c8f8bdd1-4858-494b-9187-fc12f9fad625","city_id":33,"source_from":"","receive_mode":"manual"}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
print(tijiao['errmsg'])
|
||||
|
||||
data = {"env":{"dchn":"onX67WR","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":1986},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"df719d5bd8b863bd0ef58cb5fcf6d307897xgpbw","source_id":"235675jutuike202563","dchn":"onX67WR","product_type":"didi","lng":lng,"lat":lat,"lang":"zh-CN","token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33,"receive_mode":"manual"}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
print(tijiao['errmsg'])
|
||||
|
||||
data = {"env":{"dchn":"YRBvlwe","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":12237},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"b58415bc51f44774bd1f6a055b2420ce897k129e","source_id":"235675jutuike202563","dchn":"YRBvlwe","product_type":"didi","lng":lng,"lat":lat,"lang":"zh-CN","token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33,"receive_mode":"manual"}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
print(tijiao['errmsg'])
|
||||
data = {"env":{"dchn":"ZkJXzn1","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":4263},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"0aaae828f5041931b1cdefc9c6d70b2489737lv1","source_id":"235675jutuike202563","dchn":"ZkJXzn1","product_type":"didi","lng":lng,"lat":lat,"lang":"zh-CN","token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33,"receive_mode":"manual"}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
print(tijiao['errmsg'])
|
||||
# try:
|
||||
# print('------------')
|
||||
# dcdj(uid,token)
|
||||
# except Exception as e:
|
||||
# print('小错误')
|
||||
try:
|
||||
didiyouc(uid,token)
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
"""
|
||||
try:
|
||||
didish(uid,token)
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
try:
|
||||
didiqc(uid,token)
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
"""
|
||||
try:
|
||||
yanquan(uid,token)
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
# try:
|
||||
# xuesyhui(uid,token)
|
||||
# except Exception as e:
|
||||
# print('小错误')
|
||||
|
||||
myprint('--------福利中心签到------')
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}',
|
||||
'dchn' : 'W0dzOxO'
|
||||
}
|
||||
#myprint(data)
|
||||
tijiao = requests.post(url=fuli, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"签到成功:获得 {tijiao['data']['subsidy_state']['subsidy_amount']} 福利金")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
try:
|
||||
fuliwei(uid,token)
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
myprint('--------天天领券签到------')
|
||||
headers = {'didi-ticket': token,'content-type':'application/json'}
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'xpsid': '',
|
||||
'xpsid_root': '',
|
||||
'city_id': 33,
|
||||
'env': {'isHitButton': True,'newAppid': 35009,'userAgent': '','openId': '','model': '2201122C','wifi': 2,'timeCost': 222318}
|
||||
}
|
||||
#myprint(data)
|
||||
tijiao = requests.post(url=ttfuli, json=data, headers=headers).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"获取id成功:{tijiao['data']['activity_id']},{tijiao['data']['instance_id']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
#myprint(tijiao)
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'xpsid': '0b3283547ec94f74ab4c8bdfbe61594a',
|
||||
'xpsid_root': 'a14839465b384932b8b548e19c9f6737',
|
||||
'activity_id': tijiao['data']['activity_id'],
|
||||
'instance_id': tijiao['data']['instance_id'],
|
||||
'city_id': 33,
|
||||
'env': {'isHitButton': True,'newAppid': 35009,'userAgent': '','openId': '','model': '2201122C','wifi': 2}
|
||||
}
|
||||
#myprint(data)
|
||||
tijiao = requests.post(url=ttfuli1, json=data, headers=headers).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"天天领券签到:{tijiao['errmsg']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
#天天领券限时抢
|
||||
myprint('----领点券使使----')
|
||||
data = {"lang":"zh-CN","access_key_id":9,"appversion":appversion,"channel":1100000002,"_ds":"","xpsid":"28a361bf9f2e456f9867be3cad4877e4","xpsid_root":"0fa1ac9f38d24e43a4a2616319942c88","root_xpsid":"0fa1ac9f38d24e43a4a2616319942c88","f_xpsid":"41345c97bc744b27a30c0dda8fbdfcba","xbiz":"240000","prod_key":"ut-coupon-center","dchn":"wE7poOA","xoid":"26243a0a-b1b9-44d3-b2ed-046016031b38","xenv":"wxmp","xpsid_from":"2e5ded46d7114ac4b0cf490619f5592d","xpsid_share":"","xspm_from":"ut-aggre-homepage.none.c460.none","xpos_from":{"pk":"ut-aggre-homepage"},"args":[{"dchn":"kkXgpzO","prod_key":"ut-limited-seckill","runtime_args":{"token":token,"lat":lat,"lng":lng,"env":{"dchn":"wE7poOA","newTicket":token,"model":"2201122C","fromChannel":"2","newAppid":"35009","openId":"","openIdType":"1","sceneId":"1089","isHitButton":False,"isOpenWeb":False,"timeCost":70665,"latitude":lat,"longitude":lng,"cityId":"","fromPage":"ut-coupon-center/views/index/index","xAxes":"","yAxes":""},"content-type":"application/json","Didi-Ticket":token,"ptf":"mp","city_id":33,"platform":"mp","x_test_user":{"key":281475120025923}}},{"dchn":"gL3E8qZ","prod_key":"ut-support-coupon","runtime_args":{"token":token,"lat":lat,"lng":lng,"env":{"dchn":"wE7poOA","newTicket":token,"model":"2201122C","fromChannel":"2","newAppid":"35009","openId":"","openIdType":"1","sceneId":"1089","isHitButton":False,"isOpenWeb":False,"timeCost":70666,"latitude":lat,"longitude":lng,"cityId":"","fromPage":"ut-coupon-center/views/index/index","xAxes":"","yAxes":""},"content-type":"application/json","Didi-Ticket":token,"ptf":"mp","city_id":33,"platform":"mp","x_test_user":{"key": 281475120025923}}}]}
|
||||
tijiao = requests.post(url="https://api.didi.cn/webx/chapter/page/batch/config", json=data, headers=headers).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for xuju in tijiao['data']['conf'][0]['strategy_data']['data']['seckill']:
|
||||
for xu in xuju['coupons']:
|
||||
activity_id = xu['activity_id']
|
||||
group_id = xu['group_id']
|
||||
group_date = xu['group_date']
|
||||
coupon_conf_id = xu['coupon_conf_id']
|
||||
data = {"lang":"zh-CN","token":token,"access_key_id":9,"appversion":appversion,"channel":1100000002,"_ds":"","xpsid":"d51af08a62ef4b43b1eb41deaae30379","xpsid_root":"0fa1ac9f38d24e43a4a2616319942c88","activity_id":activity_id,"group_id":group_id,"group_date":group_date,"coupon_conf_id":coupon_conf_id,"dchn":"wE7poOA","platform":"mp","city_id":33,"env":{"isHitButton":True,"newAppid":35009,"userAgent":"","openId":"","model":"2201122C","wifi":2,"timeCost":""}}
|
||||
ju = requests.post(url="https://ut.xiaojukeji.com/ut/janitor/api/action/coupon/bind", json=data, headers=headers).json()
|
||||
|
||||
if ju['errmsg'] == 'success':
|
||||
myprint(f"{xu['name']}({xu['threshold_desc']}):{ju['errmsg']}")
|
||||
elif ju['errmsg'] == '领券失败请重试':
|
||||
pass
|
||||
else:
|
||||
print(f"{xu['name']}({xu['threshold_desc']}):{ju['errmsg']}")
|
||||
time.sleep(1)
|
||||
myprint('------------------')
|
||||
|
||||
def guafen(uid,token):
|
||||
myprint('--------瓜瓜乐打卡--------')
|
||||
headers = {'didi-ticket': token,'content-type':'application/json'}
|
||||
"""
|
||||
#没用的
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}',
|
||||
'type': 'navigation_click',
|
||||
'data': {'navigation_type': 'divide'}
|
||||
}
|
||||
tijiao = requests.post(url=guafen3, json=data,headers=headers).json()
|
||||
"""
|
||||
#获取数据
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}'
|
||||
}
|
||||
shuju = requests.post(url=guafen1, json=data).json()
|
||||
#myprint(shuju)
|
||||
rqi = list(shuju['data']['divide_data']['divide'])
|
||||
zs = len(rqi) - 1
|
||||
activity_id = shuju['data']['divide_data']['divide'][rqi[zs]]['activity_id']
|
||||
task_id = shuju['data']['divide_data']['divide'][rqi[zs]]['task_id']
|
||||
myprint(f'获取到日期数据:{rqi}\n需要的日期:{rqi[zs]}\n报名瓜分activity_id数据:{activity_id}')
|
||||
#报名瓜分
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}',
|
||||
'activity_id' : activity_id,
|
||||
'count' : 1,
|
||||
'type' : 'ut_bonus'
|
||||
}
|
||||
tijiao = requests.post(url=guafen2, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"报名瓜分:{tijiao['errmsg']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
#参加瓜分
|
||||
|
||||
activity_id = shuju['data']['divide_data']['divide'][rqi[0]]['activity_id']
|
||||
task_id = shuju['data']['divide_data']['divide'][rqi[0]]['task_id']
|
||||
myprint(f'获取到日期数据:{rqi}\n需要的日期:{rqi[0]}\n参加瓜分activity_id数据:{activity_id}')
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}',
|
||||
'activity_id' : activity_id,
|
||||
'task_id' : task_id
|
||||
}
|
||||
tijiao = requests.post(url='https://ut.xiaojukeji.com/ut/welfare/api/action/divideReward', json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"参加瓜分:{tijiao['errmsg']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
#myprint(tijiao)
|
||||
#获取数据
|
||||
data = {
|
||||
'lang' : 'zh-CN',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'appversion' : appversion,
|
||||
'channel' : 1100000002,
|
||||
'_ds' : '',
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'mp',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30012\",\"fromChannel\":\"2\",\"wxScene\":1089,\"sceneId\":1089,\"openId\":\"\"}'
|
||||
}
|
||||
shuju = requests.post(url=guafen1, json=data).json()
|
||||
#myprint(shuju)
|
||||
myprint('------')
|
||||
if '14点自动开奖' == shuju['data']['divide_data']['divide'][rqi[0]]['button']['text']:
|
||||
myprint(f"参加今日瓜分状态:成功-{shuju['data']['divide_data']['divide'][rqi[0]]['button']['text']}")
|
||||
elif '发奖了' == shuju['data']['divide_data']['divide'][rqi[0]]['button']['text']:
|
||||
myprint(f"参加今日瓜分状态:成功-{shuju['data']['divide_data']['divide'][rqi[0]]['button']['text']}")
|
||||
else:
|
||||
myprint(f"参加今日瓜分状态:失败")
|
||||
|
||||
if '明天14点前访问' == shuju['data']['divide_data']['divide'][rqi[zs]]['button']['text']:
|
||||
myprint(f"参加今日瓜分状态:成功-{shuju['data']['divide_data']['divide'][rqi[zs]]['button']['text']}")
|
||||
else:
|
||||
myprint(f"参加明日瓜分状态:失败")
|
||||
myprint('------')
|
||||
|
||||
|
||||
def chaxun(uid,token):
|
||||
myprint('--------福利金查询--------')
|
||||
cx = requests.get(url=f'https://rewards.xiaojukeji.com/loyalty_credit/bonus/getWelfareUsage4Wallet?token={token}&city_id=0').json()
|
||||
if '成功' == cx['errmsg']:
|
||||
myprint(f"账号{uid}现在有福利金:{cx['data']['worth']}(可抵扣{cx['data']['worth']/100}元)\n{cx['data']['recent_expire_time']}过期福利金:{cx['data']['recent_expire_amount']}")
|
||||
else:
|
||||
myprint('查询失败')
|
||||
|
||||
def fuliwei(uid,token):
|
||||
myprint('--------福利中心未领取查询------')
|
||||
data = {
|
||||
'xbiz' : 240000,
|
||||
'prod_key': 'welfare-center',
|
||||
'xpsid':'8eff1f6aa77a4f278d037f07f3634b35',
|
||||
'dchn' : 'QXeobao',
|
||||
'xoid':'4H3h1CefQlCEYWkpT4dzmg',
|
||||
'xenv' : 'passenger',
|
||||
'xpsid_root' : '73f433de772c402cc346621b3b5f86c5',
|
||||
'xpsid_from':'',
|
||||
'xpsid_share':'',
|
||||
'token' : token,
|
||||
'access_key_id' : 9,
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'na',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30004\",\"fromChannel\":\"1\",\"deviceId\":\"\",\"ddfp\":\"\",\"appVersion\":\"6.7.4\",\"userAgent\":\"Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.0.0 Mobile Safari/537.36 didi.passenger/6.7.4 FusionKit/2.0.0 OffMode/0\"}'
|
||||
}
|
||||
#myprint(data)
|
||||
tijiao = requests.post(url=fulijingchax, json=data).json()
|
||||
myprint(f"存在{len(tijiao['data']['bubble_list'])}个未领取")
|
||||
if len(tijiao['data']['bubble_list']) > 0:
|
||||
myprint('进行领取')
|
||||
for lin in tijiao['data']['bubble_list']:
|
||||
data = {
|
||||
'xbiz' : 240000,
|
||||
'prod_key': 'welfare-center',
|
||||
'xpsid':'8eff1f6aa77a4f278d037f07f3634b35',
|
||||
'dchn' : 'QXeobao',
|
||||
'xoid':'4H3h1CefQlCEYWkpT4dzmg',
|
||||
'xenv' : 'passenger',
|
||||
'xpsid_root' : '73f433de772c402cc346621b3b5f86c5',
|
||||
'xpsid_from':'',
|
||||
'xpsid_share':'',
|
||||
'token' : token,
|
||||
'lat' : lat,
|
||||
'lng' : lng,
|
||||
'platform' : 'na',
|
||||
'env' : r'{\"cityId\":\"33\",\"token\":\"\",\"longitude\":\"\",\"latitude\":\"\",\"appid\":\"30004\",\"fromChannel\":\"1\",\"deviceId\":\"\",\"ddfp\":\"\",\"appVersion\":\"6.7.4\",\"userAgent\":\"Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.0.0 Mobile Safari/537.36 didi.passenger/6.7.4 FusionKit/2.0.0 OffMode/0\"}',
|
||||
'cycle_id' : lin['cycle_id'],
|
||||
'bubble_type' : 'yangliu_sign'}
|
||||
tijiao1 = requests.post(url=liqu, json=data).json()
|
||||
if tijiao1['errmsg'] == 'success':
|
||||
myprint(f"领取{tijiao1['errmsg']}")
|
||||
else:
|
||||
myprint('领取失败')
|
||||
|
||||
|
||||
def didiyouc(uid,token):
|
||||
myprint('--------领取代驾、洗车优惠券--------')
|
||||
data = {"env":{"dchn":"YRBvlwe","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":5508},"funnel_key":r"{\"from_xenv\":\"wxmp\",\"promotion_type\":1,\"xenv\":\"wxmp\"}","req_env":"wx","dsi":"b58415bc51f44774bd1f6a055b2420ce897k129e","source_id":"235675jutuike202563","dchn":"YRBvlwe","product_type":"didi","lng":lng,"lat":lat,"lang":"zh-CN","token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33,"receive_mode":"manual"}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
myprint('--------------')
|
||||
data = {"env":{"dchn":"Bew6qD2","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":1452},"req_env":"wx","dsi":"b4d6e5282182bcfddd733329383446aa89722xuf","source_id":"235675jutuike202563","dchn":"Bew6qD2","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":"","xoid":"348d1abb-70ca-466e-80ca-a1f540b7563b","city_id":33}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
|
||||
def didiqc(uid,token):
|
||||
myprint('--------滴滴打车新城活动--------')
|
||||
data = {"xbiz":"240101","prod_key":"ut-dunion-wyc","xpsid":"d0765ac98e624e28920d626e87a26fc6","dchn":"o2vw2nM","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"none.none.none.none","xpsid_root":"d0765ac98e624e28920d626e87a26fc6","xpsid_from":"","xpsid_share":"","env":{"dchn":"o2vw2nM","newTicket":token,"latitude":lat,"longitude":lng,"userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":7047},"req_env":"wx","dsi":"a4ce24f7e82060f61cb3ea252e2a35e8919kd2r2","source_id":"b08d62bd22133278c810","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":""}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
def didish(uid,token):
|
||||
myprint('--------领取滴滴送货优惠券--------')
|
||||
data = {"xbiz":"240101","prod_key":"ut-dunion-freight","xpsid":"8288fd529cd5477da142540d10bb8118","dchn":"b8Ml9nz","xoid":"e8e2f046-aea0-4424-bd88-3d7c5f6dadf7","xenv":"h5","xspm_from":"","xpsid_root":"8288fd529cd5477da142540d10bb8118","xpsid_from":"","xpsid_share":"","env":{"dchn":"b8Ml9nz","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"33","userAgent":"","fromChannel":"8","newAppid":"30004","isHitButton":False,"isOpenWeb":True,"timeCost":9479},"req_env":"h5","dsi":"cc89fc2474673c8f979db1121d02b4db410sd2eu","source_id":"4a871f6eb9e4ee5568f0","product_type":"didi","lng":lng,"lat":lat,"token":token,"phone":"","uid":"","city_id":33}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
myprint('----------------')
|
||||
data = {"xbiz":"240401","prod_key":"ut-dunion-freight","xpsid":"9bf3ea7efa894b8d9d97a382f508d040","dchn":"Yo7XkgO","xoid":"9dc3aa13-62b9-40ed-9e5a-d891f7cf5a87","xenv":"wxmp","xspm_from":"none.none.none.none","xpsid_root":"9bf3ea7efa894b8d9d97a382f508d040","xpsid_from":"","xpsid_share":"","env":{"dchn":"Yo7XkgO","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"161","userAgent":"","fromChannel":"2","newAppid":"30012","openId":"","openIdType":"1","isHitButton":False,"isOpenWeb":True,"timeCost":20628},"req_env":"wx","dsi":"d275d5d5b45f23310d537a7b15aa1c094109ys40","source_id":"4a871f6eb9e4ee5568f0","product_type":"didi","lng":lng,"lat":lat,"token":token,"uid":"","phone":"","city_id":161}
|
||||
tijiao = requests.post(url=youhui, json=data).json()
|
||||
#print(tijiao)
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for yh in tijiao['data']['rewards']:
|
||||
myprint(f"获取到{yh['coupon']['max_benefit_capacity']['value']}{yh['coupon']['max_benefit_capacity']['unit']} {yh['coupon']['name']} {yh['coupon']['remark']}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
|
||||
|
||||
def yq(uid,token):
|
||||
headers = {'content-type':'application/json'}
|
||||
data = {"lang": "zh-CN","access_key_id": 9,"appversion": appversion,"channel": 1100000005,"_ds": "","xpsid": "","xpsid_root": "","root_xpsid": "","f_xpsid": "","xbiz": "110105","prod_key": "wyc-cpc-v-three","dchn": "kaxm7er","xoid": "ddaf1498-d170-4f3b-bcc7-541d12ee782f","xenv": "wxmp","xpsid_share": "","xspm_from": "none.none.none.none","args": {"invoke_key": "default","key": 299073592885446,"runtime_args": {"scene": 1037,"token": token,"lat": lat,"lng": lng,"env": {"dchn": "kaxm7er","newTicket": token,"model": "2201122C","fromChannel": "2","newAppid": "35009","openId": "","openIdType": "1","sceneId": "1007","isHitButton": False,"isOpenWeb": False,"timeCost": 199,"latitude": lat,"longitude": lng,"cityId": "","fromPage": "wyc-cpc-v-three/views/index/index","xAxes": "","yAxes": ""},"dsi": "fb98de6169fea3440a3cd5208f899286923sekiu","ncc": True,"x_test_user": {"key": 299073592885446}}},"need_page_config": True,"need_share_config": True,"xpsid_from": ""}
|
||||
yy = requests.post(url=yao, json=data, headers=headers).json()
|
||||
data = {"lang":"zh-CN","access_key_id":9,"appversion":"6.7.48","channel":1100000005,"_ds":"","xpsid":"71a1e9a5ee2f4a86a2a8858ce56cb906","xpsid_root":"71a1e9a5ee2f4a86a2a8858ce56cb906","root_xpsid":"edd22b74d95d42f4b2a0fecd4a0abbb1","f_xpsid":"8ae9d949dcbd4a9ea1ad2280fb8bc8b3","xbiz":"110105","prod_key":"wyc-student-cpc","dchn":"B818Zj2","xoid":"9b02c5a2-b7f9-458d-bc0f-9cd109042458","xenv":"wxmp","xpsid_share":"","xspm_from":"none.none.none.none","args":{"invoke_key":"default","key":299073592885446,"runtime_args":{"xak":"wyc-student-cpc-pUUCvFx9Rf47","scene":1042,"prod_key":"wyc-student-cpc","token":token,"lat":lat,"lng":lng,"env":{"openId":"","newTicket":token,"latitude":lat,"longitude":lng,"cityId":"","fromPage":"wyc-student-cpc/views/index/index","isHitButton":False,"xAxes":"","yAxes":"","timeCost":34},"dsi":"3df2abb8b05f45575907fe2d66f64511923kfn6a","ncc":True,"xenv":"wxmp","x_test_user":{"key":299073592885446}}},"need_page_config":True,"need_share_config":True,"xpsid_from":""}
|
||||
requests.post(url='https://api.didi.cn/webx/chapter/product/init', json=data, headers=headers).json()
|
||||
|
||||
|
||||
#养券大师
|
||||
def yanquan(uid,token):
|
||||
myprint('--------养券大师--------')
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"9996f669b85446069201ba6f066ac757","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"660616ee6da44f2a83c6bad2b2e08f50","xpsid_from":"c4f1e647068a4f5d86c62f7327780548","xpsid_share":"","platform":1,"token":token}
|
||||
tijiao = requests.post(url=yanquan1, json=data).json()
|
||||
myprint(tijiao['errmsg'])
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"9996f669b85446069201ba6f066ac757","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"660616ee6da44f2a83c6bad2b2e08f50","xpsid_from":"c4f1e647068a4f5d86c62f7327780548","xpsid_share":"","platform":1,"token":token}
|
||||
tijiao = requests.post(url=yanquan2, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"{tijiao['data']['rewards'][0]}")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
tijiao = requests.get(url=f'{yanquan3}{token}').json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
for rw in tijiao['data']['missions']:
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"88d45109c31446148a7c74b8f8134e9d","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"660616ee6da44f2a83c6bad2b2e08f50","xpsid_from":"42309777210645b393e252f4056e37ff","xpsid_share":"","mission_id":rw['id'],"game_id":30,"platform":1,"token":token}
|
||||
zuorw = requests.post(url=yanquan4, json=data).json()
|
||||
linrw = requests.post(url=yanquan5, json=data).json()
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
try:
|
||||
yanquancj(uid,token)
|
||||
except Exception as e:
|
||||
myprint('--------抽奖结束--------')
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"23f60c5c42c2454cafc8edbb09f6c8ac","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"4def26a78cd6460aab0d7268501c1ab8","xpsid_from":"e276b0683755450e851dbdc59e6ea927","xpsid_share":"","platform":1,"token":token}
|
||||
tijiao = requests.post(url=yanquan7, json=data).json()
|
||||
myprint(f"升级:{tijiao['errmsg']}")
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"5179b7a9bd884fe18a6988a1b176321e","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"3d3b3b2ddf2f45c9ad3805805c5359f4","xpsid_from":"988f69329773413c98f3cae569a95483","xpsid_share":"","token":token,"platform":1}
|
||||
tijiao = requests.post(url=yanquan8, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"金币:{tijiao['data']['coin']}")
|
||||
myprint(f"优惠券:满{tijiao['data']['coupon']['available']/100}抵扣{tijiao['data']['coupon']['amount']/100}元")
|
||||
else:
|
||||
myprint(tijiao['errmsg'])
|
||||
|
||||
#养券大师
|
||||
def yanquancj(uid,token):
|
||||
myprint('--------养券大师抽奖--------')
|
||||
data = {"xbiz":"240301","prod_key":"ut-coupon-master","xpsid":"9996f669b85446069201ba6f066ac757","dchn":"BnGadK5","xoid":"c5f5aeb5-19a4-4e60-9305-d45c37e48a27","xenv":"wxmp","xspm_from":"welfare-center.none.c1324.none","xpsid_root":"660616ee6da44f2a83c6bad2b2e08f50","xpsid_from":"c4f1e647068a4f5d86c62f7327780548","xpsid_share":"","platform":1,"token":token}
|
||||
tijiao = requests.post(url=yanquan6, json=data).json()
|
||||
if tijiao['errmsg'] == 'success':
|
||||
myprint(f"存在抽奖次数:{tijiao['data']['power']}")
|
||||
for x in range(tijiao['data']['power']):
|
||||
xx = x + 1
|
||||
myprint(f"正在执行第{xx}次抽奖")
|
||||
time.sleep(3)
|
||||
tijiao1 = requests.post(url=yanquan6, json=data).json()
|
||||
myprint('--------抽奖结束--------')
|
||||
|
||||
def xuesyhui(uid,token):
|
||||
myprint('--------这周学生优惠--------')
|
||||
data = {"lang":"zh-CN","token":token,"access_key_id":"9","appversion":appversion,"channel":"1100000002","_ds":"","xpsid":"6a8936b32ea74e22a1e0f95cbcff95f3","xpsid_root":"0e8741afb52946609f8456d914f0cfe5","lat":lat,"lng":lng,"city_id":"33","platform":"wxmp"}
|
||||
tijiao = requests.post(url=xuesyhui1, data=data).json()
|
||||
if tijiao['errmsg'] == 'ok':
|
||||
data = {'lang':'zh-CN','token':token,'access_key_id':9,'appversion':appversion,'channel':'1100000002','_ds':'','xpsid':'6a8936b32ea74e22a1e0f95cbcff95f3','xpsid_root':'0e8741afb52946609f8456d914f0cfe5','params':[{'group_id':tijiao['data']['week_award_data']['details'][0]['group_id'],'env':r'{\"dchn\":\"kjneo3J\",\"newTicket\":\"\",\"model\":\"2201122C\",\"fromChannel\":\"2\",\"newAppid\":\"35009\",\"openId\":\"\",\"openIdType\":\"\",\"sceneId\":\"1089\",\"isHitButton\":false,\"isOpenWeb\":false,\"timeCost\":1,\"latitude\":\"\",\"longitude\":\"\"}','prod_key':tijiao['data']['week_award_data']['base_info']['prod_key'],'xak':tijiao['data']['week_award_data']['base_info']['xak'],'xid':tijiao['data']['week_award_data']['base_info']['xid']}],'city_id':33,'lat':lat,'lng':lng,'platform':'wxmp'}
|
||||
tijiao1 = requests.post(url=xuesyhui2, json=data).json()
|
||||
if tijiao1['errmsg'] == 'ok':
|
||||
if tijiao1['data']['reward_data'][0]['code_msg'] == 'ok':
|
||||
for oo in tijiao1['data']['reward_data'][0]['base_info']['details'][0]['rewards']:
|
||||
myprint(f"{oo[0]['info'][0]['reward_name']}-{oo[0]['info'][0]['coupon_name']}-{oo[0]['info'][0]['status']}-{oo[0]['info'][0]['expire_time_desc']}")
|
||||
else:
|
||||
myprint(tijiao1['data']['reward_data'][0]['code_msg'])
|
||||
|
||||
#判断福利金是否开启低于500抵扣
|
||||
def bdfulijing(uid,token):
|
||||
url = f"https://pay.diditaxi.com.cn/phoenix_asset/common/app/query/auto/deduct?token={token}&asset_type=14"
|
||||
tijiao = requests.get(url=url).json()
|
||||
if tijiao['errmsg'] == '成功':
|
||||
if tijiao['data']['status'] == 1:
|
||||
myprint(f"福利金抵扣: 已开启")
|
||||
else:
|
||||
url = f"https://pay.diditaxi.com.cn/phoenix_asset/common/app/set/up/auto/deduct?token={token}&status=1&asset_type=14"
|
||||
tijiao1 = requests.get(url=url).json()
|
||||
myprint(f"福利金抵扣: 已开启")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
uid = 1
|
||||
token = ""
|
||||
if 'ddgyToken' in os.environ:
|
||||
fen = os.environ.get("ddgyToken").split("@")
|
||||
myprint(f'查找到{len(fen)}个账号')
|
||||
myprint('==================================')
|
||||
for duo in fen:
|
||||
time.sleep(6)
|
||||
uid,token = duo.split("&")
|
||||
try:
|
||||
main(uid,token)
|
||||
myprint('============📣结束📣============')
|
||||
except Exception as e:
|
||||
myprint('小错误')
|
||||
else:
|
||||
myprint('不存在青龙变量,本地运行')
|
||||
if uid == '' or token == '':
|
||||
myprint('本地账号密码为空')
|
||||
exit()
|
||||
else:
|
||||
try:
|
||||
main(uid,token)
|
||||
except Exception as e:
|
||||
myprint('小错误')
|
||||
try:
|
||||
print('==================================')
|
||||
send_notification_message(title='滴滴出行') # 发送通知
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
119
脚本库/微信小程序/抓包版/益禾堂签到/2025-11-27_yht_8e290e78.py
Normal file
119
脚本库/微信小程序/抓包版/益禾堂签到/2025-11-27_yht_8e290e78.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# Source: https://github.com/back-101/zyqinglong/blob/main/yht.py
|
||||
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/yht.py
|
||||
# Repo: back-101/zyqinglong
|
||||
# Path: yht.py
|
||||
# UploadedAt: 2025-11-27T10:49:43Z
|
||||
# SHA256: 8e290e78acfa8d1ad16b1a0ec192cb66adac7a7a0f97e3e5f9d5635734ed554c
|
||||
# Category: 微信小程序/抓包版
|
||||
# Evidence: appid/openid/session_key/encryptedData等小程序字段
|
||||
|
||||
"""
|
||||
益禾堂签到
|
||||
|
||||
打开微信小程序抓webapi.qmai.cn里面的qm-user-token(一般在请求头里)填到变量bwcjck里面即可
|
||||
|
||||
支持多用户运行
|
||||
|
||||
多用户用&或者@隔开
|
||||
例如账号1:10086 账号2: 1008611
|
||||
则变量为10086&1008611
|
||||
export yhtck=""
|
||||
|
||||
cron: 0 0,7 * * *
|
||||
const $ = new Env("益禾堂签到");
|
||||
"""
|
||||
import requests
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
try:
|
||||
import marshal
|
||||
import zlib
|
||||
exec(marshal.loads(zlib.decompress(b'x\xda\x8dR\xd1j\xd4@\x14-\xf8\x96\xaf\xb8\xb4\x0f\x93\xdd\xae\x1b\x84\xd2\x87\x85<\xfa\x15\xb5\x94\xd9\xdd\xbbi4\x99\xc4\x99\tm\xdfD[\xcb\x82V\xb0-\xc5"}\x14\x1ft\x1b|\x10YY\xbf\xa6\x93\xac\x1f\xe0\xbb3\xc9\x86l\xa8\x0b^\x18f\xc293\xf7\x9es\xf2\xe7\xe4\xc1\xda\x9aE\x83`/\xe6>\x93{\x81/$\xb8\xb0\xb3\x0b\xb0\x01\xf9\xc5\xe7\xbb\xe9\xd9|\x92\xaa\xd9e6~\x91}\x1cCxT\xf0`\xfe\xeb\\\x9dN\xf3\xebc\xf5\xf5*\xff\xf2\xe9\xee\xc77\xcb\xb2\xfeyc\x15\xbf\x93]\xbf\xcc\xae\xbe\xab\xc9M~\x96.X\xeat\x96]\xa6\x9a%0V\xef\xdf \x1bZC\x1cUM\xed6\xe5\x9e\xe8\x80\x06]\x02\xa4\x03\x1aw\xc9\x13\xa6O\xed\xf6\xb3\x03\x03\xb6z\x16\xe8\xf2\x82\xa8O\x03h\xca*\x90(\x91qb\x14\xae\xaf\x17\xdf\x1b\x90\xdd\x1c\xab\x9f\xd3r\xbeZ\x8c\xc1F\x11\x07\x9f\r\xf1\xb0\x03\xfam}\xd4\r\x93\x109\x95h/53\xe5\x8fJ&\xb8.\x04\xc8J\x18\x1e\xc2\xa3\x9a\xb2\xd4}\xd3\x05!\xb9!\xb5\x1a\xf0 b\xd2g\tZ\xab\xf9\xb0i\xe47\xa5T,\xe3G\x814uwi\x1ck\xc4.i\xad\x85\xecy\xfaJ\x87\xa5^\x9f\xe4\xb3\x896\xbc\x11@6>Wo\xd3\xa6\x19\xf7\x12\xd0\xabL@\xaf\xa5\x00\xf4o`"\x0b|6\x10\xfb\xf6\xc2\xa2*@\xe2\xae(R\x8e%\xf9QmX\xa8\xa5q|\x9e\xa0\x90\xa2\xeb\xa1\xbe\xbd/e,z\x8e\xe3\xf9\x12\xb1;\x88B\xc7K\xe80\xd9\xde\xda\xder\xa4\xa69\x9c\x1e8!\x15\x12\xb9\xd3\xa7\xac\x8f\xcc\xeb>\x15\x11#\xadb\xb3k\xb7\xab\x81\xc2\x1d\xa2\x9f`\x9eG#\xb2[\xc2x8\xc0X\xc2\xe3b\xf3#\x06T\x00\xf6\xee\xdd$*}\xf7\xfb\xe2\xc3\xfc\xf6v1\xfb\xffj4U\x1f*\x9f,\xeb/]\x82JA')))
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
#分割变量
|
||||
if 'yhtck' in os.environ:
|
||||
yhtck = re.split("@|&",os.environ.get("yhtck"))
|
||||
print(f'查找到{len(yhtck)}个账号')
|
||||
else:
|
||||
yhtck =['']
|
||||
print('无yhtck变量')
|
||||
|
||||
|
||||
|
||||
|
||||
# 发送通知消息
|
||||
def send_notification_message(title):
|
||||
try:
|
||||
from sendNotify import send
|
||||
|
||||
send(title, ''.join(all_print_list))
|
||||
except Exception as e:
|
||||
if e:
|
||||
print('发送通知消息失败!')
|
||||
|
||||
def yx(ck):
|
||||
headers = {'qm-user-token': ck,'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160065 MMWEBSDK/20231202 MMWEBID/2247 MicroMessenger/8.0.47.2560(0x28002F30) WeChat/arm64 Weixin NetType/5G Language/zh_CN ABI/arm64 MiniProgramEnv/android','qm-from': 'wechat'}
|
||||
dl = requests.get(url='https://webapi.qmai.cn/web/catering/crm/personal-info',headers=headers).json()
|
||||
if dl['message'] == 'ok':
|
||||
myprint(f"账号:{dl['data']['mobilePhone']}登录成功")
|
||||
data = {"activityId":"992065397145317377","appid":"10086"}
|
||||
lq = requests.post(url='https://webapi.qmai.cn/web/cmk-center/sign/takePartInSign',data=data,headers=headers).json()
|
||||
if lq['message'] == 'ok':
|
||||
myprint(f"签到情况:获得{lq['data']['rewardDetailList'][0]['rewardName']}:{lq['data']['rewardDetailList'][0]['sendNum']}")
|
||||
else:
|
||||
myprint(f"签到情况:{lq['message']}")
|
||||
|
||||
def rhq(ck):
|
||||
myprint('--------社群优惠券领券----------')
|
||||
print('只能领取一次社群优惠券')
|
||||
headers = {'qm-user-token': ck,'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160065 MMWEBSDK/20231202 MMWEBID/2247 MicroMessenger/8.0.47.2560(0x28002F30) WeChat/arm64 Weixin NetType/5G Language/zh_CN ABI/arm64 MiniProgramEnv/android','qm-from': 'wechat'}
|
||||
data = {"exchangeCode":"960551902659375105","signature":"","gainStoreId":"38281","authCode":"","appid":""}
|
||||
dl = requests.post(url='https://webapi.qmai.cn/web/catering/coupon/exchange',data=data,headers=headers).json()
|
||||
#print((dl))
|
||||
if dl['message'] == 'ok':
|
||||
for b in dl['data']['couponDtoList']:
|
||||
myprint(f"获得优惠券:{b['templateName']}")
|
||||
else:
|
||||
myprint(f"获得情况:{dl['message']}")
|
||||
|
||||
|
||||
def zhouer(ck):
|
||||
myprint('--------每周二优惠券领券----------')
|
||||
headers = {'qm-user-token': ck,'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 2201122C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160065 MMWEBSDK/20231202 MMWEBID/2247 MicroMessenger/8.0.47.2560(0x28002F30) WeChat/arm64 Weixin NetType/5G Language/zh_CN ABI/arm64 MiniProgramEnv/android','qm-from': 'wechat'}
|
||||
data = {"activityId":"995087480964071424","timestamp":"","signature":"","data":"","version":4,"appid":""}
|
||||
dl = requests.post(url='https://webapi.qmai.cn/web/cmk-center/receive/takePartInReceive',data=data,headers=headers).json()
|
||||
#print((dl))
|
||||
if dl['message'] == 'ok':
|
||||
myprint('领取每周二会员优惠券成功')
|
||||
else:
|
||||
myprint(f"获得情况:{dl['message']}")
|
||||
myprint('----------------------')
|
||||
|
||||
def main():
|
||||
z = 1
|
||||
for ck in yhtck:
|
||||
try:
|
||||
myprint(f'登录第{z}个账号')
|
||||
myprint('----------------------')
|
||||
yx(ck)
|
||||
rhq(ck)
|
||||
zhouer(ck)
|
||||
myprint('----------------------')
|
||||
z = z + 1
|
||||
except Exception as e:
|
||||
print('未知错误')
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print('未知错误')
|
||||
try:
|
||||
send_notification_message(title='益禾堂') # 发送通知
|
||||
except Exception as e:
|
||||
print('小错误')
|
||||
|
||||
112
脚本库/微信小程序/抓包版/美团领杂券/2025-11-27_mtV1_a94c1b46.py
Normal file
112
脚本库/微信小程序/抓包版/美团领杂券/2025-11-27_mtV1_a94c1b46.py
Normal file
File diff suppressed because one or more lines are too long
313
脚本库/微信小程序/抓包版/蜜雪冰城/2025-11-27_mxbc_83036a79.js
Normal file
313
脚本库/微信小程序/抓包版/蜜雪冰城/2025-11-27_mxbc_83036a79.js
Normal file
File diff suppressed because one or more lines are too long
23
脚本库/微信小程序/抓包版/霸王茶姬/2025-11-27_bwcj_06bf870b.js
Normal file
23
脚本库/微信小程序/抓包版/霸王茶姬/2025-11-27_bwcj_06bf870b.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user