73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
"""Behavioral pattern randomization for anti-detection.
|
|
|
|
Varies bot behavior to avoid detectable patterns like identical
|
|
farming routes, consistent timing, or perfect execution.
|
|
"""
|
|
|
|
import random
|
|
import logging
|
|
from typing import List, Tuple, Callable, Any
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class RouteRandomizer:
|
|
"""Randomizes farming routes and action sequences."""
|
|
|
|
def __init__(self, variation_factor: float = 0.15):
|
|
self.variation_factor = variation_factor
|
|
|
|
def shuffle_optional_steps(
|
|
self, steps: List[Any], required_indices: List[int] = None,
|
|
) -> List[Any]:
|
|
"""Shuffle non-required steps while keeping required ones in order."""
|
|
required_indices = set(required_indices or [])
|
|
required = [(i, s) for i, s in enumerate(steps) if i in required_indices]
|
|
optional = [s for i, s in enumerate(steps) if i not in required_indices]
|
|
|
|
random.shuffle(optional)
|
|
|
|
result = []
|
|
opt_iter = iter(optional)
|
|
req_iter = iter(required)
|
|
next_req = next(req_iter, None)
|
|
|
|
for i in range(len(steps)):
|
|
if next_req and next_req[0] == i:
|
|
result.append(next_req[1])
|
|
next_req = next(req_iter, None)
|
|
else:
|
|
result.append(next(opt_iter))
|
|
|
|
return result
|
|
|
|
def vary_route(
|
|
self, waypoints: List[Tuple[int, int]],
|
|
) -> List[Tuple[int, int]]:
|
|
"""Add slight variations to a route's waypoints."""
|
|
varied = []
|
|
for x, y in waypoints:
|
|
offset_x = int(x * self.variation_factor * random.uniform(-1, 1))
|
|
offset_y = int(y * self.variation_factor * random.uniform(-1, 1))
|
|
varied.append((x + offset_x, y + offset_y))
|
|
return varied
|
|
|
|
def should_skip_optional(self, skip_chance: float = 0.1) -> bool:
|
|
"""Randomly decide to skip an optional action."""
|
|
return random.random() < skip_chance
|
|
|
|
|
|
class ActionVariator:
|
|
"""Varies how actions are performed."""
|
|
|
|
@staticmethod
|
|
def vary_count(target: int, variance: int = 1) -> int:
|
|
"""Vary a repeat count (e.g., click 2-4 times instead of always 3)."""
|
|
return max(1, target + random.randint(-variance, variance))
|
|
|
|
@staticmethod
|
|
def random_order(actions: List[Callable]) -> List[Callable]:
|
|
"""Randomize the order of independent actions."""
|
|
shuffled = actions.copy()
|
|
random.shuffle(shuffled)
|
|
return shuffled
|