const config = { "PATH_IMG_V2_PRO": "https://cdn-image.gandart.com/", "RUN_TYPE": 1, "BOTTOM_LOAD_MORE_THROTTLE": 100, "BASE_API": "https://api.gandart.com/base", "RESALE_API": "https://api.gandart.com/market", "RESALE_API_V2": "https://api2.gandart.com/market/api/v2", "RESALE_API_V3": "https://api2.gandart.com/market/api/v3", "SALE_API": "https://api.gandart.com/read/api", "ORDER_API": "https://api.gandart.com", "WALLET_API": "https://api.gandart.com/api", "HXT_API": "https://api.gandart.com/wallet", "PATH_IMG_V2": "https://cdn-image.gandart.com/", "SAND_RECHARGE_ACTION": "https://cap.sandpay.com.cn/v4/front-electrans/ceas.elec.trans.quick.deposit.apply", "GAME_ElF_API": "https://elf.pentajam.cn/api", "GAME_ELF_URL": "https://elf.pentajam.cn", "CORECENTER_URL": "https://api.gandart.com/corecenter" }; const lk = new ToolKit(`光予助手`, `GandartHelper`, `gandartHelper.js`); const gandartTokenKey = 'lkGandartToken'; const gardartCollectionNameKey = 'lkGandartCollectionName'; const gardartCastingIdKey = 'lkGandartCastingId'; const gardartLimitPriceKey = 'lkGandartLimitPrice'; const gandartTransactionRecordIdKey = 'lkGandartTransactionRecordId'; const gandartCollectionCateLstKey = 'lkGandartCollectionCateLst'; let gandartToken = lk.getVal(gandartTokenKey, ''); const GCommonGandartHeads = { 'Accept': `application/json, text/plain, */*`, 'Origin': `https://www.gandart.com`, 'Accept-Encoding': `gzip, deflate, br`, 'Content-Type': `application/x-www-form-urlencoded;charset=UTF-8`, 'Connection': `keep-alive`, 'Host': `api2.gandart.com`, 'User-Agent': `Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1`, 'Referer': `https://www.gandart.com/`, 'Accept-Language': `zh-CN,zh-Hans;q=0.9`, 'token': gandartToken }; if (!lk.isExecComm) { if (lk.isRequest()) { checkHanldeRequest(); lk.done(); } else { all(); } } function checkHanldeRequest() { const url = $request.url; const path = lk.getUrlPath(url); lk.log(`请求url=${url}#${$request.method}`); lk.log(`请求body=${$request.body}`); if ($request && $request.method != 'OPTIONS') { switch(path){ case `base/auth/verifyCodeLogin`: handleVerifyCodeLogin(); break; case `base/v2/resaleManage/resale/findAllIsOpenResale`: handleFindAllIsOpenResale(); break; case `base/v2/favorite/selectRecord`: // handleSelectRecord(); break; case `market/api/v3/resaleManage/resale/tradingMarket`: handleTradingMarket(); break; case `market/api/v2/resaleManage/resale/collectionDetailsByCastingId`: handleCollectionDetailsByCastingId(); break; default: break; } } } function handleVerifyCodeLogin(){ lk.log(`开始获取Token`); let data = lk.getResponseBody(); try { data = JSON.parse(data); if (data.success) { let jwktoken = data.obj.token; lk.setVal(gandartTokenKey, jwktoken); lk.appendNotifyInfo('🎉成功获取光予token,可以关闭相应脚本'); } else { lk.execFail(); lk.appendNotifyInfo('❌获取光予token失败,请稍后再试'); } } catch (e) { lk.execFail(); lk.appendNotifyInfo('❌获取光予token失败'); } lk.msg(''); } function handleFindAllIsOpenResale(){ lk.log(`获取最新产品开放在售列表`); let data = lk.getResponseBody(); try { data = JSON.parse(data); if (data.success) { let obj = data.obj; let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]')); let pageItemlst = obj; let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst); let jsonStr = JSON.stringify(newLst); lk.setVal(gandartCollectionCateLstKey, jsonStr); lk.log(jsonStr); } } catch (e) { lk.logErr(e); lk.execFail(); } lk.msg(''); } function handleSelectRecord(){ lk.log(`获取收藏的产品列表`); let data = lk.getResponseBody(); try { data = JSON.parse(data); if (data.success) { let obj = data.obj; let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]')); let pageItemlst = obj; let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst); let jsonStr = JSON.stringify(newLst); lk.setVal(gandartCollectionCateLstKey, jsonStr); lk.log(jsonStr); } } catch (e) { lk.logErr(e); lk.execFail(); } lk.msg(''); } function handleTradingMarket(){ lk.log(`获取最新Token并更新产品列表`); if ($request.headers.token) { let jwktoken = $request.headers.token; lk.setVal(gandartTokenKey, jwktoken); } let data = lk.getResponseBody(); try { data = JSON.parse(data); if (data.success) { let obj = data.obj; let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]')); let pageItemlst = obj.list; let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst); let jsonStr = JSON.stringify(newLst); lk.setVal(gandartCollectionCateLstKey, jsonStr); lk.log(jsonStr); } } catch (e) { lk.logErr(e); lk.execFail(); } lk.msg(''); } function handleCollectionDetailsByCastingId(){ lk.log(`开始获取产品信息`); let data = lk.getResponseBody(); try { data = JSON.parse(data); if (data["success"]) { let obj = data["obj"]; let castingId = String(obj["castingId"]); if (castingId == "") { // 无法获取请求体 let body = $request.body; } if (castingId != "") { lk.setVal(gardartCastingIdKey, castingId); let collectionName = obj["collectionName"]; lk.setVal(gardartCollectionNameKey, collectionName); lk.log(collectionName + " castingId=" + obj["castingId"]); lk.appendNotifyInfo(`🎉成功获取[${collectionName}]信息`); } else { lk.appendNotifyInfo('❌获取产品信息失败'); } } else { lk.execFail(); lk.appendNotifyInfo('❌获取产品信息失败,请稍后再试'); } } catch (e) { lk.logErr(e); lk.execFail(); lk.appendNotifyInfo('❌获取产品信息失败'); } lk.msg(''); } function checkAppendCollectionItemsDiff(cLst, pageLst) { let dic = {}; for (const d of cLst) { dic[d.castingId] = d; } for (const d of pageLst) { dic[d.castingId] = Object.assign(d || {}, dic[d.castingId]); } let newLst = []; for (let k in dic) { let ele = { castingId: dic[k].castingId, collectionName: dic[k].collectionName, resalePrice: dic[k].resalePrice || 0, }; newLst.push(ele); } return newLst; } function getCollectionNameById(castingId) { let name = '未获取'; let clst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, "[]")); for (const d of clst) { if (d.castingId == castingId) { name = d.collectionName; break; } } return name; } function getCurCollectionName() { let collectionName = lk.setVal(gardartCollectionNameKey, ""); return collectionName; } async function all() { let hasNeedSendNotify = true; if (gandartToken == '') { lk.execFail(); lk.appendNotifyInfo(`⚠️请先打开光予登录获取token`); } else { let castingId = lk.getVal(gardartCastingIdKey, 0); castingId = Number(castingId); let price = lk.getVal(gardartLimitPriceKey, 0); price = Number(price); if (castingId <= 0) { lk.prependNotifyInfo('⚠️请设置产品品类'); hasNeedSendNotify = true; } else if (price <= 0) { lk.prependNotifyInfo('⚠️请设置监控价格'); hasNeedSendNotify = true; } else { let item = await refreshLstOnSale(castingId, price); if (item) { hasNeedSendNotify = await checkToBuy(item); } else { hasNeedSendNotify = false; } } } if (hasNeedSendNotify) { lk.msg(``); } lk.done(); } function refreshLstOnSale(castingId, price) { return new Promise((resolve, _reject) => { try { const headers = GCommonGandartHeads; headers.Host = "api2.gandart.com"; let signData = getSign(); signData.castingId = castingId; signData.page = 1; signData.pageSize = 15; signData.sort = 2;// 1=编号,2=价格 signData.transactionStatus = 2; let body = objToUrlParams(signData); let url = { url: `${config.RESALE_API_V2}/resaleManage/resale/onSale`, headers: headers, body: body }; let collectionName = getCollectionNameById(castingId) lk.log(`请求产品[${collectionName}(${castingId})]寄售列表:${body}`); lk.post(url, async (error, _response, data) => { let retItem; try { if (error) { lk.log(`获取寄售列表信息发生错误`); lk.execFail(); lk.appendNotifyInfo(`❌获取寄售列表失败,请稍后再试`); } else { let ret = JSON.parse(data); let minPrice = 9999999; if (ret.success) { let obj = ret.obj; let lst = obj.list; for (let d of lst) { if (d.transactionStatus == 2) {//2=可购买,4=支付中 const resalePrice = Number(d.resalePrice); if (minPrice > resalePrice) { minPrice = resalePrice; } if (price >= resalePrice) { retItem = d; lk.appendNotifyInfo(`🎉成功匹配产品[${d.collectionName}#${d.viewSort}],价格:${d.resalePrice}`); break; } } } if (!retItem) { lk.log(`无匹配的价格,当前[${collectionName}]最低价:${minPrice}`); } } else { lk.execFail(); } } } catch (e) { lk.log(`获取寄售列表信息失败`); lk.logErr(e); lk.execFail(); } finally { resolve(retItem); } }); } catch (e) { lk.log(`获取寄售列表信息发生错误`); lk.logErr(e); resolve(); } }); } function checkToBuy(item) { return new Promise((resolve, _reject) => { try { const id = item.id; const viewSort = item.viewSort || 0; const headers = GCommonGandartHeads; headers.Host = "api.gandart.com"; const body = `transactionRecordId=${id}`; let url = { url: `${config.BASE_API}/v2/resaleManage/resale/buy/v2`, headers: headers, body: body }; lk.log(`请求购买产品[${item.collectionName}#${viewSort}]=${body}`); // resolve(1); const collectionName = item.collectionName; lk.post(url, async (error, _response, data) => { let retItem; try { if (error) { lk.log(`无法下单产品[${collectionName}#${viewSort}]`); lk.execFail(); lk.appendNotifyInfo(`❌购买失败,请稍后再试`); } else { lk.log(data); let ret = JSON.parse(data); if (ret.success) { let obj = ret.obj; let orderNum = obj.orderNum; if (orderNum && orderNum.length > 0) { retItem = ret; lk.log(`成功下单产品[${obj.collectionName}#${viewSort}],订单号:${obj.orderNum}`); lk.appendNotifyInfo(`🎉成功下单产品[${obj.collectionName}#${viewSort}],订单号:${obj.orderNum}`); } } else { lk.log(`产品[${collectionName}#${viewSort}]下单失败`); lk.execFail(); } } } catch (e) { lk.log(`下单产品[${collectionName}#${viewSort}]发生错误`); lk.logErr(e); lk.execFail(); } finally { resolve(retItem); } }); } catch (e) { lk.log(`下单产品[${item.collectionName}#${item.viewSort}]发生错误`); lk.logErr(e); resolve(); } }); } function objToUrlParams(param, key, encode) { let paramStr = urlEncode(param, key, encode); let len = paramStr.length; if (len > 0) { paramStr = paramStr.substring(1, len); } return paramStr; } function urlEncode(param, key, encode) { if (param == null) return ''; let paramStr = ''; let t = typeof (param); if (t == 'string' || t == 'number' || t == 'boolean') { paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param); } else { for (let i in param) { let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i); paramStr += urlEncode(param[i], k, encode); } } return paramStr; } function getSign() { const now = new Date().getTime(); const s1 = now - 20000; const s2 = now; const s3 = now + 20000; const s4 = now + 40000; const sssfffeee = 'e9'; //localStorage.getItem('sssfffeee'); const aggaaa = '9'; //localStorage.getItem('aggaaa'); const yyhhhasdww = '0a'; let arr = [sssfffeee, yyhhhasdww, aggaaa, '29', 'e', 'c', 3]; let crypto = Crypto(); let s5 = crypto.md5(s3 + arr.join('')); return { 's1': s1, 's2': s2, 's3': s3, 's4': s4, 's5': s5 }; } // https://github.com/lowking/Scripts/blob/master/util/ToolKit.min.js //ToolKit-start function ToolKit(scriptName,scriptId,options){return new class{constructor(scriptName,scriptId,options){this.tgEscapeCharMapping={"&":"&","#":"#"},this.userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15",this.prefix="lk",this.name=scriptName,this.id=scriptId,this.data=null,this.dataFile=this.getRealPath(`${this.prefix}${this.id}.dat`),this.boxJsJsonFile=this.getRealPath(`${this.prefix}${this.id}.boxjs.json`),this.options=options,this.isExecComm=!1,this.isEnableLog=this.getVal(`${this.prefix}IsEnableLog${this.id}`),this.isEnableLog=!!this.isEmpty(this.isEnableLog)||JSON.parse(this.isEnableLog),this.isNotifyOnlyFail=this.getVal(`${this.prefix}NotifyOnlyFail${this.id}`),this.isNotifyOnlyFail=!this.isEmpty(this.isNotifyOnlyFail)&&JSON.parse(this.isNotifyOnlyFail),this.isEnableTgNotify=this.getVal(`${this.prefix}IsEnableTgNotify${this.id}`),this.isEnableTgNotify=!this.isEmpty(this.isEnableTgNotify)&&JSON.parse(this.isEnableTgNotify),this.tgNotifyUrl=this.getVal(`${this.prefix}TgNotifyUrl${this.id}`),this.isEnableTgNotify=this.isEnableTgNotify?!this.isEmpty(this.tgNotifyUrl):this.isEnableTgNotify,this.costTotalStringKey=`${this.prefix}CostTotalString${this.id}`,this.costTotalString=this.getVal(this.costTotalStringKey),this.costTotalString=this.isEmpty(this.costTotalString)?"0,0":this.costTotalString.replace('"',""),this.costTotalMs=this.costTotalString.split(",")[0],this.execCount=this.costTotalString.split(",")[1],this.costTotalMs=this.isEmpty(this.costTotalMs)?0:parseInt(this.costTotalMs),this.execCount=this.isEmpty(this.execCount)?0:parseInt(this.execCount),this.logSeparator="\n██",this.now=new Date,this.startTime=this.now.getTime(),this.node=(()=>{if(this.isNode()){const request=require("request");return{request:request}}return null})(),this.execStatus=!0,this.notifyInfo=[],this.log(`${this.name}, 开始执行!`),this.initCache(),this.execComm()}initCache(){const pKey=this.getPersistKey();if(this.isQuanX()&&(this.cache=JSON.parse($prefs.valueForKey(pKey)||"{}")),(this.isLoon()||isSurge)&&(this.cache=JSON.parse($persistentStore.read(pKey)||"{}")),this.isNode()){let fpath="root.json";this.node.fs.existsSync(fpath)||this.node.fs.writeFileSync(fpath,JSON.stringify({}),{flag:"wx"},err=>console.log(err)),this.root={},fpath=`${pKey}.json`,this.node.fs.existsSync(fpath)?this.cache=JSON.parse(this.node.fs.readFileSync(`${pKey}.json`)):(this.node.fs.writeFileSync(fpath,JSON.stringify({}),{flag:"wx"},err=>console.log(err)),this.cache={})}}getPersistKey(){return`private_${this.id}`}persistCache(){const pKey=this.getPersistKey(),data=JSON.stringify(this.cache,null,2);this.isQuanX()&&$prefs.setValueForKey(data,pKey),(this.isLoon()||this.isSurge())&&$persistentStore.write(data,pKey),this.isNode()&&(this.node.fs.writeFileSync(`${pKey}.json`,data,{flag:"w"},err=>console.log(err)),this.node.fs.writeFileSync("root.json",JSON.stringify(this.root,null,2),{flag:"w"},err=>console.log(err)))}write(data,key){if(this.log(`SET ${key}`),-1!==key.indexOf("#")){if(key=key.substr(1),isSurge||this.isLoon())return $persistentStore.write(data,key);if(this.isQuanX())return $prefs.setValueForKey(data,key);this.isNode()&&(this.root[key]=data)}else this.cache[key]=data;this.persistCache()}read(key){return this.log(`READ ${key}`),-1===key.indexOf("#")?this.cache[key]:(key=key.substr(1),this.isSurge()||this.isLoon()?$persistentStore.read(key):this.isQuanX()?$prefs.valueForKey(key):this.isNode()?this.root[key]:void 0)}delete(key){if(this.log(`DELETE ${key}`),-1!==key.indexOf("#")){if(key=key.substr(1),this.isSurge()||this.isLoon())return $persistentStore.write(null,key);if(this.isQuanX())return $prefs.removeValueForKey(key);this.isNode()&&delete this.root[key]}else delete this.cache[key];this.persistCache()}getRealPath(fileName){if(this.isNode()){let targetPath=process.argv.slice(1,2)[0].split("/");return targetPath[targetPath.length-1]=fileName,targetPath.join("/")}return fileName}getUrlHost(url){return url.slice(0,url.indexOf("/",8))}getUrlPath(url){const end=url.lastIndexOf("/")===url.length-1?-1:void 0;return url.slice(url.indexOf("/",8),end)}async execComm(){if(this.isNode()){this.comm=process.argv.slice(1);let isHttpApiErr=!1;"p"==this.comm[1]&&(this.isExecComm=!0,this.log(`开始执行指令【${this.comm[1]}】=> 发送到手机测试脚本!`),this.isEmpty(this.options)||this.isEmpty(this.options.httpApi)?(this.log("未设置options,使用默认值"),this.isEmpty(this.options)&&(this.options={}),this.options.httpApi="ffff@10.0.0.9:6166"):/.*?@.*?:[0-9]+/.test(this.options.httpApi)||(isHttpApiErr=!0,this.log("❌httpApi格式错误!格式:ffff@3.3.3.18:6166"),this.done()),isHttpApiErr||this.callApi(this.comm[2]))}}callApi(timeout){let fname=this.comm[0];this.log(`获取【${fname}】内容传给手机`);let scriptStr="";this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const curDirDataFilePath=this.path.resolve(fname),rootDirDataFilePath=this.path.resolve(process.cwd(),fname),isCurDirDataFile=this.fs.existsSync(curDirDataFilePath),isRootDirDataFile=!isCurDirDataFile&&this.fs.existsSync(rootDirDataFilePath);if(isCurDirDataFile||isRootDirDataFile){const datPath=isCurDirDataFile?curDirDataFilePath:rootDirDataFilePath;try{scriptStr=this.fs.readFileSync(datPath)}catch(e){scriptStr=""}}else scriptStr="";let options={url:`http://${this.options.httpApi.split("@")[1]}/v1/scripting/evaluate`,headers:{"X-Key":`${this.options.httpApi.split("@")[0]}`},body:{script_text:`${scriptStr}`,mock_type:"cron",timeout:!this.isEmpty(timeout)&&timeout>5?timeout:5},json:!0};this.post(options,(_error,_response,_data)=>{this.log(`已将脚本【${fname}】发给手机!`),this.done()})}getCallerFileNameAndLine(){let error;try{throw Error("")}catch(err){error=err}const stack=error.stack,stackArr=stack.split("\n");let callerLogIndex=1;{const callerStackLine=stackArr[1];return this.path=this.path?this.path:require("path"),`[${callerStackLine.substring(callerStackLine.lastIndexOf(this.path.sep)+1,callerStackLine.lastIndexOf(":"))}]`}}getFunName(fun){var ret=fun.toString();return ret=(ret=ret.substr("function ".length)).substr(0,ret.indexOf("("))}boxJsJsonBuilder(info,param){if(this.isNode()){let boxjsJsonPath="/Users/lowking/Desktop/Scripts/lowking.boxjs.json";if(param&¶m.hasOwnProperty("target_boxjs_json_path")&&(boxjsJsonPath=param.target_boxjs_json_path),!this.fs.existsSync(boxjsJsonPath))return;if(!this.isJsonObject(info)||!this.isJsonObject(param))return void this.log("构建BoxJsJson传入参数格式错误,请传入json对象");this.log("using node");let needAppendKeys=["settings","keys"];const domain="https://raw.githubusercontent.com/Orz-3";let boxJsJson={},scritpUrl="#lk{script_url}";if(param&¶m.hasOwnProperty("script_url")&&(scritpUrl=this.isEmpty(param.script_url)?"#lk{script_url}":param.script_url),boxJsJson.id=`${this.prefix}${this.id}`,boxJsJson.name=this.name,boxJsJson.desc_html=`⚠️使用说明
详情【点我查看】`,boxJsJson.icons=[`${domain}/mini/master/Alpha/${this.id.toLocaleLowerCase()}.png`,`${domain}/mini/master/Color/${this.id.toLocaleLowerCase()}.png`],boxJsJson.keys=[],boxJsJson.settings=[{id:`${this.prefix}IsEnableLog${this.id}`,name:"开启/关闭日志",val:!0,type:"boolean",desc:"默认开启"},{id:`${this.prefix}NotifyOnlyFail${this.id}`,name:"只当执行失败才通知",val:!1,type:"boolean",desc:"默认关闭"},{id:`${this.prefix}IsEnableTgNotify${this.id}`,name:"开启/关闭Telegram通知",val:!1,type:"boolean",desc:"默认关闭"},{id:`${this.prefix}TgNotifyUrl${this.id}`,name:"Telegram通知地址",val:"",type:"text",desc:"Tg的通知地址,如:https://api.telegram.org/bot-token/sendMessage?chat_id=-100140&parse_mode=Markdown&text="}],boxJsJson.author="#lk{author}",boxJsJson.repo="#lk{repo}",boxJsJson.script=`${scritpUrl}?raw=true`,!this.isEmpty(info))for(let i in needAppendKeys){let key=needAppendKeys[i];if(!this.isEmpty(info[key])){if("settings"===key)for(let i=0;i0){let apps=boxjsJson.apps,targetIdx=apps.indexOf(apps.filter(app=>app.id==boxJsJson.id)[0]);targetIdx>=0?boxjsJson.apps[targetIdx]=boxJsJson:boxjsJson.apps.push(boxJsJson);let ret=JSON.stringify(boxjsJson,null,2);if(!this.isEmpty(param))for(const key in param){let val="";param.hasOwnProperty(key)?val=param[key]:"author"===key?val="@lowking":"repo"===key&&(val="https://github.com/lowking/Scripts"),ret=ret.replace(`#lk{${key}}`,val)}const regex=/(?:#lk\{)(.+?)(?=\})/;let m=regex.exec(ret);null!==m&&this.log("生成BoxJs还有未配置的参数,请参考https://github.com/lowking/Scripts/blob/master/util/example/ToolKitDemo.js#L17-L18传入参数:\n");let loseParamSet=new Set;for(;null!==(m=regex.exec(ret));)loseParamSet.add(m[1]),ret=ret.replace(`#lk{${m[1]}}`,"");loseParamSet.forEach(p=>{console.log(`${p} `)}),this.fs.writeFileSync(boxjsJsonPath,ret)}}}}isJsonObject(obj){return"object"==typeof obj&&"[object object]"==Object.prototype.toString.call(obj).toLowerCase()&&!obj.length}appendNotifyInfo(info,type){1==type?this.notifyInfo=info:this.notifyInfo.push(info)}prependNotifyInfo(info){this.notifyInfo.splice(0,0,info)}execFail(){this.execStatus=!1}isRequest(){return"undefined"!=typeof $request}isSurge(){return"undefined"!=typeof $httpClient}isQuanX(){return"undefined"!=typeof $task}isLoon(){return"undefined"!=typeof $loon}isJSBox(){return"undefined"!=typeof $app&&"undefined"!=typeof $http}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}isNode(){return"function"==typeof require&&!this.isJSBox()}sleep(time){return new Promise(resolve=>setTimeout(resolve,time))}log(message){this.isEnableLog&&console.log(`${this.logSeparator}${message}`)}logErr(message){this.execStatus=!0,this.isEnableLog&&(console.log(`${this.logSeparator}${this.name}执行异常:`),console.log(message),console.log(`\n${message.message}`))}msg(subtitle,message,openUrl,mediaUrl){if(!this.isRequest()&&this.isNotifyOnlyFail&&this.execStatus);else if(this.isEmpty(message)&&(message=Array.isArray(this.notifyInfo)?this.notifyInfo.join("\n"):this.notifyInfo),!this.isEmpty(message))if(this.isEnableTgNotify){this.log(`${this.name}Tg通知开始`);for(let key in this.tgEscapeCharMapping)this.tgEscapeCharMapping.hasOwnProperty(key)&&(message=message.replace(key,this.tgEscapeCharMapping[key]));this.get({url:encodeURI(`${this.tgNotifyUrl}📌${this.name}\n${message}`)},(_error,_statusCode,_body)=>{this.log("Tg通知完毕")})}else{let options={};const hasOpenUrl=!this.isEmpty(openUrl),hasMediaUrl=!this.isEmpty(mediaUrl);this.isQuanX()&&(hasOpenUrl&&(options["open-url"]=openUrl),hasMediaUrl&&(options["media-url"]=mediaUrl),$notify(this.name,subtitle,message,options)),(this.isSurge()||this.isStash())&&(hasOpenUrl&&(options.url=openUrl),$notification.post(this.name,subtitle,message,options)),this.isNode()&&this.log("⭐️"+this.name+"\n"+subtitle+"\n"+message),this.isJSBox()&&$push.schedule({title:this.name,body:subtitle?subtitle+"\n"+message:message})}}getVal(key,defaultValue=""){let value;return this.isSurge()||this.isLoon()||this.isStash()?value=$persistentStore.read(key):this.isQuanX()?value=$prefs.valueForKey(key):this.isNode()?(this.data=this.loadData(),value=process.env[key]||this.data[key]):value=this.data&&this.data[key]||null,value||defaultValue}setVal(key,val){return this.isSurge()||this.isLoon()||this.isStash()?$persistentStore.write(val,key):this.isQuanX()?$prefs.setValueForKey(val,key):this.isNode()?(this.data=this.loadData(),this.data[key]=val,this.writeData(),!0):this.data&&this.data[key]||null}loadData(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const curDirDataFilePath=this.path.resolve(this.dataFile),rootDirDataFilePath=this.path.resolve(process.cwd(),this.dataFile),isCurDirDataFile=this.fs.existsSync(curDirDataFilePath),isRootDirDataFile=!isCurDirDataFile&&this.fs.existsSync(rootDirDataFilePath);if(!isCurDirDataFile&&!isRootDirDataFile)return{};{const datPath=isCurDirDataFile?curDirDataFilePath:rootDirDataFilePath;try{return JSON.parse(this.fs.readFileSync(datPath))}catch(e){return{}}}}}writeData(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const curDirDataFilePath=this.path.resolve(this.dataFile),rootDirDataFilePath=this.path.resolve(process.cwd(),this.dataFile),isCurDirDataFile=this.fs.existsSync(curDirDataFilePath),isRootDirDataFile=!isCurDirDataFile&&this.fs.existsSync(rootDirDataFilePath),jsondata=JSON.stringify(this.data);isCurDirDataFile?this.fs.writeFileSync(curDirDataFilePath,jsondata):isRootDirDataFile?this.fs.writeFileSync(rootDirDataFilePath,jsondata):this.fs.writeFileSync(curDirDataFilePath,jsondata)}}adapterStatus(response){return response&&(response.status?response.statusCode=response.status:response.statusCode&&(response.status=response.statusCode)),response}get(options,callback=(()=>{})){this.isQuanX()&&("string"==typeof options&&(options={url:options}),options.method="GET",$task.fetch(options).then(response=>{callback(null,this.adapterStatus(response),response.body)},reason=>callback(reason.error,null,null))),(this.isSurge()||this.isLoon()||this.isStash())&&$httpClient.get(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)}),this.isNode()&&this.node.request(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)}),this.isJSBox()&&("string"==typeof options&&(options={url:options}),options.header=options.headers,options.handler=function(resp){let error=resp.error;error&&(error=JSON.stringify(resp.error));let body=resp.data;"object"==typeof body&&(body=JSON.stringify(resp.data)),callback(error,this.adapterStatus(resp.response),body)},$http.get(options))}post(options,callback=(()=>{})){this.isQuanX()&&("string"==typeof options&&(options={url:options}),options.method="POST",$task.fetch(options).then(response=>{callback(null,this.adapterStatus(response),response.body)},reason=>callback(reason.error,null,null))),(this.isSurge()||this.isLoon()||this.isStash())&&$httpClient.post(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)}),this.isNode()&&this.node.request.post(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)}),this.isJSBox()&&("string"==typeof options&&(options={url:options}),options.header=options.headers,options.handler=function(resp){let error=resp.error;error&&(error=JSON.stringify(resp.error));let body=resp.data;"object"==typeof body&&(body=JSON.stringify(resp.data)),callback(error,this.adapterStatus(resp.response),body)},$http.post(options))}put(options,callback=(()=>{})){this.isQuanX()&&("string"==typeof options&&(options={url:options}),options.method="PUT",$task.fetch(options).then(response=>{callback(null,this.adapterStatus(response),response.body)},reason=>callback(reason.error,null,null))),(this.isSurge()||this.isLoon()||this.isStash())&&(options.method="PUT",$httpClient.put(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)})),this.isNode()&&(options.method="PUT",this.node.request.put(options,(error,response,body)=>{callback(error,this.adapterStatus(response),body)})),this.isJSBox()&&("string"==typeof options&&(options={url:options}),options.header=options.headers,options.handler=function(resp){let error=resp.error;error&&(error=JSON.stringify(resp.error));let body=resp.data;"object"==typeof body&&(body=JSON.stringify(resp.data)),callback(error,this.adapterStatus(resp.response),body)},$http.post(options))}costTime(){let info=`${this.name}执行完毕!`;this.isNode()&&this.isExecComm&&(info=`指令【${this.comm[1]}】执行完毕!`);const endTime=(new Date).getTime(),ms=endTime-this.startTime,costTime=ms/1e3;this.execCount++,this.costTotalMs+=ms,this.log(`${info}耗时【${costTime}】秒\n总共执行【${this.execCount}】次,平均耗时【${(this.costTotalMs/this.execCount/1e3).toFixed(4)}】秒`),this.setVal(this.costTotalStringKey,JSON.stringify(`${this.costTotalMs},${this.execCount}`))}done(value={}){this.costTime(),(this.isSurge()||this.isQuanX()||this.isLoon()||this.isStash())&&$done(value)}getRequestUrl(){return $request.url}getResponseBody(){return $response.body}isGetCookie(reg){return!("OPTIONS"==$request.method||!this.getRequestUrl().match(reg))}isEmpty(obj){return void 0===obj||null==obj||""==obj||"null"==obj||"undefined"==obj||0===obj.length}randomString(len){len=len||32;var $chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890",maxPos=$chars.length,pwd="";for(let i=0;i>> 32 - u, r) } function c(n, t, r, e, u, o, c) { return f(t & r | ~t & e, n, t, u, o, c) } function i(n, t, r, e, u, o, c) { return f(t & e | r & ~e, n, t, u, o, c) } function l(n, t, r, e, u, o, c) { return f(t ^ r ^ e, n, t, u, o, c) } function a(n, t, r, e, u, o, c) { return f(r ^ (t | ~e), n, t, u, o, c) } function t(n) { /[\x80-\xFF]/.test(n) && (n = unescape(encodeURI(n))), txt = ""; let t = n.length, r = [1732584193, -271733879, -1732584194, 271733878], e; for (e = 64; e <= n.length; e += 64)o(r, function (n) { let t = [], r; for (r = 0; r < 64; r += 4)t[r >> 2] = n.charCodeAt(r) + (n.charCodeAt(r + 1) << 8) + (n.charCodeAt(r + 2) << 16) + (n.charCodeAt(r + 3) << 24); return t }(n.substring(e - 64, e))); n = n.substring(e - 64); var u = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for (e = 0; e < n.length; e++)u[e >> 2] |= n.charCodeAt(e) << (e % 4 << 3); if (u[e >> 2] |= 128 << (e % 4 << 3), 55 < e) for (o(r, u), e = 0; e < 16; e++)u[e] = 0; return u[14] = 8 * t, o(r, u), r } let e = "0123456789abcdef".split(""); function r(t) { for (let n = 0; n < t.length; n++)t[n] = function (n) { let t = "", r = 0; for (; r < 4; r++)t += e[n >> 8 * r + 4 & 15] + e[n >> 8 * r & 15]; return t }(t[n]); return t.join("") } function h(n, t) { return n + t & 4294967295 } return { md5: function (n) { return r(t(n)) } } } //Crypto-end