port: P3-c PythonExchange + exchange module (1:1 40250)

Copy PythonExchange.cpp/PythonExchangeModule.cpp verbatim, drop the pending
stand-in and the exchange module stub, register initTrade() after
initNonPlayer(). The fake server answers CG_EXCHANGE START with the partner's
item + gold and CANCEL with END; port.login_flow drives the exchange round-trip
through the Python exchange/net modules and uiexchange.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 00:59:05 +09:00
co-authored by Claude Opus 5.5
parent 9298500df9
commit 72b19b677d
14 changed files with 853 additions and 162 deletions
+2
View File
@@ -438,6 +438,8 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
P3-b(2026-09-24):`PythonItem.cpp` 与 `PythonItemModule.cpp` 原样移植,删除 pending 替身与 item 模块桩,`initItem()` 按 40250 顺序在 `initPlayer()` 之后;平台 `CPythonApplication::Create` 按原序调 `m_pyItem.Create()`(dropitem.mse 注册仍落在 CEffectManager 桩)。改动:`itemGetIconImage` 用 `Py_BuildPointer` 返回图标指针(40250 ILP32 用 `"i"`,64 位下被截断,真服背包 `wndMgr.SetSlot` 段错误);`D3DXMath.h` 补 `D3DXQuaternionConjugate`;pending `CMapManager::GetNormal` 以 `CTerrain::CalculateNormal` 公式按需在高度块上算法线;`CPythonTextTail` 的物品名牌四函数暂为桩,`Pick` 按 40250 空表语义返回 -1(返回 0 会把地面物品 VID 0 当作选中,点地移动失效)。假服入场时按 `CItem::EncodeInsertPacket` 发 vnum 19 的 `GC_ITEM_GROUND_ADD`+`GC_ITEM_OWNERSHIP`,收到 `CG_ITEM_PICKUP` 回 `GC_ITEM_GROUND_DEL`;`port.login_flow` 验证地面物品位置/归属/vnum,`player.PickCloseItem()` 发出拾取、物品被删除,以及 `item.SelectItem(19)` 的名称/类型/子类型/数值。下一步 P3-c:`PythonExchange`,之后 `PythonTextTail`(物品名牌)与 `PythonMiniMap`。
P3-c(2026-09-24):`PythonExchange.cpp` 与 `PythonExchangeModule.cpp` 原样移植(无手改),删除 pending 替身与 exchange 模块桩,`initTrade()` 按 40250 顺序在 `initNonPlayer()` 之后。假服按 `CInputMain::Exchange` 应答:`CG_EXCHANGE` START 回 `GC_EXCHANGE` START(arg1 = 请求的 vid)+ 对方 ITEM_ADD(vnum 19,格 0)+ GOLD_ADD 1000,CANCEL 回 END;`port.login_flow` 用 `net.SendExchangeStartPacket` 开交易,验证 `exchange.isTrading/GetItemVnumFromTarget/GetItemCountFromTarget/GetElkFromTarget`,uiexchange 打开后 `net.SendExchangeExitPacket` 收到 END 关闭。注意:40250 `SendExchangeExitPacket` 的 arg1 未初始化(原样保留,假服不记录它);`uiexchange.CloseDialog` 调 `wndMgr.OnceIgnoreMouseLeftButtonUpEvent()`,测试先消耗这次被忽略的左键抬起,否则下一次点地的抬起被吞、角色一直按住行走。下一步 `PythonTextTail`(物品名牌)与 `PythonMiniMap`。
每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。
## 5. 数据源切换:m2dev assets → 40250