Skip to content

引入全局状态感知与分层自愈机制,降低脚本对固定流程的依赖 #422

@syokounya

Description

@syokounya

Validations

  • 我已经阅读了 用户文档 并尝试自己解决问题,同时在社群中进行了讨论
  • 我无法找到任何 open issue 提出了相同的建议

问题描述

当前后端的核心战斗、导航与任务执行流程是开环设计:系统严格依赖预设的状态转移图和页面跳转路径执行,但缺乏对"实际游戏画面"的通用兜底感知能力。

一旦现实偏离预设路径(手动误触模拟器、模拟器卡顿掉帧、网络延迟、意外弹窗、动画跳过),脚本无法定位自己的真实状态,也没有标准化的恢复路径,最终只能抛出异常并终止任务。

典型故障场景

  1. 战斗状态机超时即宕机CombatEngine._try_recovery() 仅检查是否到达 end_phase,若用户误触返回导致回到主页面/地图页面,直接判定为识别超时并 SL。
  2. 导航系统无兜底恢复goto_page()identify_current_page 连续 5 次失败后直接抛出 NavigationError,没有"安全回退到主页再重试"的通用逃生通道。
  3. 通用弹窗无统一拦截:网络错误、远程登录、公告浮层等弹窗的处理分散在各个 ops 模块,战斗/导航过程中出现即导致流程中断。
  4. 任务级无断点续传run_for_times() 等循环一旦单次 run() 异常,整个批次终止,不会区分"可恢复错误"与"不可恢复错误"。
  5. 固定超时无法应对卡顿:大量 time.sleep() 和固定 timeout 在模拟器卡顿时频繁触发假阳性超时。

解决方案

建议分阶段引入**"全局状态感知 + 分层自愈"**机制,将系统从"按剧本执行的演员"转变为"能随机应变的玩家"。

Phase 1:战斗引擎增强 — 状态重新同步与全局定位

改造 CombatEngine._try_recovery(),在识别超时后执行三级恢复:

  1. 全局页面定位:调用 identify_current_page() 判断当前是否处于主页面/地图页面/活动地图页面。若是,说明战斗流程被打断,抛出可恢复的 CombatInterruptedError,由上层 Runner 重新进入战斗,而非直接 SL。
  2. 战斗状态重新同步:在所有 CombatPhase 中搜索当前截图,若匹配到某个中间态,将 self._phase 直接修正为该状态并继续执行。
  3. 通用弹窗处理:检测并点击网络重试、远程登录确认、公告关闭等常见弹窗。

Phase 2:导航系统增强 — 安全回退与自适应重规划

改造 goto_page() 的错误处理链路:

  1. 安全回退(Safe Retreat):当页面识别完全失败时,执行 safe_retreat_to_main() —— 连续发送 Back 键并轮询,强制回到主页面这一稳定锚点。
  2. 动作后置验证edge.action(ctx) 执行后,增加短暂的状态验证(如是否离开原页面),未生效时自动重试该步。
  3. 异常截图诊断NavigationError 已保存截图,可进一步增加规则判断(黑屏/转圈/弹窗),自动选择延长等待或关闭浮层。

Phase 3:建立 OverlayManager — 统一弹窗拦截层

新增 OverlayManager 模块,在统一的截图入口(或每次轮询前)自动检测并处理通用浮层:

  • 网络错误 → 点击重试
  • 远程登录 → 点击确认
  • 资源/船坞确认 → 点击确认
  • 公告/新闻 → 点击关闭
    该层优先级高于业务状态机,确保弹窗不会击穿到战斗/导航逻辑。

Phase 4:任务执行框架 — 分级重试与断点续传

新增 TaskExecutor 包装 run_for_times() 等入口:

  1. 错误分级
    • 可恢复:NavigationErrorCombatRecognitionTimeoutNetworkError
    • 不可恢复:ConfigErrorEmulatorConnectionError
  2. 分级重试策略
    • 战斗内识别超时 → 局部恢复(3 次)
    • 局部恢复失败 → 全局回退到主页并重新进入(2 次)
    • 连续失败 → 熔断暂停,通知用户
  3. 断点续传:记录当前进度(如第 3/10 次,节点 B),重试时从断点继续。

Phase 5:模拟器健康监控 — 动态超时

AndroidController 层增加截图帧率统计:

  • 若平均截图耗时 > 500ms,自动延长后续所有 timeoutinterval
  • 将固定 time.sleep() 逐步替换为"状态变化轮询",降低卡顿导致的假阳性。

预期收益:按此路径实施后,可解决当前约 80% 因"误触、卡顿、弹窗"导致的非预期宕机,实现接近无人值守的稳定性。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions