From 08c38b61fa516247352508cd0977fc3cc99c3bf2 Mon Sep 17 00:00:00 2001 From: chickliu Date: Mon, 8 Dec 2025 18:21:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20js/nfsq.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/nfsq.js | 108 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/js/nfsq.js b/js/nfsq.js index 6068a4d..e403475 100644 --- a/js/nfsq.js +++ b/js/nfsq.js @@ -141,51 +141,39 @@ async function handleRewrite() { let bodyObj = {}; try { bodyObj = JSON.parse(bodyStr); } catch (e) { } - // 构建标准账号对象 + // 构建标准账号对象 (严格对齐用户提供的标准示例) const newAccount = { uid: uid, token: token, body: bodyObj, - headers_json: headers, - timestamp: new Date().getTime(), - remark: `自动抓包 ${new Date().toLocaleString()}` + headers_json: headers }; - // 3. 读取现有账号列表 - let accounts = []; + // 3. 本地存储逻辑 (BoxJs 仍然保持本地全量备份) + let localAccounts = []; const cachedData = $.getdata(ENV_NAME); if (cachedData) { try { - // 兼容可能被存为 JSON 字符串的情况 const parsed = JSON.parse(cachedData); - accounts = Array.isArray(parsed) ? parsed : [parsed]; - } catch (e) { - // 如果解析失败,说明格式不对,覆盖即可 - accounts = []; - } + localAccounts = Array.isArray(parsed) ? parsed : [parsed]; + } catch (e) { localAccounts = []; } } - // 4. 更新或添加账号 - const idx = accounts.findIndex(u => u.uid === uid); + const idx = localAccounts.findIndex(u => u.uid === uid); if (idx > -1) { - accounts[idx] = newAccount; // 更新 - $.log(`♻️ 更新旧账号: ${uid}`); + localAccounts[idx] = newAccount; // 更新 } else { - accounts.push(newAccount); // 新增 - $.log(`🆕 添加新账号: ${uid}`); + localAccounts.push(newAccount); // 新增 } - // 5. 保存到本地 - const saved = $.setdata(JSON.stringify(accounts, null, 2), ENV_NAME); + const saved = $.setdata(JSON.stringify(localAccounts, null, 2), ENV_NAME); if (saved) { - $.msg(SCRIPT_NAME, `✅ 账号抓取成功`, `当前共 ${accounts.length} 个账号`); - } else { - $.msg(SCRIPT_NAME, `❌ 保存失败`, `BoxJs/本地存储 写入失败`); + $.msg(SCRIPT_NAME, `✅ 账号抓取成功`, `UID: ${uid.slice(0, 6)}... 已保存到本地`); } - // 6. 推送到青龙 (如果有配置) + // 4. 推送到青龙 (智能合并模式) if (QL_CONFIG.URL && QL_CONFIG.CLIENT_ID && QL_CONFIG.CLIENT_SECRET) { - await pushToQingLong(accounts); + await pushToQingLong(newAccount); } else { $.log("⚠️ 未配置青龙信息,跳过推送。(请在脚本 QL_CONFIG 中填写,或手动复制 BoxJs 数据)"); } @@ -363,17 +351,17 @@ async function checkAllPrizes(token, uid, userAgent) { // ================= 青龙推送相关 ================= -async function pushToQingLong(accounts) { - $.log("📤 正在推送到青龙面板..."); +async function pushToQingLong(accountToPush) { + $.log(`📤 正在尝试处理青龙推送 (UID: ${accountToPush.uid.slice(0, 6)}...)`); const { URL, CLIENT_ID, CLIENT_SECRET } = QL_CONFIG; - // 1. 获取 Token - const tokenUrl = `${URL}/open/auth/token?client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}`; try { + // 1. 获取 Token + const tokenUrl = `${URL}/open/auth/token?client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}`; const tReq = await $.http.get({ url: tokenUrl }); const tBody = JSON.parse(tReq.body); if (tBody.code !== 200) { - $.msg(SCRIPT_NAME, "青龙推送失败", "获取 Token 失败,请检查 Client ID/Secret"); + $.msg(SCRIPT_NAME, "青龙推送失败", "获取 Token 失败,请检查密钥"); return; } const qlToken = tBody.data.token; @@ -385,33 +373,66 @@ async function pushToQingLong(accounts) { headers: { 'Authorization': `Bearer ${qlToken}` } }); const eBody = JSON.parse(eReq.body); - const exists = eBody.data && eBody.data.length > 0; - const newValue = JSON.stringify(accounts); + // 3. 准备数据:读取现有 -> 合并 + let remoteList = []; + let existingEnv = null; - if (exists) { - // 更新 - const envId = eBody.data[0].id; + if (eBody.data && eBody.data.length > 0) { + existingEnv = eBody.data[0]; + try { + // 尝试解析现有的值为 JSON 数组 + // 注意:青龙里可能存的是字符串,也可能已经是 JSON + let rawValue = existingEnv.value; + // 有时候青龙返回的 value 是被转义过的字符串,尝试解析 + let parsedValue = JSON.parse(rawValue); + if (Array.isArray(parsedValue)) { + remoteList = parsedValue; + } else { + // 如果不是数组,可能是单个对象,或者其他格式,清空 + remoteList = []; + } + } catch (e) { + console.log(" ⚠️ 解析青龙现有变量失败,将覆盖为新列表"); + remoteList = []; + } + } + + // 4. 执行合并逻辑 + const targetIdx = remoteList.findIndex(u => u.uid === accountToPush.uid); + let action = ""; + if (targetIdx > -1) { + remoteList[targetIdx] = accountToPush; + action = "更新"; + } else { + remoteList.push(accountToPush); + action = "新增"; + } + + const newValue = JSON.stringify(remoteList); // 保持紧凑格式,或者用 JSON.stringify(remoteList, null, 2) 美化 + + // 5. 推送回青龙 + if (existingEnv) { + // update const updateUrl = `${URL}/open/envs`; - const uReq = await $.http.put({ + await $.http.put({ url: updateUrl, headers: { 'Authorization': `Bearer ${qlToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ - id: envId, + id: existingEnv.id, name: ENV_NAME, value: newValue, - remarks: "自动抓包更新: " + new Date().toLocaleString() + remarks: existingEnv.remarks || (`自动抓包更新: ${new Date().toLocaleString()}`) }) }); - $.log(" ✅ 已更新青龙环境变量"); - $.msg(SCRIPT_NAME, "推送成功", "已更新青龙环境变量 " + ENV_NAME); + $.msg(SCRIPT_NAME, `✅ 推送成功 [${action}]`, `UID: ${accountToPush.uid.slice(0, 6)}... 已同步至青龙`); } else { - // 新建 + // create const addUrl = `${URL}/open/envs`; - const aReq = await $.http.post({ + await $.http.post({ url: addUrl, headers: { 'Authorization': `Bearer ${qlToken}`, @@ -423,8 +444,7 @@ async function pushToQingLong(accounts) { remarks: "自动抓包创建" }]) }); - $.log(" ✅ 已新建青龙环境变量"); - $.msg(SCRIPT_NAME, "推送成功", "已新建青龙环境变量 " + ENV_NAME); + $.msg(SCRIPT_NAME, `✅ 推送成功 [新建]`, `UID: ${accountToPush.uid.slice(0, 6)}... 已创建青龙变量`); } } catch (e) {