Skip to content

fix bug-道中战斗失败撤退#99

Merged
wess09 merged 1 commit into
wess09:devfrom
moon-dim:master
May 17, 2026
Merged

fix bug-道中战斗失败撤退#99
wess09 merged 1 commit into
wess09:devfrom
moon-dim:master

Conversation

@moon-dim
Copy link
Copy Markdown
Contributor

@moon-dim moon-dim commented May 16, 2026

由于出现bug,将道中战斗失败撤退的代码修改回原pr的代码。
2026-05-16_14-08-17-912057
log.txt

原代码中if self.appear_then_click(FLEET_SWITCH_CONFIRM, offset=(30, 30)):的功能等价于
if self.handle_urgent_commission():
我没测试出我写的代码的bug,于是复原了我的代码,若有发现bug请告知一下。

Summary by Sourcery

恢复并调整战斗中撤退处理逻辑,以解决基于战败触发的撤退行为问题。

Bug 修复:

  • 通过恢复到之前类似“紧急委托”的确认处理方式,并稳定撤退画面检测逻辑,修复战斗失败后错误的撤退流程。

增强:

  • 通过在执行撤退操作前加入短暂的稳定计时器,提高撤退画面检测的稳定性和可靠性。
Original summary in English

Summary by Sourcery

Restore and adjust in-battle withdrawal handling logic to address issues with defeat-based retreat behavior.

Bug Fixes:

  • Fix incorrect withdrawal flow after combat failure by reverting to the previous urgent-commission–equivalent confirmation handling and stabilizing detection of the withdraw screen.

Enhancements:

  • Improve robustness of withdraw screen detection by introducing a short stability timer before proceeding with retreat actions.
Original summary in English

Summary by Sourcery

恢复并调整战斗中撤退处理逻辑,以解决基于战败触发的撤退行为问题。

Bug 修复:

  • 通过恢复到之前类似“紧急委托”的确认处理方式,并稳定撤退画面检测逻辑,修复战斗失败后错误的撤退流程。

增强:

  • 通过在执行撤退操作前加入短暂的稳定计时器,提高撤退画面检测的稳定性和可靠性。
Original summary in English

Summary by Sourcery

Restore and adjust in-battle withdrawal handling logic to address issues with defeat-based retreat behavior.

Bug Fixes:

  • Fix incorrect withdrawal flow after combat failure by reverting to the previous urgent-commission–equivalent confirmation handling and stabilizing detection of the withdraw screen.

Enhancements:

  • Improve robustness of withdraw screen detection by introducing a short stability timer before proceeding with retreat actions.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 16, 2026

审阅者指南(在小型 PR 上折叠)

审阅者指南

回滚并简化了中途战斗撤退逻辑,将其改为更稳定的、基于计时器确认的流程,并移除了未使用的、由紧急委托驱动的撤退处理。

auto_search_combat_status 中撤退处理与紧急委托的时序图

sequenceDiagram
    participant AutoSearch as AutoSearchCombat
    participant Timer as withdraw_stable_timer

    loop auto_search_combat_status loop
        alt _withdraw is True
            AutoSearch->>AutoSearch: appear_then_click FLEET_SWITCH_CONFIRM
            alt FLEET_SWITCH_CONFIRM clicked
                AutoSearch->>AutoSearch: set fleet_alive_multiple False
                AutoSearch->>AutoSearch: set _withdraw False
                AutoSearch-->>AutoSearch: continue
            else not clicked
                AutoSearch->>AutoSearch: appear WITHDRAW
                alt WITHDRAW appears
                    AutoSearch->>Timer: reached
                    alt not reached
                        AutoSearch-->>AutoSearch: continue
                    else reached
                        AutoSearch->>AutoSearch: appear WITHDRAW
                        alt WITHDRAW no longer appears
                            AutoSearch->>Timer: reset
                            AutoSearch-->>AutoSearch: continue
                        else stable WITHDRAW
                            AutoSearch->>AutoSearch: set _withdraw False
                            alt config.Campaign_DefeatWithdraw or not fleet_alive_multiple
                                AutoSearch->>AutoSearch: withdraw
                                AutoSearch-->>AutoSearch: break
                            else need continue battle
                                AutoSearch->>AutoSearch: wait loop (screenshot, click)
                            end
                        end
                    end
                else WITHDRAW not appears
                    AutoSearch->>Timer: reset
                    AutoSearch-->>AutoSearch: continue
                end
            end
        else normal handling
            AutoSearch->>AutoSearch: handle_popup_confirm
            AutoSearch->>AutoSearch: handle_urgent_commission
            AutoSearch->>AutoSearch: handle_story_skip
        end
    end
Loading

文件级变更

变更 详情 文件
使用稳定性计时器而不是紧急委托标志,恢复原有的撤退确认流程。
  • 用初始化为 2 秒的 withdraw_stable_timer 替换未使用的 get_urgent_commission 布尔值。
  • 在点击 FLEET_SWITCH_CONFIRM 时,立即标记舰队为非存活状态,清除撤退标志,并继续循环。
  • 为 WITHDRAW 对话框引入基于 withdraw_stable_timer 的稳定性检查:要求 WITHDRAW 持续存在达到计时器时长后再继续处理;当 WITHDRAW 不存在时重置计时器。
  • 简化撤退决策分支,使其仅依赖 Campaign_DefeatWithdraw 和 fleet_alive_multiple,移除基于紧急委托的额外路径。
module/combat/auto_search_combat.py
移除紧急委托处理与撤退状态之间的耦合。
  • 在 handle_urgent_commission 返回 true 时不再设置 get_urgent_commission,并删除所有依赖该标志的逻辑。
  • 保留 handle_urgent_commission(),仅作为主循环中的一个独立弹窗处理函数。
module/combat/auto_search_combat.py

提示与命令

与 Sourcery 交互

  • 触发新审阅: 在 pull request 上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 在审阅评论下回复,要求 Sourcery 从该评论创建 issue。你也可以在审阅评论下回复 @sourcery-ai issue 来从中创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在你想要的位置随时生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 一次性解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 一次性忽略所有 Sourcery 审阅: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审阅。特别适合想重新开始一次全新审阅的情况——别忘了再评论 @sourcery-ai review 以触发新的审阅!

自定义你的体验

访问你的控制面板以:

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

获取帮助

Original review guide in English
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Reverts and simplifies the mid-route combat withdrawal logic to a more stable, timer-based confirmation flow and removes unused urgent-commission-driven withdrawal handling.

Sequence diagram for withdrawal handling and urgent commission in auto_search_combat_status

sequenceDiagram
    participant AutoSearch as AutoSearchCombat
    participant Timer as withdraw_stable_timer

    loop auto_search_combat_status loop
        alt _withdraw is True
            AutoSearch->>AutoSearch: appear_then_click FLEET_SWITCH_CONFIRM
            alt FLEET_SWITCH_CONFIRM clicked
                AutoSearch->>AutoSearch: set fleet_alive_multiple False
                AutoSearch->>AutoSearch: set _withdraw False
                AutoSearch-->>AutoSearch: continue
            else not clicked
                AutoSearch->>AutoSearch: appear WITHDRAW
                alt WITHDRAW appears
                    AutoSearch->>Timer: reached
                    alt not reached
                        AutoSearch-->>AutoSearch: continue
                    else reached
                        AutoSearch->>AutoSearch: appear WITHDRAW
                        alt WITHDRAW no longer appears
                            AutoSearch->>Timer: reset
                            AutoSearch-->>AutoSearch: continue
                        else stable WITHDRAW
                            AutoSearch->>AutoSearch: set _withdraw False
                            alt config.Campaign_DefeatWithdraw or not fleet_alive_multiple
                                AutoSearch->>AutoSearch: withdraw
                                AutoSearch-->>AutoSearch: break
                            else need continue battle
                                AutoSearch->>AutoSearch: wait loop (screenshot, click)
                            end
                        end
                    end
                else WITHDRAW not appears
                    AutoSearch->>Timer: reset
                    AutoSearch-->>AutoSearch: continue
                end
            end
        else normal handling
            AutoSearch->>AutoSearch: handle_popup_confirm
            AutoSearch->>AutoSearch: handle_urgent_commission
            AutoSearch->>AutoSearch: handle_story_skip
        end
    end
Loading

File-Level Changes

Change Details Files
Restore original withdrawal confirmation flow using a stability timer instead of urgent-commission flags.
  • Replace the unused get_urgent_commission boolean with a withdraw_stable_timer initialized to 2 seconds.
  • On FLEET_SWITCH_CONFIRM click, immediately mark fleet as not alive, clear the withdraw flag, and continue the loop.
  • Introduce a stability check for the WITHDRAW dialog using withdraw_stable_timer: require WITHDRAW to persist for the timer duration before proceeding, and reset the timer when WITHDRAW is not present.
  • Simplify the withdrawal decision branch to only depend on Campaign_DefeatWithdraw and fleet_alive_multiple, removing the extra urgent-commission-based path.
module/combat/auto_search_combat.py
Remove coupling between urgent commission handling and withdrawal state.
  • Stop setting get_urgent_commission when handle_urgent_commission returns true, and drop all logic that depended on that flag.
  • Retain handle_urgent_commission() purely as an independent popup handler in the main loop.
module/combat/auto_search_combat.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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题

给 AI 代理的提示
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="module/combat/auto_search_combat.py" line_range="336-337" />
<code_context>
-                    continue
-
-                logger.info(f'fleet_alive_multiple: {self.fleet_alive_multiple}')
+            if self._withdraw and self.appear(WITHDRAW, offset=(30, 30)):
                 self._withdraw = False
                 if self.config.Campaign_DefeatWithdraw or not self.fleet_alive_multiple:
                     self.withdraw()
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 WITHDRAW 未出现时的行为发生了变化,可能会在继续执行剩余循环的同时让 `_withdraw` 保持为 True。

在旧的逻辑下,一旦 `self._withdraw` 被设置为 True,循环就会一直 `continue`,直到撤退 UI 达到已知状态(处理完 `FLEET_SWITCH_CONFIRM`,或 `WITHDRAW` 未能出现)。在新的条件下,如果 `self._withdraw` 为 True 但 `self.appear(WITHDRAW, …)` 为 False,执行就会向下继续,`auto_search_combat_status` 剩余的部分会在 `_withdraw` 仍为 True 的情况下运行。这改变了控制流,并可能在其他分支执行时让系统处于待撤退的悬而未决状态。如果你想保持之前的行为,大概率需要在 `_withdraw` 为 True 但 `WITHDRAW` 不可见时,保留一个提前的 `continue`(或等价的显式处理)。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据反馈改进给你的代码评审。
Original comment in English

Hey - I've found 1 issue

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

## Individual Comments

### Comment 1
<location path="module/combat/auto_search_combat.py" line_range="336-337" />
<code_context>
-                    continue
-
-                logger.info(f'fleet_alive_multiple: {self.fleet_alive_multiple}')
+            if self._withdraw and self.appear(WITHDRAW, offset=(30, 30)):
                 self._withdraw = False
                 if self.config.Campaign_DefeatWithdraw or not self.fleet_alive_multiple:
                     self.withdraw()
</code_context>
<issue_to_address>
**issue (bug_risk):** Behavior when WITHDRAW does not appear has changed and may leave `_withdraw` True while continuing the rest of the loop.

Under the old logic, once `self._withdraw` was set, the loop always `continue`d until the withdraw UI reached a known state (`FLEET_SWITCH_CONFIRM` handled, or `WITHDRAW` failed to appear). With the new condition, if `self._withdraw` is True but `self.appear(WITHDRAW, …)` is False, execution now falls through and the rest of `auto_search_combat_status` runs with `_withdraw` still True. This changes the control flow and can leave the system in a pending withdraw state while other branches execute. If you want to match the previous behavior, you likely need to keep an early `continue` (or equivalent explicit handling) when `_withdraw` is True but `WITHDRAW` is not visible.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread module/combat/auto_search_combat.py Outdated
Comment on lines 336 to 337
if self._withdraw and self.appear(WITHDRAW, offset=(30, 30)):
self._withdraw = False
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): 当 WITHDRAW 未出现时的行为发生了变化,可能会在继续执行剩余循环的同时让 _withdraw 保持为 True。

在旧的逻辑下,一旦 self._withdraw 被设置为 True,循环就会一直 continue,直到撤退 UI 达到已知状态(处理完 FLEET_SWITCH_CONFIRM,或 WITHDRAW 未能出现)。在新的条件下,如果 self._withdraw 为 True 但 self.appear(WITHDRAW, …) 为 False,执行就会向下继续,auto_search_combat_status 剩余的部分会在 _withdraw 仍为 True 的情况下运行。这改变了控制流,并可能在其他分支执行时让系统处于待撤退的悬而未决状态。如果你想保持之前的行为,大概率需要在 _withdraw 为 True 但 WITHDRAW 不可见时,保留一个提前的 continue(或等价的显式处理)。

Original comment in English

issue (bug_risk): Behavior when WITHDRAW does not appear has changed and may leave _withdraw True while continuing the rest of the loop.

Under the old logic, once self._withdraw was set, the loop always continued until the withdraw UI reached a known state (FLEET_SWITCH_CONFIRM handled, or WITHDRAW failed to appear). With the new condition, if self._withdraw is True but self.appear(WITHDRAW, …) is False, execution now falls through and the rest of auto_search_combat_status runs with _withdraw still True. This changes the control flow and can leave the system in a pending withdraw state while other branches execute. If you want to match the previous behavior, you likely need to keep an early continue (or equivalent explicit handling) when _withdraw is True but WITHDRAW is not visible.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request simplifies the withdrawal logic in the combat module and introduces a minor formatting change. The review feedback identifies a potential logic bug where resetting the withdrawal flag too early could cause the script to skip necessary actions if interrupted by other events, such as urgent commissions. Additionally, a PEP 8 style violation was noted due to a missing space after a comma in a function call.

Comment thread module/combat/auto_search_combat.py Outdated
Comment on lines 336 to 337
if self._withdraw and self.appear(WITHDRAW, offset=(30, 30)):
self._withdraw = False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

这里的逻辑修改可能会导致在战斗失败后的撤退操作被跳过。在第337行直接将 self._withdraw 设为 False,如果此时 get_urgent_commissionTrue(例如在之前的循环中处理了紧急委托),代码会进入第341行的 elif 分支并执行 continue。由于 _withdraw 标志已被清除,后续的循环将无法再次进入此撤退逻辑块,导致脚本卡在显示“撤退”按钮的地图界面,无法继续执行。建议将 self._withdraw = False 的赋值移动到实际执行撤退操作(如调用 self.withdraw() 或进入切换舰队循环)的分支内部,以确保撤退逻辑被正确执行。

Comment thread module/combat/auto_search_combat.py Outdated
if self.appear_then_click(FLEET_WITHDRAW, offset=(30, 30)):
break
if self.appear_then_click(SWITCH_OVER, interval=2):
if self.appear_then_click(SWITCH_OVER,interval=2):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

逗号后缺少空格,不符合 PEP 8 代码风格规范,建议保持良好的代码格式以提高可读性。

Suggested change
if self.appear_then_click(SWITCH_OVER,interval=2):
if self.appear_then_click(SWITCH_OVER, interval=2):

@wess09
Copy link
Copy Markdown
Owner

wess09 commented May 16, 2026

会出现卡在切换到第二舰队的弹窗
不明白你是怎么测试的?

@wess09
Copy link
Copy Markdown
Owner

wess09 commented May 16, 2026

你的原始代码会卡在这里
QQ_1778941728593

@moon-dim
Copy link
Copy Markdown
Contributor Author

刚刚试了一下,确实会卡住,我之前处理这个弹窗利用的这段代码

if self.handle_urgent_commission():
    get_urgent_commission = True

如果这段代码不行的话,换成你新加的也可以,但是需要get_urgent_commission = True,用于判断已经弹过窗导致舰队撤退了,否则

elif get_urgent_commission:
    self.fleet_alive_multiple = False
    continue
else:
    while True:

此段代码的elif不生效,会触发while死循环。

@wess09
Copy link
Copy Markdown
Owner

wess09 commented May 16, 2026 via email

@wess09
Copy link
Copy Markdown
Owner

wess09 commented May 16, 2026

刚刚试了一下,确实会卡住,我之前处理这个弹窗利用的这段代码

if self.handle_urgent_commission():
    get_urgent_commission = True

如果这段代码不行的话,换成你新加的也可以,但是需要get_urgent_commission = True,用于判断已经弹过窗导致舰队撤退了,否则

elif get_urgent_commission:
    self.fleet_alive_multiple = False
    continue
else:
    while True:

此段代码的elif不生效,会触发while死循环。

建议你来做修复 毕竟你的需求你更清楚些

@moon-dim
Copy link
Copy Markdown
Contributor Author

刚刚试了一下,确实会卡住,我之前处理这个弹窗利用的这段代码

if self.handle_urgent_commission():
    get_urgent_commission = True

如果这段代码不行的话,换成你新加的也可以,但是需要get_urgent_commission = True,用于判断已经弹过窗导致舰队撤退了,否则

elif get_urgent_commission:
    self.fleet_alive_multiple = False
    continue
else:
    while True:

此段代码的elif不生效,会触发while死循环。

建议你来做修复 毕竟你的需求你更清楚些

我正在试,不过我现在用你的代码也识别不到弹窗了,并且在有弹窗的情况下还会识别到红色的撤退TAT

@moon-dim
Copy link
Copy Markdown
Contributor Author

刚刚试了一下,确实会卡住,我之前处理这个弹窗利用的这段代码

if self.handle_urgent_commission():
    get_urgent_commission = True

如果这段代码不行的话,换成你新加的也可以,但是需要get_urgent_commission = True,用于判断已经弹过窗导致舰队撤退了,否则

elif get_urgent_commission:
    self.fleet_alive_multiple = False
    continue
else:
    while True:

此段代码的elif不生效,会触发while死循环。

建议你来做修复 毕竟你的需求你更清楚些

我来改吧,改好了再给提交给你

@wess09 wess09 added the 需要修改 / Request changes Changes required in PR label May 16, 2026
@wess09 wess09 marked this pull request as draft May 16, 2026 15:50
@moon-dim
Copy link
Copy Markdown
Contributor Author

现在应该可以了,弹窗会比红色撤退按钮后出现,所以会有一刻检测到红色撤退按钮,导致判断成另一种不会不会出现弹窗的情况。
我新增了计时器,需要红色撤退按钮出现2s以上才算判断成功,期间若出现弹窗则点击确认。

@wess09 wess09 marked this pull request as ready for review May 17, 2026 02:00
@wess09 wess09 changed the base branch from master to dev May 17, 2026 02:01
@wess09 wess09 removed the 需要修改 / Request changes Changes required in PR label May 17, 2026
@wess09 wess09 merged commit 71eaa66 into wess09:dev May 17, 2026
3 of 4 checks passed
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 2 个问题

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

## Individual Comments

### Comment 1
<location path="module/combat/auto_search_combat.py" line_range="324" />
<code_context>
         self.device.click_record_clear()
         exp_info = False  # This is for the white screen bug in game
-        get_urgent_commission = False
+        withdraw_stable_timer = Timer(2)

         for _ in self.loop():
</code_context>
<issue_to_address>
**issue (bug_risk):** 计时器在真正需要之前就被启动了,这会破坏预期的 2 秒稳定性检查。

由于 `withdraw_stable_timer` 是在 `auto_search_combat_status` 开头创建的,当 `self._withdraw` 变为 `True` 且 WITHDRAW 界面出现时,它可能已经过期。这样 `withdraw_stable_timer.reached()` 会在第一次检测到 WITHDRAW 时就返回 `True`,从而跳过预期的 2 秒稳定窗口。相反,应在首次进入撤退流程时(例如 `_withdraw` 变为 `True` 时,或第一次检测到 WITHDRAW 时)创建或重置计时器,使其衡量的是 WITHDRAW 界面保持稳定的 2 秒时间,而不是整个函数执行时间。
</issue_to_address>

### Comment 2
<location path="module/combat/auto_search_combat.py" line_range="342-345" />
<code_context>
+                    self._withdraw = False
                     continue
+                
+                if self.appear(WITHDRAW, offset=(30, 30)):
+                    if not withdraw_stable_timer.reached():
+                        continue
                 if not self.appear(WITHDRAW, offset=(30, 30)):
+                    withdraw_stable_timer.reset()
                     continue
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 在每次循环迭代中检查两次 WITHDRAW,可能会引入不稳定性和冗余工作。

`self.appear(WITHDRAW, offset=(30, 30))` 在同一个分支中被调用了两次:一次在计时器检查之前,一次在重置之前。这样会造成多余的工作,并引入 TOCTOU 风险,因为第二次调用可能与第一次不一致(例如由于瞬时画面变化),从而导致意外的计时器重置。可以考虑只调用一次 `appear`,将结果存储下来,并用这一份结果同时驱动 `reached()` 检查以及重置/continue 逻辑:

```python
visible = self.appear(WITHDRAW, offset=(30, 30))
if visible:
    if not withdraw_stable_timer.reached():
        continue
else:
    withdraw_stable_timer.reset()
    continue
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've found 2 issues

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

## Individual Comments

### Comment 1
<location path="module/combat/auto_search_combat.py" line_range="324" />
<code_context>
         self.device.click_record_clear()
         exp_info = False  # This is for the white screen bug in game
-        get_urgent_commission = False
+        withdraw_stable_timer = Timer(2)

         for _ in self.loop():
</code_context>
<issue_to_address>
**issue (bug_risk):** Timer is started long before it is actually needed, which can defeat the intended 2-second stability check.

Because `withdraw_stable_timer` is created at the start of `auto_search_combat_status`, it may have already expired by the time `self._withdraw` is `True` and the WITHDRAW screen appears. Then `withdraw_stable_timer.reached()` will return `True` on the first WITHDRAW detection, skipping the intended 2-second stability window. Instead, create or reset the timer when you first enter the withdraw flow (e.g. when `_withdraw` becomes `True` or on the first WITHDRAW detection) so it measures 2 seconds of a stable WITHDRAW screen, not total function time.
</issue_to_address>

### Comment 2
<location path="module/combat/auto_search_combat.py" line_range="342-345" />
<code_context>
+                    self._withdraw = False
                     continue
+                
+                if self.appear(WITHDRAW, offset=(30, 30)):
+                    if not withdraw_stable_timer.reached():
+                        continue
                 if not self.appear(WITHDRAW, offset=(30, 30)):
+                    withdraw_stable_timer.reset()
                     continue
</code_context>
<issue_to_address>
**suggestion (bug_risk):** WITHDRAW is checked twice per loop iteration, which can introduce instability and redundant work.

`self.appear(WITHDRAW, offset=(30, 30))` is invoked twice in the same branch: once before the timer check and once before the reset. This does redundant work and introduces a TOCTOU risk where the second call may disagree with the first (e.g., due to a transient frame), causing an unintended timer reset. Consider calling `appear` once, storing the result, and using that single value for both the `reached()` check and the reset/continue logic:

```python
visible = self.appear(WITHDRAW, offset=(30, 30))
if visible:
    if not withdraw_stable_timer.reached():
        continue
else:
    withdraw_stable_timer.reset()
    continue
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

self.device.click_record_clear()
exp_info = False # This is for the white screen bug in game
get_urgent_commission = False
withdraw_stable_timer = Timer(2)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): 计时器在真正需要之前就被启动了,这会破坏预期的 2 秒稳定性检查。

由于 withdraw_stable_timer 是在 auto_search_combat_status 开头创建的,当 self._withdraw 变为 True 且 WITHDRAW 界面出现时,它可能已经过期。这样 withdraw_stable_timer.reached() 会在第一次检测到 WITHDRAW 时就返回 True,从而跳过预期的 2 秒稳定窗口。相反,应在首次进入撤退流程时(例如 _withdraw 变为 True 时,或第一次检测到 WITHDRAW 时)创建或重置计时器,使其衡量的是 WITHDRAW 界面保持稳定的 2 秒时间,而不是整个函数执行时间。

Original comment in English

issue (bug_risk): Timer is started long before it is actually needed, which can defeat the intended 2-second stability check.

Because withdraw_stable_timer is created at the start of auto_search_combat_status, it may have already expired by the time self._withdraw is True and the WITHDRAW screen appears. Then withdraw_stable_timer.reached() will return True on the first WITHDRAW detection, skipping the intended 2-second stability window. Instead, create or reset the timer when you first enter the withdraw flow (e.g. when _withdraw becomes True or on the first WITHDRAW detection) so it measures 2 seconds of a stable WITHDRAW screen, not total function time.

Comment on lines +342 to 345
if self.appear(WITHDRAW, offset=(30, 30)):
if not withdraw_stable_timer.reached():
continue
if not self.appear(WITHDRAW, offset=(30, 30)):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (bug_risk): 在每次循环迭代中检查两次 WITHDRAW,可能会引入不稳定性和冗余工作。

self.appear(WITHDRAW, offset=(30, 30)) 在同一个分支中被调用了两次:一次在计时器检查之前,一次在重置之前。这样会造成多余的工作,并引入 TOCTOU 风险,因为第二次调用可能与第一次不一致(例如由于瞬时画面变化),从而导致意外的计时器重置。可以考虑只调用一次 appear,将结果存储下来,并用这一份结果同时驱动 reached() 检查以及重置/continue 逻辑:

visible = self.appear(WITHDRAW, offset=(30, 30))
if visible:
    if not withdraw_stable_timer.reached():
        continue
else:
    withdraw_stable_timer.reset()
    continue
Original comment in English

suggestion (bug_risk): WITHDRAW is checked twice per loop iteration, which can introduce instability and redundant work.

self.appear(WITHDRAW, offset=(30, 30)) is invoked twice in the same branch: once before the timer check and once before the reset. This does redundant work and introduces a TOCTOU risk where the second call may disagree with the first (e.g., due to a transient frame), causing an unintended timer reset. Consider calling appear once, storing the result, and using that single value for both the reached() check and the reset/continue logic:

visible = self.appear(WITHDRAW, offset=(30, 30))
if visible:
    if not withdraw_stable_timer.reached():
        continue
else:
    withdraw_stable_timer.reset()
    continue

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