# pbot — 传奇996盒子纯协议机器人 · 分层框架 > 2026-09-24 从骨架完成首轮实装并联调。前序调研与可运行代码保留在 > `../protocol_bot_backup/`(2026-09-22 曾端到端打通任务+打怪)。 > 本目录按分层框架重写,游戏逻辑通过 Behavior 插件接入。 ## 已打通链路(2026-09-24 实测日志) | 阶段 | 状态 | 证据(/tmp/pbot_run*.log) | |---|---|---| | 盒子登录(极验滑块+RSA+HMAC) | ✅ | `byPwd => code=200`, uid/token 下发 | | EnterGameClient 选区上报 | ✅ | `code=200` | | 登录服网关链 2001→529→104→530→100→520→101→521→103→525 | ✅ | key32/sid/角色列表/创角票据/游戏端口 | | 创角 & 复用 & 删角(CS102→523) | ✅ | `[删角] 萌新7748 删除成功(523)` | | 游戏服 CS20(v2 11字段)→SC658 | ✅ | `世界已初始化` | | 17帧初始化(5027 body=当前图名) | ✅ | 服务器逐帧应答(5037/6215/60006…) | | SC50 出生 + SC51 地图(等待图 24,30) | ✅ | `map=等待地图 @(24,30) actor=… uid=…` | | CS60000 心跳(tail 主链纪律) | ✅ | 服务器持续回显 60000 | | CS3199 喝药面板(@openmianban,23 / @chiyao_kaiqi) | ✅ 已发 | 面板回包状态待调(None) | | 移动帧链 CS3011+CS1(+GOOD, cap_wait 抓包同构) | ✅ 已发 | 服务器确认(SC1/SC28)未获得,见下 | ## 当前状态: 走动瓶颈已破案(2026-09-24 深夜) 对 `/tmp/cap_unlock.jsonl`(成功解锁全流量)逐帧重分析, 推翻了此前 "服务器任务态间歇可用"的归因。真因是三重客户端协议误读: 1. **CS1(tail=817)方向搞反** — 它是 SC1 服务器→客户端行为确认帧 (cap_unlock dir 字段实锤), 旧版当上行帧重放 = 污染会话 2. **renwu_mov "间歇 1/5" 是时序竞态假象** — 真客户端 CS3031→CS1011 间隔 1.23s(等 SC-1 提交任务态), 旧版 6 帧连发 <100ms 必被忽略 3. **renwu 后 3011 被 M2 锁定, 必须 3013 跑** — walk_final:71-77 "48帧全拒铁证"; 真客户端 SC20102 后连跑3帧全确认, @exit 后 3011 才解禁 完整证据链与修复清单见 [`docs/走动瓶颈分析报告.md §十](docs/走动瓶颈分析报告.md)。 **另发现**: cap_unlock 存有完整 562B CS3031 任务体(此前只有 200B 截断版), 已提取为 `assets/cs3031_full.bin`。 ## 分层架构 ``` ┌─────────────────────────────────────────────┐ │ bot/ Behavior 插件 + tick 决策循环 │ ← 游戏逻辑写在这里 ├─────────────────────────────────────────────┤ │ world/ 虚拟世界镜像(SC帧→状态) │ ← 服务器推送 → 状态 ├─────────────────────────────────────────────┤ │ game/ 消息号表 + 帧分发 + 会话编排 │ ← 协议语义层 ├─────────────────────────────────────────────┤ │ transport/ 网关TCP链路(登录服/游戏服) │ ← 字节流 ↔ Frame ├─────────────────────────────────────────────┤ │ login/ 996盒子 HTTP 登录(极验滑块) │ ← token / 票据 ├─────────────────────────────────────────────┤ │ codec/ Encode6BitBuf + 帧编解码 │ ← 纯函数,无 IO └─────────────────────────────────────────────┘ ``` 依赖方向自上而下,下层禁止 import 上层。 ## 用法 ```bash cd protocol_bot uv sync uv run python main.py -u <账号> -p <密码> --zone <区ID> --name <角色名> \ --wander-seconds 10 [--reset] ``` - `--zone 0` 自动选服务器列表最新已开区 - `--reset` 先删角重创(新手任务重置) - 流程: 登录 → 选区 → 创角/复用 → 进游戏 → 喝药 → 解锁 → 走动 ## 模块清单 | 模块 | 文件 | 职责 | 状态 | |---|---|---|---| | codec | `bitbuf.py` | 6bit 编解码(pcap 向量 100% 匹配) | ✅ 实装 | | codec | `frame.py` | 帧构造/解析/流式切帧(防伪帧头) | ✅ 实装 | | login | `box_proto.py` | 抓包逆向常量/签名/RSA/验证码体 | ✅ 实装 | | login | `geeked_solver.py` | 极验 v4 滑块(vendor 封装+重试) | ✅ 实装 | | login | `box_client.py` | 登录会话+频控退避+公钥自愈 | ✅ 实装 | | transport | `gateway.py` | 登录服全链/删角/游戏服 CS20/tail 纪律 | ✅ 实装 | | game | `messages.py` | ScMsg/CsMsg 实测消息号表 | ✅ | | game | `session.py` | 658→SC51→17帧→出生→ACK 编排+批量帧拆包 | ✅ 实装 | | game | `heal.py` | 喝药开关 toggle(CS3199) | ✅ 实装(状态确认待调) | | world | `update.py` | SC帧→镜像(SC51/28/11/53/55 真源解析) | ✅ 实装 | | world | `mirror.py` | 虚拟世界镜像数据结构 | ✅ | | bot | `wander.py` | 等待图走链(单帧 3013/3011, SC1 确认门控) | ✅ 重写(破案后) | | bot | `unlock.py` | 等待图解锁(renwu_mov 黄金时序状态机) | ✅ 重写(破案后) | | bot | `runner.py`/`heartbeat.py` | 节拍循环/心跳 | ✅ 实装 | ## 实测关键定案(迁移自 backup + 本轮复验) - **tail 全链唯一递增**: 17帧显式 tail=2..19,心跳/ACK/走链共用主链;重复=会话非法 - **SC1 是服务器下行确认帧**(cap_unlock dir 字段实锤): recog=落点X, p1=落点Y, tail=817 — 每步移动只发一帧 3011/3013, 服务器逐帧回 SC1;**客户端不重放 CS1** - **renwu_mov 黄金时序**: CS3031(562B完整体)→[等1.2s]→CS1011@renwu_mov,1 →SC20102(受理信号)→10ms内CS3013起跑→到达后@exit→SC644→3011解禁 - **renwu 后 3011 被 M2 锁定, 3013 放行**(walk_final:71-77, 48帧全拒铁证) - **CS3011/3013 布局**: recog=0, p1=dir, p2=起点(Y<<16|X), p3=sid, body=协议图名 - **SC51 坐标布局**: recog=X, p1=Y(bit11=标志位非坐标) — 解析错位是"走不动"历史根因 - **SC28 两类**: p3=32368232=锚点回显(非拒绝); 其他=真拒绝(X/Y反序就近采信, (0,0)清位忽略, 连续≥3次同raw=权威锚点) - **5027 body 必须是当前图名**(等待地图/比奇'0'/盟重'3') - **M2 封速**: 移动包间隔 <1.4s 累计超速计数,超限全部静默丢弃;传送后静置洗计数 - **多线程 recv 撕裂 TCP 流**: 收帧必须单消费者 ## 注意 - ⚠️ 仅限学习研究,勿高频调用/勿用于商业用途 - 协议实测备忘: `../protocol_bot_backup/README.md` + 本目录各模块 docstring - 测试: `uv run pytest`(36 用例)/ `uv run ruff check .` / `uv run basedpyright`