Yolov5 fps游戏AI挂的原理研究

使用Yolov5对fps游戏AI挂的原理研究项目


yolov5_valorant项目网址

流程设计

  1. 中键开关挂
  2. 左键按下时检测(即非自动开火模式)
  3. 抓取屏幕
  4. yolo检测
  5. 鼠标控制模拟

屏幕抓取

1
2
3
from PIL import ImageGrab
im = ImageGrab.grab(bbox=rect)
img0 = np.array(im)

yolov5的检测关键代码提取

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
import win32api
import win32con
from PIL import ImageGrab
import numpy as np
import torch
import cv2

from utils.augmentations import letterbox
from utils.general import (non_max_suppression, scale_coords)
from models.experimental import attempt_load

# pt_path = 'valorant-v12.pt'
pt_path = 'valorant-bot.pt'

def run():
rect = (0, 0, 1920, 1080)
mid_screen_x = (rect[2] - rect[0]) >> 1
mid_screen_y = (rect[3] - rect[1]) >> 1
mid_screen = mid_screen_x + mid_screen_y
aims = []
device = 'cuda' if torch.cuda.is_available() else 'cpu'
half = device != 'cpu'
conf_thres = 0.4
iou_thres = 0.05

model = attempt_load(pt_path, device=device, inplace=True, fuse=True)
stride = max(int(model.stride.max()), 32) # model stride
model.half()

open_helper = False

while True:
if ((win32api.GetAsyncKeyState(0x01) & 0x8000) > 0 or (
win32api.GetAsyncKeyState(0x02) & 0x8000) > 0) and open_helper:
im = ImageGrab.grab(bbox=rect)
img0 = np.array(im)
img = letterbox(img0, stride=stride)[0]
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(device)
img = img.half() if half else img.float()
img /= 255 # 0 - 255 to 0.0 - 1.0
if len(img.shape) == 3:
img = img[None] # 压缩数据维度

img = img.permute(0, 3, 1, 2)
pred = model(img, augment=False, visualize=False)[0]
pred = non_max_suppression(pred, conf_thres, iou_thres)

# Process predictions (based on source code of yolo)
for i, det in enumerate(pred): # per image
if len(det):
# Rescale boxes from img_size to im0 size
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round()
# Write results
for *xyxy, conf, cls in reversed(det):
aims.append(((xyxy[0] + xyxy[2]) / 2, (xyxy[3] - xyxy[1]) / 5 + xyxy[1]))

if len(aims):
min_dis = 100000
target_x = 960
target_y = 540
for a, b in aims:
dis = a + b - mid_screen
if dis < min_dis:
target_x = a
target_y = b
min_dis = dis
print(f"{target_x}, {target_y}")
aims = []

if __name__ == "__main__":
run()

鼠标的操控和窗口句柄问题

鼠标
窗口句柄