├── .gitattributes ├── .gitignore ├── Loader.py ├── Overlay.py ├── README.md ├── Recoil.py ├── dist └── Recoil-V1.exe └── requirements.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | -------------------------------------------------------------------------------- /Loader.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtCore, QtGui, QtWidgets 2 | from cryptography.fernet import Fernet 3 | import mysql.connector, threading, Recoil, os, subprocess, time, Overlay 4 | 5 | class Ui_MainWindow(object): 6 | def __login(self): 7 | encH = b'' #SQL Conn Host Encrypted 8 | encU = b'' #SQL Conn Username Encrypted 9 | encPW = b'' #SQL Conn Password Encrypted 10 | encDB = b'' #SQL Conn DB IP Encrypted 11 | 12 | UlXJn8jT = b'' #Encryption Key 13 | naviFer = Fernet(UlXJn8jT) #Encryption Class Init 14 | 15 | __hwid = str(subprocess.check_output('wmic csproduct get uuid')).split('\\r\\n')[1].strip('\\r').strip() #Get HWID from users PC 16 | __u = self.txtUser.text() 17 | __p = self.txtPass.text() 18 | #__u = naviFer.encrypt(self.txtUser.text().encode()) 19 | #__p = naviFer.encrypt(self.txtPass.text().encode()) 20 | 21 | if __u and __p: 22 | __mydb = mysql.connector.connect( 23 | host = str(naviFer.decrypt(encH))[2:-1], #SQL Conn Host Decrypted 24 | user = str(naviFer.decrypt(encU))[2:-1], #SQL Username Decrypted 25 | password = str(naviFer.decrypt(encPW))[2:-1], #SQL password Decrypted 26 | database = str(naviFer.decrypt(encDB))[2:-1] #SQL DB ip Decrypted 27 | ) 28 | 29 | __mycursor = __mydb.cursor() 30 | __mycursor.execute("SELECT `id` FROM `LoginList` WHERE `user` = '"+ __u +"' AND `key` = '"+ __p +"'") #Get id from user and pass 31 | __id = __mycursor.fetchall() 32 | 33 | if (__id == []): #If id was not found 34 | self.lblStatus.setText("Login Failed") 35 | else: #If id exists in db 36 | __mycursor.execute("SELECT `id` FROM `LoginList` WHERE `user` = '"+ __u +"' AND `key` = '"+ __p +"' AND `hwid` = '"+ __hwid +"'") # Grab id if HWID exists from db from user and pass 37 | __idHWID = __mycursor.fetchall() 38 | if (__idHWID == []): # If no id found with that hwid 39 | __mycursor.execute("UPDATE `LoginList` SET HWID = '"+ __hwid +"', reg_date = current_timestamp() WHERE id = '"+ str(__id[0][0]) +"';") # Update the hwid 40 | else: # If HWID is set 41 | __mycursor.execute("SELECT `hwid` FROM `LoginList` WHERE `user` = '"+ __u +"' AND `key` = '"+ __p +"' AND '"+ __hwid +"'") # HWID 42 | __HWID = __mycursor.fetchall() 43 | if (__HWID[0][0] != __hwid): #Check user hwid vs stored hwid 44 | self.lblStatus.setText("Login Failed") 45 | time.sleep(2) 46 | sys.exit() 47 | #overlayThread = threading.Thread(target=Overlay.draw) 48 | #overlayThread.start() 49 | scriptThread = threading.Thread(target=Recoil.run) #Start Script 50 | self.lblStatus.setText("Logged In") 51 | self.hide() 52 | scriptThread.start() 53 | scriptThread.join() 54 | #overlayThread.join() 55 | threading.Timer(2.5, sys.exit()).start() 56 | 57 | def __register(self): 58 | encH = b'' #SQL Conn Host 59 | encU = b'' #SQL Conn Username 60 | encPW = b'' #SQL Conn Password 61 | encDB = b'' #SQL Conn DB IP 62 | 63 | UlXJn8jT = b'' #Encryption Key 64 | naviFer = Fernet(UlXJn8jT) #Encryption Class Init 65 | 66 | __hwid = str(subprocess.check_output('wmic csproduct get uuid')).split('\\r\\n')[1].strip('\\r').strip() 67 | __u = self.txtUser.text() 68 | __p = self.txtPass.text() 69 | 70 | if __u and __p: 71 | __mydb = mysql.connector.connect( 72 | host = str(naviFer.decrypt(encH))[2:-1], #SQL Conn Host Decrypted 73 | user = str(naviFer.decrypt(encU))[2:-1], #SQL Username Decrypted 74 | password = str(naviFer.decrypt(encPW))[2:-1], #SQL password Decrypted 75 | database = str(naviFer.decrypt(encDB))[2:-1] #SQL DB ip Decrypted 76 | ) 77 | 78 | __mycursor = __mydb.cursor() 79 | __mycursor.execute("SELECT `key` FROM `LoginList` WHERE `key` = '"+ __p +"'") #Check key is valid 80 | __id = __mycursor.fetchall() 81 | 82 | if (__id == []): #If key was not found 83 | self.lblStatus.setText("Invalid Key") 84 | else: #If key exists 85 | __mycursor.execute("UPDATE `LoginList` SET `hwid` = '"+ __hwid +"', `user` = '"+ __u +"' , `reg_date` = current_timestamp() WHERE `key` = '"+ __p +"';") 86 | self.lblStatus.setText("Registered") 87 | threading.Timer(2.5, sys.exit()).start() 88 | 89 | def setupUi(self, MainWindow): 90 | MainWindow.setObjectName("MainWindow") 91 | MainWindow.resize(600, 250) 92 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 93 | sizePolicy.setHorizontalStretch(0) 94 | sizePolicy.setVerticalStretch(0) 95 | sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) 96 | MainWindow.setSizePolicy(sizePolicy) 97 | MainWindow.setMinimumSize(QtCore.QSize(600, 250)) 98 | MainWindow.setMaximumSize(QtCore.QSize(600, 250)) 99 | MainWindow.setContextMenuPolicy(QtCore.Qt.NoContextMenu) 100 | MainWindow.setAutoFillBackground(False) 101 | MainWindow.setStyleSheet("QMainWindow{\n" 102 | " background-color:rgb(56, 56, 56)\n" 103 | "}") 104 | MainWindow.setAnimated(False) 105 | MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded) 106 | self.centralwidget = QtWidgets.QWidget(MainWindow) 107 | self.centralwidget.setObjectName("centralwidget") 108 | self.btnRegister = QtWidgets.QPushButton(self.centralwidget) 109 | self.btnRegister.setGeometry(QtCore.QRect(260, 202, 81, 21)) 110 | font = QtGui.QFont() 111 | font.setFamily("Pixel Font7") 112 | font.setPointSize(10) 113 | self.btnRegister.setFont(font) 114 | self.btnRegister.setStyleSheet("background-color:Transparent;\n" 115 | "border:1px solid white;\n" 116 | "color:white;") 117 | self.btnRegister.setObjectName("btnRegister") 118 | self.btnLogin = QtWidgets.QPushButton(self.centralwidget) 119 | self.btnLogin.setGeometry(QtCore.QRect(260, 162, 81, 21)) 120 | font = QtGui.QFont() 121 | font.setFamily("Pixel Font7") 122 | font.setPointSize(10) 123 | self.btnLogin.setFont(font) 124 | self.btnLogin.setStyleSheet("background-color:Transparent;\n" 125 | "border:1px solid white;\n" 126 | "color:white;") 127 | self.btnLogin.setCheckable(False) 128 | self.btnLogin.setObjectName("btnLogin") 129 | self.lblMain = QtWidgets.QLabel(self.centralwidget) 130 | self.lblMain.setGeometry(QtCore.QRect(160, 0, 281, 81)) 131 | font = QtGui.QFont() 132 | font.setFamily("Akira Expanded") 133 | font.setPointSize(26) 134 | font.setBold(True) 135 | font.setWeight(75) 136 | self.lblMain.setFont(font) 137 | self.lblMain.setAutoFillBackground(False) 138 | self.lblMain.setStyleSheet("color:white;") 139 | self.lblMain.setAlignment(QtCore.Qt.AlignCenter) 140 | self.lblMain.setObjectName("lblMain") 141 | self.txtPass = QtWidgets.QLineEdit(self.centralwidget) 142 | self.txtPass.setGeometry(QtCore.QRect(240, 121, 121, 21)) 143 | font = QtGui.QFont() 144 | font.setFamily("Pixel Font7") 145 | font.setPointSize(10) 146 | self.txtPass.setFont(font) 147 | self.txtPass.setStyleSheet("background-color:Transparent;\n" 148 | "border:1px solid white;\n" 149 | "color:white;") 150 | self.txtPass.setText("") 151 | self.txtPass.setFrame(True) 152 | self.txtPass.setEchoMode(QtWidgets.QLineEdit.Password) 153 | self.txtPass.setAlignment(QtCore.Qt.AlignCenter) 154 | self.txtPass.setClearButtonEnabled(False) 155 | self.txtPass.setObjectName("txtPass") 156 | self.txtUser = QtWidgets.QLineEdit(self.centralwidget) 157 | self.txtUser.setGeometry(QtCore.QRect(240, 80, 121, 21)) 158 | font = QtGui.QFont() 159 | font.setFamily("Pixel Font7") 160 | font.setPointSize(10) 161 | self.txtUser.setFont(font) 162 | self.txtUser.setStyleSheet("background-color:Transparent;\n" 163 | "border:1px solid white;\n" 164 | "color:white;") 165 | self.txtUser.setText("") 166 | self.txtUser.setAlignment(QtCore.Qt.AlignCenter) 167 | self.txtUser.setObjectName("txtUser") 168 | self.lblStatus = QtWidgets.QLabel(self.centralwidget) 169 | self.lblStatus.setGeometry(QtCore.QRect(3, 210, 171, 51)) 170 | font = QtGui.QFont() 171 | font.setFamily("Pixel Font7") 172 | font.setPointSize(10) 173 | self.lblStatus.setFont(font) 174 | self.lblStatus.setStyleSheet("color:white;") 175 | self.lblStatus.setFrameShape(QtWidgets.QFrame.NoFrame) 176 | self.lblStatus.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) 177 | self.lblStatus.setObjectName("lblStatus") 178 | self.frame = QtWidgets.QFrame(self.centralwidget) 179 | self.frame.setGeometry(QtCore.QRect(0, 0, 600, 6)) 180 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 181 | sizePolicy.setHorizontalStretch(0) 182 | sizePolicy.setVerticalStretch(0) 183 | sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) 184 | self.frame.setSizePolicy(sizePolicy) 185 | self.frame.setMinimumSize(QtCore.QSize(0, 0)) 186 | self.frame.setMaximumSize(QtCore.QSize(600, 10)) 187 | self.frame.setStyleSheet("background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(231, 60, 126, 255), stop:1 rgba(35, 166, 213, 255))") 188 | self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) 189 | self.frame.setFrameShadow(QtWidgets.QFrame.Raised) 190 | self.frame.setObjectName("frame") 191 | self.frame2 = QtWidgets.QFrame(self.centralwidget) 192 | self.frame2.setGeometry(QtCore.QRect(0, 244, 600, 8)) 193 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 194 | sizePolicy.setHorizontalStretch(0) 195 | sizePolicy.setVerticalStretch(0) 196 | sizePolicy.setHeightForWidth(self.frame2.sizePolicy().hasHeightForWidth()) 197 | self.frame2.setSizePolicy(sizePolicy) 198 | self.frame2.setMinimumSize(QtCore.QSize(0, 0)) 199 | self.frame2.setMaximumSize(QtCore.QSize(600, 10)) 200 | self.frame2.setStyleSheet("background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(231, 60, 126, 255), stop:1 rgba(35, 166, 213, 255))") 201 | self.frame2.setFrameShape(QtWidgets.QFrame.StyledPanel) 202 | self.frame2.setFrameShadow(QtWidgets.QFrame.Raised) 203 | self.frame2.setObjectName("frame2") 204 | self.btnExit = QtWidgets.QPushButton(self.centralwidget) 205 | self.btnExit.setGeometry(QtCore.QRect(581, 2, 20, 31)) 206 | font = QtGui.QFont() 207 | font.setFamily("Pixel Font7") 208 | font.setPointSize(12) 209 | self.btnExit.setFont(font) 210 | self.btnExit.setStyleSheet("background-color:Transparent;\n" 211 | "color:White;") 212 | self.btnExit.setObjectName("btnExit") 213 | MainWindow.setCentralWidget(self.centralwidget) 214 | 215 | self.retranslateUi(MainWindow) 216 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 217 | MainWindow.setTabOrder(self.txtUser, self.txtPass) 218 | MainWindow.setTabOrder(self.txtPass, self.btnLogin) 219 | MainWindow.setTabOrder(self.btnLogin, self.btnRegister) 220 | 221 | def retranslateUi(self, MainWindow): 222 | _translate = QtCore.QCoreApplication.translate 223 | MainWindow.setWindowTitle(_translate("MainWindow", "Easy4.me")) 224 | self.btnRegister.setText(_translate("MainWindow", "Register")) 225 | self.btnLogin.setText(_translate("MainWindow", "Login")) 226 | self.lblMain.setText(_translate("MainWindow", "Easy4.me")) 227 | self.txtPass.setPlaceholderText(_translate("MainWindow", "Key")) 228 | self.txtUser.setPlaceholderText(_translate("MainWindow", "Username")) 229 | self.lblStatus.setText(_translate("MainWindow", "Status")) 230 | self.btnExit.setText(_translate("MainWindow", "X")) 231 | 232 | #Button Event 233 | self.btnLogin.clicked.connect(self.__login) 234 | self.btnRegister.clicked.connect(self.__register) 235 | self.btnExit.clicked.connect(self.close) 236 | MainWindow.setWindowFlags(QtCore.Qt.FramelessWindowHint) 237 | 238 | class MyWin(QtWidgets.QMainWindow, Ui_MainWindow): 239 | def __init__(self): 240 | super().__init__() 241 | self.setupUi(self) 242 | self.dragPos = QtCore.QPoint() 243 | 244 | def mousePressEvent(self, event): 245 | self.dragPos = event.globalPos() 246 | 247 | def mouseMoveEvent(self, event): 248 | if event.buttons() == QtCore.Qt.LeftButton: 249 | self.move(self.pos() + event.globalPos() - self.dragPos) 250 | self.dragPos = event.globalPos() 251 | event.accept() 252 | 253 | if __name__ == "__main__": 254 | import sys 255 | app = QtWidgets.QApplication(sys.argv) 256 | w = MyWin() 257 | w.show() 258 | sys.exit(app.exec_()) 259 | -------------------------------------------------------------------------------- /Overlay.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5 import QtCore, QtGui, QtWidgets 3 | 4 | class Crosshair(QtWidgets.QWidget): 5 | def __init__(self, parent=None, windowSize=24, penWidth=2, w=" AK", scope="Nil"): 6 | QtWidgets.QWidget.__init__(self, parent) 7 | self.weapon = w 8 | self.scope = scope 9 | self.ws = windowSize 10 | self.resize(24+1, 60+1) 11 | self.pen = QtGui.QPen(QtGui.QColor(231, 60, 126, 255)) 12 | self.pen.setWidth(penWidth) 13 | self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.WindowTransparentForInput) 14 | self.setAttribute(QtCore.Qt.WA_TranslucentBackground) 15 | self.move(QtWidgets.QApplication.desktop().screen().rect().center() - self.rect().center() + QtCore.QPoint(1,1)) 16 | self.setWindowFlag(QtCore.Qt.Tool) 17 | self.setWindowTitle("Easy4.me") 18 | 19 | def paintEvent(self, event): 20 | ws = self.ws 21 | d = 5 22 | painter = QtGui.QPainter(self) 23 | painter.setPen(self.pen) 24 | painter.drawLine(int(ws/2), 0 + 13, int(ws/2), int(ws/2) - int(ws/d) + 13) # Top 25 | painter.drawLine(int(ws/2), int(ws/2) + int(ws/d) + 13, int(ws/2), int(ws) + 13) # Bottom 26 | painter.drawLine(0, int(ws/2) + 13, int(ws/2) - int(ws/d), int(ws/2) + 13) # Left 27 | painter.drawLine(int(ws/2) + int(ws/d), int(ws/2) + 13, int(ws), int(ws/2) + 13) # Right 28 | 29 | painter.drawText(3, 50, self.weapon) 30 | painter.drawText(3, 60, self.scope) 31 | 32 | def draw(weapon, scope): 33 | global overlay 34 | app1 = QtWidgets.QApplication(sys.argv) 35 | 36 | overlay = Crosshair(windowSize=24, penWidth=1, w=weapon, scope=scope) 37 | overlay.show() 38 | 39 | app1.exec_() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Recoil-Script 2 | ![GitHub last commit](https://img.shields.io/github/last-commit/Bboddy/Recoil-Script) ![GitHub all releases](https://img.shields.io/github/downloads/Bboddy/Rust-Recoil-Script/total) ![Views](https://views.whatilearened.today/views/github/Bboddy/Rust-Recoil-Script.svg)
3 | 4 |

OUTDATED (the game has randomized all recoil)

5 | 6 |

Controls recoil most all the guns in Rust, with smoothing and randomization.

7 | 8 | ![Untitled](https://user-images.githubusercontent.com/43559704/143996297-681039bf-a738-40e5-9881-5c50638ef14b.gif) 9 | 10 | This script was relased because the abundant amount of people selling garbage scripts that are pasted or took them a week to write. 11 | No one should be paying for a script, the game does extreemly little to detect scripts and the fact that people are charging monthly for them is stupid. 12 | 13 | ## For Simple Use 14 | 15 | * Click Releases 16 | - Select the latest one 17 | - Download the exe 18 | - Run the exe 19 | 20 | * Keybinds 21 | - PgUp/PgDn to cycle weapons 22 | - Pause to pause the script 23 | - Home to cycle scopes 24 | - ScrLk to update sensitivity (the script grabs it at the start, use if changed after starting the script) 25 | - End to quit the script 26 | 27 | ## Warning 28 | 29 | * Use At Your Own Risk 30 | - Using this on EAC may result in a ban 31 | - Only randomization is within the smoothing 32 | 33 | ## Settings 34 | * Fov is best at 90 35 | - Best sense is 0.5 36 | * Dont Use Overlay 37 | - Its a top most and unnecessary 38 | - Remove start_overlay() inside run() under #Startup Functions 39 | * No need to setup the Loader 40 | - This was built for fun and to send to some friends 41 | * Best to Change these lines with some more randomization 42 | ![carbon (1)](https://user-images.githubusercontent.com/43559704/143992047-9b11df27-b16c-4975-a11a-26b3767d5ebf.png) 43 | * If game path is not (C:\Program Files (x86)\Steam\steamapps\common\Rust\cfg\client.cfg) 44 | - Update game path on line 59 45 | 46 | ## How To Use 47 | 48 | To clone and run this application, you'll need [Git](https://git-scm.com) and [Python 3.9](https://www.python.org/downloads/release/python-399/) 49 | 50 | 51 | * Clone this repository 52 | ```bash 53 | $ git clone https://github.com/Bboddy/Recoil-Script 54 | ``` 55 | 56 | * Go into the repository 57 | ```bash 58 | $ cd Recoil-Script 59 | ``` 60 | 61 | * Install Packages 62 | ```bash 63 | $ pip install -r requirements.txt 64 | ``` 65 | 66 | * Run the app 67 | ```bash 68 | $ python Recoil.py 69 | ``` 70 | 71 | ## How to Make Safe 72 | 73 | * Testing 74 | - To test download steamcmd and setup a rust local server (https://www.rustafied.com/how-to-host-your-own-rust-server) 75 | - Set the launch options to (+server.secure 0 +server.eac 0 +server.encryption 0) then simply run RustClient.exe <- this runs rust without eac. 76 | 77 | * Detection 78 | - To make the script undetected you need to change the script to where the binaries are different enough from the original so that EAC / VAC cannot match the signatures of the two scripts. (This is assuming my script is detected by now.) 79 | - Changing binaries is done in one of two ways, adding a ton of junk code i.e. code that does nothing. Or modify / refactor the script entirely. 80 | - You can check binarys a number of ways, the easiest probably being Sigbench which was released on unknowncheats. 81 | 82 | * Remaining Undetected 83 | - Alot of people claim mouse_event is detected but aslong as you arnt sharing your script with a ton of people you will be fine. 84 | - I used this script for ~9 months with 1-3 people with no bans. 85 | 86 | ## How To Use Loader 87 | 88 | * *This is'nt secure* 89 | 90 | * You will need a Database setup as such 91 | 92 | ![Screenshot_2](https://user-images.githubusercontent.com/43559704/144000003-438599a5-c66d-4976-a2b9-066804bde567.png) 93 | 94 | ![Screenshot_3](https://user-images.githubusercontent.com/43559704/144000073-04d12840-4a7f-4ec8-a6f7-b890c037e85c.png) 95 | 96 | - I am using PHPmyadmin setup on Cpanel 97 | 98 | * Next you will need your DB info 99 | 100 | ![carbon (2)](https://user-images.githubusercontent.com/43559704/144000309-ab9ed88e-24e7-48b2-af2f-3ccb40e3fc2b.png) 101 | 102 | - I decided to encrypt all of my connection strings before hand using cryptography.fernet 103 | 104 | * To encrypt all of your connection strings folow this for each of what you want encrypted 105 | 106 | * Otherwise remove the encryption from mysql.connector.connect(everything in here) and replace with unencrypted info 107 | 108 | - Repeat this for your DB, Username, Password 109 | - Once encrypted put them into there respective spots in Loader.py 110 | 111 | * Remove last two lines from Recoil.py 112 | 113 | - Run the app 114 | ```bash 115 | $ python Loader.py 116 | ``` 117 | ![carbon (3)](https://user-images.githubusercontent.com/43559704/144001009-7113d64f-6ef4-410a-9964-10dc887b5412.png) 118 | 119 | - Once encrypted put them into there respective spots in Loader.py mysql.connector.connect(inside here) 120 | 121 | ## Credits 122 | 123 | - [awhall56](https://www.unknowncheats.me/forum/rust/390615-paste-recoil-script.html) - A start on how everything works 124 | - [absolutenothing](https://www.unknowncheats.me/forum/rust/335162-gun-recoil-tables-crouched-standing.html) - Some of the Recoil Tables 125 | - [RandyShanks](https://www.unknowncheats.me/forum/rust/386523-rust-recoil-tables-pixel.html) - Some of the Recoil Tables 126 | - [UC](https://www.unknowncheats.me/forum/rust/) - Everything else 127 | -------------------------------------------------------------------------------- /Recoil.py: -------------------------------------------------------------------------------- 1 | import win32api, ctypes, pyttsx3, random, multiprocessing, Overlay 2 | from datetime import datetime, timedelta 3 | #Loop settings 4 | active = True 5 | paused = False 6 | ########### Recoil Tables 7 | Recoil_Tables = [ 8 | #Recoil_AK 9 | [[-35, 50],[5, 46],[-55, 42],[-42, 37],[0, 33],[16, 28],[29, 24],[38, 19],[42, 14],[42, 9],[38, 9],[30, 18],[17, 25],[0, 29],[-15, 32],[-27, 33],[-37, 32],[-43, 29],[-46, 24],[-45, 17],[-42, 8],[-35, 5],[-24, 14],[-11, 21],[12, 25],[36, 28],[49, 28],[49, 26],[38, 21]], 10 | #Recoil_LR 11 | [[-2.5716, 26.2726], [-6.499, 32.5123], [-10.5691, 34.6882], [-15.0501, 32.8004], [-16.5015, 26.8927], [-14.8903, 21.6664], [-10.2167, 18.6228], [-2.3359, 15.8424], [9.5645, 13.3251], [18.0725, 11.0709], [21.0806, 9.0797], [18.5887, 7.3517], [10.5968, 5.9258], [-0.4584, 5.1813], [-5.8302, 4.6544], [-9.7352, 4.1882], [-12.7238, 3.7826], [-14.7961, 3.4377], [-15.952, 3.1534], [-16.1917, 2.9299], [-15.5149, 2.7669], [-13.9219, 2.6647], [-11.4124, 2.6231], [-7.9867, 2.6421], [-3.5444, 2.7219], [14.0846, 2.8623], [32.0283, 3.0633], [37.866, 3.325], [31.5974, 3.6474], [0, 8], [50, 0]], 12 | #Recoil_MP5 13 | [[0, 21],[0, 29],[0, 33],[12, 33],[29, 29],[33, 22],[23, 13],[0, 10],[-18, 9],[-25, 8],[-19, 7],[-3, 6],[7, 5],[14, 4],[16, 4],[16, 3],[12, 2],[6, 2],[-1, 1],[-5, 1],[-8, 0],[-10, 0],[-12, 0],[-13, 0],[-13, 0],[-12, 0],[-11, 0],[-8, 0],[-5, 0]], 14 | #Recoil_Custom 15 | [[-13.9306, 27.9232], [-6.7788, 27.6898], [-0.4073, 26.938], [6.248, 25.6679], [10.4567, 23.8793], [11.5526, 21.5724], [9.5355, 18.7471], [4.4055, 16.0817], [-3.1726, 14.6362], [-9.0352, 13.3281], [-11.5846, 12.1185], [-10.8178, 11.0074], [-6.7348, 9.9947], [0.2566, 9.0805], [6.347, 8.2648], [9.8395, 7.5476], [10.7665, 6.9289], [9.128, 6.4086], [4.9239, 5.9868], [-0.9875, 5.6635], [-4.7353, 5.4387], [-6.3062, 5.3123], [-5.7881, 5.2844], [-7, 0], [19, 5], [3, 11], [61, 0], [73, 0], [54, 6], [0, 8], [50, 0]], 16 | #Recoil_Thompson 17 | [[-15.8279, 33.4964], [-5.8047, 33.011], [3.5853, 31.6299], [11.3567, 29.353], [13.8312, 26.1803], [10.9266, 22.1118], [2.6596, 18.7347], [-7.7474, 16.766], [-13.3286, 14.9674], [-13.1795, 13.339], [-7.3, 11.8808], [2.7772, 10.5928], [10.0402, 9.4749], [12.8529, 8.5271], [11.2323, 7.7496], [5.1785, 7.1422], [-2.8139, 6.705], [-6.8923, 6.438], [-7.3495, 6.3412], [-29, 5], [-28, 0], [-21, 5], [-12, 13], [-7, 0], [19, 5], [3, 11], [61, 0], [73, 0], [54, 6], [0, 8], [50, 0]], 18 | #M249 19 | [[0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62], [0, 62]], 20 | #Sar 21 | [85, 0], 22 | #M92 23 | [82, 0], #Could be 2x'd 24 | #Python 25 | [155, 0] #Could be 2x'd 26 | ] 27 | Recoil_Delays = [ 28 | 0.1333333333, #ak_delay 29 | 0.12, #lr_delay 30 | 0.1, #mp5_delay 31 | 0.1, #custom_delay 32 | 0.12922, #tom_delay 33 | 0.103, #m249_delay 34 | 0.15, #semi_delay 35 | 0.20, 36 | 0.20, 37 | 0.20, 38 | 0.20 39 | ] 40 | Scope_Values = [ 41 | #None 42 | 1, 43 | #8x 44 | 3.84, 45 | #16x 46 | 7.68, 47 | #Holo 48 | 1.2, 49 | #Simple 50 | 0.8 51 | ] 52 | #Multipliers 53 | all_scopes = ["None", "8x", "16x", "Holo", "Simple",] 54 | all_weapons = ["AK", "LR", "MP5", "Custom", "Thompson", "M2", "Sar", "M9", "Python"] 55 | scopes_overlay = [" ", " 8X", "16X", " HOL", "SIM",] 56 | weapon_overlay = [" AK", " LR", "MP5", "CUS", "TOM", " M2", "SAR", " M9", " PY"] 57 | active_weapon, active_scope, start_time = 0, 0, 0 58 | 59 | def get_sense(): #Getting sensitivity 60 | global sense 61 | file = open('C:\Program Files (x86)\Steam\steamapps\common\Rust\cfg\client.cfg') #Path to rust 62 | for line in file: 63 | if "input.sensitivity" in line: 64 | line = line.replace('"', '') 65 | sense = float(line.replace('input.sensitivity', '')) 66 | file.close() 67 | 68 | def mouse_move_curved(x,y,delay): #Recoil control for curved weapons 69 | global start_time 70 | divider = random.randint(10,40) #Smoothing factor 71 | moveindex, dxindex, dyindex = 0, 0, 0 72 | dx = int(x / divider) 73 | absx = abs(x - dx * divider) 74 | dy = int(y / divider) 75 | ry = y % divider 76 | bullet_delay = (delay / (divider)) * 0.60 # 60% of the delay between shots 77 | while moveindex < divider: 78 | bullet_start_time = datetime.now() 79 | ctypes.windll.user32.mouse_event(0x0001, dx, dy, 0, 5) #Move recoil / divider 80 | moveindex += 1 81 | if absx * moveindex > (dxindex + 1) * divider: 82 | dxindex += 1 83 | ctypes.windll.user32.mouse_event(0x0001, int(x/abs(x)), 0, 0, 5) 84 | if ry * moveindex > (dyindex + 1) * divider: 85 | dyindex += 1 86 | ctypes.windll.user32.mouse_event(0x0001, 0, int(y/abs(y)), 0, 5) 87 | sleepTime = timedelta(seconds = bullet_delay) 88 | while bullet_start_time + sleepTime > datetime.now(): #Sleeping in between each smoothing move 89 | pass 90 | if x != 0 and y != 0: #Accounting for loss 91 | if round(x) != dxindex * int(x/abs(x)) + dx * moveindex: 92 | ctypes.windll.user32.mouse_event(0x0001, int(x/abs(x)), 0, 0, 5) 93 | dxindex += 1 94 | if round(y) != dyindex * int(y/abs(y)) + dy * moveindex: 95 | ctypes.windll.user32.mouse_event(0x0001, int(y/abs(y)), 0, 0, 5) 96 | dyindex += 1 97 | sleepTime = timedelta(seconds = delay) 98 | while start_time + sleepTime > datetime.now(): #This is more accurate then time.sleep() 99 | pass #This also wont brick if -slept time 100 | 101 | def call_move(recoil_pattern, delay): 102 | global start_time 103 | current_bullet = 0 104 | if active_weapon < 6: #Curved weapons that need smoothing 105 | while current_bullet < len(recoil_pattern) and win32api.GetKeyState(0x01) < 0: 106 | if current_bullet != 0: 107 | start_time = datetime.now() 108 | recoil_x = (((recoil_pattern[current_bullet][0] / 2) / sense) * Scope_Values[active_scope]) 109 | recoil_y = (((recoil_pattern[current_bullet][1] / 2) / sense) * Scope_Values[active_scope]) 110 | if active_weapon == 5 and win32api.GetKeyState(0x11) < 0: 111 | recoil_x = recoil_x / 2 112 | recoil_y = recoil_y / 2 113 | mouse_move_curved(recoil_x, recoil_y, delay) 114 | current_bullet += 1 115 | else: 116 | if current_bullet != 0: # Recoil control for linear weapons that need to be clicked each shot 117 | start_time = datetime.now() 118 | recoil_x = (((recoil_pattern[0] / 2) / sense) * Scope_Values[active_scope]) 119 | recoil_y = (((recoil_pattern[1] / 2) / sense) * Scope_Values[active_scope]) 120 | if win32api.GetKeyState(0x11) < 0: #If player crouched, recoil is .5 for these weapons 121 | recoil_x = recoil_x / 2 122 | recoil_y = recoil_y / 2 123 | ctypes.windll.user32.mouse_event(0x0001, int(recoil_y), int(recoil_x), 0, 5) 124 | sleepTime = timedelta(seconds = delay) 125 | while start_time + sleepTime > datetime.now() or win32api.GetKeyState(0x01) < 0: 126 | pass 127 | 128 | def scope_change(): #Changes the current scope value 129 | global active_scope 130 | if active_scope == 4: #Max number of scopes 131 | active_scope = 0 132 | else: 133 | active_scope += 1 134 | 135 | def weapon_change(int): #Changes the current weapon value 136 | if int == -1 and active_weapon == 0: 137 | return 8 138 | elif int == 1 and active_weapon == 8: #Max number of weapons 139 | return 0 140 | else: 141 | return (active_weapon + int) 142 | 143 | def run(): 144 | global active, paused, active_weapon, start_time, Recoil_Tables, Recoil_Delays, weapon_overlay 145 | #Startup Functions 146 | get_sense() 147 | #Start Overlay 148 | p = multiprocessing.Process(target=Overlay.draw, args=[weapon_overlay[active_weapon], scopes_overlay[active_scope]]) 149 | p.start() 150 | #TTS Settings 151 | engine = pyttsx3.init() 152 | engine.setProperty("volume", 0.5) 153 | engine.setProperty("rate", 350) 154 | voices = engine.getProperty("voices") 155 | engine.setProperty("voice", voices[1].id) 156 | engine.say("Started") 157 | engine.runAndWait() #Run engine.say and wait till done 158 | while active: #Main loop 159 | #While not paused 160 | if not paused: 161 | if win32api.GetKeyState(0x01) < 0 and win32api.GetKeyState(0x02) < 0: #Left n Right MB 162 | start_time = datetime.now() 163 | call_move(Recoil_Tables[active_weapon], Recoil_Delays[active_weapon]) 164 | if win32api.GetKeyState(0x22) < 0: #PageDown 165 | #win32api.SetCursorPos([300, 300]) #For drawing in paint (debugging) 166 | active_weapon = weapon_change(1) 167 | p.terminate() 168 | p = multiprocessing.Process(target=Overlay.draw, args=[weapon_overlay[active_weapon], scopes_overlay[active_scope]]) 169 | p.start() 170 | engine.say(all_weapons[active_weapon]) 171 | engine.runAndWait() 172 | if win32api.GetKeyState(0x21) < 0: #PageUp 173 | active_weapon = weapon_change(-1) 174 | p.terminate() 175 | p = multiprocessing.Process(target=Overlay.draw, args=[weapon_overlay[active_weapon], scopes_overlay[active_scope]]) 176 | p.start() 177 | engine.say(all_weapons[active_weapon]) 178 | engine.runAndWait() 179 | if win32api.GetKeyState(0x24) < 0: #Home 180 | scope_change() 181 | p.terminate() 182 | p = multiprocessing.Process(target=Overlay.draw, args=[weapon_overlay[active_weapon], scopes_overlay[active_scope]]) 183 | p.start() 184 | engine.say(all_scopes[active_scope]) 185 | engine.runAndWait() 186 | #Doesnt Matter if Paused 187 | if win32api.GetKeyState(0x91) < 0: #ScrLk 188 | get_sense() 189 | engine.say("Updated") 190 | engine.runAndWait() 191 | if win32api.GetKeyState(0x13) < 0: #Pause 192 | paused = not paused 193 | if paused: 194 | engine.say("Paused") 195 | engine.runAndWait() 196 | elif not paused: 197 | engine.say("Unpaused") 198 | engine.runAndWait() 199 | if win32api.GetKeyState(0x23) < 0: #End 200 | engine.say("Exiting") 201 | p.terminate() 202 | engine.runAndWait() 203 | active = False 204 | 205 | if __name__ == '__main__': 206 | run() -------------------------------------------------------------------------------- /dist/Recoil-V1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bboddy/Rust-Recoil-Script/b0a98dfd412b80380dd1584e1c6b672a4607e2ed/dist/Recoil-V1.exe -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bboddy/Rust-Recoil-Script/b0a98dfd412b80380dd1584e1c6b672a4607e2ed/requirements.txt --------------------------------------------------------------------------------