"""Anti-detection timing and break scheduling. Manages play sessions with realistic timing patterns to avoid behavioral detection systems. """ import random import time import logging from dataclasses import dataclass from typing import Optional logger = logging.getLogger(__name__) @dataclass class SessionSchedule: """Defines a play session schedule.""" min_session_hours: float = 1.0 max_session_hours: float = 4.0 min_break_minutes: float = 10.0 max_break_minutes: float = 45.0 max_daily_hours: float = 12.0 class SessionTimer: """Manages bot session timing to mimic human play patterns.""" def __init__(self, schedule: Optional[SessionSchedule] = None): self.schedule = schedule or SessionSchedule() self._session_start = time.time() self._daily_playtime = 0.0 self._day_start = time.time() self._target_duration = self._roll_session_duration() def _roll_session_duration(self) -> float: """Generate random session duration in seconds.""" hours = random.uniform( self.schedule.min_session_hours, self.schedule.max_session_hours, ) return hours * 3600 def session_elapsed(self) -> float: """Seconds elapsed in current session.""" return time.time() - self._session_start def should_stop_session(self) -> bool: """Check if current session should end.""" if self.session_elapsed() >= self._target_duration: return True if self._daily_playtime + self.session_elapsed() >= self.schedule.max_daily_hours * 3600: return True return False def get_break_duration(self) -> float: """Get randomized break duration in seconds.""" return random.uniform( self.schedule.min_break_minutes * 60, self.schedule.max_break_minutes * 60, ) def start_new_session(self) -> None: """Start a new play session after break.""" self._daily_playtime += self.session_elapsed() self._session_start = time.time() self._target_duration = self._roll_session_duration() logger.info(f"New session: {self._target_duration/3600:.1f}h target")