This commit is contained in:
2026-04-02 21:02:16 +08:00
commit 75b01d3e58
56 changed files with 3714 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
// ==== 配置项 ==== //
const PRODUCT_IDS = $persistentStore.read("TempProductId"); // 格式id1&id2
const MUID = $persistentStore.read("cart-x-authorization-muid");
const MS_CV = $persistentStore.read("cart-ms-cv");
// ==== 工具函数 ==== //
const generateRiskSessionId = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => (c === "x" ? (Math.random()*16|0).toString(16) : (Math.random()*4|8).toString(16)));
// ==== 执行逻辑 ==== //
const productIdArray = PRODUCT_IDS?.split("&") || [];
const results = { success: [], failure: [] };
let currentIndex = 0;
const API_URL = "https://cart.production.store-web.dynamics.com/cart/v1.0/cart/loadCart?cartType=consumer&appId=StoreWeb";
const HEADERS = {
"content-type": "application/json",
"accept": "*/*",
"x-authorization-muid": MUID,
"sec-fetch-site": "cross-site",
"x-validation-field-1": "9pgbhbppjf2b",
"ms-cv": MS_CV,
"accept-language": "ha-Latn-NG,ha;q=0.9",
"accept-encoding": "gzip, deflate, br",
"sec-fetch-mode": "cors",
"origin": "https://www.microsoft.com",
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/133.0.3065.54 Version/18.0 Mobile/15E148 Safari/604.1",
"referer": "https://www.microsoft.com/",
"x-ms-vector-id": "",
"sec-fetch-dest": "empty"
};
function sendRequest() {
if (currentIndex >= productIdArray.length) {
const successCount = results.success.length;
const failureList = results.failure.join("\n");
// 如果全部请求成功,则清空 TempProductId
if (results.failure.length === 0) {
$persistentStore.write("", "TempProductId");
}
$notification.post(
"🎮 操作完成",
`成功: ${successCount}`,
failureList || "所有请求均成功TempProductId已清空"
);
$done();
return;
}
const productId = productIdArray[currentIndex];
const riskSessionId = generateRiskSessionId();
const timeoutId = setTimeout(() => {
recordResult(productId, "超时");
proceed();
}, 30000);
// 发送skuId为0001的请求
$httpClient.put({
url: API_URL,
headers: HEADERS,
body: JSON.stringify({
locale: "en-ng",
market: "NG",
catalogClientType: "storeWeb",
friendlyName: "cart-NG",
riskSessionId: riskSessionId,
clientContext: { client: "UniversalWebStore.Cart", deviceType: "Pc" },
itemsToAdd: { items: [{ productId, skuId: "0001", quantity: 1 }] }
})
}, (error1, response1) => {
clearTimeout(timeoutId);
if (error1 || response1.status !== 200) {
recordResult(productId, `HTTP ${response1 ? response1.status : "Error1"}`);
proceed();
return;
}
// 发送skuId为0010的请求
$httpClient.put({
url: API_URL,
headers: HEADERS,
body: JSON.stringify({
locale: "en-ng",
market: "NG",
catalogClientType: "storeWeb",
friendlyName: "cart-NG",
riskSessionId: riskSessionId,
clientContext: { client: "UniversalWebStore.Cart", deviceType: "Pc" },
itemsToAdd: { items: [{ productId, skuId: "0010", quantity: 1 }] }
})
}, (error2, response2) => {
if (error2 || response2.status !== 200) {
recordResult(productId, `HTTP ${response2 ? response2.status : "Error2"}`);
} else {
// 两次请求都成功
handleSuccess(productId);
}
proceed();
});
});
}
// ==== 辅助函数 ==== //
function handleSuccess(id) {
results.success.push(id);
console.log(`${id}`);
}
function recordResult(id, reason) {
results.failure.push(`${id}: ${reason}`);
console.log(`${id} - ${reason}`);
}
function proceed() {
currentIndex++;
setTimeout(sendRequest, 10); // 请求间隔0.01秒
}
// ==== 启动检查 ==== //
if (!MUID || !PRODUCT_IDS) {
console.log("⚠️ 配置错误 - 缺少必要参数 MUID 或 PRODUCT_IDS");
$notification.post("配置错误", "缺少必要参数", "");
$done();
} else {
console.log("🚀 开始执行请求");
sendRequest();
}

View File

@@ -0,0 +1,24 @@
#!name=CoreHalo Link Collector
#!desc=Capture Xianyu/Goofish links, expose at https://corehalo.dump/
#!author=Ah Long
#!category=XBOX
#!version=1.4
#!homepage=https://github.com/XXhaos/Surge
[Host]
# 将 corehalo.dump 解析到 Surge 虚拟 IP
corehalo.dump = 198.18.0.1
[Script]
# 1. 捕获脚本 (保持原样,匹配闲鱼域名)
corehalo-capture = type=http-request, pattern=https?://h5\.m\.goofish\.com/.*reminderUrl=.+, requires-body=0, timeout=5, script-path=https://raw.githubusercontent.com/XXhaos/Surge/main/corehalo_capture.js
# 2. 导出脚本 (修改点)
# - 正则改为匹配 https://corehalo.dump/ (兼容 http)
# - 去掉了 fetch 路径,匹配根路径
corehalo-dump = type=http-request, pattern=^https?://corehalo\.dump/?$, requires-body=0, timeout=5, script-path=https://raw.githubusercontent.com/XXhaos/Surge/main/corehalo_dump.js
[MITM]
# 必须包含 corehalo.dump 才能解密 HTTPS 流量
# 同时也需要包含闲鱼域名(h5.m.goofish.com)以确保捕获功能正常
hostname = %APPEND% corehalo.dump, h5.m.goofish.com

View File

@@ -0,0 +1,41 @@
// Surge 脚本从特定URL中提取并更新 TempProductId
const key = "TempProductId";
// 获取已有 TempProductId 的值
const existingIds = $persistentStore.read(key);
// 从URL提取新的产品ID (仅匹配特定的 xbox 链接)
const url = $request.url;
// 改进正则表达式,匹配 store/ 后面的游戏ID支持大小写
const matches = url.match(/^https:\/\/www\.xbox\.com\/[eE][nN]-[uU][sS]\/games\/store\/[^\/]+\/([^\/?]+)/);
if (matches && matches[1]) {
const newProductId = matches[1];
// 将已有的 TempProductId 分割为数组
const existingIdArray = existingIds ? existingIds.split("&") : [];
if (!existingIdArray.includes(newProductId)) {
// 如果已有内容不为空,则先加入 '&' 再追加新ID
const finalProductId = existingIdArray.length > 0
? `${existingIdArray.join("&")}&${newProductId}`
: newProductId;
// 更新 TempProductId 的值
$persistentStore.write(finalProductId, key);
// 控制台输出操作
console.log(`✅ 已更新 TempProductId: ${finalProductId}`);
// 发送通知表示操作完成
$notification.post("✅ 操作成功", "已更新 TempProductId", finalProductId);
} else {
console.log(`⚠️ TempProductId 未更新,已存在: ${newProductId}`);
$notification.post("⚠️ 操作跳过", "TempProductId 已存在", newProductId);
}
}
// 结束脚本
$done();

View File

@@ -0,0 +1,51 @@
// corehalo_capture.js
//
// 触发:请求 URL 匹配 h5.m.goofish.com/...reminderUrl=...
// 逻辑:
// 1. 从 $request.url 提取 reminderUrl= 后的编码串
// 2. decodeURIComponent -> 真正目标链接 realLink
// 3. 保存到 persistentStore("corehalo_links")
// 4. 发通知,提示捕获到了什么
let reqUrl = $request && $request.url ? $request.url : "";
// 提取 reminderUrl= 后面的编码内容
let m = reqUrl.match(/reminderUrl=([^&]+)/);
if (m && m[1]) {
// decode 出真实外链
let realLink = decodeURIComponent(m[1]);
// 从持久化存储读现有列表
let raw = $persistentStore.read("corehalo_links") || "[]";
let list;
try {
list = JSON.parse(raw);
if (!Array.isArray(list)) {
list = [];
}
} catch (e) {
list = [];
}
// 去重后推入
let added = false;
if (!list.includes(realLink)) {
list.push(realLink);
$persistentStore.write(JSON.stringify(list), "corehalo_links");
added = true;
}
// 给你发一条通知,告诉你本次抓到的情况
// 标题CoreHalo Capture
// 副标题Added / Duplicate
// 正文:具体链接
$notification.post(
"CoreHalo Capture",
added ? "Added to list" : "Already in list",
realLink
);
}
// 放行原始请求
$done({});

View File

@@ -0,0 +1,84 @@
/*
* CoreHalo Web Dump
* 作用:访问 http://corehalo.dump/fetch 时,以网页形式显示捕获的链接并清空存储
*/
// 1. 读取数据
let raw = $persistentStore.read("corehalo_links") || "[]";
let list;
try {
list = JSON.parse(raw);
if (!Array.isArray(list)) list = [];
} catch (e) {
list = [];
}
const count = list.length;
// 2. 发送通知 (保持原有的系统通知功能)
if (count > 0) {
$notification.post("CoreHalo Dump", `捕获 ${count} 条链接`, "已在浏览器显示并清空");
} else {
$notification.post("CoreHalo Dump", "没有新链接", "列表为空");
}
// 3. 准备 HTML 内容
// 生成列表项 HTML
const listHtml = list.map((link, index) => `
<div class="item">
<span class="index">${index + 1}.</span>
<a href="${link}" target="_blank">${link}</a>
</div>
`).join("");
// 页面样式
const css = `
<style>
body { font-family: -apple-system, sans-serif; background-color: #f4f4f4; padding: 20px; display: flex; justify-content: center; }
.card { background: white; width: 100%; max-width: 600px; padding: 20px; border-radius: 12px; box-shadow: 0 4px 10px rgba(0,0,0,0.05); }
h1 { margin-top: 0; font-size: 20px; color: #333; border-bottom: 1px solid #eee; padding-bottom: 10px; }
.count-tag { background: #007aff; color: white; padding: 2px 8px; border-radius: 10px; font-size: 14px; margin-left: 8px; vertical-align: middle; }
.empty-state { text-align: center; color: #999; padding: 40px 0; }
.list-container { max-height: 70vh; overflow-y: auto; }
.item { padding: 12px 0; border-bottom: 1px solid #f0f0f0; display: flex; align-items: flex-start; word-break: break-all; }
.item:last-child { border-bottom: none; }
.index { color: #999; font-size: 12px; margin-right: 10px; min-width: 20px; margin-top: 2px; }
a { color: #333; text-decoration: none; font-size: 13px; line-height: 1.4; transition: color 0.2s; }
a:hover { color: #007aff; }
.footer { margin-top: 15px; font-size: 12px; color: #aaa; text-align: center; }
</style>
`;
const bodyContent = count > 0
? `<div class="list-container">${listHtml}</div>`
: `<div class="empty-state">📭 暂无捕获的链接</div>`;
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CoreHalo Links</title>
${css}
</head>
<body>
<div class="card">
<h1>捕获列表 <span class="count-tag">${count}</span></h1>
${bodyContent}
<div class="footer">列表已自动清空</div>
</div>
</body>
</html>`;
// 4. 清空存储 (提取后即焚)
$persistentStore.write("[]", "corehalo_links");
// 5. 返回网页响应
$done({
response: {
status: 200,
headers: { "Content-Type": "text/html;charset=utf-8" },
body: html
}
});