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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions