Skip to content

fix(recovery): 修复反复退出未重启模拟器及任务恢复上限误计数 - #1426

Merged
Beatrice-betty merged 2 commits into
wess09:devfrom
Beatrice-betty:codex/fix-recovery-emulator-limit
Nov 3, 2026
Merged

Beatrice-betty merged 2 commits into
wess09:devfrom
Beatrice-betty:codex/fix-recovery-emulator-limit

Conversation

@Beatrice-betty

@Beatrice-betty Beatrice-betty commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

📋 许可确认

  • 我已仔细阅读并同意 GPL-3.0 开源协议 中的所有条款,并理解我的贡献将受到该协议的约束
  • 我确认我提交的代码不会侵犯任何第三方的知识产权

💯 代码质量确认

  • 我已执行静态类型检查,确保代码不含基本类型错误:
    • 后端:uv run ruff check . --select E9,F63,F7,F82 --ignore F821,F722
    • 前端:npm run typecheck --prefix frontend
    • 实际执行等效后端命令 uv run --no-sync python -m ruff check . --no-cache --select E9,F63,F7,F82 --ignore F821,F722,通过。未修改前端代码,未运行前端类型检查,故本项不勾选。
  • 对于难以解决的必要类型忽略标记,我已添加注释说明原因
    • 不适用:没有新增类型忽略。
  • 涉及游戏交互的代码遵循状态循环模式(截图-检查循环),未使用"点击-等待-休眠"模式
    • 不适用:修改调度器恢复和计数,不新增截图、点击或等待流程。
  • 新增/修改的 UI 模板图像基于固定的 1280×720 分辨率截图
    • 不适用:没有修改图像资源。
  • 若修改了 module/config/argument/ 下的 YAML 源文件,已运行 uv run -m module.config.config_updater 并提交生成产物
    • 不适用:没有修改 YAML、配置结构、默认值或生成文件;只调整现有翻译键的名称和说明。
  • 若修改了游戏逻辑,已在真实模拟器实例上运行验证(游戏逻辑无自动化测试)
    • 尚未进行真实模拟器、登录和长时间运行验证;下述测试均为隔离设备后的离线验证。

🔍 变更类型 (勾选所有适用项)

  • 🐛 Bug 修复 (修复一个问题)
  • ✨ 新功能 (添加新功能)
  • 🔄 重构 (不改变功能的代码调整)
  • 📝 文档更新
  • 🔧 配置变更
  • 🎨 代码风格优化
  • 💅 样式调整 (UI/UX 外观变化)
  • 🚀 性能提升
  • ✅ 测试相关
  • 🌐 国际化/本地化
  • 🔗 依赖更新
  • 🗺️ 活动/地图数据 (campaign/)
  • 🖼️ 资源图像 (assets/)
  • 🔌 MCP 工具相关 (mcp_server_sse.py)
  • 🔄 其他...

📄 PR 描述

修复游戏反复退出时一直重启游戏、没有升级为模拟器恢复,且业务任务提前被延后至次日的问题。

用户日志中,游戏多次登录主界面后又退出至 MuMu 桌面,抛出的是 GameNotRunningError。原代码只对卡死/点击过多累计升级次数;游戏一度启动成功又绕过了登录前连续启动失败的兜底。与此同时,任务恢复上限累计每次失败恢复,导致 01:39:26 智能调度在仅进行了游戏重启的情况下,以“连续恢复 5 次”为由延期至 2026-11-04 00:00。

本次修改:

  • 游戏反复退出也使用现有 GameStuckRestart 开关和 GameStuckThreshold 次数阈值升级为模拟器恢复;成功重启游戏不清除该退出计数,普通任务成功或任意一次模拟器重启完成后清除。
  • 同一任务上限只累计该任务故障引发且已完成的模拟器重启。每次重启后保留重试机会;次数用完后,任务再次需要模拟器重启时才延后,避免最后一次重启尚未验证就判定任务失败。
  • 游戏未运行、设备离线和模拟器启停未完成不消耗业务任务额度,也不触发业务任务延期。系统 Restart、等待导航、资源检查继续使用原有恢复流程。
  • 同步简中、繁中、英文、日文说明,明确上限针对模拟器,并把游戏卡死阈值的错误“秒”单位改为“次数”。

影响共享调度器的恢复计数。保留敏感任务停止保护、脚本错误退出规则、启动重试次数、模拟器启停互斥及退避、正常每日重启排期、低推送模式和自定义调度冷却。未修改任务业务流程、游戏识别资源、ADB 恢复设置或任何默认值。

🔗 相关 Issue

无。依据用户提供的日志和设置截图修复。

📸 修改效果截图

仅调整设置名称与帮助文字,没有布局或游戏图像变化;未采集 WebUI 对比截图。

设置名称由“同一任务连续重启上限”改为“同一任务连续重启模拟器上限”;游戏卡死设置说明补充反复退出,并明确阈值单位为次数。延期日志改为“重启模拟器 N 次后仍未成功”。

🛠️ 实现复杂度

  • 简单 (小改动,影响有限)
  • 中等 (需要一些技术考量)
  • 复杂 (涉及多个组件或系统)

📋 实现细节 (可选)

新增独立退出计数,避免只覆盖 GameStuckError 的遗漏。自审另发现定时重启、设备离线恢复完成后可能残留旧的退出次数,已在所有模拟器重启完成的公共入口清零;启停失败或忙碌时保留。补充断言先复现该遗漏,修正后通过。任务故障通过 _restart_emulator_for_task() 在再次请求模拟器恢复前检查额度,只在 _try_restart_emulator() 返回成功后计数;共享环境故障直接保留原有恢复入口,避免把游戏或设备不可用误归为某个任务的问题。

次数与进程内冷却仍只在当前调度器进程中保留;延期排期继续写入配置。既有的次日延期不会自动提前,避免覆盖用户排期。

🧪 测试步骤 (可选)

已完成的离线检查:

  • 自审补丁后重新联合运行恢复、错误通知、真实配置调度主循环、设备恢复、模拟器互斥、战役续接和调度停止测试:173 项通过,含 104 个子测试。
  • 原版对照验证:反复退出恢复、最后一次模拟器重启后的重试、完整模拟器重启额度三个关键场景,修改前基线均复现失败,修改后全部通过。
  • 覆盖反复退出跨成功游戏重启后的模拟器升级、关闭恢复开关、模拟器恢复失败继续尝试、仅重启游戏不占额度、共享环境故障不延期任务、最后一次模拟器重启后的成功重试、按任务保留额度、次数耗尽后的延期及通知、自定义调度和内部辅助步骤。
  • 全仓库后端 Ruff 指定规则通过;四种语言 JSON 格式有效,审计确认只修改三个恢复设置;git diff --check 通过。

尚未执行:真实 MuMu 实例的反复闪退恢复、实际登录与长期挂机、WebUI 截图验证、前端类型检查。日志足以确认恢复路径遗漏,无法仅据此断定闪退的底层原因是显存或模拟器内部故障。

Sourcery 摘要

修复反复退出无法升级为模拟器恢复,以及任务恢复上限提前计数导致错误延期的问题。

错误修复:

  • 升级反复退出时的游戏恢复路径,在达到阈值后重启模拟器,避免仅反复重启游戏。
  • 修正任务恢复上限的计数方式:仅统计由任务故障触发且已完成的模拟器重启,并允许在最后一次重启后重试任务。
  • 避免因游戏未运行、设备离线、游戏级恢复或未完成的模拟器操作,消耗业务任务额度或错误地延期任务。

增强功能:

  • 统一恢复流程中的任务级模拟器重启管理,同时保留系统重启和共享环境故障的独立恢复行为。

文档:

  • 更新恢复机制文档,说明反复退出的升级条件、任务级模拟器重启上限及延期行为。
  • 同步简体中文、繁体中文、英文和日文版本中的设置名称、说明及恢复提示。

测试:

  • 补充并调整恢复计数、模拟器互斥、调度循环和任务恢复场景的测试,覆盖重试、额度、延期及计数清理行为。
Original summary in English

Summary by Sourcery

修复反复退出无法升级为模拟器恢复及任务恢复上限提前计数导致错误延期的问题。

Bug Fixes:

  • 升级反复退出的游戏恢复路径,在达到阈值后重启模拟器,避免仅反复重启游戏。
  • 修正任务恢复上限计数,仅统计任务故障触发且已完成的模拟器重启,并允许最后一次重启后的任务重试。
  • 避免游戏未运行、设备离线、游戏级恢复或未完成的模拟器操作消耗业务任务额度或错误延期任务。

Enhancements:

  • 统一恢复流程中的任务级模拟器重启管理,同时保留系统 Restart 和共享环境故障的独立恢复行为。

Documentation:

  • 更新恢复机制文档,说明反复退出升级条件、任务级模拟器重启上限及延期行为。
  • 同步简体中文、繁体中文、英文和日文的设置名称、说明及恢复提示。

Tests:

  • 补充并调整恢复计数、模拟器互斥、调度循环和任务恢复场景测试,覆盖重试、额度、延期及计数清理行为。

游戏反复退出时按现有开关和阈值升级为模拟器恢复,避免仅重启游戏而无法恢复运行环境。

任务上限只累计已完成的模拟器重启,保留重启后的任务重试;游戏未运行和设备离线不触发业务任务延期。同步四种语言说明、恢复文档与回归测试。

验证:173 项关联离线测试通过,后端 Ruff 静态检查与差异检查通过;未进行真实模拟器验证。
自审发现定时重启和设备离线恢复完成后仍保留旧的游戏退出计数,可能提前再次触发模拟器重启。统一在模拟器重启完成时清零,重启失败或操作忙碌时保留。

补充真实恢复入口的清零与忙碌保留断言,同步恢复文档。173 项关联测试和 104 个子测试通过;未进行真实模拟器验证。
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

⏳ CI 检查进行中,报告将在完成后更新。

@sourcery-ai

sourcery-ai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

审阅者指南

本 PR 修复游戏登录后反复退出无法升级为模拟器恢复,以及任务恢复上限在尚未完成或未验证模拟器重启时被提前消耗的问题:新增独立退出计数并复用既有升级开关和阈值,同时将任务额度改为仅统计该任务故障引发且成功完成的模拟器重启,耗尽后下一次恢复请求才延期任务,并同步文档、多语言文案和全面回归测试。

游戏反复退出与模拟器恢复的时序图

sequenceDiagram
    participant Scheduler
    participant Game
    participant Emulator

    Scheduler->>Game: _run(command)
    Game-->>Scheduler: GameNotRunningError
    Scheduler->>Scheduler: increment consecutive_game_not_running
    alt threshold reached and Error_GameStuckRestart enabled
        Scheduler->>Emulator: _try_restart_emulator()
        Emulator-->>Scheduler: restart completed
        Scheduler->>Scheduler: reset consecutive_game_not_running
    else threshold not reached
        Scheduler->>Scheduler: task_call(Restart)
    end
Loading

每个任务的模拟器重启上限时序图

sequenceDiagram
    participant Scheduler
    participant Task
    participant Emulator

    Scheduler->>Task: _restart_emulator_for_task(task)
    Scheduler->>Scheduler: _record_task_restart(task, False)
    alt limit already reached
        Scheduler->>Task: defer task until next schedule
    else restart still available
        Scheduler->>Emulator: _try_restart_emulator()
        alt emulator restart completed
            Emulator-->>Scheduler: True
            Scheduler->>Scheduler: increment task_restart_record
            Scheduler->>Task: retry task
        else restart incomplete or busy
            Emulator-->>Scheduler: False
            Scheduler->>Task: preserve retry and restart quota
        end
    end
Loading

文件级变更

变更 详情 文件
扩展游戏退出恢复路径,并将其与模拟器重启升级机制关联。
  • 新增独立的反复退出计数,达到既有阈值且开关启用时升级为模拟器重启。
  • 成功重启游戏不清除退出计数;普通任务成功或模拟器重启完成后清零,重启失败或忙碌时保留。
  • 共享环境故障仍走全局恢复,不归因于业务任务。
alas.py
docs/modules/entry/alas.md
tests/test_alas_error_handling.py
tests/test_emulator_restart_mutex.py
tests/test_scheduler_recovery.py
重构任务恢复额度,使其只统计任务故障触发且已完成的模拟器重启。
  • 通过任务专用恢复入口在重启前检查额度,并仅在模拟器重启成功后递增计数。
  • 每次重启后先允许任务重试;再次需要模拟器重启且额度耗尽时才延期任务。
  • 系统 Restart、内部导航/资源检查、游戏重启、设备离线及未完成的模拟器操作不消耗业务额度或触发延期。
  • 保留敏感任务保护、恢复互斥、退避、调度冷却及既有重启流程。
alas.py
docs/modules/entry/alas.md
tests/test_scheduler_live_loop.py
tests/test_scheduler_recovery.py
同步恢复相关设置文案、错误提示和多语言说明。
  • 将设置和文档明确为“模拟器重启”上限,并更新延期日志文本。
  • 补充反复退出参与升级的说明,修正卡死阈值单位为次数。
  • 同步简体中文、繁体中文、英文和日文翻译。
module/config/i18n/en-US.json
module/config/i18n/ja-JP.json
module/config/i18n/zh-CN.json
module/config/i18n/zh-TW.json
docs/modules/entry/alas.md
补充恢复计数、额度边界和调度行为的回归测试。
  • 覆盖反复退出升级、开关关闭、模拟器重启失败重试及计数清零语义。
  • 验证最后一次允许的模拟器重启后仍可重试并成功恢复。
  • 验证业务任务、共享环境故障和内部恢复步骤不会错误延期或消耗额度。
  • 更新原有额度、通知、敏感任务和全局异常测试以匹配新语义。
tests/test_alas_error_handling.py
tests/test_emulator_restart_mutex.py
tests/test_scheduler_live_loop.py
tests/test_scheduler_recovery.py

提示与命令

使用 Sourcery

  • 触发新的审阅: 在拉取请求中评论 @sourcery-ai review。
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 根据审阅评论创建 GitHub issue: 回复审阅评论,请 Sourcery 根据该评论创建 issue。你也可以在审阅评论中回复 @sourcery-ai issue 来创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,随时重新生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中你希望放置摘要的位置写入 @sourcery-ai summary,即可随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,随时重新生成摘要。
  • 生成审阅者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时重新生成审阅者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 驳回所有 Sourcery 审阅: 在拉取请求中评论 @sourcery-ai dismiss,即可驳回所有现有的 Sourcery 审阅。如果你想从头开始进行新的审阅,这尤其有用——别忘了评论 @sourcery-ai review 来触发新的审阅!

自定义使用体验

访问你的控制面板以便:

  • 启用或停用审阅功能,例如 Sourcery 生成的拉取请求摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、删除或编辑自定义审阅说明。
  • 调整其他审阅设置。

获取帮助

Original review guide in English

Reviewer's Guide

本 PR 修复游戏登录后反复退出无法升级为模拟器恢复,以及任务恢复上限在尚未完成或未验证模拟器重启时被提前消耗的问题:新增独立退出计数并复用既有升级开关和阈值,同时将任务额度改为仅统计该任务故障引发且成功完成的模拟器重启,耗尽后下一次恢复请求才延期任务,并同步文档、多语言文案和全面回归测试。

Sequence diagram for repeated game exits and emulator recovery

sequenceDiagram
    participant Scheduler
    participant Game
    participant Emulator

    Scheduler->>Game: _run(command)
    Game-->>Scheduler: GameNotRunningError
    Scheduler->>Scheduler: increment consecutive_game_not_running
    alt threshold reached and Error_GameStuckRestart enabled
        Scheduler->>Emulator: _try_restart_emulator()
        Emulator-->>Scheduler: restart completed
        Scheduler->>Scheduler: reset consecutive_game_not_running
    else threshold not reached
        Scheduler->>Scheduler: task_call(Restart)
    end
Loading

Sequence diagram for per-task emulator restart limits

sequenceDiagram
    participant Scheduler
    participant Task
    participant Emulator

    Scheduler->>Task: _restart_emulator_for_task(task)
    Scheduler->>Scheduler: _record_task_restart(task, False)
    alt limit already reached
        Scheduler->>Task: defer task until next schedule
    else restart still available
        Scheduler->>Emulator: _try_restart_emulator()
        alt emulator restart completed
            Emulator-->>Scheduler: True
            Scheduler->>Scheduler: increment task_restart_record
            Scheduler->>Task: retry task
        else restart incomplete or busy
            Emulator-->>Scheduler: False
            Scheduler->>Task: preserve retry and restart quota
        end
    end
Loading

File-Level Changes

Change Details Files
扩展游戏退出恢复路径,并将其与模拟器重启升级机制关联。
  • 新增独立的反复退出计数,达到既有阈值且开关启用时升级为模拟器重启。
  • 成功重启游戏不清除退出计数;普通任务成功或模拟器重启完成后清零,重启失败或忙碌时保留。
  • 共享环境故障仍走全局恢复,不归因于业务任务。
alas.py
docs/modules/entry/alas.md
tests/test_alas_error_handling.py
tests/test_emulator_restart_mutex.py
tests/test_scheduler_recovery.py
重构任务恢复额度,使其只统计任务故障触发且已完成的模拟器重启。
  • 通过任务专用恢复入口在重启前检查额度,并仅在模拟器重启成功后递增计数。
  • 每次重启后先允许任务重试;再次需要模拟器重启且额度耗尽时才延期任务。
  • 系统 Restart、内部导航/资源检查、游戏重启、设备离线及未完成的模拟器操作不消耗业务额度或触发延期。
  • 保留敏感任务保护、恢复互斥、退避、调度冷却及既有重启流程。
alas.py
docs/modules/entry/alas.md
tests/test_scheduler_live_loop.py
tests/test_scheduler_recovery.py
同步恢复相关设置文案、错误提示和多语言说明。
  • 将设置和文档明确为“模拟器重启”上限,并更新延期日志文本。
  • 补充反复退出参与升级的说明,修正卡死阈值单位为次数。
  • 同步简体中文、繁体中文、英文和日文翻译。
module/config/i18n/en-US.json
module/config/i18n/ja-JP.json
module/config/i18n/zh-CN.json
module/config/i18n/zh-TW.json
docs/modules/entry/alas.md
补充恢复计数、额度边界和调度行为的回归测试。
  • 覆盖反复退出升级、开关关闭、模拟器重启失败重试及计数清零语义。
  • 验证最后一次允许的模拟器重启后仍可重试并成功恢复。
  • 验证业务任务、共享环境故障和内部恢复步骤不会错误延期或消耗额度。
  • 更新原有额度、通知、敏感任务和全局异常测试以匹配新语义。
tests/test_alas_error_handling.py
tests/test_emulator_restart_mutex.py
tests/test_scheduler_live_loop.py
tests/test_scheduler_recovery.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

你好——我已经审查了你的更改,效果很棒!


Sourcery 对开源项目免费——如果你喜欢我们的审查结果,欢迎分享 ✨
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@Beatrice-betty
Beatrice-betty merged commit ae3aabd into wess09:dev Nov 3, 2026
7 of 10 checks passed
@Beatrice-betty
Beatrice-betty deleted the codex/fix-recovery-emulator-limit branch November 3, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant