From 882295dbf721552e25ea19fd6ab955f5c2b22c59 Mon Sep 17 00:00:00 2001 From: XXhaos Date: Sat, 18 Apr 2026 11:44:11 +0800 Subject: [PATCH] Create CartHistorySwitcher.js --- Scripts/CartHistorySwitcher.js | 197 +++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 Scripts/CartHistorySwitcher.js diff --git a/Scripts/CartHistorySwitcher.js b/Scripts/CartHistorySwitcher.js new file mode 100644 index 0000000..9082fcd --- /dev/null +++ b/Scripts/CartHistorySwitcher.js @@ -0,0 +1,197 @@ +/** + * Xbox Cart History Switcher + * 远程路径: https://raw.githubusercontent.com/dragonisheep/Surge/refs/heads/master/Scripts/CartHistorySwitcher.js + * + * 功能: + * 1. 访问 https://carthistory.com/ → 展示所有历史 gamertag 卡片列表 + * 2. 点击某条记录 → 访问 https://carthistory.com/?action=apply&index=N + * → 将该条的 cartId / authorization / gamertag 覆盖到 $persistentStore + * 3. 切换后自动跳回列表页,当前激活的卡片会高亮显示 + */ + +const HISTORY_KEY = "cartId_history"; +const CART_KEY = "cartId"; +const AUTH_KEY = "authorization"; +const GAMERTAG_KEY = "gamertag"; + +const url = $request.url; +const parsed = new URL(url); +const action = parsed.searchParams.get("action"); +const indexStr = parsed.searchParams.get("index"); + +if (action === "apply" && indexStr !== null) { + applySwitch(parseInt(indexStr, 10)); +} else { + showList(); +} + +// ==================== 读取历史 ==================== +function readHistory() { + const raw = $persistentStore.read(HISTORY_KEY); + if (!raw) return []; + try { + const arr = JSON.parse(raw); + return Array.isArray(arr) ? arr : []; + } catch (e) { + return []; + } +} + +// ==================== 工具函数 ==================== +function formatTimestamp(iso) { + try { + const d = new Date(iso); + const pad = n => String(n).padStart(2, '0'); + return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; + } catch (e) { + return iso; + } +} + +function escapeHtml(s) { + if (s == null) return ''; + return String(s).replace(/[&<>"']/g, c => ({ + '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' + }[c])); +} + +function respondHtml(body) { + $done({ + response: { + status: 200, + headers: { + "Content-Type": "text/html;charset=utf-8", + "Cache-Control": "no-store, no-cache, must-revalidate", + "Pragma": "no-cache" + }, + body: body + } + }); +} + +// ==================== 展示列表 ==================== +function showList() { + const history = readHistory(); + const currentCartId = $persistentStore.read(CART_KEY) || ""; + const currentGamertag = $persistentStore.read(GAMERTAG_KEY) || ""; + + // 倒序(最新在前),同时记录在原数组中的 index 用于切换 + const reversed = history.map((e, i) => ({ entry: e, originalIndex: i })).reverse(); + + const cards = reversed.map(({ entry, originalIndex }) => { + const isActive = entry.cartId === currentCartId; + const cardStyle = isActive + ? 'border:2px solid #10b981; background:#f0fdf4;' + : 'border:1px solid #e5e7eb; background:#fff;'; + const activeBadge = isActive + ? '当前激活' + : ''; + const button = isActive + ? '' + : ``; + + return ` +
+
+ ${escapeHtml(entry.gamertag)}${activeBadge} +
+
+ ${escapeHtml(formatTimestamp(entry.timestamp))} +
+ ${button} +
`; + }).join(''); + + const emptyHint = history.length === 0 + ? '
暂无历史记录
' + : ''; + + const currentInfo = currentGamertag + ? `
+
当前激活账号
+
${escapeHtml(currentGamertag)}
+
` + : ''; + + const html = ` + + + + +Cart History + + +
+

🛒 Cart 账号历史

+ ${currentInfo} +
共 ${history.length} 条历史记录(最新在前)
+ ${cards} + ${emptyHint} +
+ +`; + + respondHtml(html); +} + +// ==================== 执行切换 ==================== +function applySwitch(index) { + const history = readHistory(); + + if (!Number.isInteger(index) || index < 0 || index >= history.length) { + return showError("无效的记录索引", `index=${index}, 历史长度=${history.length}`); + } + + const entry = history[index]; + if (!entry || !entry.cartId || !entry.authorization) { + return showError("记录不完整", "该条记录缺少 cartId 或 authorization"); + } + + // 覆盖 persistentStore 中的当前值 + $persistentStore.write(entry.cartId, CART_KEY); + $persistentStore.write(entry.authorization, AUTH_KEY); + $persistentStore.write(entry.gamertag || "", GAMERTAG_KEY); + + $notification.post( + "✅ 账号切换成功", + `已切换到 ${entry.gamertag}`, + "" + ); + + const html = ` + + + + +切换成功 + + + +
+
+
切换成功
+
已切换到 ${escapeHtml(entry.gamertag)}
+
1 秒后自动返回列表...
+
+ +`; + + respondHtml(html); +} + +// ==================== 错误页 ==================== +function showError(title, detail) { + const html = ` + +错误 + +
+
+
${escapeHtml(title)}
+
${escapeHtml(detail)}
+ 返回列表 +
+ +`; + respondHtml(html); +}