Spaces:
Running
on
Zero
Running
on
Zero
| from __future__ import annotations | |
| import numpy as np | |
| from dataclasses import dataclass, field | |
| from typing import Optional, Dict, Any, Set, Tuple | |
| from enum import Enum | |
| class CheatType(Enum): | |
| AIMBOT = "aimbot" | |
| WALLHACK = "wallhack" | |
| TRIGGERBOT = "triggerbot" | |
| class TogglePattern(Enum): | |
| ALWAYS = "always" | |
| CLUTCH_ONLY = "clutch_only" | |
| LOSING_ONLY = "losing_only" | |
| RANDOM = "random" | |
| class HumanizationConfig: | |
| """Cheater's attempt to appear legit - but leaves artifacts.""" | |
| reaction_delay_ms: Tuple[float, float] = (0.0, 20.0) | |
| aim_smoothing: Tuple[float, float] = (0.0, 0.2) | |
| random_miss_rate: Tuple[float, float] = (0.0, 0.05) | |
| fov_degrees: Tuple[float, float] = (90.0, 180.0) | |
| noise_amplitude: Tuple[float, float] = (0.0, 0.0) | |
| prefire_suppression: float = 0.0 | |
| check_delay_ms: Tuple[float, float] = (0.0, 0.0) | |
| def sample(self, rng: np.random.Generator) -> Dict[str, float]: | |
| """Sample concrete values from ranges.""" | |
| return { | |
| "reaction_delay_ms": rng.uniform(*self.reaction_delay_ms), | |
| "aim_smoothing": rng.uniform(*self.aim_smoothing), | |
| "random_miss_rate": rng.uniform(*self.random_miss_rate), | |
| "fov_degrees": rng.uniform(*self.fov_degrees), | |
| "noise_amplitude": rng.uniform(*self.noise_amplitude), | |
| "prefire_suppression": self.prefire_suppression, | |
| "check_delay_ms": rng.uniform(*self.check_delay_ms) if self.check_delay_ms[1] > 0 else 0.0, | |
| } | |
| CHEAT_PROFILES: Dict[str, Dict[str, Any]] = { | |
| "blatant_rage": { | |
| "intensity": (0.8, 1.0), | |
| "toggle_pattern": TogglePattern.ALWAYS, | |
| "cheat_types": {CheatType.AIMBOT, CheatType.WALLHACK, CheatType.TRIGGERBOT}, | |
| "humanization": HumanizationConfig( | |
| reaction_delay_ms=(0.0, 20.0), | |
| aim_smoothing=(0.0, 0.2), | |
| random_miss_rate=(0.0, 0.05), | |
| fov_degrees=(90.0, 180.0), | |
| ), | |
| "base_skill_multiplier": (0.3, 0.5), | |
| }, | |
| "obvious": { | |
| "intensity": (0.5, 0.8), | |
| "toggle_pattern": TogglePattern.ALWAYS, | |
| "cheat_types": {CheatType.AIMBOT, CheatType.TRIGGERBOT}, | |
| "humanization": HumanizationConfig( | |
| reaction_delay_ms=(30.0, 80.0), | |
| aim_smoothing=(0.2, 0.5), | |
| random_miss_rate=(0.05, 0.10), | |
| fov_degrees=(30.0, 60.0), | |
| ), | |
| "base_skill_multiplier": (0.4, 0.6), | |
| }, | |
| "closet_moderate": { | |
| "intensity": (0.3, 0.5), | |
| "toggle_pattern": TogglePattern.CLUTCH_ONLY, | |
| "cheat_types": {CheatType.AIMBOT}, | |
| "humanization": HumanizationConfig( | |
| reaction_delay_ms=(80.0, 150.0), | |
| aim_smoothing=(0.5, 0.8), | |
| random_miss_rate=(0.10, 0.18), | |
| fov_degrees=(10.0, 25.0), | |
| ), | |
| "base_skill_multiplier": (0.5, 0.7), | |
| }, | |
| "closet_subtle": { | |
| "intensity": (0.15, 0.35), | |
| "toggle_pattern": TogglePattern.LOSING_ONLY, | |
| "cheat_types": {CheatType.AIMBOT, CheatType.TRIGGERBOT}, | |
| "humanization": HumanizationConfig( | |
| reaction_delay_ms=(150.0, 250.0), | |
| aim_smoothing=(0.8, 0.95), | |
| random_miss_rate=(0.15, 0.25), | |
| fov_degrees=(3.0, 10.0), | |
| noise_amplitude=(0.5, 1.5), | |
| ), | |
| "base_skill_multiplier": (0.6, 0.8), | |
| }, | |
| "wallhack_only": { | |
| "intensity": (0.4, 0.7), | |
| "toggle_pattern": TogglePattern.ALWAYS, | |
| "cheat_types": {CheatType.WALLHACK}, | |
| "humanization": HumanizationConfig( | |
| prefire_suppression=0.7, | |
| check_delay_ms=(500.0, 1500.0), | |
| ), | |
| "base_skill_multiplier": (0.7, 0.9), | |
| }, | |
| } | |
| class CheatConfig: | |
| """Configuration for a specific cheater.""" | |
| profile_name: str | |
| cheat_types: Set[CheatType] | |
| intensity: float | |
| toggle_pattern: TogglePattern | |
| humanization: Dict[str, float] | |
| base_skill_multiplier: float | |
| def from_profile( | |
| cls, | |
| profile_name: str, | |
| seed: Optional[int] = None, | |
| ) -> CheatConfig: | |
| """Create config from predefined profile.""" | |
| if profile_name not in CHEAT_PROFILES: | |
| raise ValueError(f"Unknown profile: {profile_name}. Valid: {list(CHEAT_PROFILES.keys())}") | |
| rng = np.random.default_rng(seed) | |
| profile = CHEAT_PROFILES[profile_name] | |
| intensity = rng.uniform(*profile["intensity"]) | |
| base_skill_mult = rng.uniform(*profile["base_skill_multiplier"]) | |
| humanization = profile["humanization"].sample(rng) | |
| return cls( | |
| profile_name=profile_name, | |
| cheat_types=profile["cheat_types"].copy(), | |
| intensity=intensity, | |
| toggle_pattern=profile["toggle_pattern"], | |
| humanization=humanization, | |
| base_skill_multiplier=base_skill_mult, | |
| ) | |
| class CheatBehavior: | |
| """Runtime cheat behavior with toggle logic.""" | |
| config: CheatConfig | |
| is_active: bool = True | |
| rounds_since_toggle: int = 0 | |
| def from_profile(cls, profile_name: str, seed: Optional[int] = None) -> CheatBehavior: | |
| config = CheatConfig.from_profile(profile_name, seed) | |
| return cls(config=config) | |
| def toggle_pattern(self) -> TogglePattern: | |
| return self.config.toggle_pattern | |
| def should_activate( | |
| self, | |
| is_clutch: bool = False, | |
| is_losing: bool = False, | |
| round_number: int = 0, | |
| rng: Optional[np.random.Generator] = None, | |
| ) -> bool: | |
| """Determine if cheat should be active this round.""" | |
| pattern = self.config.toggle_pattern | |
| if pattern == TogglePattern.ALWAYS: | |
| return True | |
| elif pattern == TogglePattern.CLUTCH_ONLY: | |
| return is_clutch | |
| elif pattern == TogglePattern.LOSING_ONLY: | |
| return is_losing | |
| elif pattern == TogglePattern.RANDOM: | |
| if rng is None: | |
| rng = np.random.default_rng() | |
| return rng.random() < 0.5 | |
| return True | |
| def get_aim_modification(self, target_angle: float, current_angle: float) -> float: | |
| """Calculate aim correction from cheat.""" | |
| if CheatType.AIMBOT not in self.config.cheat_types: | |
| return 0.0 | |
| if not self.is_active: | |
| return 0.0 | |
| angle_diff = target_angle - current_angle | |
| fov_limit = self.config.humanization["fov_degrees"] | |
| if abs(angle_diff) > fov_limit: | |
| return 0.0 | |
| smoothing = self.config.humanization["aim_smoothing"] | |
| intensity = self.config.intensity | |
| # Smoothed correction | |
| correction = angle_diff * (1.0 - smoothing) * intensity | |
| # Add humanization noise | |
| noise_amp = self.config.humanization.get("noise_amplitude", 0.0) | |
| if noise_amp > 0: | |
| correction += np.random.normal(0, noise_amp) | |
| return correction | |
| def get_reaction_delay(self) -> float: | |
| """Get reaction delay in ms.""" | |
| return self.config.humanization["reaction_delay_ms"] | |
| def should_miss_intentionally(self, rng: Optional[np.random.Generator] = None) -> bool: | |
| """Check if should intentionally miss (humanization).""" | |
| if rng is None: | |
| rng = np.random.default_rng() | |
| miss_rate = self.config.humanization["random_miss_rate"] | |
| return rng.random() < miss_rate | |