Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
344 changes: 344 additions & 0 deletions advanced_aiming.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
"""
็ฒพ็ฎ€้ซ˜็บง็ž„ๅ‡†็ณป็ปŸ
ไฟ็•™ๆ ธๅฟƒๅŠŸ่ƒฝ๏ผš็Šถๆ€ๆœบ้”ๅฎšใ€ไบบ็ฑป่กŒไธบๆจกๆ‹Ÿใ€ๆ™บ่ƒฝ็›ฎๆ ‡้€‰ๆ‹ฉ
"""
import time
import math
import random
from collections import deque
from typing import Optional, Tuple, List, Dict
from enum import Enum
from dataclasses import dataclass

class LockState(Enum):
SEARCHING = "searching"
ACQUIRING = "acquiring"
LOCKED = "locked"
TRACKING = "tracking"
LOST = "lost"

@dataclass
class TargetInfo:
x: float
y: float
width: float
height: float
confidence: float
velocity_x: float = 0.0
velocity_y: float = 0.0
last_seen: float = 0.0

class AdvancedAimingSystem:
def __init__(self):
self.lock_state = LockState.SEARCHING
self.current_target: Optional[TargetInfo] = None
self.state_start_time = time.time()
self.lock_start_time = 0.0

# ๅކๅฒ่ฎฐๅฝ•
self.target_history = deque(maxlen=10)
self.move_history = deque(maxlen=5)

# ๅนณๆป‘็Šถๆ€
self.smoothed_x = 0.0
self.smoothed_y = 0.0

# ๆ€ง่ƒฝ็ปŸ่ฎก
self.stats = {
'targets_locked': 0,
'target_switches': 0,
'reaction_times': []
}

def update(self, targets: List[Dict], screen_center: Tuple[int, int],
config) -> Optional[Tuple[float, float]]:
"""ไธปๆ›ดๆ–ฐๅ‡ฝๆ•ฐ"""
current_time = time.time()

# ็Šถๆ€ๆœบๅค„็†
old_state = self.lock_state
movement = None
if self.lock_state == LockState.SEARCHING:
movement = self._handle_searching(targets, screen_center, config, current_time)
elif self.lock_state == LockState.ACQUIRING:
movement = self._handle_acquiring(targets, screen_center, config, current_time)
elif self.lock_state == LockState.LOCKED:
movement = self._handle_locked(targets, screen_center, config, current_time)
elif self.lock_state == LockState.TRACKING:
movement = self._handle_tracking(targets, screen_center, config, current_time)
elif self.lock_state == LockState.LOST:
movement = self._handle_lost(current_time)

# ่ฐƒ่ฏ•ไฟกๆฏ
if getattr(config, 'cpsDisplay', False):
if old_state != self.lock_state:
print(f"็Šถๆ€่ฝฌๆข: {old_state.value} -> {self.lock_state.value}")
if movement:
print(f"็Šถๆ€ {self.lock_state.value}: ็งปๅŠจ {movement}")

return movement

def _handle_searching(self, targets: List[Dict], screen_center: Tuple[int, int],
config, current_time: float) -> Optional[Tuple[float, float]]:
"""ๆœ็ดข็Šถๆ€"""
if not targets:
return None

# ้€‰ๆ‹ฉๆœ€ไฝณ็›ฎๆ ‡๏ผˆ่ท็ฆปไผ˜ๅ…ˆ๏ผ‰
best_target = min(targets, key=lambda t: math.sqrt(
(t['current_mid_x'] - screen_center[0])**2 +
(t['current_mid_y'] - screen_center[1])**2
))

# ๅผ€ๅง‹่Žทๅ–็›ฎๆ ‡
self.current_target = TargetInfo(
x=best_target['current_mid_x'],
y=best_target['current_mid_y'],
width=best_target['width'],
height=best_target['height'],
confidence=best_target['confidence'],
velocity_x=0.0, # ๆ˜พๅผๅˆๅง‹ๅŒ–้€Ÿๅบฆ
velocity_y=0.0,
last_seen=current_time
)

self.lock_state = LockState.ACQUIRING
self.state_start_time = current_time

# ๆจกๆ‹Ÿไบบ็ฑปๅๅบ”ๅปถ่ฟŸ
reaction_delay = getattr(config, 'humanReactionTime', 0.15)
self.lock_acquisition_time = current_time + reaction_delay

return None

def _handle_acquiring(self, targets: List[Dict], screen_center: Tuple[int, int],
config, current_time: float) -> Optional[Tuple[float, float]]:
"""่Žทๅ–้”ๅฎš็Šถๆ€"""
# ๅๅบ”ๅปถ่ฟŸๆฃ€ๆŸฅ
if current_time < self.lock_acquisition_time:
return None

# ๆŸฅๆ‰พๅฝ“ๅ‰็›ฎๆ ‡
current_target = self._find_target(targets, max_distance=50)
if not current_target:
self._transition_to_lost()
return None

# ๆ›ดๆ–ฐ็›ฎๆ ‡ไฟกๆฏ
self._update_target(current_target, current_time)

# ่ฎก็ฎ—่ท็ฆป
distance = math.sqrt(
(self.current_target.x - screen_center[0])**2 +
(self.current_target.y - screen_center[1])**2
)

# ่ท็ฆป่ถณๅคŸ่ฟ‘ๅˆ™้”ๅฎš (ๅขžๅคง้”ๅฎš่ท็ฆป้˜ˆๅ€ผ)
if distance < 50: # ไปŽ20ๅขžๅŠ ๅˆฐ50ๅƒ็ด 
self.lock_state = LockState.LOCKED
self.lock_start_time = current_time
self.stats['targets_locked'] += 1

# ่ฎฐๅฝ•ๅๅบ”ๆ—ถ้—ด
reaction_time = current_time - self.state_start_time
self.stats['reaction_times'].append(reaction_time)

# ่ฎก็ฎ—็ž„ๅ‡†็งปๅŠจ
return self._calculate_movement(screen_center, config, acquiring=True)

def _handle_locked(self, targets: List[Dict], screen_center: Tuple[int, int],
config, current_time: float) -> Optional[Tuple[float, float]]:
"""้”ๅฎš็Šถๆ€"""
current_target = self._find_target(targets, max_distance=30)
if not current_target:
self._transition_to_lost()
return None

self._update_target(current_target, current_time)

# ๆฃ€ๆŸฅ็›ฎๆ ‡ๆ˜ฏๅฆ็งปๅŠจ
speed = math.sqrt(self.current_target.velocity_x**2 + self.current_target.velocity_y**2)
if speed > 25:
self.lock_state = LockState.TRACKING

# ๅๆฃ€ๆต‹๏ผšๆœ€ๅคง้”ๅฎšๆ—ถ้—ด
max_lock_time = getattr(config, 'maxContinuousFrames', 120) / 60.0 # ่ฝฌๆขไธบ็ง’
if current_time - self.lock_start_time > max_lock_time:
self._transition_to_lost()
return None

return self._calculate_movement(screen_center, config)

def _handle_tracking(self, targets: List[Dict], screen_center: Tuple[int, int],
config, current_time: float) -> Optional[Tuple[float, float]]:
"""่ทŸ่ธช็Šถๆ€"""
current_target = self._find_target(targets, max_distance=40)
if not current_target:
self._transition_to_lost()
return None

self._update_target(current_target, current_time)

# ๆฃ€ๆŸฅ็›ฎๆ ‡ๆ˜ฏๅฆๅœๆญข
speed = math.sqrt(self.current_target.velocity_x**2 + self.current_target.velocity_y**2)
if speed < 15:
self.lock_state = LockState.LOCKED
self.lock_start_time = current_time

return self._calculate_movement(screen_center, config, tracking=True)

def _handle_lost(self, current_time: float) -> Optional[Tuple[float, float]]:
"""ไธขๅคฑ็Šถๆ€"""
self.current_target = None

# ็Ÿญๆš‚ๆš‚ๅœๅŽ้‡ๆ–ฐๆœ็ดข
if current_time - self.state_start_time > 0.3:
self.lock_state = LockState.SEARCHING
self.state_start_time = current_time

return None

def _calculate_movement(self, screen_center: Tuple[int, int], config,
acquiring: bool = False, tracking: bool = False) -> Tuple[float, float]:
"""่ฎก็ฎ—็ž„ๅ‡†็งปๅŠจ"""
if not self.current_target:
return 0.0, 0.0

# ็›ฎๆ ‡ไฝ็ฝฎ
target_x = self.current_target.x
target_y = self.current_target.y

# ๅบ”็”จ็ž„ๅ‡†ๅ็งป
aim_offset = getattr(config, 'aimOffsetRatio', 0.4)
y_offset = (aim_offset - 0.5) * self.current_target.height
target_y += y_offset

# ่ฟๅŠจ้ข„ๆต‹
if tracking and getattr(config, 'enablePredictiveAim', True):
pred_strength = getattr(config, 'predictionStrength', 0.3)
target_x += self.current_target.velocity_x * pred_strength * 0.1
target_y += self.current_target.velocity_y * pred_strength * 0.1

# ๅŽŸๅง‹็งปๅŠจ้‡
raw_x = target_x - screen_center[0]
raw_y = target_y - screen_center[1]

# ไบบ็ฑปๅŒ–ๅพฎ่ฐƒ
if random.random() < 0.3: # 30%ๆฆ‚็އๆทปๅŠ ๅพฎ่ฐƒ
raw_x += random.uniform(-0.5, 0.5)
raw_y += random.uniform(-0.5, 0.5)

# ๅนณๆป‘ๅค„็†
smooth_factor = getattr(config, 'smoothingFactor', 0.6)
if acquiring:
smooth_factor *= 0.7 # ่Žทๅ–ๆ—ถๅ‡ๅฐ‘ๅนณๆป‘
elif tracking:
smooth_factor *= 0.8 # ่ทŸ่ธชๆ—ถไธญ็ญ‰ๅนณๆป‘

self.smoothed_x = self.smoothed_x * smooth_factor + raw_x * (1 - smooth_factor)
self.smoothed_y = self.smoothed_y * smooth_factor + raw_y * (1 - smooth_factor)

# ็งปๅŠจ้˜ˆๅ€ผ (้™ไฝŽ้˜ˆๅ€ผ๏ผŒ่ฎฉๅฐ่ท็ฆป็งปๅŠจไนŸ่ƒฝ็”Ÿๆ•ˆ)
threshold = getattr(config, 'movementThreshold', 0.5) # ไปŽ1.0้™ๅˆฐ0.5
distance = math.sqrt(self.smoothed_x**2 + self.smoothed_y**2)

if distance < threshold:
return 0.0, 0.0

return self.smoothed_x, self.smoothed_y

def _find_target(self, targets: List[Dict], max_distance: float) -> Optional[Dict]:
"""ๅœจๅˆ—่กจไธญๆŸฅๆ‰พๅฝ“ๅ‰็›ฎๆ ‡"""
if not self.current_target or not targets:
return None

for target in targets:
distance = math.sqrt(
(target['current_mid_x'] - self.current_target.x)**2 +
(target['current_mid_y'] - self.current_target.y)**2
)
if distance <= max_distance:
return target

return None

def _update_target(self, target_dict: Dict, current_time: float):
"""ๆ›ดๆ–ฐ็›ฎๆ ‡ไฟกๆฏ"""
if not self.current_target:
return

# ไฟๅญ˜ๆ—งไฝ็ฝฎ็”จไบŽ้€Ÿๅบฆ่ฎก็ฎ—
old_x, old_y = self.current_target.x, self.current_target.y
old_time = self.current_target.last_seen

# ๅ…ˆๆ›ดๆ–ฐไฝ็ฝฎ
self.current_target.x = target_dict['current_mid_x']
self.current_target.y = target_dict['current_mid_y']
self.current_target.width = target_dict['width']
self.current_target.height = target_dict['height']
self.current_target.confidence = target_dict['confidence']
self.current_target.last_seen = current_time

# ่ฎก็ฎ—้€Ÿๅบฆ๏ผˆไฝฟ็”จๆ–ฐๆ—งไฝ็ฝฎๅทฎ๏ผ‰
dt = current_time - old_time
if dt > 0 and dt < 1.0: # ้˜ฒๆญขๅผ‚ๅธธๅคง็š„ๆ—ถ้—ด้—ด้š”
self.current_target.velocity_x = (self.current_target.x - old_x) / dt
self.current_target.velocity_y = (self.current_target.y - old_y) / dt
else:
# ๆ—ถ้—ด้—ด้š”ๅผ‚ๅธธ๏ผŒ้‡็ฝฎ้€Ÿๅบฆ
self.current_target.velocity_x = 0.0
self.current_target.velocity_y = 0.0

def _transition_to_lost(self):
"""่ฝฌๆขๅˆฐไธขๅคฑ็Šถๆ€"""
self.lock_state = LockState.LOST
self.state_start_time = time.time()
self.stats['target_switches'] += 1

# ้‡็ฝฎๅนณๆป‘็Šถๆ€
self.smoothed_x = 0.0
self.smoothed_y = 0.0

def get_stats(self) -> Dict:
"""่Žทๅ–็ปŸ่ฎกไฟกๆฏ"""
return {
'current_state': self.lock_state.value,
'targets_locked': self.stats['targets_locked'],
'target_switches': self.stats['target_switches'],
'avg_reaction_time': sum(self.stats['reaction_times']) / len(self.stats['reaction_times']) if self.stats['reaction_times'] else 0
}

# ๅ…จๅฑ€ๅฎžไพ‹
aiming_system = AdvancedAimingSystem()

def get_advanced_aiming_movement(targets_df, screen_center_x: int, screen_center_y: int, config) -> Optional[Tuple[float, float]]:
"""่Žทๅ–้ซ˜็บง็ž„ๅ‡†็งปๅŠจ้‡"""
# ่ฝฌๆขๆ•ฐๆฎๆ ผๅผ
targets = []
if not targets_df.empty:
for _, row in targets_df.iterrows():
targets.append({
'current_mid_x': row['current_mid_x'],
'current_mid_y': row['current_mid_y'],
'width': row['width'],
'height': row['height'],
'confidence': row['confidence']
})

screen_center = (screen_center_x, screen_center_y)

# ่ฐƒ่ฏ•ไฟกๆฏ
if getattr(config, 'cpsDisplay', False):
print(f"็ž„ๅ‡†็ณป็ปŸ่พ“ๅ…ฅ: ็›ฎๆ ‡ๆ•ฐ={len(targets)}, ๅฑๅน•ไธญๅฟƒ={screen_center}")
if targets:
closest_target = min(targets, key=lambda t: math.sqrt((t['current_mid_x'] - screen_center[0])**2 + (t['current_mid_y'] - screen_center[1])**2))
distance = math.sqrt((closest_target['current_mid_x'] - screen_center[0])**2 + (closest_target['current_mid_y'] - screen_center[1])**2)
print(f"ๆœ€่ฟ‘็›ฎๆ ‡: ไฝ็ฝฎ=({closest_target['current_mid_x']:.1f}, {closest_target['current_mid_y']:.1f}), ่ท็ฆป={distance:.1f}")

# ๆ›ดๆ–ฐ็ž„ๅ‡†็ณป็ปŸ
result = aiming_system.update(targets, screen_center, config)

if getattr(config, 'cpsDisplay', False) and result:
print(f"็ž„ๅ‡†็ณป็ปŸ่พ“ๅ‡บ: ็งปๅŠจ้‡=({result[0]:.2f}, {result[1]:.2f})")

return result
17 changes: 16 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,19 @@
# 1 - CPU
# 2 - AMD
# 3 - NVIDIA
onnxChoice = 1
onnxChoice = 1
# ========================================
# Enhanced Features by yin1895
# ========================================

# ========== Driver Mouse Configuration ==========
useDriverMouse = True # Use driver-level control (requires Logitech GHUB/LGS)
fallbackToSystemMouse = True # Fallback to system-level control when driver fails

# ========== Advanced Aiming Configuration ==========
enableAdvancedAiming = False # Enable advanced aiming system
enableSmoothMovement = True # Enable smooth movement
smoothingFactor = 0.6 # Smoothing factor (0.1-0.9)
movementThreshold = 2 # Movement threshold (pixels)
enablePredictiveAim = False # Enable predictive aiming
predictionStrength = 0.6 # Prediction strength
Binary file added ghub_move/ghub_device.dll
Binary file not shown.
Loading