@@ -38,7 +38,14 @@ def run_general_battle(self, config: GeneralBattleConfig = None, buff: BuffClass
3838 self .current_count += 1
3939 logger .info (f"Current count: { self .current_count } " )
4040 # 战前设置
41- self .battle_before (buff , config )
41+ if not self .battle_before (buff , config ):
42+ # battle_before 超时未进入战斗: 常见原因是点击"开始战斗"时被预设面板的关闭动画拦截,
43+ # 点击未生效。此时画面已经稳定(面板动画已结束), 再识别一次:
44+ # 若仍在战斗准备界面则再点击一次开始战斗, 若已进入战斗则直接继续。
45+ if not self .retry_prepare_click ():
46+ logger .warning ('battle_before failed: not in real battle within timeout, '
47+ 'skip this battle and return False' )
48+ return False
4249 # 绿标
4350 if self .is_in_battle (False ):
4451 self .green_mark (config .green_enable , config .green_mark )
@@ -78,6 +85,34 @@ def battle_before(self, buff: BuffClass | list[BuffClass], config: GeneralBattle
7885 sleep (random .uniform (0.4 , 0.8 ))
7986 return False
8087
88+ def retry_prepare_click (self , timeout : float = 3 ) -> bool :
89+ """
90+ battle_before 超时后的补偿: 再次识别画面并尝试开始战斗。
91+ 点击"开始战斗"可能被预设面板关闭动画拦截而未生效, 超时返回后画面已稳定,
92+ 此时若仍在战斗准备界面则再点击一次开始战斗; 若已进入战斗则直接成功。
93+ :return: True: 超时内确认已进入真实战斗
94+ False: 超时仍未进入战斗(界面异常, 应由上层按战斗失败处理)
95+ """
96+ timer = Timer (timeout ).start ()
97+ clicked = False # 只补点一次, 避免在界面切换/点击延迟期间重复触发开始战斗
98+ while not timer .reached ():
99+ self .screenshot ()
100+ if self .is_in_real_battle (False ): # 已经进入战斗
101+ return True
102+ if self .is_in_prepare (False ): # 仍在准备界面
103+ if not clicked :
104+ clicked = True # 只补点一次: 无论本次点击是否成功, 之后仅轮询
105+ if self .appear_then_click (self .I_PREPARE_HIGHLIGHT , interval = 0.8 ):
106+ continue
107+ sleep (0.3 )
108+ continue
109+ # 已补点过一次, 只轮询等待进入战斗, 不再重复点击
110+ sleep (0.3 )
111+ continue
112+ # 未知界面, 等待画面变化
113+ sleep (random .uniform (0.4 , 0.8 ))
114+ return False
115+
81116 def run_general_battle_back (self , config : GeneralBattleConfig = None , exit_four : bool = False ) -> bool :
82117 """
83118 进入挑战然后直接返回
0 commit comments