feat: 新增出站包抓取,供「走不动」逐包对照(TODO 假设 5)
线上实测确认手动执行器(1.7.0 备选方案)不能解决「走不动」:前 20 秒走 13 格后 即卡在「执行中断(stuck)→重规划→缩短段长→跳过目标→重新规划同一目标」的死循环。 只靠 packetStats.outboundTypes 的计数看不出「发出去的内容对不对」,所以补一个 能录原始出站序列、并能在「能走」与「走不动」两种状态下 diff 的诊断能力。 新增 src/core/packetCapture.js: - 只在录制期间挂钩 client.write,其余时间零开销(该钩子每个出站包都要过一遍); - 录到的内容做降深 + 截断的 JSON 化处理,向量对象只留坐标 (move_minecart 这类包能带上万个浮点数,不处理会把缓冲区撑爆); - 只放内存、有上限(默认 4000 包),不写盘。 接口(控制台): - POST /api/bots/:id/capture/start(可带 seconds 到点自动停止) - POST /api/bots/:id/capture/stop - GET /api/bots/:id/capture(支持 ?types= 与 ?limit=) 顺带修掉两个先前就存在的问题: - scripts/check-protocol.js 其实一直跑不通:minecraft-data 的 types.packet[1][1].type[1].fields[包名] 给的是类型名字符串, 要再去 types[名字] 取 ['container', [字段...]] 才能展开,原实现直接 .map() 必然抛错; 另有读 node_modules 少一层 '..' 的路径问题。 - 两条租约用例(expansionController / targetLease)的时序余量只有 15ms, 全量并行跑测试时偶发失败;改为 TTL 400ms 配 280ms 睡眠,各留 120ms 余量, 断言内容不变。 测试:436 → 451 个用例,连续 16 轮全量运行全绿。
这个提交包含在:
+35
@@ -2,6 +2,41 @@
|
||||
|
||||
本项目遵循 [约定式提交](https://www.conventionalcommits.org/zh-hans/) 与 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||
|
||||
## [1.8.0] - 2026-09-29
|
||||
|
||||
把「走不动」的排查手段补成可复用的诊断能力:能按需录下机器人**真正发出的协议包内容**,
|
||||
与「能走」时的序列逐包对照(TODO.md 问题 1 · 假设 5)。
|
||||
|
||||
### 新增
|
||||
|
||||
- **出站包抓取**(`src/core/packetCapture.js` + 控制台接口):
|
||||
- `POST /api/bots/:id/capture/start`(可带 `seconds` 到点自动停止)、
|
||||
`POST /api/bots/:id/capture/stop`、`GET /api/bots/:id/capture`(支持 `?types=` 与 `?limit=`);
|
||||
- **只在录制期间挂钩 `client.write`**,其余时间零开销 —— 这个钩子每个出站包都要过一遍;
|
||||
- 录到的内容做降深 + 截断的 JSON 化处理,向量对象只留坐标(`move_minecart` 这类包
|
||||
能带上万个浮点数,不处理会把缓冲区撑爆);
|
||||
- 只放内存、有上限(默认 4000 包),不写盘。
|
||||
|
||||
### 修复
|
||||
|
||||
- **`scripts/check-protocol.js` 其实一直跑不通**:`minecraft-data` 的
|
||||
`types.packet[1][1].type[1].fields[包名]` 给出的是**类型名字符串**(如 `packet_position_look`),
|
||||
必须再去 `types[名字]` 取 `['container', [字段...]]` 才能展开字段;原实现直接对它 `.map()`,
|
||||
必然抛 `def.map is not a function`。顺带修掉读 `node_modules` 时少了一层 `..` 的路径。
|
||||
- 修完即可确认:1.21.4 上 `position` / `position_look` / `look` 的地面标志是
|
||||
`flags: MovementFlags`(`u8` 位标志 `[onGround, hasHorizontalCollision]`),
|
||||
没有独立的 `onGround` 字段;`_fixOutboundOnGround` 改的正是正确的 `flags.onGround`。
|
||||
- **两条租约用例的时序余量过窄,会偶发失败**:`ttlMs: 40` 配两次 `setTimeout(25)`,
|
||||
只剩 15ms 调度余量,全量并行跑测试时会被压垮。改为 `ttlMs: 400` 配 280ms 睡眠,
|
||||
两侧各留 120ms 余量;断言内容不变(仍是「总耗时 > 原始 TTL、距续租 < TTL」)。
|
||||
|
||||
### 测试
|
||||
|
||||
新增 15 个用例(436 → 451):抓包器的录制 / 摘钩子 / 上限丢弃 / 按包名过滤 /
|
||||
序列化边界,其中包含一条回归用例 —— `position_look` 的参数本身就是
|
||||
`{x, y, z, yaw, pitch, onGround, flags}`,**不能**被「有 x/y/z 就当向量」的规则吞掉;
|
||||
另有控制台抓包接口的 HTTP 用例。
|
||||
|
||||
## [1.7.0] - 2026-09-29
|
||||
|
||||
按 `TODO.md` 的优先级把待办全部落地:先是「走不动」的攻关与备选方案,
|
||||
|
||||
在新工单中引用
屏蔽一个用户