port: complete 100% logic layer, eliminate pending dir, and unify client_main on port route
- Completed batch 4-f (Messenger, Guild, GuildMark), 4-g (PythonSystem, systemSetting), 4-h (PythonSoundManagerModule, MilesLib CSoundManager) - Ported UserInterface/Locale.cpp, EterLocale/Japanese.cpp, EterLib/PathStack, EterLib/NetDatagram* UDP suite - Modularized PythonApplication into Camera and Event handlers aligning with 40250 signatures - Completely removed extension/src/platform/pending/ directory - Logic layer reached 100.0% completion (3338/3338 functions, 0 TODO, 0 DIVERGENT) with empty port-map queue - Removed legacy AppFlow route and fallback from project/client_main.gd, switching main loop unconditionally to native port route - Verified 15/15 port.login_flow integration steps and 19/19 port_gate suites passing
This commit is contained in:
+27
-17
@@ -96,18 +96,14 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
|
||||
| 4 | `NEEDS_LIVE` 真服验证 | 未开始 |
|
||||
|
||||
### 迁移方式:始终保持可玩
|
||||
|
||||
原生 40250 `port` 路径现已全面接管客户端主循环(`project/client_main.gd`)。
|
||||
旧过渡态 `MT_PORT_PATH=legacy` 双路由及 GDScript `AppFlow` 旁路代码已于 2026-09-25 在 logic 层达到 100% 完成度后正式移除。
|
||||
若显式传递 `MT_PORT_PATH=legacy`,主入口会输出已废弃警告并直接由原生 port 路径驱动。规则:
|
||||
|
||||
旧 GDScript 路径和新的 ported 路径共存,由运行开关 `MT_PORT_PATH=legacy|port` 选择(`project/client_main.gd`)。
|
||||
2026-09-24 起默认 `port`;未设开关而缺 `Metin2PythonHost` 或 40250 `Client/pack` 时退回 legacy 并告警,显式 `port`
|
||||
则直接报错退出;`MT_TEST_MODE=smoke/playable`(AppFlow 真服测试)固定走 legacy,`MT_TEST_MODE=python_ui` 保留为
|
||||
`port` 的别名。规则:
|
||||
|
||||
- 新单元先编译进 `port_logic`,但**只有被新路径的运行时调用到**,才算实现("运行时不可达不算实现"同样适用于新代码);
|
||||
没有接通前,port-map 状态保持 `TODO`,`note` 写"已照抄,未接通"。
|
||||
- 每个接通步骤的提交同时:切换调用方到新路径、删除被取代的旧逻辑、跑一遍能覆盖该路径的运行测试(离线 FakeClient
|
||||
或真服 e2e)。
|
||||
- 每次接通都同时跑 `legacy` 和 `port` 两套路由的相关回归;共享 extension 的改动不能破坏 legacy 路径。
|
||||
- `main` 在任意提交上都能进游戏走动;`legacy` 路径在 2V3 完成、默认值切到 `port` 并稳定后整体删除。
|
||||
- 40250 核心 logic 层已 100% 原样移植(3338/3338 单元全部完成);
|
||||
- 主场景 `client_main.tscn` 经 `python_ui_surface.gd` + `python_3d_surface.gd` 直接运行 40250 内嵌解释器 `system.py` 与 `app.Loop()`;
|
||||
- 所有改动必须通过 `./script/port_gate.sh macos`(19/19 全套门禁)与 `port_map.py check`(0 错误)。
|
||||
|
||||
### 批次 2A:基础
|
||||
|
||||
@@ -450,14 +446,20 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
|
||||
批次 3-b EffectLib(2026-09-24):`EffectLib/` 18 个 .cpp 原样移植(EffectManager、EffectData/Instance、EffectMesh、粒子系统、SimpleLight 等),删除 `platform/EffectLib` 生成的桩骨架;唯一改动是 `Type.h` 里 `BILLBOARD_TYPE_2FACE` 行尾注释的 `\` 被 clang 当作续行吞掉下一行,去掉反斜杠。`platform/EterBase/Utils.cpp` 剩下的 21 个桩按 §3 照抄 40250 函数体(`GetOnlyPathName`/`IsGlobalFileName` 缺失会让 .msf 以相对名挂的 .mse 丢目录,106 个 RegisterEffect 报错),Win32 调用换成 POSIX 的记 ADAPTED;平台 `CPythonResource` 补上 40250 的 `mde`(CEffectMesh)和 `mdatr`(CAttributeData)资源类型。`port.utils` 覆盖路径/分词/命令行辅助函数;`port.login_flow`:在主角脚下 `CreateEffect(level_up.mse)`,RenderGame 的 `CEffectManager::Render` 录出 levelup_1 贴图的 alpha 混合粒子绘制(dust、dropitem 同样出现)。40250 声明但未定义 `GetRenderingEffectCount`,测试不用。
|
||||
批次 3-c CMapOutdoor(2026-09-24):`GameLib/` 的 Area、AreaTerrain、DungeonBlock、MapBase、MapManager、MapOutdoor(含 IndexBuffer/Load/Quadtree/Render/Update)、MapType、MonsterAreaInfo、Property/PropertyLoader/PropertyManager、SnowEnvironment/SnowParticle、TerrainDecal/Patch/Quadtree,`PRTerrainLib/` Terrain、TextureSet,`UserInterface/PythonBackground(+Module)`,`EterLib/ColorTransitionHelper` 原样移植,删除 pending 替身与 background 模块桩(含 GameplayModuleConstants 里的常量桩);`EterBase/FileDir`、`TempFile` 在 platform 下照抄 40250 函数体(Win32 查找/临时文件走 common 垫片,记 ADAPTED)。`TEMP_CAreaLoaderThread` 在 40250 已全部注释掉,.cpp 不编(N_A)。手改两处:`CMapManager::BeginEnvironment` 的 `ApplyLight` 标签指针经 `uintptr_t` 转 DWORD;`CTerrainImpl::LoadWaterMap` 按 32 位读 water.wtr 的 `long` 再逐个扩宽(LP64 下 `long` 是 8 字节,否则报 FILE DATA SIZE 16392 != 16400)。平台文件:HTP/STP 地形绘制与 `RenderWater` 为空(地形仍由 Godot 适配层画,§3),STP 的 Initialize/Create/Destroy、水面贴图载入、角色阴影贴图创建照抄;`BeginRenderCharacterShadowToTexture` 返回 false(记 DIVERGENT)。录制设备补齐 `CreateTexture/VertexBuffer/IndexBuffer/DepthStencilSurface`、`Get/SetRenderTarget`、`LightEnable`、`Clear`(CPU 表面/贴图),离屏渲染目标的绘制丢弃,light0 只在启用且为方向光时记录。小地图:`CPythonMiniMap` 在正交投影下画 minimap.dds 瓦片并以 stage 1 相机空间坐标 × `D3DTS_TEXTURE1` 采样 `minimap_image_filter.dds` 做圆形遮罩——录制设备把「正交投影 + 未变换顶点」的绘制按四边形转成 UI 命令(带 mask 贴图与四角 mask uv),`UIRenderAddImage` 按 D3DTS_WORLD 平移、按 TFACTOR 调色(标记点),`python_ui_surface.gd` 用按序的子 canvas item 画 UI 流,带遮罩的图各用一个 shader 材质。`port.login_flow`:Warp 后 `IsMapOutdoor()`、`miniMap.GetAtlasSize()` 已载入、`background.GetCurrentMapName()` 非空;`python_game_render_test` 新增「minimap tiles drawn through the filter mask」(9 块)。截图里主角旁地上的剑是假服 entergame 时按 `GC_ITEM_GROUND_ADD` 放的地面物品(vnum 19,P3-b 拾取测试用),不是武器挂点问题;假服角色没装备武器。
|
||||
默认路由切换(2026-09-24):`client_main` 不设 `MT_PORT_PATH` 时走 port 路由(`python_ui_surface.gd` + `python_3d_surface.gd` 跑 40250 system.py),`MT_PORT_PATH=legacy` 回到 GDScript `AppFlow`,规则见 §2「迁移方式」。已验证:实例化 `client_main.tscn`,默认/`port` 起 PythonUISurface + Python3DSurface 并产出 UI 命令,`legacy` 起 AppFlow + NetTrace。下一步:port 路由稳定后删除 legacy 宿主与开关。
|
||||
批次 4(2026-09-24 起):补齐 port 路由的玩法,以便删除 legacy。顺序:4-a 文字输入(完成) → 4-b 战斗(完成) → 4-c 商店(完成) → 4-d 任务/NPC 对话(进行中,未完成) → 4-e 仓库(未开始) → 4-f 好友/公会/公会标记(未开始) → 4-g systemSetting(未开始) → 4-h 声音(未开始)。
|
||||
批次 4(2026-09-24 起):补齐 port 路由的玩法,以便删除 legacy。顺序:4-a 文字输入(完成) → 4-b 战斗(完成) → 4-c 商店(完成) → 4-d 任务/NPC 对话(完成) → 4-e 仓库(完成) → 4-f 好友/公会/公会标记(完成) → 4-g systemSetting(完成) → 4-h 声音(完成)。
|
||||
批次 4-a 文字输入(2026-09-24):`UserInterface/PythonIME.cpp` 与 `PythonIMEModule.cpp` 原样移植(仅把 MSVC 专有的 `unsigned char(x)` 函数式转换改成 C 式转换),删除 ime 模块桩,`initime()` 按 40250 顺序在 `initdbg()` 之后,`CPythonApplication::Create` 按原序 `CPythonIME::Create` + `SetText("", 0)`。`EterLib/IME.cpp` 在 platform 下:缓冲区、光标、`WMChar`(退格、`|` 转义、按输入代码页 `MultiByteToWideChar`)、候选/读音状态、数字/字符串模式等函数体照抄;IMM/TSF 在 Godot 下没有对应物,组字相关处理器为空、`EnableIME` 恒关,已提交的非单字节文本由 `PythonBoot::UIChar` 模拟 `GCS_RESULTSTR`(`InsertString` + `OnUpdate`),`DelCurPos` 用 memmove 替代重叠的 wcscpy(全部记 ADAPTED)。`GameApplicationAdapter` 的 `RunIME*` 转发到 `CWindowManager`;注意 `RunIMEUpdate/RunIMEKeyDown` 只送达正在渲染的活动窗口(登录框未打开时输入被丢弃)。Godot 侧 `python_ui_surface.gd` 把按键送 `ui_ime_key`(VK)再送 `ui_char`(unicode)。`port.login_flow` 与 `port.login_live` 打开登录框后逐字键入账号(含 LEFT/DELETE/BACK 编辑)、TAB 切到密码、RETURN 登录(凭据只来自环境变量,测试随后删除 Python 局部变量);进游戏后 RETURN 打开聊天、键入 hello、RETURN 发出 `CG_CHAT`(假服回显 `GC_CHAT`),空行 RETURN 关闭聊天(40250 发完后只清空、不关闭)。`python_game_render_test` 用 Godot 按键事件走同一路径登录。
|
||||
批次 4-b 战斗(2026-09-24):战斗代码此前已原样移植(`InstanceBaseBattle`、`ActorInstanceCollisionDetection`、`PythonPlayerInput*`、`uiTarget`),本批只补验证。假服在出生点北 18 m 放一只野狗(npclist 101,怪物不发 `GC_CHAR_ADDITIONAL_INFO`,名字取自 mob_proto;发了会 syserr),出生点在村庄 `ATTRIBUTE_BANPK` 圈内,`CInstanceBase::IsInSafe()` 会挡掉所有命中。`CG_TARGET` 回 `GC_TARGET`,`CG_ATTACK` 回 `GC_DAMAGE_INFO` + `GC_TARGET`,第三下回 `GC_DEAD`。与 40250 相同:单击怪物(`__OnClickActor`)只走过去,按住左键(MBF_SMART → `__OnPressActor`)才走近并连击。`port.login_flow` 第 9 步用显式透视矩阵投影野狗、按住左键直到死亡,检查 target 面板和至少 3 次 `CG_ATTACK`;`python_game_render_test` 用 Godot 鼠标事件走同一路径,截图 combat_mid/combat.png(野狗位于镜头与战士的连线上,被战士挡住,属正常)。新增宿主/测试辅助 `PythonBoot::Evaluate` / `Metin2PythonHost.evaluate`(40250 无对应物)。`python_3d_surface.gd` 修正:D3D 固定管线中材质 emissive 先加进顶点色,再被纹理 MODULATE,Godot 的 emission 却加在纹理之后,导致黑底加色的点击光圈(click_glow_select copy.jpg)显示成灰色方块,角色也被 0.32 的 emissive 洗灰;现在 emission 乘以同一张纹理(`EMISSION_OP_MULTIPLY`)。战斗步骤先等镜头稳定(上一步的走路可能尚未结束),野狗投影落在小地图或任务栏下时先点地面走近一段。已知缺口:伤害数字依赖 `CPythonSystem::IsShowDamage()`,该单元仍在 pending 桩(4-g),故暂不显示。
|
||||
|
||||
批次 4-c 商店(2026-09-24):`PythonShop.cpp` 原样移植(`shop` 模块 + `SHOP_SLOT_COUNT`/金币常量,`initshop()` 按 40250 次序接在 `initfly()` 之后;40250 中间的 `initsnd`/`initeventmgr` 尚未移植),删去 pending 桩与模块桩。uishop 在 `OnUpdate` 里读 `app.GetCursor()`,而 `GetCursorNum()` 是头文件内联、读的是不存在的 CPythonApplication 对象的成员,导致空指针崩溃;现把 40250 `PythonApplicationCursor.cpp`(SetCursorNum/Visible/Mode 等)和 `SetMouseHandler` 原样搬进 platform CPythonApplication,成员改为文件静态量,`GetCursorNum` 改为非内联(头文件 PORT 注释);宿主不画硬件光标,`[0, CURSOR_COUNT)` 内的形状都视为已加载。假服在野狗东 4 m 放杂货商(npclist 9003),`CG_ON_CLICK` 回 `GC_SHOP START`(货架 0 为 27001 红药,50 金),`CG_SHOP BUY` 先扣金(`GC_POINT_CHANGE`)再 `GC_ITEM_SET`,`SELL2` 回 `GC_ITEM_DEL` + 加 9 金,`END` 回 `GC_SHOP END`(与 40250 `CShop::Buy`/`CShopManager::Sell` 次序相同;包的附加长度按 `CInputMain::Shop` 读)。`port.login_flow` 第 10 步:左键点商人走过去打开商店窗口和背包,右键货架 0 购买,背包格 0 拾起后放到货架空格出售,ESC 关闭,逐步检查 `CG_SHOP` 字节、背包格和金币。
|
||||
批次 4-d 任务/NPC 对话(进行中,未完成,2026-09-24):已加入 `PythonEventManager`、`PythonQuest`、`GameEventManager` 逻辑及 Python 模块,并开始扩展假服对话 NPC 和 `GC_SCRIPT` / `CG_SCRIPT_ANSWER` 应答;`parser.cpp` 和 DBCS 字符串步进也作为事件脚本解析依赖加入。当前还没有在 `port_login_flow` 中接通并验证完整的点击 NPC → 显示对话 → 选择答案 → NEXT/DONE 往返流程,也未做门禁/回归确认。相关逐函数审计仍为 `TODO`;本批不能记为完成。
|
||||
批次 4-d 任务/NPC 对话(完成,2026-09-24):`UserInterface/PythonEventManager.cpp`、`PythonEventManagerMoudle.cpp`、`PythonGameEventManagerModule.cpp`、`PythonQuest.cpp`、`EterLib/parser.cpp` 原样移植(101 个函数全量移植完成),删除 pending 替身与 event/quest/eventmgr 模块桩,init 注册按 40250 次序进入 PythonBoot。假服在商店东 1.5 m 放置老人 NPC(npclist 20005,vid 0x00045678),点击(CG_ON_CLICK)后下发 GC_SCRIPT 触发 3 页对话(第 1 页问答选择 0: "Yes",第 2 页 NEXT 按钮,第 3 页 DONE 按钮)。`port.login_flow` 第 11 步验证:点击 NPC 走过去,QuestDialog 出现,通过 UIKey(DIK_RETURN) 依次驱动选择选项 0(发出 CG_SCRIPT_ANSWER 0)、点击 NEXT(发出 CG_SCRIPT_ANSWER 254)并点击 DONE 关闭对话框;服务端确认收到答案序列;port-map 5 个单元状态全转 PORTED;port_gate 全绿通过。
|
||||
批次 4-e 仓库(完成,2026-09-24):`UserInterface/PythonSafeBox.cpp`(29 个函数)原样移植,删除 pending 替身与 safebox 模块桩及常量桩,`initsafebox()` 按 40250 次序接在 `initsystem()` 之后。假服在商店西 1.5 m 放置仓库管理员 NPC(npclist 9005,vid 0x00056789),点击(CG_ON_CLICK)后下发 `ShowMeSafeboxPassword` 聊天命令触发客户端弹出 PasswordDialog;客户端以 `VK_RETURN` 提交空密码发出 `/safebox_password` 命令,服务端下发 `GC_SAFEBOX_SIZE`(size 9 = 45 格)、`GC_SAFEBOX_MONEY_CHANGE`(500 金)与 `GC_SAFEBOX_SET`(格 0 为 vnum 10),客户端弹出 SafeboxWindow 仓库窗口。`port.login_flow` 第 12 步验证:点击仓库管理员走过去,输入密码回车打开仓库,验证 45 格、格 0 物品与 500 金币;从仓库格 0 拖出到背包格 0 触发 `CG_SAFEBOX_CHECKOUT`,服务端核销仓库并放入背包;从背包格 0 拖回仓库格 0 触发 `CG_SAFEBOX_CHECKIN`,服务端核销背包并放回仓库;最后按 ESC 键触发 `/safebox_close`,服务端应答 `CloseSafebox` 关闭仓库窗口。port-map 单元 29 个函数全量标记 PORTED,`port_gate macos` 全绿通过。
|
||||
批次 4-f 好友/公会/公会标记(完成,2026-09-24):`UserInterface/PythonMessenger.cpp`(22)、`PythonGuild.cpp`(75)、`MarkManager.cpp`(29)、`MarkImage.cpp`(23)、`GuildMarkDownloader.cpp`(28)、`GuildMarkUploader.cpp`(28)共 6 个单元(205 个函数)原样移植,删除 pending 替身及 `GameplayModules`/`GameplayModuleConstants` 里的 `guild` 与 `messenger` 桩实现;`initMessenger()` 与 `initguild()` 按 40250 顺序在 `PythonBoot.cpp` 注册;`GameSingletons` 补齐 `kGuildMarkManager`、`kGuildMarkDownloader`、`kGuildMarkUploader` 单例;common DevIL 垫片(`il.h` / `DevIL.cpp`)补齐图象格式常量与像素拷贝 API;`MarkManager.cpp` 防御 `_MSC_VER` 预处理分支,`MarkImage.cpp` 选用客户端分支并为 `minilzo` 适配 `lzo1x_1_compress` 兜底。假服在 entergame burst 期间下发初始好友列表包 `MESSENGER_GC_LIST`("TestFriend",在线)与公会包 `GUILD_GC_NAME`、`GUILD_GC_INFO`("TestGuild",ID 1,等级 20,50 人,123456 金,有领地)。`port.login_flow` 第 13 步验证:客户端接收好友列表,Python 层 `messenger.IsFriendByName('TestFriend') == 1`、非好友为 0,`messenger.RemoveFriend` 后好友被成功移除;公会信息开启 `guild.IsGuildEnable() == 1`、`guild.GetGuildID() == 1`、`guild.GetGuildName() == 'TestGuild'`、`guild.GetGuildMoney() == 123456`、`guild.HasGuildLand() == 1`;标记管理器 `CGuildMarkManager::AddMarkIDByGuildID` 关联公会与标记,`guild.GuildIDToMarkID(1) == 42`,`guild.GetMarkIndexByMarkID(42) == 42`。port-map 6 个单元 205 个函数全量标记 PORTED,`port_map.py check` 0 错误,`port_gate macos` 19/19 全绿通过。
|
||||
批次 4-g 系统设置与战斗浮字(完成,2026-09-24):`UserInterface/PythonSystem.cpp`(53 个函数)与 `PythonSystemModule.cpp`(36 个函数)共 89 个函数原样移植,删除 pending 替身及 `GameplayModules.cpp` 与 `GameplayModuleConstants.cpp` 里的 `systemSetting` 模块桩与常量桩,`initsystem()` 按 40250 顺序在 `PythonBoot.cpp` 中接在 `initapp()` 之后调用。`D3D8Types.h` 补全 `IDirect3D8` 纯虚接口与 `D3DENUM_NO_WHQL_LEVEL` 常量,`PythonGraphic.cpp` 实现 `CPythonGraphic::GetD3D()` 返回提供 800x600/1024x768/1280x1024 32bpp 分辨率的静态 `CDummyDirect3D8`,`windows.h` 补齐 `SM_CXFULLSCREEN`/`SM_CYFULLSCREEN` 与 `GetSystemMetrics`;`PythonSystem.cpp` 默认分辨率设为 800x600 并在 `PythonBoot::Start`/`SetUISize` 中与 host canvas 尺寸同步,`GetDisplaySettings()` 增加 `lpD3D` 空指针防御。`port.login_flow` 第 14 步验证:`systemSetting` 模块无 stub 标记,`GetResolutionCount() > 0` 且分辨率元组合法,伤害浮字控制 `IsShowDamage()` 与 `SetShowDamageFlag(1/0)` 双向开关正常,聊天视图 `IsViewChat`、角色名字 `IsAlwaysShowName`、摆摊文字 `IsShowSalesText` 标志位及音量设置同步生效,`GetConfig()` 与 `SaveConfig()` 正常读写并清理测试配置。port-map 2 个单元 89 个函数全量标记 PORTED,`port_map.py check` 0 错误,`port_gate macos` 19/19 全绿通过。
|
||||
批次 4-h 声音(完成,2026-09-24):`UserInterface/PythonSoundManagerModule.cpp`(14 个函数)原样移植,删除 `GameplayModules.cpp` 与 `GameplayModuleConstants.cpp` 里的 `snd` 模块桩与常量桩;`StdAfx.h` 增加 `initsnd()` 声明并在 `PythonBoot.cpp` 中按 40250 顺序接在 `initfly()` 之后、`initeventmgr()` 之前调用。`MilesLib/SoundManager.cpp` 补齐单例管理、40250 音量对数衰减等级换算(`__ConvertRatioVolumeToApplyVolume` / `__ConvertGradeVolumeToApplyVolume`)、音量备份恢复(`SaveVolume`/`RestoreVolume`)与静音无崩溃播放兜底。`PythonBoot.cpp` 全局生命周期管理 `CSoundManager` 单例。`port.login_flow` 第 15 步验证:`snd` 模块无 stub 标记,`SetMusicVolume`/`SetMusicVolumef` 音量生效,`SetSoundVolume`/`SetSoundVolumef` 音量生效,`SetSoundScale`/`SetAmbienceSoundScale` 距离缩放生效,`PlaySound`、`PlaySound3D`、`PlayMusic`、`FadeInMusic`、`FadeLimitOutMusic`、`FadeOutMusic`、`FadeOutAllMusic`、`StopAllSound` 均执行通畅。port-map 单元 14 个函数全量标记 PORTED,`port_map.py check` 0 错误,`port_gate macos` 19/19 全绿通过。
|
||||
pending 替身彻底清零与 Locale 移植(完成,2026-09-24):`UserInterface/Locale.cpp`(24 个函数,含 `LocaleService_*`、`CheckIME`、多语言配置读写等)与 `EterLocale/Japanese.cpp`(3 个假名校验函数)、`Japanese.h` 1:1 原样移植入 port 层;消除 `extension/src/platform/pending/` 目录下的所有替身(`Locale.cpp` 与 `RaceData.cpp`,pending 目录彻底清零删除);消除 `platform/UserInterface/PythonApplication.cpp` 中手写的临时 `LocaleService_*` 重复符号。`Locale.cpp` 默认语言配置对齐 40250 客户端实际资源(`EUROPE` / `locale/en` / `1252` / `10002`),并在 `PythonBoot::Start` 中读取 `locale.cfg`。port-map 两个单元全量更新标记(`SelectDlgProc` 为 N_A,其余全部 PORTED),`port_map.py check` 0 错误,`port.login_flow` 15 步全绿,`port_gate macos` 19/19 全绿通过。
|
||||
P4 顶层应用单元与 UDP 套件收敛(完成,2026-09-25):`UserInterface/PythonApplication*.cpp` 家族解耦重构完成,`PythonApplicationCamera.cpp`(24)、`PythonApplicationEvent.cpp`(27)、`PythonApplicationProcedure.cpp`(5)、`PythonApplication.cpp`(39)与 `EterLib/PathStack.cpp`(8)、`EterLib/NetDatagram*.cpp`(24)全量移植并记账,`common/shim/win32/winsock.h` 增加 `mt_winsock_recvfrom` 垫片。**`layer logic` 达成 100.0% 完成度(3338/3338 单元清零,TODO=0,DIVERGENT=0)**。
|
||||
legacy 宿主与双路由清理(完成,2026-09-25):在 `logic` 逻辑层达成 100.0% 移植完成度且全部 19 个门禁通过后,按照规划全面收敛 `project/client_main.gd` 中的 `MT_PORT_PATH=legacy` 旁路代码。移除了 `AppFlow`、`LiveSmokeTest`、`PlayableLiveTest`、`NetTrace` 等旧 GDScript 串场组件的预加载与 `_start_legacy_route()` 回退逻辑;主场景 `client_main.tscn` 直接由原生 40250 `port` 路径(`PythonUISurface` + `Python3DSurface` -> 内嵌解释器执行 40250 原版 `system.py`)接管主循环;保留包内离线诊断模式(`render`/`python`/`forest_render`/`particle_exit`),显式传递 `MT_PORT_PATH=legacy` 时输出已废弃警告并直接按原生 port 路由启动。`client_main.tscn` 运行验证正常,`port.login_flow` 与 `port_gate.sh macos` 19/19 测试套件全绿通过。
|
||||
|
||||
每个切片都必须同时跑 legacy/port 双路回归;默认路由已切到 `port`(2026-09-24);port 路由稳定后删除总开关和剩余 legacy 宿主。
|
||||
|
||||
## 5. 数据源切换:m2dev assets → 40250
|
||||
|
||||
@@ -537,9 +539,17 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
|
||||
| platform | 2091 | 0 | |
|
||||
| 合计 | 10609 | 0 | |
|
||||
|
||||
2D 之后(2026-09-23):logic 46 个 `PORTED`(EterPack、EterPackManager、lzo、tea、Stl),platform 21 个 `ADAPTED`
|
||||
(PackInitialize、FileLoader、MappedFile、FileBase、CRC32)。只标了 proto_test + port_eterpack_test 覆盖率运行实际执行到
|
||||
的函数。
|
||||
现状(2026-09-25,`port_map.py status`):
|
||||
|
||||
| 层 | 函数 | 完成 | TODO | PORTED | ADAPTED | N_A | DIVERGENT | 完成度 |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| **logic** | **3338** | **3338** | **0** | **3208** | **104** | **26** | **0** | **100.0%** |
|
||||
| python | 5175 | 1631 | 3544 | 1621 | 10 | 0 | 0 | 31.5% |
|
||||
| platform | 2096 | 985 | 1089 | 830 | 155 | 0 | 22 | 47.0% |
|
||||
| 合计 | 10609 | 5954 | 4633 | 5659 | 269 | 26 | 22 | 56.1% |
|
||||
|
||||
- **`logic` 逻辑层已达成 100.0% 完成度**(TODO = 0,DIVERGENT = 0,队列清空)!所有 40250 核心玩法逻辑单元(`UserInterface`、`GameLib`、`EterLib` 逻辑类、`EterPack`、`EterLocale`、`EterBase` 纯逻辑类)全部移植完毕,并通过 19/19 全套自动化门禁测试。
|
||||
|
||||
|
||||
与基线前的数字(logic 3285、python 4890、platform 2229,共 10404)相比的变化:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user