revert(relay): 回退「按首帧分流上游」(假设已被原始 bundle 证伪)

- 依据:官方 main.9f4e7a89.js 中 config-template = https://c{server}.3dtank.com/config.xml,server 号由 balancer(/s/status.js)决定,与连接类型无关

- 本机镜像走 else 分支:config-template = http://<本机>/config.xml(无 {server} 占位符),根本不参与分服

- 恢复「连上立即建上游」以保持与上游 TLS 建连并行;保留 --upstream-alt 参数与 FirstCmdId 记录备用
This commit is contained in:
TermiNexus committed 2026-10-15 16:19:35 +08:00
1 parent 941dde0913
commit 1b487fbdd6
1 file changed
+5 -15
+5 -15
View File
@@ -555,9 +555,10 @@ WsServer.on('connection', (Client, Req) => {
: undefined;
// 转发:客户端帧**原样直发**;上游未就绪时暂存,open 后按原序补发(不重放、不改字节)。
// ★ 上游不再"连上就建":等客户端首帧到达、解出命令 ID 后再选上游(见下方 Client.on('message'))。
// 注:曾试过"等首帧再选上游",但已证伪(本机镜像的 config-template 没有 {server},官方分服是靠 /s/status.js),
// 故恢复为"连上立即建上游",保持与上游 TLS 建连的并行(不增加握手延迟)。
const StartUpstream = (Target) => {
State.Log('上游选择: ' + Target + (Target === UPSTREAM ? '(主:大厅连接)' : '(备:复用哈希的二次进空间)'));
State.Log('上游选择: ' + Target);
const U = new Ws(Target, { headers: UpHeaders, protocols: UpProtocols, rejectUnauthorized: false });
U.binaryType = 'nodebuffer';
U.on('open', () => {
@@ -578,25 +579,14 @@ WsServer.on('connection', (Client, Req) => {
U.on('error', (Err) => State.Log('上游错误: ' + Err.message));
Upstream = U;
};
StartUpstream(UPSTREAM);
Client.on('message', (Data) => {
const Buf = Buffer.from(Data);
SaveFrame(State, 'c2s', Buf);
Decoders.c2s.Feed(Buf);
SyncKeys(Decoders);
if (!Upstream) {
// 上游还没定:先暂存,并尝试用首帧的命令 ID 决定去主上游还是备用上游
Pending.push(Buf);
const Id = Decoders.c2s.FirstCmdId;
if (Id === null) {
State.Log('等待首帧命令 ID 以决定上游(暂存 ' + Buf.length + ' 字节)');
return;
}
// 1 = Hash Request(大厅)→ 主上游;3 = Auth/EnterSpace(复用会话哈希的二次进空间)→ 备用上游
StartUpstream(Id === 3 ? UPSTREAM_ALT : UPSTREAM);
return;
}
if (Upstream.readyState === Ws.OPEN) Upstream.send(Buf);
if (Upstream && Upstream.readyState === Ws.OPEN) Upstream.send(Buf);
else {
State.Log('上游尚未就绪,暂存 ' + Buf.length + ' 字节待补发');
Pending.push(Buf);