init
This commit is contained in:
129
Discard/AddToCart.js
Normal file
129
Discard/AddToCart.js
Normal 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();
|
||||
}
|
||||
24
Discard/CoreHaloLinkCollector.sgmodule
Normal file
24
Discard/CoreHaloLinkCollector.sgmodule
Normal 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
|
||||
41
Discard/GetProductId.js
Normal file
41
Discard/GetProductId.js
Normal 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();
|
||||
51
Discard/corehalo_capture.js
Normal file
51
Discard/corehalo_capture.js
Normal 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({});
|
||||
84
Discard/corehalo_dump.js
Normal file
84
Discard/corehalo_dump.js
Normal 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
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user