fix(relay): 上游对齐官方 —— config 回源与中继上游改为 c2

- serve.js:新增 --config-upstream(默认 https://c2.3dtank.com),/config.xml 回源与改写底稿都改用它

- wss_server.js / Start-LocalAndRelay.ps1:上游默认 c1 改为 c2,可用 -Upstream / --upstream 切回

- 依据:客户端 JS 无 c1/c2 硬编码(连谁完全由 config 决定);实测 c1/c2 各自提供指向自己的 config,官方客户端实际连 c2
This commit is contained in:
TermiNexus committed 2026-10-15 14:09:25 +08:00
1 parent 9bce46a86e
commit cca13974de
3 files changed
+10 -6

No files matched your search

+1 -1
View File
@@ -26,7 +26,7 @@
param(
[int]$MirrorPort = 8080,
[int]$RelayPort = 9091,
[string]$Upstream = 'wss://c1.3dtank.com:9090/', # 战斗要连 c1(c2 只用于其它阶段)
[string]$Upstream = 'wss://c2.3dtank.com:9090/', # 官方客户端实际连 c2(c1/c2 是两个独立服;要切回 c1 用 -Upstream wss://c1.3dtank.com:9090/)
[string]$Label = (Get-Date -Format 'yyyyMMdd-HHmmss'),
[switch]$FetchAssets, # 先跑 fetch_assets.js 镜像资源(首次或资源缺失时用)
[switch]$KillExisting, # 端口被占用时,先结束占用进程
+8 -4
View File
@@ -44,10 +44,13 @@ const RELAY_PORT = Number(Arg('relay-port', '0')) || 0;
// 任何 hash(哪怕只是 #hook)都会让它进不去战场。
const WS_HOOK = Argv.indexOf('--ws-hook') >= 0;
// config.xml 的回源目标:官方客户端实际连的是 **c2**(c1/c2 是两个独立服,各自提供自己的 config)
// 可用 --config-upstream 覆盖(例如 https://c1.3dtank.com)
const CONFIG_UPSTREAM = Arg('config-upstream', 'https://c2.3dtank.com').replace(/\/+$/, '');
// 本机路径 → 真实站点(StripPrefix: 去掉本机前缀再拼到 Target 上;KeepQuery: 是否保留查询串)
const PROXY = [
{ Prefix: '/resources', Target: 'https://res.3dtank.com', StripPrefix: true, KeepQuery: true },
{ Prefix: '/config.xml', Target: 'https://c1.3dtank.com', StripPrefix: false, KeepQuery: false },
{ Prefix: '/config.xml', Target: CONFIG_UPSTREAM, StripPrefix: false, KeepQuery: false },
{ Prefix: '/s/', Target: 'https://3dtank.com', StripPrefix: false, KeepQuery: false },
];
// 代理回源头:Origin 按规范只到源(不带路径),Referer 才是完整地址
@@ -175,16 +178,17 @@ async function HandleProxy(Rule, Req, Res) {
}
}
// 中继模式:取真实 config.xml(本地缓存优先,否则回源 c1),把 address/wsProtocol/port 改写成
// 中继模式:取真实 config.xml(本地缓存优先,否则回源 CONFIG_UPSTREAM),把 address/wsProtocol/port 改写成
// 指向本机中继 ws://localhost:<RELAY_PORT>/,每次实时生成返回给客户端(不落盘)。
async function ServeRewrittenConfig(Res) {
const CacheFile = path.join(CACHE_DIR, 'c1.3dtank.com', 'config.xml');
const UpHost = new URL(CONFIG_UPSTREAM).hostname;
const CacheFile = path.join(CACHE_DIR, UpHost, 'config.xml');
let Xml = '';
try {
if (fs.existsSync(CacheFile)) {
Xml = fs.readFileSync(CacheFile, 'utf8');
} else {
const Up = await fetch('https://c1.3dtank.com/config.xml', { headers: UPSTREAM_HEADERS, redirect: 'follow' });
const Up = await fetch(CONFIG_UPSTREAM + '/config.xml', { headers: UPSTREAM_HEADERS, redirect: 'follow' });
if (Up.ok) Xml = await Up.text();
}
} catch (Err) {
+1 -1
View File
@@ -40,7 +40,7 @@ const Arg = (Name, Def) => {
};
const PORT = Number(Arg('port', '9091'));
const UPSTREAM = Arg('upstream', 'wss://c1.3dtank.com:9090/'); // 注意:开始战斗要连 c1,别改成 c2(c2 只用于其它阶段)
const UPSTREAM = Arg('upstream', 'wss://c2.3dtank.com:9090/'); // 官方客户端实际连 c2(c1/c2 是两个独立服;要切回来用 --upstream wss://c1.3dtank.com:9090/)
const LABEL = Arg('label', new Date().toISOString().replace(/[:.]/g, '-'));
const PACKET_DIR = path.resolve(Arg('dir', path.join(PROJECT, 'packets', LABEL)));