diff --git a/bot_core.py b/bot_core.py index c8dd782..d6828bc 100644 --- a/bot_core.py +++ b/bot_core.py @@ -71,6 +71,7 @@ class DirtyLeagueBot: self.running = False self.state = GameState.UNKNOWN + self._unknown_state_count = 0 self.wm = WindowManager( window_title=self.target_conf.get("title", "DirtyLeague"), @@ -231,6 +232,9 @@ class DirtyLeagueBot: user32.mouse_event(0x0002, 0, 0, 0, 0) # MOUSEEVENTF_LEFTDOWN time.sleep(0.08) user32.mouse_event(0x0004, 0, 0, 0, 0) # MOUSEEVENTF_LEFTUP + # Briefly park cursor in neutral corner to prevent buttons staying in hover/glow state + park_x, park_y = self.wm.client_to_screen(50, 50) + user32.SetCursorPos(park_x, park_y) time.sleep(self.action_delay) def click_client_pos_fast(self, x: int, y: int): @@ -364,7 +368,7 @@ class DirtyLeagueBot: Uses relative ROI for the top-right corner across all resolutions. """ for tpl_name in ["btn_close", "btn_close_offer"]: - pos = self.find_template_in_rel_roi(frame, tpl_name, self.REL_ROI_OFFER_CLOSE, threshold=0.65) + pos = self.find_template_in_rel_roi(frame, tpl_name, self.REL_ROI_OFFER_CLOSE, threshold=0.55) if pos: logging.info(f"[OFFER POPUP] Detected close button '{tpl_name}' at client {pos}. Dismissing...") self.click_client_pos(pos[0], pos[1]) @@ -614,8 +618,19 @@ class DirtyLeagueBot: self.handle_defeat(frame) elif self.state == GameState.NO_FREE_SLOTS_SCREEN: self.handle_no_free_slots(frame) - else: + if self.state == GameState.UNKNOWN: + self._unknown_state_count += 1 + if self._unknown_state_count % 15 == 0: + logging.warning( + f"[STALL WARNING] State has been UNKNOWN for {self._unknown_state_count * self.poll_interval:.1f}s. " + f"Attempting cursor unpark and recovery..." + ) + park_x, park_y = self.wm.client_to_screen(50, 50) + from window_utils import user32 + user32.SetCursorPos(park_x, park_y) logging.debug("State: UNKNOWN (waiting or transition in progress)") + else: + self._unknown_state_count = 0 def start(self, max_duration_sec: Optional[int] = None, max_cycles: Optional[int] = None): """Starts main bot loop with optional duration and battle cycle limits."""