Post

Yolov5 fps游戏AI挂的原理研究

使用Yolov5对屏幕实时检测,并控制鼠标

Yolov5 fps游戏AI挂的原理研究

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

yolov5_valorant项目网址

fps游戏AI外挂原理实现

流程设计

  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()

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

鼠标

窗口句柄

This post is licensed under CC BY 4.0 by the author.

© Liu Yifei. Some rights reserved.

Using the Chirpy theme for Jekyll.