├── _config.yml
├── training_tools
├── obj.names
├── obj.data
├── dataset.yaml
├── process.py
├── put_train.py
├── prep_mark.py
├── Conv_PrtScn.py
├── 900cvt450.py
└── Gen_PrtScn.ahk
├── PDF_Images
├── 自瞄待命运行.png
├── 自瞄控制运行.png
├── 自瞄显示图像.png
├── 自瞄模式选择.png
└── 自瞄等待窗口.png
├── aimbot-exec
├── 安装包生成.iss
├── now
│ ├── msdk.dll
│ ├── ghub_mouse.dll
│ ├── 调用罗技
│ │ ├── ghub_mouse.h
│ │ └── ghub_mouse.cpp
│ ├── two_class_threat.py
│ ├── AI_M_BOT_N.py
│ ├── darknet_yolo34.py
│ ├── scrnshot.py
│ ├── mouse.py
│ ├── util.py
│ ├── torch_yolox.py
│ ├── AI_main.py
│ └── AI_main_pow.py
├── 先锋自瞄安装包生成.iss
├── beta
│ └── mousemove.py
├── test_mouse_move.py
├── FPS战斗助手.ahk
└── old
│ ├── AI_M_BOT_X2.py
│ └── AI_M_BOT_X1.py
├── 完成度.txt
├── notebooks
└── YOLOv4_Series_Custom_Training.pdf
├── README.md
├── yolov4-tiny
└── yolov4-tiny-custom.cfg
└── yolov4
└── yolov4-custom.cfg
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/training_tools/obj.names:
--------------------------------------------------------------------------------
1 | human-head
2 | human-body
3 |
--------------------------------------------------------------------------------
/PDF_Images/自瞄待命运行.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/PDF_Images/自瞄待命运行.png
--------------------------------------------------------------------------------
/PDF_Images/自瞄控制运行.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/PDF_Images/自瞄控制运行.png
--------------------------------------------------------------------------------
/PDF_Images/自瞄显示图像.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/PDF_Images/自瞄显示图像.png
--------------------------------------------------------------------------------
/PDF_Images/自瞄模式选择.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/PDF_Images/自瞄模式选择.png
--------------------------------------------------------------------------------
/PDF_Images/自瞄等待窗口.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/PDF_Images/自瞄等待窗口.png
--------------------------------------------------------------------------------
/aimbot-exec/安装包生成.iss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/aimbot-exec/安装包生成.iss
--------------------------------------------------------------------------------
/aimbot-exec/now/msdk.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/aimbot-exec/now/msdk.dll
--------------------------------------------------------------------------------
/aimbot-exec/先锋自瞄安装包生成.iss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/aimbot-exec/先锋自瞄安装包生成.iss
--------------------------------------------------------------------------------
/完成度.txt:
--------------------------------------------------------------------------------
1 | 新运输船 致命街区 沙漠-灰 椰岛之巅 胜利广场 守望之城 怒海狙击 =沙漠-1 =小型工厂 =新金字塔
2 | 新卫星基地 新黑色城镇 潜艇 港口 供电所 异域小镇 新年广场 冲锋大道 =新沙漠灰
--------------------------------------------------------------------------------
/aimbot-exec/now/ghub_mouse.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/aimbot-exec/now/ghub_mouse.dll
--------------------------------------------------------------------------------
/notebooks/YOLOv4_Series_Custom_Training.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Congrammer/AI-M-BOT/HEAD/notebooks/YOLOv4_Series_Custom_Training.pdf
--------------------------------------------------------------------------------
/training_tools/obj.data:
--------------------------------------------------------------------------------
1 | classes = 2
2 | train = data/train.txt
3 | valid = data/test.txt
4 | names = data/obj.names
5 | backup = /mydrive/yolo/training
--------------------------------------------------------------------------------
/training_tools/dataset.yaml:
--------------------------------------------------------------------------------
1 | path: ../素材标注 # dataset root dir
2 | train: ../train.txt # train images
3 | val: ../train.txt # val images
4 | test: ../test.txt # test images
5 |
6 | # Classes
7 | nc: 3 # number of classes
8 | names: [ 'human-head', 'human-body' ] # class names
9 |
--------------------------------------------------------------------------------
/aimbot-exec/now/调用罗技/ghub_mouse.h:
--------------------------------------------------------------------------------
1 | //fork from https://github.com/ekknod/logitech-cve
2 | #ifndef MOUSE_H
3 | #define MOUSE_H
4 |
5 |
6 | #define GHUB_API __declspec(dllexport)
7 | typedef int BOOL;
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 |
13 | BOOL GHUB_API Agulll(void); // mouse_open
14 | void GHUB_API Shwaji(void); // mouse_close
15 | void Check(char button, char x, char y, char wheel); // mouse_move
16 | void GHUB_API Mach_Move(int x, int y); // moveR
17 | void GHUB_API Leo_Kick(char button); // press
18 | void GHUB_API Niman_years(); // release
19 | void GHUB_API Mebiuspin(char wheel); // scroll
20 |
21 | #ifdef __cplusplus
22 | }
23 | #endif
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/training_tools/process.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | # Current directory
4 | # current_dir = os.path.dirname(os.path.abspath(__file__))
5 | # print(current_dir)
6 | current_dir = 'data/obj/'
7 |
8 | # Percentage of images to be used for the test set
9 | percentage_test = 10
10 |
11 | # Create and/or truncate train.txt and test.txt
12 | file_train = open('data/train.txt', 'w')
13 | file_test = open('data/test.txt', 'w')
14 |
15 | # Enable multiple extension names
16 | types = ('.jpg', '.png', '.JPG', '.jpeg')
17 |
18 | # Populate train.txt and test.txt
19 | counter = 1
20 | index_test = round(100 / percentage_test)
21 | for pathAndFilename in os.listdir(current_dir):
22 | title, ext = os.path.splitext(pathAndFilename)
23 |
24 | if ext in types:
25 | if counter == index_test:
26 | counter = 1
27 | file_test.write(current_dir + title + ext + '\n')
28 | else:
29 | counter += 1
30 | file_train.write(current_dir + title + ext + '\n')
31 |
32 | file_train.close()
33 | file_test.close()
34 |
--------------------------------------------------------------------------------
/aimbot-exec/now/two_class_threat.py:
--------------------------------------------------------------------------------
1 | from cv2 import line
2 |
3 |
4 | def threat_handling(frame, window_w, threat_alist, recoil_ctrl, frame_height, frame_width, class_num):
5 | x0, y0, fire_pos, fire_close, fire_ok = 0, 0, 0, 0, 0
6 | if len(threat_alist):
7 | threat_alist.sort(key=lambda x:x[0])
8 | x_tht, y_tht, w_tht, h_tht = threat_alist[0][1]
9 | fire_close = (1 if window_w / w_tht <= 50 else 0)
10 |
11 | # 指向距离最近威胁中心的位移(class0为头部,class1为身体)
12 | x0 = x_tht + (w_tht - frame_width) / 2
13 | y0 = y_tht + (h_tht - frame_height) / 2
14 |
15 | if abs(x0) <= 1/4 * w_tht and abs(y0) <= 2/5 * h_tht: # 查看是否已经指向目标
16 | fire_ok = 1
17 |
18 | if threat_alist[0][2] == 0 and class_num > 1:
19 | fire_pos = 1
20 | elif h_tht > w_tht:
21 | y0 -= h_tht / 4
22 | fire_pos = 2
23 | if fire_close:
24 | y0 -= h_tht / 8
25 | fire_pos = 1
26 |
27 | y0 += recoil_ctrl # 后座控制
28 | xpos, ypos = x0 + frame_width / 2, y0 + frame_height / 2
29 | line(frame, (frame_width // 2, frame_height // 2), (int(xpos), int(ypos)), (0, 0, 255), 2)
30 |
31 | return x0, y0, fire_pos, fire_close, fire_ok, frame
32 |
--------------------------------------------------------------------------------
/aimbot-exec/now/AI_M_BOT_N.py:
--------------------------------------------------------------------------------
1 | """
2 | New Detection method(onnxruntime) modified from Project YOLOX
3 | YOLOX Project Authors: Zheng Ge, Songtao Liu, Feng Wang, Zeming Li, Jian Sun
4 | YOLOX Project website: https://github.com/Megvii-BaseDetection/YOLOX
5 | New Detection method(onnxruntime) cooperator: Barry
6 | Detection code modified from project AIMBOT-YOLO
7 | Detection code Author: monokim
8 | Detection project website: https://github.com/monokim/AIMBOT-YOLO
9 | Detection project video: https://www.youtube.com/watch?v=vQlb0tK1DH0
10 | Screenshot method from: https://www.youtube.com/watch?v=WymCpVUPWQ4
11 | Screenshot method code modified from project: opencv_tutorials
12 | Screenshot method code Author: Ben Johnson (learncodebygaming)
13 | Screenshot method website: https://github.com/learncodebygaming/opencv_tutorials
14 | Mouse event method code modified from project logitech-cve
15 | Mouse event method website: https://github.com/ekknod/logitech-cve
16 | Mouse event method project Author: ekknod
17 | """
18 |
19 | from multiprocessing import freeze_support
20 | from util import use_choice
21 |
22 |
23 | # 主程序
24 | if __name__ == '__main__':
25 | # 为了Pyinstaller顺利生成exe
26 | freeze_support()
27 |
28 | # 选择标准/烧卡模式
29 | main_model = use_choice(1, 2, '请问您的电脑是高配机吗?(1:不是, 2:是): ')
30 | if main_model == 2:
31 | from AI_main_pow import main
32 | else:
33 | from AI_main import main
34 |
35 | main()
36 |
--------------------------------------------------------------------------------
/training_tools/put_train.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 | from tqdm import tqdm
3 | from sys import exit
4 | import random
5 | import os
6 |
7 |
8 | final_path = './标注完成/' # 标注好的图片路径
9 | label_path = './素材标注/'
10 | train_txt = 'train.txt' # 标注好用于训练的图片
11 | test_txt = 'test.txt' # 标注好用于测试的图片
12 |
13 |
14 | def Diff(li1, li2):
15 | return list(set(li1) - set(li2)) + list(set(li2) - set(li1))
16 |
17 |
18 | if not os.path.isdir(final_path):
19 | os.makedirs(final_path)
20 |
21 |
22 | if __name__ == '__main__':
23 | if not os.listdir(final_path):
24 | exit(0)
25 |
26 | train_file = open(train_txt, 'w')
27 | test_file = open(test_txt, 'w')
28 | label_list = []
29 | file_list = []
30 | marked = 0
31 | totals = 0
32 |
33 | for labels in (os.listdir(label_path)):
34 | label_list.append(labels.replace('.txt', ''))
35 | if labels != 'classes.txt' and os.path.getsize(label_path + labels):
36 | marked += 1
37 |
38 | for files in tqdm(os.listdir(final_path)):
39 | file_names, file_ext = os.path.splitext(files)
40 | file_list.append(file_names)
41 | if random.randint(0, 999) >= 100:
42 | train_file.write(final_path + file_names + file_ext + '\n') # 录入文件名
43 | else:
44 | test_file.write(final_path + file_names + file_ext + '\n') # 录入文件名
45 | totals += 1
46 | if not file_names in label_list:
47 | file_create = open(label_path + file_names + '.txt', 'w')
48 | file_create.close()
49 | label_list.append(file_names)
50 |
51 | train_file.close()
52 | test_file.close()
53 |
54 | print(f'批量处理完成,图片标注率={100*(marked/totals):.2f}%')
55 | print(f'不同处={Diff(label_list, file_list)}')
56 | sleep(3)
57 |
--------------------------------------------------------------------------------
/training_tools/prep_mark.py:
--------------------------------------------------------------------------------
1 | from time import time, sleep
2 | from tqdm import tqdm
3 | from sys import exit
4 | import numpy as np
5 | import os
6 | import cv2
7 |
8 |
9 | prep_label_path = './测试标注/'
10 | if not os.path.isdir(prep_label_path):
11 | os.makedirs(prep_label_path)
12 |
13 | pics_path = './预先处理/'
14 | if not os.path.isdir(pics_path):
15 | os.makedirs(pics_path)
16 |
17 |
18 | if __name__ == '__main__':
19 | if not os.listdir(pics_path):
20 | exit(0)
21 |
22 | CONFIG_FILE = './yolov4-tiny.cfg'
23 | WEIGHT_FILE = './yolov4-tiny.weights'
24 |
25 | net = cv2.dnn.readNet(CONFIG_FILE, WEIGHT_FILE)
26 | net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
27 | net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
28 | model = cv2.dnn_DetectionModel(net)
29 | model.setInputParams(size=(512, 320), scale=1/255, swapRB=False)
30 |
31 | start_time = time()
32 |
33 | for pics in tqdm(os.listdir(pics_path)):
34 | pic_names, pic_ext = os.path.splitext(pics)
35 | file_create = open(prep_label_path + pic_names + '.txt', 'w')
36 | pictures = cv2.imdecode(np.fromfile(pics_path + pics, dtype=np.uint8), -1)
37 | pictures = pictures[..., :3]
38 | # cv2.imshow('Show frame', pictures)
39 | # cv2.waitKey(1)
40 |
41 | frame_height, frame_width = pictures.shape[:2]
42 | classes, scores, boxes = model.detect(pictures, 0.2, 0.3)
43 |
44 | for (classid, score, box) in zip(classes, scores, boxes):
45 | x, y, w, h = box
46 | x = x + w/2
47 | y = y + h/2
48 | if classid == 0:
49 | file_create.write(f'0 {(x/frame_width):.6f} {(y/frame_height):.6f} {(w/frame_width):.6f} {(h/frame_height):.6f}\n')
50 | if classid == 1:
51 | file_create.write(f'1 {(x/frame_width):.6f} {(y/frame_height):.6f} {(w/frame_width):.6f} {(h/frame_height):.6f}\n')
52 |
53 | file_create.close()
54 |
55 | end_time = time() - start_time
56 |
57 | print(f'Time used: {end_time:.3f} s')
58 | sleep(3)
59 |
--------------------------------------------------------------------------------
/training_tools/Conv_PrtScn.py:
--------------------------------------------------------------------------------
1 | from win32file import CreateFile, SetFileTime, CloseHandle
2 | from win32file import GENERIC_READ, GENERIC_WRITE, OPEN_EXISTING
3 | from random import randrange
4 | from time import time, sleep
5 | from tqdm import tqdm
6 | from sys import exit
7 | import numpy as np
8 | import pywintypes
9 | import cv2
10 | import os
11 |
12 |
13 | # 随机改变文件创建/修改/访问时间
14 | def RandomFileTime(file_path):
15 | try:
16 | fh = CreateFile(file_path, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, 0)
17 | new_c_time = int(time() - randrange(2500000, 30000000))
18 | new_m_time = new_c_time + randrange(10000, 500000)
19 | new_a_time = new_m_time + randrange(90000, 2000000)
20 |
21 | createTimes = pywintypes.Time(new_c_time)
22 | accessTimes = pywintypes.Time(new_a_time)
23 | modifyTimes = pywintypes.Time(new_m_time)
24 | SetFileTime(fh, createTimes, accessTimes, modifyTimes)
25 | CloseHandle(fh)
26 | return 0
27 | except pywintypes.error:
28 | return 1
29 |
30 |
31 | source_path = './游戏截图/' # 源文件路径
32 | target_path = './预先处理/' # 输出目标文件路径
33 |
34 | if not os.path.isdir(source_path):
35 | os.makedirs(source_path)
36 | exit(0)
37 |
38 | if not os.path.isdir(target_path):
39 | os.makedirs(target_path)
40 |
41 | if __name__ == '__main__':
42 | if not os.listdir(source_path):
43 | exit(0)
44 |
45 | fail_change_time = 0
46 | for file in tqdm(os.listdir(source_path)):
47 | if not os.path.isfile(source_path + file):
48 | continue
49 | image_source = cv2.imdecode(np.fromfile(source_path + file, dtype=np.uint8), -1) # 读取图片
50 | if RandomFileTime(source_path + file):
51 | fail_change_time += 1
52 |
53 | image = cv2.resize(image_source, (512, 320), 0, 0, cv2.INTER_LINEAR) # 修改尺寸
54 | cv2.imencode('.png', image, [int(cv2.IMWRITE_PNG_COMPRESSION), 3])[1].tofile(target_path + file[0:file.find('.')] + '.png') # 重命名并且保存
55 |
56 | print(f'批量处理完成,文件改时失败{fail_change_time}个')
57 | sleep(3)
58 |
--------------------------------------------------------------------------------
/training_tools/900cvt450.py:
--------------------------------------------------------------------------------
1 | from tqdm import tqdm
2 | import numpy as np
3 | import cv2
4 | import os
5 |
6 | source_path = './完成/' # 源文件路径
7 | target_path = './转换宽高/' # 输出目标文件路径
8 | txt_path = './转换标注/'
9 |
10 | if not os.path.isdir(source_path):
11 | os.makedirs(source_path)
12 | exit(0)
13 |
14 | if not os.path.isdir(target_path):
15 | os.makedirs(target_path)
16 |
17 | if not os.path.isdir(txt_path):
18 | os.makedirs(txt_path)
19 |
20 | if __name__ == '__main__':
21 | if not os.listdir(source_path):
22 | exit(0)
23 | for files in tqdm(os.listdir(source_path)):
24 | file_names, file_ext = os.path.splitext(files)
25 | if file_ext == '.txt':
26 | file_create = open(txt_path + files, 'w')
27 | if not os.path.getsize(source_path + files):
28 | file_create.close()
29 | continue
30 |
31 | file_data = []
32 |
33 | with open(source_path + files, 'r') as myfile:
34 | # 读取数据
35 | for line in myfile:
36 | currentLine = line[:-1]
37 | data = currentLine.split(' ')
38 | if float(data[2]) + float(data[4]) / 2 > 0.25 and float(data[2]) - float(data[4]) / 2 < 0.75:
39 | file_data.append(data)
40 |
41 | # 处理转换数据
42 | for i in file_data:
43 | h1, h2 = float(i[2]) - float(i[4]) / 2, float(i[2]) + float(i[4]) / 2
44 | h1 = 0.5 + ((0.25 if h1 < 0.25 else h1) - 0.5) * 2
45 | h2 = 0.5 + ((0.75 if h2 > 0.75 else h2) - 0.5) * 2
46 | i[4] = str('{:.6f}'.format(h2 - h1))
47 | i[2] = str('{:.6f}'.format((h2 + h1) / 2))
48 |
49 | # 写入数据
50 | for j in file_data:
51 | content = ''
52 | for k in j:
53 | content += k + ' '
54 | file_create.write(content)
55 | file_create.write('\n')
56 |
57 | file_create.close()
58 |
59 | else:
60 | pics = cv2.imdecode(np.fromfile(source_path + files, dtype=np.uint8), -1)
61 | crop_img = pics[int(pics.shape[1] / 4):int(pics.shape[1] * 3 / 4), 0:pics.shape[0]]
62 | cv2.imencode('.jpg', crop_img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])[1].tofile(target_path + files[0:files.find('.')] + '.jpg') # 重命名并且保存
63 |
--------------------------------------------------------------------------------
/aimbot-exec/beta/mousemove.py:
--------------------------------------------------------------------------------
1 | """
2 | from https://stackoverflow.com/questions/44467329/pyautogui-mouse-movement-with-bezier-curve
3 | """
4 |
5 | import pyautogui
6 | import bezier
7 | import numpy as np
8 | from time import time
9 |
10 |
11 | # Disable pyautogui pauses (from DJV's answer)
12 | pyautogui.MINIMUM_DURATION = 0
13 | pyautogui.MINIMUM_SLEEP = 0
14 | pyautogui.PAUSE = 0
15 |
16 | # We'll wait 5 seconds to prepare the starting position
17 | start_delay = 2
18 | print("Drawing curve from mouse in {} seconds.".format(start_delay))
19 | pyautogui.moveTo(100, 100)
20 | pyautogui.sleep(start_delay)
21 |
22 | # For this example we'll use four control points, including start and end coordinates
23 | start = pyautogui.position()
24 | print(start)
25 | end = start[0]+600, start[1]+200
26 | print(end)
27 |
28 | begin_time = time()
29 | # Two intermediate control points that may be adjusted to modify the curve.
30 | control1 = start[0]+125, start[1]+100
31 | control2 = start[0]+375, start[1]+50
32 |
33 | # Format points to use with bezier
34 | control_points = np.array([start, control1, control2, end])
35 | points = np.array([control_points[:,0], control_points[:,1]]) # Split x and y coordinates
36 |
37 | # You can set the degree of the curve here, should be less than # of control points
38 | degree = 3
39 | # Create the bezier curve
40 | curve = bezier.Curve(points, degree)
41 | # You can also create it with using Curve.from_nodes(), which sets degree to len(control_points)-1
42 | # curve = bezier.Curve.from_nodes(points)
43 |
44 | curve_steps = 50 # How many points the curve should be split into. Each is a separate pyautogui.moveTo() execution
45 | delay = 1/curve_steps # Time between movements. 1/curve_steps = 1 second for entire curve
46 |
47 | listx = []
48 | listy = []
49 |
50 | # Move the mouse
51 | for i in range(1, curve_steps+1):
52 | # The evaluate method takes a float from [0.0, 1.0] and returns the coordinates at that point in the curve
53 | # Another way of thinking about it is that i/steps gets the coordinates at (100*i/steps) percent into the curve
54 | x, y = curve.evaluate(i/curve_steps)
55 | listx.append(x[0])
56 | listy.append(y[0])
57 | # print(x, y)
58 | # pyautogui.moveTo(x, y) # Move to point in curve
59 | # pyautogui.sleep(delay) # Wait delay
60 |
61 | nlistx = np.diff(np.array(listx))
62 | nlisty = np.diff(np.array(listy))
63 |
64 | print(nlistx)
65 | print(nlisty)
66 |
67 | print(nlistx.size)
68 |
69 | for i in range(nlistx.size):
70 | pyautogui.moveRel(int(round(nlistx[i])), int(round(nlisty[i])))
71 | pyautogui.sleep(delay)
72 |
73 | end_time = time() - begin_time
74 | print(end_time)
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # I AM BOT========================AI-M-BOT
2 |
3 | [](https://996.icu/#/zh_CN) [](https://996.icu/#/en_US) [](https://github.com/996icu/996.ICU/blob/master/LICENSE_CN) [](https://github.com/996icu/996.ICU/blob/master/LICENSE)
4 |
5 | [](https://github.com/JiaPai12138/AI-M-BOT) [](https://github.com/JiaPai12138/AI-M-BOT) [](https://github.com/JiaPai12138/AI-M-BOT) [](https://github.com/JiaPai12138/AI-M-BOT/releases) [](https://github.com/JiaPai12138/AI-M-BOT/blob/main/LICENSE) [](https://github.com/JiaPai12138/AI-M-BOT/blob/main/使用说明.rtf)
6 |
7 | `YOLOv4-tiny (yolox) and OpenCV-gpu (onnxruntime-gpu) based aimbot powered up by multiprocessing (and pid control in the future)`
8 | ```
9 | 1, 本作者不对任何由本开源软件造成的任何问题(包括封号)负责。。。
10 | 2, 本开源免费软件为学习/娱乐之用,禁止贩卖,欢迎参与改进。。。
11 | 3, 本人所在战队为正规战队,除本人外皆游戏技艺娴熟之辈。。。
12 | 4, 本人对本瞎几把不专业申明拥有最终解释权,哈哈。。。
13 | 5, 没有惊喜,没有意外。。。
14 | ```
15 |
16 | * 使用自瞄时请将游戏分辨率调整至1600*900及以下,将画面效果调整至中等及以下
17 | * 需要计算能力6.1及以上版本的N卡以及安装相应驱动,详情请见[CUDA wiki](https://zh.wikipedia.org/wiki/CUDA)
18 | * 按1或2或3或4选择自瞄模式(图像预测尺寸递增,预测速度递减)
19 | * 等待游戏窗口成为当前活动窗口(点击一下游戏窗口即可)
20 | * 脚本正常工作时桌面左上角会显示截屏识别区域小视频
21 | * 按"1"/"2"键保持自瞄状态并控制鼠标
22 | * 按"3"/"4"键保持自瞄状态但不控制鼠标
23 | * 按"p"键重启程序
24 | * 按"END"结束程序
25 | * 自瞄只截屏识别准星附近区域,对于16:9的CF游戏窗口识别区域大小为(高=游戏窗口高*1/2,宽=高*4/3)
26 | * 本程序使用python语言以及自源码编译的opencv-cuda加速库
27 | * 本程序目前使用yolov4-tiny模型,只因其快(目前使用b站大佬[VeniVediVeci](https://space.bilibili.com/196421117)训练的权值)
28 | * 本程序很吃性能,使用前请先确认您的电脑配置: [GPU天梯1](http://cdn.malu.me/gpu/),[GPU天梯2](https://topic.expreview.com/GPU/)或[参考知乎](https://zhuanlan.zhihu.com/p/133845310)
29 | * 游戏截图器启动需要管理员权限,使需要被截图的窗口成为(当前)活动窗口,并在确认游戏窗口标题后点击"Yes";之后按"F8"键,听到声音提示并看到游戏窗口左上角的弹出式提示框即表明正在/停止自动截图
30 | * 游戏截图器也可以单独截图,按下鼠标前进/后退键或者按住"1"的同时按下鼠标左键进行单独截图
31 | * 当不需要游戏截图器工作时,直接退出游戏或者按一下"F8"键直到左上角的弹出式提示框消失,之后去托盘图标处右键点击Exit退出截图程序
32 | * 提供的截图程序将截取游戏窗口的指定区域且保存为bmp格式并以简单算法命名文件
33 | * 提供的转换工具将随机改变截图创建以及修改时间达到略微保护隐私的效果,保存格式为png
34 | * 提供的转换工具也会将从CF窗口截取的4:3拉升画面转换为1:1比例
35 | * 提供的空白标注文件生成工具会将指定目录下的图片文件名保存到train.txt,并对未标注的图片生成相应空白标注文件
36 |
--------------------------------------------------------------------------------
/aimbot-exec/now/调用罗技/ghub_mouse.cpp:
--------------------------------------------------------------------------------
1 | //fork from https://github.com/ekknod/logitech-cve
2 | #include "ghub_mouse.h"
3 | #include "pch.h"
4 | #include
5 | #include
6 | #include
7 | #pragma comment(lib, "ntdll.lib")
8 |
9 | typedef struct {
10 | char button;
11 | char x;
12 | char y;
13 | char wheel;
14 | char unk1;
15 | } MOUSE_IO;
16 |
17 |
18 | static HANDLE g_input;
19 | static IO_STATUS_BLOCK g_io;
20 |
21 | BOOL g_found_mouse;
22 |
23 |
24 | static BOOL callmouse(MOUSE_IO* buffer)
25 | {
26 | IO_STATUS_BLOCK block;
27 | return NtDeviceIoControlFile(g_input, 0, 0, 0, &block, 0x2a2010, buffer, sizeof(MOUSE_IO), 0, 0) == 0L;
28 | }
29 |
30 |
31 | static NTSTATUS device_initialize(PCWSTR device_name)
32 | {
33 | UNICODE_STRING name;
34 | OBJECT_ATTRIBUTES attr;
35 |
36 | RtlInitUnicodeString(&name, device_name);
37 | InitializeObjectAttributes(&attr, &name, 0, NULL, NULL);
38 |
39 | NTSTATUS status = NtCreateFile(&g_input, GENERIC_WRITE | SYNCHRONIZE, &attr, &g_io, 0,
40 | FILE_ATTRIBUTE_NORMAL, 0, 3, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
41 |
42 | return status;
43 | }
44 |
45 |
46 | BOOL Agulll() // mouse_open
47 | {
48 | NTSTATUS status = 0;
49 |
50 | if (g_input == 0) {
51 |
52 | wchar_t buffer0[] = L"\\??\\ROOT#SYSTEM#0002#{1abc05c0-c378-41b9-9cef-df1aba82b015}";
53 |
54 | status = device_initialize(buffer0);
55 | if (NT_SUCCESS(status))
56 | g_found_mouse = 1;
57 | else {
58 | wchar_t buffer1[] = L"\\??\\ROOT#SYSTEM#0001#{1abc05c0-c378-41b9-9cef-df1aba82b015}";
59 | status = device_initialize(buffer1);
60 | if (NT_SUCCESS(status))
61 | g_found_mouse = 1;
62 | }
63 | }
64 | return status == 0;
65 | }
66 |
67 |
68 | void Shwaji() // mouse_close
69 | {
70 | if (g_input != 0) {
71 | NtClose(g_input); //ZwClose
72 | g_input = 0;
73 | }
74 | }
75 |
76 |
77 | void Check(char button, char x, char y, char wheel) // mouse_move
78 | {
79 | MOUSE_IO io;
80 | io.unk1 = 0;
81 | io.button = button;
82 | io.x = x;
83 | io.y = y;
84 | io.wheel = wheel;
85 |
86 | if (!callmouse(&io)) {
87 | Shwaji(); // mouse_close
88 | Agulll(); // mouse_open
89 | }
90 | }
91 |
92 |
93 | void Mach_Move(int x, int y) // moveR
94 | {
95 | if (abs(x) > 127 || abs(y) > 127) {
96 | int x_left = x; int y_left = y;
97 | if (abs(x) > 127) {
98 | Check(0, int(x / abs(x)) * 127, 0, 0);
99 | x_left = x - int(x / abs(x)) * 127;
100 | }
101 | else { Check(0, int(x), 0, 0); x_left = 0; }
102 |
103 | if (abs(y) > 127) {
104 | Check(0, 0, int(y / abs(y)) * 127, 0);
105 | y_left = y - int(y / abs(y)) * 127;
106 | }
107 | else { Check(0, 0, int(y), 0); y_left = 0; }
108 |
109 | return Mach_Move(x_left, y_left);
110 | }
111 | else { Check(0, x, y, 0); }
112 | }
113 |
114 |
115 | void Leo_Kick(char button) // press
116 | {
117 | Check(button, 0, 0, 0);
118 | }
119 |
120 |
121 | void Niman_years() // release
122 | {
123 | Check(0, 0, 0, 0);
124 | }
125 |
126 |
127 | void Mebiuspin(char wheel) // scroll
128 | {
129 | Check(0, 0, 0, -wheel); //向下为正
130 | }
131 |
--------------------------------------------------------------------------------
/aimbot-exec/test_mouse_move.py:
--------------------------------------------------------------------------------
1 | from win32con import SPI_GETMOUSE, SPI_SETMOUSE, SPI_GETMOUSESPEED, SPI_SETMOUSESPEED, MOUSEEVENTF_MOVE, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP
2 | from win32api import mouse_event
3 | from sys import exit, executable
4 | from keyboard import is_pressed
5 | from time import sleep, time
6 | from mss import mss, tools
7 | from ctypes import windll
8 | import pywintypes
9 | import win32gui
10 | import os
11 |
12 |
13 | def restart():
14 | windll.shell32.ShellExecuteW(None, 'runas', executable, __file__, None, 1)
15 | exit(0)
16 |
17 |
18 | def is_admin():
19 | try:
20 | return windll.shell32.IsUserAnAdmin()
21 | except OSError as err:
22 | print('OS error: {0}'.format(err))
23 | return False
24 |
25 |
26 | def mouse_move_lr(num):
27 | DPI_Var = windll.user32.GetDpiForWindow(hwnd) / 96
28 | enhanced_holdback = win32gui.SystemParametersInfo(SPI_GETMOUSE)
29 | if enhanced_holdback[1]:
30 | win32gui.SystemParametersInfo(SPI_SETMOUSE, [0, 0, 0], 0)
31 | mouse_speed = win32gui.SystemParametersInfo(SPI_GETMOUSESPEED)
32 | if mouse_speed != 10:
33 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, 10, 0)
34 |
35 | mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
36 | mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
37 | sleep(0.3)
38 | for i in range(20):
39 | mouse_event(MOUSEEVENTF_MOVE, int(num/DPI_Var), 0, 0, 0)
40 | sleep(0.2)
41 | mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
42 | mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
43 | sleep(0.3)
44 | mouse_event(MOUSEEVENTF_MOVE, -int(num*10/DPI_Var), 0, 0, 0)
45 | sleep(0.3)
46 |
47 | if enhanced_holdback[1]:
48 | win32gui.SystemParametersInfo(SPI_SETMOUSE, enhanced_holdback, 0)
49 | if mouse_speed != 10:
50 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, mouse_speed, 0)
51 |
52 |
53 | os.chdir(os.path.dirname(os.path.abspath(__file__)))
54 | find_window = 0
55 |
56 | if not is_admin():
57 | restart()
58 |
59 | while not find_window:
60 | sleep(3)
61 | hwnd_active = win32gui.GetForegroundWindow()
62 | try:
63 | title_name = win32gui.GetWindowText(hwnd_active)
64 | class_name = win32gui.GetClassName(hwnd_active)
65 | result = windll.user32.MessageBoxW(0, title_name, 'Is this the window you want?', 4)
66 | find_window = (1 if result == 6 else 0)
67 | except pywintypes.error:
68 | continue
69 |
70 | with mss() as sct:
71 | hwnd = win32gui.FindWindow(class_name, None)
72 | client_rect = win32gui.GetClientRect(hwnd)
73 | corner_xy = win32gui.ClientToScreen(hwnd, (0, 0))
74 | monitor = {'top': corner_xy[1], 'left': corner_xy[0], 'width': client_rect[2] - client_rect[0], 'height': client_rect[3] - client_rect[1]}
75 | print('Get start!!! ' + class_name)
76 | moved = 0
77 | while True:
78 | sleep(0.1)
79 | if is_pressed('left'):
80 | mouse_move_lr(-5)
81 | moved = 1
82 | elif is_pressed('right'):
83 | mouse_move_lr(5)
84 | moved = 1
85 | if moved:
86 | sct_img = sct.grab(monitor)
87 | output = 'sct-{top}x{left}_{width}x{height}'.format(**monitor) + f'_{time()}.png'
88 | tools.to_png(sct_img.rgb, sct_img.size, output=output)
89 | moved = 0
90 | if is_pressed('end'):
91 | break
92 |
93 | exit(0)
--------------------------------------------------------------------------------
/yolov4-tiny/yolov4-tiny-custom.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | #batch=1
4 | #subdivisions=1
5 | # Training
6 | batch=64
7 | subdivisions=8
8 | width=512
9 | height=288
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.00261
19 | burn_in=1000
20 | max_batches = 6000
21 | policy=steps
22 | steps=4800,5400
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=32
28 | size=3
29 | stride=2
30 | pad=1
31 | activation=leaky
32 |
33 | [convolutional]
34 | batch_normalize=1
35 | filters=64
36 | size=3
37 | stride=2
38 | pad=1
39 | activation=leaky
40 |
41 | [convolutional]
42 | batch_normalize=1
43 | filters=64
44 | size=3
45 | stride=1
46 | pad=1
47 | activation=leaky
48 |
49 | [route]
50 | layers=-1
51 | groups=2
52 | group_id=1
53 |
54 | [convolutional]
55 | batch_normalize=1
56 | filters=32
57 | size=3
58 | stride=1
59 | pad=1
60 | activation=leaky
61 |
62 | [convolutional]
63 | batch_normalize=1
64 | filters=32
65 | size=3
66 | stride=1
67 | pad=1
68 | activation=leaky
69 |
70 | [route]
71 | layers = -1,-2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=64
76 | size=1
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [route]
82 | layers = -6,-1
83 |
84 | [maxpool]
85 | size=2
86 | stride=2
87 |
88 | [convolutional]
89 | batch_normalize=1
90 | filters=128
91 | size=3
92 | stride=1
93 | pad=1
94 | activation=leaky
95 |
96 | [route]
97 | layers=-1
98 | groups=2
99 | group_id=1
100 |
101 | [convolutional]
102 | batch_normalize=1
103 | filters=64
104 | size=3
105 | stride=1
106 | pad=1
107 | activation=leaky
108 |
109 | [convolutional]
110 | batch_normalize=1
111 | filters=64
112 | size=3
113 | stride=1
114 | pad=1
115 | activation=leaky
116 |
117 | [route]
118 | layers = -1,-2
119 |
120 | [convolutional]
121 | batch_normalize=1
122 | filters=128
123 | size=1
124 | stride=1
125 | pad=1
126 | activation=leaky
127 |
128 | [route]
129 | layers = -6,-1
130 |
131 | [maxpool]
132 | size=2
133 | stride=2
134 |
135 | [convolutional]
136 | batch_normalize=1
137 | filters=256
138 | size=3
139 | stride=1
140 | pad=1
141 | activation=leaky
142 |
143 | [route]
144 | layers=-1
145 | groups=2
146 | group_id=1
147 |
148 | [convolutional]
149 | batch_normalize=1
150 | filters=128
151 | size=3
152 | stride=1
153 | pad=1
154 | activation=leaky
155 |
156 | [convolutional]
157 | batch_normalize=1
158 | filters=128
159 | size=3
160 | stride=1
161 | pad=1
162 | activation=leaky
163 |
164 | [route]
165 | layers = -1,-2
166 |
167 | [convolutional]
168 | batch_normalize=1
169 | filters=256
170 | size=1
171 | stride=1
172 | pad=1
173 | activation=leaky
174 |
175 | [route]
176 | layers = -6,-1
177 |
178 | [maxpool]
179 | size=2
180 | stride=2
181 |
182 | [convolutional]
183 | batch_normalize=1
184 | filters=512
185 | size=3
186 | stride=1
187 | pad=1
188 | activation=leaky
189 |
190 | ##################################
191 |
192 | [convolutional]
193 | batch_normalize=1
194 | filters=256
195 | size=1
196 | stride=1
197 | pad=1
198 | activation=leaky
199 |
200 | [convolutional]
201 | batch_normalize=1
202 | filters=512
203 | size=3
204 | stride=1
205 | pad=1
206 | activation=leaky
207 |
208 | [convolutional]
209 | size=1
210 | stride=1
211 | pad=1
212 | filters=21
213 | activation=linear
214 |
215 |
216 |
217 | [yolo]
218 | mask = 3,4,5
219 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
220 | classes=2
221 | num=6
222 | jitter=.3
223 | scale_x_y = 1.05
224 | cls_normalizer=1.0
225 | iou_normalizer=0.07
226 | iou_loss=ciou
227 | ignore_thresh = .7
228 | truth_thresh = 1
229 | random=0
230 | resize=1.5
231 | nms_kind=greedynms
232 | beta_nms=0.6
233 |
234 | [route]
235 | layers = -4
236 |
237 | [convolutional]
238 | batch_normalize=1
239 | filters=128
240 | size=1
241 | stride=1
242 | pad=1
243 | activation=leaky
244 |
245 | [upsample]
246 | stride=2
247 |
248 | [route]
249 | layers = -1, 23
250 |
251 | [convolutional]
252 | batch_normalize=1
253 | filters=256
254 | size=3
255 | stride=1
256 | pad=1
257 | activation=leaky
258 |
259 | [convolutional]
260 | size=1
261 | stride=1
262 | pad=1
263 | filters=21
264 | activation=linear
265 |
266 | [yolo]
267 | mask = 0,1,2
268 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
269 | classes=2
270 | num=6
271 | jitter=.3
272 | scale_x_y = 1.05
273 | cls_normalizer=1.0
274 | iou_normalizer=0.07
275 | iou_loss=ciou
276 | ignore_thresh = .7
277 | truth_thresh = 1
278 | random=0
279 | resize=1.5
280 | nms_kind=greedynms
281 | beta_nms=0.6
--------------------------------------------------------------------------------
/aimbot-exec/now/darknet_yolo34.py:
--------------------------------------------------------------------------------
1 | from two_class_threat import threat_handling
2 | from math import sqrt, pow
3 | from util import check_gpu
4 | import numpy as np
5 | import win32gui
6 | import cv2
7 |
8 |
9 | # 分析类
10 | class FrameDetection34:
11 | # 类属性
12 | side_width, side_height = 288, 352 # 512, 320 # 输入尺寸
13 | conf_thd = 0.5 # 置信度阀值
14 | nms_thd = 0.3 # 非极大值抑制
15 | win_class_name = None # 窗口类名
16 | class_names = None # 检测类名
17 | total_classes = 1 # 模型类数量
18 | CONFIG_FILE, WEIGHT_FILE = ['./'], ['./']
19 | COLORS = []
20 | model, net = None, None # 建立模型, 建立网络
21 | errors = 0 # 仅仅显示一次错误
22 |
23 | # 构造函数
24 | def __init__(self, hwnd_value):
25 | self.win_class_name = win32gui.GetClassName(hwnd_value)
26 | self.nms_thd = {
27 | 'Valve001': 0.45,
28 | 'CrossFire': 0.45,
29 | }.get(self.win_class_name, 0.45)
30 |
31 | load_file('yolov4-tiny', self.CONFIG_FILE, self.WEIGHT_FILE)
32 | self.net = cv2.dnn.readNet(self.CONFIG_FILE[0], self.WEIGHT_FILE[0]) # 读取权重与配置文件
33 | self.model = cv2.dnn_DetectionModel(self.net)
34 | self.model.setInputParams(size=(self.side_width, self.side_height), scale=1/255, swapRB=False)
35 | try:
36 | with open('classes.txt', 'r') as f:
37 | self.class_names = [cname.strip() for cname in f.readlines()]
38 | except FileNotFoundError:
39 | self.class_names = ['human-head', 'human-body']
40 | for i in range(len(self.class_names)):
41 | self.COLORS.append(tuple(np.random.randint(256, size=3).tolist()))
42 |
43 | # 检测并设置在GPU上运行图像识别
44 | if cv2.cuda.getCudaEnabledDeviceCount():
45 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
46 | gpu_eval = check_gpu()
47 | # self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16) # 似乎需要模型支持半精度浮点
48 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
49 | gpu_message = {
50 | 2: '小伙电脑顶呱呱啊',
51 | 1: '战斗完全木得问题',
52 | }.get(gpu_eval, '您的显卡配置不够')
53 | print(gpu_message)
54 | else:
55 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT)
56 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
57 | print('您没有可识别的N卡')
58 |
59 | def detect(self, frames, recoil_coty, windoww = 1600):
60 | try:
61 | if frames.any():
62 | frame_height, frame_width = frames.shape[:2]
63 | frame_height += 0
64 | frame_width += 0
65 | except (cv2.error, AttributeError, UnboundLocalError) as e:
66 | if self.errors < 2:
67 | print(str(e))
68 | self.errors += 1
69 | return 0, 0, 0, 0, 0, frames
70 |
71 | # 检测
72 | classes, scores, boxes = self.model.detect(frames, self.conf_thd, self.nms_thd)
73 | threat_list = []
74 |
75 | # 画框
76 | for (classid, score, box) in zip(classes, scores, boxes):
77 | color = self.COLORS[int(classid) % len(self.COLORS)]
78 | label = self.class_names[classid[0]] + ': ' + str(round(score[0], 3))
79 | x, y, w, h = box
80 | cv2.rectangle(frames, (x, y), (x + w, y + h), color, 2)
81 | cv2.putText(frames, label, (int(x + w/2 - 4*len(label)), int(y + h/2 - 8)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)
82 | if classid == self.total_classes:
83 | self.total_classes += 1
84 |
85 | # 计算威胁指数(正面画框面积的平方根除以鼠标移动到目标距离)
86 | h_factor = (0.5 if w >= h or (self.total_classes > 1 and classid == 0) else 0.25)
87 | dist = sqrt(pow(frame_width / 2 - (x + w / 2), 2) + pow(frame_height / 2 - (y + h * h_factor), 2))
88 | threat_var = -(pow(w * h, 1/2) / dist * score if dist else 9999)
89 | if classid == 0:
90 | threat_var *= 6
91 | threat_list.append([threat_var, box, classid])
92 |
93 | x0, y0, fire_pos, fire_close, fire_ok, frames = threat_handling(frames, windoww, threat_list, recoil_coty, frame_height, frame_width, self.total_classes)
94 |
95 | return len(threat_list), int(x0), int(y0), fire_pos, fire_close, fire_ok, frames
96 |
97 |
98 | # 加载配置与权重文件
99 | def load_file(file, config_filename, weight_filename):
100 | cfg_filename = file + '.cfg'
101 | weights_filename = file + '.weights'
102 | config_filename[0] += cfg_filename
103 | weight_filename[0] += weights_filename
104 | return
105 |
--------------------------------------------------------------------------------
/aimbot-exec/now/scrnshot.py:
--------------------------------------------------------------------------------
1 | from win32con import SRCCOPY
2 | from ctypes import windll
3 | import numpy as np
4 | import pywintypes
5 | import win32gui
6 | import win32ui
7 | import mss
8 |
9 |
10 | class WindowCapture: # 截图类
11 | # 类属性
12 | hwnd, outerhwnd = None, None # 窗口句柄
13 | windows_class = None # 窗口类名
14 | ratio_h2H, ratio_w2h = 1, 1 # 截图比例(高对于窗口高,宽对于高)
15 | total_w, total_h = 0, 0 # 窗口内宽高
16 | cut_w, cut_h = 0, 0 # 截取宽高
17 | offset_x, offset_y = 0, 0 # 窗口内偏移x,y
18 | actual_x, actual_y = 0, 0 # 截图左上角屏幕位置x,y
19 | left_corner = [0, 0] # 窗口左上角屏幕位置
20 | errors = 0 # 仅仅显示一次错误
21 | sct = mss.mss() # mss截图初始化
22 | wDC, dcObj, cDC = None, None, None
23 |
24 | # 构造函数
25 | def __init__(self, window_class, window_hwnd, h2H = 4/9, w2h = 1.6):
26 | self.windows_class = window_class
27 | self.ratio_h2H, self.ratio_w2h = h2H, w2h
28 | self.hwnd = window_hwnd
29 | try:
30 | self.outerhwnd = win32gui.FindWindow(window_class, None)
31 | except pywintypes.error as e:
32 | print('找窗口错误\n' + str(e))
33 | if not self.hwnd:
34 | raise Exception(f'窗口类名未找到: {window_class}')
35 | self.update_window_info()
36 | self.wDC = win32gui.GetWindowDC(self.hwnd)
37 | self.dcObj = win32ui.CreateDCFromHandle(self.wDC)
38 | self.cDC = self.dcObj.CreateCompatibleDC()
39 |
40 | def update_window_info(self):
41 | try:
42 | # 获取窗口数据
43 | window_rect = win32gui.GetWindowRect(self.hwnd)
44 | client_rect = win32gui.GetClientRect(self.hwnd)
45 | self.left_corner = win32gui.ClientToScreen(self.hwnd, (0, 0))
46 |
47 | # 确认截图相关数据
48 | self.total_w = client_rect[2] - client_rect[0]
49 | self.total_h = client_rect[3] - client_rect[1]
50 | self.cut_h = int(self.total_h * self.ratio_h2H)
51 | self.cut_w = int(self.cut_h * self.ratio_w2h)
52 |
53 | if (self.cut_w > min(self.total_w, windll.user32.GetSystemMetrics(0))) or (self.cut_h > min(self.total_h, windll.user32.GetSystemMetrics(1))):
54 | raise Exception(f'这宽高不行: {self.cut_w} {self.cut_h}')
55 |
56 | self.offset_x = (self.total_w - self.cut_w) // 2 + self.left_corner[0] - window_rect[0]
57 | self.offset_y = (self.total_h - self.cut_h) // 2 + self.left_corner[1] - window_rect[1]
58 | self.actual_x = window_rect[0] + self.offset_x
59 | self.actual_y = window_rect[1] + self.offset_y
60 | except pywintypes.error as e:
61 | if self.errors < 2:
62 | print('获取窗口数据错误\n' + str(e))
63 | self.errors += 1
64 | pass
65 |
66 | def get_screenshot(self): # 只能在windows上使用,画面无法被遮蔽
67 | self.update_window_info()
68 | try:
69 | dataBitMap = win32ui.CreateBitmap()
70 | dataBitMap.CreateCompatibleBitmap(self.dcObj, self.cut_w, self.cut_h)
71 | self.cDC.SelectObject(dataBitMap)
72 | self.cDC.BitBlt((0, 0), (self.cut_w, self.cut_h), self.dcObj, (self.offset_x, self.offset_y), SRCCOPY)
73 |
74 | # 转换使得opencv可读
75 | signedIntsArray = dataBitMap.GetBitmapBits(True)
76 | cut_img = np.frombuffer(signedIntsArray, dtype='uint8')
77 | cut_img.shape = (self.cut_h, self.cut_w, 4)
78 | cut_img = cut_img[..., :3] # 去除alpha
79 | cut_img = np.ascontiguousarray(cut_img) # 转换减少错误
80 |
81 | win32gui.DeleteObject(dataBitMap.GetHandle()) # 释放资源
82 | return cut_img
83 | except (pywintypes.error, win32ui.error, ValueError) as e:
84 | print('截图出错\n' + str(e))
85 | return None
86 |
87 | def get_window_info(self):
88 | return self.total_w, self.total_h
89 |
90 | def get_cut_info(self):
91 | return self.cut_w, self.cut_h
92 |
93 | def get_actual_xy(self):
94 | return self.actual_x, self.actual_y
95 |
96 | def get_window_left(self):
97 | return win32gui.GetWindowRect(self.outerhwnd)[0]
98 |
99 | def get_side_len(self):
100 | return int(self.total_h * (2/3))
101 |
102 | def get_region(self):
103 | self.update_window_info()
104 | return (self.actual_x, self.actual_y, self.actual_x + self.cut_w, self.actual_y + self.cut_h)
105 |
106 | def grab_screenshot(self):
107 | scrnshot = np.array(self.sct.grab(self.get_region()), dtype=np.uint8)[..., :3]
108 | return np.ascontiguousarray(scrnshot)
109 |
110 | def release_resource(self):
111 | self.wDC, self.dcObj, self.cDC = None, None, None
112 |
--------------------------------------------------------------------------------
/aimbot-exec/now/mouse.py:
--------------------------------------------------------------------------------
1 | from ctypes import CDLL, c_int, c_int64
2 | from os import path
3 |
4 |
5 | basedir = path.dirname(path.abspath(__file__))
6 | ghubdlldir = path.join(basedir, 'ghub_mouse.dll')
7 | msdkdlldir = path.join(basedir, 'msdk.dll')
8 |
9 | # ↓↓↓↓↓↓↓↓↓ 调用ghub/键鼠驱动 ↓↓↓↓↓↓↓↓↓
10 |
11 | gm = CDLL(ghubdlldir)
12 | gmok = gm.Agulll()
13 |
14 | msdk = CDLL(msdkdlldir)
15 | M_Open = msdk.M_Open
16 | M_Open.argtypes = [c_int]
17 | M_Open.restype = c_int64
18 | msdk_hdl = M_Open(1)
19 | msdkok = 1 if msdk_hdl else 0
20 |
21 | if msdkok:
22 | M_LeftDown = msdk.M_LeftDown
23 | M_LeftDown.restype = c_int
24 | M_LeftDown.argtypes = [c_int64]
25 |
26 | M_RightDown = msdk.M_RightDown
27 | M_RightDown.restype = c_int
28 | M_RightDown.argtypes = [c_int64]
29 |
30 | M_LeftUp = msdk.M_LeftUp
31 | M_LeftUp.restype = c_int
32 | M_LeftUp.argtypes = [c_int64]
33 |
34 | M_RightUp = msdk.M_RightUp
35 | M_RightUp.restype = c_int
36 | M_RightUp.argtypes = [c_int64]
37 |
38 | M_MoveR = msdk.M_MoveR
39 | M_MoveR.restype = c_int
40 | M_MoveR.argtypes = [c_int64, c_int, c_int]
41 |
42 | M_MouseWheel = msdk.M_MouseWheel
43 | M_MouseWheel.restype = c_int
44 | M_MouseWheel.argtypes = [c_int64, c_int]
45 |
46 | M_KeyDown2 = msdk.M_KeyDown2
47 | M_KeyDown2.restype = c_int
48 | M_KeyDown2.argtypes = [c_int64, c_int]
49 |
50 | M_KeyUp2 = msdk.M_KeyUp2
51 | M_KeyUp2.restype = c_int
52 | M_KeyUp2.argtypes = [c_int64, c_int]
53 |
54 | M_Close = msdk.M_Close
55 | M_Close.restype = c_int
56 | M_Close.argtypes = [c_int64]
57 |
58 |
59 | def mouse_xy(x, y):
60 | if gmok:
61 | return gm.Mach_Move(int(x), int(y))
62 | elif msdkok:
63 | return M_MoveR(msdk_hdl, int(x), int(y))
64 |
65 |
66 | def mouse_down(key = 1):
67 | if gmok:
68 | return gm.Leo_Kick(int(key))
69 | elif msdkok:
70 | if key == 1:
71 | return M_LeftDown(msdk_hdl)
72 | elif key == 2:
73 | return M_RightDown(msdk_hdl)
74 |
75 |
76 | def mouse_up(key = 1):
77 | if gmok:
78 | return gm.Niman_years()
79 | elif msdkok:
80 | if key == 1:
81 | return M_LeftUp(msdk_hdl)
82 | elif key == 2:
83 | return M_RightUp(msdk_hdl)
84 |
85 |
86 | def scroll(num = 1):
87 | if gmok:
88 | return gm.Mebiuspin(int(num))
89 | elif msdkok:
90 | return M_MouseWheel(msdk_hdl, -int(num))
91 |
92 |
93 | def mouse_close():
94 | if gmok:
95 | return gm.Shwaji()
96 | elif msdkok:
97 | return M_Close(msdk_hdl)
98 |
99 |
100 | def key_down(key = 69):
101 | if msdkok:
102 | return M_KeyDown2(msdk_hdl, key)
103 |
104 |
105 | def key_up(key = 69):
106 | if msdkok:
107 | return M_KeyUp2(msdk_hdl, key)
108 |
109 | # ↑↑↑↑↑↑↑↑↑ 调用ghub/键鼠驱动 ↑↑↑↑↑↑↑↑↑
110 |
111 | """
112 | 键盘按键和键盘对应代码表:
113 | A <--------> 65 B <--------> 66 C <--------> 67 D <--------> 68
114 | E <--------> 69 F <--------> 70 G <--------> 71 H <--------> 72
115 | I <--------> 73 J <--------> 74 K <--------> 75 L <--------> 76
116 | M <--------> 77 N <--------> 78 O <--------> 79 P <--------> 80
117 | Q <--------> 81 R <--------> 82 S <--------> 83 T <--------> 84
118 | U <--------> 85 V <--------> 86 W <--------> 87 X <--------> 88
119 | Y <--------> 89 Z <--------> 90 0 <--------> 48 1 <--------> 49
120 | 2 <--------> 50 3 <--------> 51 4 <--------> 52 5 <--------> 53
121 | 6 <--------> 54 7 <--------> 55 8 <--------> 56 9 <--------> 57
122 | 数字键盘 1 <--------> 96 数字键盘 2 <--------> 97 数字键盘 3 <--------> 98
123 | 数字键盘 4 <--------> 99 数字键盘 5 <--------> 100 数字键盘 6 <--------> 101
124 | 数字键盘 7 <--------> 102 数字键盘 8 <--------> 103 数字键盘 9 <--------> 104
125 | 数字键盘 0 <--------> 105
126 | 乘号 <--------> 106 加号 <--------> 107 Enter <--------> 108 减号 <--------> 109
127 | 小数点 <--------> 110 除号 <--------> 111
128 | F1 <--------> 112 F2 <--------> 113 F3 <--------> 114 F4 <--------> 115
129 | F5 <--------> 116 F6 <--------> 117 F7 <--------> 118 F8 <--------> 119
130 | F9 <--------> 120 F10 <--------> 121 F11 <--------> 122 F12 <--------> 123
131 | F13 <--------> 124 F14 <--------> 125 F15 <--------> 126
132 | Backspace <--------> 8
133 | Tab <--------> 9
134 | Clear <--------> 12
135 | Enter <--------> 13
136 | Shift <--------> 16
137 | Control <--------> 17
138 | Alt <--------> 18
139 | Caps Lock <--------> 20
140 | Esc <--------> 27
141 | 空格键 <--------> 32
142 | Page Up <--------> 33
143 | Page Down <--------> 34
144 | End <--------> 35
145 | Home <--------> 36
146 | 左箭头 <--------> 37
147 | 向上箭头 <--------> 38
148 | 右箭头 <--------> 39
149 | 向下箭头 <--------> 40
150 | Insert <--------> 45
151 | Delete <--------> 46
152 | Help <--------> 47
153 | Num Lock <--------> 144
154 | ; : <--------> 186
155 | = + <--------> 187
156 | - _ <--------> 189
157 | / ? <--------> 191
158 | ` ~ <--------> 192
159 | [ { <--------> 219
160 | | <--------> 220
161 | ] } <--------> 221
162 | '' ' <--------> 222
163 | """
164 |
--------------------------------------------------------------------------------
/aimbot-exec/now/util.py:
--------------------------------------------------------------------------------
1 | from win32con import SPI_GETMOUSE, SPI_SETMOUSE, SPI_GETMOUSESPEED, SPI_SETMOUSESPEED
2 | from sys import exit, executable
3 | from platform import release
4 | from mouse import mouse_xy
5 | from ctypes import windll
6 | from os import system
7 | from math import atan
8 | import nvidia_smi
9 | import pywintypes
10 | import win32gui
11 | import pynvml
12 |
13 |
14 | # 预加载为睡眠函数做准备
15 | TimeBeginPeriod = windll.winmm.timeBeginPeriod
16 | HPSleep = windll.kernel32.Sleep
17 | TimeEndPeriod = windll.winmm.timeEndPeriod
18 |
19 |
20 | # 简单检查gpu是否够格
21 | def check_gpu():
22 | try:
23 | pynvml.nvmlInit()
24 | gpu_handle = pynvml.nvmlDeviceGetHandleByIndex(0) # 默认卡1
25 | gpu_name = pynvml.nvmlDeviceGetName(gpu_handle)
26 | memory_info = pynvml.nvmlDeviceGetMemoryInfo(gpu_handle)
27 | pynvml.nvmlShutdown()
28 | except FileNotFoundError as e:
29 | # pynvml.nvml.NVML_ERROR_LIBRARY_NOT_FOUND
30 | print(str(e))
31 | nvidia_smi.nvmlInit()
32 | gpu_handle = nvidia_smi.nvmlDeviceGetHandleByIndex(0) # 默认卡1
33 | gpu_name = nvidia_smi.nvmlDeviceGetName(gpu_handle)
34 | memory_info = nvidia_smi.nvmlDeviceGetMemoryInfo(gpu_handle)
35 | nvidia_smi.nvmlShutdown()
36 | if b'RTX' in gpu_name:
37 | return 2
38 | memory_total = memory_info.total / 1024 / 1024
39 | if memory_total > 3000:
40 | return 1
41 | return 0
42 |
43 |
44 | # 高DPI感知
45 | def set_dpi():
46 | if int(release()) >= 7:
47 | try:
48 | windll.shcore.SetProcessDpiAwareness(1)
49 | except AttributeError:
50 | windll.user32.SetProcessDPIAware()
51 | else:
52 | exit(0)
53 |
54 |
55 | # 检测是否全屏
56 | def is_full_screen(hWnd):
57 | try:
58 | full_screen_rect = (0, 0, windll.user32.GetSystemMetrics(0), windll.user32.GetSystemMetrics(1))
59 | window_rect = win32gui.GetWindowRect(hWnd)
60 | return window_rect == full_screen_rect
61 | except pywintypes.error as e:
62 | print('全屏检测错误\n' + str(e))
63 | return False
64 |
65 |
66 | # 检查是否为管理员权限
67 | def is_admin():
68 | try:
69 | return windll.shell32.IsUserAnAdmin()
70 | except OSError as err:
71 | print('OS error: {0}'.format(err))
72 | return False
73 |
74 |
75 | # 重启脚本
76 | def restart(file_path):
77 | windll.shell32.ShellExecuteW(None, 'runas', executable, file_path, None, 1)
78 | exit(0)
79 |
80 |
81 | # 清空命令指示符输出
82 | def clear():
83 | _ = system('cls')
84 |
85 |
86 | # 确认窗口句柄与类名
87 | def get_window_info():
88 | supported_games = 'Valve001 CrossFire LaunchUnrealUWindowsClient LaunchCombatUWindowsClient UnrealWindow UnityWndClass'
89 | test_window = 'Notepad3 PX_WINDOW_CLASS Notepad Notepad++'
90 | emulator_window = 'BS2CHINAUI Qt5154QWindowOwnDCIcon LSPlayerMainFrame TXGuiFoundation Qt5QWindowIcon LDPlayerMainFrame'
91 | class_name, hwnd_var = None, None
92 | testing_purpose = False
93 | while not hwnd_var: # 等待游戏窗口出现
94 | millisleep(3000)
95 | try:
96 | hwnd_active = win32gui.GetForegroundWindow()
97 | class_name = win32gui.GetClassName(hwnd_active)
98 | if class_name not in (supported_games + test_window + emulator_window):
99 | print('请使支持的游戏/程序窗口成为活动窗口...')
100 | continue
101 | else:
102 | outer_hwnd = hwnd_var = win32gui.FindWindow(class_name, None)
103 | if class_name in emulator_window:
104 | hwnd_var = win32gui.FindWindowEx(hwnd_var, None, None, None)
105 | elif class_name in test_window:
106 | testing_purpose = True
107 | print('已找到窗口')
108 | except pywintypes.error:
109 | print('您可能正使用沙盒,目前不支持沙盒使用')
110 | exit(0)
111 |
112 | return class_name, hwnd_var, outer_hwnd, testing_purpose
113 |
114 |
115 | # 比起python自带sleep稍微精准的睡眠
116 | def millisleep(num):
117 | TimeBeginPeriod(1)
118 | HPSleep(int(num)) # 减少报错
119 | TimeEndPeriod(1)
120 |
121 |
122 | # 移动鼠标
123 | def move_mouse(a, b):
124 | enhanced_holdback = win32gui.SystemParametersInfo(SPI_GETMOUSE)
125 | if enhanced_holdback[1]:
126 | win32gui.SystemParametersInfo(SPI_SETMOUSE, [0, 0, 0], 0)
127 | mouse_speed = win32gui.SystemParametersInfo(SPI_GETMOUSESPEED)
128 | if mouse_speed != 10:
129 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, 10, 0)
130 |
131 | mouse_xy(round(a), round(b))
132 |
133 | if enhanced_holdback[1]:
134 | win32gui.SystemParametersInfo(SPI_SETMOUSE, enhanced_holdback, 0)
135 | if mouse_speed != 10:
136 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, mouse_speed, 0)
137 |
138 |
139 | # 简易FOV计算
140 | def FOV(target_move, base_len):
141 | actual_move = atan(target_move/base_len) * base_len # 弧长
142 | return actual_move
143 |
144 |
145 | # 用户选择
146 | def use_choice(rangemin, rangemax, askstring):
147 | selection = -1
148 | while not (rangemax >= selection >= rangemin):
149 | user_choice = input(askstring)
150 | try:
151 | selection = int(user_choice)
152 | if not (rangemax >= selection >= rangemin):
153 | print('请在给定范围选择')
154 | except ValueError:
155 | print('呵呵...请重新输入')
156 |
157 | return selection
158 |
--------------------------------------------------------------------------------
/aimbot-exec/now/torch_yolox.py:
--------------------------------------------------------------------------------
1 | from two_class_threat import threat_handling
2 | from math import sqrt, pow
3 | from util import check_gpu
4 | from numba import njit
5 | import numpy as np
6 | import onnxruntime
7 | import win32gui
8 | import cv2
9 |
10 |
11 | # 分析类
12 | class FrameDetectionX:
13 | # 类属性
14 | std_confidence = 0.5 # 置信度阀值
15 | nms_thd = 0.3 # 非极大值抑制
16 | win_class_name = None # 窗口类名
17 | class_names = None # 检测类名
18 | total_classes = 1 # 模型类数量
19 | COLORS = []
20 | WEIGHT_FILE = ['./']
21 | input_shape = (224, 192) # 输入尺寸
22 | EP_list = onnxruntime.get_available_providers() # ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] Tensorrt优先于CUDA优先于CPU执行提供程序
23 | session, io_binding, device_name = None, None, None
24 | errors = 0 # 仅仅显示一次错误
25 |
26 | # 构造函数
27 | def __init__(self, hwnd_value):
28 | self.win_class_name = win32gui.GetClassName(hwnd_value)
29 | self.nms_thd = {
30 | 'Valve001': 0.45,
31 | 'CrossFire': 0.45,
32 | }.get(self.win_class_name, 0.45)
33 | load_file('yolox_tiny', self.WEIGHT_FILE)
34 |
35 | # 检测是否在GPU上运行图像识别
36 | self.device_name = onnxruntime.get_device()
37 | try:
38 | self.session = onnxruntime.InferenceSession(self.WEIGHT_FILE[0], None) # 推理构造
39 | except RuntimeError:
40 | self.session = onnxruntime.InferenceSession(self.WEIGHT_FILE[0], providers=['CPUExecutionProvider']) # 推理构造
41 | # self.session.set_providers('CPUExecutionProvider')
42 | self.device_name = 'CPU'
43 | if self.device_name == 'GPU':
44 | gpu_eval = check_gpu()
45 | gpu_message = {
46 | 2: '小伙电脑顶呱呱啊',
47 | 1: '战斗完全木得问题',
48 | }.get(gpu_eval, '您的显卡配置不够')
49 | print(gpu_message)
50 | else:
51 | print('中央处理器烧起来')
52 | print('PS:注意是否安装CUDA')
53 |
54 | self.io_binding = self.session.io_binding()
55 |
56 | try:
57 | with open('classes.txt', 'r') as f:
58 | self.class_names = [cname.strip() for cname in f.readlines()]
59 | except FileNotFoundError:
60 | self.class_names = ['human-head', 'human-body']
61 | for i in range(len(self.class_names)):
62 | self.COLORS.append(tuple(np.random.randint(256, size=3).tolist()))
63 |
64 | def detect(self, frames, recoil_coty, windoww = 1600):
65 | try:
66 | if frames.any():
67 | frame_height, frame_width = frames.shape[:2]
68 | frame_height += 0
69 | frame_width += 0
70 | except (cv2.error, AttributeError, UnboundLocalError) as e:
71 | if self.errors < 2:
72 | print(str(e))
73 | self.errors += 1
74 | return 0, 0, 0, 0, 0, frames
75 |
76 | # 预处理
77 | img, ratio = preprocess(frames, self.input_shape)
78 |
79 | # 检测
80 | if self.device_name == 'GPU':
81 | ortvalue = onnxruntime.OrtValue.ortvalue_from_numpy(img[None, :, :, :], 'cuda', 0)
82 | self.io_binding.bind_input(name=self.session.get_inputs()[0].name, device_type=ortvalue.device_name(), device_id=0, element_type=np.float32, shape=ortvalue.shape(), buffer_ptr=ortvalue.data_ptr())
83 | self.io_binding.bind_output('output')
84 | self.session.run_with_iobinding(self.io_binding)
85 | output = self.io_binding.copy_outputs_to_cpu()[0]
86 | else:
87 | ort_inputs = {self.session.get_inputs()[0].name: img[None, :, :, :]}
88 | output = self.session.run(None, ort_inputs)[0]
89 |
90 | predictions = demo_postprocess(output, self.input_shape)[0]
91 | boxes_xyxy, scores = analyze(predictions, ratio)
92 | dets = multiclass_nms(boxes_xyxy, scores, self.nms_thd, self.std_confidence)
93 |
94 | # 画框
95 | threat_list = []
96 | if not (dets is None):
97 | final_boxes, final_scores, final_cls_inds = dets[:, :4], dets[:, 4], dets[:, 5]
98 | for (box, final_score, final_cls_ind) in zip(final_boxes, final_scores, final_cls_inds):
99 | cv2.rectangle(frames, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), self.COLORS[0], 2)
100 | label = str(round(final_score, 3))
101 | x, y, w, h = box[0], box[1], box[2] - box[0], box[3] - box[1]
102 | cv2.putText(frames, label, (int(x + w/2 - 4*len(label)), int(y + h/2 - 8)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)
103 | if final_cls_ind == self.total_classes:
104 | self.total_classes += 1
105 |
106 | # 计算威胁指数(正面画框面积的平方根除以鼠标移动到目标距离)
107 | h_factor = (0.5 if w >= h or (self.total_classes > 1 and final_cls_ind == 0) else 0.25)
108 | dist = sqrt(pow(frame_width / 2 - (x + w / 2), 2) + pow(frame_height / 2 - (y + h * h_factor), 2))
109 | threat_var = -(pow(w * h, 1/2) / dist * final_score if dist else 9999)
110 | threat_list.append([threat_var, [x, y, w, h], final_cls_ind])
111 |
112 | x0, y0, fire_pos, fire_close, fire_ok, frames = threat_handling(frames, windoww, threat_list, recoil_coty, frame_height, frame_width, self.total_classes)
113 |
114 | return len(threat_list), int(x0), int(y0), fire_pos, fire_close, fire_ok, frames
115 |
116 |
117 | # 分析预测数据
118 | @njit(fastmath=True)
119 | def analyze(predictions, ratio):
120 | boxes = predictions[:, :4]
121 | scores = predictions[:, 4:5] * predictions[:, 5:]
122 |
123 | boxes_xyxy = np.ones_like(boxes)
124 | boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2]/2.
125 | boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3]/2.
126 | boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2]/2.
127 | boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3]/2.
128 | boxes_xyxy /= ratio
129 |
130 | return boxes_xyxy, scores
131 |
132 |
133 | # 从yolox复制的预处理函数
134 | def preprocess(img, input_size, swap=(2, 0, 1)):
135 | padded_img = np.ones((input_size[0], input_size[1], 3)) * 114
136 | r = min(input_size[0] / img.shape[0], input_size[1] / img.shape[1])
137 | resized_img = cv2.resize(img, (int(img.shape[1] * r), int(img.shape[0] * r)), interpolation=cv2.INTER_LINEAR).astype(np.float32)
138 | padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img
139 |
140 | padded_img = padded_img.transpose(swap)
141 | padded_img = np.ascontiguousarray(padded_img, dtype=np.float32)
142 | return padded_img, r
143 |
144 |
145 | # 从yolox复制的单类非极大值抑制函数
146 | @njit(fastmath=True)
147 | def nms(boxes, scores, nms_thr):
148 | """Single class NMS implemented in Numpy."""
149 | x1 = boxes[:, 0]
150 | y1 = boxes[:, 1]
151 | x2 = boxes[:, 2]
152 | y2 = boxes[:, 3]
153 |
154 | areas = (x2 - x1 + 1) * (y2 - y1 + 1)
155 | order = scores.argsort()[::-1]
156 |
157 | keep = []
158 | while order.size > 0:
159 | i = order[0]
160 | keep.append(i)
161 | xx1 = np.maximum(x1[i], x1[order[1:]])
162 | yy1 = np.maximum(y1[i], y1[order[1:]])
163 | xx2 = np.minimum(x2[i], x2[order[1:]])
164 | yy2 = np.minimum(y2[i], y2[order[1:]])
165 |
166 | w = np.maximum(0.0, xx2 - xx1 + 1)
167 | h = np.maximum(0.0, yy2 - yy1 + 1)
168 | inter = w * h
169 | ovr = inter / (areas[i] + areas[order[1:]] - inter)
170 |
171 | inds = np.where(ovr <= nms_thr)[0]
172 | order = order[inds + 1]
173 |
174 | return keep
175 |
176 |
177 | # 从yolox复制的多类非极大值抑制函数
178 | def multiclass_nms(boxes, scores, nms_thr, score_thr, class_agnostic=True):
179 | """Multiclass NMS implemented in Numpy"""
180 | if class_agnostic:
181 | nms_method = multiclass_nms_class_agnostic
182 | else:
183 | nms_method = multiclass_nms_class_aware
184 | return nms_method(boxes, scores, nms_thr, score_thr)
185 |
186 |
187 | # 从yolox复制的多类非极大值抑制函数(class-agnostic方式)
188 | def multiclass_nms_class_agnostic(boxes, scores, nms_thr, score_thr):
189 | """Multiclass NMS implemented in Numpy. Class-agnostic version."""
190 | cls_inds = scores.argmax(1)
191 | cls_scores = scores[np.arange(len(cls_inds)), cls_inds]
192 |
193 | valid_score_mask = cls_scores > score_thr
194 | if valid_score_mask.sum() == 0:
195 | return None
196 | valid_scores = cls_scores[valid_score_mask]
197 | valid_boxes = boxes[valid_score_mask]
198 | valid_cls_inds = cls_inds[valid_score_mask]
199 | keep = nms(valid_boxes, valid_scores, nms_thr)
200 | if keep:
201 | dets = np.concatenate(
202 | [valid_boxes[keep], valid_scores[keep, None], valid_cls_inds[keep, None]], 1
203 | )
204 | return dets
205 |
206 |
207 | # 从yolox复制的多类非极大值抑制函数(class-aware方式)
208 | def multiclass_nms_class_aware(boxes, scores, nms_thr, score_thr):
209 | """Multiclass NMS implemented in Numpy. Class-aware version."""
210 | final_dets = []
211 | num_classes = scores.shape[1]
212 | for cls_ind in range(num_classes):
213 | cls_scores = scores[:, cls_ind]
214 | valid_score_mask = cls_scores > score_thr
215 | if valid_score_mask.sum() == 0:
216 | continue
217 | else:
218 | valid_scores = cls_scores[valid_score_mask]
219 | valid_boxes = boxes[valid_score_mask]
220 | keep = nms(valid_boxes, valid_scores, nms_thr)
221 | if len(keep) > 0:
222 | cls_inds = np.ones((len(keep), 1)) * cls_ind
223 | dets = np.concatenate(
224 | [valid_boxes[keep], valid_scores[keep, None], cls_inds], 1
225 | )
226 | final_dets.append(dets)
227 | if len(final_dets) == 0:
228 | return None
229 | return np.concatenate(final_dets, 0)
230 |
231 |
232 | # 从yolox复制的后置处理函数
233 | def demo_postprocess(outputs, img_size, p6=False):
234 | grids = []
235 | expanded_strides = []
236 |
237 | if not p6:
238 | strides = [8, 16, 32]
239 | else:
240 | strides = [8, 16, 32, 64]
241 |
242 | hsizes = [img_size[0] // stride for stride in strides]
243 | wsizes = [img_size[1] // stride for stride in strides]
244 |
245 | for hsize, wsize, stride in zip(hsizes, wsizes, strides):
246 | xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize))
247 | grid = np.stack((xv, yv), 2).reshape(1, -1, 2)
248 | grids.append(grid)
249 | shape = grid.shape[:2]
250 | expanded_strides.append(np.full((*shape, 1), stride))
251 |
252 | grids = np.concatenate(grids, 1)
253 | expanded_strides = np.concatenate(expanded_strides, 1)
254 | outputs[..., :2] = (outputs[..., :2] + grids) * expanded_strides
255 | outputs[..., 2:4] = np.exp(outputs[..., 2:4]) * expanded_strides
256 |
257 | return outputs
258 |
259 |
260 | # 加载配置与权重文件
261 | def load_file(file, weight_filename):
262 | weights_filename = file + '.onnx'
263 | weight_filename[0] += weights_filename
264 | return
265 |
--------------------------------------------------------------------------------
/training_tools/Gen_PrtScn.ahk:
--------------------------------------------------------------------------------
1 | #include Gdip_All.ahk
2 | #NoEnv ;不检查空变量是否为环境变量
3 | ;#Warn ;(不)启用可能产生错误的特定状况时的警告
4 | #Persistent ;让脚本持久运行
5 | #MenuMaskKey, vkFF ;改变用来掩饰(屏蔽)Win或Alt松开事件的按键
6 | #MaxHotkeysPerInterval, 1000 ;与下行代码一起指定热键激活的速率(次数)
7 | #HotkeyInterval, 1000 ;与上一行代码一起指定热键激活的速率(时间)
8 | #SingleInstance, Force ;跳过对话框并自动替换旧实例
9 | #KeyHistory, 0 ;禁用按键历史
10 | ListLines, Off ;不显示最近执行的脚本行
11 | SendMode, Input ;使用更速度和可靠方式发送键鼠点击
12 | SetWorkingDir, %A_ScriptDir% ;保证一致的脚本起始工作目录
13 | Process, Priority, , A ;进程高优先级
14 | SetBatchLines, -1 ;全速运行,且因为全速运行,部分代码不得不调整
15 | ;==================================================================================
16 | PS_Service_On := False
17 | CheckPermission1()
18 | CheckWindow(win_class, win_title)
19 | MsgBox, %win_title% 出现!!!
20 | If Not InStr(FileExist("游戏截图\"win_class), "D")
21 | FileCreateDir, 游戏截图\%win_class%
22 | FileAppend, %win_title%, %A_ScriptDir%\游戏截图\%win_class%\游戏名称.txt, UTF-8
23 | global ReadyShot := True
24 | global CapSave := False
25 | global PrintedScn := 0
26 | global letters := "!@$%^-+=1234567890aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"
27 | CheckPosition1(BX, BY, BW, BH, win_class)
28 | boxh := Round(BH / 9 * 4)
29 | boxw := Round(boxh * 1.6)
30 | showx := BX + (BW - boxw) // 2 - 1
31 | showy := BY + (BH - boxh) // 2 - 1
32 | showw := boxw + 2
33 | showh := boxh + 2
34 | boundingbox := (Ceil(boxw/2) + 1)"-0 0-0 0-"(boxh+2)" "(boxw+2)"-"(boxh+2)" "(boxw+2)"-0 "(Ceil(boxw/2) + 1)"-0 "(Ceil(boxw/2) + 1)"-1 "(boxw+1)"-1 "(boxw+1)"-"(boxh+1)" 1-"(boxh+1)" 1-1 "(Ceil(boxw/2) + 1)"-1 " (Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1 - boxh//10)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1 - boxh//10)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 2 + boxh//10)" "(Ceil(boxw/2) + 2)"-"(Ceil(boxh/2) + 2 + boxh//10)" "(Ceil(boxw/2) + 2)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 2 + boxh//10)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 2 + boxh//10)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 1)
35 | Gui, box: New, +lastfound +ToolWindow -Caption +AlwaysOnTop +Hwndbb -DPIScale, cshp001
36 | Gui, box: Color, 00FFFF ;#00FFFF
37 | Gui, box: Show, x%showx% y%showy% w%showw% h%showh% NA
38 | WinSet, Region, %boundingbox%, ahk_id %bb%
39 | WinSet, Transparent, 225, ahk_id %bb%
40 | WinSet, ExStyle, +0x20 +0x8; 鼠标穿透以及最顶端
41 | PS_Service_On := True
42 | ;==================================================================================
43 | ~*End::ExitApp
44 |
45 | #If PS_Service_On ;以下的热键需要相应条件才能激活
46 |
47 | ~*RAlt::
48 | Gui, box: Show, Hide
49 | Return
50 |
51 | ~*RAlt Up::
52 | If !WinExist("ahk_class "win_class)
53 | ExitApp
54 | CheckPosition1(BX, BY, BW, BH, win_class)
55 | showx := BX + (BW - boxw) // 2 - 1
56 | showy := BY + (BH - boxh) // 2 - 1
57 | Gui, box: Show, x%showx% y%showy% w%showw% h%showh% NA
58 | Return
59 |
60 | #If PS_Service_On && WinActive("ahk_class "win_class) ;以下的热键需要相应条件才能激活
61 |
62 | ~*F8::
63 | SoundBeep, 1000, 300
64 | CapSave := !CapSave
65 | If CapSave
66 | {
67 | pToken := Gdip_Startup()
68 | SetTimer, ShotAndSave, 2000
69 | }
70 | Else
71 | {
72 | SetTimer, ShotAndSave, Off
73 | PrintedScn := 0
74 | HyperSleep(2000)
75 | Gdip_Shutdown(pToken)
76 | ToolTip, , , , 1
77 | }
78 | Return
79 |
80 | ~*LButton::
81 | ~*XButton1::
82 | ~*XButton2::
83 | If GetKeyState("LButton", "P") && !GetKeyState("1", "P")
84 | Return
85 | If ReadyShot
86 | {
87 | pToken := Gdip_Startup()
88 | ShotAndSave()
89 | ReadyShot := False
90 | }
91 | Return
92 |
93 | ~*LButton Up::
94 | ~*XButton1 Up::
95 | ~*XButton2 Up::
96 | Gdip_Shutdown(pToken)
97 | ReadyShot := True
98 | Return
99 |
100 | ~*Esc::
101 | ToolTip, , , , 1
102 | PrintedScn := 0
103 | Return
104 | ;==================================================================================
105 | ;找到并由使用者确认游戏窗口
106 | CheckWindow(ByRef ClassName, ByRef TitleName)
107 | {
108 | hwnd_id := 0
109 | confirmed := False
110 | Loop
111 | {
112 | HyperSleep(3000)
113 | hwnd_id := WinExist("A")
114 | WinGetClass, Class_Name, ahk_id %hwnd_id%
115 | WinGetTitle, Title_Name, ahk_class %Class_Name%
116 | MsgBox, 262148, 确认框/Confirm Box, %Title_Name% 是您需要的窗口标题吗?`nIs %Title_Name% the window title you want?
117 | IfMsgBox, Yes
118 | confirmed := True
119 | ClassName := Class_Name, TitleName := Title_Name
120 | } Until (confirmed && ClassName && TitleName)
121 | }
122 | ;==================================================================================
123 | ;重复截图
124 | ShotAndSave()
125 | {
126 | global win_class, boxw, boxh
127 | If !WinExist("ahk_class " . win_class)
128 | {
129 | MsgBox, 程序已退出/Program Exited
130 | ExitApp
131 | }
132 | CheckPosition1(PX, PY, PW, PH, win_class)
133 | PrintedScn += 1
134 | show_PrintedScn := SubStr("000" . PrintedScn, -2)
135 | ToolTip, 正在截图中:%PX%|%PY%|%PW%|%PH% 数量%show_PrintedScn%, PX, PY, 1
136 |
137 | cap_zoom := PX + (PW - boxw) // 2 . "|" . PY + (PH - boxh) // 2 . "|" . boxw . "|" . boxh
138 |
139 | randStr := SubStr("000000" . (A_TickCount / A_MSec), -5)
140 | loop, 12
141 | {
142 | Random, randChar, 0, strlen(letters) - 1
143 | randStr .= SubStr(letters, randChar, 1)
144 | }
145 | Screenshot(A_ScriptDir . "\游戏截图\" . win_class . "\SS_" . win_class . "_" . randStr . ".bmp", cap_zoom)
146 | }
147 | ;==================================================================================
148 | ;截图存图,screen: X|Y|W|H
149 | Screenshot(outfile, screen)
150 | {
151 | global pToken ;:= Gdip_Startup()
152 | pBitmap := Gdip_BitmapFromScreen(screen)
153 | Gdip_SaveBitmapToFile(pBitmap, outfile, 100)
154 | Gdip_DisposeImage(pBitmap)
155 | }
156 | ;==================================================================================
157 | ;检查脚本执行权限,只有以管理员权限或以UI Access运行才能正常工作
158 | CheckPermission1()
159 | {
160 | If A_OSVersion in WIN_NT4, WIN_95, WIN_98, WIN_ME, WIN_2000, WIN_2003, WIN_XP, WIN_VISTA ;检测操作系统版本
161 | {
162 | MsgBox, 262160, 错误/Error, 此辅助需要Win 7及以上操作系统!!!`nThis program requires Windows 7 or later!!!
163 | ExitApp
164 | }
165 |
166 | If !A_Is64bitOS ;检测操作系统是否为64位
167 | {
168 | MsgBox, 262160, 错误/Error, 此辅助需要64位操作系统!!!`nThis program requires 64-bit OS!!!
169 | ExitApp
170 | }
171 |
172 | If Not (CheckAdmin1() || CheckUIA1())
173 | {
174 | Try
175 | {
176 | If A_IsCompiled ;编译时请用加密减少侦测几率
177 | Run, *RunAs "%A_ScriptFullPath%" ;管理员权限运行
178 | Else
179 | {
180 | MsgBox, 262148, 警告/Warning, 请问你开启UIA了吗?`nDo you have UIAccess enabled?
181 | IfMsgBox Yes
182 | Run, "%A_ProgramFiles%\AutoHotkey\AutoHotkeyU64_UIA.exe" "%A_ScriptFullPath%"
183 | Else
184 | Run, *RunAs "%A_ScriptFullPath%"
185 | ExitApp
186 | }
187 | }
188 | Catch
189 | {
190 | MsgBox, 262160, 错误/Error, 未正确运行!辅助将退出!!`nUnable to start correctly!The program will exit!!
191 | ExitApp
192 | }
193 | }
194 | }
195 | ;==================================================================================
196 | ;检查脚本是否由管理员权限运行
197 | CheckAdmin1()
198 | {
199 | If A_IsAdmin
200 | Return True
201 | Return False
202 | }
203 | ;==================================================================================
204 | ;检查脚本是否由指定的UIA权限运行
205 | CheckUIA1()
206 | {
207 | process_id := ProcessInfo_GetCurrentProcessID()
208 | process_name := GetProcessName(process_id)
209 | If InStr(process_name, "AutoHotkeyU64_UIA.exe")
210 | Return True
211 | Return False
212 | }
213 | ;==================================================================================
214 | ;拷贝自 https://github.com/camerb/AHKs/blob/master/thirdParty/ProcessInfo.ahk ,检测脚本运行的进程ID
215 | ProcessInfo_GetCurrentProcessID()
216 | {
217 | Return DllCall("GetCurrentProcessId")
218 | }
219 | ;==================================================================================
220 | ;拷贝自 https://www.reddit.com/r/AutoHotkey/comments/6zftle/process_name_from_pid/ ,通过进程ID得到进程完整路径
221 | GetProcessName(ProcessID)
222 | {
223 | If (hProcess := DllCall("OpenProcess", "uint", 0x0410, "int", 0, "uint", ProcessID, "ptr"))
224 | {
225 | size := VarSetCapacity(buf, 0x0104 << 1, 0)
226 | If (DllCall("psapi\GetModuleFileNameEx", "ptr", hProcess, "ptr", 0, "ptr", &buf, "uint", size))
227 | Return StrGet(&buf), DllCall("CloseHandle", "ptr", hProcess)
228 | DllCall("CloseHandle", "ptr", hProcess)
229 | }
230 | Return False
231 | }
232 | ;==================================================================================
233 | ;检查游戏界面真正位置,不包括标题栏和边缘等等,既Client位置
234 | CheckPosition1(ByRef Xcp, ByRef Ycp, ByRef Wcp, ByRef Hcp, class_name)
235 | {
236 | WinGet, Win_ID, ID, ahk_class %class_name%
237 |
238 | VarSetCapacity(rect, 16)
239 | DllCall("GetClientRect", "ptr", Win_ID, "ptr", &rect) ;内在宽高
240 | Wcp := NumGet(rect, 8, "int")
241 | Hcp := NumGet(rect, 12, "int")
242 |
243 | VarSetCapacity(WINDOWINFO, 60, 0)
244 | DllCall("GetWindowInfo", "ptr", Win_ID, "ptr", &WINDOWINFO) ;内在XY
245 | Xcp := NumGet(WINDOWINFO, 20, "Int")
246 | Ycp := NumGet(WINDOWINFO, 24, "Int")
247 |
248 | VarSetCapacity(Screen_Info, 156)
249 | DllCall("EnumDisplaySettingsA", Ptr, 0, UInt, -1, UInt, &Screen_Info) ;真实分辨率
250 | Mon_Width := NumGet(Screen_Info, 108, "int")
251 | Mon_Hight := NumGet(Screen_Info, 112, "int")
252 |
253 | If (Wcp >= Mon_Width) || (Hcp >= Mon_Hight) ;全屏检测,未知是否适应UHD不放大
254 | {
255 | CoordMode, Pixel, Client ;坐标相对活动窗口的客户端
256 | CoordMode, Mouse, Client
257 | CoordMode, ToolTip, Client
258 | }
259 | Else
260 | {
261 | CoordMode, Pixel, Screen ;坐标相对全屏幕
262 | CoordMode, Mouse, Screen
263 | CoordMode, ToolTip, Screen
264 | }
265 | }
266 | ;==================================================================================
267 | ;学习自Bilibili用户开发的CSGO压枪脚本中的高精度时钟
268 | SystemTime()
269 | {
270 | freq := 0, tick := 0
271 | DllCall("QueryPerformanceFrequency", "Int64*", freq)
272 | DllCall("QueryPerformanceCounter", "Int64*", tick)
273 | Return tick / freq * 1000
274 | }
275 | ;==================================================================================
276 | ;学习自Bilibili用户开发的CSGO压枪脚本中的高精度睡眠
277 | HyperSleep(value)
278 | {
279 | s_begin_time := SystemTime()
280 | freq := 0, t_current := 0
281 | DllCall("QueryPerformanceFrequency", "Int64*", freq)
282 | s_end_time := (s_begin_time + value) * freq / 1000
283 | While, (t_current < s_end_time)
284 | {
285 | If (s_end_time - t_current) > 20000 ;大于二毫秒时不暴力轮询,以减少CPU占用
286 | {
287 | DllCall("Winmm.dll\timeBeginPeriod", UInt, 1)
288 | DllCall("Sleep", "UInt", 1)
289 | DllCall("Winmm.dll\timeEndPeriod", UInt, 1)
290 | ;以上三行代码为相对ahk自带sleep函数稍高精度的睡眠
291 | }
292 | DllCall("QueryPerformanceCounter", "Int64*", t_current)
293 | }
294 | }
295 | ;==================================================================================
296 |
--------------------------------------------------------------------------------
/aimbot-exec/now/AI_main.py:
--------------------------------------------------------------------------------
1 | from util import set_dpi, is_full_screen, is_admin, clear, restart, millisleep, get_window_info, FOV, use_choice, move_mouse
2 | from mouse import mouse_down, mouse_up, mouse_close, scroll, key_down, key_up, gmok, msdkok
3 | from win32api import GetAsyncKeyState, GetCurrentProcessId, OpenProcess, GetSystemMetrics
4 | from win32process import SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS
5 | from multiprocessing import Process, shared_memory, Array, Lock
6 | from win32con import VK_END, PROCESS_ALL_ACCESS
7 | from darknet_yolo34 import FrameDetection34
8 | from pynput.mouse import Listener, Button
9 | from torch_yolox import FrameDetectionX
10 | from scrnshot import WindowCapture
11 | from sys import exit, platform
12 | from collections import deque
13 | from statistics import median
14 | from time import time, sleep
15 | from math import sqrt, pow
16 | from simple_pid import PID
17 | from random import uniform
18 | from ctypes import windll
19 | import numpy as np
20 | import pywintypes
21 | import win32gui
22 | import bezier
23 | import cv2
24 | import os
25 |
26 |
27 | # 检测是否存在配置与权重文件
28 | def check_file(file):
29 | cfg_file = file + '.cfg'
30 | weights_file = file + '.weights'
31 | if not (os.path.isfile(cfg_file) and os.path.isfile(weights_file)):
32 | print(f'请下载{file}相关文件!!!')
33 | millisleep(3000)
34 | exit(0)
35 |
36 |
37 | # 加锁换值
38 | def change_withlock(arrays, var, target_var, locker):
39 | with locker:
40 | arrays[var] = target_var
41 |
42 |
43 | # 鼠标射击
44 | def click_mouse(win_class, rate, go_fire):
45 | # 不分敌友射击
46 | if arr[15]: # GetAsyncKeyState(VK_LBUTTON) < 0
47 | if time() * 1000 - arr[16] > 30.6: # press_moment
48 | mouse_up()
49 | elif win_class != 'CrossFire' or arr[13]:
50 | if arr[13] or go_fire:
51 | if time() * 1000 - arr[17] > rate: # release_moment
52 | mouse_down()
53 | change_withlock(arr, 18, arr[18] + 1, lock)
54 |
55 | if time() * 1000 - arr[17] > 219.4:
56 | change_withlock(arr, 18, 0, lock)
57 |
58 | if arr[18] > 12:
59 | change_withlock(arr, 18, 12, lock)
60 |
61 |
62 | # 转变状态
63 | def check_status(arr):
64 | if GetAsyncKeyState(VK_END) < 0: # End
65 | change_withlock(arr, 14, 1, lock)
66 | if GetAsyncKeyState(0x31) < 0: # 1
67 | change_withlock(arr, 6, 1, lock)
68 | if GetAsyncKeyState(0x32) < 0: # 2
69 | change_withlock(arr, 6, 2, lock)
70 | if GetAsyncKeyState(0x33) < 0 or GetAsyncKeyState(0x34) < 0: # 3,4
71 | change_withlock(arr, 6, 0, lock)
72 | change_withlock(arr, 18, 0, lock)
73 | if GetAsyncKeyState(0x46) < 0: # F恢复移动
74 | change_withlock(arr, 8, 1, lock)
75 | if GetAsyncKeyState(0x4A) < 0: # J停止移动
76 | change_withlock(arr, 8, 0, lock)
77 | if GetAsyncKeyState(0x12) < 0: # Alt恢复开火
78 | change_withlock(arr, 9, 1, lock)
79 | if GetAsyncKeyState(0x30) < 0: # 0停止开火
80 | change_withlock(arr, 9, 0, lock)
81 |
82 |
83 | # 多线程展示效果
84 | def show_frames(array):
85 | set_dpi()
86 | cv2.namedWindow('Show frame', cv2.WINDOW_KEEPRATIO)
87 | cv2.moveWindow('Show frame', 0, 0)
88 | cv2.destroyAllWindows()
89 | font = cv2.FONT_HERSHEY_SIMPLEX # 效果展示字体
90 | fire_target_show = ['middle', 'head', 'chest']
91 |
92 | while True: # 等待共享内存加载完毕
93 | try:
94 | existing_show_shm = shared_memory.SharedMemory(name='showimg')
95 | millisleep(1000)
96 | break
97 | except FileNotFoundError:
98 | millisleep(1000)
99 |
100 | while not array[14]:
101 | show_img = np.ndarray((int(array[0]), int(array[1]), 3), dtype=np.uint8, buffer=existing_show_shm.buf)
102 | show_color = {
103 | 0: (127, 127, 127),
104 | 1: (255, 255, 0),
105 | 2: (0, 255, 0)
106 | }.get(array[6])
107 | try:
108 | img_ex = np.zeros((1, 1, 3), np.uint8)
109 | show_str0 = str('{:03.1f}'.format(array[4]))
110 | show_str1 = 'Detected ' + str('{:02.0f}'.format(array[7])) + ' targets'
111 | show_str2 = 'Aiming at ' + fire_target_show[int(array[11])] + ' position'
112 | show_str3 = 'Fire rate is at ' + str('{:02.0f}'.format((1000 / (array[10] + 30.6)))) + ' RPS'
113 | show_str4 = 'Please enjoy coding ^_^' if array[8] else 'Please enjoy coding @_@'
114 | if show_img.any():
115 | show_img_h, show_img_w = show_img.shape[:2]
116 | show_img = cv2.resize(show_img, (int(array[3]), int(array[3] / show_img_w * show_img_h)))
117 | img_ex = cv2.resize(img_ex, (int(array[3]), int(array[3] / 2)))
118 | cv2.putText(show_img, show_str0, (int(array[3] / 25), int(array[3] / 12)), font, array[3] / 600, (127, 255, 0), 2, cv2.LINE_AA)
119 | cv2.putText(img_ex, show_str1, (10, int(array[3] / 9)), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
120 | cv2.putText(img_ex, show_str2, (10, int(array[3] / 9) * 2), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
121 | cv2.putText(img_ex, show_str3, (10, int(array[3] / 9) * 3), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
122 | cv2.putText(img_ex, show_str4, (10, int(array[3] / 9) * 4), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
123 | show_image = cv2.vconcat([show_img, img_ex])
124 | cv2.imshow('Show frame', show_image)
125 | cv2.waitKey(25)
126 | check_status(array)
127 | except (AttributeError, Exception): # cv2.error
128 | cv2.destroyAllWindows()
129 |
130 | cv2.destroyAllWindows()
131 | existing_show_shm.close()
132 |
133 |
134 | # 鼠标检测进程
135 | def mouse_detection(array, lock):
136 | def on_click(x, y, button, pressed):
137 | if array[14]:
138 | return False
139 | change_withlock(array, 15, 1 if pressed and button == Button.left else 0, lock)
140 | if pressed and button == Button.left:
141 | change_withlock(array, 16, time() * 1000, lock)
142 | elif not pressed and button == Button.left:
143 | change_withlock(array, 17, time() * 1000, lock)
144 |
145 | with Listener(on_click=on_click) as listener:
146 | listener.join() # 阻塞鼠标检测线程
147 |
148 |
149 | # 主程序
150 | def main():
151 | if not is_admin(): # 检查管理员权限
152 | restart(__file__)
153 |
154 | set_dpi() # 设置高DPI不受影响
155 | os.chdir(os.path.dirname(os.path.abspath(__file__))) # 设置工作路径
156 | check_file('yolov4-tiny') # 如果文件不存在则退出
157 | print(f'罗技驱动加载状态: {gmok}')
158 | print(f'飞易来/文盒驱动加载状态: {msdkok}')
159 |
160 | # 提升进程优先级
161 | if platform == 'win32':
162 | pid = GetCurrentProcessId()
163 | handle = OpenProcess(PROCESS_ALL_ACCESS, True, pid)
164 | SetPriorityClass(handle, ABOVE_NORMAL_PRIORITY_CLASS)
165 | else:
166 | os.nice(1)
167 |
168 | # 滑稽/选择模型
169 | print('提示: 您的选择将决定使用的模型')
170 | Conan = use_choice(0, 2, '柯南能在本程序作者有生之年完结吗?(1:能, 2:能, 0:不能): ')
171 |
172 | show_fps, DPI_Var = [1], [1]
173 |
174 | # 寻找读取游戏窗口类型并确认截取位置
175 | window_class_name, window_hwnd_name, window_outer_hwnd, test_win = get_window_info()
176 |
177 | mouse_detect_proc = Process(target=mouse_detection, args=(arr, lock,)) # 鼠标检测进程
178 | show_proc = Process(target=show_frames, args=(arr,)) # 效果展示进程
179 |
180 | # 检查窗口DPI
181 | DPI_Var[0] = max(windll.user32.GetDpiForWindow(window_outer_hwnd) / 96, windll.user32.GetDpiForWindow(window_hwnd_name) / 96)
182 | DPI_Var[0] = 1.0 if DPI_Var[0] == 0.0 else DPI_Var[0]
183 |
184 | process_times = deque()
185 |
186 | arr[0] = 0 # 截图宽
187 | arr[1] = 0 # 截图高
188 | arr[2] = 1 # 截图进程状态
189 | arr[3] = 0 # 左侧距离
190 | arr[4] = 0 # FPS值
191 | arr[5] = 600 # 基础边长
192 | arr[6] = 0 # 控制鼠标/所持武器
193 | arr[7] = 0 # 目标数量
194 | arr[8] = 1 # 移动鼠标与否
195 | arr[9] = 1 # 按击鼠标与否
196 | arr[10] = 94.4 # 射击速度
197 | arr[11] = 0 # 瞄准位置(0中1头2胸)
198 | arr[12] = 0 # 简易后坐力控制
199 | arr[13] = 0 # CF下红名
200 | arr[14] = 0 # 是否退出
201 | arr[15] = 0 # 鼠标状态
202 | arr[16] = time() # 左键按下时刻
203 | arr[17] = time() # 左键抬起时刻
204 | arr[18] = 0 # 连续射击次数
205 | arr[19] = 1600 # 窗口宽
206 |
207 | # 确认大致平均后坐影响
208 | recoil_more = 1
209 | recoil_control = {
210 | 'CrossFire': 2, # 32
211 | 'Valve001': 2, # 2.5
212 | 'LaunchCombatUWindowsClient': 2, # 10.0
213 | 'LaunchUnrealUWindowsClient': 5, # 20
214 | }.get(window_class_name, 2)
215 |
216 | # 测试过的几个游戏的移动系数,鼠标灵敏度设置看备注
217 | move_factor = {
218 | 'CrossFire': 0.971, # 32
219 | 'Valve001': 1.667, # 2.5
220 | 'LaunchCombatUWindowsClient': 1.319, # 10.0
221 | 'LaunchUnrealUWindowsClient': 0.500, # 20
222 | }.get(window_class_name, 1)
223 |
224 | mouse_detect_proc.start() # 开始鼠标监测进程
225 |
226 | # 如果非全屏则展示效果
227 | F11_Mode = 1 if is_full_screen(window_hwnd_name) else 0
228 | if not F11_Mode:
229 | show_proc.start()
230 | else:
231 | print('全屏模式下不会有小窗口...')
232 |
233 | # 等待游戏画面完整出现(拥有大于0的长宽)
234 | window_ready = 0
235 | while not window_ready:
236 | millisleep(1000)
237 | win_client_rect = win32gui.GetClientRect(window_hwnd_name)
238 | win_pos = win32gui.ClientToScreen(window_hwnd_name, (0, 0))
239 | if win_client_rect[2] - win_client_rect[0] > 0 and win_client_rect[3] - win_client_rect[1] > 0:
240 | window_ready = 1
241 |
242 | print(win_pos[0], win_pos[1], win_client_rect[2], win_client_rect[3])
243 |
244 | # 初始化分析类
245 | (Analysis, string_model) = (FrameDetection34(window_hwnd_name), '您正使用yolov4-tiny模型') if Conan == 1 else (FrameDetectionX(window_hwnd_name), '您正使用yolox-tiny模型')
246 | print(string_model)
247 |
248 | # 等待截图类初始化
249 | while not arr[2]:
250 | millisleep(1000)
251 |
252 | # clear() # 清空命令指示符面板
253 |
254 | ini_sct_time = 0 # 初始化计时
255 | target_count, moveX, moveY, fire0pos, enemy_close, can_fire = 0, 0, 0, 0, 0, 0
256 | pidx = PID(0.3, 0.75, 0.001, setpoint=0, sample_time=0.015,) # 初始化pid
257 | pidy = PID(0.3, 0.0, 0.0, setpoint=0, sample_time=0.015,) # ...
258 | small_float = np.finfo(np.float64).eps # 初始化一个尽可能小却小得不过分的数
259 | shm_show_img = shared_memory.SharedMemory(create=True, size=GetSystemMetrics(0) * GetSystemMetrics(1) * 3, name='showimg') # 创建进程间共享内存
260 | cf_enemy_color = np.array([3487638, 3487639, 3487640, 3487641, 3422105, 3422106, 3422362, 3422363, 3422364, 3356828, 3356829, 3356830, 3356831, 3291295, 3291551, 3291552, 3291553, 3291554, 3226018, 3226019, 3226020, 3226276, 3226277, 3160741, 3160742, 3160743, 3160744, 3095208, 3095209, 3095465, 3095466, 3095467, 3029931, 3029932, 3029933, 3029934, 3030190, 2964654, 2964655, 2964656, 2964657, 2899121, 2899122, 2899123, 2899379, 2899380, 2833844, 2833845, 2833846, 2833847, 2768311, 2768567, 2768568, 2768569, 2768570, 2703034, 2703035, 2703036, 2703292, 2703292, 2703293, 2637757, 2637758, 2637759, 2637760, 2572224, 2572225, 2572481, 2572482, 2572483, 2506948, 2506949, 2506950, 2507206, 2507207, 2441671, 2441672, 2441673, 2441674, 2376138, 2376139, 2376395, 2376396, 2376397, 2310861, 2310862, 2310863, 2310864, 2311120, 2245584, 2245585, 2245586, 2245587, 2180051, 2180052, 2180308, 2180309, 2180310, 2114774, 2114775, 2114776, 2114777, 2049241, 2049497, 2049498, 2049499, 2049500, 1983964, 1983965, 1983966, 1984222, 1984223, 1918687, 1918688, 1918689, 1918690, 1853154, 1853155, 1853411, 1853412, 1853413, 1787877, 1787878, 1787879, 1787880, 1788136, 1722600, 1722601, 1722602, 1722603, 1657067, 1657068, 1657069, 1657325, 1657326, 1591790, 1591791, 1591792, 1591793, 1526514]) # CF敌方红名库
261 |
262 | win_cap = WindowCapture(window_class_name, window_hwnd_name, 1/3, 192/224) # 初始化截图类
263 | winw, winh = win_cap.get_window_info() # 获取窗口宽高
264 | change_withlock(arr, 19, winw, lock)
265 | cutw, cuth = win_cap.get_cut_info() # 获取截屏宽高
266 | change_withlock(arr, 1, cutw, lock)
267 | change_withlock(arr, 0, cuth, lock)
268 |
269 | # 计算基础边长
270 | change_withlock(arr, 5, win_cap.get_side_len(), lock)
271 | print(f'基础边长 = {arr[5]}')
272 |
273 | while not arr[14]:
274 | screenshot = win_cap.grab_screenshot()
275 | # screenshot = win_cap.get_screenshot()
276 | change_withlock(arr, 0, screenshot.shape[0], lock)
277 | change_withlock(arr, 1, screenshot.shape[1], lock)
278 | try:
279 | screenshot.any()
280 |
281 | # 穿越火线检测红名
282 | if window_class_name == 'CrossFire':
283 | cut_scrn = screenshot[cuth // 2 + winh // 16 : cuth // 2 + winh // 15, cutw // 2 - winw // 40 : cutw // 2 + winw // 40] # 从截屏中截取红名区域
284 |
285 | # 将红名区域rgb转为十进制数值
286 | hexcolor = []
287 | for i in range(cut_scrn.shape[0]):
288 | for j in range(cut_scrn.shape[1]):
289 | rgbint = cut_scrn[i][j][0]<<16 | cut_scrn[i][j][1]<<8 | cut_scrn[i][j][2]
290 | hexcolor.append(rgbint)
291 |
292 | # 与内容中的敌方红名色库比较
293 | hexcolor = np.array(hexcolor)
294 | indices = np.intersect1d(cf_enemy_color, hexcolor)
295 | change_withlock(arr, 13, len(indices), lock)
296 |
297 | win_left = (150 if win_cap.get_window_left() - 10 < 150 else win_cap.get_window_left() - 10)
298 | change_withlock(arr, 3, win_left, lock)
299 |
300 | except (AttributeError, pywintypes.error) as e:
301 | print('窗口已关闭\n' + str(e))
302 | break
303 |
304 | if Conan:
305 | target_count, moveX, moveY, fire0pos, enemy_close, can_fire, screenshot = Analysis.detect(screenshot, arr[12], arr[19])
306 | change_withlock(arr, 7, target_count, lock)
307 | change_withlock(arr, 11, fire0pos, lock)
308 |
309 | if str(win32gui.GetForegroundWindow()) in (str(window_hwnd_name) + str(window_outer_hwnd)) and not test_win and arr[6]: # 是否需要控制鼠标:
310 | change_withlock(arr, 12, recoil_more * recoil_control * arr[18] / arr[6], lock)
311 | moveX = FOV(moveX, arr[5]) / DPI_Var[0] * move_factor
312 | moveY = FOV(moveY, arr[5]) / DPI_Var[0] * move_factor
313 | pid_moveX = -pidx(moveX)
314 | pid_moveY = -pidy(moveY)
315 | if arr[6] == 1: # 主武器
316 | change_withlock(arr, 10, 94.4 if enemy_close or arr[11] != 1 else 169.4, lock)
317 | elif arr[6] == 2: # 副武器
318 | change_withlock(arr, 10, 69.4 if enemy_close or arr[11] != 1 else 94.4, lock)
319 | recoil_more = 1.25 if 1000/(arr[10] + 30.6) > 6 else 1
320 | if target_count and arr[8]:
321 | move_mouse(round(pid_moveX, 3), round(pid_moveY, 3))
322 | if arr[9]:
323 | click_mouse(window_class_name, arr[10], can_fire)
324 |
325 | if not (arr[6] and target_count and arr[8]): # 测试帮助复原
326 | relax = -pidx(0.0)
327 |
328 | with lock:
329 | show_img = np.ndarray(screenshot.shape, dtype=screenshot.dtype, buffer=shm_show_img.buf)
330 | show_img[:] = screenshot[:] # 将截取数据拷贝进分享的内存
331 |
332 | time_used = time() - ini_sct_time
333 | ini_sct_time = time()
334 | process_times.append(time_used)
335 | med_time = median(process_times)
336 | pidx.sample_time = pidy.sample_time = med_time
337 | pidx.kp = pidy.kp = 1 / pow(show_fps[0]/3, 1/3)
338 | show_fps[0] = 1 / med_time if med_time > 0 else 1 / (med_time + small_float)
339 | change_withlock(arr, 4, show_fps[0], lock)
340 | if len(process_times) > 119:
341 | process_times.popleft()
342 |
343 | print('关闭进程中......')
344 | win_cap.release_resource()
345 | millisleep(1000) # 为了稳定
346 | shm_show_img.close()
347 | shm_show_img.unlink()
348 | if not F11_Mode:
349 | show_proc.terminate()
350 | mouse_detect_proc.terminate()
351 | mouse_close()
352 | exit(0)
353 |
354 |
355 | arr = Array('d', range(20)) # 进程间分享数据
356 | lock = Lock() # 锁
357 |
--------------------------------------------------------------------------------
/aimbot-exec/now/AI_main_pow.py:
--------------------------------------------------------------------------------
1 | from util import set_dpi, is_full_screen, is_admin, clear, restart, millisleep, get_window_info, FOV, use_choice, move_mouse
2 | from mouse import mouse_down, mouse_up, mouse_close, scroll, key_down, key_up, gmok, msdkok
3 | from win32api import GetAsyncKeyState, GetCurrentProcessId, OpenProcess, GetSystemMetrics
4 | from win32process import SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS
5 | from multiprocessing import Process, shared_memory, Array, Lock
6 | from win32con import VK_END, PROCESS_ALL_ACCESS
7 | from darknet_yolo34 import FrameDetection34
8 | from pynput.mouse import Listener, Button
9 | from torch_yolox import FrameDetectionX
10 | from scrnshot import WindowCapture
11 | from sys import exit, platform
12 | from collections import deque
13 | from statistics import median
14 | from time import time, sleep
15 | from math import sqrt, pow
16 | from simple_pid import PID
17 | from random import uniform
18 | from ctypes import windll
19 | import numpy as np
20 | import pywintypes
21 | import win32gui
22 | import bezier
23 | import cv2
24 | import os
25 |
26 |
27 | # 检测是否存在配置与权重文件
28 | def check_file(file):
29 | cfg_file = file + '.cfg'
30 | weights_file = file + '.weights'
31 | if not (os.path.isfile(cfg_file) and os.path.isfile(weights_file)):
32 | print(f'请下载{file}相关文件!!!')
33 | millisleep(3000)
34 | exit(0)
35 |
36 |
37 | # 加锁换值
38 | def change_withlock(arrays, var, target_var, locker):
39 | with locker:
40 | arrays[var] = target_var
41 |
42 |
43 | # 鼠标射击
44 | def click_mouse(win_class, rate, go_fire):
45 | # 不分敌友射击
46 | if arr[15]: # GetAsyncKeyState(VK_LBUTTON) < 0
47 | if time() * 1000 - arr[16] > 30.6: # press_moment
48 | mouse_up()
49 | elif win_class != 'CrossFire' or arr[13]:
50 | if arr[13] or go_fire:
51 | if time() * 1000 - arr[17] > rate: # release_moment
52 | mouse_down()
53 | change_withlock(arr, 18, arr[18] + 1, lock)
54 |
55 | if time() * 1000 - arr[17] > 219.4:
56 | change_withlock(arr, 18, 0, lock)
57 |
58 | if arr[18] > 12:
59 | change_withlock(arr, 18, 12, lock)
60 |
61 |
62 | # 转变状态
63 | def check_status(arr):
64 | if GetAsyncKeyState(VK_END) < 0: # End
65 | change_withlock(arr, 14, 1, lock)
66 | if GetAsyncKeyState(0x31) < 0: # 1
67 | change_withlock(arr, 6, 1, lock)
68 | if GetAsyncKeyState(0x32) < 0: # 2
69 | change_withlock(arr, 6, 2, lock)
70 | if GetAsyncKeyState(0x33) < 0 or GetAsyncKeyState(0x34) < 0: # 3,4
71 | change_withlock(arr, 6, 0, lock)
72 | change_withlock(arr, 18, 0, lock)
73 | if GetAsyncKeyState(0x46) < 0: # F恢复移动
74 | change_withlock(arr, 8, 1, lock)
75 | if GetAsyncKeyState(0x4A) < 0: # J停止移动
76 | change_withlock(arr, 8, 0, lock)
77 | if GetAsyncKeyState(0x12) < 0: # Alt恢复开火
78 | change_withlock(arr, 9, 1, lock)
79 | if GetAsyncKeyState(0x30) < 0: # 0停止开火
80 | change_withlock(arr, 9, 0, lock)
81 |
82 |
83 | # 多线程展示效果
84 | def show_frames(array):
85 | set_dpi()
86 | cv2.namedWindow('Show frame', cv2.WINDOW_KEEPRATIO)
87 | cv2.moveWindow('Show frame', 0, 0)
88 | cv2.destroyAllWindows()
89 | font = cv2.FONT_HERSHEY_SIMPLEX # 效果展示字体
90 | fire_target_show = ['middle', 'head', 'chest']
91 |
92 | while True: # 等待共享内存加载完毕
93 | try:
94 | existing_show_shm = shared_memory.SharedMemory(name='showimg')
95 | millisleep(1000)
96 | break
97 | except FileNotFoundError:
98 | millisleep(1000)
99 |
100 | while not array[14]:
101 | show_img = np.ndarray((int(array[0]), int(array[1]), 3), dtype=np.uint8, buffer=existing_show_shm.buf)
102 | show_color = {
103 | 0: (127, 127, 127),
104 | 1: (255, 255, 0),
105 | 2: (0, 255, 0)
106 | }.get(array[6])
107 | try:
108 | img_ex = np.zeros((1, 1, 3), np.uint8)
109 | show_str0 = str('{:03.1f}'.format(array[4]))
110 | show_str1 = 'Detected ' + str('{:02.0f}'.format(array[7])) + ' targets'
111 | show_str2 = 'Aiming at ' + fire_target_show[int(array[11])] + ' position'
112 | show_str3 = 'Fire rate is at ' + str('{:02.0f}'.format((1000 / (array[10] + 30.6)))) + ' RPS'
113 | show_str4 = 'Please enjoy coding ^_^' if array[8] else 'Please enjoy coding @_@'
114 | if show_img.any():
115 | show_img_h, show_img_w = show_img.shape[:2]
116 | show_img = cv2.resize(show_img, (int(array[3]), int(array[3] / show_img_w * show_img_h)))
117 | img_ex = cv2.resize(img_ex, (int(array[3]), int(array[3] / 2)))
118 | cv2.putText(show_img, show_str0, (int(array[3] / 25), int(array[3] / 12)), font, array[3] / 600, (127, 255, 0), 2, cv2.LINE_AA)
119 | cv2.putText(img_ex, show_str1, (10, int(array[3] / 9)), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
120 | cv2.putText(img_ex, show_str2, (10, int(array[3] / 9) * 2), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
121 | cv2.putText(img_ex, show_str3, (10, int(array[3] / 9) * 3), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
122 | cv2.putText(img_ex, show_str4, (10, int(array[3] / 9) * 4), font, array[3] / 450, show_color, 1, cv2.LINE_AA)
123 | show_image = cv2.vconcat([show_img, img_ex])
124 | cv2.imshow('Show frame', show_image)
125 | cv2.waitKey(25)
126 | check_status(array)
127 | except (AttributeError, Exception): # cv2.error
128 | cv2.destroyAllWindows()
129 |
130 | cv2.destroyAllWindows()
131 | existing_show_shm.close()
132 |
133 |
134 | # 鼠标检测进程
135 | def mouse_detection(array, lock):
136 | def on_click(x, y, button, pressed):
137 | if array[14]:
138 | return False
139 | change_withlock(array, 15, 1 if pressed and button == Button.left else 0, lock)
140 | if pressed and button == Button.left:
141 | change_withlock(array, 16, time() * 1000, lock)
142 | elif not pressed and button == Button.left:
143 | change_withlock(array, 17, time() * 1000, lock)
144 |
145 | with Listener(on_click=on_click) as listener:
146 | listener.join() # 阻塞鼠标检测线程
147 |
148 |
149 | # 截图进程
150 | def capturing(array, the_class_name, the_hwnd_name, lock):
151 | shm_img = shared_memory.SharedMemory(create=True, size=GetSystemMetrics(0) * GetSystemMetrics(1) * 3, name='shareimg') # 创建进程间共享内存
152 | cf_enemy_color = np.array([3487638, 3487639, 3487640, 3487641, 3422105, 3422106, 3422362, 3422363, 3422364, 3356828, 3356829, 3356830, 3356831, 3291295, 3291551, 3291552, 3291553, 3291554, 3226018, 3226019, 3226020, 3226276, 3226277, 3160741, 3160742, 3160743, 3160744, 3095208, 3095209, 3095465, 3095466, 3095467, 3029931, 3029932, 3029933, 3029934, 3030190, 2964654, 2964655, 2964656, 2964657, 2899121, 2899122, 2899123, 2899379, 2899380, 2833844, 2833845, 2833846, 2833847, 2768311, 2768567, 2768568, 2768569, 2768570, 2703034, 2703035, 2703036, 2703292, 2703292, 2703293, 2637757, 2637758, 2637759, 2637760, 2572224, 2572225, 2572481, 2572482, 2572483, 2506948, 2506949, 2506950, 2507206, 2507207, 2441671, 2441672, 2441673, 2441674, 2376138, 2376139, 2376395, 2376396, 2376397, 2310861, 2310862, 2310863, 2310864, 2311120, 2245584, 2245585, 2245586, 2245587, 2180051, 2180052, 2180308, 2180309, 2180310, 2114774, 2114775, 2114776, 2114777, 2049241, 2049497, 2049498, 2049499, 2049500, 1983964, 1983965, 1983966, 1984222, 1984223, 1918687, 1918688, 1918689, 1918690, 1853154, 1853155, 1853411, 1853412, 1853413, 1787877, 1787878, 1787879, 1787880, 1788136, 1722600, 1722601, 1722602, 1722603, 1657067, 1657068, 1657069, 1657325, 1657326, 1591790, 1591791, 1591792, 1591793, 1526514]) # CF敌方红名库
153 |
154 | win_cap = WindowCapture(the_class_name, the_hwnd_name, 1/3, 192/224) # 初始化截图类
155 | winw, winh = win_cap.get_window_info() # 获取窗口宽高
156 | change_withlock(array, 19, winw, lock)
157 | cutw, cuth = win_cap.get_cut_info() # 获取截屏宽高
158 | change_withlock(array, 1, cutw, lock)
159 | change_withlock(array, 0, cuth, lock)
160 |
161 | # 计算基础边长
162 | change_withlock(array, 5, win_cap.get_side_len(), lock)
163 | change_withlock(array, 2, 1, lock)
164 | print(f'基础边长 = {array[5]}')
165 |
166 | while not array[14]:
167 | # millisleep(1) # 降低平均cpu占用
168 | screenshots = win_cap.grab_screenshot()
169 | # screenshots = win_cap.get_screenshot()
170 | change_withlock(array, 0, screenshots.shape[0], lock)
171 | change_withlock(array, 1, screenshots.shape[1], lock)
172 | with lock:
173 | shared_img = np.ndarray(screenshots.shape, dtype=screenshots.dtype, buffer=shm_img.buf)
174 | shared_img[:] = screenshots[:] # 将截取数据拷贝进分享的内存
175 | if the_class_name == 'CrossFire':
176 | cut_scrn = screenshots[cuth // 2 + winh // 16 : cuth // 2 + winh // 15, cutw // 2 - winw // 40 : cutw // 2 + winw // 40] # 从截屏中截取红名区域
177 |
178 | # 将红名区域rgb转为十进制数值
179 | hexcolor = []
180 | for i in range(cut_scrn.shape[0]):
181 | for j in range(cut_scrn.shape[1]):
182 | rgbint = cut_scrn[i][j][0]<<16 | cut_scrn[i][j][1]<<8 | cut_scrn[i][j][2]
183 | hexcolor.append(rgbint)
184 |
185 | # 与内容中的敌方红名色库比较
186 | hexcolor = np.array(hexcolor)
187 | indices = np.intersect1d(cf_enemy_color, hexcolor)
188 | change_withlock(array, 13, len(indices), lock)
189 |
190 | win_left = (150 if win_cap.get_window_left() - 10 < 150 else win_cap.get_window_left() - 10)
191 | change_withlock(array, 3, win_left, lock)
192 |
193 | win_cap.release_resource()
194 | shm_img.close()
195 |
196 |
197 | # 主程序
198 | def main():
199 | if not is_admin(): # 检查管理员权限
200 | restart(__file__)
201 |
202 | set_dpi() # 设置高DPI不受影响
203 | os.chdir(os.path.dirname(os.path.abspath(__file__))) # 设置工作路径
204 | check_file('yolov4-tiny') # 如果文件不存在则退出
205 | print(f'罗技驱动加载状态: {gmok}')
206 | print(f'飞易来/文盒驱动加载状态: {msdkok}')
207 |
208 | # 提升进程优先级
209 | if platform == 'win32':
210 | pid = GetCurrentProcessId()
211 | handle = OpenProcess(PROCESS_ALL_ACCESS, True, pid)
212 | SetPriorityClass(handle, ABOVE_NORMAL_PRIORITY_CLASS)
213 | else:
214 | os.nice(1)
215 |
216 | # 滑稽/选择模型
217 | print('提示: 您的选择将决定使用的模型')
218 | Conan = use_choice(0, 2, '柯南能在本程序作者有生之年完结吗?(1:能, 2:能, 0:不能): ')
219 |
220 | show_fps, DPI_Var = [1], [1]
221 |
222 | # 寻找读取游戏窗口类型并确认截取位置
223 | window_class_name, window_hwnd_name, window_outer_hwnd, test_win = get_window_info()
224 |
225 | mouse_detect_proc = Process(target=mouse_detection, args=(arr, lock,)) # 鼠标检测进程
226 | show_proc = Process(target=show_frames, args=(arr,)) # 效果展示进程
227 | capture_proc = Process(target=capturing, args=(arr, window_class_name, window_hwnd_name, lock,)) # 截图进程
228 |
229 | # 检查窗口DPI
230 | DPI_Var[0] = max(windll.user32.GetDpiForWindow(window_outer_hwnd) / 96, windll.user32.GetDpiForWindow(window_hwnd_name) / 96)
231 | DPI_Var[0] = 1.0 if DPI_Var[0] == 0.0 else DPI_Var[0]
232 |
233 | process_times = deque()
234 |
235 | arr[0] = 0 # 截图宽
236 | arr[1] = 0 # 截图高
237 | arr[2] = 0 # 截图进程状态
238 | arr[3] = 0 # 左侧距离
239 | arr[4] = 0 # FPS值
240 | arr[5] = 600 # 基础边长
241 | arr[6] = 0 # 控制鼠标/所持武器
242 | arr[7] = 0 # 目标数量
243 | arr[8] = 1 # 移动鼠标与否
244 | arr[9] = 1 # 按击鼠标与否
245 | arr[10] = 94.4 # 射击速度
246 | arr[11] = 0 # 瞄准位置(0中1头2胸)
247 | arr[12] = 0 # 简易后坐力控制
248 | arr[13] = 0 # CF下红名
249 | arr[14] = 0 # 是否退出
250 | arr[15] = 0 # 鼠标状态
251 | arr[16] = time() # 左键按下时刻
252 | arr[17] = time() # 左键抬起时刻
253 | arr[18] = 0 # 连续射击次数
254 | arr[19] = 1600 # 窗口宽
255 |
256 | # 确认大致平均后坐影响
257 | recoil_more = 1
258 | recoil_control = {
259 | 'CrossFire': 2, # 32
260 | 'Valve001': 2, # 2.5
261 | 'LaunchCombatUWindowsClient': 2, # 10.0
262 | 'LaunchUnrealUWindowsClient': 5, # 20
263 | }.get(window_class_name, 2)
264 |
265 | # 测试过的几个游戏的移动系数,鼠标灵敏度设置看备注
266 | move_factor = {
267 | 'CrossFire': 0.971, # 32
268 | 'Valve001': 1.667, # 2.5
269 | 'LaunchCombatUWindowsClient': 1.319, # 10.0
270 | 'LaunchUnrealUWindowsClient': 0.500, # 20
271 | }.get(window_class_name, 1)
272 |
273 | capture_proc.start() # 开始截图进程
274 | mouse_detect_proc.start() # 开始鼠标监测进程
275 |
276 | # 如果非全屏则展示效果
277 | F11_Mode = 1 if is_full_screen(window_hwnd_name) else 0
278 | if not F11_Mode:
279 | show_proc.start()
280 | else:
281 | print('全屏模式下不会有小窗口...')
282 |
283 | # 等待游戏画面完整出现(拥有大于0的长宽)
284 | window_ready = 0
285 | while not window_ready:
286 | millisleep(1000)
287 | win_client_rect = win32gui.GetClientRect(window_hwnd_name)
288 | win_pos = win32gui.ClientToScreen(window_hwnd_name, (0, 0))
289 | if win_client_rect[2] - win_client_rect[0] > 0 and win_client_rect[3] - win_client_rect[1] > 0:
290 | window_ready = 1
291 |
292 | print(win_pos[0], win_pos[1], win_client_rect[2], win_client_rect[3])
293 |
294 | # 初始化分析类
295 | (Analysis, string_model) = (FrameDetection34(window_hwnd_name), '您正使用yolov4-tiny模型') # if Conan == 1 else (FrameDetectionX(window_hwnd_name), '您正使用yolox-tiny模型')
296 | print(string_model)
297 |
298 | # 等待截图类初始化
299 | while not arr[2]:
300 | millisleep(1000)
301 |
302 | # clear() # 清空命令指示符面板
303 |
304 | ini_sct_time = 0 # 初始化计时
305 | target_count, moveX, moveY, fire0pos, enemy_close, can_fire = 0, 0, 0, 0, 0, 0
306 | pidx = PID(0.2, 0.0, 0.0, setpoint=0, sample_time=0.006,) # 初始化pid
307 | pidy = PID(0.2, 0.0, 0.0, setpoint=0, sample_time=0.006,) # ...
308 | small_float = np.finfo(np.float64).eps # 初始化一个尽可能小却小得不过分的数
309 | shm_show_img = shared_memory.SharedMemory(create=True, size=GetSystemMetrics(0) * GetSystemMetrics(1) * 3, name='showimg') # 创建进程间共享内存
310 | existing_shm = shared_memory.SharedMemory(name='shareimg')
311 |
312 | while not arr[14]:
313 | try:
314 | screenshots = np.ndarray((int(arr[0]), int(arr[1]), 3), dtype=np.uint8, buffer=existing_shm.buf)
315 | if screenshots.any():
316 | screenshot = np.ndarray(screenshots.shape, dtype=screenshots.dtype)
317 | screenshot[:] = screenshots[:]
318 |
319 | except (AttributeError, pywintypes.error) as e:
320 | print('窗口已关闭\n' + str(e))
321 | break
322 |
323 | if Conan:
324 | target_count, moveX, moveY, fire0pos, enemy_close, can_fire, screenshot = Analysis.detect(screenshot, arr[12], arr[19])
325 | change_withlock(arr, 7, target_count, lock)
326 | change_withlock(arr, 11, fire0pos, lock)
327 |
328 | if str(win32gui.GetForegroundWindow()) in (str(window_hwnd_name) + str(window_outer_hwnd)) and not test_win and arr[6]: # 是否需要控制鼠标:
329 | change_withlock(arr, 12, recoil_more * recoil_control * arr[18] / arr[6], lock)
330 | moveX = FOV(moveX, arr[5]) / DPI_Var[0] * move_factor
331 | moveY = FOV(moveY, arr[5]) / DPI_Var[0] * move_factor
332 | pid_moveX = -pidx(moveX)
333 | pid_moveY = -pidy(moveY)
334 | if arr[6] == 1: # 主武器
335 | change_withlock(arr, 10, 94.4 if enemy_close or arr[11] != 1 else 169.4, lock)
336 | elif arr[6] == 2: # 副武器
337 | change_withlock(arr, 10, 69.4 if enemy_close or arr[11] != 1 else 94.4, lock)
338 | recoil_more = 1.25 if 1000/(arr[10] + 30.6) > 6 else 1
339 | if target_count and arr[8]:
340 | move_mouse(round(pid_moveX, 3), round(pid_moveY, 3))
341 | if arr[9]:
342 | click_mouse(window_class_name, arr[10], can_fire)
343 |
344 | if not (arr[6] and target_count and arr[8]): # 测试帮助复原
345 | relax = -pidx(0.0)
346 |
347 | with lock:
348 | show_img = np.ndarray(screenshot.shape, dtype=screenshot.dtype, buffer=shm_show_img.buf)
349 | show_img[:] = screenshot[:] # 将截取数据拷贝进分享的内存
350 |
351 | # millisleep(1) # 降低平均cpu占用
352 | time_used = time() - ini_sct_time
353 | ini_sct_time = time()
354 | process_times.append(time_used)
355 | med_time = median(process_times)
356 | pidx.sample_time = pidy.sample_time = med_time
357 | pidx.kp = pidy.kp = 1 / pow(show_fps[0]/3, 1/3)
358 | show_fps[0] = 1 / med_time if med_time > 0 else 1 / (med_time + small_float)
359 | change_withlock(arr, 4, show_fps[0], lock)
360 | if len(process_times) > 119:
361 | process_times.popleft()
362 |
363 | print('关闭进程中......')
364 | millisleep(1000) # 为了稳定
365 | shm_show_img.close()
366 | existing_shm.close()
367 | shm_show_img.unlink()
368 | existing_shm.unlink()
369 | if not F11_Mode:
370 | show_proc.terminate()
371 | mouse_detect_proc.terminate()
372 | capture_proc.terminate()
373 | mouse_close()
374 | exit(0)
375 |
376 |
377 | arr = Array('d', range(20)) # 进程间分享数据
378 | lock = Lock() # 锁
379 |
--------------------------------------------------------------------------------
/aimbot-exec/FPS战斗助手.ahk:
--------------------------------------------------------------------------------
1 | #NoEnv ;不检查空变量是否为环境变量
2 | #Warn ;启用可能产生错误的特定状况时的警告
3 | #Persistent ;让脚本持久运行
4 | #MenuMaskKey, vkFF ;改变用来掩饰(屏蔽)Win或Alt松开事件的按键
5 | #MaxHotkeysPerInterval, 1000 ;与下行代码一起指定热键激活的速率(次数)
6 | #HotkeyInterval, 1000 ;与上一行代码一起指定热键激活的速率(时间)
7 | #SingleInstance, Force ;跳过对话框并自动替换旧实例
8 | #KeyHistory, 0 ;禁用按键历史
9 | #InstallMouseHook ;强制无条件安装鼠标钩子
10 | #InstallKeybdHook ;强制无条件安装键盘钩子
11 | ListLines, Off ;不显示最近执行的脚本行
12 | SendMode, Input ;使用更速度和可靠方式发送键鼠点击
13 | SetWorkingDir, %A_ScriptDir% ;保证一致的脚本起始工作目录
14 | Process, Priority, , A ;进程高于普通优先级
15 | SetBatchLines, -1 ;全速运行,且因为全速运行,部分代码不得不调整
16 | SetKeyDelay, -1, -1 ;设置每次Send和ControlSend发送键击后无延时
17 | SetMouseDelay, -1 ;设置每次鼠标移动或点击后无延时
18 | SetTitleMatchMode, RegEx ;设置WinTitle参数的匹配模式为支持正则表达式
19 | ;==================================================================================
20 | CheckPermission1()
21 | CheckWindow(win_class, win_title, win_id)
22 | MsgBox, %win_title%出现!!!
23 | IsJumping := False
24 | w_pressed := s_pressed := a_pressed := d_pressed := 0
25 | CheckPosition1(BX, BY, BW, BH, win_class)
26 | boxh := Round(BH / 9 * 4)
27 | boxw := Round(boxh * 1.6)
28 | showx := BX + (BW - boxw) // 2 - 1
29 | showy := BY + (BH - boxh) // 2 - 1
30 | showw := boxw + 2
31 | showh := boxh + 2
32 | boundingbox := (Ceil(boxw/2) + 1)"-0 0-0 0-"(boxh+2)" "(boxw+2)"-"(boxh+2)" "(boxw+2)"-0 "(Ceil(boxw/2) + 1)"-0 "(Ceil(boxw/2) + 1)"-1 "(boxw+1)"-1 "(boxw+1)"-"(boxh+1)" 1-"(boxh+1)" 1-1 "(Ceil(boxw/2) + 1)"-1 " (Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1 - boxh//10)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1 - boxh//10)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 2 + boxh//10)" "(Ceil(boxw/2) + 2)"-"(Ceil(boxh/2) + 2 + boxh//10)" "(Ceil(boxw/2) + 2)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 2 + boxh//10)"-"(Ceil(boxh/2) + 2)" "(Ceil(boxw/2) + 2 + boxh//10)"-"(Ceil(boxh/2) + 1)" "(Ceil(boxw/2) + 1)"-"(Ceil(boxh/2) + 1)
33 | Gui, box: New, +lastfound +ToolWindow -Caption +AlwaysOnTop +Hwndbb -DPIScale, cshp001
34 | Gui, box: Color, 00FFFF ;#00FFFF
35 | Gui, box: Show, x%showx% y%showy% w%showw% h%showh% NA
36 | WinSet, Region, %boundingbox%, ahk_id %bb%
37 | WinSet, Transparent, 225, ahk_id %bb%
38 | WinSet, ExStyle, +0x20 +0x8; 鼠标穿透以及最顶端
39 | ;==================================================================================
40 | ~*End::ExitApp
41 |
42 | ~*RAlt::
43 | Gui, box: Show, Hide
44 | Return
45 |
46 | ~*RAlt Up::
47 | If !WinExist("ahk_id "win_id)
48 | ExitApp
49 | CheckPosition1(BX, BY, BW, BH, win_class)
50 | showx := BX + (BW - boxw) // 2 - 1
51 | showy := BY + (BH - boxh) // 2 - 1
52 | Gui, box: Show, x%showx% y%showy% w%showw% h%showh% NA
53 | Return
54 |
55 | #If WinActive("ahk_class Valve001") || WinActive("ahk_class Valorant")
56 |
57 | ~*w::
58 | If GetKeyState("w", "P")
59 | {
60 | CheckPressTime("w", state_w)
61 | w_pressed := 1
62 | }
63 | Return
64 |
65 | ~*w Up::
66 | If w_pressed
67 | {
68 | Reverse_move("S", state_w)
69 | w_pressed := 0
70 | }
71 | Return
72 |
73 | ~*s::
74 | If GetKeyState("s", "P")
75 | {
76 | CheckPressTime("s", state_s)
77 | s_pressed := 1
78 | }
79 | Return
80 |
81 | ~*s Up::
82 | If s_pressed
83 | {
84 | Reverse_move("W", state_s)
85 | s_pressed := 0
86 | }
87 | Return
88 |
89 | ~*a::
90 | If GetKeyState("a", "P")
91 | {
92 | CheckPressTime("a", state_a)
93 | a_pressed := 1
94 | }
95 | Return
96 |
97 | ~*a Up::
98 | If a_pressed
99 | {
100 | Reverse_move("d", state_a)
101 | a_pressed := 0
102 | }
103 | Return
104 |
105 | ~*d::
106 | If GetKeyState("d", "P")
107 | {
108 | CheckPressTime("d", state_d)
109 | d_pressed := 1
110 | }
111 | Return
112 |
113 | ~*d Up::
114 | If d_pressed
115 | {
116 | Reverse_move("a", state_d)
117 | d_pressed := 0
118 | }
119 | Return
120 |
121 | ~*Space::
122 | If !GetKeyState("Space", "P")
123 | Return
124 | IsJumping := True
125 | HyperSleep(600)
126 | IsJumping := False
127 | Return
128 | ;==================================================================================
129 | ;记录按键时间
130 | CheckPressTime(key, ByRef pressed_time)
131 | {
132 | key_pressed := SystemTime()
133 | While (GetKeyState(key, "P")) ;当按下时
134 | {
135 | pressed_time := SystemTime() - key_pressed
136 | HyperSleep(1)
137 | }
138 | }
139 | ;==================================================================================
140 | ;反向(刹车)运动
141 | Reverse_move(rvs_key, pressed_time := 0)
142 | {
143 | global IsJumping
144 | RandFactor := 0
145 | Random, RandPress, 28.0, 30.0
146 | If pressed_time > 240
147 | RandFactor := 4
148 | Else If pressed_time > 120
149 | RandFactor := 1 + (pressed_time - 120) / 40
150 | If !IsJumping
151 | press_key(rvs_key, Round(RandPress * RandFactor), 0)
152 | }
153 | ;==================================================================================
154 | ;找到并由使用者确认游戏窗口
155 | CheckWindow(ByRef ClassName, ByRef TitleName, ByRef hwnd_id := 0)
156 | {
157 | confirmed := False
158 | Loop
159 | {
160 | HyperSleep(3000)
161 | hwnd_id := WinExist("A")
162 | WinGetClass, Class_Name, ahk_id %hwnd_id%
163 | WinGetTitle, Title_Name, ahk_class %Class_Name%
164 | MsgBox, 262148, 确认框/Confirm Box, %Title_Name% 是您需要的窗口标题吗?`nIs %Title_Name% the window title you want?
165 | IfMsgBox, Yes
166 | {
167 | confirmed := True
168 | ClassName := Class_Name
169 | TitleName := Title_Name
170 | }
171 | } Until, (confirmed && ClassName && TitleName)
172 | }
173 | ;==================================================================================
174 | ;检查脚本执行权限,只有以管理员权限或以UI Access运行才能正常工作
175 | CheckPermission1()
176 | {
177 | If A_OSVersion in WIN_NT4, WIN_95, WIN_98, WIN_ME, WIN_2000, WIN_2003, WIN_XP, WIN_VISTA ;检测操作系统版本
178 | {
179 | MsgBox, 262160, 错误/Error, 此辅助需要Win 7及以上操作系统!!!`nThis program requires Windows 7 or later!!!
180 | ExitApp
181 | }
182 |
183 | If !A_Is64bitOS ;检测操作系统是否为64位
184 | {
185 | MsgBox, 262160, 错误/Error, 此辅助需要64位操作系统!!!`nThis program requires 64-bit OS!!!
186 | ExitApp
187 | }
188 |
189 | If Not (A_IsAdmin || CheckUIA1())
190 | {
191 | Try
192 | {
193 | If A_IsCompiled ;编译时请用加密减少侦测几率
194 | Run, *RunAs "%A_ScriptFullPath%" ;管理员权限运行
195 | Else
196 | {
197 | MsgBox, 262148, 警告/Warning, 请问你开启UIA了吗?`nDo you have UIAccess enabled?
198 | IfMsgBox Yes
199 | Run, "%A_ProgramFiles%\AutoHotkey\AutoHotkeyU64_UIA.exe" "%A_ScriptFullPath%"
200 | Else
201 | Run, *RunAs "%A_ScriptFullPath%"
202 | ExitApp
203 | }
204 | }
205 | Catch
206 | {
207 | MsgBox, 262160, 错误/Error, 未正确运行!辅助将退出!!`nUnable to start correctly!The program will exit!!
208 | ExitApp
209 | }
210 | }
211 | }
212 | ;==================================================================================
213 | ;检查脚本是否由指定的UIA权限运行
214 | CheckUIA1()
215 | {
216 | process_name := GetProcessName(DllCall("GetCurrentProcessId"))
217 | If InStr(process_name, "AutoHotkeyU64_UIA.exe")
218 | Return True
219 | Return False
220 | }
221 | ;==================================================================================
222 | ;拷贝自 https://www.reddit.com/r/AutoHotkey/comments/6zftle/process_name_from_pid/ ,通过进程ID得到进程完整路径
223 | GetProcessName(ProcessID)
224 | {
225 | If (hProcess := DllCall("OpenProcess", "UInt", 0x0410, "Int", 0, "UInt", ProcessID, "Ptr"))
226 | {
227 | size := VarSetCapacity(buf, 0x0104 << 1, 0)
228 | If (DllCall("psapi\GetModuleFileNameEx", "Ptr", hProcess, "Ptr", 0, "Ptr", &buf, "UInt", size))
229 | Return StrGet(&buf), DllCall("CloseHandle", "Ptr", hProcess)
230 | DllCall("CloseHandle", "Ptr", hProcess)
231 | }
232 | Return False
233 | }
234 | ;==================================================================================
235 | ;检查游戏界面真正位置,不包括标题栏和边缘等等,既Client位置
236 | CheckPosition1(ByRef Xcp, ByRef Ycp, ByRef Wcp, ByRef Hcp, class_name)
237 | {
238 | WinGet, Window_ID, ID, ahk_class %class_name%
239 |
240 | VarSetCapacity(rect, 16)
241 | DllCall("GetClientRect", "Ptr", Window_ID, "Ptr", &rect) ;内在宽高
242 | Wcp := NumGet(rect, 8, "Int")
243 | Hcp := NumGet(rect, 12, "Int")
244 |
245 | VarSetCapacity(WINDOWINFO, 60, 0)
246 | DllCall("GetWindowInfo", "Ptr", Window_ID, "Ptr", &WINDOWINFO) ;内在XY
247 | Xcp := NumGet(WINDOWINFO, 20, "Int")
248 | Ycp := NumGet(WINDOWINFO, 24, "Int")
249 |
250 | VarSetCapacity(Screen_Info, 156)
251 | DllCall("EnumDisplaySettingsA", Ptr, 0, UInt, -1, UInt, &Screen_Info) ;真实分辨率
252 | Mon_Width := NumGet(Screen_Info, 108, "Int")
253 | Mon_Hight := NumGet(Screen_Info, 112, "Int")
254 |
255 | If (Wcp >= Mon_Width) || (Hcp >= Mon_Hight) ;全屏检测,未知是否适应UHD不放大
256 | {
257 | CoordMode, Pixel, Client ;坐标相对活动窗口的客户端
258 | CoordMode, Mouse, Client
259 | CoordMode, ToolTip, Client
260 | }
261 | Else
262 | {
263 | CoordMode, Pixel, Screen ;坐标相对全屏幕
264 | CoordMode, Mouse, Screen
265 | CoordMode, ToolTip, Screen
266 | }
267 | }
268 | ;==================================================================================
269 | ;学习自Bilibili用户开发的CSGO压枪脚本中的高精度时钟
270 | SystemTime()
271 | {
272 | freq := 1, tick := 0
273 | DllCall("QueryPerformanceFrequency", "Int64*", freq)
274 | DllCall("QueryPerformanceCounter", "Int64*", tick)
275 | Return tick / freq * 1000
276 | }
277 | ;==================================================================================
278 | ;学习自Bilibili用户开发的CSGO压枪脚本中的高精度睡眠
279 | HyperSleep(value)
280 | {
281 | s_begin_time := SystemTime()
282 | freq := 0, t_current := 0
283 | DllCall("QueryPerformanceFrequency", "Int64*", freq)
284 | s_end_time := (s_begin_time + value) * freq / 1000
285 | While, (t_current < s_end_time)
286 | {
287 | If (s_end_time - t_current) > 20000 ;大于二毫秒时不暴力轮询,以减少CPU占用
288 | {
289 | DllCall("Winmm.dll\timeBeginPeriod", UInt, 1)
290 | DllCall("Sleep", "UInt", 1)
291 | DllCall("Winmm.dll\timeEndPeriod", UInt, 1)
292 | ;以上三行代码为相对ahk自带sleep函数稍高精度的睡眠
293 | }
294 | DllCall("QueryPerformanceCounter", "Int64*", t_current)
295 | }
296 | }
297 | ;==================================================================================
298 | ;鼠标左右键按下(SendInput方式)
299 | mouse_sendinput_down(key_name := "LButton")
300 | {
301 | If !Instr(key_name, "Button")
302 | Return False
303 | StructSize := A_PtrSize + 4*4 + A_PtrSize*2
304 | WhichDown := Instr(key_name, "L") ? 0x0002 : 0x0008
305 | ;MOUSEEVENTF_LEFTDOWN := 0x0002, MOUSEEVENTF_RIGHTDOWN := 0x0008
306 | VarSetCapacity(Key_Down, StructSize)
307 | NumPut(0, Key_Down, "UInt") ;4 bit
308 | NumPut(0, Key_Down, A_PtrSize, "UInt")
309 | NumPut(0, Key_Down, A_PtrSize + 4, "UInt")
310 | NumPut(WhichDown, Key_Down, A_PtrSize + 4*3, "UInt")
311 | DllCall("SendInput", "UInt", 1, "Ptr", &Key_Down, "Int", StructSize)
312 | VarSetCapacity(Key_Down, 0) ;释放内存
313 | }
314 | ;==================================================================================
315 | ;鼠标左右键抬起(SendInput方式)
316 | mouse_sendinput_up(key_name := "LButton")
317 | {
318 | If !Instr(key_name, "Button")
319 | Return False
320 | StructSize := A_PtrSize + 4*4 + A_PtrSize*2
321 | WhichDown := Instr(key_name, "L") ? 0x0004 : 0x0010
322 | ;MOUSEEVENTF_LEFTUP := 0x0004, MOUSEEVENTF_RIGHTUP := 0x0010
323 | VarSetCapacity(Key_Up, StructSize)
324 | NumPut(0, Key_Up, "UInt") ;4 bit
325 | NumPut(0, Key_Up, A_PtrSize, "UInt")
326 | NumPut(0, Key_Up, A_PtrSize + 4, "UInt")
327 | NumPut(WhichDown, Key_Up, A_PtrSize + 4*3, "UInt")
328 | DllCall("SendInput", "UInt", 1, "Ptr", &Key_Up, "Int", StructSize)
329 | VarSetCapacity(Key_Up, 0) ;释放内存
330 | }
331 | ;==================================================================================
332 | ;鼠标左右键按下
333 | mouse_down(key_name := "LButton", sendinput_method := True)
334 | {
335 | If sendinput_method
336 | {
337 | mouse_sendinput_down(key_name)
338 | Return
339 | }
340 | If !Instr(key_name, "Button")
341 | Return False
342 | Switch key_name
343 | {
344 | Case "LButton": DllCall("mouse_event", "UInt", 0x02) ;左键按下
345 | Case "RButton": DllCall("mouse_event", "UInt", 0x08) ;右键按下
346 | }
347 | }
348 | ;==================================================================================
349 | ;鼠标左右键抬起
350 | mouse_up(key_name := "LButton", sendinput_method := True)
351 | {
352 | If sendinput_method
353 | {
354 | mouse_sendinput_up(key_name)
355 | Return
356 | }
357 | If !Instr(key_name, "Button")
358 | Return False
359 | Switch key_name
360 | {
361 | Case "LButton": DllCall("mouse_event", "UInt", 0x04) ;左键弹起
362 | Case "RButton": DllCall("mouse_event", "UInt", 0x10) ;右键弹起
363 | }
364 | }
365 | ;==================================================================================
366 | ;键位按下(SendInput方式)
367 | key_sendinput_down(key_name)
368 | {
369 | static INPUT_KEYBOARD := 1, KEYEVENTF_KEYUP := 2, KEYEVENTF_SCANCODE := 8, InputSize := 16 + A_PtrSize*3
370 | Input_Index := (StrLen(key_name) == 1 && Ord(key_name) > 64 && Ord(key_name) < 91) ? 2 : 1
371 | VarSetCapacity(INPUTS, InputSize*Input_Index, 0)
372 | addr := &INPUTS, Scancode := GetKeySC(key_name)
373 | If Input_Index = 2
374 | addr := NumPut(0 | KEYEVENTF_SCANCODE | 0
375 | , NumPut(0x2A & 0xFF
376 | , NumPut(INPUT_KEYBOARD, addr + 0) + 2, "UShort"), "UInt" ) + 8 + A_PtrSize*2
377 | addr := NumPut(0 | KEYEVENTF_SCANCODE | 0
378 | , NumPut(Scancode & 0xFF
379 | , NumPut(INPUT_KEYBOARD, addr + 0) + 2, "UShort"), "UInt" ) + 8 + A_PtrSize*2
380 | DllCall("SendInput", "UInt", Input_Index, "Ptr", &INPUTS, "Int", InputSize)
381 | VarSetCapacity(INPUTS, 0) ;释放内存
382 | }
383 | ;==================================================================================
384 | ;键位弹起(SendInput方式)
385 | key_sendinput_up(key_name)
386 | {
387 | static INPUT_KEYBOARD := 1, KEYEVENTF_KEYUP := 2, KEYEVENTF_SCANCODE := 8, InputSize := 16 + A_PtrSize*3
388 | Input_Index := (StrLen(key_name) == 1 && Ord(key_name) > 64 && Ord(key_name) < 91) ? 2 : 1
389 | VarSetCapacity(INPUTS, InputSize*Input_Index, 0)
390 | addr := &INPUTS, Scancode := GetKeySC(key_name)
391 | If Input_Index = 2
392 | addr := NumPut(2 | KEYEVENTF_SCANCODE | 0
393 | , NumPut(0x2A & 0xFF
394 | , NumPut(INPUT_KEYBOARD, addr + 0) + 2, "UShort"), "UInt" ) + 8 + A_PtrSize*2
395 | addr := NumPut(2 | KEYEVENTF_SCANCODE | 0
396 | , NumPut(Scancode & 0xFF
397 | , NumPut(INPUT_KEYBOARD, addr + 0) + 2, "UShort"), "UInt" ) + 8 + A_PtrSize*2
398 | DllCall("SendInput", "UInt", Input_Index, "Ptr", &INPUTS, "Int", InputSize)
399 | VarSetCapacity(INPUTS, 0) ;释放内存
400 | }
401 | ;==================================================================================
402 | ;键位按下
403 | key_down(key_name, sendinput_method := True)
404 | {
405 | If sendinput_method
406 | {
407 | key_sendinput_down(key_name)
408 | Return
409 | }
410 | If StrLen(key_name) == 1
411 | {
412 | If (Ord(key_name) > 64 && Ord(key_name) < 91)
413 | DllCall("keybd_event", "Int", 16, "Int", 42, "Int", 0, "Int", 0) ;Shift
414 | }
415 | VirtualKey := GetKeyVK(key_name)
416 | ScanCode := GetKeySC(key_name)
417 | DllCall("keybd_event", "Int", VirtualKey, "Int", ScanCode, "Int", 0, "Int", 0)
418 | }
419 | ;==================================================================================
420 | ;键位弹起
421 | key_up(key_name, sendinput_method := True)
422 | {
423 | If sendinput_method
424 | {
425 | key_sendinput_up(key_name)
426 | Return
427 | }
428 | If StrLen(key_name) == 1
429 | {
430 | If (Ord(key_name) > 64 && Ord(key_name) < 91)
431 | DllCall("keybd_event", "Int", 16, "Int", 42, "Int", 2, "Int", 0) ;Shift
432 | }
433 | VirtualKey := GetKeyVK(key_name)
434 | ScanCode := GetKeySC(key_name)
435 | DllCall("keybd_event", "Int", VirtualKey, "Int", ScanCode, "Int", 2, "Int", 0)
436 | }
437 | ;==================================================================================
438 | ;按键函数,鉴于Input模式下单纯的send速度不合要求而开发
439 | press_key(key_name, press_time, sleep_time, sendinput_method := True)
440 | {
441 | ;本机鼠标延迟测试,包括按下弹起
442 | If InStr(key_name, "Button")
443 | press_time -= 0.56, sleep_time -= 0.56
444 | Else
445 | press_time -= 0.24, sleep_time -= 0.24
446 |
447 | If !GetKeyState(key_name)
448 | {
449 | If InStr(key_name, "Button")
450 | sendinput_method ? mouse_sendinput_down(key_name) : mouse_down(key_name)
451 | Else
452 | sendinput_method ? key_sendinput_down(key_name) : key_down(key_name)
453 | }
454 | HyperSleep(press_time)
455 |
456 | If !GetKeyState(key_name, "P")
457 | {
458 | If InStr(key_name, "Button")
459 | sendinput_method ? mouse_sendinput_up(key_name) : mouse_up(key_name)
460 | Else
461 | sendinput_method ? key_sendinput_up(key_name) : key_up(key_name)
462 | }
463 | HyperSleep(sleep_time)
464 | }
465 | ;==================================================================================
466 |
--------------------------------------------------------------------------------
/yolov4/yolov4-custom.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | #batch=1
4 | #subdivisions=1
5 | # Training
6 | batch=64
7 | subdivisions=16
8 | width=512
9 | height=288
10 | channels=3
11 | momentum=0.949
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 6000
21 | policy=steps
22 | steps=4800,5400
23 | scales=.1,.1
24 |
25 | #cutmix=1
26 | mosaic=1
27 |
28 | #:104x104 54:52x52 85:26x26 104:13x13 for 416
29 |
30 | [convolutional]
31 | batch_normalize=1
32 | filters=32
33 | size=3
34 | stride=1
35 | pad=1
36 | activation=mish
37 |
38 | # Downsample
39 |
40 | [convolutional]
41 | batch_normalize=1
42 | filters=64
43 | size=3
44 | stride=2
45 | pad=1
46 | activation=mish
47 |
48 | [convolutional]
49 | batch_normalize=1
50 | filters=64
51 | size=1
52 | stride=1
53 | pad=1
54 | activation=mish
55 |
56 | [route]
57 | layers = -2
58 |
59 | [convolutional]
60 | batch_normalize=1
61 | filters=64
62 | size=1
63 | stride=1
64 | pad=1
65 | activation=mish
66 |
67 | [convolutional]
68 | batch_normalize=1
69 | filters=32
70 | size=1
71 | stride=1
72 | pad=1
73 | activation=mish
74 |
75 | [convolutional]
76 | batch_normalize=1
77 | filters=64
78 | size=3
79 | stride=1
80 | pad=1
81 | activation=mish
82 |
83 | [shortcut]
84 | from=-3
85 | activation=linear
86 |
87 | [convolutional]
88 | batch_normalize=1
89 | filters=64
90 | size=1
91 | stride=1
92 | pad=1
93 | activation=mish
94 |
95 | [route]
96 | layers = -1,-7
97 |
98 | [convolutional]
99 | batch_normalize=1
100 | filters=64
101 | size=1
102 | stride=1
103 | pad=1
104 | activation=mish
105 |
106 | # Downsample
107 |
108 | [convolutional]
109 | batch_normalize=1
110 | filters=128
111 | size=3
112 | stride=2
113 | pad=1
114 | activation=mish
115 |
116 | [convolutional]
117 | batch_normalize=1
118 | filters=64
119 | size=1
120 | stride=1
121 | pad=1
122 | activation=mish
123 |
124 | [route]
125 | layers = -2
126 |
127 | [convolutional]
128 | batch_normalize=1
129 | filters=64
130 | size=1
131 | stride=1
132 | pad=1
133 | activation=mish
134 |
135 | [convolutional]
136 | batch_normalize=1
137 | filters=64
138 | size=1
139 | stride=1
140 | pad=1
141 | activation=mish
142 |
143 | [convolutional]
144 | batch_normalize=1
145 | filters=64
146 | size=3
147 | stride=1
148 | pad=1
149 | activation=mish
150 |
151 | [shortcut]
152 | from=-3
153 | activation=linear
154 |
155 | [convolutional]
156 | batch_normalize=1
157 | filters=64
158 | size=1
159 | stride=1
160 | pad=1
161 | activation=mish
162 |
163 | [convolutional]
164 | batch_normalize=1
165 | filters=64
166 | size=3
167 | stride=1
168 | pad=1
169 | activation=mish
170 |
171 | [shortcut]
172 | from=-3
173 | activation=linear
174 |
175 | [convolutional]
176 | batch_normalize=1
177 | filters=64
178 | size=1
179 | stride=1
180 | pad=1
181 | activation=mish
182 |
183 | [route]
184 | layers = -1,-10
185 |
186 | [convolutional]
187 | batch_normalize=1
188 | filters=128
189 | size=1
190 | stride=1
191 | pad=1
192 | activation=mish
193 |
194 | # Downsample
195 |
196 | [convolutional]
197 | batch_normalize=1
198 | filters=256
199 | size=3
200 | stride=2
201 | pad=1
202 | activation=mish
203 |
204 | [convolutional]
205 | batch_normalize=1
206 | filters=128
207 | size=1
208 | stride=1
209 | pad=1
210 | activation=mish
211 |
212 | [route]
213 | layers = -2
214 |
215 | [convolutional]
216 | batch_normalize=1
217 | filters=128
218 | size=1
219 | stride=1
220 | pad=1
221 | activation=mish
222 |
223 | [convolutional]
224 | batch_normalize=1
225 | filters=128
226 | size=1
227 | stride=1
228 | pad=1
229 | activation=mish
230 |
231 | [convolutional]
232 | batch_normalize=1
233 | filters=128
234 | size=3
235 | stride=1
236 | pad=1
237 | activation=mish
238 |
239 | [shortcut]
240 | from=-3
241 | activation=linear
242 |
243 | [convolutional]
244 | batch_normalize=1
245 | filters=128
246 | size=1
247 | stride=1
248 | pad=1
249 | activation=mish
250 |
251 | [convolutional]
252 | batch_normalize=1
253 | filters=128
254 | size=3
255 | stride=1
256 | pad=1
257 | activation=mish
258 |
259 | [shortcut]
260 | from=-3
261 | activation=linear
262 |
263 | [convolutional]
264 | batch_normalize=1
265 | filters=128
266 | size=1
267 | stride=1
268 | pad=1
269 | activation=mish
270 |
271 | [convolutional]
272 | batch_normalize=1
273 | filters=128
274 | size=3
275 | stride=1
276 | pad=1
277 | activation=mish
278 |
279 | [shortcut]
280 | from=-3
281 | activation=linear
282 |
283 | [convolutional]
284 | batch_normalize=1
285 | filters=128
286 | size=1
287 | stride=1
288 | pad=1
289 | activation=mish
290 |
291 | [convolutional]
292 | batch_normalize=1
293 | filters=128
294 | size=3
295 | stride=1
296 | pad=1
297 | activation=mish
298 |
299 | [shortcut]
300 | from=-3
301 | activation=linear
302 |
303 |
304 | [convolutional]
305 | batch_normalize=1
306 | filters=128
307 | size=1
308 | stride=1
309 | pad=1
310 | activation=mish
311 |
312 | [convolutional]
313 | batch_normalize=1
314 | filters=128
315 | size=3
316 | stride=1
317 | pad=1
318 | activation=mish
319 |
320 | [shortcut]
321 | from=-3
322 | activation=linear
323 |
324 | [convolutional]
325 | batch_normalize=1
326 | filters=128
327 | size=1
328 | stride=1
329 | pad=1
330 | activation=mish
331 |
332 | [convolutional]
333 | batch_normalize=1
334 | filters=128
335 | size=3
336 | stride=1
337 | pad=1
338 | activation=mish
339 |
340 | [shortcut]
341 | from=-3
342 | activation=linear
343 |
344 | [convolutional]
345 | batch_normalize=1
346 | filters=128
347 | size=1
348 | stride=1
349 | pad=1
350 | activation=mish
351 |
352 | [convolutional]
353 | batch_normalize=1
354 | filters=128
355 | size=3
356 | stride=1
357 | pad=1
358 | activation=mish
359 |
360 | [shortcut]
361 | from=-3
362 | activation=linear
363 |
364 | [convolutional]
365 | batch_normalize=1
366 | filters=128
367 | size=1
368 | stride=1
369 | pad=1
370 | activation=mish
371 |
372 | [convolutional]
373 | batch_normalize=1
374 | filters=128
375 | size=3
376 | stride=1
377 | pad=1
378 | activation=mish
379 |
380 | [shortcut]
381 | from=-3
382 | activation=linear
383 |
384 | [convolutional]
385 | batch_normalize=1
386 | filters=128
387 | size=1
388 | stride=1
389 | pad=1
390 | activation=mish
391 |
392 | [route]
393 | layers = -1,-28
394 |
395 | [convolutional]
396 | batch_normalize=1
397 | filters=256
398 | size=1
399 | stride=1
400 | pad=1
401 | activation=mish
402 |
403 | # Downsample
404 |
405 | [convolutional]
406 | batch_normalize=1
407 | filters=512
408 | size=3
409 | stride=2
410 | pad=1
411 | activation=mish
412 |
413 | [convolutional]
414 | batch_normalize=1
415 | filters=256
416 | size=1
417 | stride=1
418 | pad=1
419 | activation=mish
420 |
421 | [route]
422 | layers = -2
423 |
424 | [convolutional]
425 | batch_normalize=1
426 | filters=256
427 | size=1
428 | stride=1
429 | pad=1
430 | activation=mish
431 |
432 | [convolutional]
433 | batch_normalize=1
434 | filters=256
435 | size=1
436 | stride=1
437 | pad=1
438 | activation=mish
439 |
440 | [convolutional]
441 | batch_normalize=1
442 | filters=256
443 | size=3
444 | stride=1
445 | pad=1
446 | activation=mish
447 |
448 | [shortcut]
449 | from=-3
450 | activation=linear
451 |
452 |
453 | [convolutional]
454 | batch_normalize=1
455 | filters=256
456 | size=1
457 | stride=1
458 | pad=1
459 | activation=mish
460 |
461 | [convolutional]
462 | batch_normalize=1
463 | filters=256
464 | size=3
465 | stride=1
466 | pad=1
467 | activation=mish
468 |
469 | [shortcut]
470 | from=-3
471 | activation=linear
472 |
473 |
474 | [convolutional]
475 | batch_normalize=1
476 | filters=256
477 | size=1
478 | stride=1
479 | pad=1
480 | activation=mish
481 |
482 | [convolutional]
483 | batch_normalize=1
484 | filters=256
485 | size=3
486 | stride=1
487 | pad=1
488 | activation=mish
489 |
490 | [shortcut]
491 | from=-3
492 | activation=linear
493 |
494 |
495 | [convolutional]
496 | batch_normalize=1
497 | filters=256
498 | size=1
499 | stride=1
500 | pad=1
501 | activation=mish
502 |
503 | [convolutional]
504 | batch_normalize=1
505 | filters=256
506 | size=3
507 | stride=1
508 | pad=1
509 | activation=mish
510 |
511 | [shortcut]
512 | from=-3
513 | activation=linear
514 |
515 |
516 | [convolutional]
517 | batch_normalize=1
518 | filters=256
519 | size=1
520 | stride=1
521 | pad=1
522 | activation=mish
523 |
524 | [convolutional]
525 | batch_normalize=1
526 | filters=256
527 | size=3
528 | stride=1
529 | pad=1
530 | activation=mish
531 |
532 | [shortcut]
533 | from=-3
534 | activation=linear
535 |
536 |
537 | [convolutional]
538 | batch_normalize=1
539 | filters=256
540 | size=1
541 | stride=1
542 | pad=1
543 | activation=mish
544 |
545 | [convolutional]
546 | batch_normalize=1
547 | filters=256
548 | size=3
549 | stride=1
550 | pad=1
551 | activation=mish
552 |
553 | [shortcut]
554 | from=-3
555 | activation=linear
556 |
557 |
558 | [convolutional]
559 | batch_normalize=1
560 | filters=256
561 | size=1
562 | stride=1
563 | pad=1
564 | activation=mish
565 |
566 | [convolutional]
567 | batch_normalize=1
568 | filters=256
569 | size=3
570 | stride=1
571 | pad=1
572 | activation=mish
573 |
574 | [shortcut]
575 | from=-3
576 | activation=linear
577 |
578 | [convolutional]
579 | batch_normalize=1
580 | filters=256
581 | size=1
582 | stride=1
583 | pad=1
584 | activation=mish
585 |
586 | [convolutional]
587 | batch_normalize=1
588 | filters=256
589 | size=3
590 | stride=1
591 | pad=1
592 | activation=mish
593 |
594 | [shortcut]
595 | from=-3
596 | activation=linear
597 |
598 | [convolutional]
599 | batch_normalize=1
600 | filters=256
601 | size=1
602 | stride=1
603 | pad=1
604 | activation=mish
605 |
606 | [route]
607 | layers = -1,-28
608 |
609 | [convolutional]
610 | batch_normalize=1
611 | filters=512
612 | size=1
613 | stride=1
614 | pad=1
615 | activation=mish
616 |
617 | # Downsample
618 |
619 | [convolutional]
620 | batch_normalize=1
621 | filters=1024
622 | size=3
623 | stride=2
624 | pad=1
625 | activation=mish
626 |
627 | [convolutional]
628 | batch_normalize=1
629 | filters=512
630 | size=1
631 | stride=1
632 | pad=1
633 | activation=mish
634 |
635 | [route]
636 | layers = -2
637 |
638 | [convolutional]
639 | batch_normalize=1
640 | filters=512
641 | size=1
642 | stride=1
643 | pad=1
644 | activation=mish
645 |
646 | [convolutional]
647 | batch_normalize=1
648 | filters=512
649 | size=1
650 | stride=1
651 | pad=1
652 | activation=mish
653 |
654 | [convolutional]
655 | batch_normalize=1
656 | filters=512
657 | size=3
658 | stride=1
659 | pad=1
660 | activation=mish
661 |
662 | [shortcut]
663 | from=-3
664 | activation=linear
665 |
666 | [convolutional]
667 | batch_normalize=1
668 | filters=512
669 | size=1
670 | stride=1
671 | pad=1
672 | activation=mish
673 |
674 | [convolutional]
675 | batch_normalize=1
676 | filters=512
677 | size=3
678 | stride=1
679 | pad=1
680 | activation=mish
681 |
682 | [shortcut]
683 | from=-3
684 | activation=linear
685 |
686 | [convolutional]
687 | batch_normalize=1
688 | filters=512
689 | size=1
690 | stride=1
691 | pad=1
692 | activation=mish
693 |
694 | [convolutional]
695 | batch_normalize=1
696 | filters=512
697 | size=3
698 | stride=1
699 | pad=1
700 | activation=mish
701 |
702 | [shortcut]
703 | from=-3
704 | activation=linear
705 |
706 | [convolutional]
707 | batch_normalize=1
708 | filters=512
709 | size=1
710 | stride=1
711 | pad=1
712 | activation=mish
713 |
714 | [convolutional]
715 | batch_normalize=1
716 | filters=512
717 | size=3
718 | stride=1
719 | pad=1
720 | activation=mish
721 |
722 | [shortcut]
723 | from=-3
724 | activation=linear
725 |
726 | [convolutional]
727 | batch_normalize=1
728 | filters=512
729 | size=1
730 | stride=1
731 | pad=1
732 | activation=mish
733 |
734 | [route]
735 | layers = -1,-16
736 |
737 | [convolutional]
738 | batch_normalize=1
739 | filters=1024
740 | size=1
741 | stride=1
742 | pad=1
743 | activation=mish
744 | stopbackward=800
745 |
746 | ##########################
747 |
748 | [convolutional]
749 | batch_normalize=1
750 | filters=512
751 | size=1
752 | stride=1
753 | pad=1
754 | activation=leaky
755 |
756 | [convolutional]
757 | batch_normalize=1
758 | size=3
759 | stride=1
760 | pad=1
761 | filters=1024
762 | activation=leaky
763 |
764 | [convolutional]
765 | batch_normalize=1
766 | filters=512
767 | size=1
768 | stride=1
769 | pad=1
770 | activation=leaky
771 |
772 | ### SPP ###
773 | [maxpool]
774 | stride=1
775 | size=5
776 |
777 | [route]
778 | layers=-2
779 |
780 | [maxpool]
781 | stride=1
782 | size=9
783 |
784 | [route]
785 | layers=-4
786 |
787 | [maxpool]
788 | stride=1
789 | size=13
790 |
791 | [route]
792 | layers=-1,-3,-5,-6
793 | ### End SPP ###
794 |
795 | [convolutional]
796 | batch_normalize=1
797 | filters=512
798 | size=1
799 | stride=1
800 | pad=1
801 | activation=leaky
802 |
803 | [convolutional]
804 | batch_normalize=1
805 | size=3
806 | stride=1
807 | pad=1
808 | filters=1024
809 | activation=leaky
810 |
811 | [convolutional]
812 | batch_normalize=1
813 | filters=512
814 | size=1
815 | stride=1
816 | pad=1
817 | activation=leaky
818 |
819 | [convolutional]
820 | batch_normalize=1
821 | filters=256
822 | size=1
823 | stride=1
824 | pad=1
825 | activation=leaky
826 |
827 | [upsample]
828 | stride=2
829 |
830 | [route]
831 | layers = 85
832 |
833 | [convolutional]
834 | batch_normalize=1
835 | filters=256
836 | size=1
837 | stride=1
838 | pad=1
839 | activation=leaky
840 |
841 | [route]
842 | layers = -1, -3
843 |
844 | [convolutional]
845 | batch_normalize=1
846 | filters=256
847 | size=1
848 | stride=1
849 | pad=1
850 | activation=leaky
851 |
852 | [convolutional]
853 | batch_normalize=1
854 | size=3
855 | stride=1
856 | pad=1
857 | filters=512
858 | activation=leaky
859 |
860 | [convolutional]
861 | batch_normalize=1
862 | filters=256
863 | size=1
864 | stride=1
865 | pad=1
866 | activation=leaky
867 |
868 | [convolutional]
869 | batch_normalize=1
870 | size=3
871 | stride=1
872 | pad=1
873 | filters=512
874 | activation=leaky
875 |
876 | [convolutional]
877 | batch_normalize=1
878 | filters=256
879 | size=1
880 | stride=1
881 | pad=1
882 | activation=leaky
883 |
884 | [convolutional]
885 | batch_normalize=1
886 | filters=128
887 | size=1
888 | stride=1
889 | pad=1
890 | activation=leaky
891 |
892 | [upsample]
893 | stride=2
894 |
895 | [route]
896 | layers = 54
897 |
898 | [convolutional]
899 | batch_normalize=1
900 | filters=128
901 | size=1
902 | stride=1
903 | pad=1
904 | activation=leaky
905 |
906 | [route]
907 | layers = -1, -3
908 |
909 | [convolutional]
910 | batch_normalize=1
911 | filters=128
912 | size=1
913 | stride=1
914 | pad=1
915 | activation=leaky
916 |
917 | [convolutional]
918 | batch_normalize=1
919 | size=3
920 | stride=1
921 | pad=1
922 | filters=256
923 | activation=leaky
924 |
925 | [convolutional]
926 | batch_normalize=1
927 | filters=128
928 | size=1
929 | stride=1
930 | pad=1
931 | activation=leaky
932 |
933 | [convolutional]
934 | batch_normalize=1
935 | size=3
936 | stride=1
937 | pad=1
938 | filters=256
939 | activation=leaky
940 |
941 | [convolutional]
942 | batch_normalize=1
943 | filters=128
944 | size=1
945 | stride=1
946 | pad=1
947 | activation=leaky
948 |
949 | ##########################
950 |
951 | [convolutional]
952 | batch_normalize=1
953 | size=3
954 | stride=1
955 | pad=1
956 | filters=256
957 | activation=leaky
958 |
959 | [convolutional]
960 | size=1
961 | stride=1
962 | pad=1
963 | filters=21
964 | activation=linear
965 |
966 |
967 | [yolo]
968 | mask = 0,1,2
969 | anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
970 | classes=2
971 | num=9
972 | jitter=.3
973 | ignore_thresh = .7
974 | truth_thresh = 1
975 | scale_x_y = 1.2
976 | iou_thresh=0.213
977 | cls_normalizer=1.0
978 | iou_normalizer=0.07
979 | iou_loss=ciou
980 | nms_kind=greedynms
981 | beta_nms=0.6
982 | max_delta=5
983 |
984 |
985 | [route]
986 | layers = -4
987 |
988 | [convolutional]
989 | batch_normalize=1
990 | size=3
991 | stride=2
992 | pad=1
993 | filters=256
994 | activation=leaky
995 |
996 | [route]
997 | layers = -1, -16
998 |
999 | [convolutional]
1000 | batch_normalize=1
1001 | filters=256
1002 | size=1
1003 | stride=1
1004 | pad=1
1005 | activation=leaky
1006 |
1007 | [convolutional]
1008 | batch_normalize=1
1009 | size=3
1010 | stride=1
1011 | pad=1
1012 | filters=512
1013 | activation=leaky
1014 |
1015 | [convolutional]
1016 | batch_normalize=1
1017 | filters=256
1018 | size=1
1019 | stride=1
1020 | pad=1
1021 | activation=leaky
1022 |
1023 | [convolutional]
1024 | batch_normalize=1
1025 | size=3
1026 | stride=1
1027 | pad=1
1028 | filters=512
1029 | activation=leaky
1030 |
1031 | [convolutional]
1032 | batch_normalize=1
1033 | filters=256
1034 | size=1
1035 | stride=1
1036 | pad=1
1037 | activation=leaky
1038 |
1039 | [convolutional]
1040 | batch_normalize=1
1041 | size=3
1042 | stride=1
1043 | pad=1
1044 | filters=512
1045 | activation=leaky
1046 |
1047 | [convolutional]
1048 | size=1
1049 | stride=1
1050 | pad=1
1051 | filters=21
1052 | activation=linear
1053 |
1054 |
1055 | [yolo]
1056 | mask = 3,4,5
1057 | anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
1058 | classes=2
1059 | num=9
1060 | jitter=.3
1061 | ignore_thresh = .7
1062 | truth_thresh = 1
1063 | scale_x_y = 1.1
1064 | iou_thresh=0.213
1065 | cls_normalizer=1.0
1066 | iou_normalizer=0.07
1067 | iou_loss=ciou
1068 | nms_kind=greedynms
1069 | beta_nms=0.6
1070 | max_delta=5
1071 |
1072 |
1073 | [route]
1074 | layers = -4
1075 |
1076 | [convolutional]
1077 | batch_normalize=1
1078 | size=3
1079 | stride=2
1080 | pad=1
1081 | filters=512
1082 | activation=leaky
1083 |
1084 | [route]
1085 | layers = -1, -37
1086 |
1087 | [convolutional]
1088 | batch_normalize=1
1089 | filters=512
1090 | size=1
1091 | stride=1
1092 | pad=1
1093 | activation=leaky
1094 |
1095 | [convolutional]
1096 | batch_normalize=1
1097 | size=3
1098 | stride=1
1099 | pad=1
1100 | filters=1024
1101 | activation=leaky
1102 |
1103 | [convolutional]
1104 | batch_normalize=1
1105 | filters=512
1106 | size=1
1107 | stride=1
1108 | pad=1
1109 | activation=leaky
1110 |
1111 | [convolutional]
1112 | batch_normalize=1
1113 | size=3
1114 | stride=1
1115 | pad=1
1116 | filters=1024
1117 | activation=leaky
1118 |
1119 | [convolutional]
1120 | batch_normalize=1
1121 | filters=512
1122 | size=1
1123 | stride=1
1124 | pad=1
1125 | activation=leaky
1126 |
1127 | [convolutional]
1128 | batch_normalize=1
1129 | size=3
1130 | stride=1
1131 | pad=1
1132 | filters=1024
1133 | activation=leaky
1134 |
1135 | [convolutional]
1136 | size=1
1137 | stride=1
1138 | pad=1
1139 | filters=21
1140 | activation=linear
1141 |
1142 |
1143 | [yolo]
1144 | mask = 6,7,8
1145 | anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
1146 | classes=2
1147 | num=9
1148 | jitter=.3
1149 | ignore_thresh = .7
1150 | truth_thresh = 1
1151 | random=1
1152 | scale_x_y = 1.05
1153 | iou_thresh=0.213
1154 | cls_normalizer=1.0
1155 | iou_normalizer=0.07
1156 | iou_loss=ciou
1157 | nms_kind=greedynms
1158 | beta_nms=0.6
1159 | max_delta=5
1160 |
1161 |
--------------------------------------------------------------------------------
/aimbot-exec/old/AI_M_BOT_X2.py:
--------------------------------------------------------------------------------
1 | '''
2 | Detection code modified from project AIMBOT-YOLO
3 | Detection code Author: monokim
4 | Detection project website: https://github.com/monokim/AIMBOT-YOLO
5 | Detection project video: https://www.youtube.com/watch?v=vQlb0tK1DH0
6 | Screenshot method from: https://www.youtube.com/watch?v=WymCpVUPWQ4
7 | Screenshot method code modified from project: opencv_tutorials
8 | Screenshot method code Author: Ben Johnson (learncodebygaming)
9 | Screenshot method website: https://github.com/learncodebygaming/opencv_tutorials
10 | '''
11 |
12 | from win32con import SRCCOPY, VK_LBUTTON, VK_END, PROCESS_ALL_ACCESS, SPI_GETMOUSE, SPI_SETMOUSE, SPI_GETMOUSESPEED, SPI_SETMOUSESPEED
13 | from win32api import GetAsyncKeyState, GetKeyState, GetCurrentProcessId, OpenProcess, mouse_event
14 | from multiprocessing import Process, Array, Pipe, freeze_support, JoinableQueue
15 | from win32con import MOUSEEVENTF_MOVE, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP
16 | from win32process import SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS
17 | from math import sqrt, pow, ceil, atan, cos, pi
18 | from sys import exit, executable, platform
19 | from collections import deque
20 | from statistics import median
21 | from time import sleep, time
22 | from platform import release
23 | from random import uniform
24 | from ctypes import windll
25 | from numba import njit
26 | import numpy as np
27 | import pywintypes
28 | import nvidia_smi
29 | import win32gui
30 | import win32ui
31 | import queue
32 | import cv2
33 | import os
34 |
35 |
36 | # 截图类
37 | class WindowCapture:
38 | # 类属性
39 | hwnd = '' # 窗口句柄
40 | windows_class = '' # 窗口类名
41 | total_w, total_h = 0, 0 # 窗口内宽高
42 | cut_w, cut_h = 0, 0 # 截取宽高
43 | offset_x, offset_y = 0, 0 # 窗口内偏移x,y
44 | actual_x, actual_y = 0, 0 # 截图左上角屏幕位置x,y
45 | left_corner = [0, 0] # 窗口左上角屏幕位置
46 | errors = 0 # 仅仅显示一次错误
47 |
48 | # 构造函数
49 | def __init__(self, window_class, window_hwnd):
50 | self.windows_class = window_class
51 | try:
52 | self.hwnd = win32gui.FindWindow(window_class, None)
53 | except pywintypes.error as e:
54 | print('找窗口错误\n' + str(e))
55 | if not self.hwnd:
56 | raise Exception(f'\033[1;31;40m窗口类名未找到: {window_class}')
57 | self.update_window_info()
58 |
59 | def update_window_info(self):
60 | try:
61 | # 获取窗口数据
62 | window_rect = win32gui.GetWindowRect(self.hwnd)
63 | client_rect = win32gui.GetClientRect(self.hwnd)
64 | self.left_corner = win32gui.ClientToScreen(self.hwnd, (0, 0))
65 |
66 | # 确认截图相关数据
67 | self.total_w = client_rect[2] - client_rect[0]
68 | self.total_h = client_rect[3] - client_rect[1]
69 | self.cut_h = self.total_h // 2
70 | self.cut_w = self.cut_h
71 | if self.windows_class == 'CrossFire': # 画面实际4:3简单拉平
72 | self.cut_w = int(self.cut_w * (self.total_w / self.total_h) * 3 / 4)
73 | self.offset_x = (self.total_w - self.cut_w) // 2 + self.left_corner[0] - window_rect[0]
74 | self.offset_y = (self.total_h - self.cut_h) // 2 + self.left_corner[1] - window_rect[1]
75 | self.actual_x = window_rect[0] + self.offset_x
76 | self.actual_y = window_rect[1] + self.offset_y
77 | except pywintypes.error as e:
78 | if self.errors < 2:
79 | print('获取窗口数据错误\n' + str(e))
80 | self.errors += 1
81 | pass
82 |
83 | def get_screenshot(self): # 只能在windows上使用
84 | self.update_window_info()
85 | # 获取截图相关
86 | try:
87 | wDC = win32gui.GetWindowDC(self.hwnd)
88 | dcObj = win32ui.CreateDCFromHandle(wDC)
89 | cDC = dcObj.CreateCompatibleDC()
90 | dataBitMap = win32ui.CreateBitmap()
91 | dataBitMap.CreateCompatibleBitmap(dcObj, self.cut_w, self.cut_h)
92 | cDC.SelectObject(dataBitMap)
93 | cDC.BitBlt((0, 0), (self.cut_w, self.cut_h), dcObj, (self.offset_x, self.offset_y), SRCCOPY)
94 |
95 | # 转换使得opencv可读
96 | signedIntsArray = dataBitMap.GetBitmapBits(True)
97 | cut_img = np.frombuffer(signedIntsArray, dtype='uint8')
98 | cut_img.shape = (self.cut_h, self.cut_w, 4)
99 |
100 | # 释放资源
101 | dcObj.DeleteDC()
102 | cDC.DeleteDC()
103 | win32gui.ReleaseDC(self.hwnd, wDC)
104 | win32gui.DeleteObject(dataBitMap.GetHandle())
105 |
106 | # 去除alpha
107 | cut_img = cut_img[..., :3]
108 |
109 | # 转换减少错误
110 | cut_img = np.ascontiguousarray(cut_img)
111 | return cut_img
112 | except (pywintypes.error, win32ui.error, ValueError):
113 | return None
114 |
115 | def get_cut_info(self):
116 | return self.cut_w, self.cut_h
117 |
118 | def get_actual_xy(self):
119 | return self.actual_x, self.actual_y
120 |
121 | def get_window_left(self):
122 | return win32gui.GetWindowRect(self.hwnd)[0]
123 |
124 | def get_side_len(self):
125 | return int(self.total_h / (2/3))
126 |
127 |
128 | # 分析类
129 | class FrameDetection:
130 | # 类属性
131 | side_length = 416 # 输入尺寸
132 | std_confidence = 0 # 置信度阀值
133 | conf_thd = 0.4 # 置信度阀值
134 | nms_thd = 0.3 # 非极大值抑制
135 | win_class_name = '' # 窗口类名
136 | CONFIG_FILE = ['./']
137 | WEIGHT_FILE = ['./']
138 | net = '' # 建立网络
139 | ln = ''
140 | errors = 0 # 仅仅显示一次错误
141 |
142 | # 构造函数
143 | def __init__(self, hwnd_value):
144 | self.win_class_name = win32gui.GetClassName(hwnd_value)
145 | self.std_confidence = {
146 | 'Valve001': 0.45,
147 | 'CrossFire': 0.45,
148 | }.get(self.win_class_name, 0.5)
149 |
150 | load_file('yolov4-tiny', self.CONFIG_FILE, self.WEIGHT_FILE)
151 | self.net = cv2.dnn.readNet(self.CONFIG_FILE[0], self.WEIGHT_FILE[0]) # 读取权重与配置文件
152 |
153 | # 读取YOLO神经网络内容
154 | self.ln = self.net.getLayerNames()
155 | self.ln = [self.ln[i[0] - 1] for i in self.net.getUnconnectedOutLayers()]
156 |
157 | # 检测并设置在GPU上运行图像识别
158 | if cv2.cuda.getCudaEnabledDeviceCount():
159 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
160 | gpu_eval = check_gpu()
161 | # self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)
162 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
163 | gpu_message = {
164 | 2: '小伙电脑顶呱呱啊',
165 | 1: '战斗完全木得问题',
166 | }.get(gpu_eval, '您的显卡配置不够')
167 | print(gpu_message)
168 | else:
169 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT)
170 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) # OPENCL
171 | print('您没有可识别的N卡')
172 |
173 | def detect(self, frames):
174 | try:
175 | if frames.any():
176 | frame_height, frame_width = frames.shape[:2]
177 | frame_height += 0
178 | frame_width += 0
179 | except (cv2.error, AttributeError, UnboundLocalError) as e:
180 | if self.errors < 2:
181 | print(str(e))
182 | self.errors += 1
183 | return 0, 0, 0, 0, 0, 0, 0, frames
184 |
185 | # 画实心框避免错误检测武器与手
186 | if self.win_class_name == 'CrossFire':
187 | cv2.rectangle(frames, (int(frame_width*3/5), int(frame_height*3/4)), (frame_width, frame_height), (127, 127, 127), cv2.FILLED)
188 | cv2.rectangle(frames, (0, int(frame_height*3/4)), (int(frame_width*2/5), frame_height), (127, 127, 127), cv2.FILLED)
189 | if frame_width / frame_height > 1.3:
190 | frame_width = int(frame_width / 4 * 3)
191 | dim = (frame_width, frame_height)
192 | frames = cv2.resize(frames, dim, interpolation=cv2.INTER_AREA)
193 | elif self.win_class_name == 'Valve001':
194 | cv2.rectangle(frames, (int(frame_width*3/4), int(frame_height*3/5)), (frame_width, frame_height), (127, 127, 127), cv2.FILLED)
195 | cv2.rectangle(frames, (0, int(frame_height*3/5)), (int(frame_width*1/4), frame_height), (127, 127, 127), cv2.FILLED)
196 |
197 | # 检测
198 | blob = cv2.dnn.blobFromImage(frames, 1 / 255.0, (self.side_length, self.side_length), swapRB=False, crop=False) # 转换为二进制大型对象
199 | self.net.setInput(blob)
200 | layerOutputs = np.vstack(self.net.forward(self.ln)) # 前向传播
201 | boxes, confidences = analyze(layerOutputs, self.std_confidence, frame_width, frame_height)
202 |
203 | # 初始化返回数值
204 | x0, y0, fire_range, fire_pos, fire_close, fire_ok = 0, 0, 0, 0, 0, 0
205 |
206 | # 移除重复
207 | indices = cv2.dnn.NMSBoxes(boxes, confidences, self.conf_thd, self.nms_thd)
208 |
209 | # 画框,计算距离框中心距离最小的威胁目标
210 | max_var = 0
211 | max_at = 0
212 | if len(indices) > 0:
213 | for j in indices.flatten():
214 | (x, y) = (boxes[j][0], boxes[j][1])
215 | (w, h) = (boxes[j][2], boxes[j][3])
216 | cv2.rectangle(frames, (int(x - w / 2), int(y - h / 2)), (int(x + w / 2), int(y + h / 2)), (0, 36, 255), 2)
217 | cv2.putText(frames, str(round(confidences[j], 3)), (x - 4*len(str(round(confidences[j], 3))), y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2, cv2.LINE_AA)
218 |
219 | # 计算威胁指数(正面画框面积的平方根除以鼠标移动到目标距离)
220 | h_factor = (0.3125 if h > w else 0)
221 | dist = sqrt(pow(frame_width / 2 - x, 2) + pow(frame_height / 2 - y + h * h_factor, 2))
222 |
223 | if dist:
224 | threat_var = pow(boxes[j][2] * boxes[j][3], 1/2) / dist
225 | if threat_var > max_var:
226 | max_var = threat_var
227 | max_at = j
228 | else:
229 | max_at = j
230 | break
231 |
232 | # 指向距离最近威胁的位移
233 | x0 = boxes[max_at][0] - frame_width / 2
234 | if boxes[max_at][3] > boxes[max_at][2]:
235 | y1 = boxes[max_at][1] - boxes[max_at][3] * 3 / 8 - frame_height / 2 # 爆头优先
236 | y2 = boxes[max_at][1] - boxes[max_at][3] / 4 - frame_height / 2 # 击中优先
237 | fire_close = (1 if frame_width / boxes[max_at][2] <= 8 else 0)
238 | if abs(y1) <= abs(y2) or fire_close:
239 | y0 = y1
240 | fire_range = boxes[max_at][2] / 8
241 | fire_pos = 1
242 | else:
243 | y0 = y2
244 | fire_range = boxes[max_at][2] / 4
245 | fire_pos = 2
246 | else:
247 | y0 = boxes[max_at][1] - frame_height / 2
248 | fire_range = min(boxes[max_at][2], boxes[max_at][3]) / 2
249 | fire_pos = 0
250 |
251 | xpos = x0 + frame_width / 2
252 | ypos = y0 + frame_height / 2
253 | cv2.line(frames, (frame_width // 2, frame_height // 2), (int(xpos), int(ypos)), (0, 0, 255), 2)
254 |
255 | # 查看是否已经指向目标
256 | if 1/4 * boxes[max_at][2] > abs(frame_width / 2 - boxes[max_at][0]) and 2/5 * boxes[max_at][3] > abs(frame_height / 2 - boxes[max_at][1]):
257 | fire_ok = 1
258 |
259 | return len(indices), int(x0), int(y0), int(ceil(fire_range)), fire_pos, fire_close, fire_ok, frames
260 |
261 |
262 | # 分析预测数据
263 | @njit(fastmath=True)
264 | def analyze(layerOutputs, std_confidence, frame_width, frame_height):
265 | boxes = []
266 | confidences = []
267 |
268 | # 检测目标,计算框内目标到框中心距离
269 | for outputs in layerOutputs:
270 | scores = outputs[5:]
271 | classID = np.argmax(scores)
272 | confidence = scores[classID]
273 | if confidence > std_confidence and classID == 0: # 人类/body为0
274 | X, Y, W, H = outputs[:4] * np.array([frame_width, frame_height, frame_width, frame_height])
275 | boxes.append([int(X), int(Y), int(W), int(H)])
276 | confidences.append(float(confidence))
277 |
278 | return boxes, confidences
279 |
280 |
281 | # 简单检查gpu是否够格
282 | def check_gpu():
283 | nvidia_smi.nvmlInit()
284 | gpu_handle = nvidia_smi.nvmlDeviceGetHandleByIndex(0) # 默认卡1
285 | gpu_name = nvidia_smi.nvmlDeviceGetName(gpu_handle)
286 | memory_info = nvidia_smi.nvmlDeviceGetMemoryInfo(gpu_handle)
287 | nvidia_smi.nvmlShutdown()
288 | if b'RTX' in gpu_name:
289 | return 2
290 | memory_total = memory_info.total / 1024 / 1024
291 | if memory_total > 3000:
292 | return 1
293 | return 0
294 |
295 |
296 | # 高DPI感知
297 | def set_dpi():
298 | if int(release()) >= 7:
299 | try:
300 | windll.shcore.SetProcessDpiAwareness(1)
301 | except AttributeError:
302 | windll.user32.SetProcessDPIAware()
303 | else:
304 | exit(0)
305 |
306 |
307 | # 检测是否全屏
308 | def is_full_screen(hWnd):
309 | try:
310 | full_screen_rect = (0, 0, windll.user32.GetSystemMetrics(0), windll.user32.GetSystemMetrics(1))
311 | window_rect = win32gui.GetWindowRect(hWnd)
312 | return window_rect == full_screen_rect
313 | except pywintypes.error as e:
314 | print('全屏检测错误\n' + str(e))
315 | return False
316 |
317 |
318 | # 确认窗口句柄与类名
319 | def get_window_info():
320 | supported_games = 'Valve001 CrossFire LaunchUnrealUWindowsClient LaunchCombatUWindowsClient UnrealWindow UnityWndClass'
321 | test_window = 'Notepad3 PX_WINDOW_CLASS Notepad Notepad++'
322 | class_name = ''
323 | hwnd_var = ''
324 | testing_purpose = False
325 | while not hwnd_var: # 等待游戏窗口出现
326 | hwnd_active = win32gui.GetForegroundWindow()
327 | try:
328 | class_name = win32gui.GetClassName(hwnd_active)
329 | except pywintypes.error:
330 | continue
331 |
332 | if class_name not in (supported_games + test_window):
333 | print('请使支持的游戏/程序窗口成为活动窗口...')
334 | else:
335 | try:
336 | hwnd_var = win32gui.FindWindow(class_name, None)
337 | except pywintypes.error:
338 | print('您正使用沙盒')
339 | hwnd_var = hwnd_active
340 | print('已找到窗口')
341 | if class_name in test_window:
342 | testing_purpose = True
343 | sleep(3)
344 | return class_name, hwnd_var, testing_purpose
345 |
346 |
347 | # 重启脚本
348 | def restart():
349 | windll.shell32.ShellExecuteW(None, 'runas', executable, __file__, None, 1)
350 | exit(0)
351 |
352 |
353 | # 退出脚本
354 | def close():
355 | if not arr[2]:
356 | show_proc.terminate()
357 | detect_proc.terminate()
358 |
359 |
360 | # 加载配置与权重文件
361 | def load_file(file, config_filename, weight_filename):
362 | cfg_filename = file + '.cfg'
363 | weights_filename = file + '.weights'
364 | config_filename[0] += cfg_filename
365 | weight_filename[0] += weights_filename
366 | return
367 |
368 |
369 | # 检测是否存在配置与权重文件
370 | def check_file(file):
371 | cfg_file = file + '.cfg'
372 | weights_file = file + '.weights'
373 | if not (os.path.isfile(cfg_file) and os.path.isfile(weights_file)):
374 | print(f'请下载{file}相关文件!!!')
375 | sleep(3)
376 | exit(0)
377 |
378 |
379 | # 检查是否为管理员权限
380 | def is_admin():
381 | try:
382 | return windll.shell32.IsUserAnAdmin()
383 | except OSError as err:
384 | print('OS error: {0}'.format(err))
385 | return False
386 |
387 |
388 | # 清空命令指示符输出
389 | def clear():
390 | _ = os.system('cls')
391 |
392 |
393 | # 移动鼠标(并射击)
394 | def control_mouse(a, b, fps_var, ranges, rate, go_fire, win_class, move_rx, move_ry):
395 | recoil_control = 0
396 | move_range = sqrt(pow(a, 2) + pow(b, 2))
397 | DPI_Var = windll.user32.GetDpiForWindow(window_hwnd_name) / 96
398 | move_rx, a = track_opt(move_rx, a, DPI_Var)
399 | move_ry, b = track_opt(move_ry, b, DPI_Var)
400 | enhanced_holdback = win32gui.SystemParametersInfo(SPI_GETMOUSE)
401 | if enhanced_holdback[1]:
402 | win32gui.SystemParametersInfo(SPI_SETMOUSE, [0, 0, 0], 0)
403 | mouse_speed = win32gui.SystemParametersInfo(SPI_GETMOUSESPEED)
404 | if mouse_speed != 10:
405 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, 10, 0)
406 |
407 | if fps_var and arr[17] and arr[11]:
408 | a = cos((pi - atan(a/arr[18])) / 2) * (2*arr[18]) / DPI_Var
409 | b = cos((pi - atan(b/arr[18])) / 2) * (2*arr[18]) / DPI_Var
410 | if move_range > 6 * ranges:
411 | a *= uniform(0.9, 1.1)
412 | b *= uniform(0.9, 1.1)
413 | fps_factor = pow(fps_var/3, 1/3)
414 | x0 = {
415 | 'CrossFire': a / 2.719 * (client_ratio / (4/3)) / fps_factor, # 32
416 | 'Valve001': a * 1.667 / fps_factor, # 2.5
417 | 'LaunchCombatUWindowsClient': a * 1.319 / fps_factor, # 10.0
418 | 'LaunchUnrealUWindowsClient': a / 2.557 / fps_factor, # 20
419 | }.get(win_class, a / fps_factor)
420 | (y0, recoil_control) = {
421 | 'CrossFire': (b / 2.719 * (client_ratio / (4/3)) / fps_factor, 4), # 32
422 | 'Valve001': (b * 1.667 / fps_factor, 4), # 2.5
423 | 'LaunchCombatUWindowsClient': (b * 1.319 / fps_factor, 4), # 10.0
424 | 'LaunchUnrealUWindowsClient': (b / 2.557 / fps_factor, 10), # 20
425 | }.get(win_class, (b / fps_factor, 2))
426 |
427 | if arr[12] == 1 or arr[14]:
428 | y0 += (recoil_control * shoot_times[0]) # 简易压枪
429 |
430 | # windll.user32.mouse_event(0x0001, int(round(x0)), int(round(y0)), 0, 0)
431 | mouse_event(MOUSEEVENTF_MOVE, int(round(x0)), int(round(y0)), 0, 0)
432 |
433 | # 不分敌友射击
434 | if win_class != 'CrossFire':
435 | if (go_fire or move_range < ranges) and arr[11]:
436 | if (time() * 1000 - up_time[0]) > rate:
437 | if not (GetAsyncKeyState(VK_LBUTTON) < 0 or GetKeyState(VK_LBUTTON) < 0):
438 | # windll.user32.mouse_event(0x0002, 0, 0, 0, 0)
439 | mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
440 | press_time[0] = int(time() * 1000)
441 | if (time() * 1000 - up_time[0]) <= 219.4:
442 | shoot_times[0] += 1
443 | if shoot_times[0] > 10:
444 | shoot_times[0] = 10
445 |
446 | if (GetAsyncKeyState(VK_LBUTTON) < 0 or GetKeyState(VK_LBUTTON) < 0):
447 | if (time() * 1000 - press_time[0]) > 30.6 or not arr[11]:
448 | # windll.user32.mouse_event(0x0004, 0, 0, 0, 0)
449 | mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
450 | up_time[0] = int(time() * 1000)
451 |
452 | if (time() * 1000 - up_time[0]) > 219.4:
453 | shoot_times[0] = 0
454 |
455 | if enhanced_holdback[1]:
456 | win32gui.SystemParametersInfo(SPI_SETMOUSE, enhanced_holdback, 0)
457 | if mouse_speed != 10:
458 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, mouse_speed, 0)
459 |
460 | return move_rx, move_ry
461 |
462 |
463 | # 追踪优化
464 | def track_opt(record_list, range_m, vDPI):
465 | if len(record_list):
466 | if abs(median(record_list) - range_m) <= 10*vDPI and abs(range_m) <= 100*vDPI:
467 | record_list.append(range_m)
468 | else:
469 | record_list.clear()
470 | if len(record_list) > sqrt(show_fps[0]) and arr[4]:
471 | range_m *= pow(show_fps[0]/2, 1/3)
472 | record_list.clear()
473 | else:
474 | record_list.append(range_m)
475 |
476 | return record_list, range_m
477 |
478 |
479 | # 转变状态
480 | def check_status(exit0, mouse):
481 | if GetAsyncKeyState(VK_END) < 0: # End
482 | exit0 = True
483 | if GetAsyncKeyState(0x31) < 0: # 1
484 | mouse = 1
485 | arr[15] = 1
486 | if GetAsyncKeyState(0x32) < 0: # 2
487 | mouse = 2
488 | arr[15] = 2
489 | if GetAsyncKeyState(0x33) < 0 or GetAsyncKeyState(0x34) < 0: # 3,4
490 | mouse = 0
491 | arr[15] = 0
492 | if GetAsyncKeyState(0x46) < 0: # F
493 | arr[17] = 1
494 | if GetAsyncKeyState(0x4A) < 0: # J
495 | arr[17] = 0
496 | if GetAsyncKeyState(0x50) < 0: # P
497 | close()
498 | restart()
499 |
500 | return exit0, mouse
501 |
502 |
503 | # 多线程展示效果
504 | def show_frames(output_pipe, array):
505 | set_dpi()
506 | cv2.namedWindow('Show frame', cv2.WINDOW_KEEPRATIO)
507 | cv2.moveWindow('Show frame', 0, 0)
508 | cv2.destroyAllWindows()
509 | font = cv2.FONT_HERSHEY_SIMPLEX # 效果展示字体
510 | fire_target_show = ['middle', 'head', 'chest']
511 | while True:
512 | show_img = output_pipe.recv()
513 | show_color = {
514 | 0: (127, 127, 127),
515 | 1: (255, 255, 0),
516 | 2: (0, 255, 0)
517 | }.get(array[4])
518 | try:
519 | img_ex = np.zeros((1, 1, 3), np.uint8)
520 | show_str0 = str('{:03.0f}'.format(array[3]))
521 | show_str1 = 'Detected ' + str('{:02.0f}'.format(array[11])) + ' targets'
522 | show_str2 = 'Aiming at ' + fire_target_show[array[12]] + ' position'
523 | show_str3 = 'Fire rate is at ' + str('{:02.0f}'.format((10000 / (array[13] + 306)))) + ' RPS'
524 | show_str4 = 'Please enjoy coding ^_^' if array[17] else 'Please enjoy coding @_@'
525 | if show_img.any():
526 | show_img = cv2.resize(show_img, (array[5], array[5]))
527 | img_ex = cv2.resize(img_ex, (array[5], int(array[5] / 2)))
528 | cv2.putText(show_img, show_str0, (int(array[5] / 25), int(array[5] / 12)), font, array[5] / 600, (127, 255, 0), 2, cv2.LINE_AA)
529 | cv2.putText(img_ex, show_str1, (10, int(array[5] / 9)), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
530 | cv2.putText(img_ex, show_str2, (10, int(array[5] / 9) * 2), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
531 | cv2.putText(img_ex, show_str3, (10, int(array[5] / 9) * 3), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
532 | cv2.putText(img_ex, show_str4, (10, int(array[5] / 9) * 4), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
533 | show_image = cv2.vconcat([show_img, img_ex])
534 | cv2.imshow('Show frame', show_image)
535 | cv2.waitKey(1)
536 | except (AttributeError, cv2.error):
537 | cv2.destroyAllWindows()
538 |
539 |
540 | # 分析进程
541 | def detection(que, array, frame_in):
542 | Analysis = FrameDetection(array[0])
543 | array[1] = 1
544 | while True:
545 | if not que.empty():
546 | try:
547 | frame = que.get_nowait()
548 | que.task_done()
549 | array[1] = 2
550 | if array[10]:
551 | array[11], array[7], array[8], array[9], array[12], array[14], array[16], frame = Analysis.detect(frame)
552 | if not array[2]:
553 | frame_in.send(frame)
554 | except (queue.Empty, TypeError):
555 | continue
556 | array[1] = 1
557 |
558 |
559 | # 主程序
560 | if __name__ == '__main__':
561 | # 为了Pyinstaller顺利生成exe
562 | freeze_support()
563 |
564 | # 检查管理员权限
565 | if not is_admin():
566 | restart()
567 |
568 | # 设置高DPI不受影响
569 | set_dpi()
570 |
571 | # 设置工作路径
572 | os.chdir(os.path.dirname(os.path.abspath(__file__)))
573 |
574 | # 滑稽
575 | Conan = -1
576 | while not (2 >= Conan >= 0):
577 | user_choice = input('柯南能在本程序作者有生之年完结吗?(1:能, 2:能, 0:不能): ')
578 | try:
579 | Conan = int(user_choice)
580 | except ValueError:
581 | print('呵呵...请重新输入')
582 | else:
583 | if not (2 >= Conan >= 0):
584 | print('请在给定范围选择')
585 |
586 | # 初始化变量以及提升进程优先级
587 | if platform == 'win32':
588 | pid = GetCurrentProcessId()
589 | handle = OpenProcess(PROCESS_ALL_ACCESS, True, pid)
590 | SetPriorityClass(handle, ABOVE_NORMAL_PRIORITY_CLASS)
591 | else:
592 | os.nice(1)
593 |
594 | queue = JoinableQueue() # 初始化队列
595 | frame_output, frame_input = Pipe(False) # 初始化管道(receiving,sending)
596 | press_time, up_time, show_fps = [0], [0], [1]
597 | process_time = deque()
598 | exit_program = False
599 | test_win = [False]
600 | move_record_x = []
601 | move_record_y = []
602 | shoot_times = [0]
603 |
604 | # 如果文件不存在则退出
605 | check_file('yolov4-tiny')
606 |
607 | # 分享数据以及展示新进程
608 | arr = Array('i', range(21))
609 | '''
610 | 0 窗口句柄
611 | 1 分析进程状态
612 | 2 是否全屏
613 | 3 截图FPS整数值
614 | 4 控制鼠标
615 | 5 左侧距离除数
616 | 6 使用GPU/CPU(1/0)
617 | 7 鼠标移动x
618 | 8 鼠标移动y
619 | 9 鼠标开火r
620 | 10 柯南
621 | 11 敌人数量
622 | 12 瞄准位置
623 | 13 射击速度
624 | 14 敌人近否
625 | 15 所持武器
626 | 16 指向身体
627 | 17 自瞄自火
628 | 18 基础边长
629 | '''
630 | arr[1] = 0 # 分析进程状态
631 | arr[2] = 0 # 是否全屏
632 | arr[3] = 0 # FPS值
633 | arr[4] = 0 # 控制鼠标
634 | arr[7] = 0 # 鼠标移动x
635 | arr[8] = 0 # 鼠标移动r
636 | arr[9] = 0 # 鼠标开火r
637 | arr[10] = Conan # 柯南
638 | arr[11] = 0 # 敌人数量
639 | arr[12] = 0 # 瞄准位置(0中1头2胸)
640 | arr[13] = 944 # 射击速度
641 | arr[14] = 0 # 敌人近否
642 | arr[15] = 0 # 所持武器(0无1主2副)
643 | arr[16] = 0 # 指向身体
644 | arr[17] = 1 # 自瞄/自火
645 | arr[18] = 0 # 基础边长
646 | detect_proc = Process(target=detection, args=(queue, arr, frame_input,))
647 |
648 | # 寻找读取游戏窗口类型并确认截取位置
649 | window_class_name, window_hwnd_name, test_win[0] = get_window_info()
650 | arr[0] = window_hwnd_name
651 |
652 | # 如果非全屏则展示效果
653 | arr[2] = 1 if is_full_screen(window_hwnd_name) else 0
654 | if not arr[2]:
655 | show_proc = Process(target=show_frames, args=(frame_output, arr,))
656 | show_proc.start()
657 | else:
658 | print('全屏模式下不会有小窗口...')
659 |
660 | # 等待游戏画面完整出现(拥有大于0的长宽)
661 | window_ready = 0
662 | while not window_ready:
663 | sleep(1)
664 | win_client_rect = win32gui.GetClientRect(window_hwnd_name)
665 | if win_client_rect[2] - win_client_rect[0] > 0 and win_client_rect[3] - win_client_rect[1] > 0:
666 | window_ready = 1
667 | client_ratio = (win_client_rect[2] - win_client_rect[0]) / (win_client_rect[3] - win_client_rect[1])
668 |
669 | # 初始化截图类
670 | win_cap = WindowCapture(window_class_name, window_hwnd_name)
671 |
672 | # 计算基础边长
673 | arr[18] = win_cap.get_side_len()
674 |
675 | # 开始分析进程
676 | detect_proc.start()
677 |
678 | # 等待分析类初始化
679 | while not arr[1]:
680 | sleep(4)
681 |
682 | # 清空命令指示符面板
683 | # clear()
684 |
685 | ini_sct_time = 0 # 初始化计时
686 | small_float = np.finfo(np.float64).eps # 初始化一个尽可能小却小得不过分的数
687 |
688 | while True:
689 | screenshot = win_cap.get_screenshot()
690 |
691 | try:
692 | screenshot.any()
693 | arr[5] = (150 if win_cap.get_window_left() - 10 < 150 else win_cap.get_window_left() - 10)
694 | except (AttributeError, pywintypes.error) as e:
695 | print('窗口已关闭\n' + str(e))
696 | break
697 |
698 | queue.put_nowait(screenshot)
699 | queue.join()
700 |
701 | exit_program, arr[4] = check_status(exit_program, arr[4])
702 |
703 | if exit_program:
704 | break
705 |
706 | if win32gui.GetForegroundWindow() == window_hwnd_name and not test_win[0]:
707 | if arr[4]: # 是否需要控制鼠标
708 | if arr[15] == 1: # 主武器
709 | arr[13] = (944 if arr[14] or arr[12] != 1 else 1694)
710 | elif arr[15] == 2: # 副武器
711 | arr[13] = (694 if arr[14] or arr[12] != 1 else 944)
712 | move_record_x, move_record_y = control_mouse(arr[7], arr[8], show_fps[0], arr[9], arr[13] / 10, arr[16], window_class_name, move_record_x, move_record_y)
713 |
714 | time_used = time() - ini_sct_time
715 | ini_sct_time = time()
716 | current_fps = 1 / (time_used + small_float)
717 | process_time.append(current_fps)
718 | if len(process_time) > 119:
719 | process_time.popleft()
720 |
721 | show_fps[0] = median(process_time) # 计算fps
722 | arr[3] = int(show_fps[0])
723 |
724 | close()
725 | exit(0)
726 |
--------------------------------------------------------------------------------
/aimbot-exec/old/AI_M_BOT_X1.py:
--------------------------------------------------------------------------------
1 | '''
2 | Detection code modified from project AIMBOT-YOLO
3 | Detection code Author: monokim
4 | Detection project website: https://github.com/monokim/AIMBOT-YOLO
5 | Detection project video: https://www.youtube.com/watch?v=vQlb0tK1DH0
6 | Screenshot method from: https://www.youtube.com/watch?v=WymCpVUPWQ4
7 | Screenshot method code modified from project: opencv_tutorials
8 | Screenshot method code Author: Ben Johnson (learncodebygaming)
9 | Screenshot method website: https://github.com/learncodebygaming/opencv_tutorials
10 | '''
11 |
12 | from win32con import VK_LBUTTON, VK_END, PROCESS_ALL_ACCESS, SPI_GETMOUSE, SPI_SETMOUSE, SPI_GETMOUSESPEED, SPI_SETMOUSESPEED
13 | from win32api import GetAsyncKeyState, GetKeyState, GetCurrentProcessId, OpenProcess
14 | from ctypes import windll, c_long, c_ulong, Structure, Union, c_int, POINTER, sizeof
15 | from multiprocessing import Process, Array, Pipe, freeze_support, JoinableQueue
16 | from win32process import SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS
17 | from math import sqrt, pow, ceil, atan, cos, pi
18 | from sys import exit, executable, platform
19 | from collections import deque
20 | from statistics import median
21 | from time import sleep, time
22 | from platform import release
23 | from random import uniform
24 | import numpy as np
25 | import pywintypes
26 | import nvidia_smi
27 | import win32gui
28 | import pynvml
29 | import queue
30 | import mss
31 | import cv2
32 | import os
33 |
34 |
35 | # ↓↓↓↓↓↓↓↓↓ 简易鼠标行为模拟,使用SendInput函数 ↓↓↓↓↓↓↓↓↓
36 | LONG = c_long
37 | DWORD = c_ulong
38 | ULONG_PTR = POINTER(DWORD)
39 |
40 | class MOUSEINPUT(Structure):
41 | _fields_ = (('dx', LONG),
42 | ('dy', LONG),
43 | ('mouseData', DWORD),
44 | ('dwFlags', DWORD),
45 | ('time', DWORD),
46 | ('dwExtraInfo', ULONG_PTR))
47 |
48 | class _INPUTunion(Union):
49 | _fields_ = (('mi', MOUSEINPUT), ('mi', MOUSEINPUT))
50 |
51 | class INPUT(Structure):
52 | _fields_ = (('type', DWORD),
53 | ('union', _INPUTunion))
54 |
55 | def SendInput(*inputs):
56 | nInputs = len(inputs)
57 | LPINPUT = INPUT * nInputs
58 | pInputs = LPINPUT(*inputs)
59 | cbSize = c_int(sizeof(INPUT))
60 | return windll.user32.SendInput(nInputs, pInputs, cbSize)
61 |
62 | def Input(structure):
63 | return INPUT(0, _INPUTunion(mi=structure))
64 |
65 | def MouseInput(flags, x, y, data):
66 | return MOUSEINPUT(x, y, data, flags, 0, None)
67 |
68 | def Mouse(flags, x=0, y=0, data=0):
69 | return Input(MouseInput(flags, x, y, data))
70 |
71 | def sp_mouse_xy(x, y):
72 | return SendInput(Mouse(0x0001, x, y))
73 |
74 | def sp_mouse_down(key = 'LButton'):
75 | if key == 'LButton':
76 | return SendInput(Mouse(0x0002))
77 | elif key == 'RButton':
78 | return SendInput(Mouse(0x0008))
79 |
80 | def sp_mouse_up(key = 'LButton'):
81 | if key == 'LButton':
82 | return SendInput(Mouse(0x0004))
83 | elif key == 'RButton':
84 | return SendInput(Mouse(0x0010))
85 | # ↑↑↑↑↑↑↑↑↑ 简易鼠标行为模拟,使用SendInput函数 ↑↑↑↑↑↑↑↑↑
86 |
87 |
88 | # 截图类
89 | class WindowCapture:
90 | # 类属性
91 | hwnd = '' # 窗口句柄
92 | windows_class = '' # 窗口类名
93 | total_w, total_h = 0, 0 # 窗口内宽高
94 | cut_w, cut_h = 0, 0 # 截取宽高
95 | offset_x, offset_y = 0, 0 # 窗口内偏移x,y
96 | actual_x, actual_y = 0, 0 # 截图左上角屏幕位置x,y
97 | left_corner = [0, 0] # 窗口左上角屏幕位置
98 | sct = mss.mss() # 初始化mss截图
99 | errors = 0 # 仅仅显示一次错误
100 |
101 | # 构造函数
102 | def __init__(self, window_class, window_hwnd):
103 | self.windows_class = window_class
104 | try:
105 | self.hwnd = win32gui.FindWindow(window_class, None)
106 | except pywintypes.error as e:
107 | print('找窗口错误\n' + str(e))
108 | if not self.hwnd:
109 | raise Exception(f'\033[1;31;40m窗口类名未找到: {window_class}')
110 | self.update_window_info()
111 |
112 | def update_window_info(self):
113 | try:
114 | # 获取窗口数据
115 | window_rect = win32gui.GetWindowRect(self.hwnd)
116 | client_rect = win32gui.GetClientRect(self.hwnd)
117 | self.left_corner = win32gui.ClientToScreen(self.hwnd, (0, 0))
118 |
119 | # 确认截图相关数据
120 | self.total_w = client_rect[2] - client_rect[0]
121 | self.total_h = client_rect[3] - client_rect[1]
122 | self.cut_h = self.total_h // 2
123 | self.cut_w = self.cut_h
124 | if self.windows_class == 'CrossFire': # 画面实际4:3简单拉平
125 | self.cut_w = int(self.cut_w * (self.total_w / self.total_h) * 3 / 4)
126 | self.offset_x = (self.total_w - self.cut_w) // 2 + self.left_corner[0] - window_rect[0]
127 | self.offset_y = (self.total_h - self.cut_h) // 2 + self.left_corner[1] - window_rect[1]
128 | self.actual_x = window_rect[0] + self.offset_x
129 | self.actual_y = window_rect[1] + self.offset_y
130 | except pywintypes.error as e:
131 | if self.errors < 2:
132 | print('获取窗口数据错误\n' + str(e))
133 | self.errors += 1
134 | pass
135 |
136 | def get_cut_info(self):
137 | return self.cut_w, self.cut_h
138 |
139 | def get_actual_xy(self):
140 | return self.actual_x, self.actual_y
141 |
142 | def get_window_left(self):
143 | return win32gui.GetWindowRect(self.hwnd)[0]
144 |
145 | def get_side_len(self):
146 | return int(self.total_h / (2/3))
147 |
148 | def get_region(self):
149 | self.update_window_info()
150 | return (self.actual_x, self.actual_y, self.actual_x + self.cut_w, self.actual_y + self.cut_h)
151 |
152 | def grab_screenshot(self):
153 | return cv2.cvtColor(np.array(self.sct.grab(self.get_region())), cv2.COLOR_RGBA2RGB)
154 |
155 |
156 | # 分析类
157 | class FrameDetection:
158 | # 类属性
159 | side_length = 416 # 输入尺寸
160 | std_confidence = 0 # 置信度阀值
161 | conf_thd = 0.4 # 置信度阀值
162 | nms_thd = 0.3 # 非极大值抑制
163 | win_class_name = '' # 窗口类名
164 | class_names = '' # 检测类名
165 | CONFIG_FILE = ['./']
166 | WEIGHT_FILE = ['./']
167 | COLORS = []
168 | model = '' # 建立模型
169 | net = '' # 建立网络
170 | errors = 0 # 仅仅显示一次错误
171 |
172 | # 构造函数
173 | def __init__(self, hwnd_value):
174 | self.win_class_name = win32gui.GetClassName(hwnd_value)
175 | self.std_confidence = {
176 | 'Valve001': 0.45,
177 | 'CrossFire': 0.45,
178 | }.get(self.win_class_name, 0.5)
179 |
180 | load_file('yolov4-tiny', self.CONFIG_FILE, self.WEIGHT_FILE)
181 | self.net = cv2.dnn.readNet(self.CONFIG_FILE[0], self.WEIGHT_FILE[0]) # 读取权重与配置文件
182 | self.model = cv2.dnn_DetectionModel(self.net)
183 | self.model.setInputParams(size=(self.side_length, self.side_length), scale=1/255, swapRB=False)
184 | try:
185 | with open('classes.txt', 'r') as f:
186 | self.class_names = [cname.strip() for cname in f.readlines()]
187 | except FileNotFoundError:
188 | self.class_names = ['human-head', 'human-body']
189 | for i in range(len(self.class_names)):
190 | self.COLORS.append(tuple(np.random.randint(256, size=3).tolist()))
191 |
192 | # 检测并设置在GPU上运行图像识别
193 | if cv2.cuda.getCudaEnabledDeviceCount():
194 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
195 | gpu_eval = check_gpu()
196 | # self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)
197 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
198 | gpu_message = {
199 | 2: '小伙电脑顶呱呱啊',
200 | 1: '战斗完全木得问题',
201 | }.get(gpu_eval, '您的显卡配置不够')
202 | print(gpu_message)
203 | else:
204 | self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT)
205 | self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) # OPENCL
206 | print('您没有可识别的N卡')
207 |
208 | def detect(self, frames):
209 | try:
210 | if frames.any():
211 | frame_height, frame_width = frames.shape[:2]
212 | frame_height += 0
213 | frame_width += 0
214 | except (cv2.error, AttributeError, UnboundLocalError) as e:
215 | if self.errors < 2:
216 | print(str(e))
217 | self.errors += 1
218 | return 0, 0, 0, 0, 0, 0, 0, frames
219 |
220 | # 画实心框避免错误检测武器与手
221 | if self.win_class_name == 'CrossFire':
222 | cv2.rectangle(frames, (int(frame_width*3/5), int(frame_height*3/4)), (frame_width, frame_height), (127, 127, 127), cv2.FILLED)
223 | cv2.rectangle(frames, (0, int(frame_height*3/4)), (int(frame_width*2/5), frame_height), (127, 127, 127), cv2.FILLED)
224 | if frame_width / frame_height > 1.3:
225 | frame_width = int(frame_width / 4 * 3)
226 | dim = (frame_width, frame_height)
227 | frames = cv2.resize(frames, dim, interpolation=cv2.INTER_AREA)
228 | elif self.win_class_name == 'Valve001':
229 | cv2.rectangle(frames, (int(frame_width*3/4), int(frame_height*3/5)), (frame_width, frame_height), (127, 127, 127), cv2.FILLED)
230 | cv2.rectangle(frames, (0, int(frame_height*3/5)), (int(frame_width*1/4), frame_height), (127, 127, 127), cv2.FILLED)
231 |
232 | # 初始化返回数值
233 | x0, y0, fire_range, fire_pos, fire_close, fire_ok = 0, 0, 0, 0, 0, 0
234 |
235 | # 检测
236 | classes, scores, boxes = self.model.detect(frames, self.conf_thd, self.nms_thd)
237 | threat_list = []
238 |
239 | # 画框
240 | for (classid, score, box) in zip(classes, scores, boxes):
241 | if score > self.std_confidence:
242 | color = self.COLORS[int(classid) % len(self.COLORS)]
243 | label = self.class_names[classid[0]] + ': ' + str(round(score[0], 3))
244 | x, y, w, h = box
245 | cv2.rectangle(frames, (x, y), (x + w, y + h), color, 2)
246 | cv2.putText(frames, label, (int(x + w/2 - 4*len(label)), int(y + h/2 - 8)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)
247 |
248 | # 计算威胁指数(正面画框面积的平方根除以鼠标移动到目标距离)
249 | if classid == 0:
250 | h_factor = (0.1875 if h > w else 0.5)
251 | dist = sqrt(pow(frame_width / 2 - (x + w / 2), 2) + pow(frame_height / 2 - (y + h * h_factor), 2))
252 | threat_var = -(pow(w * h, 1/2) / dist if dist else 999)
253 | threat_list.append([threat_var, box])
254 |
255 | if len(threat_list):
256 | threat_list.sort(key=lambda x:x[0])
257 | x_tht, y_tht, w_tht, h_tht = threat_list[0][1]
258 |
259 | # 指向距离最近威胁的位移
260 | x0 = x_tht + (w_tht - frame_width) / 2
261 | if h_tht > w_tht:
262 | y1 = y_tht + h_tht / 8 - frame_height / 2 # 爆头优先
263 | y2 = y_tht + h_tht / 4 - frame_height / 2 # 击中优先
264 | fire_close = (1 if frame_width / w_tht <= 8 else 0)
265 | if abs(y1) <= abs(y2) or fire_close:
266 | y0 = y1
267 | fire_range = w_tht / 8
268 | fire_pos = 1
269 | else:
270 | y0 = y2
271 | fire_range = w_tht / 4
272 | fire_pos = 2
273 | else:
274 | y0 = y_tht + (h_tht - frame_height) / 2
275 | fire_range = min(w_tht, h_tht) / 2
276 | fire_pos = 0
277 |
278 | xpos = x0 + frame_width / 2
279 | ypos = y0 + frame_height / 2
280 | cv2.line(frames, (frame_width // 2, frame_height // 2), (int(xpos), int(ypos)), (0, 0, 255), 2)
281 |
282 | # 查看是否已经指向目标
283 | if 1/4 * w_tht > abs(frame_width / 2 - x_tht - w_tht / 2) and 2/5 * h_tht > abs(frame_height / 2 - y_tht - h_tht / 2):
284 | fire_ok = 1
285 |
286 | return len(threat_list), int(x0), int(y0), int(ceil(fire_range)), fire_pos, fire_close, fire_ok, frames
287 |
288 |
289 | # 简单检查gpu是否够格
290 | def check_gpu():
291 | try:
292 | pynvml.nvmlInit()
293 | gpu_handle = pynvml.nvmlDeviceGetHandleByIndex(0) # 默认卡1
294 | gpu_name = pynvml.nvmlDeviceGetName(gpu_handle)
295 | memory_info = pynvml.nvmlDeviceGetMemoryInfo(gpu_handle)
296 | pynvml.nvmlShutdown()
297 | except (FileNotFoundError, pynvml.nvml.NVML_ERROR_LIBRARY_NOT_FOUND) as e:
298 | print(str(e))
299 | nvidia_smi.nvmlInit()
300 | gpu_handle = nvidia_smi.nvmlDeviceGetHandleByIndex(0) # 默认卡1
301 | gpu_name = nvidia_smi.nvmlDeviceGetName(gpu_handle)
302 | memory_info = nvidia_smi.nvmlDeviceGetMemoryInfo(gpu_handle)
303 | nvidia_smi.nvmlShutdown()
304 | if b'RTX' in gpu_name:
305 | return 2
306 | memory_total = memory_info.total / 1024 / 1024
307 | if memory_total > 3000:
308 | return 1
309 | return 0
310 |
311 |
312 | # 高DPI感知
313 | def set_dpi():
314 | if int(release()) >= 7:
315 | try:
316 | windll.shcore.SetProcessDpiAwareness(1)
317 | except AttributeError:
318 | windll.user32.SetProcessDPIAware()
319 | else:
320 | exit(0)
321 |
322 |
323 | # 检测是否全屏
324 | def is_full_screen(hWnd):
325 | try:
326 | full_screen_rect = (0, 0, windll.user32.GetSystemMetrics(0), windll.user32.GetSystemMetrics(1))
327 | window_rect = win32gui.GetWindowRect(hWnd)
328 | return window_rect == full_screen_rect
329 | except pywintypes.error as e:
330 | print('全屏检测错误\n' + str(e))
331 | return False
332 |
333 |
334 | # 确认窗口句柄与类名
335 | def get_window_info():
336 | supported_games = 'Valve001 CrossFire LaunchUnrealUWindowsClient LaunchCombatUWindowsClient UnrealWindow UnityWndClass'
337 | test_window = 'Notepad3 PX_WINDOW_CLASS Notepad Notepad++'
338 | class_name = ''
339 | hwnd_var = ''
340 | testing_purpose = False
341 | while not hwnd_var: # 等待游戏窗口出现
342 | hwnd_active = win32gui.GetForegroundWindow()
343 | try:
344 | class_name = win32gui.GetClassName(hwnd_active)
345 | except pywintypes.error:
346 | continue
347 |
348 | if class_name not in (supported_games + test_window):
349 | print('请使支持的游戏/程序窗口成为活动窗口...')
350 | else:
351 | try:
352 | hwnd_var = win32gui.FindWindow(class_name, None)
353 | except pywintypes.error:
354 | print('您正使用沙盒')
355 | hwnd_var = hwnd_active
356 | print('已找到窗口')
357 | if class_name in test_window:
358 | testing_purpose = True
359 | sleep(3)
360 | return class_name, hwnd_var, testing_purpose
361 |
362 |
363 | # 重启脚本
364 | def restart():
365 | windll.shell32.ShellExecuteW(None, 'runas', executable, __file__, None, 1)
366 | exit(0)
367 |
368 |
369 | # 退出脚本
370 | def close():
371 | if not arr[2]:
372 | show_proc.terminate()
373 | detect_proc.terminate()
374 |
375 |
376 | # 加载配置与权重文件
377 | def load_file(file, config_filename, weight_filename):
378 | cfg_filename = file + '.cfg'
379 | weights_filename = file + '.weights'
380 | config_filename[0] += cfg_filename
381 | weight_filename[0] += weights_filename
382 | return
383 |
384 |
385 | # 检测是否存在配置与权重文件
386 | def check_file(file):
387 | cfg_file = file + '.cfg'
388 | weights_file = file + '.weights'
389 | if not (os.path.isfile(cfg_file) and os.path.isfile(weights_file)):
390 | print(f'请下载{file}相关文件!!!')
391 | sleep(3)
392 | exit(0)
393 |
394 |
395 | # 检查是否为管理员权限
396 | def is_admin():
397 | try:
398 | return windll.shell32.IsUserAnAdmin()
399 | except OSError as err:
400 | print('OS error: {0}'.format(err))
401 | return False
402 |
403 |
404 | # 清空命令指示符输出
405 | def clear():
406 | _ = os.system('cls')
407 |
408 |
409 | # 移动鼠标(并射击)
410 | def control_mouse(a, b, fps_var, ranges, rate, go_fire, win_class, move_rx, move_ry):
411 | recoil_control = 0
412 | move_range = sqrt(pow(a, 2) + pow(b, 2))
413 | DPI_Var = windll.user32.GetDpiForWindow(window_hwnd_name) / 96
414 | move_rx, a = track_opt(move_rx, a, DPI_Var)
415 | move_ry, b = track_opt(move_ry, b, DPI_Var)
416 | enhanced_holdback = win32gui.SystemParametersInfo(SPI_GETMOUSE)
417 | if enhanced_holdback[1]:
418 | win32gui.SystemParametersInfo(SPI_SETMOUSE, [0, 0, 0], 0)
419 | mouse_speed = win32gui.SystemParametersInfo(SPI_GETMOUSESPEED)
420 | if mouse_speed != 10:
421 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, 10, 0)
422 |
423 | if fps_var and arr[17] and arr[11]:
424 | a = cos((pi - atan(a/arr[18])) / 2) * (2*arr[18]) / DPI_Var
425 | b = cos((pi - atan(b/arr[18])) / 2) * (2*arr[18]) / DPI_Var
426 | if move_range > 6 * ranges:
427 | a *= uniform(0.9, 1.1)
428 | b *= uniform(0.9, 1.1)
429 | fps_factor = pow(fps_var/3, 1/3)
430 | x0 = {
431 | 'CrossFire': a / 2.719 * (client_ratio / (4/3)) / fps_factor, # 32
432 | 'Valve001': a * 1.667 / fps_factor, # 2.5
433 | 'LaunchCombatUWindowsClient': a * 1.319 / fps_factor, # 10.0
434 | 'LaunchUnrealUWindowsClient': a / 2.557 / fps_factor, # 20
435 | }.get(win_class, a / fps_factor)
436 | (y0, recoil_control) = {
437 | 'CrossFire': (b / 2.719 * (client_ratio / (4/3)) / fps_factor, 2), # 32
438 | 'Valve001': (b * 1.667 / fps_factor, 2), # 2.5
439 | 'LaunchCombatUWindowsClient': (b * 1.319 / fps_factor, 2), # 10.0
440 | 'LaunchUnrealUWindowsClient': (b / 2.557 / fps_factor, 5), # 20
441 | }.get(win_class, (b / fps_factor, 2))
442 |
443 | if arr[12] == 1 or arr[14]:
444 | y0 += (recoil_control * shoot_times[0]) # 简易压枪
445 |
446 | sp_mouse_xy(int(round(x0)), int(round(y0)))
447 |
448 | # 不分敌友射击
449 | if win_class != 'CrossFire':
450 | if (go_fire or move_range < ranges) and arr[11]:
451 | if (time() * 1000 - up_time[0]) > rate:
452 | if not (GetAsyncKeyState(VK_LBUTTON) < 0 or GetKeyState(VK_LBUTTON) < 0):
453 | sp_mouse_down()
454 | press_time[0] = int(time() * 1000)
455 | if (time() * 1000 - up_time[0]) <= 219.4:
456 | shoot_times[0] += 1
457 | if shoot_times[0] > 10:
458 | shoot_times[0] = 10
459 |
460 | if (GetAsyncKeyState(VK_LBUTTON) < 0 or GetKeyState(VK_LBUTTON) < 0):
461 | if (time() * 1000 - press_time[0]) > 30.6 or not arr[11]:
462 | sp_mouse_up()
463 | up_time[0] = int(time() * 1000)
464 |
465 | if (time() * 1000 - up_time[0]) > 219.4:
466 | shoot_times[0] = 0
467 |
468 | if enhanced_holdback[1]:
469 | win32gui.SystemParametersInfo(SPI_SETMOUSE, enhanced_holdback, 0)
470 | if mouse_speed != 10:
471 | win32gui.SystemParametersInfo(SPI_SETMOUSESPEED, mouse_speed, 0)
472 |
473 | return move_rx, move_ry
474 |
475 |
476 | # 追踪优化
477 | def track_opt(record_list, range_m, vDPI):
478 | if len(record_list):
479 | if abs(median(record_list) - range_m) <= 10*vDPI and abs(range_m) <= 100*vDPI:
480 | record_list.append(range_m)
481 | else:
482 | record_list.clear()
483 | if len(record_list) > sqrt(show_fps[0]) and arr[4]:
484 | range_m *= pow(show_fps[0]/2, 1/3)
485 | record_list.clear()
486 | else:
487 | record_list.append(range_m)
488 |
489 | return record_list, range_m
490 |
491 |
492 | # 转变状态
493 | def check_status(exit0, mouse):
494 | if GetAsyncKeyState(VK_END) < 0: # End
495 | exit0 = True
496 | if GetAsyncKeyState(0x31) < 0: # 1
497 | mouse = 1
498 | arr[15] = 1
499 | if GetAsyncKeyState(0x32) < 0: # 2
500 | mouse = 2
501 | arr[15] = 2
502 | if GetAsyncKeyState(0x33) < 0 or GetAsyncKeyState(0x34) < 0: # 3,4
503 | mouse = 0
504 | arr[15] = 0
505 | if GetAsyncKeyState(0x46) < 0: # F
506 | arr[17] = 1
507 | if GetAsyncKeyState(0x4A) < 0: # J
508 | arr[17] = 0
509 | if GetAsyncKeyState(0x50) < 0: # P
510 | close()
511 | restart()
512 |
513 | return exit0, mouse
514 |
515 |
516 | # 多线程展示效果
517 | def show_frames(output_pipe, array):
518 | set_dpi()
519 | cv2.namedWindow('Show frame', cv2.WINDOW_KEEPRATIO)
520 | cv2.moveWindow('Show frame', 0, 0)
521 | cv2.destroyAllWindows()
522 | font = cv2.FONT_HERSHEY_SIMPLEX # 效果展示字体
523 | fire_target_show = ['middle', 'head', 'chest']
524 | while True:
525 | show_img = output_pipe.recv()
526 | show_color = {
527 | 0: (127, 127, 127),
528 | 1: (255, 255, 0),
529 | 2: (0, 255, 0)
530 | }.get(array[4])
531 | try:
532 | img_ex = np.zeros((1, 1, 3), np.uint8)
533 | show_str0 = str('{:03.0f}'.format(array[3]))
534 | show_str1 = 'Detected ' + str('{:02.0f}'.format(array[11])) + ' targets'
535 | show_str2 = 'Aiming at ' + fire_target_show[array[12]] + ' position'
536 | show_str3 = 'Fire rate is at ' + str('{:02.0f}'.format((10000 / (array[13] + 306)))) + ' RPS'
537 | show_str4 = 'Please enjoy coding ^_^' if array[17] else 'Please enjoy coding @_@'
538 | if show_img.any():
539 | show_img = cv2.resize(show_img, (array[5], array[5]))
540 | img_ex = cv2.resize(img_ex, (array[5], int(array[5] / 2)))
541 | cv2.putText(show_img, show_str0, (int(array[5] / 25), int(array[5] / 12)), font, array[5] / 600, (127, 255, 0), 2, cv2.LINE_AA)
542 | cv2.putText(img_ex, show_str1, (10, int(array[5] / 9)), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
543 | cv2.putText(img_ex, show_str2, (10, int(array[5] / 9) * 2), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
544 | cv2.putText(img_ex, show_str3, (10, int(array[5] / 9) * 3), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
545 | cv2.putText(img_ex, show_str4, (10, int(array[5] / 9) * 4), font, array[5] / 450, show_color, 1, cv2.LINE_AA)
546 | show_image = cv2.vconcat([show_img, img_ex])
547 | cv2.imshow('Show frame', show_image)
548 | cv2.waitKey(1)
549 | except (AttributeError, cv2.error):
550 | cv2.destroyAllWindows()
551 |
552 |
553 | # 分析进程
554 | def detection(que, array, frame_in):
555 | Analysis = FrameDetection(array[0])
556 | array[1] = 1
557 | while True:
558 | if not que.empty():
559 | try:
560 | frame = que.get_nowait()
561 | que.task_done()
562 | array[1] = 2
563 | if array[10]:
564 | array[11], array[7], array[8], array[9], array[12], array[14], array[16], frame = Analysis.detect(frame)
565 | if not array[2]:
566 | frame_in.send(frame)
567 | except (queue.Empty, TypeError):
568 | continue
569 | array[1] = 1
570 |
571 |
572 | # 主程序
573 | if __name__ == '__main__':
574 | # 为了Pyinstaller顺利生成exe
575 | freeze_support()
576 |
577 | # 检查管理员权限
578 | if not is_admin():
579 | restart()
580 |
581 | # 设置高DPI不受影响
582 | set_dpi()
583 |
584 | # 设置工作路径
585 | os.chdir(os.path.dirname(os.path.abspath(__file__)))
586 |
587 | # 滑稽
588 | Conan = -1
589 | while not (2 >= Conan >= 0):
590 | user_choice = input('柯南能在本程序作者有生之年完结吗?(1:能, 2:能, 0:不能): ')
591 | try:
592 | Conan = int(user_choice)
593 | except ValueError:
594 | print('呵呵...请重新输入')
595 | else:
596 | if not (2 >= Conan >= 0):
597 | print('请在给定范围选择')
598 |
599 | # 初始化变量以及提升进程优先级
600 | if platform == 'win32':
601 | pid = GetCurrentProcessId()
602 | handle = OpenProcess(PROCESS_ALL_ACCESS, True, pid)
603 | SetPriorityClass(handle, ABOVE_NORMAL_PRIORITY_CLASS)
604 | else:
605 | os.nice(1)
606 |
607 | queue = JoinableQueue() # 初始化队列
608 | frame_output, frame_input = Pipe(False) # 初始化管道(receiving,sending)
609 | press_time, up_time, show_fps = [0], [0], [1]
610 | process_time = deque()
611 | exit_program = False
612 | test_win = [False]
613 | move_record_x = []
614 | move_record_y = []
615 | shoot_times = [0]
616 |
617 | # 如果文件不存在则退出
618 | check_file('yolov4-tiny')
619 |
620 | # 分享数据以及展示新进程
621 | arr = Array('i', range(21))
622 | '''
623 | 0 窗口句柄
624 | 1 分析进程状态
625 | 2 是否全屏
626 | 3 截图FPS整数值
627 | 4 控制鼠标
628 | 5 左侧距离除数
629 | 6 使用GPU/CPU(1/0)
630 | 7 鼠标移动x
631 | 8 鼠标移动y
632 | 9 鼠标开火r
633 | 10 柯南
634 | 11 敌人数量
635 | 12 瞄准位置
636 | 13 射击速度
637 | 14 敌人近否
638 | 15 所持武器
639 | 16 指向身体
640 | 17 自瞄自火
641 | 18 基础边长
642 | '''
643 | arr[1] = 0 # 分析进程状态
644 | arr[2] = 0 # 是否全屏
645 | arr[3] = 0 # FPS值
646 | arr[4] = 0 # 控制鼠标
647 | arr[7] = 0 # 鼠标移动x
648 | arr[8] = 0 # 鼠标移动r
649 | arr[9] = 0 # 鼠标开火r
650 | arr[10] = Conan # 柯南
651 | arr[11] = 0 # 敌人数量
652 | arr[12] = 0 # 瞄准位置(0中1头2胸)
653 | arr[13] = 944 # 射击速度
654 | arr[14] = 0 # 敌人近否
655 | arr[15] = 0 # 所持武器(0无1主2副)
656 | arr[16] = 0 # 指向身体
657 | arr[17] = 1 # 自瞄/自火
658 | arr[18] = 0 # 基础边长
659 | detect_proc = Process(target=detection, args=(queue, arr, frame_input,))
660 |
661 | # 寻找读取游戏窗口类型并确认截取位置
662 | window_class_name, window_hwnd_name, test_win[0] = get_window_info()
663 | arr[0] = window_hwnd_name
664 |
665 | # 如果非全屏则展示效果
666 | arr[2] = 1 if is_full_screen(window_hwnd_name) else 0
667 | if not arr[2]:
668 | show_proc = Process(target=show_frames, args=(frame_output, arr,))
669 | show_proc.start()
670 | else:
671 | print('全屏模式下不会有小窗口...')
672 |
673 | # 等待游戏画面完整出现(拥有大于0的长宽)
674 | window_ready = 0
675 | while not window_ready:
676 | sleep(1)
677 | win_client_rect = win32gui.GetClientRect(window_hwnd_name)
678 | if win_client_rect[2] - win_client_rect[0] > 0 and win_client_rect[3] - win_client_rect[1] > 0:
679 | window_ready = 1
680 | client_ratio = (win_client_rect[2] - win_client_rect[0]) / (win_client_rect[3] - win_client_rect[1])
681 |
682 | # 初始化截图类
683 | win_cap = WindowCapture(window_class_name, window_hwnd_name)
684 |
685 | # 计算基础边长
686 | arr[18] = win_cap.get_side_len()
687 |
688 | # 开始分析进程
689 | detect_proc.start()
690 |
691 | # 等待分析类初始化
692 | while not arr[1]:
693 | sleep(4)
694 |
695 | # 清空命令指示符面板
696 | # clear()
697 |
698 | ini_sct_time = 0 # 初始化计时
699 | small_float = np.finfo(np.float64).eps # 初始化一个尽可能小却小得不过分的数
700 |
701 | while True:
702 | screenshot = win_cap.grab_screenshot()
703 |
704 | try:
705 | screenshot.any()
706 | arr[5] = (150 if win_cap.get_window_left() - 10 < 150 else win_cap.get_window_left() - 10)
707 | except (AttributeError, pywintypes.error) as e:
708 | print('窗口已关闭\n' + str(e))
709 | break
710 |
711 | queue.put_nowait(screenshot)
712 | queue.join()
713 |
714 | exit_program, arr[4] = check_status(exit_program, arr[4])
715 |
716 | if exit_program:
717 | break
718 |
719 | if win32gui.GetForegroundWindow() == window_hwnd_name and not test_win[0]:
720 | if arr[4]: # 是否需要控制鼠标
721 | if arr[15] == 1: # 主武器
722 | arr[13] = (944 if arr[14] or arr[12] != 1 else 1694)
723 | elif arr[15] == 2: # 副武器
724 | arr[13] = (694 if arr[14] or arr[12] != 1 else 944)
725 | move_record_x, move_record_y = control_mouse(arr[7], arr[8], show_fps[0], arr[9], arr[13] / 10, arr[16], window_class_name, move_record_x, move_record_y)
726 |
727 | time_used = time() - ini_sct_time
728 | ini_sct_time = time()
729 | current_fps = 1 / (time_used + small_float)
730 | process_time.append(current_fps)
731 | if len(process_time) > 119:
732 | process_time.popleft()
733 |
734 | show_fps[0] = median(process_time) # 计算fps
735 | arr[3] = int(show_fps[0])
736 |
737 | close()
738 | exit(0)
739 |
--------------------------------------------------------------------------------