iso-bot/engine/safety/timing.py

68 lines
2.2 KiB
Python

"""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")