Files
mtgodot-poc/audit/contracts/lifecycle.platform-release.md
T
shenandshen c93894313a fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧
- inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域
- 包含其他累积的功能开发和测试文件
2026-09-21 16:38:59 -07:00

109 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# lifecycle.platform_release —— Windows/桌面窗口、导出、资源自包含、崩溃和发布门禁
状态:`PARTIAL`
本合同检查 40250 的 Win32 应用/窗口消息循环、全屏与窗口状态、资源自包含、版本/CRC 检查、异常退出、前后台处理和发布产物。判断标准是目标平台上是否具备相同的启动、窗口、资源、错误处理和退出副作用;“某个平台能导出”不能代替 Windows 40250 等价实现。
## 40250 参考调用链
- `EterLib/MSApplication.cpp` / `MSWindow.cpp`
- `CMSApplication::Initialize` 保存 HINSTANCE`MessageLoop` 通过 `GetMessage/TranslateMessage/DispatchMessage` 驱动窗口;`WM_CLOSE` 转为退出消息。
- `CMSWindow` 注册 Win32 窗口类,创建 HWND,处理 `WM_SIZE``WM_ACTIVATEAPP`、显示/隐藏、窗口/客户区尺寸、鼠标坐标、居中、位置和全屏窗口尺寸。
- `UserInterface/PythonApplication.cpp` / `PythonApplicationProcedure.cpp`
- 初始化 800×600、60 FPS、相机/渲染/网络/音频/Granny 共享资源,并在非 Debug 模式安装 Eter 异常处理器。
- `WM_ACTIVATEAPP` 负责音量 Save/Restore 和全屏显示模式切换;`WM_SIZE`/`WM_EXITSIZEMOVE` 重建 back buffer`WM_CLOSE` 按构建配置退出或进入退出流程。
- 统一处理 IME 消息、鼠标 capture、输入和窗口激活状态,主循环按固定帧/网络/场景更新顺序执行。
- `UserInterface/CheckLatestFiles.cpp`
- 可选编译 `CHECK_LATEST_DATA_FILES` 时启动低优先级线程,对 `CRC32_inc.h` 中的文件逐个检查可读性和 CRC;错误通过 Application error string 触发退出。
- `EterPack/*` / `Locale*`
- 运行时从 EterPack/locale 读取资源,并通过版本/资源链保证客户端数据完整;坏资源和版本不匹配有明确失败路径。
## 当前端实现映射
- `project/client_main.gd` / `project/app_flow.gd`
- 已有 Godot 主场景、AppFlow 状态机、登录→选人→游戏切换、断线重连和测试模式;客户端启动时配置协议、AssetPack 和资源根。
- Godot MainLoop 取代 Win32 `CMSApplication`,没有 40250 的 HWND 类注册、Win32 消息分派、back buffer resize 和全屏显示模式切换等价代码。
- `project/app_lifecycle.gd`
- 已处理 Godot 的暂停/恢复、窗口焦点、内存警告、Android 返回和桌面关闭信号,后台降 FPS 并绑定客户端/音频。
- 窗口失焦/重新获得焦点现在复用后台入口,分别执行音量保存、BGM/SFX 静音和恢复;关闭请求目前主要发信号,仍未形成与 40250 `WM_CLOSE`/`PostQuitMessage`/退出清理一致的统一出口。
- `project/asset_root.gd` / `asset_pack.gd` / `build-macos-client.sh` / `build-android.sh` / `project/export_presets.cfg`
- macOS 脚本将 assets/bgm 复制到 app ResourcesAndroid 使用 `assets.zip`/`asset_index.txt`,AssetRoot 支持环境变量、散文件、包内资源和可执行文件旁资源。
- 当前没有 Windows 导出预设或 Windows GDExtension 构建脚本;资源链也不是 EterPack 的原生 eix/epk/CRC/更新流程,移动端还依赖外部 zip。
- `oracle/*`
- 有 Windows/Wine Granny 对拍工具和文档,但它是测试 oracle,不是客户端发布/崩溃/版本链。
## 分支等价矩阵
| 40250 判据/副作用 | 当前实现 | 结论 |
|---|---|---|
| Win32 HINSTANCE/HWND、窗口类、消息循环和 WM_CLOSE | Godot MainLoop/Window | 平台适配;没有 Windows 40250 同链实现,Windows 发布未闭合 |
| WM_SIZE/EXITSIZEMOVE、back buffer resize、窗口/客户区尺寸 | Godot 窗口系统自动处理,脚本未提供等价回调证据 | 部分等价;缺 Windows 原生尺寸/渲染设备恢复测试 |
| 前后台激活、全屏显示模式切换和音量保存恢复 | AppLifecycle 对 focus/pause 统一进入/退出后台,保存并恢复 BGM/SFX;全屏切换由 Godot 配置承担 | 部分等价;焦点音量副作用已有回归,Win32 全屏显示模式分支仍缺失 |
| 初始化/固定帧/网络/渲染/退出顺序 | AppFlow/GameScene/Godot scene tree 已有状态机 | 部分等价;没有与 `CPythonApplication::Process` 更新顺序和异常中止路径的生产级证据 |
| Eter 异常处理、Abort/Exit 和错误退出 | Godot 日志/进程退出,未发现专用异常处理器和 crash report | GAP;崩溃收集、错误字符串和资源回收链未对齐 |
| CheckLatestFiles CRC/可读性/低优先级线程更新检查 | 没有对应版本/CRC 更新线程 | GAP |
| EterPack/locale 自包含和坏资源失败回退 | AssetRoot/AssetPack/外部 assets.zip/手工复制 | 部分等价;资源来源可用,但原生 pack、版本校验、坏包/缺包门禁和 Windows 路径未闭合 |
| Windows 导出、GDExtension、资源自包含和启动验证 | 只有 macOS/Android 导出预设;macOS 导出探针通过 | GAP(Windows);其它平台基础导出通过 |
| 应用关闭、场景释放、音频/网络/模型清理 | queue_free、AppFlow 状态切换和局部生命周期测试 | 部分等价;没有 Windows 关闭消息、崩溃中止和整包资源释放门禁 |
## 已执行测试
- `project/app_flow_lifecycle_test.gd`:通过;覆盖 AppFlow 单一生命周期属主、登录/游戏断线重连和场景状态摘要。
- `project/bgm_test.gd`:通过;覆盖窗口失焦/获得焦点时 BGM/SFX 保存、静音和恢复;修复前该回归有 2 项失败。
- `project/dds_lifecycle_test.gd`:通过;20 次 DDS 解码后图像仍有效且节点计数不变。
- `godot --headless --path project --editor --quit`:退出码 0,脚本/GDExtension/项目结构校验完成;过程自动补建若干缺失 `.uid` 缓存文件,未发现阻断错误。
- `godot --headless --path project --export-release macOS /tmp/mtgodot-platform-audit.app`:退出码 0,macOS 导出流程通过;该结果不代表 Windows 导出可用。
## Deep audit round 2026-09-21
### Fresh regression results
- `app_flow_lifecycle_test.gd``dds_lifecycle_test.gd` 均退出码 0;覆盖生命周期属主和 DDS 资源解码后对象稳定性。
- `godot --headless --path project --editor --quit` 退出码 0,但编辑器自动重建了缺失的 `view_equipment_ui_test.gd.uid`,且在无 Android daemon 时出现连接拒绝提示;这不是 Windows 发布验证。
- 当前没有 Windows export preset/GDExtension 构建脚本;本轮没有把 macOS/Android 结果替代 Windows 发布通过。
### Static parity conclusion
- Godot MainLoop/AppLifecycle 能覆盖跨平台基础生命周期,且焦点音量保存/恢复已对齐 `WM_ACTIVATEAPP` 的可观察副作用,但没有 40250 Win32 HWND/WM_SIZE/WM_CLOSE、Eter 异常处理、CRC 更新检查和统一崩溃/退出链。
- 资源合同确认的 PCK/zip/loose 入口和当前自定义 pack 不能直接证明 Windows 自包含资源、坏包/缺包阻断、版本校验和路径大小写行为。
- 未发现可执行的 Windows 导出、Windows GDExtension 和启动/连接/地图/音频/退出冒烟门禁,因此平台发布合同继续保持 PARTIAL。
本轮仍为 `PARTIAL`,完成焦点激活链的实现和第三轮平台生命周期证据登记。
### Implementation fix round 2026-09-22T09:10Z
- 修复前新增的 `bgm_test.gd` 失焦回归出现 2 项失败:`WM_WINDOW_FOCUS_OUT` 不会静音 BGM/SFX,重新获得焦点也没有恢复备份音量。
- 参考 `CPythonApplication::WindowProcedure``WM_ACTIVATEAPP` 分支,`AppLifecycle._notification` 现在在 `APPLICATION_FOCUS_OUT`/`WM_WINDOW_FOCUS_OUT` 调用 `_enter_background()`,在对应 `*_FOCUS_IN` 调用 `_exit_background()``_bg` 守卫避免同时收到 pause/focus 通知时重复保存或恢复。
- 修复后 `bgm_test.gd``app_flow_lifecycle_test.gd``mouse_controller_test.gd``audio_miles_test.gd` 通过。全屏显示模式、WM_SIZE/back-buffer、Windows 导出和 Win32 异常/CRC 链仍为平台级未闭合项。
### Active EterLib device-core review
- `EterLib/GrpDevice.cpp``GrpScreen.cpp``GrpShadowTexture.cpp` 负责 D3D 设备/交换链创建、back buffer、lost/reset、屏幕尺寸和阴影纹理资源;这些不是单纯由窗口系统自动替代的 UI 行为,而是和渲染资源、全屏切换、设备丢失恢复绑定的状态机。
- 当前 Godot renderer 由引擎托管,`AppLifecycle` 只收到焦点/暂停/窗口通知,没有对应的设备创建、lost-device、reset、back-buffer 和 shadow texture 重建回调,也没有 Windows 目标上的验证矩阵。
- 因此本轮完成上述活跃 EterLib 图形设备源码静态核对;Godot editor/macOS 导出通过不能证明 Windows D3D/窗口/设备恢复一致,平台合同继续为 `PARTIAL`
### Active EterLib graphics/runtime utility review
- `EterLib/GrpDetector.cpp` 枚举 adapter/display mode/pixel format/capability`GrpBase.cpp` 维护 back buffer、camera/projection/view、default index buffer、dynamic vertex stream 和 screen effects`StateManager.cpp` 保存/恢复 D3D render/texture/shader/transform/stream/index/material 状态。
- `GrpVertexBuffer*``GrpIndexBuffer*``GrpD3DXBuffer``GrpPixelShader`/`GrpVertexShader``GrpLightManager``GrpObjectInstance``GrpColorInstance` 分别管理 GPU buffer/shader/light/object transform/color transition;当前 Godot renderer 将这些责任下沉给引擎,没有对应 Windows lost/reset 和状态恢复 oracle。
- `Pool.h``Dynamic.h``Ref.h`/`ReferenceObject.cpp``Thread.cpp``Event.h``Mutex.h` 形成参考端池化、引用计数、线程、事件排序和同步清理基础;当前端虽有 queue_free/RefCounted/SceneTree,但池容量、引用自毁、线程 shutdown 和按时间排序事件没有同一可观察契约。
- 本轮完成 EterLib 图形/runtime utility 活跃文件静态核对,合同仍为 `PARTIAL`
### Active UserInterface platform-host review
- `PythonSystem.cpp` 的配置文件、分辨率/频率枚举、窗口状态、音量/阴影/光标和 D3D adapter 查询,与当前 Godot `project/system_options.gd`/`app_lifecycle.gd` 的配置来源和窗口能力不同。
- `PythonApplicationLogo.cpp`/`MovieMan.cpp` 通过 DirectShow/DirectDraw surface 驱动开场视频并恢复 D3D 状态;当前项目没有等价的 Windows media surface/skip/fade 生命周期。
- `ProcessCRC``ProcessScanner``PythonExceptionSender` 与 GameGuard/HackShield/XTrap 提供参考端完整性/异常/安全发布门禁;当前没有相应的 Windows 组件和可执行验证。静态核对完成,但这些平台能力仍明确为 `PARTIAL/GAP`
## 已确认差异和未验证项
1. 增加 Windows 导出预设、Windows GDExtension 构建和资源自包含脚本,至少验证启动、连接、地图/模型/音频资源加载和退出。
2. 建立平台窗口合同:窗口大小/客户区、resize、全屏/窗口化、激活/失焦、关闭、鼠标坐标和输入法消息的运行时快照。
3. 建立发布资源门禁:资源清单、哈希/版本、缺包/坏包/权限失败、路径大小写和外部 zip/PCK 解包失败均必须可诊断并阻断启动。
4. 补充崩溃/异常/退出测试和诊断日志;区分正常关闭、网络断开、资源失败、GDExtension 加载失败和 native crash。
5. 将 Windows、macOS、Android 的导出产物、资源来源、版本号和回归测试结果写入发布报告,避免把单平台导出通过误记为完整发布通过。
## 下一轮验证入口
- `world.environment_weather` 是当前唯一尚未逐分支审计的映射域;完成后生成全清单覆盖报告,再进入按优先级修复阶段。