diff --git a/bjxd.js b/bjxd.js deleted file mode 100644 index 5d2f349..0000000 --- a/bjxd.js +++ /dev/null @@ -1,785 +0,0 @@ -/* -北京现代 -(不是北京汽车) - -积分换实物,积分涨的比较慢,自己决定跑不跑吧 - -捉域名bm2-api.bluemembers.com.cn任意包的token填到bjxdCookie里,多账户换行隔开 -安卓CK需要在对应的CK后面加上#android -不加默认为IOS CK,不通用 - -重写:打开APP获取 -[task_local] -#北京现代 -58 0,9-22/4 * * * https://raw.githubusercontent.com/leafTheFish/DeathNote/main/bjxd.js, tag=北京现代, enabled=true -[rewrite_local] -https://bm2-api.bluemembers.com.cn/v1/app/white/lovecar/banner url script-request-header https://raw.githubusercontent.com/leafTheFish/DeathNote/main/bjxd.js -[MITM] -hostname = bm2-api.bluemembers.com.cn - -定时:一天一两次 -cron: 36 7,20 * * * - -const $ = new Env("北京现代") -*/ -//Tue Feb 18 2025 06:05:49 GMT+0000 (Coordinated Universal Time) -//Base:https://github.com/echo094/decode-js -//Modify:https://github.com/smallfawn/decode_action -const _0x8716db = new _0x4cda8f("北京现代"); -let _0x268653 = ["\n"]; -let _0x2fdc9f = "bjxdCookie"; -let _0x219a02 = (_0x8716db.isNode() ? process.env[_0x2fdc9f] : _0x8716db.getdata(_0x2fdc9f)) || ""; -let _0x2d9559 = []; -let _0x2c43fb = 0; -let _0x1b86b6 = 0; -let _0x30fc44 = "application/json;charset=utf-8"; -let _0x1d8bc9 = "ModernCar/8.10.0 (iPhone; iOS 15.0; Scale/3.00)"; -let _0x8c33cb = "iOS"; -let _0x5403e8 = 7; -let _0x32da0f = 8; -let _0x1a4387 = 300; -let _0x491d53 = 1000; -let _0x49a9ae = 1.02; -let _0x194108 = "bjxd"; -let _0x6567ed = "https://leafxcy.coding.net/api/user/leafxcy/project/validcode/shared-depot/validCode/git/blob/master/code.json"; -class _0x4c27a8 { - constructor(_0x17c2ed) { - this.index = ++_0x2c43fb; - this.name = this.index; - this.valid = false; - let _0x465c2e = _0x17c2ed.split("#"); - this.token = _0x465c2e[0]; - this.device = _0x465c2e[1] || _0x8c33cb; - } - async taskApi(_0x3967b8 = {}) { - let _0x4dd0e8 = {}; - try { - let _0x1c0362 = _0x3967b8.url.replace("//", "/").split("/")[1]; - let _0x1e768b = _0x3967b8.url; - if (_0x3967b8.queryParam) { - _0x1e768b += "?" + _0x8716db.json2str(_0x3967b8.queryParam, "&", true); - } - const _0x206c16 = { - Host: _0x1c0362, - Connection: "keep-alive", - token: this.token, - "User-Agent": _0x1d8bc9, - device: this.device - }; - let _0x47c42e = { - url: _0x1e768b, - headers: _0x206c16, - timeout: 5000 - }; - if (_0x3967b8.body) { - _0x47c42e.headers["Content-Type"] = _0x3967b8["Content-Type"] || _0x30fc44; - if (typeof _0x3967b8.body === "object") { - if (_0x47c42e.headers["Content-Type"].includes("json")) { - _0x47c42e.body = JSON.stringify(_0x3967b8.body); - } else { - for (let _0x35ecf0 in _0x3967b8.body) { - typeof _0x3967b8.body[_0x35ecf0] === "object" && (_0x3967b8.body[_0x35ecf0] = JSON.stringify(_0x3967b8.body[_0x35ecf0])); - } - _0x47c42e.body = _0x8716db.json2str(_0x3967b8.body, "&"); - } - } else { - _0x47c42e.body = _0x3967b8.body; - } - } - if (_0x3967b8.urlObjectParam) { - Object.assign(_0x47c42e, _0x3967b8.urlObjectParam); - } - if (_0x3967b8.headerParam) { - Object.assign(_0x47c42e.headers, _0x3967b8.headerParam); - } - _0x4dd0e8 = Object.assign({}, await _0x521f1c(_0x3967b8.method, _0x47c42e)); - _0x4dd0e8.statusCode = _0x4dd0e8?.["err"]?.["response"]?.["statusCode"] || _0x4dd0e8?.["resp"]?.["statusCode"]; - _0x4dd0e8.statusCode != 200 && console.log("[" + _0x3967b8.fn + "]返回[" + _0x4dd0e8.statusCode + "]"); - if (_0x4dd0e8?.["resp"]?.["body"]) { - if (typeof _0x4dd0e8.resp.body === "object") { - _0x4dd0e8.result = _0x4dd0e8.resp.body; - } else { - try { - _0x4dd0e8.result = JSON.parse(_0x4dd0e8.resp.body); - } catch (_0x3866e6) { - console.log("[" + _0x3967b8.fn + "]没有返回json数据"); - _0x4dd0e8.result = _0x4dd0e8.resp.body; - } - } - } - } catch (_0x1e3872) { - console.log(_0x1e3872); - } finally { - return Promise.resolve(_0x4dd0e8); - } - } - async getUserInfo() { - let _0x38b266 = {}; - try { - let _0xcaf926 = { - fn: "getUserInfo", - method: "get", - url: "https://bm2-api.bluemembers.com.cn/v1/app/account/users/info" - }; - _0x38b266 = Object.assign({}, await this.taskApi(_0xcaf926)); - if (typeof _0x38b266?.["result"] === "object") { - let _0x4299a4 = _0x38b266.result; - if (_0x4299a4.code == 0) { - this.valid = true; - this.hid = _0x4299a4.data.hid; - this.name = _0x4299a4.data.nickname; - this.phone = _0x4299a4.data.phone; - this.mixPhone = this.phone.slice(0, 3) + "****" + this.phone.slice(7, 13); - this.nid = _0x4299a4.data.nid; - this.score = _0x4299a4.data.score_value; - this.isSign = _0x4299a4.data.if_signed_in; - _0x8716db.logAndNotify("昵称:" + this.name); - _0x8716db.logAndNotify("手机:" + this.mixPhone); - } else { - _0x8716db.logAndNotify("登录失败:" + _0x4299a4.msg); - } - } - } catch (_0x304632) { - console.log(_0x304632); - } finally { - return Promise.resolve(_0x38b266); - } - } - async getScore() { - let _0x12fb1e = {}; - try { - let _0x43a101 = { - fn: "getScore", - method: "get", - url: "https://bm2-api.bluemembers.com.cn/v1/app/account/users/info" - }; - _0x12fb1e = Object.assign({}, await this.taskApi(_0x43a101)); - if (typeof _0x12fb1e?.["result"] === "object") { - let _0x332edd = _0x12fb1e.result; - _0x332edd.code == 0 ? (this.score = _0x332edd.data.score_value, _0x8716db.logAndNotify("积分:" + this.score)) : console.log("查询积分失败:" + _0x332edd.msg); - } - } catch (_0x163403) { - console.log(_0x163403); - } finally { - return Promise.resolve(_0x12fb1e); - } - } - async reward_list() { - let _0x3f6116 = {}; - try { - let _0xe5198f = { - fn: "reward_list", - method: "get", - url: "https://bm2-api.bluemembers.com.cn/v1/app/user/reward_list" - }; - _0x3f6116 = Object.assign({}, await this.taskApi(_0xe5198f)); - if (typeof _0x3f6116?.["result"] === "object") { - let _0x56041 = _0x3f6116.result; - if (_0x56041.code == 0) { - let _0x2fbcf1 = _0x56041.data.list.filter(_0x5ae0ff => _0x5ae0ff.hid == _0x56041.data.hid); - let _0x4a8869 = _0x2fbcf1[0].score; - _0x4a8869 >= _0x5403e8 ? (console.log("获取到签到积分" + _0x4a8869 + "的请求,满足门槛,进行签到"), await this.reward_report(_0x56041.data), this.isSign = true) : console.log("获取到签到积分" + _0x4a8869 + "的请求,小于门槛,不进行签到"); - } else { - console.log("获取签到奖励信息失败:" + _0x56041.msg); - } - } - } catch (_0x64bff7) { - console.log(_0x64bff7); - } finally { - return Promise.resolve(_0x3f6116); - } - } - async reward_report(_0x589132) { - let _0x46c394 = {}; - try { - const _0x34c67b = { - hid: _0x589132.hid, - hash: _0x589132.rewardHash, - sm_deviceId: "" - }; - let _0x4c6530 = { - fn: "reward_report", - method: "post", - url: "https://bm2-api.bluemembers.com.cn/v1/app/user/reward_report", - body: _0x34c67b - }; - _0x46c394 = Object.assign({}, await this.taskApi(_0x4c6530)); - if (typeof _0x46c394?.["result"] === "object") { - let _0x435e80 = _0x46c394.result; - _0x435e80.code == 0 ? console.log("签到成功") : console.log("签到失败:" + _0x435e80.msg); - } - } catch (_0x149902) { - console.log(_0x149902); - } finally { - return Promise.resolve(_0x46c394); - } - } - async taskList() { - let _0x17e315 = {}; - try { - let _0x4b8eca = { - fn: "taskList", - method: "get", - url: "https://bm2-api.bluemembers.com.cn/v1/app/user/task/list" - }; - _0x17e315 = Object.assign({}, await this.taskApi(_0x4b8eca)); - if (typeof _0x17e315?.["result"] === "object") { - let _0x537fef = _0x17e315.result; - _0x537fef.code == 0 ? (!_0x537fef.data.action12.status && (await this.appScore(12)), !_0x537fef.data.action39.status && (await this.ask_info())) : console.log("获取任务列表失败:" + _0x537fef.msg); - } - } catch (_0x217171) { - console.log(_0x217171); - } finally { - return Promise.resolve(_0x17e315); - } - } - async appScore(_0x2e08b2) { - let _0x56f9a9 = {}; - try { - let _0x139670 = { - fn: "appScore", - method: "post", - url: "https://bm2-api.bluemembers.com.cn/v1/app/score", - body: { - action: Number(_0x2e08b2) - } - }; - _0x56f9a9 = Object.assign({}, await this.taskApi(_0x139670)); - if (typeof _0x56f9a9?.["result"] === "object") { - let _0x2398d7 = _0x56f9a9.result; - _0x2398d7.code == 0 ? _0x2398d7.data.is_stop ? console.log("完成任务[" + _0x2e08b2 + "]成功,获得" + _0x2398d7.data.score + "积分") : console.log("任务[" + _0x2e08b2 + "]已完成过") : console.log("完成任务[" + _0x2e08b2 + "]失败:" + _0x2398d7.msg); - } - } catch (_0x4aaf25) { - console.log(_0x4aaf25); - } finally { - return Promise.resolve(_0x56f9a9); - } - } - async ask_info() { - let _0x8f513e = {}; - try { - let _0x2a7cc6 = { - fn: "ask_info", - method: "get", - url: "https://bm2-api.bluemembers.com.cn/v1/app/special/daily/ask_info", - queryParam: { - date: _0x8716db.time("yyyyMMdd") - } - }; - _0x8f513e = Object.assign({}, await this.taskApi(_0x2a7cc6)); - if (typeof _0x8f513e?.["result"] === "object") { - let _0x5469c5 = _0x8f513e.result; - if (_0x5469c5.code == 0) { - if (_0x5469c5.data.state == 1) { - console.log("开始答题:"); - console.log(_0x5469c5.data.question_info.content); - for (let _0x296803 of _0x5469c5.data.question_info.option) { - console.log(_0x296803.option + ": " + _0x296803.option_content); - } - await this.ask_answer(_0x5469c5.data.question_info); - } else { - console.log("今日已完成答题"); - } - } else { - console.log("获取任务列表失败:" + _0x5469c5.msg); - } - } - } catch (_0x45d564) { - console.log(_0x45d564); - } finally { - return Promise.resolve(_0x8f513e); - } - } - async ask_answer(_0x4ee39a) { - let _0x320116 = {}; - try { - let _0x16af4f = _0x8716db.randomList(_0x4ee39a.option); - console.log("随机选择[" + _0x16af4f.option + "]"); - const _0x5c6056 = { - answer: _0x16af4f.option, - questions_hid: _0x4ee39a.questions_hid - }; - let _0x237782 = { - fn: "ask_answer", - method: "post", - url: "https://bm2-api.bluemembers.com.cn/v1/app/special/daily/ask_answer", - body: _0x5c6056 - }; - _0x320116 = Object.assign({}, await this.taskApi(_0x237782)); - if (typeof _0x320116?.["result"] === "object") { - let _0x30d161 = _0x320116.result; - _0x30d161.code == 0 ? _0x30d161.data.state == 2 ? console.log("回答正确,获得" + _0x30d161.data.answer_score + "积分") : console.log("回答错误") : console.log("回答失败:" + _0x30d161.msg); - } - } catch (_0x26cc04) { - console.log(_0x26cc04); - } finally { - return Promise.resolve(_0x320116); - } - } - async userTask() { - let _0x4937de = {}; - try { - _0x8716db.logAndNotify("\n============= 账号[" + this.index + "] ============="); - await this.getUserInfo(); - if (!this.valid) { - return; - } - for (let _0x50258e = 0; _0x50258e < 50 && !this.isSign; _0x50258e++) { - await this.reward_list(); - } - await this.taskList(); - await this.getScore(); - } catch (_0x5859d2) { - console.log(_0x5859d2); - } finally { - return Promise.resolve(_0x4937de); - } - } -} -!(async () => { - if (typeof $request !== "undefined") { - await _0x14afab(); - } else { - /*if (!(await _0x2b9e78())) { - return; - }*/ - if (!_0x5783c6()) { - return; - } - for (let _0x446442 of _0x2d9559) { - await _0x446442.userTask(); - } - } -})().catch(_0x2a23c4 => console.log(_0x2a23c4)).finally(() => _0x8716db.done()); -async function _0x14afab() { - if ($request.url.includes("v1/app/white/lovecar/banner")) { - try { - let _0x13b4b6 = $request.headers.token; - let _0x4dcfbd = _0x268653[0]; - for (let _0x44475f of _0x268653) { - if (_0x219a02?.["includes"](_0x44475f)) { - _0x4dcfbd = _0x44475f; - break; - } - } - if (!_0x219a02?.["includes"](_0x13b4b6)) { - let _0x1b71ef = _0x219a02 ? _0x219a02.split(_0x4dcfbd) : []; - _0x1b71ef.push(_0x13b4b6); - _0x219a02 = _0x1b71ef.join(_0x4dcfbd); - _0x8716db.setdata(_0x219a02, _0x2fdc9f); - _0x8716db.msg("获取第" + _0x1b71ef.length + "个账户CK成功,保存到变量[" + _0x2fdc9f + "]: " + _0x13b4b6); - } - } catch (_0x4cf3b5) {} - } -} -function _0x5783c6() { - if (_0x219a02) { - let _0x3f061f = _0x268653[0]; - for (let _0x4cde89 of _0x268653) { - if (_0x219a02.indexOf(_0x4cde89) > -1) { - _0x3f061f = _0x4cde89; - break; - } - } - for (let _0x442d1d of _0x219a02.split(_0x3f061f)) { - if (_0x442d1d) { - _0x2d9559.push(new _0x4c27a8(_0x442d1d)); - } - } - _0x1b86b6 = _0x2d9559.length; - } else { - console.log("未找到CK: " + _0x2fdc9f); - return false; - } - console.log("共找到" + _0x1b86b6 + "个账号"); - return true; -} -async function _0x2b9e78(_0x52f9ac = 0) { - let _0x454209 = false; - try { - let _0x20d7ff = { - url: _0x6567ed, - timeout: 5000 - }; - let _0x239829 = null; - let _0x457fa9 = await _0x521f1c("get", _0x20d7ff); - if (_0x457fa9.err) { - console.log("服务器错误[" + _0x457fa9?.["resp"]?.["statusCode"] + "],重试..."); - } else { - try { - _0x239829 = JSON.parse(_0x457fa9.resp.body); - _0x239829?.["code"] == 0 && (_0x239829 = JSON.parse(_0x239829.data.file.data)); - } catch (_0x5d759c) {} - } - if (!_0x239829) { - if (_0x52f9ac < _0x32da0f) { - let _0x22b7e = Math.floor(Math.random() * _0x491d53) + _0x1a4387; - _0x454209 = await _0x2b9e78(++_0x52f9ac); - } - } else { - _0x239829?.["commonNotify"] && _0x239829.commonNotify.length > 0 && _0x8716db.logAndNotify(_0x239829.commonNotify.join("\n") + "\n"); - _0x239829?.["commonMsg"] && _0x239829.commonMsg.length > 0 && console.log(_0x239829.commonMsg.join("\n") + "\n"); - if (_0x239829[_0x194108]) { - let _0x1d6833 = _0x239829[_0x194108]; - _0x1d6833.status == 0 ? _0x49a9ae >= _0x1d6833.version ? (_0x454209 = true, console.log(_0x1d6833.msg[_0x1d6833.status]), console.log(_0x1d6833.updateMsg), console.log("现在运行的脚本版本是:" + _0x49a9ae + ",最新脚本版本:" + _0x1d6833.latestVersion)) : console.log(_0x1d6833.versionMsg) : console.log(_0x1d6833.msg[_0x1d6833.status]); - } else { - console.log(_0x239829.errorMsg); - } - } - } catch (_0x3f1377) { - console.log(_0x3f1377); - } finally { - return Promise.resolve(_0x454209); - } -} -async function _0x521f1c(_0x263b8f, _0x513b4c) { - return new Promise(_0x40a2b3 => { - _0x8716db.send(_0x263b8f, _0x513b4c, async (_0x6e577d, _0x129293, _0xf085c6) => { - const _0x348782 = { - err: _0x6e577d, - req: _0x129293, - resp: _0xf085c6 - }; - _0x40a2b3(_0x348782); - }); - }); -} -function _0x4cda8f(_0x1e4724, _0xff6f77) { - "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0); - return new class { - constructor(_0x4178f5, _0x2ac14c) { - this.name = _0x4178f5; - this.notifyStr = ""; - this.startTime = new Date().getTime(); - Object.assign(this, _0x2ac14c); - console.log(this.name + " 开始运行:\n"); - } - isNode() { - return "undefined" != typeof module && !!module.exports; - } - isQuanX() { - return "undefined" != typeof $task; - } - isSurge() { - return "undefined" != typeof $httpClient && "undefined" == typeof $loon; - } - isLoon() { - return "undefined" != typeof $loon; - } - getdata(_0x4fefce) { - let _0x3782e9 = this.getval(_0x4fefce); - if (/^@/.test(_0x4fefce)) { - const [, _0x34b308, _0x48c0c3] = /^@(.*?)\.(.*?)$/.exec(_0x4fefce); - const _0x31bfd6 = _0x34b308 ? this.getval(_0x34b308) : ""; - if (_0x31bfd6) { - try { - const _0x479c6a = JSON.parse(_0x31bfd6); - _0x3782e9 = _0x479c6a ? this.lodash_get(_0x479c6a, _0x48c0c3, "") : _0x3782e9; - } catch (_0x4facad) { - _0x3782e9 = ""; - } - } - } - return _0x3782e9; - } - setdata(_0x4beabf, _0x590b04) { - let _0x38fc86 = false; - if (/^@/.test(_0x590b04)) { - const [, _0x20017f, _0x55f66f] = /^@(.*?)\.(.*?)$/.exec(_0x590b04); - const _0x3e34f7 = this.getval(_0x20017f); - const _0x3a6458 = _0x20017f ? "null" === _0x3e34f7 ? null : _0x3e34f7 || "{}" : "{}"; - try { - const _0x2b471b = JSON.parse(_0x3a6458); - this.lodash_set(_0x2b471b, _0x55f66f, _0x4beabf); - _0x38fc86 = this.setval(JSON.stringify(_0x2b471b), _0x20017f); - } catch (_0x1494d0) { - const _0xd89f1b = {}; - this.lodash_set(_0xd89f1b, _0x55f66f, _0x4beabf); - _0x38fc86 = this.setval(JSON.stringify(_0xd89f1b), _0x20017f); - } - } else { - _0x38fc86 = this.setval(_0x4beabf, _0x590b04); - } - return _0x38fc86; - } - getval(_0x54eb3e) { - return this.isSurge() || this.isLoon() ? $persistentStore.read(_0x54eb3e) : this.isQuanX() ? $prefs.valueForKey(_0x54eb3e) : this.isNode() ? (this.data = this.loaddata(), this.data[_0x54eb3e]) : this.data && this.data[_0x54eb3e] || null; - } - setval(_0x491870, _0x2145f6) { - return this.isSurge() || this.isLoon() ? $persistentStore.write(_0x491870, _0x2145f6) : this.isQuanX() ? $prefs.setValueForKey(_0x491870, _0x2145f6) : this.isNode() ? (this.data = this.loaddata(), this.data[_0x2145f6] = _0x491870, this.writedata(), true) : this.data && this.data[_0x2145f6] || null; - } - send(_0x30ed81, _0x46cad7, _0x1cc856 = () => {}) { - if (_0x30ed81 != "get" && _0x30ed81 != "post" && _0x30ed81 != "put" && _0x30ed81 != "delete") { - console.log("无效的http方法:" + _0x30ed81); - return; - } - if (_0x30ed81 == "get" && _0x46cad7.headers) { - delete _0x46cad7.headers["Content-Type"]; - delete _0x46cad7.headers["Content-Length"]; - } else { - if (_0x46cad7.body && _0x46cad7.headers) { - if (!_0x46cad7.headers["Content-Type"]) { - _0x46cad7.headers["Content-Type"] = "application/x-www-form-urlencoded"; - } - } - } - if (this.isSurge() || this.isLoon()) { - if (this.isSurge() && this.isNeedRewrite) { - _0x46cad7.headers = _0x46cad7.headers || {}; - const _0x26fc4f = { - "X-Surge-Skip-Scripting": false - }; - Object.assign(_0x46cad7.headers, _0x26fc4f); - } - let _0x5bc71d = { - method: _0x30ed81, - url: _0x46cad7.url, - headers: _0x46cad7.headers, - timeout: _0x46cad7.timeout, - data: _0x46cad7.body - }; - if (_0x30ed81 == "get") { - delete _0x5bc71d.data; - } - $axios(_0x5bc71d).then(_0x5bd58f => { - const { - status: _0x170536, - request: _0x1e7cb3, - headers: _0x468f75, - data: _0x580b03 - } = _0x5bd58f; - const _0x571f3c = { - statusCode: _0x170536, - headers: _0x468f75, - body: _0x580b03 - }; - _0x1cc856(null, _0x1e7cb3, _0x571f3c); - }).catch(_0x4bda4a => console.log(_0x4bda4a)); - } else { - if (this.isQuanX()) { - const _0x327740 = { - hints: false - }; - _0x46cad7.method = _0x30ed81.toUpperCase(); - this.isNeedRewrite && (_0x46cad7.opts = _0x46cad7.opts || {}, Object.assign(_0x46cad7.opts, _0x327740)); - $task.fetch(_0x46cad7).then(_0x54076a => { - const { - statusCode: _0x1a879b, - request: _0x425de9, - headers: _0x3d8419, - body: _0x40f74b - } = _0x54076a; - const _0x206c23 = { - statusCode: _0x1a879b, - headers: _0x3d8419, - body: _0x40f74b - }; - _0x1cc856(null, _0x425de9, _0x206c23); - }, _0x3c58de => _0x1cc856(_0x3c58de)); - } else { - if (this.isNode()) { - this.got = this.got ? this.got : require("got"); - const { - url: _0x5838e9, - ..._0x4db42f - } = _0x46cad7; - const _0x527bb1 = { - followRedirect: false - }; - this.instance = this.got.extend(_0x527bb1); - this.instance[_0x30ed81](_0x5838e9, _0x4db42f).then(_0x5339a9 => { - const { - statusCode: _0x3bc338, - request: _0x576247, - headers: _0x6e3fd4, - body: _0x1a837a - } = _0x5339a9; - const _0x420bc3 = { - statusCode: _0x3bc338, - headers: _0x6e3fd4, - body: _0x1a837a - }; - _0x1cc856(null, _0x576247, _0x420bc3); - }, _0x86d1ba => { - const { - message: _0x53d502, - request: _0x507dc9, - response: _0x598f0c - } = _0x86d1ba; - _0x1cc856(_0x53d502, _0x507dc9, _0x598f0c); - }); - } - } - } - } - time(_0x2ef619, _0x16db29 = null) { - let _0x2c3750 = _0x16db29 ? new Date(_0x16db29) : new Date(); - let _0x5cd64f = { - "M+": _0x2c3750.getMonth() + 1, - "d+": _0x2c3750.getDate(), - "h+": _0x2c3750.getHours(), - "m+": _0x2c3750.getMinutes(), - "s+": _0x2c3750.getSeconds(), - "q+": Math.floor((_0x2c3750.getMonth() + 3) / 3), - S: _0x2c3750.getMilliseconds() - }; - /(y+)/.test(_0x2ef619) && (_0x2ef619 = _0x2ef619.replace(RegExp.$1, (_0x2c3750.getFullYear() + "").substr(4 - RegExp.$1.length))); - for (let _0x4ccae2 in _0x5cd64f) new RegExp("(" + _0x4ccae2 + ")").test(_0x2ef619) && (_0x2ef619 = _0x2ef619.replace(RegExp.$1, 1 == RegExp.$1.length ? _0x5cd64f[_0x4ccae2] : ("00" + _0x5cd64f[_0x4ccae2]).substr(("" + _0x5cd64f[_0x4ccae2]).length))); - return _0x2ef619; - } - async showmsg() { - if (!this.notifyStr) { - return; - } - let _0x69a576 = this.name + " 运行通知\n\n" + this.notifyStr; - if (_0x8716db.isNode()) { - var _0x4ded0f = require("./sendNotify"); - console.log("\n============== 推送 =============="); - await _0x4ded0f.sendNotify(this.name, _0x69a576); - } else { - this.msg(_0x69a576); - } - } - logAndNotify(_0x5d20e5) { - console.log(_0x5d20e5); - this.notifyStr += _0x5d20e5; - this.notifyStr += "\n"; - } - logAndNotifyWithTime(_0x13c259) { - let _0x5d180a = "[" + this.time("hh:mm:ss.S") + "]" + _0x13c259; - console.log(_0x5d180a); - this.notifyStr += _0x5d180a; - this.notifyStr += "\n"; - } - logWithTime(_0xe9e4ad) { - console.log("[" + this.time("hh:mm:ss.S") + "]" + _0xe9e4ad); - } - msg(_0x281b91 = t, _0x2a5e45 = "", _0x441be7 = "", _0xd75caf) { - const _0x3c126f = _0xf16ff0 => { - if (!_0xf16ff0) { - return _0xf16ff0; - } - if ("string" == typeof _0xf16ff0) { - return this.isLoon() ? _0xf16ff0 : this.isQuanX() ? { - "open-url": _0xf16ff0 - } : this.isSurge() ? { - url: _0xf16ff0 - } : undefined; - } - if ("object" == typeof _0xf16ff0) { - if (this.isLoon()) { - let _0x2fda6e = _0xf16ff0.openUrl || _0xf16ff0.url || _0xf16ff0["open-url"]; - let _0x1bd995 = _0xf16ff0.mediaUrl || _0xf16ff0["media-url"]; - const _0x5d7302 = { - openUrl: _0x2fda6e, - mediaUrl: _0x1bd995 - }; - return _0x5d7302; - } - if (this.isQuanX()) { - let _0x5464ef = _0xf16ff0["open-url"] || _0xf16ff0.url || _0xf16ff0.openUrl; - let _0x3b60b5 = _0xf16ff0["media-url"] || _0xf16ff0.mediaUrl; - const _0x3f7c94 = { - "open-url": _0x5464ef, - "media-url": _0x3b60b5 - }; - return _0x3f7c94; - } - if (this.isSurge()) { - let _0x4f4b61 = _0xf16ff0.url || _0xf16ff0.openUrl || _0xf16ff0["open-url"]; - const _0x40f4f2 = { - url: _0x4f4b61 - }; - return _0x40f4f2; - } - } - }; - this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(_0x281b91, _0x2a5e45, _0x441be7, _0x3c126f(_0xd75caf)) : this.isQuanX() && $notify(_0x281b91, _0x2a5e45, _0x441be7, _0x3c126f(_0xd75caf))); - let _0x3eabf5 = ["", "============== 系统通知 =============="]; - _0x3eabf5.push(_0x281b91); - _0x2a5e45 && _0x3eabf5.push(_0x2a5e45); - _0x441be7 && _0x3eabf5.push(_0x441be7); - console.log(_0x3eabf5.join("\n")); - } - getMin(_0x15962f, _0x2a34e2) { - return _0x15962f < _0x2a34e2 ? _0x15962f : _0x2a34e2; - } - getMax(_0x10b5c9, _0xd6c9d7) { - return _0x10b5c9 < _0xd6c9d7 ? _0xd6c9d7 : _0x10b5c9; - } - padStr(_0x3b72ab, _0x3e7ee5, _0x173b51 = "0") { - let _0x444bd6 = String(_0x3b72ab); - let _0x5a80d4 = _0x3e7ee5 > _0x444bd6.length ? _0x3e7ee5 - _0x444bd6.length : 0; - let _0xbedc9d = ""; - for (let _0x3f8956 = 0; _0x3f8956 < _0x5a80d4; _0x3f8956++) { - _0xbedc9d += _0x173b51; - } - _0xbedc9d += _0x444bd6; - return _0xbedc9d; - } - json2str(_0x4cb5d6, _0x36e3c5, _0x2ec4bc = false) { - let _0x4d114d = []; - for (let _0x207106 of Object.keys(_0x4cb5d6).sort()) { - let _0x3811eb = _0x4cb5d6[_0x207106]; - if (_0x3811eb && _0x2ec4bc) { - _0x3811eb = encodeURIComponent(_0x3811eb); - } - _0x4d114d.push(_0x207106 + "=" + _0x3811eb); - } - return _0x4d114d.join(_0x36e3c5); - } - str2json(_0x153294, _0x4b27fb = false) { - let _0x593ed4 = {}; - for (let _0xdc7f24 of _0x153294.split("&")) { - if (!_0xdc7f24) { - continue; - } - let _0x221d9d = _0xdc7f24.indexOf("="); - if (_0x221d9d == -1) { - continue; - } - let _0x48bba3 = _0xdc7f24.substr(0, _0x221d9d); - let _0x2a45fc = _0xdc7f24.substr(_0x221d9d + 1); - if (_0x4b27fb) { - _0x2a45fc = decodeURIComponent(_0x2a45fc); - } - _0x593ed4[_0x48bba3] = _0x2a45fc; - } - return _0x593ed4; - } - randomPattern(_0x39c9a4, _0x782889 = "abcdef0123456789") { - let _0x167a1 = ""; - for (let _0x4c9048 of _0x39c9a4) { - if (_0x4c9048 == "x") { - _0x167a1 += _0x782889.charAt(Math.floor(Math.random() * _0x782889.length)); - } else { - _0x4c9048 == "X" ? _0x167a1 += _0x782889.charAt(Math.floor(Math.random() * _0x782889.length)).toUpperCase() : _0x167a1 += _0x4c9048; - } - } - return _0x167a1; - } - randomString(_0x600a62, _0x1be07f = "abcdef0123456789") { - let _0x23158e = ""; - for (let _0x1ed705 = 0; _0x1ed705 < _0x600a62; _0x1ed705++) { - _0x23158e += _0x1be07f.charAt(Math.floor(Math.random() * _0x1be07f.length)); - } - return _0x23158e; - } - randomList(_0x4acba4) { - let _0x91a694 = Math.floor(Math.random() * _0x4acba4.length); - return _0x4acba4[_0x91a694]; - } - wait(_0x530f72) { - return new Promise(_0x3e7b59 => setTimeout(_0x3e7b59, _0x530f72)); - } - async done(_0x5b659f = {}) { - await this.showmsg(); - const _0x1541e5 = new Date().getTime(); - const _0x2fa0de = (_0x1541e5 - this.startTime) / 1000; - console.log("\n" + this.name + " 运行结束,共运行了 " + _0x2fa0de + " 秒!"); - if (this.isSurge() || this.isQuanX() || this.isLoon()) { - $done(_0x5b659f); - } - } - }(_0x1e4724, _0xff6f77); -} \ No newline at end of file diff --git a/bjxd.py b/bjxd.py new file mode 100644 index 0000000..05b8a75 --- /dev/null +++ b/bjxd.py @@ -0,0 +1,639 @@ +""" +北京现代 APP 自动任务脚本 +功能:自动完成签到、浏览文章、每日答题等任务 +DOG :QQ 2979873337 努力中(🤩) 禁止使用 此人是探子 任何人见了避而远之 +环境变量: + BJXD: str - 北京现代 APP api token (多个账号用英文逗号分隔,建议每个账号一个变量) + BJXD1/BJXD2/BJXD3: str - 北京现代 APP api token (每个账号一个变量) + BJXD_ANSWER: str - 预设答案 (可选, ABCD 中的一个) + HUNYUAN_API_KEY: str - 腾讯混元AI APIKey (可选) + +cron: 25 6 * * * +""" + +import os +import random +import time +from datetime import datetime +from typing import List, Dict, Any +import requests +from urllib3.exceptions import InsecureRequestWarning, InsecurePlatformWarning + +# 禁用 SSL 警告 +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) +requests.packages.urllib3.disable_warnings(InsecurePlatformWarning) + + +class BeiJingHyundai: + """北京现代APP自动任务类""" + + # 基础配置 + NAME = "北京现代 APP 自动任务" + BASE_URL = "https://bm2-api.bluemembers.com.cn" + + # API endpoints + API_USER_INFO = "/v1/app/account/users/info" + API_MY_SCORE = "/v1/app/user/my_score" + API_TASK_LIST = "/v1/app/user/task/list" + API_SIGN_LIST = "/v1/app/user/reward_list" + API_SIGN_SUBMIT = "/v1/app/user/reward_report" + API_ARTICLE_LIST = "/v1/app/white/article/list2" + API_ARTICLE_DETAIL = "/v1/app/white/article/detail_app/{}" + API_ARTICLE_SCORE_SUBMIT = "/v1/app/score" + API_QUESTION_INFO = "/v1/app/special/daily/ask_info" + API_QUESTION_SUBMIT = "/v1/app/special/daily/ask_answer" + + # 预设的备用 share_user_hid 列表 + BACKUP_HIDS = [ + "a6688ec1a9ee429fa7b68d50e0c92b1f", + "bb8cd2e44c7b45eeb8cc5f7fa71c3322", + "5f640c50061b400c91be326c8fe0accd", + "55a5d82dacd9417483ae369de9d9b82d", + ] + + def __init__(self): + """初始化实例变量""" + self.token: str = "" # 当前用户token + self.user: Dict[str, Any] = {} # 当前用户信息 + self.users: List[Dict[str, Any]] = [] # 所有用户信息列表 + self.correct_answer: str = "" # 正确答案 + self.preset_answer: str = "" # 预设答案 + self.ai_api_key: str = "" # 腾讯混元AI APIKey + self.wrong_answers: set = set() # 错误答案集合 + self.log_content: str = "" # 日志内容 + + def log(self, content: str, print_to_console: bool = True) -> None: + """添加日志""" + if print_to_console: + print(content) + self.log_content += content + "\n" + + def push_notification(self) -> None: + """推送通知""" + try: + QLAPI.notify(self.NAME, self.log_content) + except NameError: + print(f"\n\n🚀 推送通知\n\n{self.NAME}\n\n{self.log_content}") + + def make_request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]: + """ + 发送API请求 + Args: + method: 请求方法 (GET/POST) + endpoint: API端点 + **kwargs: 请求参数 + Returns: + Dict[str, Any]: API响应数据 + """ + url = f"{self.BASE_URL}{endpoint}" + headers = {"token": self.token, "device": "android"} + if "headers" not in kwargs: + kwargs["headers"] = headers + else: + kwargs["headers"].update(headers) + try: + response = requests.request(method, url, **kwargs) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + self.log(f"❌ API request failed: {str(e)}") + return {"code": -1, "msg": str(e)} + + def get_user_info(self) -> Dict[str, Any]: + """ + 获取用户信息 + Returns: + Dict[str, Any]: 用户信息字典,获取失败返回空字典 + """ + response = self.make_request("GET", self.API_USER_INFO) + print(f"get_user_info API response ——> {response}") + + if response["code"] == 0: + data = response["data"] + # 直接生成掩码后的手机号 + masked_phone = f"{data['phone'][:3]}******{data['phone'][-2:]}" + return { + "token": self.token, + "hid": data["hid"], + "nickname": data["nickname"], + "phone": masked_phone, # 直接存储掩码后的手机号 + "score_value": data["score_value"], + "share_user_hid": "", + "task": {"sign": False, "view": False, "question": False}, + } + + self.log(f"❌ 账号已失效, 请重新获取 token: {self.token}") + return {} + + def get_score_details(self) -> None: + """显示积分详情,包括总积分、今日变动和最近记录""" + params = {"page_no": "1", "page_size": "10"} # 获取最近10条记录 + response = self.make_request("GET", self.API_MY_SCORE, params=params) + print(f"get_score_details API response ——> {response}") + + if response["code"] == 0: + data = response["data"] + # 先获取今日记录 + today = datetime.now().strftime("%Y-%m-%d") + today_records = [ + record + for record in data["points_record"]["list"] + if record["created_at"].startswith(today) + ] + + # 计算今日积分变化 + today_score = sum( + int(record["score_str"].strip("+")) for record in today_records + ) + today_score_str = f"+{today_score}" if today_score > 0 else str(today_score) + self.log(f"🎉 总积分: {data['score']} | 今日积分变动: {today_score_str}") + + # 输出今日积分记录 + if today_records: + self.log("今日积分记录:") + for record in today_records: + self.log( + f"{record['created_at']} {record['desc']} {record['score_str']}" + ) + else: + self.log("今日暂无积分变动") + + # 任务相关 + def check_task_status(self, user: Dict[str, Any]) -> None: + """检查任务状态""" + response = self.make_request("GET", self.API_TASK_LIST) + print(f"get_task_status API response ——> {response}") + + if response["code"] != 0: + self.log(f'❌ 获取任务列表失败: {response["msg"]}') + return + + actions = response.get("data", {}) + + # 检查签到任务 + if "action4" in actions: + user["task"]["sign"] = actions["action4"].get("status") == 1 + else: + self.log("❌ task list action4 签到任务 不存在") + + # 检查浏览文章任务 + if "action12" in actions: + user["task"]["view"] = actions["action12"].get("status") == 1 + else: + self.log("❌ task list action12 浏览文章任务 不存在") + + # 检查答题任务 + if "action39" in actions: + user["task"]["question"] = actions["action39"].get("status") == 1 + else: + self.log("❌ task list action39 答题任务 不存在") + + # 签到相关 + def get_sign_info(self) -> None: + """执行签到任务""" + max_attempts = 5 # 最大尝试次数 + best_score = 0 + best_params = None + + for attempt in range(max_attempts): + response = self.make_request("GET", self.API_SIGN_LIST) + print(f"get_sign_info (attempt {attempt + 1}) API response ——> {response}") + + if response["code"] != 0: + self.log(f'❌ 获取签到列表失败: {response["msg"]}') + break + + data = response["data"] + hid = data["hid"] + reward_hash = data["rewardHash"] + + for item in data["list"]: + if item["hid"] == hid: + current_score = item["score"] + print( + f"第{attempt + 1}次获取签到列表: score={current_score} hid={hid} rewardHash={reward_hash}" + ) + + if current_score > best_score: + best_score = current_score + best_params = (hid, reward_hash, current_score) + print(f"当前可获得签到积分: {best_score}") + break + + if attempt < max_attempts - 1: # 不是最后一次循环 + print(f"继续尝试获取更高积分, 延时5-10s") + time.sleep(random.randint(5, 10)) + else: # 最后一次循环 即将提交签到 + print(f"即将提交签到, 延时3-4s") + time.sleep(random.randint(3, 4)) + + if best_params: + self.submit_sign(*best_params) + else: + self.log("❌ 未能获取到有效的签到参数") + + def submit_sign(self, hid: str, reward_hash: str, score: int) -> None: + """提交签到""" + json_data = { + "hid": hid, + "hash": reward_hash, + "sm_deviceId": "", + "ctu_token": None, + } + response = self.make_request("POST", self.API_SIGN_SUBMIT, json=json_data) + print(f"submit_sign API response ——> {response}") + + if response["code"] == 0: + self.log(f"✅ 签到成功 | 积分 +{score}") + else: + self.log(f'❌ 签到失败: {response["msg"]}') + + # 文章浏览相关 + def get_article_list(self) -> List[str]: + """获取文章列表""" + params = { + "page_no": "1", + "page_size": "20", + "type_hid": "", + } + response = self.make_request("GET", self.API_ARTICLE_LIST, params=params) + print(f"get_article_list API response ——> {response}") + + if response["code"] == 0: + # 从文章列表中随机选择3个ID + article_list = [item["data_id"] for item in response["data"]["list"]] + return random.sample(article_list, min(3, len(article_list))) + + self.log(f'❌ 获取文章列表失败: {response["msg"]}') + return [] + + def get_article_detail(self, article_id: str) -> None: + """浏览文章""" + self.log(f"浏览文章 article_id: {article_id}") + endpoint = self.API_ARTICLE_DETAIL.format(article_id) + self.make_request("GET", endpoint) + + def submit_article_score(self) -> None: + """提交文章积分""" + json_data = { + "ctu_token": "", + "action": 12, + } + response = self.make_request( + "POST", self.API_ARTICLE_SCORE_SUBMIT, json=json_data + ) + print(f"submit_article_score API response ——> {response}") + + if response["code"] == 0: + score = response["data"]["score"] + self.log(f"✅ 浏览文章成功 | 积分 +{score}") + else: + self.log(f'❌ 浏览文章失败: {response["msg"]}') + + # 答题相关 + def get_question_info(self, share_user_hid: str) -> None: + """执行答题任务""" + params = {"date": datetime.now().strftime("%Y%m%d")} + response = self.make_request("GET", self.API_QUESTION_INFO, params=params) + print(f"get_question_info API response ——> {response}") + if response["code"] != 0: + self.log(f'❌ 获取问题失败: {response["msg"]}') + return + # response['data']['state'] 1=表示未答题 2=已答题且正确 3=答错且未有人帮忙答题 4=答错但有人帮忙答题 + if response["data"].get("state") == 3: + self.log("今日已答题但回答错误,当前无人帮助答题,跳过") + return + if response["data"].get("state") != 1: + if response["data"].get("answer"): + answer = response["data"]["answer"][0] + if answer in ["A", "B", "C", "D"]: + self.correct_answer = answer + self.log(f"今日已答题,跳过,答案:{answer}") + return + self.log("今日已答题,但未获取到答案,跳过") + return + + question_info = response["data"]["question_info"] + questions_hid = question_info["questions_hid"] + + # 构建问题字符串,只包含未被标记为错误的选项 + question_str = f"{question_info['content']}\n" + valid_options = [] + for option in question_info["option"]: + if option["option"] not in self.wrong_answers: + valid_options.append(option) + question_str += f'{option["option"]}. {option["option_content"]}\n' + else: + print(f"跳过错误选项 {option['option']}. {option['option_content']}") + + print(f"\n问题详情:\n{question_str}") + + # 如果只剩一个选项,直接使用 + if len(valid_options) == 1: + answer = valid_options[0]["option"] + self.log(f"仅剩一个选项,使用答案: {answer}") + time.sleep(random.randint(3, 5)) + self.submit_question_answer(questions_hid, answer, share_user_hid) + return + + # 获取答案并提交 + answer = self.get_question_answer(question_str) + + time.sleep(random.randint(3, 5)) + self.submit_question_answer(questions_hid, answer, share_user_hid) + + def get_ai_answer(self, question: str) -> str: + """获取AI答案""" + headers = { + "Authorization": f"Bearer {self.ai_api_key}", + "Content-Type": "application/json", + } + prompt = f"你是一个专业的北京现代汽车专家,请直接给出这个单选题的答案,并且不要带'答案'等其他内容。\n{question}" + json_data = { + "model": "hunyuan-turbo", + "messages": [{"role": "user", "content": prompt}], + "enable_enhancement": True, + "force_search_enhancement": True, + "enable_instruction_search": True, + } + + try: + response = requests.post( + "https://api.hunyuan.cloud.tencent.com/v1/chat/completions", + headers=headers, + json=json_data, + ) + response.raise_for_status() + response_json = response.json() + print(f"腾讯混元AI API response ——> {response_json}") + + # 获取AI回答内容并转大写 + ai_response = response_json["choices"][0]["message"]["content"].upper() + + # 使用集合操作找出有效答案 + valid_answers = set("ABCD") - self.wrong_answers + found_answers = set(ai_response) & valid_answers + + # 如果找到答案则返回其中一个 + if found_answers: + return found_answers.pop() + else: + print(f"❌ 没有找到符合的 AI 答案") + return "" + + except Exception as e: + print(f"腾讯混元AI API 请求失败: {str(e)}") + + return "" + + def get_question_answer(self, question: str) -> str: + """获取答题答案""" + # 1. 存在正确答案时,使用正确答案 + if self.correct_answer: + self.log(f"使用历史正确答案: {self.correct_answer}") + return self.correct_answer + + # 2. 存在预设答案时,使用预设答案 + if self.preset_answer: + self.log(f"使用预设答案: {self.preset_answer}") + return self.preset_answer + + # 3. 存在AI APIKey时,使用AI答案 + if self.ai_api_key: + ai_answer = self.get_ai_answer(question) + if ai_answer: + self.log(f"使用AI答案: {ai_answer}") + return ai_answer + + # 4. 随机选择答案(排除错误答案) + answer = self.get_random_answer() + self.log(f"随机答题,答案: {answer}") + return answer + + def get_random_answer(self) -> str: + """获取随机答案,排除已知错误答案""" + available_answers = set(["A", "B", "C", "D"]) - self.wrong_answers + if not available_answers: + self.wrong_answers.clear() + available_answers = set(["A", "B", "C", "D"]) + return random.choice(list(available_answers)) + + def get_answered_question(self) -> None: + """从已答题账号获取答案""" + params = {"date": datetime.now().strftime("%Y%m%d")} + response = self.make_request("GET", self.API_QUESTION_INFO, params=params) + print(f"get_answered_question API response ——> {response}") + if response["code"] != 0: + self.log(f'❌ 从已答题账号获取问题失败: {response["msg"]}') + return + # response['data']['state'] 1=表示未答题 2=已答题且正确 4=已答题但错误 + if response["code"] == 0 and response["data"].get("answer"): + answer = response["data"]["answer"][0] + if answer in ["A", "B", "C", "D"]: + self.correct_answer = answer + self.log(f"从已答题账号获取到答案:{answer}") + return + self.log("从已答题账号获取答案失败") + + def submit_question_answer( + self, question_id: str, answer: str, share_user_hid: str + ) -> None: + """提交答题答案""" + json_data = { + "answer": answer, + "questions_hid": question_id, + "ctu_token": "", + } + if share_user_hid: + json_data["date"] = datetime.now().strftime("%Y%m%d") + json_data["share_user_hid"] = share_user_hid + + response = self.make_request("POST", self.API_QUESTION_SUBMIT, json=json_data) + print(f"submit_question_answer API response ——> {response}") + + if response["code"] == 0: + data = response["data"] + if data["state"] == 3: # 答错 + # 记录错误答案 + self.wrong_answers.add(answer) + # 如果是正确答案,清除它 + if self.correct_answer == answer: + self.correct_answer = "" + # 如果是预设答案,清除它 + if self.preset_answer == answer: + self.preset_answer = "" + self.log("❌ 答题错误") + elif data["state"] == 2: # 答对了 + if self.correct_answer != answer: + self.correct_answer = answer + score = data["answer_score"] + self.log(f"✅ 答题正确 | 积分 +{score}") + else: + self.log(f'❌ 答题失败: {response["msg"]}') + + def get_backup_share_hid(self, user_hid: str) -> str: + """从备用 hid 列表中获取一个不同于用户自身的 hid""" + available_hids = [hid for hid in self.BACKUP_HIDS if hid != user_hid] + return random.choice(available_hids) if available_hids else "" + + def run(self) -> None: + """运行主程序""" + # 使用列表保持顺序,使用集合实现去重 + tokens = [] + tokens_set = set() + + # 方式1: 从BJXD环境变量获取(逗号分隔的多个token) + token_str = os.getenv("BJXD") + if token_str: + # 过滤空值并保持顺序添加 + for token in token_str.split(","): + token = token.strip() + if token and token not in tokens_set: + tokens.append(token) + tokens_set.add(token) + + # 方式2: 从BJXD1/BJXD2/BJXD3等环境变量获取 + i = 1 + empty_count = 0 # 记录连续空值的数量 + while empty_count < 5: # 连续5个空值才退出 + token = os.getenv(f"BJXD{i}") + if not token: + empty_count += 1 + else: + token = token.strip() + if token and token not in tokens_set: # 确保token不是空字符串且未重复 + empty_count = 0 # 重置连续空值计数 + tokens.append(token) + tokens_set.add(token) + i += 1 + + if not tokens: + self.log( + "⛔️ 未获取到 tokens, 请检查环境变量 BJXD 或 BJXD1/BJXD2/... 是否填写" + ) + self.push_notification() + return + + self.log(f"👻 共获取到用户 token {len(tokens)} 个") + + self.ai_api_key = os.getenv("HUNYUAN_API_KEY", "") + self.log( + "💯 已获取到腾讯混元 AI APIKey, 使用腾讯混元 AI 答题" + if self.ai_api_key + else "😭 未设置腾讯混元 AI HUNYUAN_API_KEY 环境变量,使用随机答题" + ) + + # 获取预设答案 + self.preset_answer = os.getenv("BJXD_ANSWER", "").upper() + if self.preset_answer: + if self.preset_answer in ["A", "B", "C", "D"]: + self.log(f"📝 已获取预设答案: {self.preset_answer}") + else: + self.preset_answer = "" + self.log("❌ 预设答案格式错误,仅支持 A/B/C/D") + + # 获取所有用户信息 + for token in tokens: + self.token = token + user = self.get_user_info() + if user: + self.users.append(user) + + if not self.users: + self.log("❌ 未获取到有效用户") + return + + # 设置分享用户ID + for i, user in enumerate(self.users): + prev_index = (i - 1) if i > 0 else len(self.users) - 1 + # 如果有多个用户且上一个用户不是自己,使用上一个用户的 hid + if len(self.users) > 1 and self.users[prev_index]["hid"] != user["hid"]: + user["share_user_hid"] = self.users[prev_index]["hid"] + else: + # 否则从备用 hid 列表中选择一个 + user["share_user_hid"] = self.get_backup_share_hid(user["hid"]) + + # 执行任务 + self.log("\n============ 执行任务 ============") + for i, user in enumerate(self.users, 1): + # 更新当前用户信息 + self.token = user["token"] + self.user = user + + # 随机延迟 + if i > 1: + print("\n进行下一个账号, 等待 5-10 秒...") + time.sleep(random.randint(5, 10)) + + self.log(f"\n======== ▷ 第 {i} 个账号 ◁ ========") + + # 打印用户信息 + self.log( + f"👻 用户名: {self.user['nickname']} | " + f"手机号: {self.user['phone']} | " + f"积分: {self.user['score_value']}\n" + f"🆔 用户hid: {self.user['hid']}\n" + f"🆔 分享hid: {self.user['share_user_hid']}" + ) + + # 检查任务状态 + self.check_task_status(self.user) + self.log(f"任务状态: {self.user['task']}") + + # 调试使用 设置任务状态 + # self.user["task"]["sign"] = False + # self.user["task"]["view"] = False + # self.user["task"]["question"] = False + + # 签到 + if not self.user["task"]["sign"]: + self.get_sign_info() + time.sleep(random.randint(5, 10)) + else: + self.log("✅ 签到任务 已完成,跳过") + + # 阅读文章 + if not self.user["task"]["view"]: + article_ids = self.get_article_list() + if article_ids: + for article_id in article_ids: # 已经只有3篇了 + self.get_article_detail(article_id) + time.sleep(random.randint(10, 15)) + self.submit_article_score() + else: + self.log("✅ 浏览文章任务 已完成,跳过") + + # 答题 + if not self.user["task"]["question"]: + self.get_question_info(self.user["share_user_hid"]) + else: + self.log("✅ 答题任务 已完成,跳过") + if not self.correct_answer: + self.get_answered_question() + + self.log("\n============ 积分详情 ============") + for i, user in enumerate(self.users, 1): + if i > 1: + print("\n进行下一个账号, 等待 5-10 秒...") + time.sleep(random.randint(5, 10)) + + # 更新当前用户信息 + self.token = user["token"] + self.user = user + + self.log(f"\n======== ▷ 第 {i} 个账号 ◁ ========") + + # 打印用户信息 + self.log( + f"👻 用户名: {self.user['nickname']} | 手机号: {self.user['phone']}" + ) + + # 显示积分详情 + self.get_score_details() + + # 最后推送通知 + self.push_notification() + + +if __name__ == "__main__": + BeiJingHyundai().run() \ No newline at end of file