From cca13974dee4e12e6f4e9e56002447b03eba3110 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 15 Oct 2026 14:09:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(relay):=20=E4=B8=8A=E6=B8=B8=E5=AF=B9?= =?UTF-8?q?=E9=BD=90=E5=AE=98=E6=96=B9=20=E2=80=94=E2=80=94=20config=20?= =?UTF-8?q?=E5=9B=9E=E6=BA=90=E4=B8=8E=E4=B8=AD=E7=BB=A7=E4=B8=8A=E6=B8=B8?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20c2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- 3DTank/Start-LocalAndRelay.ps1 | 2 +- 3DTank/tools/serve.js | 12 ++++++++---- 3DTank/tools/wss_server.js | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/3DTank/Start-LocalAndRelay.ps1 b/3DTank/Start-LocalAndRelay.ps1 index 57c21e8..f72a8b2 100644 --- a/3DTank/Start-LocalAndRelay.ps1 +++ b/3DTank/Start-LocalAndRelay.ps1 @@ -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, # 端口被占用时,先结束占用进程 diff --git a/3DTank/tools/serve.js b/3DTank/tools/serve.js index 54ef7c2..f298fc6 100644 --- a/3DTank/tools/serve.js +++ b/3DTank/tools/serve.js @@ -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:/,每次实时生成返回给客户端(不落盘)。 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) { diff --git a/3DTank/tools/wss_server.js b/3DTank/tools/wss_server.js index 4ccabac..501449e 100644 --- a/3DTank/tools/wss_server.js +++ b/3DTank/tools/wss_server.js @@ -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)));