Files
TankIC/3DTank/tools/server/world.js
T
TermiNexus b6f2cb71ee feat(3dtank): 协议逆向工程与自研服务器入库(工具链 + 协议表 + 空间回放 + MySQL)
工具链(3DTank/tools/):extract(模块提取)、mine_evidence/apply_names(命名证据与别名回填)、extract_codec_fields(字段表 + 全库槽位类型 + PrimClassWire/ResourceClasses)、mine_downlink(下行字段表)、extract_space_init/rebase_space_init/audit_space_init(空间模板与记录切分审计)、extract_space_session(把真实会话切成按上行触发的回放模板)、pair_flow(请求→应答配对)、probe_containers、ingest/decrypt_frames(抓包入库与解密)、serve/fetch_assets(本地站点镜像)、import_db(抓包对象仓库导入 MySQL)。

服务器(3DTank/tools/server/):link/entry/codec/container/dispatch/world/space/semantic(协议层与 lt/pt/zt 三个容器布局)、session(会话回放,顺序推进)、db + schema.sql(MySQL 连接层与对象仓库表结构)、store/responder(查库组帧与定向应答;接管范围默认只开 ba.lcr)。

同时修 pair_flow 的时间轴偏移:timeline_c2s 与 timeline_s2c 的 0 点相差 144~4453ms,改前配对整体偏约 2 秒(实测 space-100073070 偏 2084ms),改后 22.4% 的触发者被纠正。

src/、src_named/、packets/、3DTank/local/(含数据库口令)不进库,可用上述工具重新生成。
2026-09-17 20:00:41 +08:00

68 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// world.js - 服务端世界状态:空间实例表 / 空间分类 / 未实现命令清单
//
// M1 只承载「服务器需要记住什么」:客户端连过哪些空间、每个空间收到了哪些命令(尚未实现语义)。
// 这四个注册表(gameType / model / resource / space)在 M2 才会真正填内容——
// 现在先把「客户端要什么」记全,那就是施工图。
'use strict';
// 入口空间:真实服务器在 Hash Response 同一帧里下发(实测 0x5f691cc = 100045260)
const ENTRANCE_SPACE = 100045260;
// 空间分类。置信度如实标注:
// 实测 = 抓包/源码直接对得上;容器 = 从该空间容器的模式表推出来的用途;待核实 = 只有命名线索
// 注意:超过 2^53 的 id 必须写成字符串(3074457345817190050 用数字字面量会掉精度)
const SPACE_KIND = {
100045260: 'Entrance', // 实测:与 Hash Response 同帧下发,只有 3 条 s2c
100073070: 'Garage', // 实测:客户端上报 button_click "GARAGE" 后服务器 Open Space(100073070)
100072911: 'Shop', // 容器模式表 = Jj / ShopCategoryCC
100045720: 'Chat', // 容器模式表 = _t / Kz / ChatCC / ClanChatCC / NewsShowingCC
920007382011: 'Queue', // 待核实(旧注释写「快速战斗队列」)
100119080: 'Unknown',
'3074457345817190050': 'Unknown', // 待核实:帧量极大(3551 条 s2c),疑似战斗
};
function MakeWorld() {
const Spaces = new Map();
const Unimplemented = new Map();
let NoteCount = 0;
function EnsureSpace(Id) {
const Key = String(Id);
let S = Spaces.get(Key);
if (!S) {
S = { Id: Key, Kind: ClassifySpace(Key), Commands: 0, Since: new Date().toISOString() };
Spaces.set(Key, S);
}
return S;
}
// 记一条「还没实现语义」的上行命令(按 空间类别 + 命令名 归并)
function NoteUnimplemented(Kind, Name, MethodId, Target) {
NoteCount++;
const Key = Kind + ' ' + Name;
let U = Unimplemented.get(Key);
if (!U) {
U = { Kind, Name, MethodId, Count: 0, Targets: new Set() };
Unimplemented.set(Key, U);
}
U.Count++;
if (U.Targets.size < 5) U.Targets.add(String(Target));
}
// 会话结束/定时打印用:按次数排序的未实现清单
function UnimplementedSummary() {
const Rows = [...Unimplemented.values()]
.sort((A, B) => B.Count - A.Count)
.map((U) => ({ Kind: U.Kind, Name: U.Name, MethodId: U.MethodId, Count: U.Count, Targets: [...U.Targets] }));
return { Total: NoteCount, Distinct: Rows.length, Rows };
}
return { Spaces, Unimplemented, EnsureSpace, NoteUnimplemented, UnimplementedSummary };
}
function ClassifySpace(Id) {
return SPACE_KIND[String(Id)] || 'Unknown';
}
module.exports = { MakeWorld, ClassifySpace, ENTRANCE_SPACE, SPACE_KIND };