装备校验链/快捷栏/公会/好友情侣/交易仓库五项差距修复(增量 129)

- 装备校验:can_equip 按 CanEquipNow→FindEquipCell→EquipItem 精确重排,
  新增 find_equip_cell() 1:1 复刻(RING/UNIQUE 占用翻转、COSTUME/BELT/DS),
  帝国 antiflag 降级为 tooltip 提示,LIMIT_PCBANG/REAL_TIME* 语义与倒计时文案
- 快捷栏:死亡全槽禁用+激活守卫、变身(affect 220)技能置灰、
  物品槽失配置灰(服务器回收/换武器后刷新)
- 公会:GUILD_AUTH_* 权限位门控踢人/公告/技能升级,/gskillup、
  被宣战应答弹窗(/war·/nowar)、资金存取行(40250 服务端已禁用仍保留 1:1)
- 好友/情侣:messenger 三固定组(好友/公会/情侣),lover_login/logout/
  near/far/divorce 命令事件→在线/在身边状态与离婚隐藏
- 交易/仓库:ExchangeState.last_notice(ALREADY/LESS_GOLD)结束浮层提示;
  仓库改密 /safebox_change_password 三段输入;关窗补 /safebox_close·/mall_close;
  仓库金钱经核实 40250 无 wire 协议,UI 定界只读
- app_flow:重连时 guild_marks_ready 重复连接加 is_connected 守卫
- 相机 look_at 零向量守卫(首帧/传送落点)
- 测试:equip/love/guild 断言更新,79 项中 78 绿(game_camera_test 为
  HEAD 既有失败);真服冒烟 LIVE_SMOKE PASS(192.168.21.203 全链路)
- docs/CLIENT-GAP.md 同步增量 129

Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018kUFvQGYusuY3dkfGitmAe
This commit is contained in:
shenlei
2026-09-07 21:43:30 +09:00
co-authored by Claude Code
parent 61272b75e9
commit 8092ff44e2
25 changed files with 1067 additions and 134 deletions
+50 -16
View File
@@ -1900,8 +1900,8 @@
| — | ❌ | 拍卖行 / auction house | 不做 | 当前 40250 默认构建未发现完整 ClientVS22 拍卖行 UI / handler;但客户端 `Packet.h` 保留 `__AUCTION__` 下的 `CG_AUCTION_CMD=205`,服务端也保留列表包 `=206`。当前默认服务端关闭该宏,因此本阶段不做;若启用需另行验收,不能称为“协议不存在” |
| P1 | 🟡 | Cube (제작) / 能量系统 | **首版**Cube 走 `GC_CHAT`/`CHAT_TYPE_COMMAND` 文本总线(对齐 `ServerCommand()`),`EntityStore::apply_server_command` 解析 `cube open/close/info/success/fail/r_list/m_info`(配方 `v,c` 列表 + `@`/`&`/`|`/`/` 分层材料 + 金币)→ `CubeState` + `drain_cube_events()``GameClient::send_cube_make/material_info/result_list``/cube make|mInfo|rList`);`M2Client` `get_cube`/`cube_make`/`cube_request_*` + `cube_opened`/`cube_closed`/`cube_changed`/`cube_result` 信号;`ui/cube_ui.gd`(配方列表 + 材料/金币 + 제작)。`net.entity_store` + `net.loopback_flow` 覆盖。真机(2026-08-31`/cube rList` 送出不断连,但服务器只在玩家站到 cube NPC 前才回应 → `cube open=0`,需 NPC 交互完整验。`POINT_ENERGY` 已由 HUD 快照显示;仍缺原 `uiCube.py` 材料格 3D 图标 / 拖放 / 결과 애니、NPC 前完整验 send 命令字 |
| P1 | 🟡 | 组队 | 邀请、接受、离队;**成员信息板(`party_ui.gd`1:1 迁移 `uiparty.PartyMemberInfoBoard`):每员角色状态按钮(队长弹菜单 → `CG_PARTY_SET_STATE=75` 分配 攻/坦/迅捷/辅/宗/防 或踢人)+ 名字(★队长) + HP gauge + `affects[7]` 附加效果 chip;顶部 EXP 分配开关(`party_set_distribute`+ 组队治疗(`party_use_skill(1,0)`)**;角色 / 治疗控件已按 40250 服务端 Leadership 规则本地门控(攻击≥10、坦克/迅捷≥20、辅助≥25、宗师≥35、防御≥40,治疗≥18);真服单会话 `CG_PARTY_USE_SKILL`(9B) 后仍在线;小地图 / Atlas 绿色队员点 + 队长环 | 仍需真版 `.sub` 图标 / 颜色、队伍技能冷却 / 权限、离线颜色语义和真实两账号组队验收 |
| P1 | 🟡 | 好友 / 情侣 | 好友列表、上线状态和私聊入口已有;`GC_LOVER_INFO`(70B) / `GC_LOVE_POINT_UPDATE`(5B) 已有尺寸断言、`EntityStore::LoverInfo` 状态、`M2Client.get_lover()` / `lover_changed``love_ui` 常驻显示伴侣名和 0–100 爱意值;`net.entity_store``love_ui_test.gd` 覆盖 | 补好友分组和完整 messenger 行为;情侣仍需完整交互 / 状态图标与 affect 表现、断线 / 切图生命周期、原版文案和真服务器端到端验收 |
| P1 | 🟡 | 公会(暂缓) | 信息、成员、技能、公会战、会徽上 / 下载和部分操作已有首版;`GC_REQUEST_MAKE_GUILD=82` 已解析并以 `M2Client.guild_make_requested` 通知;公会窗已弹出创建名称输入并发送 `CG_ANSWER_MAKE_GUILD``CG_GUILD_SYMBOL_CRC=113` / `GC_GUILD_SYMBOL_DATA=133` 已支持原始符号文件下载 | 本阶段暂缓完整权限 / 等级页、公告与日志、成员管理、公会战应答、积分板、领地和公会建筑;恢复公会范围后再做完整真服验收 |
| P1 | 🟡 | 好友 / 情侣 | 好友列表、上线状态和私聊入口已有;`GC_LOVER_INFO`(70B) / `GC_LOVE_POINT_UPDATE`(5B) 已有尺寸断言、`EntityStore::LoverInfo` 状态、`M2Client.get_lover()` / `lover_changed``love_ui` 常驻显示伴侣名和 0–100 爱意值;`net.entity_store``love_ui_test.gd` 覆盖 | 增量 129 补 messenger 三固定组(好友 / 公会 / 情侣,对齐 `uimessenger.py:274-295`)与 `lover_login/logout/near/far/divorce` 命令事件 → 情侣在线 / 在身边状态(`love_ui` 后缀 + `friend_ui` 分组行);仍需情侣 affect 表现、断线 / 切图生命周期、原版文案和真服务器端到端验收 |
| P1 | 🟡 | 公会 | 信息、成员、技能、公会战、会徽上 / 下载和部分操作已有首版;`GC_REQUEST_MAKE_GUILD=82` 已解析并以 `M2Client.guild_make_requested` 通知;公会窗已弹出创建名称输入并发送 `CG_ANSWER_MAKE_GUILD``CG_GUILD_SYMBOL_CRC=113` / `GC_GUILD_SYMBOL_DATA=133` 已支持原始符号文件下载。**增量 129 恢复公会范围**:权限门(`GUILD_AUTH_*` 位控踢人 / 公告 / 技能升级 / 施放,grade 0 = 会长,数据未同步回退全开交服务器权威)、成员页资金行与踢人按钮、`!` 前缀公告发布、`/gskillup <vnum>` 技能升级、公会战宣战应答弹窗(state 3 → `/war`·`/nowar` | 仍缺公会日志页、积分板、领地和公会建筑;完整真服验收待进行 |
| — | ❌ | 龙魂精炼 | 当前目标 40250 服务端不提供该玩法;本阶段不纳入支持或验收,已有兼容代码仅保留作协议参考 | 若未来服务端增加该玩法,再另立协议、UI 和验收需求 |
| P1 | 🟡 | 世界玩法 | 有 `CG_WARP=65` 主动请求、`GC_WARP=65` 处理、`NetWorld` / `GameScene` 的无条件 `lAddr:wPort` 重连与换图清理首版、`CG_FISHING=82` / `GC_FISHING=89` 钓鱼方向与状态事件、`NetPlay` 钓鱼动作分发、`ChatUI` 鱼获 / 失败日志、`CG_DUNGEON=110` / `GC_DUNGEON=110` 副本请求与状态事件、`GC_DIG_MOTION=134` 挖矿动作广播、`GC_LAND_LIST=130` 领地状态、`GC_OBSERVER_ADD/REMOVE/MOVE=9698` 观战者状态、频道、时间、NPC marker、天气粒子和 mount_vnum 字段;真服登录洪流已收到并解析 `GC_LAND_LIST`(436B),单会话发送 `CG_FISHING`(5B) 后收到“Please choose a Fishing Pole.”业务拒绝且连接保持 | 补完整钓鱼 UI / 鱼获背包落地、副本计时 / 入口 UI、坐骑真模型 / 骑乘动作 / 移速、地图 BGM / 天气配置、地形贴花、DungeonBlock;换图首版已落地,仍需真实 40250 端到端验收 |
| P1 | 🟡 | 小地图 / Atlas | 可画玩家、实体、NPC、任务标记、观战者紫色菱形和 `GC_LAND_LIST` 领地边框;支持 `set_scale()` / 鼠标滚轮缩放;增量 61 接入 EventManager 任务信号点、清除和 Atlas center adjust;增量 108 任务信号点越出小地图半径时按 `m2dev PythonMiniMap.cpp:441-462` 夹到圆周并改画指向目标的方向箭头(`SIGNAL_RIM_INSET=9.0`);Atlas 支持底图、地图名称、玩家坐标、拖动和坐标查询 | 补原 minimap / Atlas 贴图细节、提示、队员 / NPC 分类、Atlas 侧同一信标夹边、完整 `.sub` 边缘指示图标、地图驱动天气配置和原版窗口视觉 |
@@ -2029,7 +2029,7 @@ enum,不存在 `namespace CG` / `namespace GC`。本文此前的“68 + 109 =
1. 任务完整标签 / 输入 / 选道具 / 指引;
2. 商店 START_EX、仓库密码、商城、私人商店、Cube(拍卖行 40250/ClientVS22 无,除非另起协议);
3. 组队角色、情侣完整交互、领地与公会建筑;公会完整页面暂缓
3. 组队角色、情侣完整交互、公会日志 / 积分板、领地与公会建筑;公会完整页面已随增量 129 恢复
4. 钓鱼、副本、坐骑、观战者和 Atlas。
### M3UI 与表现 1:1
@@ -2485,9 +2485,23 @@ Python 脚本;文档中出现的 `assets/root/*.py` 均属于本工程迁移
头发保留。`net_world._apply_field_updates()` 确认 `set_armor→set_weapon→set_hair` 字段序已 1:1 于
`NetworkActorManager.cpp:473`。新增 canonical 测试 #18 `part_hiding_test.gd`45 断言)+
`equip_model_test.gd` 补 7 段。
**仍为 seam**:精确 tie-break 顺序 / 已穿同槽替换 / `LIMIT_PCBANG`·`REAL_TIME*` / 属性 4 项按名读取
留待接服务器 `char_item.cpp` 比对;**变身态**40250 实体表无 `poly_race` 字段,`_is_poly()`
`false`,等 `GC_CHARACTER_UPDATE` 带变身 race;**远端 PC 换模链首版已在增量 99 落地**——
~~仍为 seam:精确 tie-break 顺序 / 已穿同槽替换 / `LIMIT_PCBANG`·`REAL_TIME*` / 属性 4 项按名读取
留待接服务器 `char_item.cpp` 比对;变身态(40250 实体表无 `poly_race` 字段,`_is_poly()`
`false`,等 `GC_CHARACTER_UPDATE` 带变身 race。~~ **增量 129(§4.1 装备校验链精确化)**
已对照 40250 服务器源码逐行核实链路并重排 `equip_rules.gd.can_equip()`——
`char_item.cpp:7462 CanEquipNow`JOB antiflag → LIMIT_LEVEL/STR/INT/DEX/CON → WEARABLE_UNIQUE
同组去重,`IsSameSpecialGroup` 客户端退化为同 vnum 判定)→ `item.cpp:472 FindEquipCell`(新增
1:1 复刻 `find_equip_cell()`else-if 优先级 BODY→HEAD→FOOTS→WRIST→WEAPON→SHIELD→NECK→EAR→
ARROWRING→RING1 空则 RING2UNIQUE→UNIQUE1 空则 UNIQUE2COSTUME 按 sub_typeBELT 固定,
DS/SPECIAL_DS 走龙魂专用路径返回 -1)→ `char_item.cpp:6100 EquipItem` 后置检查(礼服
vnum 11901..11904 + 骑乘禁止 → 变身中除 `WEAR_ARROW` 一律禁止 → `FN_check_item_sex` 性别 →
`IsRideItem` 已骑乘禁止)。**帝国 antiflag 从装备门降级为 tooltip 提示**(`empire_warning()`
服务器装备路径从不检查、仅显示层语义);`LIMIT_PCBANG(6)` 不是门禁(仅标记),
`LIMIT_REAL_TIME(7)` / `LIMIT_REAL_TIME_START_FIRST_USE(8)` 由 socket 驱动到期,客户端职责只有
tooltip 倒计时(`item_tooltip.gd` 补「PC房专用道具」「首次使用后计时」与到期文案);变身门读
实体 `polymorph`/`poly_vnum` + affect 220`_equip_ctx()` 同步采集 st/dx/ht/iq 四属性与穿戴表
0..10 + 新装备槽 90+19..90+23)。`equip_rules_test.gd``find_equip_cell` 与后置检查断言。
**远端 PC 换模链首版已在增量 99 落地**——
`game_scene``ch_type==0` 创建 `RemotePlayerView`,复用真实 `PlayerView` race / GR2 / MSA
远端 `EquipModel` 只消费 `awPart[ARMOR,WEAPON,HEAD,HAIR]``net_world` 按四字段调用 setter
不读取本地 `get_equipment()`。所有职业 / race、变身字段、远端真服换装和精确视觉仍待验收。见
@@ -2508,12 +2522,21 @@ Python 脚本;文档中出现的 `assets/root/*.py` 均属于本工程迁移
技能书 / 遗忘书 / 变身道具标题和基于限制字段的实时剩余时间。仍缺 CJK 文案 / 字体、其他
特殊分支、装备对比(参考源码未发现对应方法)和完整计时来源语义。
4. **Safebox 是列表和自动找空位。** 当前 deposit 使用下一个空位,缺少 45 格网格、分页、指定
目标格、仓库内移动、金币存取、密码修改、重试限制、完整错误状态和原版互斥规则。
见 [`safebox_ui.gd:7`](/Users/shenlei/Work/mt/mtgodot-poc/project/ui/safebox_ui.gd:7)。
4. **Safebox 金币 / 改密已按 40250 真实能力定界(增量 129),网格仍为首版。** 金币存取经核实
**40250 无 wire 协议**`HEADER_CG_SAFEBOX_MONEY` 服务端不存在、`GC_SAFEBOX_MONEY_CHANGE(84)`
从不发送、ClientVS22 `SendSafeBoxMoneyPacket` 为 assert-stub、原版 `RefreshSafeboxMoney`
`pass`——故 UI 金币只读展示(不伪造协议包,避免状态失步)。`close()` 补发聊天命令
`/safebox_close``cmd.cpp:350`,对齐原版关窗即服务器侧关闭);改密走
`/safebox_change_password <old> <new>``cmd.cpp:354`,各 1..6 位)三段密码 ConfirmationDialog
`mall_ui.close()` 同步补 `/mall_close`。仍缺 45 格网格、分页、指定目标格、仓库内移动、重试
限制和原版互斥规则。见 [`safebox_ui.gd:7`](/Users/shenlei/Work/mt/mtgodot-poc/project/ui/safebox_ui.gd:7)。
5. **交易缺少事务状态。** 当前是两列文字列表,没有锁定、接受后修改自动取消接受、物品占用、
服务器回滚、交易失败恢复、对方物品变化提示和交易中的背包锁定。
5. **交易结束 / 失败提示已补(增量 129),事务状态仍缺** 已核实 `GC_END` 对成功与取消发同码
`exchange.cpp` `EXCHANGE_END``Cancel()`),包级不可区分——`EntityStore.ExchangeState` 新增
`last_notice` 捕获 `EXCHANGE_GC_ALREADY(6)` / `EXCHANGE_GC_LESS_GOLD(7)`(新协议 wire 名
`LESS_ELK`),`exchange_ui` 结束时 5s 浮层提示(「对方已经在交易中」/「金币不足」)+ 交易中
状态行内联提示;最终结果以 `CHAT_TYPE_INFO` 为准。仍缺锁定、接受后修改自动取消接受、物品
占用、交易失败恢复和交易中的背包锁定。
6. **NPC 商店已有货位网格与购买确认,但仍非完整原版商店。** 增量 59 已接入 5×8/40 格货位、
空位禁用、货架全局槽号、tooltip 和 BUY 确认(固定数量 1);仍缺真实图标 / `.sub`、非金币货币、
@@ -2522,16 +2545,27 @@ Python 脚本;文档中出现的 `assets/root/*.py` 均属于本工程迁移
7. **私人商店是兼容实现。** 虽然 `CG_MYSHOP` 已能发送,但原版库存模型、拖放、价格编辑、
开店前检查、库存锁定、撤下回滚和其他玩家查看流程尚未完整迁移。
8. **快捷栏类型映射和键位主语义已修正,刷新边界仍不完整** 参考端可执行类型只有
8. **快捷栏死亡 / 变身 / 失配刷新已补(增量 129),特殊技能冷却仍缺** 参考端可执行类型只有
`INVENTORY(1)``SKILL(2)``EMOTION(3)`,当前已统一该编号、接通表情执行、4×8 显示、
inventory → quickslot 投放以及数字 / F1F4 / Shift 入口;仍缺特殊技能冷却、死亡 / 变身 /
换武器后的完整服务端刷新。见 [`quickbar.gd`](/Users/shenlei/Work/mt/mtgodot-poc/project/ui/quickbar.gd)。
inventory → quickslot 投放以及数字 / F1F4 / Shift 入口;增量 129 接 `entity_dead`(死亡全槽
置灰 + 激活守卫)、`affect_added`/`affect_removed`affect 220 = 变身,技能槽置灰)、
`inventory_changed`(物品槽 `get_item` 为空 / vnum==0 时置灰并显示 `×vnum`,覆盖换武器 /
服务器回收)。仍缺特殊技能冷却。见
[`quickbar.gd`](/Users/shenlei/Work/mt/mtgodot-poc/project/ui/quickbar.gd)。
9. **组队状态是近似定义。** affect 标签仍有暂定映射,队伍技能冷却、队长权限动态变化、离线、
死亡、距离状态和多账号行为还未完成真实验收。
10. **好友、情侣、公会只有首版状态展示。** Messenger 分组、上线/离线、私聊生命周期、情侣
交互、公会权限、公告、日志、成员管理、公会战应答、领地和公会建筑均不完整或暂缓。
10. **好友 / 公会 / 情侣 messenger 与公会权限已有完整首版(增量 129)。** `friend_ui.gd`
原版三固定组(好友 / 公会 / 情侣,`uimessenger.py:274-295`)分列:好友行、公会行(在线点 /
会长标记 / 点击私聊)、情侣行(♥ 在线点 + 「在身边」标记);情侣在线 / 在身边 / 离婚由
`CHAT_TYPE_COMMAND` 事件 `lover_login/logout/near/far/divorce``marriage.cpp`)驱动
`LoverInfo.online/near``love_ui` 状态后缀与自动隐藏。公会:`_my_auth()` 按自身 grade 查
auth 位(`guild.h:94-97` ADD/REMOVE/NOTICE/USE_SKILL)门控踢人按钮、`!` 前缀公告、技能施放 /
`/gskillup` 升级,成员数据未同步时回退全开(服务器权威,对齐原版无前端门);公会战宣战
应答弹窗(state 3 = `GUILD_WAR_RECV_DECLARE``/war <name>` 接受 / `/nowar <name>` 拒绝);
成员页资金行(存 / 取包保留 1:1,40250 服务端已禁用 `CG 13/14` 处理器)。仍缺:私聊生命
周期细节、情侣 affect 表现、公会日志页、积分板、领地和公会建筑、真服端到端验收。
### 5. P1:任务、NPC 和世界玩法