├── .DS_Store
├── .gitattributes
├── .idea
├── .gitignore
├── .name
├── FTNAIMZ.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── Arduino Sketch
├── FTN-Arduino
│ └── FTN-Arduino.ino
├── ImprovedMouse.cpp
├── ImprovedMouse.h
└── hidcustom.h
├── README.md
├── __pycache__
├── capture.cpython-39.pyc
├── fov_window.cpython-39.pyc
├── ftnaimz.cpython-39.pyc
└── mouse.cpython-39.pyc
├── capture.py
├── fov_window.py
├── ftnaimz.py
├── main.py
└── mouse.py
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostspaceship/ColorBasedAimbot/79449176df40f7a161147986d869c4ba293c6d85/.DS_Store
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.cpp linguist-vendored
2 | *.h linguist-vendored
3 | *.ino linguist-vendored
4 | *.hpp linguist-vendored
5 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | main.py
--------------------------------------------------------------------------------
/.idea/FTNAIMZ.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Arduino Sketch/FTN-Arduino/FTN-Arduino.ino:
--------------------------------------------------------------------------------
1 | #ifdef dobogusinclude
2 | #include
3 | #endif
4 | #include
5 |
6 | #include "hidcustom.h"
7 |
8 | signed char delta[3] = {0, 0, 0};
9 |
10 | void MouseRptParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
11 | {
12 | MYMOUSEINFO *pmi = (MYMOUSEINFO *)buf;
13 |
14 | if (CHECK_BIT(prevState.mouseInfo.buttons, MOUSE_LEFT) != CHECK_BIT(pmi->buttons, MOUSE_LEFT))
15 | {
16 | if (CHECK_BIT(pmi->buttons, MOUSE_LEFT))
17 | Mouse.press(MOUSE_LEFT);
18 | else
19 | Mouse.release(MOUSE_LEFT);
20 | }
21 |
22 | if (CHECK_BIT(prevState.mouseInfo.buttons, MOUSE_RIGHT) != CHECK_BIT(pmi->buttons, MOUSE_RIGHT))
23 | {
24 | if (CHECK_BIT(pmi->buttons, MOUSE_RIGHT))
25 | Mouse.press(MOUSE_RIGHT);
26 | else
27 | Mouse.release(MOUSE_RIGHT);
28 | }
29 |
30 | if (CHECK_BIT(prevState.mouseInfo.buttons, MOUSE_MIDDLE) != CHECK_BIT(pmi->buttons, MOUSE_MIDDLE))
31 | {
32 | if (CHECK_BIT(pmi->buttons, MOUSE_MIDDLE))
33 | Mouse.press(MOUSE_MIDDLE);
34 | else
35 | Mouse.release(MOUSE_MIDDLE);
36 | }
37 |
38 | if (CHECK_BIT(prevState.mouseInfo.buttons, MOUSE_PREV) != CHECK_BIT(pmi->buttons, MOUSE_PREV))
39 | {
40 | if (CHECK_BIT(pmi->buttons, MOUSE_PREV))
41 | Mouse.press(MOUSE_PREV);
42 | else
43 | Mouse.release(MOUSE_PREV);
44 | }
45 |
46 | if (CHECK_BIT(prevState.mouseInfo.buttons, MOUSE_NEXT) != CHECK_BIT(pmi->buttons, MOUSE_NEXT))
47 | {
48 | if (CHECK_BIT(pmi->buttons, MOUSE_NEXT))
49 | Mouse.press(MOUSE_NEXT);
50 | else
51 | Mouse.release(MOUSE_NEXT);
52 | }
53 |
54 | if (pmi->dX || pmi->dY)
55 | OnMouseMove(pmi);
56 |
57 | prevState.bInfo[0] = buf[0];
58 | }
59 |
60 | void MouseRptParser::OnMouseMove(MYMOUSEINFO *mi)
61 | {
62 | delta[0] = mi->dX;
63 | delta[1] = mi->dY;
64 | }
65 |
66 |
67 | #include
68 |
69 | USB Usb;
70 | USBHub Hub(&Usb);
71 | HIDBoot HidMouse(&Usb);
72 |
73 | MouseRptParser Prs;
74 |
75 | void setup()
76 | {
77 | Serial.begin(115200);
78 | Serial.setTimeout(1);
79 | Usb.Init();
80 | HidMouse.SetReportParser(0, &Prs);
81 | Mouse.begin();
82 | }
83 |
84 | void loop()
85 | {
86 | delta[0] = 0;
87 | delta[1] = 0;
88 | delta[2] = 0;
89 | Usb.Task();
90 |
91 | if (Serial.available() > 0)
92 | {
93 | char inChar = Serial.read();
94 | if (inChar == 'M')
95 | Serial.readBytes((char *)&delta, 2);
96 | else if (inChar == 'C')
97 | Mouse.click();
98 | }
99 | Mouse.move(delta[0], delta[1], delta[2]);
100 | }
--------------------------------------------------------------------------------
/Arduino Sketch/ImprovedMouse.cpp:
--------------------------------------------------------------------------------
1 | #include "ImprovedMouse.h"
2 |
3 | static const uint8_t _hidMultiReportDescriptorMouse[] PROGMEM = {
4 | /* Mouse relative */
5 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 54 */
6 | 0x09, 0x02, /* USAGE (Mouse) */
7 | 0xa1, 0x01, /* COLLECTION (Application) */
8 | 0x85, HID_REPORTID_MOUSE, /* REPORT_ID */
9 |
10 | /* 8 Buttons */
11 | 0x05, 0x09, /* USAGE_PAGE (Button) */
12 | 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
13 | 0x29, 0x08, /* USAGE_MAXIMUM (Button 8) */
14 | 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
15 | 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
16 | 0x95, 0x08, /* REPORT_COUNT (8) */
17 | 0x75, 0x01, /* REPORT_SIZE (1) */
18 | 0x81, 0x02, /* INPUT (Data,Var,Abs) */
19 |
20 | /* X, Y, Wheel */
21 | 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
22 | 0x09, 0x30, /* USAGE (X) */
23 | 0x09, 0x31, /* USAGE (Y) */
24 | 0x09, 0x38, /* USAGE (Wheel) */
25 | 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
26 | 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
27 | 0x75, 0x08, /* REPORT_SIZE (8) */
28 | 0x95, 0x03, /* REPORT_COUNT (3) */
29 | 0x81, 0x06, /* INPUT (Data,Var,Rel) */
30 |
31 | /* End */
32 | 0xc0 /* END_COLLECTION */
33 | };
34 |
35 | Mouse_::Mouse_(void)
36 | {
37 | static HIDSubDescriptor node(_hidMultiReportDescriptorMouse, sizeof(_hidMultiReportDescriptorMouse));
38 | HID().AppendDescriptor(&node);
39 | }
40 |
41 | void Mouse_::begin(void)
42 | {
43 | end();
44 | }
45 |
46 | void Mouse_::end(void)
47 | {
48 | _buttons = 0;
49 | move(0, 0, 0);
50 | }
51 |
52 | void Mouse_::click(uint8_t b)
53 | {
54 | _buttons = b;
55 | move(0, 0, 0);
56 | _buttons = 0;
57 | move(0, 0, 0);
58 | }
59 |
60 | void Mouse_::move(signed char x, signed char y, signed char wheel)
61 | {
62 | HID_MouseReport_Data_t report;
63 | report.buttons = _buttons;
64 | report.xAxis = x;
65 | report.yAxis = y;
66 | report.wheel = wheel;
67 | SendReport(&report, sizeof(report));
68 | }
69 |
70 | void Mouse_::buttons(uint8_t b)
71 | {
72 | if (b != _buttons)
73 | {
74 | _buttons = b;
75 | move(0, 0, 0);
76 | }
77 | }
78 |
79 | void Mouse_::press(uint8_t b)
80 | {
81 | buttons(_buttons | b);
82 | }
83 |
84 | void Mouse_::release(uint8_t b)
85 | {
86 | buttons(_buttons & ~b);
87 | }
88 |
89 | void Mouse_::releaseAll(void)
90 | {
91 | _buttons = 0;
92 | move(0, 0, 0);
93 | }
94 |
95 | bool Mouse_::isPressed(uint8_t b)
96 | {
97 | if ((b & _buttons) > 0)
98 | return true;
99 | return false;
100 | }
101 |
102 | void Mouse_::SendReport(void *data, int length)
103 | {
104 | HID().SendReport(HID_REPORTID_MOUSE, data, length);
105 | }
106 |
107 | Mouse_ Mouse;
108 |
--------------------------------------------------------------------------------
/Arduino Sketch/ImprovedMouse.h:
--------------------------------------------------------------------------------
1 |
2 | // Include guard
3 | #pragma once
4 |
5 | //================================================================================
6 | // Settings
7 | //================================================================================
8 |
9 | #define HID_REPORTID_NONE 0
10 |
11 | #ifndef HID_REPORTID_MOUSE
12 | #define HID_REPORTID_MOUSE 1
13 | #endif
14 |
15 | #ifndef HID_REPORTID_KEYBOARD
16 | #define HID_REPORTID_KEYBOARD 2
17 | #endif
18 |
19 | #ifndef HID_REPORTID_RAWHID
20 | // This will not work properly in most cases.
21 | // The number is just kept from the old number counting.
22 | //#define HID_REPORTID_RAWHID 3
23 | #endif
24 |
25 | #ifndef HID_REPORTID_CONSUMERCONTROL
26 | #define HID_REPORTID_CONSUMERCONTROL 4
27 | #endif
28 |
29 | #ifndef HID_REPORTID_SYSTEMCONTROL
30 | #define HID_REPORTID_SYSTEMCONTROL 5
31 | #endif
32 |
33 | #ifndef HID_REPORTID_GAMEPAD
34 | #define HID_REPORTID_GAMEPAD 6
35 | #endif
36 |
37 | #ifndef HID_REPORTID_MOUSE_ABSOLUTE
38 | #define HID_REPORTID_MOUSE_ABSOLUTE 7
39 | #endif
40 |
41 | #ifndef HID_REPORTID_NKRO_KEYBOARD
42 | #define HID_REPORTID_NKRO_KEYBOARD 8
43 | #endif
44 |
45 | #ifndef HID_REPORTID_TEENSY_KEYBOARD
46 | #define HID_REPORTID_TEENSY_KEYBOARD 9
47 | #endif
48 |
49 | #ifndef HID_REPORTID_SURFACEDIAL
50 | #define HID_REPORTID_SURFACEDIAL 10
51 | #endif
52 |
53 | #if defined(ARDUINO_ARCH_AVR)
54 |
55 | // Use default alignment for AVR
56 | #define ATTRIBUTE_PACKED
57 |
58 | #include "PluggableUSB.h"
59 |
60 | #define EPTYPE_DESCRIPTOR_SIZE uint8_t
61 |
62 | #elif defined(ARDUINO_ARCH_SAM)
63 |
64 | #define ATTRIBUTE_PACKED __attribute__((packed, aligned(1)))
65 |
66 | #include "USB/PluggableUSB.h"
67 |
68 | #define EPTYPE_DESCRIPTOR_SIZE uint32_t
69 | #define EP_TYPE_INTERRUPT_IN (UOTGHS_DEVEPTCFG_EPSIZE_512_BYTE | \
70 | UOTGHS_DEVEPTCFG_EPDIR_IN | \
71 | UOTGHS_DEVEPTCFG_EPTYPE_BLK | \
72 | UOTGHS_DEVEPTCFG_EPBK_1_BANK | \
73 | UOTGHS_DEVEPTCFG_NBTRANS_1_TRANS | \
74 | UOTGHS_DEVEPTCFG_ALLOC)
75 | #define EP_TYPE_INTERRUPT_OUT (UOTGHS_DEVEPTCFG_EPSIZE_512_BYTE | \
76 | UOTGHS_DEVEPTCFG_EPTYPE_BLK | \
77 | UOTGHS_DEVEPTCFG_EPBK_1_BANK | \
78 | UOTGHS_DEVEPTCFG_NBTRANS_1_TRANS | \
79 | UOTGHS_DEVEPTCFG_ALLOC)
80 | #define USB_EP_SIZE EPX_SIZE
81 | #define USB_SendControl USBD_SendControl
82 | #define USB_Available USBD_Available
83 | #define USB_Recv USBD_Recv
84 | #define USB_Send USBD_Send
85 | #define USB_Flush USBD_Flush
86 |
87 | #elif defined(ARDUINO_ARCH_SAMD)
88 |
89 | #define ATTRIBUTE_PACKED __attribute__((packed, aligned(1)))
90 |
91 | #define USB_EP_SIZE EPX_SIZE
92 | #define EP_TYPE_INTERRUPT_IN USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0);
93 | #define EP_TYPE_INTERRUPT_OUT USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_OUT(0);
94 |
95 | #if defined(ARDUINO_API_VERSION)
96 | #include "api/PluggableUSB.h"
97 | #define EPTYPE_DESCRIPTOR_SIZE unsigned int
98 | #else
99 | #include "USB/PluggableUSB.h"
100 |
101 | #define EPTYPE_DESCRIPTOR_SIZE uint32_t
102 | //#define USB_SendControl USBDevice.sendControl -> real C++ functions to take care of PGM overloading
103 | #define USB_Available USBDevice.available
104 | #define USB_Recv USBDevice.recv
105 | #define USB_RecvControl USBDevice.recvControl
106 | #define USB_Send USBDevice.send
107 | #define USB_Flush USBDevice.flush
108 |
109 | int USB_SendControl(void *y, uint8_t z);
110 | int USB_SendControl(uint8_t x, const void *y, uint8_t z);
111 | #endif
112 |
113 | #define TRANSFER_PGM 0
114 | #define TRANSFER_RELEASE 0
115 |
116 | #define HID_REPORT_TYPE_INPUT 1
117 | #define HID_REPORT_TYPE_OUTPUT 2
118 | #define HID_REPORT_TYPE_FEATURE 3
119 |
120 | #else
121 |
122 | #error "Unsupported architecture"
123 |
124 | #endif
125 |
126 | #include
127 |
128 | #define MOUSE_LEFT (1 << 0)
129 | #define MOUSE_RIGHT (1 << 1)
130 | #define MOUSE_MIDDLE (1 << 2)
131 | #define MOUSE_PREV (1 << 3)
132 | #define MOUSE_NEXT (1 << 4)
133 | // actually this mouse report has 8 buttons (for smaller descriptor)
134 | // but the last 3 wont do anything from what I tested
135 | #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE | MOUSE_PREV | MOUSE_NEXT)
136 |
137 | typedef union ATTRIBUTE_PACKED
138 | {
139 | // Mouse report: 8 buttons, position, wheel
140 | uint8_t whole8[0];
141 | uint16_t whole16[0];
142 | uint32_t whole32[0];
143 | struct ATTRIBUTE_PACKED
144 | {
145 | uint8_t buttons;
146 | int8_t xAxis;
147 | int8_t yAxis;
148 | int8_t wheel;
149 | };
150 | } HID_MouseReport_Data_t;
151 |
152 | typedef union ATTRIBUTE_PACKED
153 | {
154 | // BootMouse report: 3 buttons, position
155 | // Wheel is not supported by boot protocol
156 | uint8_t whole8[0];
157 | uint16_t whole16[0];
158 | uint32_t whole32[0];
159 | struct ATTRIBUTE_PACKED
160 | {
161 | uint8_t buttons;
162 | int8_t xAxis;
163 | int8_t yAxis;
164 | };
165 | } HID_BootMouseReport_Data_t;
166 |
167 | class Mouse_
168 | {
169 | public:
170 | Mouse_(void);
171 | void begin(void);
172 | void end(void);
173 | void click(uint8_t b = MOUSE_LEFT);
174 | void move(signed char x, signed char y, signed char wheel = 0);
175 | void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
176 | void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
177 | void releaseAll(void);
178 | bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
179 |
180 | void SendReport(void *data, int length);
181 |
182 | protected:
183 | uint8_t _buttons;
184 | inline void buttons(uint8_t b);
185 | };
186 | extern Mouse_ Mouse;
--------------------------------------------------------------------------------
/Arduino Sketch/hidcustom.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include "ImprovedMouse.h"
3 |
4 | #define CHECK_BIT(var, pos) ((var)&pos)
5 |
6 | struct MYMOUSEINFO
7 | {
8 | uint8_t buttons;
9 | int8_t dX;
10 | int8_t dY;
11 | int8_t wheel;
12 | };
13 |
14 | class MouseRptParser : public MouseReportParser
15 | {
16 | union
17 | {
18 | MYMOUSEINFO mouseInfo;
19 | uint8_t bInfo[sizeof(MYMOUSEINFO)];
20 | } prevState;
21 |
22 | protected:
23 | void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
24 |
25 | void OnMouseMove(MYMOUSEINFO *mi);
26 | void OnWheelMove(MYMOUSEINFO *mi);
27 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | REQUIRED HARDWARE:
2 |
3 | - ARDUINO LEONARDO
4 | - USB HOST SHIELD
5 |
6 | REQUIRED LIBRARIES:
7 |
8 | - NUMPY
9 | - MSS
10 | - PILLOW
11 | - TERMCOLOR
12 | - PYSERIAL
13 | - KEYBOARD
14 | - OPENCV-PYTHON
15 | - PYWIN32
16 | - PYAUTOGUI
17 |
--------------------------------------------------------------------------------
/__pycache__/capture.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostspaceship/ColorBasedAimbot/79449176df40f7a161147986d869c4ba293c6d85/__pycache__/capture.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/fov_window.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostspaceship/ColorBasedAimbot/79449176df40f7a161147986d869c4ba293c6d85/__pycache__/fov_window.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/ftnaimz.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostspaceship/ColorBasedAimbot/79449176df40f7a161147986d869c4ba293c6d85/__pycache__/ftnaimz.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/mouse.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostspaceship/ColorBasedAimbot/79449176df40f7a161147986d869c4ba293c6d85/__pycache__/mouse.cpython-39.pyc
--------------------------------------------------------------------------------
/capture.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import time
4 | from mss import mss
5 | import threading
6 |
7 |
8 | class Capture:
9 | def __init__(self, x, y, xfov, yfov):
10 | self.x, self.y, self.xfov, self.yfov = x, y, xfov, yfov
11 | self.screen = np.zeros((xfov, yfov, 3), np.uint8)
12 | self.image = None
13 | self.lock = threading.Lock()
14 | self.capture_thread = threading.Thread(target=self.capture_loop, daemon=True)
15 | self.capture_thread.start()
16 | self.start_time = time.time()
17 | self.frame_count = 0
18 |
19 | def capture_loop(self):
20 | while True:
21 | with self.lock:
22 | self.capture_screen()
23 | self.update_fps()
24 |
25 | def capture_screen(self):
26 | with mss() as sct:
27 | monitor = sct.monitors[0]
28 | top, left = monitor["top"] + self.y, monitor["left"] + self.x
29 | monitor = {"top": self.y, "left": self.x, "width": self.xfov, "height": self.yfov, "monitor": 0}
30 | self.image = sct.grab(monitor)
31 | self.screen = np.array(self.image)
32 |
33 | def update_fps(self):
34 | self.frame_count += 1
35 | elapsed_time = time.time() - self.start_time
36 | if elapsed_time >= 1:
37 | fps = self.frame_count / elapsed_time
38 | print(f" - FPS: {fps:.0f}", end="\r")
39 | self.frame_count = 0
40 | self.start_time = time.time()
41 |
42 | def get_screen(self):
43 | with self.lock:
44 | return self.screen
45 |
--------------------------------------------------------------------------------
/fov_window.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import threading
4 |
5 | LOWER_COLOR = np.array([140, 111, 160])
6 | UPPER_COLOR = np.array([148, 154, 194])
7 |
8 |
9 | def show_detection_window(grabber, window_toggled):
10 | while window_toggled():
11 | screen = grabber.get_screen()
12 | hsv = cv2.cvtColor(screen, cv2.COLOR_BGR2HSV)
13 |
14 | mask = cv2.inRange(hsv, LOWER_COLOR, UPPER_COLOR)
15 | highlighted = cv2.bitwise_and(screen, screen, mask=mask)
16 | blurred = cv2.GaussianBlur(highlighted, (0, 0), sigmaX=1, sigmaY=1)
17 | dimmed = cv2.addWeighted(screen, 0.1, np.zeros(screen.shape, dtype=screen.dtype), 0, 0)
18 | result = cv2.add(blurred, dimmed)
19 |
20 | if screen.shape[0] < 500 or screen.shape[1] < 500:
21 | result_resized = cv2.resize(result, (500, 500))
22 | else:
23 | result_resized = result
24 |
25 | cv2.imshow('DETECTION WINDOW FOR FTNAIMZ', result_resized)
26 |
27 | if cv2.waitKey(1) & 0xFF == ord('q'):
28 | break
29 | cv2.destroyAllWindows()
30 |
31 |
32 | def toggle_window(ftnaim):
33 | ftnaim.window_toggled = not ftnaim.window_toggled
34 |
35 | if ftnaim.window_toggled:
36 | threading.Thread(target=show_detection_window, args=(ftnaim.grabber, lambda: ftnaim.window_toggled),
37 | daemon=True).start()
--------------------------------------------------------------------------------
/ftnaimz.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | import threading
4 | import time
5 | import win32api
6 |
7 | from capture import Capture
8 | from mouse import ArduinoMouse
9 | from fov_window import toggle_window
10 |
11 |
12 | class Ftnaim:
13 | LOWER_COLOR = np.array([140, 120, 180])
14 | UPPER_COLOR = np.array([160, 200, 255])
15 |
16 | def __init__(self, x, y, xfov, yfov, FLICKSPEED, MOVESPEED):
17 | self.arduinomouse = ArduinoMouse()
18 | self.grabber = Capture(x, y, xfov, yfov)
19 | self.flickspeed = FLICKSPEED
20 | self.movespeed = MOVESPEED
21 | threading.Thread(target=self.listen, daemon=True).start()
22 | self.toggled = False
23 | self.window_toggled = False
24 |
25 | def toggle(self):
26 | self.toggled = not self.toggled
27 | time.sleep(0.2)
28 |
29 | def listen(self):
30 | while True:
31 | if win32api.GetAsyncKeyState(0x71) < 0:
32 | toggle_window(self)
33 | time.sleep(0.2)
34 | if win32api.GetAsyncKeyState(0x02) < 0 and self.toggled:
35 | self.process("move")
36 | elif win32api.GetAsyncKeyState(0x12) < 0 and self.toggled:
37 | self.process("click")
38 |
39 | def process(self, action):
40 | screen = self.grabber.get_screen()
41 | hsv = cv2.cvtColor(screen, cv2.COLOR_BGR2HSV)
42 | mask = cv2.inRange(hsv, self.LOWER_COLOR, self.UPPER_COLOR)
43 | dilated = cv2.dilate(mask, None, iterations=5)
44 | contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
45 |
46 | if not contours:
47 | return
48 |
49 | contour = max(contours, key=cv2.contourArea)
50 | x, y, w, h = cv2.boundingRect(contour)
51 | center = (x + w // 2, y + h // 2)
52 | y_offset = int(h * 0.3)
53 |
54 | if action == "move":
55 | cX = center[0]
56 | cY = y + y_offset
57 | x_diff = cX - self.grabber.xfov // 2
58 | y_diff = cY - self.grabber.yfov // 2
59 | self.arduinomouse.move(x_diff * self.movespeed, y_diff * self.movespeed)
60 |
61 | elif action == "click" and abs(center[0] - self.grabber.xfov // 2) <= 4 and abs(
62 | center[1] - self.grabber.yfov // 2) <= 10:
63 | self.arduinomouse.click()
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | import keyboard
4 | import pyautogui
5 | from termcolor import colored
6 | from ftnaimz import Ftnaim
7 |
8 | # Settings
9 | TOGGLE_KEY = 'F1' # Toggle on/off FTNAIM key
10 | XFOV = 100 # X-Axis FOV
11 | YFOV = 50 # Y-Axis FOV
12 | FLICKSPEED = 1.07437623 # Default flick speed
13 | MOVESPEED = 1 / 5 # Default move speed
14 |
15 | monitor = pyautogui.size()
16 | CENTER_X, CENTER_Y = monitor.width // 2, monitor.height // 2
17 |
18 | senstitle = colored('''
19 | ░██████╗███████╗███╗░░██╗░██████╗░█████╗░
20 | ██╔════╝██╔════╝████╗░██║██╔════╝██╔══██╗
21 | ╚█████╗░█████╗░░██╔██╗██║╚█████╗░╚═╝███╔╝
22 | ░╚═══██╗██╔══╝░░██║╚████║░╚═══██╗░░░╚══╝░
23 | ███████╔╝███████╗██║░╚███║██████╔╝░░░██╗░░
24 | ╚═════╝░╚══════╝╚═╝░░╚══╝╚═════╝░░░░╚═╝░░
25 | ''', 'magenta')
26 |
27 | ftntitle = colored('''
28 | ███████╗████████╗███╗░░██╗ ░▄▄▄▄░ ░█████╗░██╗███╗░░░███╗███████╗
29 | ██╔════╝╚══██╔══╝████╗░██║ ▀▀▄██► ██╔══██╗██║████╗░████║╚════██║
30 | █████╗░░░░░██║░░░██╔██╗██║ ▀▀███► ███████║██║██╔████╔██║░░███╔═╝
31 | ██╔══╝░░░░░██║░░░██║╚████║ ░▀███►░█► ██╔══██║██║██║╚██╔╝██║██╔══╝░░
32 | ██║░░░░░░░░██║░░░██║░╚███║ ▒▄████▀▀ ██║░░██║██║██║░╚═╝░██║███████╗
33 | ╚═╝░░░░░░░░╚═╝░░░╚═╝░░╚══╝ ╚═╝░░╚═╝╚═╝╚═╝░░░░░╚═╝╚══════╝
34 | FTN AIMZ - v1.0''', 'magenta')
35 |
36 |
37 | def calculate_settings(sensitivity):
38 | global FLICKSPEED, MOVESPEED
39 | FLICKSPEED = 1.07437623 * (sensitivity ** -0.9936827126) # Calculate flick speed
40 | MOVESPEED = 1 / (5 * sensitivity) # Calculate move speed
41 |
42 |
43 | def main():
44 | os.system('title ftnaimbot')
45 |
46 | print(senstitle)
47 | sensitivity = float(input(colored("Enter your sensitivity: ", 'magenta')))
48 | calculate_settings(sensitivity)
49 |
50 | os.system("cls")
51 |
52 | ftnaimbot = Ftnaim(CENTER_X - XFOV // 2, CENTER_Y - YFOV // 2, XFOV, YFOV, FLICKSPEED, MOVESPEED)
53 |
54 | print(ftntitle)
55 | print(colored('Discord:', 'magenta'), colored('lostspaceship', 'magenta'))
56 | print(colored('GitHub:', 'magenta'), end=' ')
57 | print(colored('https://github.com/lostspaceship', 'magenta', attrs=['underline']))
58 |
59 | print()
60 | print(colored('[Info]', 'magenta'), colored('Set enemies to', 'white'), colored('Purple', 'magenta'))
61 | print(colored('[Info]', 'magenta'), colored(f'Press {TOGGLE_KEY} to toggle FTN AIM', 'white'))
62 | print(colored('[Info]', 'magenta'), colored(f'Press F2 to toggle Detection Window', 'white'))
63 | print(colored('[Info]', 'magenta'), colored('RightMB', 'magenta'), colored('= Aimbot', 'white'))
64 | print(colored('[Info]', 'magenta'), colored('LeftAlt', 'magenta'), colored('= Triggerbot', 'white'))
65 | status = 'Disabled'
66 |
67 | try:
68 | while True:
69 | if keyboard.is_pressed(TOGGLE_KEY):
70 | ftnaimbot.toggle()
71 | status = 'Enabled ' if ftnaimbot.toggled else 'Disabled'
72 | print(f'\r{colored("[Status]", "magenta")} {colored(status, "white")}', end='')
73 | time.sleep(0.01)
74 | except (KeyboardInterrupt, SystemExit):
75 | print(colored('\n[Info]', 'magenta'), colored('Exiting...', 'white') + '\n')
76 | finally:
77 | ftnaimbot.close()
78 |
79 |
80 | if __name__ == '__main__':
81 | main()
--------------------------------------------------------------------------------
/mouse.py:
--------------------------------------------------------------------------------
1 | import serial
2 | import serial.tools.list_ports
3 | import random
4 | import time
5 | import sys
6 | from termcolor import colored
7 |
8 |
9 | class ArduinoMouse:
10 | def __init__(self, filter_length=3):
11 | self.serial_port = serial.Serial()
12 | self.serial_port.baudrate = 115200
13 | self.serial_port.timeout = 1
14 | self.serial_port.port = self.find_serial_port()
15 | self.filter_length = filter_length
16 | self.x_history = [0] * filter_length
17 | self.y_history = [0] * filter_length
18 | try:
19 | self.serial_port.open()
20 | except serial.SerialException:
21 | print(colored('[Error]', 'red'), colored(
22 | 'FTNAIMZ is already open or serial port in use by another app. Close FTNAIMZ and other apps before retrying.',
23 | 'white'))
24 | time.sleep(10)
25 | sys.exit()
26 |
27 | def find_serial_port(self):
28 | port = next((port for port in serial.tools.list_ports.comports() if "Arduino" in port.description), None)
29 | if port is not None:
30 | return port.device
31 | else:
32 | print(colored('[Error]', 'red'), colored(
33 | 'Unable to find serial port or the Arduino device is with different name. Please check its connection and try again.',
34 | 'white'))
35 | time.sleep(10)
36 | sys.exit()
37 |
38 | def move(self, x, y):
39 | self.x_history.append(x)
40 | self.y_history.append(y)
41 |
42 | self.x_history.pop(0)
43 | self.y_history.pop(0)
44 |
45 | smooth_x = int(sum(self.x_history) / self.filter_length)
46 | smooth_y = int(sum(self.y_history) / self.filter_length)
47 |
48 | finalx = smooth_x + 256 if smooth_x < 0 else smooth_x
49 | finaly = smooth_y + 256 if smooth_y < 0 else smooth_y
50 | self.serial_port.write(b"M" + bytes([int(finalx), int(finaly)]))
51 |
52 | def flick(self, x, y):
53 | x = x + 256 if x < 0 else x
54 | y = y + 256 if y < 0 else y
55 | self.serial_port.write(b"M" + bytes([int(x), int(y)]))
56 |
57 | def click(self):
58 | delay = random.uniform(0.01, 0.1)
59 | self.serial_port.write(b"C")
60 | time.sleep(delay)
61 |
62 | def close(self):
63 | self.serial_port.close()
64 |
65 | def __del__(self):
66 | self.close()
--------------------------------------------------------------------------------