-
Notifications
You must be signed in to change notification settings - Fork 129
/
aimbot.py
240 lines (201 loc) · 11.4 KB
/
aimbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
import ctypes
import cv2
import json
import math
import mss
import numpy as np
import os
import pygame
import sys
import time
import torch
import uuid
import win32api
from termcolor import colored
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
class POINT(ctypes.Structure):
_fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
class Aimbot:
extra = ctypes.c_ulong(0)
ii_ = Input_I()
screen = mss.mss()
pixel_increment = 1 #controls how many pixels the mouse moves for each relative movement
with open("lib/config/config.json") as f:
sens_config = json.load(f)
aimbot_status = colored("ENABLED", 'green')
def __init__(self, box_constant = 416, collect_data = False, mouse_delay = 0.0001, debug = False, controller = False):
#controls the initial centered box width and height of the "Lunar Vision" window
self.box_constant = box_constant #controls the size of the detection box (equaling the width and height)
print("[INFO] Loading the neural network model")
self.model = torch.hub.load('ultralytics/yolov5', 'custom', path='lib/best.pt')
if torch.cuda.is_available():
if "16" in torch.cuda.get_device_name(torch.cuda.current_device()): #known error with the 1650 GPUs where detection doesn't work
print(colored("[!] CUDA ACCELERATION IS UNAVAILABLE (ISSUE WITH 1650/1660 GPUs)", "red"))
os._exit(1)
else:
print(colored("CUDA ACCELERATION [ENABLED]", "green"))
else:
print(colored("[!] CUDA ACCELERATION IS UNAVAILABLE", "red"))
print(colored("[!] Check your PyTorch installation, else performance will be very poor", "red"))
self.model.conf = 0.55 # base confidence threshold (or base detection (0-1)
self.model.iou = 0.45 # NMS IoU (0-1)
self.collect_data = collect_data
self.mouse_delay = mouse_delay
self.debug = debug
if controller:
pygame.init()
self.controller = pygame.joystick.Joystick(0)
self.controller.init()
else:
self.controller = False
print("\n[INFO] PRESS 'F1' TO TOGGLE AIMBOT\n[INFO] PRESS 'F2' TO QUIT")
def update_status_aimbot():
if Aimbot.aimbot_status == colored("ENABLED", 'green'):
Aimbot.aimbot_status = colored("DISABLED", 'red')
else:
Aimbot.aimbot_status = colored("ENABLED", 'green')
sys.stdout.write("\033[K")
print(f"[!] AIMBOT IS [{Aimbot.aimbot_status}]", end = "\r")
def left_click():
ctypes.windll.user32.mouse_event(0x0002) #left mouse down
Aimbot.sleep(0.0001)
ctypes.windll.user32.mouse_event(0x0004) #left mouse up
def sleep(duration, get_now = time.perf_counter):
if duration == 0: return
now = get_now()
end = now + duration
while now < end:
now = get_now()
def is_target_locked(x, y):
#plus/minus 5 pixel threshold
threshold = 5
return True if 960 - threshold <= x <= 960 + threshold and 540 - threshold <= y <= 540 + threshold else False
def move_crosshair(self, x, y, targeted):
if targeted:
scale = Aimbot.sens_config["targeting_scale"]
else:
return #TODO
if self.debug: start_time = time.perf_counter()
for rel_x, rel_y in Aimbot.interpolate_coordinates_from_center((x, y), scale):
Aimbot.ii_.mi = MouseInput(rel_x, rel_y, 0, 0x0001, 0, ctypes.pointer(Aimbot.extra))
input_obj = Input(ctypes.c_ulong(0), Aimbot.ii_)
ctypes.windll.user32.SendInput(1, ctypes.byref(input_obj), ctypes.sizeof(input_obj))
if not self.debug: Aimbot.sleep(self.mouse_delay) #time.sleep is not accurate enough
if self.debug: #remove this later
print(f"TIME: {time.perf_counter() - start_time}")
print("DEBUG: SLEEPING FOR 1 SECOND")
time.sleep(1)
#generator yields pixel tuples for relative movement
def interpolate_coordinates_from_center(absolute_coordinates, scale):
diff_x = (absolute_coordinates[0] - 960) * scale/Aimbot.pixel_increment
diff_y = (absolute_coordinates[1] - 540) * scale/Aimbot.pixel_increment
length = int(math.dist((0,0), (diff_x, diff_y)))
if length == 0: return
unit_x = (diff_x/length) * Aimbot.pixel_increment
unit_y = (diff_y/length) * Aimbot.pixel_increment
x = y = sum_x = sum_y = 0
for k in range(0, length):
sum_x += x
sum_y += y
x, y = round(unit_x * k - sum_x), round(unit_y * k - sum_y)
yield x, y
def is_L2_pressed(self):
events = pygame.event.get()
for event in events:
if event.type == pygame.JOYBUTTONDOWN:
return self.controller.get_button(6)
return False
def start(self):
print("[INFO] Beginning screen capture")
Aimbot.update_status_aimbot()
half_screen_width = ctypes.windll.user32.GetSystemMetrics(0)/2 #this should always be 960
half_screen_height = ctypes.windll.user32.GetSystemMetrics(1)/2 #this should always be 540
detection_box = {'left': int(half_screen_width - self.box_constant//2), #x1 coord (for top-left corner of the box)
'top': int(half_screen_height - self.box_constant//2), #y1 coord (for top-left corner of the box)
'width': int(self.box_constant), #width of the box
'height': int(self.box_constant)} #height of the box
if self.collect_data:
collect_pause = 0
set_collect_delay = True
while True:
start_time = time.perf_counter()
frame = np.array(Aimbot.screen.grab(detection_box))
if self.collect_data: orig_frame = np.copy(frame)
results = self.model(frame)
if len(results.xyxy[0]) != 0: #player detected
least_crosshair_dist = closest_detection = player_in_frame = None
for *box, conf, cls in results.xyxy[0]: #iterate over each player detected
x1y1 = [int(x.item()) for x in box[:2]]
x2y2 = [int(x.item()) for x in box[2:]]
x1, y1, x2, y2, conf = *x1y1, *x2y2, conf.item()
height = y2 - y1
relative_head_X, relative_head_Y = int((x1 + x2)/2), int((y1 + y2)/2 - height/2.7) #offset to roughly approximate the head using a ratio of the height
is_own_player = player_in_frame = x1 < 15 or (x1 < self.box_constant/5 and y2 > self.box_constant/1.2) #helps ensure that your own player is not regarded as a valid detection
#calculate the distance between each detection and the crosshair at (self.box_constant/2, self.box_constant/2)
crosshair_dist = math.dist((relative_head_X, relative_head_Y), (self.box_constant/2, self.box_constant/2))
if not least_crosshair_dist: least_crosshair_dist = crosshair_dist #initalize least crosshair distance variable first iteration
if crosshair_dist <= least_crosshair_dist and not is_own_player:
least_crosshair_dist = crosshair_dist
closest_detection = {"x1y1": x1y1, "x2y2": x2y2, "relative_head_X": relative_head_X, "relative_head_Y": relative_head_Y, "conf": conf}
if not is_own_player:
cv2.rectangle(frame, x1y1, x2y2, (244, 113, 115), 2) #draw the bounding boxes for all of the player detections (except own)
cv2.putText(frame, f"{int(conf * 100)}%", x1y1, cv2.FONT_HERSHEY_DUPLEX, 0.5, (244, 113, 116), 2) #draw the confidence labels on the bounding boxes
else:
is_own_player = False
if self.controller:
targeted = Aimbot.is_L2_pressed(self)
else:
targeted = True if win32api.GetKeyState(0x02) in (-127, -128) else False #checks if right mouse button is being held down
if closest_detection: #if valid detection exists
cv2.circle(frame, (closest_detection["relative_head_X"], closest_detection["relative_head_Y"]), 5, (115, 244, 113), -1) #draw circle on the head
#draw line (tracer) from the crosshair to the head
cv2.line(frame, (closest_detection["relative_head_X"], closest_detection["relative_head_Y"]), (self.box_constant//2, self.box_constant//2), (244, 242, 113), 2)
absolute_head_X, absolute_head_Y = closest_detection["relative_head_X"] + detection_box['left'], closest_detection["relative_head_Y"] + detection_box['top']
x1, y1 = closest_detection["x1y1"]
if Aimbot.is_target_locked(absolute_head_X, absolute_head_Y):
cv2.putText(frame, "LOCKED", (x1 + 40, y1), cv2.FONT_HERSHEY_DUPLEX, 0.5, (115, 244, 113), 2) #draw the confidence labels on the bounding boxes
else:
cv2.putText(frame, "TARGETING", (x1 + 40, y1), cv2.FONT_HERSHEY_DUPLEX, 0.5, (115, 113, 244), 2) #draw the confidence labels on the bounding boxes
if self.collect_data and time.perf_counter() - collect_pause > 1 and targeted and not player_in_frame: #screenshots can only be taken every 1 second
if set_collect_delay:
collect_delay = time.perf_counter()
set_collect_delay = False
if time.perf_counter() - collect_delay > 0.5: #ensures that player has been targeting for at least 0.5 seconds
cv2.imwrite(f"lib/data/{str(uuid.uuid4())}.jpg", orig_frame)
collect_pause = collect_delay = time.perf_counter()
if Aimbot.aimbot_status == colored("ENABLED", 'green'):
Aimbot.move_crosshair(self, absolute_head_X, absolute_head_Y, targeted)
cv2.putText(frame, f"FPS: {int(1/(time.perf_counter() - start_time))}", (5, 30), cv2.FONT_HERSHEY_DUPLEX, 1, (113, 116, 244), 2)
cv2.imshow("Lunar Vision", frame)
if cv2.waitKey(1) & 0xFF == ord('0'):
break
def clean_up():
print("\n[INFO] F2 WAS PRESSED. QUITTING...")
cv2.destroyAllWindows()
Aimbot.screen.close()
os._exit(1)
if __name__ == "__main__": print("You are in the wrong directory and are running the wrong file; you must run lunar.py")