Skip to content

MaaEnd:损坏安装支持人工确认官方修复(旧方案) - #1910

Closed
youngslin wants to merge 4 commits into
AUTO-MAS-Project:devfrom
youngslin:fix/maaend-unusable-install-recovery
Closed

youngslin wants to merge 4 commits into
AUTO-MAS-Project:devfrom
youngslin:fix/maaend-unusable-install-recovery

Conversation

@youngslin

Copy link
Copy Markdown

问题

MaaEnd 已有 transaction.json 快照恢复与 MXU 自升级配合逻辑,不能按 BGI 的单文件未确认标记处理。当前被 MXU 原生升级过、但仍可正常识别的本体可以保持运行;然而本体 MaaEnd.exe、interface.json 或 resource/agent 真正缺损时,关闭托管更新就没有恢复通道,配置与运行都被 check() 拦住。

修改

  • 在既有跨进程安装锁下先完整执行 runtime-interface.json 和 transaction.json 事务恢复。接着主动验证 MaaEnd 原生本体;只有不可识别且 MAS 曾保存可信 program-identity.json 架构时,通过独立全局弹窗询问「官方完整包修复 / 取消任务」。
  • 对用户选择的同一份身份记录保留字节快照,下载前和下载后复核其未变化,并确认外部 MXU 没有趁机重新修复。完整包继续走官方发布匹配/大小/SHA256/平台架构校验及 script_install.install_package 的快照事务;安装后复核文件回执,绝不删 transaction.json 或跳过未确认状态。
  • 不要求永久开启托管更新:用户这一次明确选择可以单独修复。正常的 MXU 自升级可读且版本身份有效,即使旧 MAS 安装回执不再对应,也不会因此被强制覆盖、降级。
  • 身份缺失、不安全或变化,无法停写,前端不存在、取消/超时/断线均保留现场并停止启动。前端服务在主动重连后也清理旧弹窗。
  • 新增损坏本体重装、身份记录替换拒绝、无可信身份拒绝和正常安装不触发弹窗的回归用例,以及 WebSocket 重连回归测试。

区别

本 PR 独立于 BetterGI #1900 / Whimbox #1905 / SRC #1906 / BAAH #1908;MaaEnd 使用带架构身份的完整发行 ZIP 及目录事务,既有 MXU pending 不会被 MAS 擅自写入或删除。

验证

正在执行项目现有 Windows/Ubuntu pytest、格式/类型检查及 Windows 验证构建;真实 MXU/Electron 安装器端到端验证尚未进行。

@github-actions github-actions Bot added 专项: MaaEnd 类型: 修复 按更新日志碎片自动设置 labels Nov 10, 2026
Comment on lines +317 to 327
root,
config,
recovery_identity=snapshot,
)
await script_update.confirm_current_install(root)
await push_dispatch_log(self.script_info, f"用户明确修复 MaaEnd:{result}")
return True

async def _prepare_program_update(self, root: Path) -> None:
if self._program_update_prepared:
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: _recover_unusable_install runs unconditionally before check(), raising InstallUnsafeError on manual or custom builds and masking existing path verification error messages.
Severity: MEDIUM

Suggested Fix

Only run _recover_unusable_install when takeover is enabled or when MAS-managed install artifacts (such as installed.json) exist, or defer the check until after check() verifies directory and executable existence.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: app/task/MaaEnd/manager.py#L287-L327

Potential issue: In `main_task`, `_recover_unusable_install` is called unconditionally
before `check()`, executing `script_update.read_install` across all modes even when
takeover is disabled and no `installed.json` exists. If `read_install` encounters an
empty directory, invalid path, or non-standard version string (e.g. non-PEP 440 dev
builds), it raises `InstallUnsafeError` instead of allowing execution to reach
`check()`. This replaces previous path configuration warnings with an inaccurate
"install damaged" error and blocks valid manual or development builds.

Also affects:

  • app/task/MaaEnd/manager.py:525~533

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Contributor

总体结论:修改后合并

AUTO-MAS-Project/AUTO-MAS #1910

宝宝,后端这次保留了事务恢复、身份记录复核和官方完整包校验,没有把旧回执失效一律当作损坏,这个边界守住啦。不过配置入口的旧遮罩会盖住新的恢复弹窗,用户到这里就点不到“修复”了喵。

MaaEnd 管理器负责持锁、先恢复目录事务,再询问是否修复;专项更新器选择和校验官方包,通用安装服务负责目录快照与切换,前端只发送本次请求的选择。需要补的是两套界面之间的衔接。

必须处理

[兼容 · P2] 配置会话遮罩盖住修复弹窗,配置入口无法完成恢复

位置:MaaEndInstallRecoveryModal.vue:29–39;useNativeGuiSession.ts:159–170;GuiSessionMask.vue:51–59;MaaEndScriptEdit.vue:1001–1026、1135–1142。

静态可确定的流程是:安装损坏且有可信身份记录,用户从账号页或托管页打开原生配置。启动请求返回任务 ID 后,页面立即显示配置会话遮罩;与此同时,后端在真正启动 MaaEnd 前等待恢复选择。新的恢复 Modal 层级只有 900,但账号页的 GuiSessionMask 为 1000,托管页的 maaend-config-mask 更是 9999。这些遮罩都挂到 body,覆盖弹窗及按钮,弹窗先后到达也不会改变层级关系。

结果是配置入口看起来已经进入会话,却还没启动原生 GUI,用户无法通过鼠标选择修复或取消,只能结束配置会话,或等后端 120 秒超时。现有 appOverlays.css 只处理标题栏留白和尺寸,没有提高弹窗层级;WebSocket 重连清理也解决不了遮挡。

请在前端协调“等待修复”和“原生配置会话”两种界面状态,保证修复选择位于会话遮罩上方,或者等待修复时暂不展示该遮罩,同时保留窗口控制区。不能只升到 1001,否则托管页的 9999 仍会挡住。补一条从配置入口发起任务、收到恢复询问后能实际点击修复/取消的界面验证,就能把这条路接通啦。

非阻断问题

[规范 · P3] 英文、日文弹窗仍会显示中文版本状态和修复来源。 install_recovery.py:32–65发送“未知”和“所选通道官方完整包”;前端直接展示这两个非空值,所以翻译里的 Unknown/不明不会生效。让界面负责这些固定文案即可,这点不单独阻止合并。

验证情况

dot酱静态核对了恢复、下载前后身份复查、安装切换、取消停写、配置锁释放及 WebSocket 注册/清理,没有运行项目代码或测试。现有 CI 日志中,Windows 1809 passed、2 skipped,Ubuntu 1770 passed、40 skipped;前端 58 个测试文件、308 项测试通过,格式检查和 Windows 验证包构建通过。

新增测试覆盖损坏 EXE 修复、身份变化拒绝、无身份拒绝、正常安装不询问和主动重连清理;它们没有把配置页遮罩与恢复 Modal 放在一起验证,因此全绿仍会漏掉这个交互问题。真实 MXU/Electron 安装修复的端到端效果尚未验证。后端的保护继续留好,把弹窗从遮罩后面请出来再合喵。

—— 摇着尾巴的 dot酱敬上 🐈

youngslin added a commit to youngslin/AUTO-MAS that referenced this pull request Nov 10, 2026

Copy link
Copy Markdown
Author

按目前的架构决定,此 PR 的 #1900 时代人工恢复/弹窗方案停止采用。可信 program-identity.json 身份校验、官方完整包修复逻辑已迁移到 #1913;旧人工弹窗不再保留。

请以 #1913 为这条脚本的最终专项实现(依赖已经合并的 #1916 公共恢复框架)。主 PR 仍需以最新 CI 和代码审查为准,不代表已合并或生产验证通过。本 PR 关闭以避免旧 UI / WS 协议误被合入 dev。

@youngslin youngslin closed this Nov 10, 2026
@youngslin youngslin changed the title fix(maaend): allow user-confirmed repair of unusable MXU/MaaEnd installs MaaEnd:损坏安装支持人工确认官方修复(旧方案) Nov 10, 2026
youngslin added a commit that referenced this pull request Nov 10, 2026
## 方向:仅采用 #1916 公共恢复
整合旧 #1910 的可信 program-identity.json、官方完整包下载与校验;以及 #1913 的原生
transaction.json/previous/ready 安全性检查。删除所有恢复弹窗、专用 WS 及“用户确认跳过”。恢复由
`auto_recover_script_install` 接收健康检查、原生回滚和官方完整包修复回调,主流程保持安装锁及原生 MXU
清理机制。

只有确认原生进程停止、完整发行文件和回执一致、且没有尚可回滚的 previous/ready,才允许归档过期事务。不可读架构、缺少 MAS
自有身份时绝不猜测官方安装目标。关闭托管的自定义构建遵守既有 MXU 行为,不强行覆盖。自动恢复结果交公共队列末尾汇总。

本轮补充:安装器复制 `ready` 后、写入 `transaction.json` 前失败或取消时,在没有
journal/previous、确认停写和持有安装锁的条件下可清理未提交暂存。若原安装健康,核验收据后清理;若 EXE 损坏或因 MXU
独立升级导致旧收据失效,仅允许 AutoProxy + 开启托管 + MAS 可信 `program-identity.json`
的修复请求清理暂存,随后必须由 #1916 公共入口执行官方完整包重装与最终健康复核。身份缺失、previous 或 journal
存在时继续保留现场并阻断,不能把清理暂存当作恢复成功。回归测试包含真实安装器的 ready
阶段故障注入、两类受控自动修复,以及缺乏可信身份时拒绝清理。

本 PR 取代 #1910;未运行真实 MXU/Electron E2E,CI 以最新提交为准。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

专项: MaaEnd 类型: 修复 按更新日志碎片自动设置

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants