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
+1
View File
@@ -532,3 +532,4 @@
{"time": "2026-09-24T05:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P2: ServerStateChecker + module", "ported": ["UserInterface/ServerStateChecker.cpp", "UserInterface/ServerStateCheckerModule.cpp"], "adapted": [], "divergent": [], "needs_live": [], "tests": ["port.login_flow: fake state port answers CG_STATE_CHECKER, NotifyChannelState(2, 1)", "port.login_live 192.168.21.203: channel states {1: 1, 2: 1}", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3 item chain: ItemData, ItemManager, PythonItem, PythonExchange"]}
{"time": "2026-09-24T06:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-a: ItemData, ItemManager, PythonNonPlayer + LoadLocaleData", "ported": ["GameLib/ItemData.cpp", "GameLib/ItemManager.cpp", "UserInterface/PythonNonPlayer.cpp", "UserInterface/PythonNonPlayerModule.cpp"], "adapted": ["UserInterface/PythonApplication.cpp:LoadLocaleData"], "divergent": [], "needs_live": [], "tests": ["port.login_flow 3c: item 19 Sword+9 type 1 refine 9, mob 101 Wild Dog", "port.login_live 192.168.21.203: same", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-b PythonItem + PythonItemModule", "CPythonSkill (RegisterSkillDesc/Table) still pending"]}
{"time": "2026-09-24T07:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-b: PythonItem + PythonItemModule", "ported": ["UserInterface/PythonItem.cpp", "UserInterface/PythonItemModule.cpp"], "adapted": ["UserInterface/PythonItemModule.cpp:itemGetIconImage", "GameLib/MapManager.cpp:CMapManager::GetNormal"], "divergent": [], "needs_live": [], "tests": ["port.login_flow: fake GC_ITEM_GROUND_ADD vnum 19 + ownership, player.PickCloseItem -> CG_ITEM_PICKUP -> GC_ITEM_GROUND_DEL removes it", "port.login_flow: item.SelectItem(19) name/type/subtype/value", "port.login_live 192.168.21.203: passes (icon pointer truncation segfault fixed)", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-c PythonExchange", "PythonTextTail item tails (Register/Delete/SetOwner/Pick still stubs)", "CEffectManager (dropitem.mse)"]}
{"time": "2026-09-24T08:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-c: PythonExchange + PythonExchangeModule", "ported": ["UserInterface/PythonExchange.cpp", "UserInterface/PythonExchangeModule.cpp"], "adapted": [], "divergent": [], "needs_live": ["exchange with a real second player"], "tests": ["port.login_flow: net.SendExchangeStartPacket -> fake GC_EXCHANGE START/ITEM_ADD/GOLD_ADD fills target side, uiexchange opens; SendExchangeExitPacket -> END closes", "port.login_live 192.168.21.203: passes", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["PythonTextTail item tails", "PythonMiniMap", "CEffectManager", "CPythonSkill"]}
@@ -0,0 +1,224 @@
{
"reference": "UserInterface/PythonExchange.cpp",
"reference_sha256": "ed8529ffd11f1baafe7c2cc0e83d1480ecb28df69ad74aa94813223371600a2e",
"priority": "P3",
"contracts": [],
"functions": {
"CPythonExchange::SetSelfName": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetSelfName"
]
},
"CPythonExchange::SetTargetName": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetTargetName"
]
},
"CPythonExchange::GetNameFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetNameFromSelf"
]
},
"CPythonExchange::GetNameFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetNameFromTarget"
]
},
"CPythonExchange::SetElkToTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetElkToTarget"
]
},
"CPythonExchange::SetElkToSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetElkToSelf"
]
},
"CPythonExchange::GetElkFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetElkFromTarget"
]
},
"CPythonExchange::GetElkFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetElkFromSelf"
]
},
"CPythonExchange::SetItemToTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemToTarget"
]
},
"CPythonExchange::SetItemToSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemToSelf"
]
},
"CPythonExchange::SetItemMetinSocketToTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemMetinSocketToTarget"
]
},
"CPythonExchange::SetItemMetinSocketToSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemMetinSocketToSelf"
]
},
"CPythonExchange::SetItemAttributeToTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemAttributeToTarget"
]
},
"CPythonExchange::SetItemAttributeToSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetItemAttributeToSelf"
]
},
"CPythonExchange::DelItemOfTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::DelItemOfTarget"
]
},
"CPythonExchange::DelItemOfSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::DelItemOfSelf"
]
},
"CPythonExchange::GetItemVnumFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemVnumFromTarget"
]
},
"CPythonExchange::GetItemVnumFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemVnumFromSelf"
]
},
"CPythonExchange::GetItemCountFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemCountFromTarget"
]
},
"CPythonExchange::GetItemCountFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemCountFromSelf"
]
},
"CPythonExchange::GetItemMetinSocketFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemMetinSocketFromTarget"
]
},
"CPythonExchange::GetItemMetinSocketFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemMetinSocketFromSelf"
]
},
"CPythonExchange::GetItemAttributeFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemAttributeFromTarget"
]
},
"CPythonExchange::GetItemAttributeFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetItemAttributeFromSelf"
]
},
"CPythonExchange::SetAcceptToTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetAcceptToTarget"
]
},
"CPythonExchange::SetAcceptToSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetAcceptToSelf"
]
},
"CPythonExchange::GetAcceptFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetAcceptFromTarget"
]
},
"CPythonExchange::GetAcceptFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetAcceptFromSelf"
]
},
"CPythonExchange::GetElkMode": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::GetElkMode"
]
},
"CPythonExchange::SetElkMode": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::SetElkMode"
]
},
"CPythonExchange::Start": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::Start"
]
},
"CPythonExchange::End": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::End"
]
},
"CPythonExchange::isTrading": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::isTrading"
]
},
"CPythonExchange::Clear": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::Clear"
]
},
"CPythonExchange::CPythonExchange": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::CPythonExchange"
]
},
"CPythonExchange::~CPythonExchange": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchange.cpp:CPythonExchange::~CPythonExchange"
]
}
}
}
@@ -0,0 +1,122 @@
{
"reference": "UserInterface/PythonExchangeModule.cpp",
"reference_sha256": "90fb936b2f2ac29833083fd69a2c5f4307c65eda153b6f02214942d765bdb143",
"priority": "P3",
"contracts": [],
"functions": {
"exchangeInitTrading": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeInitTrading"
]
},
"exchangeisTrading": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeisTrading"
]
},
"exchangeGetElkFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetElkFromSelf"
]
},
"exchangeGetElkFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetElkFromTarget"
]
},
"exchangeGetAcceptFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetAcceptFromSelf"
]
},
"exchangeGetAcceptFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetAcceptFromTarget"
]
},
"exchangeGetItemVnumFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemVnumFromSelf"
]
},
"exchangeGetItemVnumFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemVnumFromTarget"
]
},
"exchangeGetItemCountFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemCountFromSelf"
]
},
"exchangeGetItemCountFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemCountFromTarget"
]
},
"exchangeGetNameFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetNameFromSelf"
]
},
"exchangeGetNameFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetNameFromTarget"
]
},
"exchangeGetItemMetinSocketFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemMetinSocketFromTarget"
]
},
"exchangeGetItemMetinSocketFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemMetinSocketFromSelf"
]
},
"exchangeGetItemAttributeFromTarget": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemAttributeFromTarget"
]
},
"exchangeGetItemAttributeFromSelf": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetItemAttributeFromSelf"
]
},
"exchangeGetElkMode": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeGetElkMode"
]
},
"exchangeSetElkMode": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:exchangeSetElkMode"
]
},
"initTrade": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonExchangeModule.cpp:initTrade"
]
}
}
}