mirror of
https://github.com/Sliverkiss/QuantumultX.git
synced 2026-11-05 22:36:51 +08:00
217 lines
22 KiB
JavaScript
217 lines
22 KiB
JavaScript
/*
|
||
------------------------------------------
|
||
@Author: Sliveriss
|
||
@Github: https://github.com/Sliverkiss/QuantumultX
|
||
@Description: QuantumultX 自动签到脚本
|
||
@Date: 2026.01.28
|
||
------------------------------------------
|
||
☆ ╱╲*╱╲ ☆
|
||
╱╳+▲╱ ╲ ☆
|
||
╱╱ ◢◣+ ╳╲
|
||
╱ +◢█◣ / ╲☆
|
||
☆ ◢██◣ Sakura
|
||
_▂▂█▂▂ 樱花交流会·2.0.0
|
||
若是对你有所帮助~不妨点个star🌟!:|
|
||
|
||
⚠️【免责声明】
|
||
------------------------------------------
|
||
1、此脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,本人对此不承担任何保证责任。
|
||
2、由于此脚本仅用于学习研究,您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
|
||
3、请勿将此脚本用于任何商业或非法目的,若违反规定请自行对此负责。
|
||
4、此脚本涉及应用与本人无关,本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
|
||
5、本人对任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失和损害。
|
||
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明,所有权证明,我们将在收到认证文件确认后删除此脚本。
|
||
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本,即视为您已接受此免责声明。
|
||
*/
|
||
|
||
// ----------- 固定不动区域 -----------
|
||
const $ = new Env("QuantmultX 脚本生成器");
|
||
const confPath = $.getdata("@sliverkiss_qx.confPath") || "icloud";//配置文件路径
|
||
const ckName = $.getdata("@sliverkiss_qx.ckName") || "test_data";// 脚本ck名称
|
||
const scriptName = $.getdata("@sliverkiss_qx.scriptName") || "测试";// 脚本名称
|
||
const fileName = $.getdata("@sliverkiss_qx.fileName") || "hello";// 脚本文件名
|
||
const cron = $.getdata("@sliverkiss_qx.cron") || "0 9 * * *";//脚本定时
|
||
const getCookieUrl = $.getdata("@sliverkiss_qx.getCookieUrl") || "https://cdp.myfoodiepet.com/tnew/myfoodiepet-member/v1/member/sign";// 获取ck的url
|
||
|
||
|
||
//主程序执行入口
|
||
!(async () => {
|
||
try {
|
||
if (getCookieUrl && confPath && ckName && scriptName && fileName) {
|
||
if (!writeConf()) {
|
||
await writeScript();
|
||
writeSnippet();
|
||
};
|
||
} else {
|
||
$.error("Boxjs配置未填写完整,停止运行脚本")
|
||
}
|
||
} catch (e) {
|
||
throw e;
|
||
}
|
||
})()
|
||
.catch((e) => { $.logErr(e), $.msg($.name, `⛔️ script run error!`, e.message || e) })
|
||
.finally(async () => {
|
||
$.done({});
|
||
});
|
||
|
||
//重放
|
||
function fetch(opts) {
|
||
try {
|
||
return new Promise((resolve) => {
|
||
$[opts?.method](opts, (err, resp, data) => {
|
||
let res = $.toObj(data) || data;
|
||
resolve(res);
|
||
});
|
||
});
|
||
} catch (e) {
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
// 写入脚本文件
|
||
async function writeScript() {
|
||
let scriptConetent = await fetch({
|
||
"url": "https://raw.githubusercontent.com/Sliverkiss/QuantumultX/refs/heads/main/quantumultX_checkin.js",
|
||
"method": "get"
|
||
})
|
||
// 脚本名称
|
||
scriptConetent = scriptConetent.replace(
|
||
'const scriptName = \"\"',
|
||
`const scriptName = \"${scriptName}\"`
|
||
)
|
||
// ck名称
|
||
scriptConetent = scriptConetent.replace(
|
||
'const ckName = \"\"',
|
||
`const ckName = \"${ckName}\"`
|
||
)
|
||
|
||
let scriptFilePath = `../Scripts/${fileName}.js`
|
||
let encoder = new TextEncoder();
|
||
let writeUint8Array = encoder.encode(scriptConetent);
|
||
if ($iCloud.writeFile(writeUint8Array, scriptFilePath)) {
|
||
$.info(`生成${fileName}.js脚本文件成功 ✅`);
|
||
} else {
|
||
$.error(`生成${fileName}.js脚本文件失败 ❌`);
|
||
}
|
||
}
|
||
|
||
// 写入配置文件
|
||
function writeConf() {
|
||
let confFullPath = `../Profiles/${confPath}.conf`
|
||
let readUint8Array = $iCloud.readFile(confFullPath);
|
||
|
||
if (readUint8Array === undefined) {
|
||
$.error(`读取[${confPath}]配置文件失败 ❌`);
|
||
return true;
|
||
}
|
||
|
||
$.info(`读取[${confPath}]配置文件成功 ✅`);
|
||
let textDecoder = new TextDecoder();
|
||
let readContent = textDecoder.decode(readUint8Array);
|
||
|
||
//判断脚本文件是否已存在
|
||
if (new RegExp(`tag=${scriptName}.js`).test(readContent)) {
|
||
$.warn(`该task脚本已存在,跳过[${confPath}]配置文件 ⚠️`);
|
||
} else {
|
||
//生成定时脚本配置
|
||
readContent = readContent.replace(
|
||
'[task_local]',
|
||
`[task_local]\n${cron} ${fileName}.js, tag=${scriptName}, enabled=true\n`
|
||
)
|
||
}
|
||
// 判断重写文件是否存在
|
||
if (new RegExp(`tag=QuantmultX Checkin @sliverkiss`).test(readContent)) {
|
||
$.warn(`该rewrite重写已存在,跳过[${confPath}]配置文件 ⚠️`);
|
||
} else {
|
||
readContent = readContent.replace(
|
||
'[rewrite_remote]',
|
||
`[rewrite_remote]\nqx_checkin.snippet, tag=QuantmultX Checkin @sliverkiss, update-interval=172800, opt-parser=true, enabled=true\n`
|
||
)
|
||
}
|
||
// 写入原来配置
|
||
let textEncoder = new TextEncoder();
|
||
let writeUint8Array = textEncoder.encode(readContent);
|
||
if ($iCloud.writeFile(writeUint8Array, confFullPath)) {
|
||
$.error(`刷新[${confPath}]配置文件成功 ✅`);
|
||
} else {
|
||
$.error(`刷新[${confPath}]配置文件失败 ❌`);
|
||
return true;
|
||
}
|
||
}
|
||
|
||
|
||
// 写入重写资源
|
||
function writeSnippet() {
|
||
// 获取ck正则
|
||
let urlRegx = '^' + getCookieUrl.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||
// mitm域名
|
||
let hostName = new URL(getCookieUrl).hostname;
|
||
|
||
let snippetPath = "../Profiles/qx_checkin.snippet";
|
||
let readUint8Array = $iCloud.readFile(snippetPath);
|
||
if (readUint8Array === undefined) {
|
||
$.error(`读取qx_checkin.snippet文件失败 ❌`);
|
||
$.info(`尝试创建qx_checkin.snippet文件...`);
|
||
let content = `[rewrite_local]\n#${scriptName} by QuantumultX Checkin\n${urlRegx} url script-request-body ${fileName}.js\n\n[mitm]\nhostname = ${hostName}`
|
||
let textEecoder = new TextEncoder();
|
||
let writeUint8Array = textEecoder.encode(content);
|
||
if ($iCloud.writeFile(writeUint8Array, snippetPath)) {
|
||
$.info(`写入qx_checkin.snippet文件成功 ✅`);
|
||
} else {
|
||
$.error(`写入qx_checkin.snippet文件失败 ❌`);
|
||
}
|
||
return;
|
||
} else {
|
||
let textDecoder = new TextDecoder();
|
||
let readContent = textDecoder.decode(readUint8Array);
|
||
if (new RegExp(`${hostName}`).test(readContent)) {
|
||
$.warn(`该Mitm域名已存在,跳过写入qx_checkin.snippet文件 ⚠️`);
|
||
return;
|
||
}
|
||
// 写入rewrite_local
|
||
readContent = readContent.replace(
|
||
'[rewrite_local]',
|
||
`[rewrite_local]\n#${scriptName} by QuantumultX Checkin\n${urlRegx} url script-request-body ${fileName}.js\n`
|
||
);
|
||
// 写入mitm
|
||
readContent = readContent.replace(
|
||
'hostname = ',
|
||
`hostname = ${hostName},`
|
||
);
|
||
|
||
let textEecoder = new TextEncoder();
|
||
let writeUint8Array = textEecoder.encode(readContent);
|
||
|
||
if ($iCloud.writeFile(writeUint8Array, snippetPath)) {
|
||
$.info(`写入qx_checkin.snippet文件成功 ✅`);
|
||
} else {
|
||
$.error(`写入qx_checkin.snippet文件失败 ❌`);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
//封装一个获取脚本参数的方法
|
||
function getArguments() {
|
||
if (typeof $environment != 'undefined') {
|
||
// 获取脚本路径
|
||
const sourcePath = $environment.sourcePath;
|
||
if (!sourcePath) return {}
|
||
const sourceUrl = new URL(sourcePath);
|
||
const sourceHash = sourceUrl.hash;
|
||
const scriptParams = new URLSearchParams(sourceHash.substring(1));
|
||
|
||
return {
|
||
...scriptParams,
|
||
account: $.getjson($.ckName) || []
|
||
}
|
||
} else {
|
||
return {}
|
||
}
|
||
|
||
}
|
||
|
||
// prettier-ignore
|
||
//From chavyleung's Env.js
|
||
function Env(t, e) { class s { constructor(t) { this.env = t } send(t, e = "GET") { t = "string" == typeof t ? { url: t } : t; let s = this.get; "POST" === e && (s = this.post); const i = new Promise(((e, i) => { s.call(this, t, ((t, s, o) => { t ? i(t) : e(s) })) })); return t.timeout ? ((t, e = 1e3) => Promise.race([t, new Promise(((t, s) => { setTimeout((() => { s(new Error("请求超时")) }), e) }))]))(i, t.timeout) : i } get(t) { return this.send.call(this.env, t) } post(t) { return this.send.call(this.env, t, "POST") } } return new class { constructor(t, e) { this.logLevels = { debug: 0, info: 1, warn: 2, error: 3 }, this.logLevelPrefixs = { debug: "[DEBUG] ", info: "[INFO] ", warn: "[WARN] ", error: "[ERROR] " }, this.logLevel = "info", this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.encoding = "utf-8", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`) } getEnv() { return "undefined" != typeof $environment && $environment["surge-version"] ? "Surge" : "undefined" != typeof $environment && $environment["stash-version"] ? "Stash" : "undefined" != typeof module && module.exports ? "Node.js" : "undefined" != typeof $task ? "Quantumult X" : "undefined" != typeof $loon ? "Loon" : "undefined" != typeof $rocket ? "Shadowrocket" : void 0 } isNode() { return "Node.js" === this.getEnv() } isQuanX() { return "Quantumult X" === this.getEnv() } isSurge() { return "Surge" === this.getEnv() } isLoon() { return "Loon" === this.getEnv() } isShadowrocket() { return "Shadowrocket" === this.getEnv() } isStash() { return "Stash" === this.getEnv() } toObj(t, e = null) { try { return JSON.parse(t) } catch { return e } } toStr(t, e = null, ...s) { try { return JSON.stringify(t, ...s) } catch { return e } } getjson(t, e) { let s = e; if (this.getdata(t)) try { s = JSON.parse(this.getdata(t)) } catch { } return s } setjson(t, e) { try { return this.setdata(JSON.stringify(t), e) } catch { return !1 } } getScript(t) { return new Promise((e => { this.get({ url: t }, ((t, s, i) => e(i))) })) } runScript(t, e) { return new Promise((s => { let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); i = i ? i.replace(/\n/g, "").trim() : i; let o = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); o = o ? 1 * o : 20, o = e && e.timeout ? e.timeout : o; const [r, a] = i.split("@"), n = { url: `http://${a}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: o }, headers: { "X-Key": r, Accept: "*/*" }, policy: "DIRECT", timeout: o }; this.post(n, ((t, e, i) => s(i))) })).catch((t => this.logErr(t))) } loaddata() { if (!this.isNode()) return {}; { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e); if (!s && !i) return {}; { const i = s ? t : e; try { return JSON.parse(this.fs.readFileSync(i)) } catch (t) { 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), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e), o = JSON.stringify(this.data); s ? this.fs.writeFileSync(t, o) : i ? this.fs.writeFileSync(e, o) : this.fs.writeFileSync(t, o) } } lodash_get(t, e, s) { const i = e.replace(/\[(\d+)\]/g, ".$1").split("."); let o = t; for (const t of i) if (o = Object(o)[t], void 0 === o) return s; return o } lodash_set(t, e, s) { return Object(t) !== t || (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce(((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}), t)[e[e.length - 1]] = s), t } getdata(t) { let e = this.getval(t); if (/^@/.test(t)) { const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), o = s ? this.getval(s) : ""; if (o) try { const t = JSON.parse(o); e = t ? this.lodash_get(t, i, "") : e } catch (t) { e = "" } } return e } setdata(t, e) { let s = !1; if (/^@/.test(e)) { const [, i, o] = /^@(.*?)\.(.*?)$/.exec(e), r = this.getval(i), a = i ? "null" === r ? null : r || "{}" : "{}"; try { const e = JSON.parse(a); this.lodash_set(e, o, t), s = this.setval(JSON.stringify(e), i) } catch (e) { const r = {}; this.lodash_set(r, o, t), s = this.setval(JSON.stringify(r), i) } } else s = this.setval(t, e); return s } getval(t) { switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": return $persistentStore.read(t); case "Quantumult X": return $prefs.valueForKey(t); case "Node.js": return this.data = this.loaddata(), this.data[t]; default: return this.data && this.data[t] || null } } setval(t, e) { switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": return $persistentStore.write(t, e); case "Quantumult X": return $prefs.setValueForKey(t, e); case "Node.js": return this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0; default: return this.data && this.data[e] || null } } initGotEnv(t) { this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.cookie && void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar))) } get(t, e = (() => { })) { switch (t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"], delete t.headers["content-type"], delete t.headers["content-length"]), t.params && (t.url += "?" + this.queryStr(t.params)), void 0 === t.followRedirect || t.followRedirect || ((this.isSurge() || this.isLoon()) && (t["auto-redirect"] = !1), this.isQuanX() && (t.opts ? t.opts.redirection = !1 : t.opts = { redirection: !1 })), this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": default: this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, { "X-Surge-Skip-Scripting": !1 })), $httpClient.get(t, ((t, s, i) => { !t && s && (s.body = i, s.statusCode = s.status ? s.status : s.statusCode, s.status = s.statusCode), e(t, s, i) })); break; case "Quantumult X": this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, { hints: !1 })), $task.fetch(t).then((t => { const { statusCode: s, statusCode: i, headers: o, body: r, bodyBytes: a } = t; e(null, { status: s, statusCode: i, headers: o, body: r, bodyBytes: a }, r, a) }), (t => e(t && t.error || "UndefinedError"))); break; case "Node.js": let s = require("iconv-lite"); this.initGotEnv(t), this.got(t).on("redirect", ((t, e) => { try { if (t.headers["set-cookie"]) { const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar } } catch (t) { this.logErr(t) } })).then((t => { const { statusCode: i, statusCode: o, headers: r, rawBody: a } = t, n = s.decode(a, this.encoding); e(null, { status: i, statusCode: o, headers: r, rawBody: a, body: n }, n) }), (t => { const { message: i, response: o } = t; e(i, o, o && s.decode(o.rawBody, this.encoding)) })); break } } post(t, e = (() => { })) { const s = t.method ? t.method.toLocaleLowerCase() : "post"; switch (t.body && t.headers && !t.headers["Content-Type"] && !t.headers["content-type"] && (t.headers["content-type"] = "application/x-www-form-urlencoded"), t.headers && (delete t.headers["Content-Length"], delete t.headers["content-length"]), void 0 === t.followRedirect || t.followRedirect || ((this.isSurge() || this.isLoon()) && (t["auto-redirect"] = !1), this.isQuanX() && (t.opts ? t.opts.redirection = !1 : t.opts = { redirection: !1 })), this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": default: this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, { "X-Surge-Skip-Scripting": !1 })), $httpClient[s](t, ((t, s, i) => { !t && s && (s.body = i, s.statusCode = s.status ? s.status : s.statusCode, s.status = s.statusCode), e(t, s, i) })); break; case "Quantumult X": t.method = s, this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, { hints: !1 })), $task.fetch(t).then((t => { const { statusCode: s, statusCode: i, headers: o, body: r, bodyBytes: a } = t; e(null, { status: s, statusCode: i, headers: o, body: r, bodyBytes: a }, r, a) }), (t => e(t && t.error || "UndefinedError"))); break; case "Node.js": let i = require("iconv-lite"); this.initGotEnv(t); const { url: o, ...r } = t; this.got[s](o, r).then((t => { const { statusCode: s, statusCode: o, headers: r, rawBody: a } = t, n = i.decode(a, this.encoding); e(null, { status: s, statusCode: o, headers: r, rawBody: a, body: n }, n) }), (t => { const { message: s, response: o } = t; e(s, o, o && i.decode(o.rawBody, this.encoding)) })); break } } time(t, e = null) { const s = e ? new Date(e) : new Date; let i = { "M+": s.getMonth() + 1, "d+": s.getDate(), "H+": s.getHours(), "m+": s.getMinutes(), "s+": s.getSeconds(), "q+": Math.floor((s.getMonth() + 3) / 3), S: s.getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length))); for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length))); return t } queryStr(t) { let e = ""; for (const s in t) { let i = t[s]; null != i && "" !== i && ("object" == typeof i && (i = JSON.stringify(i)), e += `${s}=${i}&`) } return e = e.substring(0, e.length - 1), e } msg(e = t, s = "", i = "", o = {}) { const r = t => { const { $open: e, $copy: s, $media: i, $mediaMime: o } = t; switch (typeof t) { case void 0: return t; case "string": switch (this.getEnv()) { case "Surge": case "Stash": default: return { url: t }; case "Loon": case "Shadowrocket": return t; case "Quantumult X": return { "open-url": t }; case "Node.js": return }case "object": switch (this.getEnv()) { case "Surge": case "Stash": case "Shadowrocket": default: { const r = {}; let a = t.openUrl || t.url || t["open-url"] || e; a && Object.assign(r, { action: "open-url", url: a }); let n = t["update-pasteboard"] || t.updatePasteboard || s; if (n && Object.assign(r, { action: "clipboard", text: n }), i) { let t, e, s; if (i.startsWith("http")) t = i; else if (i.startsWith("data:")) { const [t] = i.split(";"), [, o] = i.split(","); e = o, s = t.replace("data:", "") } else { e = i, s = (t => { const e = { JVBERi0: "application/pdf", R0lGODdh: "image/gif", R0lGODlh: "image/gif", iVBORw0KGgo: "image/png", "/9j/": "image/jpg" }; for (var s in e) if (0 === t.indexOf(s)) return e[s]; return null })(i) } Object.assign(r, { "media-url": t, "media-base64": e, "media-base64-mime": o ?? s }) } return Object.assign(r, { "auto-dismiss": t["auto-dismiss"], sound: t.sound }), r } case "Loon": { const s = {}; let o = t.openUrl || t.url || t["open-url"] || e; o && Object.assign(s, { openUrl: o }); let r = t.mediaUrl || t["media-url"]; return i?.startsWith("http") && (r = i), r && Object.assign(s, { mediaUrl: r }), console.log(JSON.stringify(s)), s } case "Quantumult X": { const o = {}; let r = t["open-url"] || t.url || t.openUrl || e; r && Object.assign(o, { "open-url": r }); let a = t["media-url"] || t.mediaUrl; i?.startsWith("http") && (a = i), a && Object.assign(o, { "media-url": a }); let n = t["update-pasteboard"] || t.updatePasteboard || s; return n && Object.assign(o, { "update-pasteboard": n }), console.log(JSON.stringify(o)), o } case "Node.js": return }default: return } }; if (!this.isMute) switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": default: $notification.post(e, s, i, r(o)); break; case "Quantumult X": $notify(e, s, i, r(o)); break; case "Node.js": break }if (!this.isMuteLog) { let t = ["", "==============📣系统通知📣=============="]; t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t) } } debug(...t) { this.logLevels[this.logLevel] <= this.logLevels.debug && (t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(`${this.logLevelPrefixs.debug}${t.map((t => t ?? String(t))).join(this.logSeparator)}`)) } info(...t) { this.logLevels[this.logLevel] <= this.logLevels.info && (t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(`${this.logLevelPrefixs.info}${t.map((t => t ?? String(t))).join(this.logSeparator)}`)) } warn(...t) { this.logLevels[this.logLevel] <= this.logLevels.warn && (t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(`${this.logLevelPrefixs.warn}${t.map((t => t ?? String(t))).join(this.logSeparator)}`)) } error(...t) { this.logLevels[this.logLevel] <= this.logLevels.error && (t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(`${this.logLevelPrefixs.error}${t.map((t => t ?? String(t))).join(this.logSeparator)}`)) } log(...t) { t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.map((t => t ?? String(t))).join(this.logSeparator)) } logErr(t, e) { switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": case "Quantumult X": default: this.log("", `❗️${this.name}, 错误!`, e, t); break; case "Node.js": this.log("", `❗️${this.name}, 错误!`, e, void 0 !== t.message ? t.message : t, t.stack); break } } wait(t) { return new Promise((e => setTimeout(e, t))) } done(t = {}) { const e = ((new Date).getTime() - this.startTime) / 1e3; switch (this.log("", `🔔${this.name}, 结束! 🕛 ${e} 秒`), this.log(), this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": case "Quantumult X": default: $done(t); break; case "Node.js": process.exit(1) } } }(t, e) }
|