Commit Graph
44 Commits
Author SHA1 Message Date
TermiNexus 2ef424929b fix(protocol): 适配 e98d0216 版编解码 API 并重生成协议表
- extract_codec_fields:字段工厂 n7f→r7g、读写方法 p7g/o7g→t7h/s7h、槽位初始化 q7g→u7h
- 资源类注册 u83→y84,核心类型按 模块::导出键 解析(Vector3/Long/实体引用)
- mine_downlink:读取器映射按当前 ByteBuffer 修正(t2u=f32、u2u=f64 等),容器槽位泛化
- 重生成 codec_fields/uplink_table/downlink_table:762 下行字段 0 未解,361 上行命令全量有类型
2026-10-21 00:03:07 +08:00
TermiNexus 78c02345c2 revert(local): 运行链路默认改回 unpacked,src 改为 -UseSrc 可选
保持原有行为:默认加载 3dtank.com/play/static/js/unpacked(含 4 个模块的人工补丁),启动时按需打单包,-Build 强制重打;-UseSrc 才切到 3DTank/src,-Split 作为兼容旧参数等同默认。serve.js 的 --src 能力保留但不启用。
2026-10-20 23:06:09 +08:00
TermiNexus a487c28dc1 feat(local): 运行链路默认切到 3DTank/src,启动时按需打单包
serve.js 新增 --src:unpacked/module_*.js、resources.json、index.json 与 unpacked.pack.json 路由到源码目录(加载器与 hornet_bundle 仍走镜像);修复 403 白名单未包含 src 目录。Start-LocalAndRelay 默认跑 src,源码更新或单包缺失时自动打包,-Build 强制重打,-Split 回退切割产物;恢复 ps1 的 UTF-8 BOM 以免 Windows PowerShell 误读中文。
2026-10-20 22:53:34 +08:00
TermiNexus fd952e814c chore(extract): 重建 src 到当前包 main.7cfa4058 并修复证据挖掘
3DTank/src 原为 6469b966(client_version 83fabafa)时代的产物,已按 main.7cfa4058(e98d0216)重新 extract(126 代码模块 + 1221 资源);mine_evidence 的组件 getter 正则补上当前版本的 Z\$ 抛错函数,字段证据从 0 恢复到 1740 条;证据来源包改为读取 index.json.bundle。
2026-10-20 22:43:37 +08:00
TermiNexus 8bbdb40364 docs(kt): 新增 Kotlin 重构计划(工具清单/阶段/验收)
按 dir.file 的 40/21/65 分类修正范围:仅 40 个游戏本体模块需要复刻;补充现有工具用法、S0-S6 阶段、可启动 JS 验收标准、换版漂移处理与风险回退。
2026-10-20 22:31:40 +08:00
TermiNexus fcc4901a1f feat(garage): 战局空闲预热车库资源,静态资源启用长缓存与异步读 2026-10-20 16:48:41 +08:00
TermiNexus 57481a1d09 feat(client-info): 本地镜像的 ClientInfo 显示 SRV: CN1/CN2 2026-10-19 21:43:33 +08:00
TermiNexus 2197f23517 feat(relay): 接管 _reconnectFast,改写战场服地址并按原 host 切换上游 2026-10-19 20:59:20 +08:00
TermiNexus 42e1944cce fix(launcher): 兼容 -SRV=1 等号写法(改用 args 手动解析) 2026-10-19 20:30:40 +08:00
TermiNexus 8820639feb feat(launcher): 增加 -SRV 1/2 统一切换前后端服务器(c1/c2) 2026-10-19 20:29:24 +08:00
TermiNexus 4d8cbd81d6 chore(sw): 本地镜像禁用 Service Worker(自注销旧注册 + 置空游戏 SW 注册模块) 2026-10-18 19:00:52 +08:00
TermiNexus 469f913619 fix(page): 修复 index.html 主文件引用失配(新主文件没被加载,自动刷新拦截等全部失效)
- 根因:index.html 写死 main.9f4e7a89.js,重拆后主文件改名 main.7cfa4058.js → 请求旧名 404,新主文件里的 HORNET 注入 / 自动刷新拦截 / F5 兜底压根没加载

- 3DTank/web/index.html:引用改为 main.7cfa4058.js

- tools/serve.js:Resolve 增加兜底 —— 请求 main.<hash>.js 但文件不存在时,回退到目录里最新的 main.<hash>.js(以后换 bundle 无需再改 HTML)

- tools/split.js:拆分完成后自动改写 index.html 的主文件引用(防复发)
2026-10-16 14:23:02 +08:00
TermiNexus fd0dffe31b feat(bundle): 迁移到新版 main.7cfa4058.js(重做拆分 + 移植 7 处针对性修改)
- 拆分:tools/split.js 重切新版(1347 模块 / 126 代码模块),主文件 main.7cfa4058.js,语法验证通过

- 修复 split.js 内自动刷新拦截的 \\n 转义:它在模板字符串里,必须写 \\\\n,否则生成的主文件字符串断行、语法报错

- 符号映射:map_symbols.js 对齐旧→新(qyr→ryz、w187→c18o、z4t→jtn、vgt→rkt、Bmt→Ezt、Qjt→Fjt、txt→Gjt、k15b→s15n、azi_1→vzr_1…)

- 移植 7 处针对性修改:炮塔摆头不回弹(vSt.ryz)、摆头不过冲(case 0)、精准跟手(case 1/2)、悬浮底盘 raw 两级(Ezt.n36 + Zmt 实际速度)、电磁炮蓄力时长(jtn.c18o)

- 重新打包 unpacked.pack.json(127 文件 / 版本 96833eb2b0cf8909)
2026-10-16 14:20:15 +08:00
TermiNexus ab4c31311c fix(relay): 上游握手不再发送 Referer(对齐浏览器真实握手)
- 依据:官方 Copy-as-cURL 的握手头里没有 Referer —— 浏览器发起的 WebSocket 握手本身不带它

- 实测:用原版头直连 wss://c1.3dtank.com:9090/ 可保持连接(8s 超时退出);而中继因多带 Referer 被上游 code=1000 关闭(短命连接)

- 仅删 Referer;Origin 仍强制覆盖为 https://3dtank.com(本机 origin 会被上游拒)
2026-10-15 16:27:34 +08:00
TermiNexus 1b487fbdd6 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 记录备用
2026-10-15 16:19:35 +08:00
TermiNexus 941dde0913 fix(relay): 按首帧分流上游 —— Hash Request 走 c2(大厅),EnterSpace 走 c1(二次进空间)
- 取证:短命连接是「复用首个会话哈希、跳过 Hash Request 直接 EnterSpace」,被服务器 code=1000 关闭(约 1.2 秒);完整握手的连接可稳定存活(2 分半)

- wss_server:上游改为「首帧到达后再建」——StreamDecoder 记录 FirstCmdId,首帧 ID=3 走备用上游、其余走主上游;首帧仍走 Pending 原序补发

- 新增 --upstream-alt / -UpstreamAlt(默认 wss://c1.3dtank.com:9090/)
2026-10-15 16:16:16 +08:00
TermiNexus cca13974de 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
2026-10-15 14:09:25 +08:00
TermiNexus 512c718d38 feat(hornet): 十字军底盘控制探针 + 中继 config.xml 动态改写
- 新增 sockets/probe_chassis.js:采样 Cyt.j14k_1 / Zmt.r14f_1 三轴并 hook Cyt.wak / Zmt.wak,转储到 names/probe_chassis.log

- serve.js:新增 /probe_chassis.js 路由与 /__probe__?f= 落盘选择;新增 --relay-port 动态改写 config.xml 指向本机中继(不落盘、不依赖 local/config.xml)

- main.9f4e7a89.js:探针块改为自动加载 railgun + chassis 两个探针

- Start-LocalAndRelay.ps1:-WithRelay 改传 --relay-port,修复「前端未走中继」的根因
2026-10-13 17:14:22 +08:00
TermiNexus 12e547f32f docs(3DTank): 电磁炮锁定蓄力改造的计划与进度(机制/门槛/改动/待办/教训)
含:z4t 三条上行(amr/o1ag/tnl)、三个时长(w1al/w187/x187)、FSM(TWt/vWt)结构、实测门槛(1.5s 最低满伤)、已落地改动与 commit 列表、离线解码流水线命令、关键行号速查。
同批提交 decode_space_frames.js 的 --side s2c/c2s 选项(MD 里的解码命令依赖它)。
2026-10-12 11:20:34 +08:00
TermiNexus 651e29f8b2 feat: 探针改整帧 hex 记录 + 新增 probe_log_to_bins.js 接现有解码流水线
- sockets/probe_railgun.js: SEND 记录整帧字节(流密码跨消息连续,截断/丢帧会导致后续解密全错)
- 3DTank/tools/probe_log_to_bins.js: 把日志里的 c2s 帧还原成 <out>/<label>/session_001/c2s_*.bin,供 decrypt_frames.js → dump_plain.js → decode_space_frames.js 复用
2026-10-12 11:11:57 +08:00
TermiNexus dfdd69b375 feat(mirror): 探针自动加载并转储(/probe_railgun.js 路由 + 加载器引入)
- tools/serve.js: 新增 /probe_railgun.js 路由,读 sockets/probe_railgun.js
- main.9f4e7a89.js: 等 __gameMode__ 就绪后自动 fetch+eval 探针(localStorage.hornetProbe='0' 可关闭),数据走 POST /__probe__ 落盘 3DTank/names/probe_railgun.log,省去每次手粘控制台
2026-10-12 10:23:07 +08:00
TermiNexus 2b95e5de28 chore(3DTank): 新增页面内探针的网络转储通道(/__probe__ + probe_railgun.js)
- tools/serve.js: POST /__probe__ 追加写 3DTank/names/probe_railgun.log
- sockets/probe_railgun.js: 电磁炮/武器链路现场探针(组件清单 + 采样 + WS 上行帧),fetch 批量转储,POST 不通自动回落控制台
2026-10-12 10:13:32 +08:00
TermiNexus 0c55021479 fix(origin): Origin 修正为 https://3dtank.com 并回退误改的 c2 上游
- 中继/代理 origin 由 https://3dtank.com/play/ 改为 https://3dtank.com(Origin 规范只到源、不带路径);referer 保持完整地址 https://3dtank.com/play/
- 上游与 /config.xml 回源回退到 c1.3dtank.com:9090:战斗必须连 c1,改 c2 会让前端战斗连 c2 而无法使用
- wss_server.js 新增「上游握手头」诊断日志,区分「浏览器→中继」与「中继→上游」两段
- README 同步
2026-10-12 00:19:04 +08:00
TermiNexus dd2c6c4c16 change(origin): Origin/Referer 改为 https://3dtank.com/play/(中继上游强制覆盖 + 镜像回源)
- wss_server.js:上游握手头的 origin/referer 不再透传前端值(前端带的是本机 http://localhost:8080),改为强制覆盖为 https://3dtank.com/play/;其余请求头仍整包透传

- serve.js:代理回源(/resources、/config.xml)的 origin/referer 同步改为 https://3dtank.com/play/
2026-10-11 22:21:14 +08:00
TermiNexus ae4d4ee055 fix(mirror): ws 抓包开关改为 serve.js --ws-hook(不碰 URL),避免 hash 破坏游戏路由
- 实测:URL 里任何 hash(包括 #hook/#nohook)都会让游戏进不去战场(游戏用 location.hash 做路由/状态),所以弃用 hash 开关

- serve.js --ws-hook:服务 HTML 时注入 /ws_hook.js;Start-LocalAndRelay.ps1 加 -Hook 开关;ws_hook.js 支持 localStorage.hornetWsHook=0 临时关闭

- index.html(本地)移除静态 ws_hook 引入
2026-10-11 21:43:12 +08:00
TermiNexus f3cd1aae67 feat(mirror): 恢复 /ws_hook.js(页面内旁听抓包,无需 SW,URL 加 #hook 才启用)
- 抓包不再依赖 Service Worker:浏览器仍直连服务器,不改传输、不改模块加载,服务端看不出差别

- index.html(本地,未入库)重新引入 ws_hook;SW 保持移除状态
2026-10-11 20:32:31 +08:00
TermiNexus 6d229abfb2 change(mirror): 撤掉 /ws_hook.js 路由与 index.html 引入,恢复默认无 hook
- serve.js 删除 /ws_hook.js 路由,该路径回落 404(sockets/ws_hook.js 文件保留在仓库,需要时再加回路由)

- index.html(本地,未入库)去掉 ws_hook 的 script 引入
2026-10-11 20:17:38 +08:00
TermiNexus 418298e2ec feat(mirror): 页面内 window.WebSocket 抓包(/ws_hook.js),用于与中继转存逐帧对比
- sockets/ws_hook.js:hook window.WebSocket,按收发顺序记录 {d,t,n,b(base64)};__ws_save__() 存到 3DTank/names/,离开页面自动 sendBeacon;#nohook 关闭

- serve.js:根路径提供 /ws_hook.js(no-cache)

- web/index.html:在主脚本之前引入,确保先于游戏创建 WebSocket
2026-10-11 20:04:23 +08:00
TermiNexus bd35ca1c12 chore(relay): 会话起始打印浏览器握手头(cookie/protocol/extensions/referer)用于诊断 2026-10-11 19:59:52 +08:00
TermiNexus 8c7f87b58f fix(relay): 上游握手整包透传客户端请求头并镜像子协议,对齐浏览器直连
- 除 Host/Connection/Upgrade/Sec-WebSocket-* 外,客户端握手头全部原样带上(Cookie / Origin / User-Agent / Referer / Accept-Language / Sec-Fetch-* 等)

- Sec-WebSocket-Protocol 改走 ws 的 protocols 选项,由 ws 负责协商校验
2026-10-11 19:54:22 +08:00
TermiNexus 5dd5560090 fix(relay): 透传客户端真实握手头(Origin/UA/Referer),消除与浏览器直连的唯一差异;镜像加 #nosw 旁路
- 上游改按 Req.headers 的 origin/user-agent/referer 透传(缺省才回退常量),避免上游按 Origin 返回与本地构建不匹配的响应(客户端握手失败自行 close=1005)

- main 加载器与 split.js 模板同步:hash 含 #nosw 时注销已注册的 Service Worker,便于排查镜像页接管问题
2026-10-11 19:47:19 +08:00
TermiNexus ad2b069659 fix(relay): 转发回退到速度优化前的可用实现(原样直发 + 竞态帧暂存补发),仅保留异步有序落盘
- 移除会话级 socket 反压暂停/看门狗/重连重试:该改动会让握手帧在内核缓冲里卡住,表现为前端反复新建 wss、进不去战场

- 恢复:客户端帧原样直发;上游未就绪时暂存 Pending,open 后按原序补发;上游关闭即关客户端

- 保留:落盘走单条有序异步写队列(默认开启),崩溃可见性兜底
2026-10-11 19:39:50 +08:00
TermiNexus 4005213226 feat(tools): 新版本工具链移植 + 本地镜像单包加载,中继改为原样直发与异步有序落盘
- hornet 工具链:无 ght 启动;透视冻结节点拖拽跟随、金箱标记、性能优化;雷达死亡红叉;鼠标稳定器;窗口布局持久化

- 本地镜像:切割与单包加载(pack_unpacked.js)+ SW 单包缓存 + F5 兜底刷新;入口更新为 main.9f4e7a89.js

- 中继 wss_server.js:转发改 socket 反压的原样直发(零等待零缓存);落盘改单条有序异步队列(默认开启);新增反压看门狗(默认 60s)
2026-10-11 19:35:54 +08:00
TermiNexus 2299b0996b fix(server): 组帧漏写帧级 nullmap 位,opt 字段改值会产出错位帧(M10 回显的真因)
space.js 的 BuildInitFrames 自己逐条调 Container.Write / Semantic.EncodeRecord 出负载,再把模板的 NullmapHex 原样带上。但帧级 nullmap 是所有记录共用的一串位(每条记录 1 个形态位 + 每个 opt 字段 1 个空/非空位,按编码顺序排),只有 semantic.EncodeFrameBody 持位游标(容器与字段两条路径都会推进 Ctx)。于是「把 opt<T> 由空改成有值」时负载多出 T 的字节数而 nullmap 位仍是 1(=空),解码侧按位读到空、把那多出来的字节当成下一条记录头 —— 实测 devicesLoaded 的 mountedDevice 由 null 改成设备 id 时帧 255848B→255856B 且 Bad(29 条记录只解出 7 条)。M7 覆盖 mountedItems 时没暴露,是因为 list<T> 改长度不占 nullmap 位(长度编在负载里)。改法:BuildInitFrames 把记录按模板形态原样交给 Semantic.EncodeFrameBody(容器 → Layout+Value、字段 → Fields、解不动 → Hex、旧模板的现成 Payload 仍透传),由它按编码顺序重建 nullmap 位;没传 semantic 实例时保留旧路径。验证:字节中性 —— names/ 下全部模板(init+session,61 帧)改动前后逐字节相同 61/61;修复有效 —— 把 s2c_0004 槽位 920009631046 的 mountedDevice 由 null 改为设备 id 后,帧 +8B、解码 29 条记录 Bad=false、nullmap 长度不变且恰好 1 个字节变化、其余 27 个槽位 0 处变化;回归 —— semantic.js --demo 全部断言通过(含「space.js 组帧 == 参考字节」那条)、selftest 逐字节一致 1108/不一致 9/解码中断 90、CompareContainerDecode 5 帧/26950/0。
2026-09-18 13:38:28 +08:00
TermiNexus 356647937e feat: M9 枚举线形序数 enum#N 解析成成员名(category 显示 ARMOR/WEAPON/PAINT…)
数据:evidence.json 的 byModule.<模块>.enums = { 枚举短名: [{field, member, value}] },全局 348 类 / 2633 成员。查表键定为 (字段所属模块, 枚举短名, 序数):同模块内短名天然唯一;跨模块同名 11 个短名 / 9 个同名异义,键含模块号即可隔离。全表 102 条 enum<X> 引用的定义模块均由字段的 TypeCodec 唯一确定(无冲突、未解 0),导出后落盘 77 类 / 1343 成员(33879 字符,整表增量 33894)。两层分离(本任务核心约束):协议层原始值仍是 enum#N,一字不改,因此 CompareContainerDecode.mjs 的逐字段对照口径不变;EnumNames 只在 UI/日志/dump 里翻译,查不到返回 null 并由调用方标「未解」,不猜。category 实测(15 件仓库物品全部解出):ARMOR#1 / WEAPON#0 / PAINT#2 / BAZOOKA#13 / DRONE#8 / INVENTORY#3 / INVISIBLE#9,真实 5 件挂载物品类别互不相同 —— M8 结论不变。UI 与日志显示「成员名(enum#N)」。顺带修正 GarageDriver 接线:上一轮把 URL 硬编码成 9092 且日志 label 写死 store-02,改为环境变量 TANKIC_WS_URL(默认 9091)与 TANKIC_LOG_LABEL(默认 store-03),否则「配对表 ⇔ 服务端日志」会找错目录。验收:CompareContainerDecode 5 帧 / 一致叶子 26950 / 不一致 0(硬门槛);server selftest 逐字节一致 1108 / 不一致 9 / 解码中断 90;三构建全绿;浏览器实测 15/15 类别显示成员名。未解:枚举成员名未覆盖 list<enum<X>>/opt<enum<X>> 的元素级。
2026-09-18 12:59:45 +08:00
TermiNexus 4277e0ae08 feat: M8 查明物品类别来源并实现同类互斥(切武器时旧件自动卸下)
类别来源(完整链):挂载 reducer IB.yr9 用物品的 qr3_1 查类别表;qr3_1 = oB 构造第 4 参 = n.yr6_1.ici_1;yr6_1 来自 pt 里 model 类 Ij 那一项 = modelId 6117306895090150422(module_85196::Lo,字段名就叫 category)。交叉验证:真实 5 件 mountedItems 的类别 {enum#1,enum#0,enum#13,enum#2,enum#8} 互不相同 → 规则成立;并确认 M7 留下的第 6 件 920009631018 与 920009631039 同为 enum#1(都是底盘),正是 M7 缺口的体现。排查并排除:不是本地静态表;GarageSelectItem 的 Yy/Xy/ek/Wy 是另一套枚举(模型 ox/2114179554921095892 的 pr3_1),与挂载互斥无关。实现:schema 加 Items.Category + 索引;新增可重跑的 backfill_category.js(从 ObjectModels 回填,支持 --dry),992 件全部回填;store.SetMounted 改为「先卸同类、再置新件」且幂等,日志打印「同时卸下 N 件同类」;客户端 ClientState.MarkMounted 同步互斥(与 IB.yr9 同顺序),UI 每行显示类别。验收:连装两件 enum#1 → 库中只剩后者(日志「同时卸下 1 件同类」);浏览器 a11y 快照前后对比正确;回归 selftest 1108/9/90、CompareContainerDecode 5 帧 0 不一致、三构建全绿。未解:enum#N 只是线形序数,枚举成员名未解出,库里一律存原始令牌 enum#N。
2026-09-18 12:26:01 +08:00
TermiNexus ab1a905d28 feat: M7 点装备即落库,重启服务端后仍回显(闭合「能切换但没持久化」)
客户端:Uplink 加 M_.fcn 构造(6 条抓包样本逐字节相同)、仓库每行加「装备」按钮、Equip() 入队 + 本地乐观标记(对齐真实客户端的 jU reducer)。服务端:store.js 加 LoadMountedFlags/SetMounted(UPDATE ... WHERE Mounted<>1,幂等)/OverrideMountedRecord;session.js 加可选 RecordOverride 钩子;index.js 进车库时刷新快照、收 M_.fcn 落库。回显只在库与模板有差异时覆盖并打日志(装备前帧仍与抓包逐字节一致 775441B;装备后 775449B,+8B = 多一个 i64)。验收:浏览器点装备 → 服务端落盘 c2s_0064.bin 与抓包 c2s_0141.bin 逐字节相同;MySQL Items.Mounted=1 共 6 行;重启 9092 后启动日志显示 Items.Mounted=1 共 6 件、重进车库 UI 6 个装备按钮置灰与库一致。回归:selftest 1108/9/90、CompareContainerDecode 5 帧 0 不一致、三构建全绿。未实现并如实记录:类别互斥(物品类别来源未解出,不硬猜)、挂载位设备 mountedDevice 未处理。
2026-09-18 12:01:30 +08:00
TermiNexus 61b57a3d11 docs(3dtank): 架构逆向:模块依赖图、6 条运行链路、TOState↔reducer 映射
names/module-graph.json:126 模块的 Kind/职责/依赖/导出/锚点,533 条依赖边,入口 13431(出度 46,依赖链深 17 层)。docs/ArchitectureModules.md:依赖图摘要 + 40 个游戏模块逐条 + 依赖分层(由数据生成)。docs/ArchitectureRuntime.md:启动引导/网络层/Redux/UI 系统/资源与渲染/空间与对象模型 6 条链路,64 条关键函数([证据] 77 / [推断] 15)。names/tostate-map.json + docs/StateMap.md:TOState 实为 89 字段(非估计的 60),89/89 由「toString 字段→槽位」与「根 reducer v8 的实参顺序→ntb 形参→w8 字段顺序」两条独立链路交叉验证,唯一未映射的是只读的 launchParams。
2026-09-18 09:30:30 +08:00
TermiNexus 4eff6bb315 chore(3dtank): 模块职责表规范化并修正两处误标
dir.file 改写为规范表格(126 模块 + 2 个资源文件),补「分类」「需反混淆」两列;分类计数与 module-graph.json 的 Stats.ByKind 逐项对齐(游戏本体 40 / Kotlin生态库 21 / 第三方库 65)。修正两处被标反的职责:module_96480 实为 inline-style-prefixer 的 transition 前缀插件(原标 Underscore.js 1.13.6);module_94965 实为 Underscore.js 1.13.6(原标 ReactHTML 标签构建器),分类随之由 Kotlin生态库 改为 第三方库。
2026-09-18 09:30:29 +08:00
TermiNexus 812d3702a5 chore(3dtank): 清理工作区可重建产物,360MB -> 199MB
删除的都是能重新生成的:cache/(124MB,serve.js 代理缓存)、src_named/(18MB,apply_names.js 重建)、旧 server-logs(19MB,保留当前在用的 store-02)、tools/symbol_map.json(8.9MB,map_symbols.js 重建)、names 下的报告产物(flow.json / commands.json / commands_decrypted.json / decoded_frames.txt,各自工具可重跑)、运行产物 missing.txt / sendlog.json,以及根目录杂项 1 / curlcmd / i.html。

保留:packets/(真实抓包证据,不可再生)、src/(权威解包)、web/(跑本地客户端要用)、names/ 协议表(工具输入,注意 model_table.json 是 probe_containers.js 的输入,没删)。
2026-09-17 20:05:12 +08:00
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
TermiNexus de3dbbc097 fix(3dtank): dump_plain 静默丢帧:明文尾部被巧合密钥当成加密段
- Solve 只按第一个可用 Start 提前返回,实测 mine-01/session_001 的 59 条 c2s 全是明文整帧,
  却被巧合的 K=31 判成「加密段只切出 1 帧」,只 dump 出 13 条(还多出一个解不开的假帧)
- 加两条护栏:① 剩余消息自身都是完整帧时不再尝试解密;② 多个候选取 Start 最大的那个
- 加覆盖度自检:解出的帧没覆盖到每条 WS 消息就在 summary 里显式报 ⚠

重跑 mine-01 入库:回放库 7 个目录 → 18 个,帧数 13621 全量为整帧、
33 个压缩帧全部解压成功(原先 session_001 的假帧已消失)
2026-09-16 17:35:55 +08:00
TermiNexus 8d2aa5566d feat(3dtank): 解出容器「模式表」头部并约束内层扫描
- ContainerSchema:容器负载头部 = [i32 a][i32 b][i64 objId][i32 N][N × i64 modelId],
  这 N 个 modelId 就是容器里出现的模型(登录批次/聊天批次/商店各自对得上)
- InnerScan 支持模式表:只认表里的模型且按表内顺序出现,内层「吃满边界」60% → 70%,假命中基本清掉
- 容器负载打印模式表模型名;README/注释补已核实结论与未闭合环节
2026-09-16 16:38:24 +08:00
TermiNexus 2e5e8bd7b0 feat(3dtank): 协议工具链入库:上行命令接入 fake server + 字段表/WireClasses
- wss_server:识别 c2s 空间命令([nullmap][objectId i64][methodId i64][负载])并逐字段解码
- 应答签名改用 S:<methodId>(pair_flow.js 同步),fake 模式能按具体上行命令触发对应下行回放
- extract_codec_fields:新增「协议核心类 → 线上基础类型」挖掘(WireClasses,xr/R → i64)
- lib_space_codec:按模型真名/核心类换算兜底(ji → i64、xr → i64),抽成上下行共享库
- decode_space_frames:记录容器(_t/lt)已核实结构与未闭合环节
- README:补「协议逆向与离线模拟」章节(帧格式/字段编码/命令表/fake 回放/容器现状)

实测:297 条上行记录 100% 完整解出;fake 模式按 G.q1wd、ls.xbl 等命令精确触发应答
2026-09-16 16:30:38 +08:00