6.3 KiB
梦三安装、卸载与发布前审查(2026-10-04)
结论:当前存在发布前应处理的问题,不能把语法检查通过视为安装、卸载验收通过。本次只审查实际源码与本地发布材料,没有修改安装器,没有执行真实安装、卸载、更新、断网模拟或发布操作。
发现的问题
1. P1:当前 Gitea 发布材料不能直接用于客户端安装
位置:.gitea/workflows/release.yml:61、update.js:238、tools/UPDATE.md:20。
Gitea 工作流在标签已经创建后,克隆标签,在临时目录生成清单并上传附件;它不会把生成的清单写回标签。客户端却从该标签的 raw 路径读取 dist/manifest.json 和模块清单,不读取附件。
当前本地 dist/manifest.json 仍是 2.0.1.1,缺少 update_channels 与 modules;本地 dist/modules 不存在。如果从这种源码状态创建新版 Gitea 标签,附件即使生成成功,客户端也会在清单校验或获取模块清单时失败。
发布前必须把同版本的主包清单、模块清单和迁移清单提交到标签所指向的提交;Gitea 工作流也应先核对标签内清单,而不是仅核对临时生成的附件。GitHub 工作流已包含先生成并提交清单、再创建标签的步骤,两条流程不能混为一谈。
2. P1:非 Error 类型的写入失败被当成成功
位置:update.js:470;适配证据:引擎 noname/init/browser.js:128、noname/init/cordova.js:287。
包装器只拒绝 result instanceof Error。浏览器端写入失败传回字符串,Cordova 的文件错误可以是含 code 的对象,写入结束回调也可能通过事件目标携带错误。这些情况都会进入 resolve。
如果临时下载已成功,而最后覆盖真实文件失败,updateAllFiles 不会再读取真实目标做哈希校验,仍可能推进安装版本并提示完成。应规范化各端错误,并在真实文件写入后读取校验;只有最终资源校验成功才标记安装完成。
3. P1:删除错误被丢弃,浏览器异常还可能一直占用操作锁
位置:update.js:483;适配证据:引擎 noname/init/node.js:186、noname/init/browser.js:138、noname/init/cordova.js:300。
删除包装器忽略回调参数,也没有向支持第三个参数的浏览器实现传入错误回调。浏览器本地文件服务请求失败时,默认错误处理不会结算包装器的 Promise,安装或卸载可以一直停住,finally 无法释放锁。
删除后虽然有存在性检查,但 safeCheckFile 又把检查错误当成缺失;删除失败同时检查失败时仍可能提示卸载成功。Cordova 实现还在实际删除完成前调用回调,因此立即检查也有误报失败的竞态。
应可靠等待删除完成,传播删除与检查错误,仅把确定的“文件不存在”当作可忽略结果。
4. P1:卸载部分失败后仍保留已安装状态
位置:update.js:1194、extension.js:253。
卸载按列表直接删除,直到全部成功才设置 disabled。若前面若干文件已删除,后续文件因锁定、权限等原因失败,catch 仅提示失败,安装版本仍保持原值。
重启后启动逻辑仍按这个版本判断模块可用;若入口仍在而依赖文件已被删除,会注册一个无法正常进入的梦三模式。卸载应有可恢复的处理中状态:处理中不注册模式,重试时继续使用原所有权清单,全部删除成功才完成卸载。
5. P2:读取旧版清单失败后用新版清单卸载,可能遗漏旧文件
位置:update.js:1173、update.js:1180。
已安装模块标签不可用,或切换到没有该旧标签的下载源时,会回退到主包版本或最新模块清单。新版清单没有旧版已经移除的路径,这些文件就不会被删除;循环结束后仍设置 disabled 并提示文件已卸载。
应在安装或成功更新时保存本地模块所有权清单,卸载依据实际安装的清单。无法取得准确所有权时,不应把仅删除新版路径说成完整卸载;不能用递归删除整个目录代替,以免删除用户自行放入的文件。
6. P2:回滚失败后仍删除唯一旧文件备份
位置:update.js:826、update.js:832。
回写旧文件失败只记录到控制台,finally 仍删除 old 下的备份。例如真实目标被锁定或空间不足导致恢复失败,而临时目录可以正常删除,此时旧版本的恢复副本会被清除。
应跟踪未恢复的文件,保留对应备份与恢复信息,明确提示恢复未完成,不能执行无条件清理。
核对正常路径的结果
- 安装下载先做 SHA-256 和大小校验,随后才进入真实文件替换。
- 主包与梦三使用独立清单;disabled 状态下主包更新和查漏补缺不会主动安装梦三。
- 模块清单校验限制文件属于
mengsan/,拒绝路径穿越;正常卸载按清单删除,不递归清空模块目录。 - 卸载入口没有清除梦三征程存档或通关记录。
- 安装、卸载取消确认后会进入 finally,释放菜单操作锁。
- 模式使用延迟加载;只有进入梦三时才导入完整模式。
- 明确成功的普通安装或更新会在资源步骤后保存模块版本;存在上述跨端错误回调问题,因此该顺序本身不足以保证资源已正确落盘。
本次静态核对
extension.js、menu.js、update.js、mengsan/register.js语法检查通过。- 扫描梦三源码 398 条显式相对模块引用,未发现目标文件缺失;这不覆盖运行时动态路径和网络清单。
- 最近新增的描述模块、虚拟网格模块、地图存档清理模块和刘备立绘在实际目录中存在。
- 当前梦三目录有 267 个未跟踪文件,近期新增的运行时代码和资源也在其中。发布工作流基于 Git 标签打包,发布前必须把需要发布的文件纳入提交,不能只核对本地目录存在。
修复后的实机验收范围
首次安装、卸载后重装、已安装版本升级、旧整包迁移、保留存档后重装、取消操作、写入失败、删除失败、断网重试,以及 Windows、浏览器文件服务与支持的手机端。还需分别验证 GitHub 和 Gitea 标签内 raw 清单与发布附件、资源文件完全对应。