├── _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 | [![Badgs](https://img.shields.io/badge/链接-996.icu-green)](https://996.icu/#/zh_CN) [![Badge](https://img.shields.io/badge/link-996.icu-pink)](https://996.icu/#/en_US) [![LICENSE](https://img.shields.io/badge/许可证-反对996-red)](https://github.com/996icu/996.ICU/blob/master/LICENSE_CN) [![LICENSE](https://img.shields.io/badge/license-Anti996-blue)](https://github.com/996icu/996.ICU/blob/master/LICENSE) 4 | 5 | [![img](https://img.shields.io/github/stars/JiaPai12138/AI-M-BOT?label=点赞)](https://github.com/JiaPai12138/AI-M-BOT) [![img](https://img.shields.io/github/forks/JiaPai12138/AI-M-BOT?label=克隆)](https://github.com/JiaPai12138/AI-M-BOT) [![img](https://img.shields.io/github/last-commit/JiaPai12138/AI-M-BOT?label=最近提交)](https://github.com/JiaPai12138/AI-M-BOT) [![img](https://img.shields.io/github/release/JiaPai12138/AI-M-BOT?label=最新版本)](https://github.com/JiaPai12138/AI-M-BOT/releases) [![img](https://img.shields.io/github/license/JiaPai12138/AI-M-BOT?label=许可证)](https://github.com/JiaPai12138/AI-M-BOT/blob/main/LICENSE) [![img](https://img.shields.io/badge/URL-帮助文档-blue)](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选择自瞄模式(图像预测尺寸递增,预测速度递减)![image](PDF_Images/自瞄模式选择.png) 19 | * 等待游戏窗口成为当前活动窗口(点击一下游戏窗口即可)![image](PDF_Images/自瞄等待窗口.png) 20 | * 脚本正常工作时桌面左上角会显示截屏识别区域小视频![image](PDF_Images/自瞄显示图像.png) 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 | --------------------------------------------------------------------------------