"""Main D2R bot class — orchestrates the bot loop. Entry point for the Diablo II: Resurrected bot. Manages the main game loop, state transitions, and routine execution. """ import logging import time from typing import Optional from engine.screen.capture import ScreenCapture from engine.input.humanize import Humanizer from engine.state.events import EventBus from engine.safety.timing import SessionTimer from games.d2r.config import D2RConfig from games.d2r.screens.ingame import InGameDetector from games.d2r.screens.menu import MenuDetector logger = logging.getLogger(__name__) class D2RBot: """Main Diablo II: Resurrected bot.""" def __init__(self, config: Optional[D2RConfig] = None): self.config = config or D2RConfig() self.screen = ScreenCapture() self.humanizer = Humanizer() self.events = EventBus() self.session_timer = SessionTimer() self.menu_detector = MenuDetector(self.config) self.ingame_detector = InGameDetector(self.config) self._running = False self._current_routine = None def start(self, routine_name: str = "mephisto") -> None: """Start the bot with a specific farming routine.""" logger.info(f"Starting D2R bot with routine: {routine_name}") self._running = True try: self._main_loop(routine_name) except KeyboardInterrupt: logger.info("Bot stopped by user") except Exception as e: logger.error(f"Bot error: {e}", exc_info=True) finally: self._running = False def stop(self) -> None: """Signal the bot to stop.""" self._running = False def _main_loop(self, routine_name: str) -> None: """Core bot loop.""" while self._running: # Check session timing if self.session_timer.should_stop_session(): break_duration = self.session_timer.get_break_duration() logger.info(f"Session break: {break_duration/60:.0f} min") time.sleep(break_duration) self.session_timer.start_new_session() # Check for breaks break_time = self.humanizer.should_take_break() if break_time: time.sleep(break_time) # Capture screen frame = self.screen.capture_screen() # Detect state and act # TODO: Implement state detection and routine execution # Small delay between loop iterations time.sleep(0.05) def main(): """CLI entry point.""" import argparse parser = argparse.ArgumentParser(description="D2R Bot") parser.add_argument("--routine", default="mephisto", choices=["mephisto", "pindle", "countess"]) parser.add_argument("--resolution", default="1920x1080") args = parser.parse_args() logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s") config = D2RConfig() bot = D2RBot(config) bot.start(args.routine) if __name__ == "__main__": main()