├── .gitignore ├── README.md ├── data ├── energy │ ├── devotion │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── havoc │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ └── tripletake │ │ ├── primary │ │ └── primary.jpeg │ │ └── secondary │ │ └── secondary.jpeg ├── heavy │ ├── flatline │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── hemlok │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── longbow │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── prowler │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── spitfire │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ └── wingman │ │ ├── primary │ │ └── primary.jpeg │ │ └── secondary │ │ └── secondary.jpeg ├── legendary │ ├── kraber │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ └── mastiff │ │ ├── primary │ │ └── primary.jpeg │ │ └── secondary │ │ └── secondary.jpeg ├── light │ ├── alternator │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── g7scout │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── p2020 │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── r301 │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ ├── r99 │ │ ├── primary │ │ │ └── primary.jpeg │ │ └── secondary │ │ │ └── secondary.jpeg │ └── re45 │ │ ├── primary │ │ └── primary.jpeg │ │ └── secondary │ │ └── secondary.jpeg └── shotgun │ ├── eva8 │ ├── primary │ │ └── primary.jpeg │ └── secondary │ │ └── secondary.jpeg │ ├── mozambique │ ├── primary │ │ └── primary.jpeg │ └── secondary │ │ └── secondary.jpeg │ └── peacekeeper │ ├── primary │ └── primary.jpeg │ └── secondary │ └── secondary.jpeg ├── examples ├── no-recoil.gif └── recoil.gif ├── guns ├── gun_detection │ ├── detect_gun.py │ ├── setup_data │ │ └── load_data.py │ └── win32_screen.py └── gun_settings │ └── gun_settings.py ├── mouse_events ├── decorators.py ├── mover.py └── pull_down.py ├── predicter.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReduxAL 2 | Medium post here: https://medium.com/@radpro/reduxal-a-smart-recoil-reducer-for-apex-legends-ad15ef415b7a 3 | 4 | 5 | Recoil | Recoil Reduced 6 | :-------------------------:|:-------------------------: 7 | ![](https://github.com/josephp27/ApexLegendsGunRecoilReducer/blob/master/examples/recoil.gif) | ![](https://github.com/josephp27/ApexLegendsGunRecoilReducer/blob/master/examples/no-recoil.gif) 8 | 9 | 10 | ## How it works 11 | Currently only works with 1080p displays 12 | 13 | 14 | ReduxAL takes a small screenshot whenever a gun swap is signaled (scroll wheel event) or whenever a gun is picked up (e pressed). This image is compared against a database of images using mean squared error. If a gun is detected, and the gun is fired using the mouse left click, the corresponding recoil reduction settings from [gun_settings.py](https://github.com/josephp27/ApexLegendsGunRecoilReducer/blob/master/guns/gun_settings/gun_settings.py) will be used to reduce recoil. 15 | 16 | ## Adding your own custom recoil reduction settings 17 | These can be added into the gun_settings.py, listed above, and loaded into [pulldown.py](https://github.com/josephp27/ApexLegendsGunRecoilReducer/blob/master/mouse_events/pull_down.py) 18 | 19 | ## Running the application 20 | Install python 3.x from [python.org](https://www.python.org/) 21 | 22 | 23 | Install requirements: 24 | ``` 25 | pip install -r requirements.txt 26 | ``` 27 | Run with: 28 | ``` 29 | python predicter.py 30 | ``` 31 | 32 | ## TODO: 33 | - Add a lot of other guns 34 | - Add more displays 35 | - Allow for dynamic displays (Possibly OCR?) 36 | 37 | ## Bugs: 38 | - Hooking libraries like to hang sometimes, so spawning threads mitigates this problem most of the time. 39 | - Program hangs right after starting. Resolution: do not click within the command prompt or powershell window. Exit by pressing "L" 40 | 41 | ## Disclaimer 42 | This program does not inject any code into the game and therefore should be hard to detect. Use at your own risk. I did this project for fun to get better with python and do not use this in game. I am not responsible if this results in you getting banned 43 | -------------------------------------------------------------------------------- /data/energy/devotion/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/devotion/primary/primary.jpeg -------------------------------------------------------------------------------- /data/energy/devotion/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/devotion/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/energy/havoc/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/havoc/primary/primary.jpeg -------------------------------------------------------------------------------- /data/energy/havoc/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/havoc/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/energy/tripletake/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/tripletake/primary/primary.jpeg -------------------------------------------------------------------------------- /data/energy/tripletake/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/energy/tripletake/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/flatline/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/flatline/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/flatline/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/flatline/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/hemlok/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/hemlok/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/hemlok/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/hemlok/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/longbow/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/longbow/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/longbow/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/longbow/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/prowler/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/prowler/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/prowler/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/prowler/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/spitfire/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/spitfire/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/spitfire/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/spitfire/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/heavy/wingman/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/wingman/primary/primary.jpeg -------------------------------------------------------------------------------- /data/heavy/wingman/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/heavy/wingman/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/legendary/kraber/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/legendary/kraber/primary/primary.jpeg -------------------------------------------------------------------------------- /data/legendary/kraber/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/legendary/kraber/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/legendary/mastiff/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/legendary/mastiff/primary/primary.jpeg -------------------------------------------------------------------------------- /data/legendary/mastiff/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/legendary/mastiff/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/alternator/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/alternator/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/alternator/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/alternator/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/g7scout/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/g7scout/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/g7scout/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/g7scout/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/p2020/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/p2020/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/p2020/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/p2020/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/r301/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/r301/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/r301/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/r301/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/r99/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/r99/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/r99/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/r99/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/light/re45/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/re45/primary/primary.jpeg -------------------------------------------------------------------------------- /data/light/re45/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/light/re45/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/shotgun/eva8/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/eva8/primary/primary.jpeg -------------------------------------------------------------------------------- /data/shotgun/eva8/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/eva8/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/shotgun/mozambique/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/mozambique/primary/primary.jpeg -------------------------------------------------------------------------------- /data/shotgun/mozambique/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/mozambique/secondary/secondary.jpeg -------------------------------------------------------------------------------- /data/shotgun/peacekeeper/primary/primary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/peacekeeper/primary/primary.jpeg -------------------------------------------------------------------------------- /data/shotgun/peacekeeper/secondary/secondary.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/data/shotgun/peacekeeper/secondary/secondary.jpeg -------------------------------------------------------------------------------- /examples/no-recoil.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/examples/no-recoil.gif -------------------------------------------------------------------------------- /examples/recoil.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephp27/ReduxAL/87a11c9b2f08a8bb8628b862512c797553d73900/examples/recoil.gif -------------------------------------------------------------------------------- /guns/gun_detection/detect_gun.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from .win32_screen import grab_screen as grabby 4 | 5 | 6 | class detect_gun: 7 | 8 | def __init__(self, training_data=None): 9 | self.training_data = training_data 10 | 11 | def mse(self, image_a, image_b): 12 | # the 'Mean Squared Error' between the two images is the 13 | # sum of the squared difference between the two images; 14 | # NOTE: the two images must have the same dimension 15 | err = np.sum((image_a.astype("float") - image_b.astype("float")) ** 2) 16 | err /= float(image_a.shape[0] * image_a.shape[1]) 17 | 18 | # return the MSE, the lower the error, the more "similar" 19 | # the two images are 20 | return err 21 | 22 | def detect(self): 23 | 24 | # grab our small screenshot for both primary and secondary weapons 25 | primary = grabby(region=(1550, 1030, 1669, 1054)) 26 | secondary = grabby(region=(1700, 1030, 1819, 1054)) 27 | 28 | # set max MSE to be 500 29 | min_ = 500 30 | best_data = [] 31 | 32 | # iterate through calculate MSE on all images in DB, finding the best match O(N) time complexity 33 | for im, data in self.training_data: 34 | error = min(self.mse(primary, np.asarray(im)), self.mse(secondary, np.asarray(im))) 35 | if error < min_: 36 | min_ = error 37 | best_data = data 38 | 39 | print(min_, best_data) 40 | return best_data[0] if len(best_data) > 0 else None 41 | -------------------------------------------------------------------------------- /guns/gun_detection/setup_data/load_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PIL import Image 4 | 5 | training_data = [] 6 | 7 | 8 | def fill_training_data(path): 9 | global training_data 10 | 11 | if 'jpeg' in path: 12 | im = Image.open(path) 13 | tokens = path.split('/') 14 | training_data.append((im, tokens[3:5])) 15 | return 16 | 17 | for type_ in os.listdir(path): 18 | fill_training_data(path + '/' + type_) 19 | 20 | 21 | def load_data(path): 22 | fill_training_data(path) 23 | return training_data 24 | -------------------------------------------------------------------------------- /guns/gun_detection/win32_screen.py: -------------------------------------------------------------------------------- 1 | # Done by Frannecklp 2 | 3 | import win32api 4 | import win32con 5 | import win32gui 6 | import win32ui 7 | 8 | import cv2 9 | import numpy as np 10 | 11 | 12 | def grab_screen(region=None): 13 | hwin = win32gui.GetDesktopWindow() 14 | 15 | if region: 16 | left, top, x2, y2 = region 17 | width = x2 - left + 1 18 | height = y2 - top + 1 19 | else: 20 | width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN) 21 | height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN) 22 | left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN) 23 | top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN) 24 | 25 | hwindc = win32gui.GetWindowDC(hwin) 26 | srcdc = win32ui.CreateDCFromHandle(hwindc) 27 | memdc = srcdc.CreateCompatibleDC() 28 | bmp = win32ui.CreateBitmap() 29 | bmp.CreateCompatibleBitmap(srcdc, width, height) 30 | memdc.SelectObject(bmp) 31 | memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY) 32 | 33 | signedIntsArray = bmp.GetBitmapBits(True) 34 | img = np.fromstring(signedIntsArray, dtype='uint8') 35 | img.shape = (height, width, 4) 36 | 37 | srcdc.DeleteDC() 38 | memdc.DeleteDC() 39 | win32gui.ReleaseDC(hwin, hwindc) 40 | win32gui.DeleteObject(bmp.GetHandle()) 41 | 42 | return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB) 43 | -------------------------------------------------------------------------------- /guns/gun_settings/gun_settings.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import time 3 | 4 | from mouse_events.mover import move_mouse 5 | 6 | 7 | class gun_settings: 8 | 9 | def __init__(self, enabled=False): 10 | self.enabled = enabled 11 | 12 | def pull_down_r301(self, parent): 13 | count = 0 14 | sleep_time = 0.0005 15 | 16 | # while the left mouse button is held 17 | while parent.enabled: 18 | print(self.enabled, 'r301', end='\r', flush=True) 19 | 20 | # do some weird delaying 21 | count += 1 22 | if count % 10 == 0: 23 | sleep_time += 0.01 24 | if 30 < count < 40: 25 | # spawn a thread call the function move mouse going left by one pixel 26 | threading.Thread(target=move_mouse, args=(-1, 0,)).start() 27 | 28 | # spawn a threads call the function move mouse to move one pixel down 29 | threading.Thread(target=move_mouse, args=(0, 1,)).start() 30 | 31 | # sleep to delay 32 | time.sleep(sleep_time) 33 | 34 | def pull_down_prowler(self, parent): 35 | sleep_time = 0.002 36 | 37 | # while left mouse button is pressed 38 | while parent.enabled: 39 | print(self.enabled, 'prowler', end='\r', flush=True) 40 | 41 | # spawn a threads call the function move mouse to move one pixel down 42 | threading.Thread(target=move_mouse, args=(0, 1,)).start() 43 | 44 | # sleep by some predetermined time 45 | time.sleep(sleep_time) 46 | 47 | def pull_down_devotion(self, parent): 48 | # insert custom code below 49 | print(self.enabled, 'devotion', end='\r', flush=True) 50 | 51 | def pull_down_havoc(self, parent): 52 | # insert custom code below 53 | print(self.enabled, 'havoc', end='\r', flush=True) 54 | 55 | def pull_down_tripletake(self, parent): 56 | # insert custom code below 57 | print(self.enabled, 'tripletake', end='\r', flush=True) 58 | 59 | def pull_down_flatline(self, parent): 60 | # insert custom code below 61 | print(self.enabled, 'flatline', end='\r', flush=True) 62 | 63 | def pull_down_hemlok(self, parent): 64 | # insert custom code below 65 | print(self.enabled, 'hemlok', end='\r', flush=True) 66 | 67 | def pull_down_longbow(self, parent): 68 | # insert custom code below 69 | print(self.enabled, 'longbow', end='\r', flush=True) 70 | 71 | def pull_down_spitfire(self, parent): 72 | # insert custom code below 73 | print(self.enabled, 'spitfire', end='\r', flush=True) 74 | 75 | def pull_down_wingman(self, parent): 76 | # insert custom code below 77 | print(self.enabled, 'wingman', end='\r', flush=True) 78 | 79 | def pull_down_kraber(self, parent): 80 | # insert custom code below 81 | print(self.enabled, 'kraber', end='\r', flush=True) 82 | 83 | def pull_down_mastiff(self, parent): 84 | # insert custom code below 85 | print(self.enabled, 'mastiff', end='\r', flush=True) 86 | 87 | def pull_down_alternator(self, parent): 88 | # insert custom code below 89 | print(self.enabled, 'alternator', end='\r', flush=True) 90 | 91 | def pull_down_g7scout(self, parent): 92 | # insert custom code below 93 | print(self.enabled, 'g7scout', end='\r', flush=True) 94 | 95 | def pull_down_p2020(self, parent): 96 | # insert custom code below 97 | print(self.enabled, 'p2020', end='\r', flush=True) 98 | 99 | def pull_down_r99(self, parent): 100 | # insert custom code below 101 | print(self.enabled, 'r99', end='\r', flush=True) 102 | 103 | def pull_down_re45(self, parent): 104 | # insert custom code below 105 | print(self.enabled, 're45', end='\r', flush=True) 106 | 107 | def pull_down_eva8(self, parent): 108 | # insert custom code below 109 | print(self.enabled, 'eva8', end='\r', flush=True) 110 | 111 | def pull_down_mozambique(self, parent): 112 | # insert custom code below 113 | print(self.enabled, 'mozambique', end='\r', flush=True) 114 | 115 | def pull_down_peacekeeper(self, parent): 116 | # insert custom code below 117 | print(self.enabled, 'peacekeeper', end='\r', flush=True) 118 | 119 | -------------------------------------------------------------------------------- /mouse_events/decorators.py: -------------------------------------------------------------------------------- 1 | def pull_down_listener(func): 2 | def loop(self, press): 3 | while 1: 4 | func(self) 5 | 6 | return loop 7 | -------------------------------------------------------------------------------- /mouse_events/mover.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | 3 | 4 | def move_mouse(x, y): 5 | 6 | windll.user32.mouse_event( 7 | c_uint(0x0001), 8 | c_uint(x), 9 | c_uint(y), 10 | c_uint(0), 11 | c_uint(0) 12 | ) 13 | -------------------------------------------------------------------------------- /mouse_events/pull_down.py: -------------------------------------------------------------------------------- 1 | from guns.gun_settings.gun_settings import gun_settings 2 | from mouse_events.decorators import pull_down_listener 3 | 4 | # instantiate our class with enabled set to False 5 | guns = gun_settings(False) 6 | 7 | 8 | class mouse_pull_down: 9 | 10 | def __init__(self, enabled=False, equipped_gun=None): 11 | self.enabled = enabled 12 | self.equipped_gun = equipped_gun 13 | 14 | @pull_down_listener 15 | def pull_down(self): 16 | 17 | print(self.enabled, end='\r', flush=True) 18 | # energy 19 | if self.equipped_gun == 'devotion': 20 | guns.pull_down_devotion(self) 21 | 22 | elif self.equipped_gun == 'havoc': 23 | guns.pull_down_havoc(self) 24 | 25 | elif self.equipped_gun == 'tripletake': 26 | guns.pull_down_tripletake(self) 27 | 28 | # heavy 29 | elif self.equipped_gun == 'prowler': 30 | guns.pull_down_prowler(self) 31 | 32 | elif self.equipped_gun == 'flatline': 33 | guns.pull_down_flatline(self) 34 | 35 | elif self.equipped_gun == 'hemlok': 36 | guns.pull_down_hemlok(self) 37 | 38 | elif self.equipped_gun == 'longbow': 39 | guns.pull_down_longbow(self) 40 | 41 | elif self.equipped_gun == 'spitfire': 42 | guns.pull_down_spitfire(self) 43 | 44 | elif self.equipped_gun == 'wingman': 45 | guns.pull_down_wingman(self) 46 | 47 | # legendary 48 | elif self.equipped_gun == 'kraber': 49 | guns.pull_down_kraber(self) 50 | 51 | elif self.equipped_gun == 'mastiff': 52 | guns.pull_down_mastiff(self) 53 | 54 | # light 55 | elif self.equipped_gun == 'alternator': 56 | guns.pull_down_alternator(self) 57 | 58 | elif self.equipped_gun == 'g7scout': 59 | guns.pull_down_g7scout(self) 60 | 61 | elif self.equipped_gun == 'p2020': 62 | guns.pull_down_p2020(self) 63 | 64 | elif self.equipped_gun == 'r99': 65 | guns.pull_down_r99(self) 66 | 67 | elif self.equipped_gun == 'r301': 68 | guns.pull_down_r301(self) 69 | 70 | elif self.equipped_gun == 're45': 71 | guns.pull_down_re45(self) 72 | 73 | # shotgun 74 | elif self.equipped_gun == 'eva8': 75 | guns.pull_down_eva8(self) 76 | 77 | elif self.equipped_gun == 'mozambique': 78 | guns.pull_down_mozambique(self) 79 | 80 | elif self.equipped_gun == 'peacekeeper': 81 | guns.pull_down_peacekeeper(self) 82 | -------------------------------------------------------------------------------- /predicter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import signal 3 | import threading 4 | import time 5 | 6 | import keyboard 7 | import mouse as m 8 | from pynput import mouse 9 | 10 | from guns.gun_detection.detect_gun import detect_gun 11 | from guns.gun_detection.setup_data.load_data import load_data 12 | from mouse_events.pull_down import mouse_pull_down 13 | 14 | training_data = load_data(os.getcwd() + '/data') 15 | equipped_gun = detect_gun(training_data) 16 | puller = mouse_pull_down() 17 | 18 | 19 | def mouse_handler(call): 20 | # if scroll wheel detected, then kick off gun detection 21 | if isinstance(call, m.WheelEvent): 22 | time.sleep(0.05) 23 | puller.equipped_gun = equipped_gun.detect() 24 | 25 | 26 | def keyboard_handler(call): 27 | # if e is pressed, kick off gun detection 28 | time.sleep(0.05) 29 | puller.equipped_gun = equipped_gun.detect() 30 | 31 | 32 | def quit_handler(call): 33 | print("quitting") 34 | # a normal exit won't work if the program hangs, need to do this 35 | os.kill(os.getpid(), signal.SIGTERM) 36 | 37 | 38 | def on_click_handler(x, y, button, pressed): 39 | # if shooting detected, tell puller we are enabled to kick off pulling down 40 | if button == mouse.Button.left and pressed: 41 | puller.enabled = True 42 | else: 43 | puller.enabled = False 44 | 45 | 46 | if __name__ == "__main__": 47 | print("press L to quit") 48 | # start our custom pull down listener 49 | threading.Thread(target=puller.pull_down, args=(False,)).start() 50 | 51 | # enable listening to keyboard and mouse events 52 | m.hook(mouse_handler) 53 | keyboard.on_release_key('e', keyboard_handler) 54 | keyboard.on_release_key('l', quit_handler) 55 | with mouse.Listener(on_click=on_click_handler) as listener: 56 | listener.join() 57 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | keyboard==0.13.3 2 | mouse==0.7.0 3 | numpy==1.16.2 4 | opencv-python==4.0.0.21 5 | Pillow==5.4.1 6 | pynput==1.4.2 7 | pypiwin32==223 8 | pywin32==224 9 | six==1.12.0 10 | --------------------------------------------------------------------------------