Skip to content

fix(Exploration): 修复特定UP类型找怪提前退出及滑屏边缘检测问题 - #1905

Merged
runhey merged 4 commits into
runhey:devfrom
VanityHuang:fix/exploration-up-search
Oct 13, 2026
Merged

runhey merged 4 commits into
runhey:devfrom
VanityHuang:fix/exploration-up-search

Conversation

@VanityHuang

@VanityHuang VanityHuang commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor
  1. 修复 search_fail_timer 未启动即触发及与 swipe(interval=3) 时序冲突吞掉滑动指令导致误判滑到底退出的问题;
  2. 将单屏找怪观察时间从 3.2s 缩短至 1.0s,并在滑屏后立即调用 is_swipe_unchanged 检测中上部背景(250,140,800,90)像素差,避开顶部跑马灯与右侧浮动鬼火干扰,到底即退;
  3. 退出/切换探索场景时清理 swipe_background_right 点击历史记录,避免多轮翻找累计触发 GameTooManyClickError;
  4. 修复 search_up_fight 在特定 UP 模式下未匹配到挑战图标时向下穿透到 UpType.ALL 的问题。

Sourcery 摘要

修复单人模式和队长模式下的探索怪物搜索与滑动结束检测问题。

错误修复:

  • 通过在场景切换和操作前后重置搜索状态,避免搜索计时器与滑动时序冲突导致探索提前退出。
  • 通过在每次滑动后检查中央上方背景,改进探索结束检测,避免受到无关 UI 元素的干扰。
  • 防止探索循环之间累积点击历史,并确保受限的 UP 搜索不会回退到兜底模式。
  • 将每个屏幕的怪物搜索间隔缩短至一秒。

增强功能:

  • 改进探索场景状态管理:进入新活动时清除搜索计时器、滑动标记和结束检测状态。
Original summary in English

Sourcery 总结

修复单人和队长模式下的探索怪物搜索与滑动结束检测问题。

错误修复:

  • 通过同步搜索计时器与滑动操作,并在场景切换时重置搜索状态,防止探索搜索过早退出。
  • 通过检查滑动后的地图背景是否未发生变化,并要求连续多次检测到未变化结果后再退出,改进探索结束检测。
  • 防止滑动点击历史记录在多个探索周期之间累积,并阻止受限的 UP 搜索回退到默认搜索模式。

改进:

  • 将单人和队长探索模式下的怪物搜索间隔缩短至一秒。
Original summary in English

Sourcery 总结

稳定单人和队长探索中的怪物搜索及滑动结束检测。

Bug 修复:

  • 通过将搜索计时器与滑动操作同步,并在场景切换期间重置搜索状态,防止探索搜索过早退出。
  • 通过在滑动后检查中央上方背景,并要求多次获得未变化的结果后再退出,改进区域结束检测。
  • 防止滑动点击历史记录在探索周期之间累积,并避免受限的 UP 搜索回退到默认模式。

增强功能:

  • 将单人和队长探索模式下的怪物搜索间隔缩短至一秒。
Original summary in English

Sourcery 总结

稳定单人和领队探索中的怪物搜索及右边缘检测。

Bug 修复:

  • 通过将搜索时机与滑动操作同步,并在场景和战斗切换时重置搜索状态,防止探索搜索过早退出。
  • 通过在滑动后比较稳定的地图中央区域,并确认结果未发生变化后再退出,改进右边缘检测。
  • 防止滑动点击历史记录在多个探索周期之间累积,并阻止受限的向上搜索回退到默认搜索模式。

增强功能:

  • 将失败搜索与后续探索滑动之间的间隔缩短至 1.5 秒。
Original summary in English

Summary by Sourcery

Stabilize solo and leader exploration monster searches and right-edge detection.

Bug Fixes:

  • Prevent exploration searches from exiting prematurely by synchronizing search timing with swipes and resetting search state across scene and combat transitions.
  • Improve right-edge detection by comparing a stable central map region after swipes and confirming unchanged results before exiting.
  • Prevent swipe click history from accumulating across exploration cycles and stop restricted UP searches from falling back to the default search mode.

Enhancements:

  • Shorten the interval between failed searches and subsequent exploration swipes to 1.5 seconds.

1. 修复 search_fail_timer 未启动即触发及与 swipe(interval=3) 时序冲突吞掉滑动指令导致误判滑到底退出的问题;
2. 将单屏找怪观察时间从 3.2s 缩短至 1.0s,并在滑屏后立即调用 is_swipe_unchanged 检测中上部背景(250,140,800,90)像素差,避开顶部跑马灯与右侧浮动鬼火干扰,到底即退;
3. 退出/切换探索场景时清理 swipe_background_right 点击历史记录,避免多轮翻找累计触发 GameTooManyClickError;
4. 修复 search_up_fight 在特定 UP 模式下未匹配到挑战图标时向下穿透到 UpType.ALL 的问题。

@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.

嘿——我发现了 3 个问题

面向 AI 代理的提示
请处理此次代码审查中的评论:

## 单独评论

### 评论 1
<location path="tasks/Exploration/solo.py" line_range="136" />
<code_context>
-                    search_fail_timer.reset()
-                    if self._match_end.stable(self.device.image, refresh_after_stable=True):
+                    before_image = self.device.image
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
</code_context>
<issue_to_address>
**长时间搜索会中止探索**

当搜索在离开 `Scene.MAIN` 前执行十次后台滑动时,每次 `self.swipe` 都会将相同的控件添加到 `Device.click_record`;随后,`Device.click_record_check` 会在清理操作运行前抛出 `GameTooManyClickError`,从而中止探索。

在持续搜索期间,应在检查第十个匹配条目之前清除或使已记录的滑动条目过期。

另见 `tasks/Exploration/solo.py:65`、`tasks/Exploration/solo.py:153`、`tasks/Exploration/solo.py:267`。
</issue_to_address>

### 评论 2
<location path="tasks/Exploration/solo.py" line_range="139" />
<code_context>
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
+                    if self.is_swipe_unchanged(before_image, self.device.image):
+                        search_fail_timer.clear()
                         self.quit_explore()
</code_context>
<issue_to_address>
**探索会在到达地图边缘前退出**

当滑动被延迟、忽略或中断,而地图仍有未探索区域时,`is_swipe_unchanged` 会将一次未变化的截图视为已到达边缘的证据,因此 `quit_explore()` 会在地图仍有未探索区域时结束探索。

在调用 `quit_explore()` 前,应等待滑动完成,并确认地图已到达边缘。

另见 `tasks/Exploration/solo.py:269-272`。
</issue_to_address>

### 评论 3
<location path="tasks/Exploration/solo.py" line_range="136" />
<code_context>
-                    search_fail_timer.reset()
-                    if self._match_end.stable(self.device.image, refresh_after_stable=True):
+                    before_image = self.device.image
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
</code_context>
<issue_to_address>
**确认操作会中断探索**

当搜索计时器运行至少一秒后点击确认,而弹窗仍然可见时,确认操作完成后 `search_fail_timer` 仍处于活动状态;下一次 MAIN 场景处理可能会将滑动操作执行到弹窗上,随后 `is_swipe_unchanged` 会调用 `quit_explore()`,结束探索。

点击确认时应清除或重置 `search_fail_timer`,并且不要将被弹窗阻挡的滑动视为地图已到达边缘的证据。

另见 `tasks/Exploration/solo.py:65`。
</issue_to_address>

Sourcery 评估

等待批准。 请先处理 3 个发现的问题。

阻塞性问题:tasks/Exploration/solo.py:136、tasks/Exploration/solo.py:139、tasks/Exploration/solo.py:136


Sourcery 对开源项目免费——如果您喜欢我们的审查,请考虑分享 ✨
Original comment in English

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tasks/Exploration/solo.py" line_range="136" />
<code_context>
-                    search_fail_timer.reset()
-                    if self._match_end.stable(self.device.image, refresh_after_stable=True):
+                    before_image = self.device.image
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
</code_context>
<issue_to_address>
**Long searches abort exploration**

When a search issues ten background swipes before leaving `Scene.MAIN`, each `self.swipe` adds the same control to `Device.click_record`; `Device.click_record_check` then raises `GameTooManyClickError` before cleanup runs, aborting exploration.

Clear or age out recorded swipe entries during continued searching, before the tenth matching entry is checked.

Also at `tasks/Exploration/solo.py:65`, `tasks/Exploration/solo.py:153`, `tasks/Exploration/solo.py:267`.
</issue_to_address>

### Comment 2
<location path="tasks/Exploration/solo.py" line_range="139" />
<code_context>
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
+                    if self.is_swipe_unchanged(before_image, self.device.image):
+                        search_fail_timer.clear()
                         self.quit_explore()
</code_context>
<issue_to_address>
**Exploration exits before map edge**

When a swipe is delayed, ignored or interrupted while unexplored map remains, `is_swipe_unchanged` treats one unchanged screenshot as proof of the edge, so `quit_explore()` ends exploration while unexplored map remains.

Wait for the swipe to finish and confirm the map is at its edge before calling `quit_explore()`.

Also at `tasks/Exploration/solo.py:269-272`.
</issue_to_address>

### Comment 3
<location path="tasks/Exploration/solo.py" line_range="136" />
<code_context>
-                    search_fail_timer.reset()
-                    if self._match_end.stable(self.device.image, refresh_after_stable=True):
+                    before_image = self.device.image
+                    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
+                    sleep(0.3)
+                    self.screenshot()
</code_context>
<issue_to_address>
**Confirmation interrupts exploration**

When a confirmation is clicked after the search timer has run for at least one second and the popup remains visible, `search_fail_timer` remains active after the confirmation; the next MAIN-scene pass can swipe into the popup, and `is_swipe_unchanged` then calls `quit_explore()`, ending exploration.

Clear or reset `search_fail_timer` when clicking a confirmation, and do not treat a popup-blocked swipe as proof that the map is at its edge.

Also at `tasks/Exploration/solo.py:65`.
</issue_to_address>

Sourcery assessment

Approval pending. 3 findings to address first.

Blocking findings: tasks/Exploration/solo.py:136, tasks/Exploration/solo.py:139, tasks/Exploration/solo.py:136


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

Comment thread tasks/Exploration/solo.py Outdated
Comment thread tasks/Exploration/solo.py Outdated
Comment thread tasks/Exploration/solo.py Outdated
…ge check

- Reset search_fail_timer and unchanged_swipe_cnt when clicking confirmation popups in Scene.MAIN
- Re-check screenshot after a delayed swipe, ignore popups/scene changes, and require 2 consecutive unchanged swipes before quitting exploration
- Clear S_SWIPE_BACKGROUND_RIGHT click records when swipes move the map or battles trigger to prevent false GameTooManyClickError during long searches
sourcery-ai[bot]
sourcery-ai Bot previously approved these changes Oct 10, 2026

@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 assessment

Approved.

@runhey

runhey commented Oct 11, 2026

Copy link
Copy Markdown
Owner

我看了这次 diff,run_solo() 和 run_leader() 里“无怪时滑屏并判断是否到边界”的状态机是整段重复的;重置 search_fail_timer、unchanged_swipe_cnt 和 _match_end 的逻辑也重复了很多次。

我在本地做了一个保持现有时序和退出条件的整理:把公共滑屏流程抽到 _search_next_area(),把搜索状态重置抽到 _reset_search_state(),然后两个入口都调用同一套实现。solo.py 净减少 52 行。核心代码如下,供你评估是否合入:

def _reset_search_state(self, search_fail_timer: Timer) -> int:
    search_fail_timer.clear()
    self._match_end.refresh()
    return 0

def _search_next_area(self, search_fail_timer: Timer, unchanged_swipe_cnt: int) -> int:
    if not search_fail_timer.started():
        search_fail_timer.start()
        return unchanged_swipe_cnt
    if not search_fail_timer.reached():
        return unchanged_swipe_cnt

    before_image = self.device.image
    self.swipe(self.S_SWIPE_BACKGROUND_RIGHT)
    sleep(0.3)
    self.screenshot()
    if self.is_swipe_unchanged(before_image, self.device.image):
        sleep(0.3)
        self.screenshot()
    if (self.get_current_scene() != Scene.MAIN
            or self.appear(self.I_UI_CONFIRM)
            or self.appear(self.I_UI_CONFIRM_SAMLL)):
        search_fail_timer.reset()
        return 0

    if self.is_swipe_unchanged(before_image, self.device.image):
        unchanged_swipe_cnt += 1
        if unchanged_swipe_cnt >= 2:
            search_fail_timer.clear()
            self.quit_explore()
            return 0
    else:
        unchanged_swipe_cnt = 0
        self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name)

    search_fail_timer.reset()
    return unchanged_swipe_cnt

两个 MAIN 分支里原本的滑屏代码替换为:

unchanged_swipe_cnt = self._search_next_area(search_fail_timer, unchanged_swipe_cnt)
continue

重置点则替换为 unchanged_swipe_cnt = self._reset_search_state(search_fail_timer)。我没有推送或改动 PR 分支;如果你觉得这个收拢方向合适,可以直接照这个整理,或者告诉我再把完整 patch 发出来。

- 抽取 _reset_search_state 统一重置滑动计时器与刷新结算状态

- 抽取 _search_next_area 统一滑屏找怪与边界停滞检测判定

- 精简 run_solo 和 run_leader,去除重复实现,保持两处逻辑一致
@VanityHuang

Copy link
Copy Markdown
Contributor Author

@runhey 感谢评审与建议!已经整理完成。见 2bc21f5

- 特定UP模式(经验/金币/达摩):启用2次滑屏早退策略(MAX_SWIPE_COUNT = 2),覆盖前3屏无怪即早退重开

- 全部模式(UpType.ALL):不限制滑屏次数,支持滑至最右边缘以打完全部小怪并击杀首领

- 剔除失效的巡航常量与 current_swipe_interval 死代码,清理废弃的 _match_end.refresh()

- 缓存滑屏位移判定,避免单次检测内重复计算图像差分与输出日志

- 成员化 search_fail_timer,消除 17 处冗余参数透传
@sourcery-ai
sourcery-ai Bot dismissed their stale review October 11, 2026 11:59

Sourcery withdrew this approval because the latest commits introduced blocking findings.

@VanityHuang

Copy link
Copy Markdown
Contributor Author

我稍微优化了一下探索滑屏策略:

  • 按 UP 类型自适应滑屏找怪:

特定 UP 模式(经验/金币/达摩):启用 2 次滑屏早退策略(MAX_SWIPE_COUNT = 2),仅检索前 3 屏小怪高密度区,无目标怪即早退重开,大幅降低后半程无效滑屏耗时;
全部模式:不限制滑屏次数,支持滑至最右边缘,保证清空全图小怪并击杀首领。

  • 代码精简:

删了失效的巡航代码及废弃的 _match_end.refresh();
成员化定时器,消除方法间冗余参数透传。

实测运行稳定,效率提高不少,烦请查阅最新提交 69a0fc4 。

@runhey
runhey merged commit 4c68886 into runhey:dev Oct 13, 2026
1 check passed
ZH-CZR added a commit to ZH-CZR/OnmyojiAutoScript that referenced this pull request Oct 14, 2026
- §1/§2 登记批次 25(6ec09b31,runhey/dev PR runhey#1934 手工移植)
- §3.7 新增批次 25 扫描判定表;PR runhey#1905 评估为「需立项」保留,不 ignore
- §4 点2 更正 ignore 计数(实测 25 条);点5 补批次 25 落地说明 + 上游↔本地映射
  (上游 ui_click(timeout=) ↔ 本地 ui_click_until_appear_or_timeout)
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.

2 participants