Commit Graph
100 Commits
Author SHA1 Message Date
TermiNexus f455fe5c35 feat(ignore): x9o 路径改为忽略本车与任意静态形状的相交查询
接触路径(q9q)仍只忽略立面三角形以防掉地;形状相交查询(x9o)对本车与任意静态形状返回 false,覆盖扫掠/查询式阻挡;新增 skippedOverlap 计数。
2026-10-21 00:42:54 +08:00
TermiNexus 0e8af39bfe feat(ignore): 同时接管形状相交查询 x9o(真形状检测)
栅栏判定同时作用于接触配对 q9q 与形状相交查询 x9o:命中时返回 false(不相交),覆盖扫掠/查询路径;新增 skippedOverlap/overlapPatched 统计;schema 补 CollisionWorld.Overlap。
2026-10-21 00:42:28 +08:00
TermiNexus 0ca28ff9b2 feat(autotest): 新增双连接接入测试与链路密钥探测
- AutoTest:大厅 Hash Request → 取 digest/空间 id → 空间连接 EnterSpace → 收空间帧
- StreamDecoder:首条密文即穷举单字节链路密钥(K),之后 s2c 自动解密
- 首条空间帧到达后再加密发送 G.q1wd,服务端才会继续下发容器数据
- RunAutoTest.ps1:自动拉起大厅/空间两条中继,跑完自动回收
- 实测通过:握手成功、K 唯一命中、容器 1 条、回编码一致
2026-10-21 00:38:59 +08:00
TermiNexus 2ba8df0245 fix(ignore): 只忽略立面三角形,type 1/4 静态代理不再跳过(修复掉地)
实测 byType={16/4:26530,16/1:4620} 表明被跳过的是非三角形地形代理,导致穿地。现判定只对 type=8 三角形生效:最高点高于车体中心 1m 且 |法线z|<0.6;非三角形静态一律保留。
2026-10-21 00:36:30 +08:00
TermiNexus 580a456032 fix(ignore): 栅栏判定加入高度门槛,避免把地面一起忽略导致掉出地图
上一版 skippedFence 达 4.6 万,说明地面三角也被忽略。现规则:静态形状最高点必须高于本地坦克中心 1m 才可能是栅栏;三角形再要求 |法线z|<0.6。新增 byType 统计(cat/type → 忽略次数)便于确认命中对象。
2026-10-21 00:32:24 +08:00
TermiNexus bfc3821dc7 fix(ignore): 恢复非三角形静态碰撞的忽略,栅栏恢复可穿过
上一版把判定收窄为仅陡峭三角形,导致非三角形静态代理(栅栏碰撞体)仍会挡住本地坦克。现判定:静态几何中非三角形一律忽略;三角形按 |法线z|<0.5 忽略,地面/缓坡保留。
2026-10-21 00:30:00 +08:00
TermiNexus 69defa85e7 feat(ignore): 栅栏诊断输出重叠物体信息(形状 + 邻近场景节点名)
保持原有几何判定(仅陡峭静态三角形);DebugFence(true) 后,本车与任意非坦克形状配对时按签名去重打印 cat/type/法线/位置/7m 内场景节点名,用于确认栅栏对应哪个物体;schema 补 Body.State/PositionVec。
2026-10-21 00:25:16 +08:00
TermiNexus 63c08ab165 fix(ignore): 放宽栅栏判定并加入静态形状诊断
静态障碍不再只认三角形:非三角形静态碰撞代理直接视为障碍,三角形按法线 |nz|<0.5 判定;新增 __hornetNoClip__.DebugFence(true) 打印静态形状样本(cat/type/三角/nz/是否跳过),用于定位未生效原因。
2026-10-21 00:18:51 +08:00
TermiNexus f3db51cf4b feat(protocol): 补齐容器命令与短命令别名机制
- Containers.kt 实现 lt/pt/zt/alias 四种布局,覆盖 ModelService 4 条容器命令
- 生成 ModelRegistry.ByModelId,供 pt 项按 modelId 展开
- 短命令:_setModelCommandAlias 解码后写入别名表,记录链可按别名继续解
- 下行注册补到 681 条;railgun-battle 400 帧复跑仍为 399/399 回编码一致
2026-10-21 00:13:12 +08:00
TermiNexus 7481dad24e feat(ignore): 面板新增「忽略」区域(坦克按阵营 / 反弹 / 栅栏)
hornet_noclip 改为通用忽略模块:配对过滤支持 关闭/仅敌方/仅友方/全部 的坦克忽略,并新增忽略栅栏(只跳过 |法线z|<0.5 的静态三角形,地面与缓坡保留);面板新增可折叠「忽略」区域,接管忽略坦克下拉、忽略反弹(NoKnockback)、忽略栅栏,各自 localStorage 持久化;schema 补 Shape.Type/Vertex0-2。
2026-10-21 00:04:38 +08:00
TermiNexus 5088524f22 feat(tankioffline): 搭建 Kotlin/JS 多模块工程与 S2 全量协议层
- 新增 TankiOffline 多模块骨架(app/core/net/ecs/physics/render/resource/state/battle/ui)
- core 实现帧边界、nullmap 位流、大端读写、varint、fflate 解压
- GenerateProtocol.py 从 names 表生成 644 个模型、679 条下行、361 条上行 Kotlin codec
- 手写 TankState 的 23 字节位打包 codec(真实注册点是 module_87072 的 T5)
- app 增加 Node golden 自检:抓包解码后立即回编码逐字节比对
- 实测 plain/railgun-battle 400 帧:399 条记录全部回编码一致
2026-10-21 00:03:18 +08:00
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 66a74df6e3 refactor(schema): 全部工具改为经字段抽象层取值
hornet_lib / hook_gamemode / radar / 透视 / 后视镜 / 瞄准警告 / 自由视角 / 战争沙盘 全部改为 Fld/Mth 常量取值;schema 补齐渲染器、网格、射线、武器、皮肤槽位等 88 项字段与别名;SelfCheck 改为只校验核心字段,避免别名误报。
2026-10-20 22:04:07 +08:00
TermiNexus 5a3440229e fix(noclip): 改为拦截碰撞配对,修复关闭后拾取物失效
穿坦克不再修改碰撞 mask(坦克 category 与拾取物触发体共用 bit0,清位会导致拾取失败且关闭后需重生才恢复)。改为包装 module_55088 碰撞世界 ki.q9q,仅跳过双方都是坦克物理组件的配对:地形、拾取物触发、地雷、子弹均保持原样,关闭开关无需还原状态。
2026-10-20 20:39:29 +08:00
TermiNexus bea22bb5f9 feat(noknockback): 新增拒绝击退开关,中弹不再被推开
在本地坦克实体的 kz7 事件派发处丢弃外力事件(ODt:作用点/方向/强度),坦克物理收不到就不产生位移与旋转;悬挂与行驶仍走 m9k 直调,不受影响。面板新增「拒绝击退」开关。字段名走 hornet_schema。
2026-10-20 20:35:19 +08:00
TermiNexus 692b812e58 fix(schema): 自检跳过常量项,避免 Team.NeutralId 误报失配 2026-10-20 20:18:26 +08:00
TermiNexus 972928e848 refactor(schema): 新增字段抽象层,透视滤除非本车节点并重做敌我判定
新增 hornet_schema.js 集中维护匿名引擎字段映射与导出键,支持 SelfCheck 自检失配;透视兜底扫描增加车体距离闸门,只保留跟着本车动的节点;敌我改为按队伍编号(k3_1)每帧比对,中立时沿用上次结果,取消一次判定永久锁定;穿坦克改用抽象字段名。
2026-10-20 20:18:14 +08:00
TermiNexus 6e79057856 feat(noclip): 新增穿坦克工具并接入面板开关
清掉本地坦克碰撞形状 mask 的坦克位(bit0),可穿过其他玩家坦克;地形静态几何(category bit4)碰撞保持不变。引擎状态切换会重写 mask,运行期每帧补一次,停止时按原始快照精确还原。
2026-10-20 20:06:24 +08:00
TermiNexus fcc4901a1f feat(garage): 战局空闲预热车库资源,静态资源启用长缓存与异步读 2026-10-20 16:48:41 +08:00
TermiNexus ce1ffbeb60 fix(team): 队伍函数按需补加载,开局即用可靠基准锁定敌我 2026-10-20 14:28:00 +08:00
TermiNexus f07f182fd8 fix(team): 本地队伍缓存不再随 gm 重建清空,并锁定单局敌我结果 2026-10-20 13:43:21 +08:00
TermiNexus 781ba862b7 fix(alive): 存活判定改用引擎 s14j()(含 TELEPORT),死亡坦克稳定过滤 2026-10-20 13:02:03 +08:00
TermiNexus 8906ba6764 fix(team): 队伍同步延迟时沿用上次判定,消除敌我颜色跳变 2026-10-20 13:01:01 +08:00
TermiNexus 62357fcd9f fix(radar): 恢复死亡坦克的红叉标记(含血量辅助判死) 2026-10-20 11:29:47 +08:00
TermiNexus 2520a91bf1 fix(team): 队伍基准改用本地拥有坦克并缓存;死亡坦克不再标记 2026-10-20 11:20:38 +08:00
TermiNexus 82ee3fd8a4 fix(client): 下发 host 为空时还原为 cN 服务器地址,修复进战斗短命连接 2026-10-20 11:19:09 +08:00
TermiNexus aa3bcba363 fix(wireframe): 扫描结果按字段路径缓存并每帧合并,补齐炮塔与车体漏采 2026-10-19 22:52:33 +08:00
TermiNexus 41b94ef0f9 fix(wireframe): 去重键去掉世界坐标并取消扫描节流,修复模型闪烁 2026-10-19 22:37:31 +08:00
TermiNexus a83f2a5407 feat(ws-hook): 控制台实时打印每个 WebSocket 的地址、关闭码与存活时长 2026-10-19 22:36:34 +08:00
TermiNexus 797f28c8cd fix(wireframe): 采集改为单路径优先并按 mesh+位置去重,修复重复身体与卡顿 2026-10-19 22:32:10 +08:00
TermiNexus af8cde08d2 fix(wireframe): 车身改用皮肤根节点并合并结构扫描,修复漏采与只剩炮塔 2026-10-19 22:08:33 +08:00
TermiNexus 526adc760c fix(wireframe): 顶点/索引优先读 CPU 端缓冲区,修复未上传 mesh 采集失败 2026-10-19 21:45:54 +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 1dd7143e67 fix(wireframe): 去掉炮塔门槛并加实体节点扫描兜底,修复只有点没有模型 2026-10-19 20:14:47 +08:00
TermiNexus dcf9a57456 fix(wireframe): GPU 顶点/索引缓冲字段按新版重定位,恢复模型采集 2026-10-18 19:37:43 +08:00
TermiNexus 86b9322a9f fix(wireframe): 按新版字段修复模型采集与敌我判定 2026-10-18 19:10:22 +08:00
TermiNexus 4d8cbd81d6 chore(sw): 本地镜像禁用 Service Worker(自注销旧注册 + 置空游戏 SW 注册模块) 2026-10-18 19:00:52 +08:00
TermiNexus a34cae5474 fix(tools): 按新旧差异修复位置与相机链路(雷达/透视恢复绘制) 2026-10-17 16:50:54 +08:00
TermiNexus 9506648877 fix(lib): 位置探测增加矩阵式兜底([12],[13],[14] 平移分量)
- 旧版位置来自物理组件的世界变换矩阵(K$ 实例,非普通向量),新版字段平移后无法靠名字命中

- 兜底 2:遍历组件找长度 >=15 的矩阵对象,取 [12]/[13]/[14] 作为平移(引擎惯用布局)
2026-10-17 16:29:06 +08:00
TermiNexus 67b2ff4a80 fix(lib): 坦克位置改为多级字段探测(修复雷达/透视为空)
- 根因:物理组件的位置向量字段每构建都平移,本次 pz7_1→gzh_1→rzf_1 的映射全都指错(gzh_1 是 TerminatorCC、rzf_1 是 RicochetSfxData)

- GetTankPosition 改为多级探测:先试一组成员字段(xzq_1/uzq_1/azr_1/bzr_1/dzr_1/izr_1/jzr_1…),再兜底遍历组件找带 f20_1/g20_1/h20_1 的 O\$ 向量

- 透视的坦克绘制与金箱位置都改用 GetTankPosition
2026-10-17 16:19:54 +08:00
TermiNexus 1cc1afdb08 fix(hook): GameMode hook 目标改为新版导出键(jc/ic),修复所有工具静默失效
- 根因:新版导出键语义漂移 —— \$.ac 变成两字段数据类 \、\ \$.zb 变成 ydt,不再是「取 gmt 实例 / ght 类」

- 新版对应关系:\ \$.jc = dct(scene) 取 ght 实例;\ \$.ic = wct 即 ght 类;\ \$.kc = gct(scene) 取 GameMode 实体

- hook 目标改为 \ \$.jc,并继续 hook wct.prototype 全方法作为兜底

- 重新生成 hornet_bundle.js 并同步 unpacked
2026-10-17 15:57:40 +08:00
TermiNexus 56a1356cce fix(tools): 补全新版符号替换(修复透视/雷达仍不可用)
- 双向校验误判:q100_1 / r11l / jyw / t101_1 在新版同名但含义不同(普通数值 / 别的方法),被当作未变而跳过

- 强制替换:q100_1 到 m10b_1(坦克管理)、r11l 到 j11y(坦克列表)、jyw 到 lz4(取实体)、t101_1 到 p10c_1

- 覆盖 hook_gamemode.js(文件名不匹配 hornet_ 被漏掉)

- 物理组件字段 gzh_1 改为 rzf_1(新版 gzh_1 已是 TerminatorCC 字段,非物理)

- 移除已不存在的 xyu(GameMode),改用 gm.lz4()(等价:取 GameMode 实体)

- 重新生成 hornet_bundle.js(10 模块 / 249229 字节)并同步 unpacked
2026-10-17 15:49:50 +08:00
TermiNexus dcf5dfce5c fix(tools): 工具链符号对齐新版 bundle(修复 HORNET 功能大面积失效)
- 根因:新版 main.7cfa4058 重拆后游戏符号整体平移,工具里写死的字段名(pyt_1/q100_1/r11l/oyz/jyw/cyw_1/dyw_1…)全部对不上 → 找不到组件/相机/场景

- 新增 tools/apply_symbol_map.js:按 map_symbols 映射批量替换,4 道安全规则:① 长名或含下划线 ② 排除 JS 关键字/内置名黑名单 ③ 游戏符号命名特征(含数字或 _数字 结尾) ④ 双向校验(旧名在新 bundle 仍存在→视为未变跳过;新名不存在→映射错误丢弃)

- 单遍替换,避免链式污染(映射表新旧同名复用时会被二次替换)

- 应用到 12 个 hornet_*.js 共 231 处(跳过 25764 个未变符号)

- 重新生成 hornet_bundle.js(10 模块 / 249263 字节)并同步 unpacked
2026-10-16 14:55:39 +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 cbeb78baba feat(page): 自动刷新拦截改为默认开启(便于查看 err toast)
- 原来默认关闭(需 localStorage.hornetBlockReload=1),游戏一遇到致命错误/断线就 location.reload() 刷页,err toast 一闪即没

- 现改为默认开启:localStorage.hornetBlockReload='0' 才关闭;F5 仍然放行一次

- 同步源文件 tools/split.js 与产物 main.9f4e7a89.js

- 注意:拦截期间游戏无法靠刷页重连,只能反复内部重连(临时排查用)
2026-10-16 14:14:51 +08:00
TermiNexus 6dbe6c6b24 fix(hover): 悬浮底盘 raw 速度补上第二级平滑器(Zmt.wak 的 m14f_1)
- 上一版只改了 Bmt.l36(目标速度那一级),实际速度还在 Zmt.wak 里经 m14f_1.x142 逐帧追赶,所以摆动依旧

- 速度链是两级串联:Bmt.y12d_1(目标速度)→ Zmt.m14f_1(实际速度),现两级都按 raw 直接锁目标

- 回退:window.__hornetHoverRaw__ = false
2026-10-15 18:51:41 +08:00
TermiNexus f8502a0726 feat(hover): 悬浮底盘改为 raw 速度(参考炮塔做法,消除无端摆动)
- 位置:module_87072 的 Bmt.l36(悬浮底盘每帧速度推进)

- 原逻辑:y12d_1/z12d_1 两个 vgt 平滑器按加速度 u143_1/v143_1 逐帧逼近目标 → 惯性来回摆

- 改为:直接 na0(w143_1) 把当前值锁成目标值(等同炮塔 qyr 的 i = this.azi_1)

- 回退开关:window.__hornetHoverRaw__ = false
2026-10-15 18:20:35 +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 529868b194 feat(wireframe): 3D 透视里给人机坦克标「人机」文字
- hornet_3d_wireframe:坦克绘制后在其上方投影并写「人机」(先描黑边再填黄字,任何背景下可读)

- 复用 lib.ScanBots / IsBot,节流约每 0.3 秒扫描一次;雷达的方块标记保留
2026-10-15 15:47:52 +08:00
TermiNexus 2b64211173 feat(radar): 人机识别标记(同队装备分数相同且 < 8000)
- hornet_lib:新增 GetGearScore(BattleGearScoreCC.score → 组件 cjf_1)、ScanBots(按队伍分组,同分且低于阈值判为人机)、GetBotSet/IsBot

- hornet_radar:约每 0.3 秒扫一次;人机画「灰方块 + 黄框」,真人仍「实心圆 + 白边」;顶部统计加 Bot 计数

- 重新生成 hornet_bundle.js 并同步到 unpacked
2026-10-15 15:27:34 +08:00
TermiNexus 92b5ca6e9b refactor(panel): 移除左上角常驻 HUD(「3DTank 控制台」小窗)
- tools/hornet_panel.js:HUD 不再挂载到页面(等于不显示),原样式与 appendChild 一并去掉

- 保留 hud 对象与 UpdateHud 循环:循环里还负责 TryAutoEnable()(按保存状态自动开启工具)

- 重新生成 hornet_bundle.js 并同步到 unpacked
2026-10-15 15:15:28 +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 9bce46a86e fix(loader): 断线重连死循环 —— location.reload 拦截改为默认关闭
- 游戏断线时靠 location.reload() 刷页重连;此前为看 err toast 接管了 reload,会把刷页吃掉

- 后果:游戏只能反复内部重连 + 反复拉 config.xml(表现为一直重连 c1 / 反复访问 xml,且只在断线时触发,故呈概率性)

- 现默认关闭;需保留页面看 err toast 时用 localStorage.hornetBlockReload='1' 临时开启
2026-10-15 13:47:35 +08:00
TermiNexus 86aa8bd9bd feat(turret): 炮塔精准跟手加死区消抖(滤掉悬浮底盘的 micro-motion)
- module_87072 oxt.wak case 1/2:目标角变化小于死区(默认 0.5 度)时不搬动炮塔

- 死区可实时调:window.__hornetTurretDeadZone__ = 弧度值
2026-10-15 13:35:39 +08:00
TermiNexus d4c5a89703 feat(turret): 炮塔摆头精准跟手(默认开启)+ 探针默认关闭
- module_87072 oxt.wak:case 1/2 直接锁到目标角,去掉速度追赶导致的追过头再回摆

- module_87072 weaponMount.qyr:去掉渲染层二次插值(dzi_1=azi_1、izi_1=gzi_1)

- 回退开关:window.__hornetTurretPrecise__ = 'off' / false

- probe_chassis.js:新增 oxt.wak / weaponMount.qyr 采样链路,用于定位过冲

- main.9f4e7a89.js:探针改为默认关闭(localStorage.hornetProbe='1' 开启)
2026-10-15 13:34: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 d4c8a843e2 feat(panel): 电磁炮锁定时长固定默认 1.5s(面板默认开启覆盖)
面板回填逻辑改为「未显式关闭即开启」,默认值 1.5s(实测满伤的最小值);取消勾选仍可回退原版 3~5s。z4t.w187 的 HORNET-TAG 同步。
2026-10-12 11:08:01 +08:00
TermiNexus db8a92a2f7 feat(panel): Alt+T 面板新增「电磁炮设置」——锁定/蓄力时长可实时调
启用时长覆盖(checkbox) + 锁定/蓄力(s) 滑块 0.1~5.0/步进0.05,拖动立即写入 window.__hornetLockSec__ 并持久化到 localStorage(hornet_lock_on/hornet_lock_sec)。实测门槛:1.5s/2.0s 满伤,1.0s/0.1s 无伤害。
2026-10-12 11:01:36 +08:00
TermiNexus 1af3b3a7a3 feat(mirror): 电磁炮锁定时长支持运行时覆盖(window.__hornetLockSec__)
z4t.w187() 优先读 window.__hornetLockSec__(正数则用它),否则回退 gaussParams.njs_1;便于面板实时调值,不必重打包刷新。
2026-10-12 11:01:34 +08:00
TermiNexus 2d2a2c9f61 chore(mirror): 电磁炮锁定时长试 0.1s(极端对照,用于离线解码对比)
z4t.w187() 返回 LR(0.1);已知 1.5s/2.0s 满伤、1.0s 掉伤。HORNET-TAG 同步 0.1s。
2026-10-12 10:57:50 +08:00
TermiNexus 8e13aac99f feat(mirror): 电磁炮锁定时长 2.0s → 1.5s(二分探门槛)
z4t.w187() 返回 LR(1.5);2.0s 已实测满伤、1.0s 掉伤,门槛在 1.0~2.0s 之间。HORNET-TAG 同步为 1.5s。
2026-10-12 10:41:49 +08:00
TermiNexus e154c1ab14 fix(sockets): 探针 WS 字节读取兼容 DataView(此前 hex 恒为空)
游戏实际发的是 DataView(有 byteLength、无 slice),走 buffer+byteOffset 取视图;此前 new Uint8Array(dataView,0,24) 得到长度 0 视图,导致 SEND 行 hex 恒空。
2026-10-12 10:35:39 +08:00
TermiNexus 712d24e059 fix(mirror): 徽标抗 DOM 裁剪 + 探针块加自证日志
- 徽标每 2s 自检补回(游戏初始化重排 DOM 时会被删掉)
- 打印「版本徽标已注入」「探针块已执行(hornetProbe=…)」两条日志,便于区分是加载器没生效还是探针 fetch 404
2026-10-12 10:31:34 +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 09f8769585 feat(mirror): 电磁炮锁定时长 3~5s → 2.0s(z4t.w187,实测满伤)
z4t.w187() 返回 LR(2),不再取 gaussParams.njs_1;冷却 w1al()/x187() 未动(服务端按冷却裁决)。附 HORNET-TAG 供版本徽标显示。
2026-10-12 10:21:04 +08:00
TermiNexus bb3d76117a feat(mirror): 右下角版本徽标(包版本 + 从模块源码读出的 HORNET-TAG)
加载器记录 __hornetPackVersion__ 并渲染固定徽标;TAG 用正则从 __modules__[87072] 源码读取,避免手写常量与真实包不一致。
2026-10-12 10:21:03 +08:00
TermiNexus b63435d401 fix(sockets): probe_railgun.js WS 上行改异步读 Blob(此前 hex 恒为空)
游戏 send 的是 Blob,slice 后 new Uint8Array(Blob) 长度为 0,导致 SEND 行 hex 全空;改为 blob.arrayBuffer() 异步读前 24 字节。
2026-10-12 10:21:02 +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 d6758b14e1 fix(mirror): ws 抓包降到最小入侵(只包 send + on* 访问器,热路径只拷贝不编码)
- 不再包装 addEventListener(会破坏 removeEventListener 的按引用移除);游戏只用 onopen/onclose/onmessage

- 逐帧 base64 推迟到 __ws_save__(),去掉战斗入口的收发延迟
2026-10-11 21:31:16 +08:00
TermiNexus 240892c9b5 fix(mirror): ws 抓包改为原型级 hook(不动 window.WebSocket 构造函数),避免被游戏察觉
- 实测替换构造函数会让 WebSocket.toString() 不再是 native code → 进不去战场;改为只包 WebSocket.prototype 的 send / addEventListener / onmessage|onopen|onclose 访问器

- window.WebSocket 的名字/长度/toString/instanceof/静态常量全部保持原生
2026-10-11 20:54:38 +08:00
TermiNexus c021d5c164 fix(mirror): ws 抓包 ToBase64 分块降到 8192,远离 apply 实参上限
- String.fromCharCode.apply 会把参数数组整包展开成实参,块过大必爆栈(V8 上限约 6.5 万);原 32768 虽安全但偏高,降到 8192
2026-10-11 20:49:41 +08:00
TermiNexus 245e27e192 chore(mirror): ws 抓包未启用时也定义 __ws_save__,调用时提示加 #hook 2026-10-11 20:43:14 +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 d33e7b0eba change(mirror): 从模板中移除 Service Worker 注册(排查断联用)
- tools/split.js 模板与已部署 main 同步删除 SW 注册块;hornet_sw.js 本体与 serve.js 的 /hornet_sw.js 路由保留

- index.html(本地,未入库)加一次性注销,清掉已装的 SW(需再刷一次生效)
2026-10-11 20:16:07 +08:00
TermiNexus ba56ab9d7c change(mirror): 页面内 ws 抓包改为默认关闭(URL 加 #hook 才启用)
- 之前默认一直挂 window.WebSocket;为避免干扰排查(先排除 SW/hook 因素),改为显式 #hook 才抓;#nohook 仍可强制关
2026-10-11 20:14:40 +08:00
TermiNexus 562835c284 fix(mirror): Service Worker 默认关闭(URL 加 #sw 才启用),排查 SW 是否导致断联
- main 加载器与 split.js 模板同步:默认注销已注册的 SW(单包缓存接管),#sw 显式启用,#nosw 仍可强制关闭

- 注意:注销在下次导航生效,需刷新两次
2026-10-11 20:11:02 +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 2224ddc3f6 feat: M14 搬运官方车库 UI(官方应用壳 + DOM 运行时等价实现 + 车库主屏)
按用户要求改为「搬运式复刻」:版式与样式全部取自官方反编译代码 module_82347.js,逐条标注 file:line,不自行排版。壳:client/src/jsMain/resources/index.html 复刻 3DTank/web/index.html(6 个 @font-face = Rubik-*.woff / MPLUS1p-*.ttf、#preloader、#root.wrapper、#app-root、#modal-root、.bgClipText),有意差异(https 重定向脚本/analytics/isRussia 检测/manifest/favicon/官方 main.6469b966.js)已在报告标注,改为加载 TankIcClient.js。运行时 Ui/Official/UiDom.kt:等价实现 FD(parent,tag,styleFn)/iq(styleObj)->类名(注入 style[data-emotion])/WD/ip2/lp1/fp2 与单位值函数(E$=%, G$=px, O$=em, zj=rgba, rnr=em/16, cnr=rem/16, Ms 的 0 去单位),并注入官方 Emotion Global 表(module_82347.js:105411-105424 的 btr:html/body/.wrapper/portrait 媒体查询)——.wrapper 的 position:absolute;height:100% 不在 index.html 里,是车库 height:100% 成立的前提。车库主屏 Ui/Official/OfficialGarage.kt:按官方实例化路径(module_82347.js:161904-162084 的 gPn -> :166813-166828 的 hGn -> _Ln/PWn/PGn/_Wn)搬节点层级与样式函数,含 GarageCommonStyle/GarageMainScreenStyle/MountedItemsStyle 的片段;设备块按官方 PGn.tan 的 case 13 语义合并为一类一块(6 块而非 33 块)。两处纠正我任务书里的错误假设(均有证据):w$ 不是单位换算而是 Kotlin 的 Any?.toString()(w$ = Co.$_$.je -> module_37036.js:1165 Br()),单位由调用点拼字符串;fq/jq/Y$ 不是样式注册表而是 Kotlin/JS 的类/对象/伴生对象元数据注册(module_37036.js:1249/1257/1266)。浏览器实测(经由 AssetRelay 8130):官方壳与车库主屏渲染、#preloader 已移除、13 条 emotion 类规则注入、字体 BaseFontRegular/Medium 与 Fallback 全 loaded、33/33 图片加载成功、真实中文名(火焰炮/炸弹/橄榄绿/神谕者/十字军/防护×28)、布局尺寸非零(host 1311x986、positionContent 1311x826@0,64、blockParameters 1119x591@96,64、mounted 368x2186)。逐步修掉两个真问题:#app-root 缺官方 PresetContainer(position:absolute;height:100%)导致下游 height:100% 退化成 auto 而塌成 0 高;以及设备块数按官方 case 13 语义合并。回归:CompareContainerDecode 5 帧/26950/0、selftest 1108/9/90、semantic --demo 全部断言通过、compileKotlinJs/jsBrowserProductionWebpack/jsBrowserDistribution 成功。未完成(待搬,附官方出处):_Ln 3D 预览、PWn TankParametersStyle 全部片段、_Wn SuppliesComponentStyle、vGn 块内 improvementArrow/commonBlockForTurretsHulls/resistanceContainer/iconNotificator/SkinsIcon;未实现:sp1 状态选择器、Global 表的 li/a(部分)/input::placeholder;物品单件图标因数据里缺 TankInfoCC(5543162332469864498) 而退化为 defaultDevice.svg(数据缺失,非算法问题)。
2026-09-18 17:01:35 +08:00
TermiNexus 6c36c5e98d feat: M13a 导出官方「型号枚举→图标」表 + 素材中继 + 物品名称/类别中文可展示
A 图标表:从 module_36659.js:5135 的 eA.upf(底盘)与 module_57128.js:840 的 Dn.duk(炮塔)解出 case→形参→实参→i(模块id)→resources.json 的映射(严格走 case→形参名→形参声明行→实参行,不假设 case 号等于实参位置,因为该模块实参表约 1000 项而工厂形参只有 714 个、多出的被丢弃)。自验:用同文件 :907 的 Dn.euk 抗性表 21 case 全命中且本地镜像均存在(去重 20 个文件)。规模:底盘 416 case(未解 1)、炮塔 20、抗性 21、7 格道具 7。B 物品信息:名称来自服务端模型 3935107155251354407(DescriptionModelCC)的 name 字段,类别中文用 lobby.garage.<枚举名>(ARMOR=底盘/WEAPON=炮塔/PAINT=迷彩/DRONE=辅助无人机…),15 件仓库物品名称 9/9、类别中文 9/9 命中;但图标 0/9 —— 承载底盘/炮塔型号的 TankInfoCC(5543162332469864498)在全部 68 个 s2c 帧与模板里 0 次出现,属数据缺失而非算法问题,已如实标注。C 素材中继 client/tools/AssetRelay.mjs(8130):/ 服务客户端产物、/play/static/** 映射 3DTank/web/play/static 本地镜像、正确 MIME 与宽 CORS、防目录穿越(%2e%2e 返回 400)。回归:CompareContainerDecode 5 帧/26950/0、selftest 1108/9/90、semantic --demo 全部断言通过、Kotlin/JS 构建 SUCCESSFUL。
2026-09-18 15:56:00 +08:00