gandartHelper.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. const config = {
  2. "PATH_IMG_V2_PRO": "https://cdn-image.gandart.com/",
  3. "RUN_TYPE": 1,
  4. "BOTTOM_LOAD_MORE_THROTTLE": 100,
  5. "BASE_API": "https://api.gandart.com/base",
  6. "RESALE_API": "https://api.gandart.com/market",
  7. "RESALE_API_V2": "https://api2.gandart.com/market/api/v2",
  8. "RESALE_API_V3": "https://api2.gandart.com/market/api/v3",
  9. "SALE_API": "https://api.gandart.com/read/api",
  10. "ORDER_API": "https://api.gandart.com",
  11. "WALLET_API": "https://api.gandart.com/api",
  12. "HXT_API": "https://api.gandart.com/wallet",
  13. "PATH_IMG_V2": "https://cdn-image.gandart.com/",
  14. "SAND_RECHARGE_ACTION": "https://cap.sandpay.com.cn/v4/front-electrans/ceas.elec.trans.quick.deposit.apply",
  15. "GAME_ElF_API": "https://elf.pentajam.cn/api",
  16. "GAME_ELF_URL": "https://elf.pentajam.cn",
  17. "CORECENTER_URL": "https://api.gandart.com/corecenter"
  18. };
  19. const lk = new ToolKit(`光予助手`, `GandartHelper`, `gandartHelper.js`);
  20. const gandartTokenKey = 'lkGandartToken';
  21. const gardartCollectionNameKey = 'lkGandartCollectionName';
  22. const gardartCastingIdKey = 'lkGandartCastingId';
  23. const gardartLimitPriceKey = 'lkGandartLimitPrice';
  24. const gandartTransactionRecordIdKey = 'lkGandartTransactionRecordId';
  25. const gandartCollectionCateLstKey = 'lkGandartCollectionCateLst';
  26. let gandartToken = lk.getVal(gandartTokenKey, '');
  27. const GCommonGandartHeads = {
  28. 'Accept' : `application/json, text/plain, */*`,
  29. 'Origin' : `https://www.gandart.com`,
  30. 'Accept-Encoding' : `gzip, deflate, br`,
  31. 'Content-Type' : `application/x-www-form-urlencoded;charset=UTF-8`,
  32. 'Connection' : `keep-alive`,
  33. 'Host' : `api2.gandart.com`,
  34. '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`,
  35. 'Referer' : `https://www.gandart.com/`,
  36. 'Accept-Language' : `zh-CN,zh-Hans;q=0.9`,
  37. 'token' : gandartToken
  38. };
  39. if(!lk.isExecComm) {
  40. if (lk.isRequest()) {
  41. getInfo();
  42. lk.done();
  43. } else {
  44. all();
  45. }
  46. }
  47. function getInfo() {
  48. const url = $request.url;
  49. lk.log(`开始url=`+url+":"+$request.method);
  50. if ($request && $request.method != 'OPTIONS') {
  51. if(url.match(/\/base\/auth\/verifyCodeLogin/)){
  52. lk.log(`开始获取Token`);
  53. let data = lk.getResponseBody();
  54. try {
  55. data = JSON.parse(data);
  56. if (data["success"]) {
  57. let jwktoken = data["obj"]["token"];
  58. lk.setVal(gandartTokenKey, jwktoken);
  59. lk.appendNotifyInfo('🎉成功获取光予token,可以关闭相应脚本');
  60. } else {
  61. lk.execFail();
  62. lk.appendNotifyInfo('❌获取光予token失败,请稍后再试');
  63. }
  64. } catch (e) {
  65. lk.execFail();
  66. lk.appendNotifyInfo('❌获取光予token失败');
  67. }
  68. lk.msg('');
  69. return;
  70. }
  71. if(url.match(/\/base\/v2\/resaleManage\/resale\/findAllIsOpenResale/)){
  72. lk.log(`获取最新产品开放在售列表`);
  73. let data = lk.getResponseBody();
  74. try {
  75. data = JSON.parse(data);
  76. if (data["success"]) {
  77. let obj = data["obj"];
  78. let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]'));
  79. let pageItemlst = obj;
  80. let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst);
  81. let jsonStr = JSON.stringify(newLst);
  82. lk.setVal(gandartCollectionCateLstKey, jsonStr);
  83. lk.log(jsonStr);
  84. }
  85. // lk.appendNotifyInfo('🎉更新了产品列表');
  86. } catch (e) {
  87. lk.logErr(e);
  88. lk.execFail();
  89. }
  90. lk.msg('');
  91. return;
  92. }
  93. // if(url.match(/\/base\/v2\/favorite\/selectRecord/)){
  94. // lk.log(`获取收藏的产品列表`);
  95. // let data = lk.getResponseBody();
  96. // try {
  97. // data = JSON.parse(data);
  98. // if (data["success"]) {
  99. // let obj = data["obj"];
  100. // let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]'));
  101. // let pageItemlst = obj;
  102. // let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst);
  103. // let jsonStr = JSON.stringify(newLst);
  104. // lk.setVal(gandartCollectionCateLstKey, jsonStr);
  105. // lk.log(jsonStr);
  106. // }
  107. // // lk.appendNotifyInfo('🎉更新了产品列表');
  108. // } catch (e) {
  109. // lk.logErr(e);
  110. // lk.execFail();
  111. // }
  112. // lk.msg('');
  113. // return;
  114. // }
  115. if(url.match(/\/market\/api\/v3\/resaleManage\/resale\/tradingMarket/)){
  116. lk.log(`获取最新Token并更新产品列表`);
  117. // lk.log(JSON.stringify($request.headers));
  118. if ($request.headers['token']) {
  119. let jwktoken = $request.headers['token'];
  120. lk.setVal(gandartTokenKey, jwktoken);
  121. // lk.appendNotifyInfo('🎉成功获取最新Token');
  122. }
  123. let data = lk.getResponseBody();
  124. try {
  125. data = JSON.parse(data);
  126. if (data["success"]) {
  127. let obj = data["obj"];
  128. let oldItemlst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, '[]'));
  129. let pageItemlst = obj["list"];
  130. let newLst = checkAppendCollectionItemsDiff(oldItemlst, pageItemlst);
  131. let jsonStr = JSON.stringify(newLst);
  132. lk.setVal(gandartCollectionCateLstKey, jsonStr);
  133. lk.log(jsonStr);
  134. }
  135. // lk.appendNotifyInfo('🎉更新了产品列表');
  136. } catch (e) {
  137. lk.logErr(e);
  138. lk.execFail();
  139. }
  140. lk.msg('');
  141. return;
  142. }
  143. if(url.match(/\/market\/api\/v2\/resaleManage\/resale\/collectionDetailsByCastingId/)){
  144. lk.log(`开始获取产品信息`);
  145. let data = lk.getResponseBody();
  146. try {
  147. data = JSON.parse(data);
  148. if (data["success"]) {
  149. let obj = data["obj"];
  150. let castingId = String(obj["castingId"]);
  151. if(castingId == ""){
  152. // 无法获取请求体
  153. }
  154. if(castingId != ""){
  155. lk.setVal(gardartCastingIdKey, castingId);
  156. let collectionName = obj["collectionName"];
  157. lk.setVal(gardartCollectionNameKey, collectionName);
  158. lk.log(collectionName+" castingId="+obj["castingId"]);
  159. lk.appendNotifyInfo(`🎉成功获取[${collectionName}]信息`);
  160. } else {
  161. lk.appendNotifyInfo('❌获取产品信息失败');
  162. }
  163. } else {
  164. lk.execFail();
  165. lk.appendNotifyInfo('❌获取产品信息失败,请稍后再试');
  166. }
  167. } catch (e) {
  168. lk.logErr(e);
  169. lk.execFail();
  170. lk.appendNotifyInfo('❌获取产品信息失败');
  171. }
  172. lk.msg('');
  173. return;
  174. }
  175. }
  176. }
  177. function copyDictTo(fromDic, toDic) {
  178. toDic = toDic || {};
  179. for(let k in fromDic){
  180. toDic[k] = fromDic[k];
  181. }
  182. return toDic;
  183. }
  184. function checkAppendCollectionItemsDiff(cLst, pageLst){
  185. let dic = {};
  186. for (const d of cLst) {
  187. dic[d.castingId] = d;
  188. }
  189. for (const d of pageLst) {
  190. dic[d.castingId] = copyDictTo(d, dic[d.castingId]);
  191. }
  192. let newLst = [];
  193. for(let k in dic){
  194. let ele = {
  195. castingId: dic[k].castingId,
  196. collectionName: dic[k].collectionName,
  197. resalePrice: dic[k].resalePrice || 0,
  198. };
  199. newLst.push(ele);
  200. }
  201. return newLst;
  202. }
  203. function getCollectionNameById(castingId) {
  204. let name = '未获取';
  205. let clst = JSON.parse(lk.getVal(gandartCollectionCateLstKey, "[]"));
  206. for (const d of clst) {
  207. if(d.castingId == castingId){
  208. name = d.collectionName;
  209. break;
  210. }
  211. }
  212. return name;
  213. }
  214. function getCurCollectionName() {
  215. let collectionName = lk.setVal(gardartCollectionNameKey, "");
  216. return collectionName;
  217. }
  218. async function all() {
  219. let hasNeedSendNotify = true;
  220. if (gandartToken == '') {
  221. lk.execFail();
  222. lk.appendNotifyInfo(`⚠️请先打开光予登录获取token`);
  223. } else {
  224. let castingId = lk.getVal(gardartCastingIdKey, 0);
  225. castingId = Number(castingId);
  226. let price = lk.getVal(gardartLimitPriceKey, 0);
  227. price = Number(price);
  228. if(castingId <= 0){
  229. lk.prependNotifyInfo('⚠️请设置产品品类');
  230. hasNeedSendNotify = true;
  231. } else if(price <= 0){
  232. lk.prependNotifyInfo('⚠️请设置监控价格');
  233. hasNeedSendNotify = true;
  234. } else {
  235. let item = await refreshLstOnSale(castingId, price);
  236. if(item){
  237. hasNeedSendNotify = await checkToBuy(item);
  238. } else {
  239. hasNeedSendNotify = false;
  240. }
  241. }
  242. }
  243. if (hasNeedSendNotify) {
  244. lk.msg(``);
  245. }
  246. lk.done();
  247. }
  248. function refreshLstOnSale(castingId, price) {
  249. return new Promise((resolve, _reject) => {
  250. try {
  251. const headers = GCommonGandartHeads;
  252. headers.Host = "api2.gandart.com";
  253. let signData = getSign();
  254. signData.castingId = castingId;
  255. signData.page = 1;
  256. signData.pageSize = 15;
  257. signData.sort = 2;// 1=编号,2=价格
  258. signData.transactionStatus = 2;
  259. let body = objToUrlParams(signData);
  260. let url = {
  261. url: `https://api2.gandart.com/market/api/v2/resaleManage/resale/onSale`,
  262. headers: headers,
  263. body: body
  264. };
  265. let collectionName = getCollectionNameById(castingId)
  266. lk.log(`请求产品[${collectionName}(${castingId})]寄售列表:${body}`);
  267. lk.post(url, async (error, _response, data) => {
  268. let retItem;
  269. try {
  270. if (error) {
  271. lk.log(`获取寄售列表信息发生错误`);
  272. lk.execFail();
  273. lk.appendNotifyInfo(`❌获取寄售列表失败,请稍后再试`);
  274. } else {
  275. let ret = JSON.parse(data);
  276. let minPrice = 9999999;
  277. if (ret.success) {
  278. let obj = ret.obj;
  279. let lst = obj.list;
  280. for(let d of lst){
  281. if(d.transactionStatus == 2){//2=可购买,4=支付中
  282. const resalePrice = Number(d.resalePrice);
  283. if(minPrice > resalePrice){
  284. minPrice = resalePrice;
  285. }
  286. if(price >= resalePrice){
  287. retItem = d;
  288. lk.appendNotifyInfo(`🎉成功匹配产品[${d.collectionName}#${d.viewSort}],价格:${d.resalePrice}`);
  289. break;
  290. }
  291. }
  292. }
  293. if(!retItem){
  294. lk.log(`无匹配的价格,当前[${collectionName}]最低价:${minPrice}`);
  295. }
  296. } else {
  297. lk.execFail();
  298. }
  299. }
  300. } catch (e) {
  301. lk.log(`获取寄售列表信息失败`);
  302. lk.logErr(e);
  303. lk.execFail();
  304. } finally {
  305. resolve(retItem);
  306. }
  307. });
  308. } catch (e) {
  309. lk.log(`获取寄售列表信息发生错误`);
  310. lk.logErr(e);
  311. resolve();
  312. }
  313. });
  314. }
  315. function checkToBuy(item){
  316. return new Promise((resolve, _reject) => {
  317. try {
  318. const id = item.id;
  319. const viewSort = item.viewSort || 0;
  320. const headers = GCommonGandartHeads;
  321. headers.Host = "api.gandart.com";
  322. const body = `transactionRecordId=${id}`;
  323. let url = {
  324. url: `https://api.gandart.com/base/v2/resaleManage/resale/buy/v2`,
  325. headers: headers,
  326. body: body
  327. };
  328. lk.log(`请求购买产品[${item.collectionName}#${viewSort}]=${body}`);
  329. // resolve(1);
  330. const collectionName = item.collectionName;
  331. lk.post(url, async (error, _response, data) => {
  332. let retItem;
  333. try {
  334. if (error) {
  335. lk.log(`无法下单产品[${collectionName}#${viewSort}]`);
  336. lk.execFail();
  337. lk.appendNotifyInfo(`❌购买失败,请稍后再试`);
  338. } else {
  339. lk.log(data);
  340. let ret = JSON.parse(data);
  341. if (ret.success) {
  342. let obj = ret.obj;
  343. let orderNum = obj.orderNum;
  344. if(orderNum && orderNum.length > 0){
  345. retItem = ret;
  346. lk.log(`成功下单产品[${obj.collectionName}#${viewSort}],订单号:${obj.orderNum}`);
  347. lk.appendNotifyInfo(`🎉成功下单产品[${obj.collectionName}#${viewSort}],订单号:${obj.orderNum}`);
  348. }
  349. } else {
  350. lk.log(`产品[${collectionName}#${viewSort}]下单失败`);
  351. lk.execFail();
  352. }
  353. }
  354. } catch (e) {
  355. lk.log(`下单产品[${collectionName}#${viewSort}]发生错误`);
  356. lk.logErr(e);
  357. lk.execFail();
  358. } finally {
  359. resolve(retItem);
  360. }
  361. });
  362. } catch (e) {
  363. lk.log(`下单产品[${item.collectionName}#${item.viewSort}]发生错误`);
  364. lk.logErr(e);
  365. resolve();
  366. }
  367. });
  368. }
  369. function objToUrlParams(param, key, encode) {
  370. let paramStr = urlEncode(param, key, encode);
  371. let len = paramStr.length;
  372. if(len > 0){
  373. paramStr = paramStr.substring(1,len);
  374. }
  375. return paramStr;
  376. }
  377. function urlEncode(param, key, encode) {
  378. if(param==null) return '';
  379. let paramStr = '';
  380. let t = typeof (param);
  381. if (t == 'string' || t == 'number' || t == 'boolean') {
  382. paramStr += '&' + key + '=' + ((encode==null||encode) ? encodeURIComponent(param) : param);
  383. } else {
  384. for (let i in param) {
  385. let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
  386. paramStr += urlEncode(param[i], k, encode);
  387. }
  388. }
  389. return paramStr;
  390. }
  391. function getSign() {
  392. const now = new Date().getTime();
  393. const s1 = now - 20000;
  394. const s2 = now;
  395. const s3 = now + 20000;
  396. const s4 = now + 40000;
  397. const sssfffeee = 'e9'; //localStorage.getItem('sssfffeee');
  398. const aggaaa = '9'; //localStorage.getItem('aggaaa');
  399. const yyhhhasdww = '0a';
  400. let arr = [sssfffeee, yyhhhasdww, aggaaa, '29', 'e','c', 3];
  401. let crypto = Crypto();
  402. let s5= crypto.md5(s3+arr.join(''));
  403. return {
  404. 's1': s1,
  405. 's2': s2,
  406. 's3': s3,
  407. 's4': s4,
  408. 's5': s5
  409. };
  410. }
  411. // https://github.com/lowking/Scripts/blob/master/util/ToolKit.min.js
  412. //ToolKit-start
  413. function ToolKit(t,s,i){return new class{constructor(t,s,i){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=t;this.id=s;this.data=null;this.dataFile=this.getRealPath(`${this.prefix}${this.id}.dat`);this.boxJsJsonFile=this.getRealPath(`${this.prefix}${this.id}.boxjs.json`);this.options=i;this.isExecComm=false;this.isEnableLog=this.getVal(`${this.prefix}IsEnableLog${this.id}`);this.isEnableLog=this.isEmpty(this.isEnableLog)?true:JSON.parse(this.isEnableLog);this.isNotifyOnlyFail=this.getVal(`${this.prefix}NotifyOnlyFail${this.id}`);this.isNotifyOnlyFail=this.isEmpty(this.isNotifyOnlyFail)?false:JSON.parse(this.isNotifyOnlyFail);this.isEnableTgNotify=this.getVal(`${this.prefix}IsEnableTgNotify${this.id}`);this.isEnableTgNotify=this.isEmpty(this.isEnableTgNotify)?false: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 t=require("request");return{request:t}}else{return null}})();this.execStatus=true;this.notifyInfo=[];this.log(`${this.name}, 开始执行!`);this.execComm()}getRealPath(t){if(this.isNode()){let s=process.argv.slice(1,2)[0].split("/");s[s.length-1]=t;return s.join("/")}return t}async execComm(){if(this.isNode()){this.comm=process.argv.slice(1);let t=false;if(this.comm[1]=="p"){this.isExecComm=true;this.log(`开始执行指令【${this.comm[1]}】=> 发送到手机测试脚本!`);if(this.isEmpty(this.options)||this.isEmpty(this.options.httpApi)){this.log(`未设置options,使用默认值`);if(this.isEmpty(this.options)){this.options={}}this.options.httpApi=`[email protected]:6166`}else{if(!/.*?@.*?:[0-9]+/.test(this.options.httpApi)){t=true;this.log(`❌httpApi格式错误!格式:[email protected]:6166`);this.done()}}if(!t){this.callApi(this.comm[2])}}}}callApi(t){let s=this.comm[0];this.log(`获取【${s}】内容传给手机`);let i="";this.fs=this.fs?this.fs:require("fs");this.path=this.path?this.path:require("path");const e=this.path.resolve(s);const o=this.path.resolve(process.cwd(),s);const h=this.fs.existsSync(e);const r=!h&&this.fs.existsSync(o);if(h||r){const t=h?e:o;try{i=this.fs.readFileSync(t)}catch(t){i=""}}else{i=""}let n={url:`http://${this.options.httpApi.split("@")[1]}/v1/scripting/evaluate`,headers:{"X-Key":`${this.options.httpApi.split("@")[0]}`},body:{script_text:`${i}`,mock_type:"cron",timeout:!this.isEmpty(t)&&t>5?t:5},json:true};this.post(n,(t,i,e)=>{this.log(`已将脚本【${s}】发给手机!`);this.done()})}getCallerFileNameAndLine(){let t;try{throw Error("")}catch(s){t=s}const s=t.stack;const i=s.split("\n");let e=1;if(e!==0){const t=i[e];this.path=this.path?this.path:require("path");return`[${t.substring(t.lastIndexOf(this.path.sep)+1,t.lastIndexOf(":"))}]`}else{return"[-]"}}getFunName(t){var s=t.toString();s=s.substr("function ".length);s=s.substr(0,s.indexOf("("));return s}boxJsJsonBuilder(t,s){if(this.isNode()){let i="/Users/lowking/Desktop/Scripts/lowking.boxjs.json";if(s&&s.hasOwnProperty("target_boxjs_json_path")){i=s["target_boxjs_json_path"]}if(!this.fs.existsSync(i)){return}if(!this.isJsonObject(t)||!this.isJsonObject(s)){this.log("构建BoxJsJson传入参数格式错误,请传入json对象");return}this.log("using node");let e=["settings","keys"];const o="https://raw.githubusercontent.com/Orz-3";let h={};let r="#lk{script_url}";if(s&&s.hasOwnProperty("script_url")){r=this.isEmpty(s["script_url"])?"#lk{script_url}":s["script_url"]}h.id=`${this.prefix}${this.id}`;h.name=this.name;h.desc_html=`⚠️使用说明</br>详情【<a href='${r}?raw=true'><font class='red--text'>点我查看</font></a>】`;h.icons=[`${o}/mini/master/Alpha/${this.id.toLocaleLowerCase()}.png`,`${o}/mini/master/Color/${this.id.toLocaleLowerCase()}.png`];h.keys=[];h.settings=[{id:`${this.prefix}IsEnableLog${this.id}`,name:"开启/关闭日志",val:true,type:"boolean",desc:"默认开启"},{id:`${this.prefix}NotifyOnlyFail${this.id}`,name:"只当执行失败才通知",val:false,type:"boolean",desc:"默认关闭"},{id:`${this.prefix}IsEnableTgNotify${this.id}`,name:"开启/关闭Telegram通知",val:false,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="}];h.author="#lk{author}";h.repo="#lk{repo}";h.script=`${r}?raw=true`;if(!this.isEmpty(t)){for(let s in e){let i=e[s];if(!this.isEmpty(t[i])){if(i==="settings"){for(let s=0;s<t[i].length;s++){let e=t[i][s];for(let t=0;t<h.settings.length;t++){let s=h.settings[t];if(e.id===s.id){h.settings.splice(t,1)}}}}h[i]=h[i].concat(t[i])}delete t[i]}}Object.assign(h,t);if(this.isNode()){this.fs=this.fs?this.fs:require("fs");this.path=this.path?this.path:require("path");const t=this.path.resolve(this.boxJsJsonFile);const e=this.path.resolve(process.cwd(),this.boxJsJsonFile);const o=this.fs.existsSync(t);const r=!o&&this.fs.existsSync(e);const n=JSON.stringify(h,null,"\t");if(o){this.fs.writeFileSync(t,n)}else if(r){this.fs.writeFileSync(e,n)}else{this.fs.writeFileSync(t,n)}let a=JSON.parse(this.fs.readFileSync(i));if(a.hasOwnProperty("apps")&&Array.isArray(a["apps"])&&a["apps"].length>0){let t=a.apps;let e=t.indexOf(t.filter(t=>{return t.id==h.id})[0]);if(e>=0){a.apps[e]=h}else{a.apps.push(h)}let o=JSON.stringify(a,null,2);if(!this.isEmpty(s)){for(const t in s){let i="";if(s.hasOwnProperty(t)){i=s[t]}else if(t==="author"){i="@lowking"}else if(t==="repo"){i="https://github.com/lowking/Scripts"}o=o.replace(`#lk{${t}}`,i)}}const r=/(?:#lk\{)(.+?)(?=\})/;let n=r.exec(o);if(n!==null){this.log(`生成BoxJs还有未配置的参数,请参考https://github.com/lowking/Scripts/blob/master/util/example/ToolKitDemo.js#L17-L18传入参数:\n`)}let l=new Set;while((n=r.exec(o))!==null){l.add(n[1]);o=o.replace(`#lk{${n[1]}}`,``)}l.forEach(t=>{console.log(`${t} `)});this.fs.writeFileSync(i,o)}}}}isJsonObject(t){return typeof t=="object"&&Object.prototype.toString.call(t).toLowerCase()=="[object object]"&&!t.length}appendNotifyInfo(t,s){if(s==1){this.notifyInfo=t}else{this.notifyInfo.push(t)}}prependNotifyInfo(t){this.notifyInfo.splice(0,0,t)}execFail(){this.execStatus=false}isRequest(){return typeof $request!="undefined"}isSurge(){return typeof $httpClient!="undefined"}isQuanX(){return typeof $task!="undefined"}isLoon(){return typeof $loon!="undefined"}isJSBox(){return typeof $app!="undefined"&&typeof $http!="undefined"}isStash(){return"undefined"!==typeof $environment&&$environment["stash-version"]}isNode(){return typeof require=="function"&&!this.isJSBox()}sleep(t){return new Promise(s=>setTimeout(s,t))}log(t){if(this.isEnableLog)console.log(`${this.logSeparator}${t}`)}logErr(t){this.execStatus=true;if(this.isEnableLog){console.log(`${this.logSeparator}${this.name}执行异常:`);console.log(t);console.log(`\n${t.message}`)}}msg(t,s,i,e){if(!this.isRequest()&&this.isNotifyOnlyFail&&this.execStatus){}else{if(this.isEmpty(s)){if(Array.isArray(this.notifyInfo)){s=this.notifyInfo.join("\n")}else{s=this.notifyInfo}}if(!this.isEmpty(s)){if(this.isEnableTgNotify){this.log(`${this.name}Tg通知开始`);for(let t in this.tgEscapeCharMapping){if(!this.tgEscapeCharMapping.hasOwnProperty(t)){continue}s=s.replace(t,this.tgEscapeCharMapping[t])}this.get({url:encodeURI(`${this.tgNotifyUrl}📌${this.name}\n${s}`)},(t,s,i)=>{this.log(`Tg通知完毕`)})}else{let o={};const h=!this.isEmpty(i);const r=!this.isEmpty(e);if(this.isQuanX()){if(h)o["open-url"]=i;if(r)o["media-url"]=e;$notify(this.name,t,s,o)}if(this.isSurge()||this.isStash()){if(h)o["url"]=i;$notification.post(this.name,t,s,o)}if(this.isNode())this.log("⭐️"+this.name+"\n"+t+"\n"+s);if(this.isJSBox())$push.schedule({title:this.name,body:t?t+"\n"+s:s})}}}}getVal(t,s=""){let i;if(this.isSurge()||this.isLoon()||this.isStash()){i=$persistentStore.read(t)}else if(this.isQuanX()){i=$prefs.valueForKey(t)}else if(this.isNode()){this.data=this.loadData();i=process.env[t]||this.data[t]}else{i=this.data&&this.data[t]||null}return!i?s:i}setVal(t,s){if(this.isSurge()||this.isLoon()||this.isStash()){return $persistentStore.write(s,t)}else if(this.isQuanX()){return $prefs.setValueForKey(s,t)}else if(this.isNode()){this.data=this.loadData();this.data[t]=s;this.writeData();return true}else{return this.data&&this.data[t]||null}}loadData(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs");this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile);const s=this.path.resolve(process.cwd(),this.dataFile);const i=this.fs.existsSync(t);const e=!i&&this.fs.existsSync(s);if(i||e){const e=i?t:s;try{return JSON.parse(this.fs.readFileSync(e))}catch(t){return{}}}else return{}}else return{}}writeData(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs");this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile);const s=this.path.resolve(process.cwd(),this.dataFile);const i=this.fs.existsSync(t);const e=!i&&this.fs.existsSync(s);const o=JSON.stringify(this.data);if(i){this.fs.writeFileSync(t,o)}else if(e){this.fs.writeFileSync(s,o)}else{this.fs.writeFileSync(t,o)}}}adapterStatus(t){if(t){if(t.status){t["statusCode"]=t.status}else if(t.statusCode){t["status"]=t.statusCode}}return t}get(t,s=(()=>{})){if(this.isQuanX()){if(typeof t=="string")t={url:t};t["method"]="GET";$task.fetch(t).then(t=>{s(null,this.adapterStatus(t),t.body)},t=>s(t.error,null,null))}if(this.isSurge()||this.isLoon()||this.isStash())$httpClient.get(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)});if(this.isNode()){this.node.request(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)})}if(this.isJSBox()){if(typeof t=="string")t={url:t};t["header"]=t["headers"];t["handler"]=function(t){let i=t.error;if(i)i=JSON.stringify(t.error);let e=t.data;if(typeof e=="object")e=JSON.stringify(t.data);s(i,this.adapterStatus(t.response),e)};$http.get(t)}}post(t,s=(()=>{})){if(this.isQuanX()){if(typeof t=="string")t={url:t};t["method"]="POST";$task.fetch(t).then(t=>{s(null,this.adapterStatus(t),t.body)},t=>s(t.error,null,null))}if(this.isSurge()||this.isLoon()||this.isStash()){$httpClient.post(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)})}if(this.isNode()){this.node.request.post(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)})}if(this.isJSBox()){if(typeof t=="string")t={url:t};t["header"]=t["headers"];t["handler"]=function(t){let i=t.error;if(i)i=JSON.stringify(t.error);let e=t.data;if(typeof e=="object")e=JSON.stringify(t.data);s(i,this.adapterStatus(t.response),e)};$http.post(t)}}put(t,s=(()=>{})){if(this.isQuanX()){if(typeof t=="string")t={url:t};t["method"]="PUT";$task.fetch(t).then(t=>{s(null,this.adapterStatus(t),t.body)},t=>s(t.error,null,null))}if(this.isSurge()||this.isLoon()||this.isStash()){t.method="PUT";$httpClient.put(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)})}if(this.isNode()){t.method="PUT";this.node.request.put(t,(t,i,e)=>{s(t,this.adapterStatus(i),e)})}if(this.isJSBox()){if(typeof t=="string")t={url:t};t["header"]=t["headers"];t["handler"]=function(t){let i=t.error;if(i)i=JSON.stringify(t.error);let e=t.data;if(typeof e=="object")e=JSON.stringify(t.data);s(i,this.adapterStatus(t.response),e)};$http.post(t)}}costTime(){let t=`${this.name}执行完毕!`;if(this.isNode()&&this.isExecComm){t=`指令【${this.comm[1]}】执行完毕!`}const s=(new Date).getTime();const i=s-this.startTime;const e=i/1e3;this.execCount++;this.costTotalMs+=i;this.log(`${t}耗时【${e}】秒\n总共执行【${this.execCount}】次,平均耗时【${(this.costTotalMs/this.execCount/1e3).toFixed(4)}】秒`);this.setVal(this.costTotalStringKey,JSON.stringify(`${this.costTotalMs},${this.execCount}`))}done(t={}){this.costTime();if(this.isSurge()||this.isQuanX()||this.isLoon()||this.isStash()){$done(t)}}getRequestUrl(){return $request.url}getResponseBody(){return $response.body}isGetCookie(t){return!!($request.method!="OPTIONS"&&this.getRequestUrl().match(t))}isEmpty(t){return typeof t=="undefined"||t==null||t==""||t=="null"||t=="undefined"||t.length===0}randomString(t){t=t||32;var s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";var i=s.length;var e="";for(let o=0;o<t;o++){e+=s.charAt(Math.floor(Math.random()*i))}return e}autoComplete(t,s,i,e,o,h,r,n,a,l){t+=``;if(t.length<o){while(t.length<o){if(h==0){t+=e}else{t=e+t}}}if(r){let s=``;for(var f=0;f<n;f++){s+=l}t=t.substring(0,a)+s+t.substring(n+a)}t=s+t+i;return this.toDBC(t)}customReplace(t,s,i,e){try{if(this.isEmpty(i)){i="#{"}if(this.isEmpty(e)){e="}"}for(let o in s){t=t.replace(`${i}${o}${e}`,s[o])}}catch(t){this.logErr(t)}return t}toDBC(t){var s="";for(var i=0;i<t.length;i++){if(t.charCodeAt(i)==32){s=s+String.fromCharCode(12288)}else if(t.charCodeAt(i)<127){s=s+String.fromCharCode(t.charCodeAt(i)+65248)}}return s}hash(t){let s=0,i,e;for(i=0;i<t.length;i++){e=t.charCodeAt(i);s=(s<<5)-s+e;s|=0}return String(s)}formatDate(t,s){let i={"M+":t.getMonth()+1,"d+":t.getDate(),"H+":t.getHours(),"m+":t.getMinutes(),"s+":t.getSeconds(),"q+":Math.floor((t.getMonth()+3)/3),S:t.getMilliseconds()};if(/(y+)/.test(s))s=s.replace(RegExp.$1,(t.getFullYear()+"").substr(4-RegExp.$1.length));for(let t in i)if(new RegExp("("+t+")").test(s))s=s.replace(RegExp.$1,RegExp.$1.length==1?i[t]:("00"+i[t]).substr((""+i[t]).length));return s}}(t,s,i)}
  414. //ToolKit-end
  415. // https://github.com/Peng-YM/QuanX/blob/master/Tools/OpenAPI/api-minified.js
  416. //OpenAPI-start
  417. function ENV(){const e="function"==typeof require&&"undefined"!=typeof $jsbox;return{isQX:"undefined"!=typeof $task,isLoon:"undefined"!=typeof $loon,isSurge:"undefined"!=typeof $httpClient&&"undefined"!=typeof $utils,isBrowser:"undefined"!=typeof document,isNode:"function"==typeof require&&!e,isJSBox:e,isRequest:"undefined"!=typeof $request,isScriptable:"undefined"!=typeof importModule}}function HTTP(e={baseURL:""}){const{isQX:t,isLoon:s,isSurge:o,isScriptable:n,isNode:i,isBrowser:r}=ENV(),u=/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;const a={};return["GET","POST","PUT","DELETE","HEAD","OPTIONS","PATCH"].forEach(h=>a[h.toLowerCase()]=(a=>(function(a,h){h="string"==typeof h?{url:h}:h;const d=e.baseURL;d&&!u.test(h.url||"")&&(h.url=d?d+h.url:h.url),h.body&&h.headers&&!h.headers["Content-Type"]&&(h.headers["Content-Type"]="application/x-www-form-urlencoded");const l=(h={...e,...h}).timeout,c={onRequest:()=>{},onResponse:e=>e,onTimeout:()=>{},...h.events};let f,p;if(c.onRequest(a,h),t)f=$task.fetch({method:a,...h});else if(s||o||i)f=new Promise((e,t)=>{(i?require("request"):$httpClient)[a.toLowerCase()](h,(s,o,n)=>{s?t(s):e({statusCode:o.status||o.statusCode,headers:o.headers,body:n})})});else if(n){const e=new Request(h.url);e.method=a,e.headers=h.headers,e.body=h.body,f=new Promise((t,s)=>{e.loadString().then(s=>{t({statusCode:e.response.statusCode,headers:e.response.headers,body:s})}).catch(e=>s(e))})}else r&&(f=new Promise((e,t)=>{fetch(h.url,{method:a,headers:h.headers,body:h.body}).then(e=>e.json()).then(t=>e({statusCode:t.status,headers:t.headers,body:t.data})).catch(t)}));const y=l?new Promise((e,t)=>{p=setTimeout(()=>(c.onTimeout(),t(`${a} URL: ${h.url} exceeds the timeout ${l} ms`)),l)}):null;return(y?Promise.race([y,f]).then(e=>(clearTimeout(p),e)):f).then(e=>c.onResponse(e))})(h,a))),a}function API(e="untitled",t=!1){const{isQX:s,isLoon:o,isSurge:n,isNode:i,isJSBox:r,isScriptable:u}=ENV();return new class{constructor(e,t){this.name=e,this.debug=t,this.http=HTTP(),this.env=ENV(),this.node=(()=>{if(i){return{fs:require("fs")}}return null})(),this.initCache();Promise.prototype.delay=function(e){return this.then(function(t){return((e,t)=>new Promise(function(s){setTimeout(s.bind(null,t),e)}))(e,t)})}}initCache(){if(s&&(this.cache=JSON.parse($prefs.valueForKey(this.name)||"{}")),(o||n)&&(this.cache=JSON.parse($persistentStore.read(this.name)||"{}")),i){let e="root.json";this.node.fs.existsSync(e)||this.node.fs.writeFileSync(e,JSON.stringify({}),{flag:"wx"},e=>console.log(e)),this.root={},e=`${this.name}.json`,this.node.fs.existsSync(e)?this.cache=JSON.parse(this.node.fs.readFileSync(`${this.name}.json`)):(this.node.fs.writeFileSync(e,JSON.stringify({}),{flag:"wx"},e=>console.log(e)),this.cache={})}}persistCache(){const e=JSON.stringify(this.cache,null,2);s&&$prefs.setValueForKey(e,this.name),(o||n)&&$persistentStore.write(e,this.name),i&&(this.node.fs.writeFileSync(`${this.name}.json`,e,{flag:"w"},e=>console.log(e)),this.node.fs.writeFileSync("root.json",JSON.stringify(this.root,null,2),{flag:"w"},e=>console.log(e)))}write(e,t){if(this.log(`SET ${t}`),-1!==t.indexOf("#")){if(t=t.substr(1),n||o)return $persistentStore.write(e,t);if(s)return $prefs.setValueForKey(e,t);i&&(this.root[t]=e)}else this.cache[t]=e;this.persistCache()}read(e){return this.log(`READ ${e}`),-1===e.indexOf("#")?this.cache[e]:(e=e.substr(1),n||o?$persistentStore.read(e):s?$prefs.valueForKey(e):i?this.root[e]:void 0)}delete(e){if(this.log(`DELETE ${e}`),-1!==e.indexOf("#")){if(e=e.substr(1),n||o)return $persistentStore.write(null,e);if(s)return $prefs.removeValueForKey(e);i&&delete this.root[e]}else delete this.cache[e];this.persistCache()}notify(e,t="",a="",h={}){const d=h["open-url"],l=h["media-url"];if(s&&$notify(e,t,a,h),n&&$notification.post(e,t,a+`${l?"\n多媒体:"+l:""}`,{url:d}),o){let s={};d&&(s.openUrl=d),l&&(s.mediaUrl=l),"{}"===JSON.stringify(s)?$notification.post(e,t,a):$notification.post(e,t,a,s)}if(i||u){const s=a+(d?`\n点击跳转: ${d}`:"")+(l?`\n多媒体: ${l}`:"");if(r){require("push").schedule({title:e,body:(t?t+"\n":"")+s})}else console.log(`${e}\n${t}\n${s}\n\n`)}}log(e){this.debug&&console.log(`[${this.name}] LOG: ${this.stringify(e)}`)}info(e){console.log(`[${this.name}] INFO: ${this.stringify(e)}`)}error(e){console.log(`[${this.name}] ERROR: ${this.stringify(e)}`)}wait(e){return new Promise(t=>setTimeout(t,e))}done(e={}){s||o||n?$done(e):i&&!r&&"undefined"!=typeof $context&&($context.headers=e.headers,$context.statusCode=e.statusCode,$context.body=e.body)}stringify(e){if("string"==typeof e||e instanceof String)return e;try{return JSON.stringify(e,null,2)}catch(e){return"[object Object]"}}}(e,t)}
  418. //OpenAPI-end
  419. //Crypto-start
  420. function Crypto(){function o(n,t){var r=c(n[0],o=n[1],u=n[2],e=n[3],t[0],7,-680876936),e=c(e,r,o,u,t[1],12,-389564586),u=c(u,e,r,o,t[2],17,606105819),o=c(o,u,e,r,t[3],22,-1044525330);r=c(r,o,u,e,t[4],7,-176418897),e=c(e,r,o,u,t[5],12,1200080426),u=c(u,e,r,o,t[6],17,-1473231341),o=c(o,u,e,r,t[7],22,-45705983),r=c(r,o,u,e,t[8],7,1770035416),e=c(e,r,o,u,t[9],12,-1958414417),u=c(u,e,r,o,t[10],17,-42063),o=c(o,u,e,r,t[11],22,-1990404162),r=c(r,o,u,e,t[12],7,1804603682),e=c(e,r,o,u,t[13],12,-40341101),u=c(u,e,r,o,t[14],17,-1502002290),r=i(r,o=c(o,u,e,r,t[15],22,1236535329),u,e,t[1],5,-165796510),e=i(e,r,o,u,t[6],9,-1069501632),u=i(u,e,r,o,t[11],14,643717713),o=i(o,u,e,r,t[0],20,-373897302),r=i(r,o,u,e,t[5],5,-701558691),e=i(e,r,o,u,t[10],9,38016083),u=i(u,e,r,o,t[15],14,-660478335),o=i(o,u,e,r,t[4],20,-405537848),r=i(r,o,u,e,t[9],5,568446438),e=i(e,r,o,u,t[14],9,-1019803690),u=i(u,e,r,o,t[3],14,-187363961),o=i(o,u,e,r,t[8],20,1163531501),r=i(r,o,u,e,t[13],5,-1444681467),e=i(e,r,o,u,t[2],9,-51403784),u=i(u,e,r,o,t[7],14,1735328473),r=l(r,o=i(o,u,e,r,t[12],20,-1926607734),u,e,t[5],4,-378558),e=l(e,r,o,u,t[8],11,-2022574463),u=l(u,e,r,o,t[11],16,1839030562),o=l(o,u,e,r,t[14],23,-35309556),r=l(r,o,u,e,t[1],4,-1530992060),e=l(e,r,o,u,t[4],11,1272893353),u=l(u,e,r,o,t[7],16,-155497632),o=l(o,u,e,r,t[10],23,-1094730640),r=l(r,o,u,e,t[13],4,681279174),e=l(e,r,o,u,t[0],11,-358537222),u=l(u,e,r,o,t[3],16,-722521979),o=l(o,u,e,r,t[6],23,76029189),r=l(r,o,u,e,t[9],4,-640364487),e=l(e,r,o,u,t[12],11,-421815835),u=l(u,e,r,o,t[15],16,530742520),r=a(r,o=l(o,u,e,r,t[2],23,-995338651),u,e,t[0],6,-198630844),e=a(e,r,o,u,t[7],10,1126891415),u=a(u,e,r,o,t[14],15,-1416354905),o=a(o,u,e,r,t[5],21,-57434055),r=a(r,o,u,e,t[12],6,1700485571),e=a(e,r,o,u,t[3],10,-1894986606),u=a(u,e,r,o,t[10],15,-1051523),o=a(o,u,e,r,t[1],21,-2054922799),r=a(r,o,u,e,t[8],6,1873313359),e=a(e,r,o,u,t[15],10,-30611744),u=a(u,e,r,o,t[6],15,-1560198380),o=a(o,u,e,r,t[13],21,1309151649),r=a(r,o,u,e,t[4],6,-145523070),e=a(e,r,o,u,t[11],10,-1120210379),u=a(u,e,r,o,t[2],15,718787259),o=a(o,u,e,r,t[9],21,-343485551),n[0]=h(r,n[0]),n[1]=h(o,n[1]),n[2]=h(u,n[2]),n[3]=h(e,n[3])}function f(n,t,r,e,u,o){return t=h(h(t,n),h(e,o)),h(t<<u|t>>>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))}}}
  421. //Crypto-end