diff --git a/.gitignore b/.gitignore
index 4c785298..7119bfd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,3 +50,4 @@ sunone_aimbot_cpp/modules/SimpleIni.h
/sunone_aimbot_cpp/modules/serial
sunone_aimbot_cpp/config.ini
/sunone_aimbot_cpp/sunone_aimbot_cpp.zip
+/sunone_aimbot_cpp/RN_AI
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 2aa7dd01..6325fe95 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024 SunOne
+Copyright (c) 2025 ReksarGames
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 3dc4555b..62194f25 100644
--- a/README.md
+++ b/README.md
@@ -1,383 +1,229 @@
-## 🛠️ Main Changes in This Version
-
-1. **HID Methods Implementation**
- Added two methods to improve system accuracy and speed.
-2. **Makcu Method**
- Improvements to game movement handling and control.
-3. **Kalman Filter**
- Increased accuracy of target movement prediction.
-4. **Aiming Smoothness**
- Reduced jitter, improving user experience.
-5. **Performance**
- Optimized processes for higher performance on supported devices.
-6. **Code Cleanup**
- Applied SOLID principles to improve code structure and maintainability.
+# 🎯 RN_AI_cpp — AI Aim Assistant
----
-
-## 🟣 New Configurations and Features
-
-### 🎨 Colorbot — Color Detection Parameters
+
-* **color_erode_iter:** number of erosion iterations — reduces image noise by removing small artifacts.
-* **color_dilate_iter:** number of dilation iterations — enlarges objects after erosion, restoring target shape.
-* **color_min_area:** minimum object area for detection — ignores very small regions (noise).
-* **color_target:** target color for tracking (e.g., Yellow).
-* **tinyArea:** minimum "point" to filter small elements — helps remove noise not related to the target.
-* **isOnlyTop:** consider only top objects/layers (true/false) — useful for selecting the most visible target.
-* **scanError:** allowed error in color scanning — reduces false positives.
+
+
+
+
+
-💡 **Description:**
-Colorbot improves target detection by color, filtering noise and keeping accuracy on top objects. Perfect for highlighting specific targets on screen.
-
----
+[🚀 Quick Start](#-quick-start) • [📚 Documentation](#-technical-details) * [📚Русская версия README](README_RU.md)
-### 🎯 Kalman Filter — Target Movement Prediction
-💡 **Description:**
-The Kalman filter smooths target movement and predicts its future position. This reduces jitter during aiming and improves shooting accuracy.
+
-**Parameter Purpose:**
-
-* **kalman_process_noise:** accounts for random changes in target movement (process noise).
-* **kalman_measurement_noise:** accounts for measurement inaccuracies (sensor or camera noise).
-* **kalman_speed_multiplier_x / kalman_speed_multiplier_y:** scales prediction speed horizontally and vertically.
-* **resetThreshold:** threshold above which the filter resets and starts tracking the target anew.
+
---
-### 🖥️ HID — Device Connection
+## ✨ Features
-* **hid_vid:** `0x1956`
-* **hid_pid:** `0x3001`
-* **PING_CODE:** `0xF9`
-
-💡 **Description:**
-HID configuration allows direct connection to specific boards for controlling the system. Use these parameters for connecting an Arduino Leonardo.
+| | |
+|---|---|
+| **🎯 AI Detection** | Target detection using neural networks with high accuracy |
+| **🎨 Color Detection** | Target identification through color-based filtering |
+| **📈 Real-time Stats** | FPS counter and latency information |
+| **🖱️ Aim Simulator** | Visualization of target movement prediction |
+| **🎛️ ClassTable** | Real-time dynamic class management |
+| **🔄 Kalman Filter** | Smooth movement without aim jitter |
+| **⚡ Multiple Backends** | DirectML, CUDA+TensorRT, Color Detection |
---
-### ⚠️ Important Changes
+## 🚀 Quick Start
-* Removed methods that are already detected automatically: **Arduino**, **WIN32**, **HID**.
-* These methods remained in the code but are no longer needed, as they are detected automatically.
-* If necessary, you can re-enable them depending on your firmware and hardware.
+### 1️⃣ Choose Your Build
+
+🟢 DirectML (Universal)
-[](https://github.com/SunOner/sunone_aimbot_cpp)
-[](https://github.com/SunOner/sunone_aimbot_cpp/blob/main/LICENSE)
-
-
-
-
-
-
+**For:** Any GPU (NVIDIA, AMD, Intel, integrated graphics)
-### 🟢 DirectML (DML) Build — Universal (All GPUs)
+```
+✅ Windows 10/11 (x64)
+✅ No CUDA required
+✅ Recommended for older GPUs
+```
-* **Works on:**
+**Recommended for:**
+- GTX 10xx/9xx/7xx series
+- AMD Radeon GPU
+- Intel Iris/Xe GPU
+- Laptops and office PCs
- * Any modern GPU (NVIDIA, AMD, Intel, including integrated graphics)
- * Windows 10/11 (x64)
- * No need for CUDA or special drivers!
-* **Recommended for:**
+
- * GTX 10xx/9xx/7xx series (old NVIDIA)
- * Any AMD Radeon or Intel Iris/Xe GPU
- * Laptops and office PCs with integrated graphics
-* **Download DML build:**
- [DirectML Release](https://disk.yandex.ru/d/9mf8VwfN0cK96w)
+
+🟡 CUDA + TensorRT (Maximum Performance)
-### 🟡 CUDA + TensorRT Build — High Performance (NVIDIA Only)
+**For:** Latest generation NVIDIA GPUs
-* **Works on:**
+```
+✅ RTX 2000/3000/4000 and newer
+✅ GTX 1660
+✅ CUDA 12.8 + TensorRT 10.8 (included)
+❌ Does not support GTX 10xx/Pascal and older
+```
- * NVIDIA GPUs **GTX 1660, RTX 2000/3000/4000 or newer**
- * **Requires:** CUDA 12.8, TensorRT 10.8 (included in build)
- * Windows 10/11 (x64)
-* **Not supported:** GTX 10xx/Pascal and older (TensorRT 10 limitation)
-* **Includes both CUDA+TensorRT and DML support (switchable in settings)**
-* **Download CUDA build:**
- [CUDA + TensorRT Release](https://disk.yandex.ru/d/VjyDyWLbv7AUHQ)
+**Features:**
+- Switch between CUDA+TensorRT and DML in settings
+- Maximum FPS and accuracy
+- Professional-grade performance
-**Both versions are ready-to-use: just download, unpack, run `ai.exe` and follow instructions in the overlay.**
+
---
-## 🚀 How to Run (For Precompiled Builds)
+## ⚙️ Configuration & Parameters
-1. **Download and unpack your chosen version (see links above).**
-2. For CUDA build, install [CUDA 12.8](https://developer.nvidia.com/cuda-12-8-0-download-archive) if not already installed.
-3. For DML build, no extra software is needed.
-4. **Run `ai.exe`.**
- On first launch, the model will be exported (may take up to 5 minutes).
-5. Place your `.onnx` model in the `models` folder and select it in the overlay (HOME key).
-6. All settings are available in the overlay.
- Use the HOME key to open/close overlay.
+### 📦 ClassTable — Class Management
-### 🎮 Controls
-
-* **Right Mouse Button:** Aim at the detected target
-* **F2:** Exit
-* **F3:** Pause aiming
-* **F4:** Reload config
-* **Home:** Open/close overlay and settings
+Dynamic management of target classes with:
+- ✅ Add/switch classes in real-time
+- ✅ Auto-detection of new classes
+- ✅ Configure Y1/Y2 position for each class
---
-# 🛠️ Build From Source (Advanced Users)
-
-If you want to compile the project yourself or modify code, follow these instructions.
-
-## 1. Requirements
-
-* **Visual Studio 2022 Community** ([Download](https://visualstudio.microsoft.com/vs/community/))
-* **Windows 10 or 11 (x64)**
-* **Windows SDK 10.0.26100.0** or newer
-* **CMake** ([Download](https://cmake.org/))
-* **OpenCV 4.10.0**
-* **\[For CUDA version]**
+### 🎨 Colorbot — Color Detection
- * [CUDA Toolkit 12.8](https://developer.nvidia.com/cuda-12-8-0-download-archive)
- * [cuDNN 9.7.1](https://developer.nvidia.com/cudnn-downloads)
- * [TensorRT 10.8.0.43](https://developer.nvidia.com/tensorrt/download/10x)
-* **\[For DML version]**
+Advanced color filtering system:
- * You can use [pre-built OpenCV DLLs](https://github.com/opencv/opencv/releases/tag/4.10.0) (just copy `opencv_world4100.dll` to your exe folder)
-* Other dependencies:
+| Parameter | Range | Description |
+|-----------|-------|-------------|
+| `color_erode_iter` | 0-5 | Number of erosion iterations (reduces noise) |
+| `color_dilate_iter` | 0-5 | Number of dilation iterations (restores size) |
+| `color_min_area` | 1-1000 | Minimum object area |
+| `color_target` | Yellow/Red/etc | Target color for tracking |
+| `tinyArea` | 1-100 | Small element filtering threshold |
+| `isOnlyTop` | true/false | Consider only top objects |
+| `scanError` | 0-100 | Allowed search error (0=precise) |
- * [simpleIni](https://github.com/brofield/simpleini/blob/master/SimpleIni.h)
- * [serial](https://github.com/wjwwood/serial)
- * [GLFW](https://www.glfw.org/download.html)
- * [ImGui](https://github.com/ocornut/imgui)
+**💡 Use:** Accurate color-based target selection while ignoring noise
---
-## 2. Choose Build Target in Visual Studio
+### 🎯 Kalman Filter — Movement Prediction
-* **DML (DirectML):**
- Select `Release | x64 | DML` (works on any modern GPU)
-* **CUDA (TensorRT):**
- Select `Release | x64 | CUDA` (requires supported NVIDIA GPU, see above)
+Smoothing filter for target position prediction:
----
-
-## 3. Placement of Third-Party Modules and Libraries
-
-Before building the project, **download and place all third-party dependencies** in the following directories inside your project structure:
+| Parameter | Description |
+|-----------|-------------|
+| `kalman_process_noise` | Accounts for random movement changes |
+| `kalman_measurement_noise` | Accounts for sensor/camera errors |
+| `kalman_speed_multiplier_x/y` | Speed multiplier per axis |
+| `resetThreshold` | Filter reinitialization threshold |
-**Required folders inside your repository:**
+**💡 Result:** Smooth aiming without jitter
-```
-sunone_aimbot_cpp/
-└── sunone_aimbot_cpp/
- └── modules/
-```
-
-**Place each dependency as follows:**
+---
-| Library | Path |
-| --------- | ----------------------------------------------------------------- |
-| SimpleIni | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/SimpleIni.h` |
-| serial | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/serial/` |
-| TensorRT | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/TensorRT-10.8.0.43/` |
-| GLFW | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/glfw-3.4.bin.WIN64/` |
-| OpenCV | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/` |
-| cuDNN | `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/cudnn/` |
+## 🖥️ Interface & Controls
-* **SimpleIni:**
- Download [`SimpleIni.h`](https://github.com/brofield/simpleini/blob/master/SimpleIni.h)
- Place in `modules/`.
+### 🎨 ImGui Menu
-* **serial:**
- Download the [`serial`](https://github.com/wjwwood/serial) library (whole folder).
- To build, open
+**Menu interface features:**
- ```
- sunone_aimbot_cpp/sunone_aimbot_cpp/modules/serial/visual_studio/visual_studio.sln
- ```
+- 🧭 Vertical navbar with custom icons
+- 🖼️ Custom background via `ui_bg.png`
+- 🎨 Theming in `ui_theme.ini`
+- ⚙️ `Components` tab for runtime configuration
- * Set **C/C++ > Code Generation > Runtime Library** to **Multi-threaded (/MT)**
- * Build in **Release x64**
- * Use the built DLL/LIB with your project.
+#### 📸 Interface Screenshots
-* **TensorRT:**
- Download [TensorRT 10.8.0.43](https://developer.nvidia.com/tensorrt/download/10x)
- Place the folder as shown above.
+| Screen Capture | Target Status |
+|---|---|
+|  |  |
-* **GLFW:**
- Download [GLFW Windows binaries](https://www.glfw.org/download.html)
- Place the folder as shown above.
+#### 🎛️ Overlay Controls
-* **OpenCV:**
- Use your custom build or official DLLs (see CUDA/DML notes below).
- Place DLLs either next to your exe or in `modules/opencv/`.
+- **Overlay Opacity** — Transparency (slider or ±)
+- **UI Scale** — Interface scale (± or manual input)
+- **Window Width/Height** — Window size (manual input)
+- **Resize Handles** — Resize window from edges
-* **cuDNN:**
- Place cuDNN files here (for CUDA build):
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/cudnn/`
+### 🎮 Game Overlay — On-Screen Visualization
-**Example structure after setup:**
+Information displayed directly on desktop over games and apps:
-```
-sunone_aimbot_cpp/
-└── sunone_aimbot_cpp/
- └── modules/
- ├── SimpleIni.h
- ├── serial/
- ├── TensorRT-10.8.0.43/
- ├── glfw-3.4.bin.WIN64/
- ├── opencv/
- └── cudnn/
-```
+- 📊 **Stats** — FPS counter and latency info
+- 🎯 **Aim Simulator** — Aiming prediction visualization
+- 🔲 **Detection Boxes** — Detected target boxes
+- 🎨 **Class Colors** — Auto-coloring (class 0 = green)
+- 📝 **Text Size** — Adjustable in Components → Advanced
---
-## 4. How to Build OpenCV 4.10.0 with CUDA Support (For CUDA Version Only)
-
-> This section is **only required** if you want to use the CUDA (TensorRT) version and need OpenCV with CUDA support.
-> For DML build, skip this step — you can use the pre-built OpenCV DLL.
-
-**Step-by-step instructions:**
-
-1. **Download Sources**
-
- * [OpenCV 4.10.0](https://github.com/opencv/opencv/releases/tag/4.10.0)
- * [OpenCV Contrib 4.10.0](https://github.com/opencv/opencv_contrib/releases/tag/4.10.0)
- * [CMake](https://cmake.org/download/)
- * [CUDA Toolkit 12.8](https://developer.nvidia.com/cuda-12-8-0-download-archive)
- * [cuDNN 9.7.1](https://developer.nvidia.com/cudnn-downloads)
-
-2. **Prepare Directories**
-
- * Create:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/`
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build`
- * Extract `opencv-4.10.0` into
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/opencv-4.10.0`
- * Extract `opencv_contrib-4.10.0` into
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/opencv_contrib-4.10.0`
- * Extract cuDNN to
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/cudnn`
-
-3. **Configure with CMake**
-
- * Open CMake GUI
- * Source code:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/opencv-4.10.0`
- * Build directory:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build`
- * Click **Configure**
- (Choose "Visual Studio 17 2022", x64)
-
-4. **Enable CUDA Options**
-
- * After first configure, set the following:
-
- * `WITH_CUDA` = ON
- * `WITH_CUBLAS` = ON
- * `ENABLE_FAST_MATH` = ON
- * `CUDA_FAST_MATH` = ON
- * `WITH_CUDNN` = ON
- * `CUDNN_LIBRARY` =
- `full_path_to/sunone_aimbot_cpp/sunone_aimbot_cpp/modules/cudnn/lib/x64/cudnn.lib`
- * `CUDNN_INCLUDE_DIR` =
- `full_path_to/sunone_aimbot_cpp/sunone_aimbot_cpp/modules/cudnn/include`
- * `CUDA_ARCH_BIN` =
- See [CUDA Wikipedia](https://en.wikipedia.org/wiki/CUDA) for your GPU.
- Example for RTX 3080-Ti: `8.6`
- * `OPENCV_DNN_CUDA` = ON
- * `OPENCV_EXTRA_MODULES_PATH` =
- `full_path_to/sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/opencv_contrib-4.10.0/modules`
- * `BUILD_opencv_world` = ON
- * Uncheck:
-
- * `WITH_NVCUVENC`
- * `WITH_NVCUVID`
- * Click **Configure** again
- (make sure nothing is reset)
- * Click **Generate**
-
-5. **Build in Visual Studio**
-
- * Open `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build/OpenCV.sln`
- or click "Open Project" in CMake
- * Set build config: **x64 | Release**
- * Build `ALL_BUILD` target (can take up to 2 hours)
- * Then build `INSTALL` target
-
-6. **Copy Resulting DLLs**
-
- * DLLs:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build/install/x64/vc16/bin/`
- * LIBs:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build/install/x64/vc16/lib/`
- * Includes:
- `sunone_aimbot_cpp/sunone_aimbot_cpp/modules/opencv/build/install/include/opencv2`
- * Copy needed DLLs (`opencv_world4100.dll`, etc.) next to your project’s executable.
+## 🔧 Technical Details
----
+### 📁 File Structure
-## 5. Notes on OpenCV for CUDA/DML
+| File | Purpose |
+|------|---------|
+| **config.ini** | Main project configuration |
+| **ui_theme.ini** | UI colors, sizes, and parameters |
+| **ui_bg.png** | Menu background image (replaceable) |
+| **imgui.ini** | Window state (local, not committed) |
-* **For CUDA build (TensorRT backend):**
+### 📦 Core Modules
- * You **must** build OpenCV with CUDA support (see the guide above).
- * Place all built DLLs (e.g., `opencv_world4100.dll`) next to your executable or in the `modules` folder.
-* **For DML build (DirectML backend):**
+📹 **capture/** — Screen capture methods
+- DirectX Duplication API — `duplication_api_capture`
+- Windows Runtime capture — `winrt_capture`
+- [📖 OBS Capture](docs/obs/obs_en.md) — `obs_capture`
- * You can use the official pre-built OpenCV DLLs if you **only** plan to use DirectML.
- * If you want to use both CUDA and DML modes in the same executable, you should always use your custom OpenCV build with CUDA enabled (it will work for both modes).
-* **Note:**
- If you run the CUDA backend with non-CUDA OpenCV DLLs, the program will not work and may crash due to missing symbols.
+🧠 **detector/** — Target detection system
+- DirectML detector — `dml_detector`
+- TensorRT detector (NVIDIA) — `trt_detector`
+- Color-based detection — `color_detector`
----
+🎨 **overlay/** — Visual interface
+- ImGui implementation — `imgui_impl_*`
+- 2D/3D rendering — `rendering`
-## 6. Build and Run
+### ⚡ Input Methods
-1. Open the solution in Visual Studio 2022.
-2. Choose your configuration (`Release | x64 | DML` or `Release | x64 | CUDA`).
-3. Build the solution.
-4. Run `ai.exe` from the output folder.
+- **WIN32 API** — Built-in Windows APIs
+ ⚠️ **Warning:** Don't use in games (instant detection)
----
+- **Makcu/Kmbox/KmboxNet** — Specialized input devices
+ ✅ Recommended for games (low latency)
-## 🔄 Exporting AI Models
+---
-* Convert PyTorch `.pt` models to ONNX:
+## 📚 Links & Resources
- ```bash
- pip install ultralytics -U
- yolo export model=sunxds_0.5.6.pt format=onnx dynamic=true simplify=true
- ```
-* To convert `.onnx` to `.engine` for TensorRT, use the overlay export tab (open overlay with HOME).
+### 📖 Documentation
-## 📋 Configuration
+- 🔗 [TensorRT Docs](https://docs.nvidia.com/deeplearning/tensorrt/)
+- 🔗 [OpenCV Docs](https://docs.opencv.org/4.x/d1/dfb/intro.html)
+- 🔗 [CUDA 12.8](https://developer.nvidia.com/cuda-12-8-0-download-archive)
+- 🔗 [Config](docs\config_en.md)
-* See all configuration options and documentation here:
- [config\_cpp.md](https://github.com/SunOner/sunone_aimbot_docs/blob/main/config/config_cpp.md)
+### 🛠️ Libraries Used
----
+| Library | Purpose |
+|---------|---------|
+| [ImGui](https://github.com/ocornut/imgui) | User Interface |
+| [OpenCV](https://opencv.org/) | Computer Vision |
+| [TensorRT](https://developer.nvidia.com/tensorrt) | Neural network inference (NVIDIA) |
+| [DirectML](https://github.com/microsoft/DirectML) | GPU computing (universal) |
+| [CppWinRT](https://github.com/microsoft/cppwinrt) | Windows Runtime APIs |
+| [GLFW](https://www.glfw.org/) | Window management |
+| [nlohmann/JSON](https://github.com/nlohmann/json) | JSON processing |
-## 📚 References & Useful Links
+### 💡 Methods & Inspiration
-* [TensorRT Documentation](https://docs.nvidia.com/deeplearning/tensorrt/)
-* [OpenCV Documentation](https://docs.opencv.org/4.x/d1/dfb/intro.html)
-* [ImGui](https://github.com/ocornut/imgui)
-* [CppWinRT](https://github.com/microsoft/cppwinrt)
-* [GLFW](https://www.glfw.org/)
-* [WindMouse](https://ben.land/post/2021/04/25/windmouse-human-mouse-movement/)
-* [KMBOX](https://www.kmbox.top/)
-* [Python AI Version](https://github.com/SunOner/sunone_aimbot)
+- 🔗 [WindMouse Algorithm](https://ben.land/post/2021/04/25/windmouse-human-mouse-movement/) — Natural mouse movement
+- 🔗 [KMBOX](https://www.kmbox.top/) — Input device integration
+- 🐍 [RN_AI (Python version)](https://github.com/ReksarGames/RN_AI)
+- 🔀 [Original SunOne Aimbot](https://github.com/SunOner/sunone_aimbot_cpp) — RN_AI_cpp is a complete fork and rebuild
---
-## 📄 Licenses
-
-### OpenCV
+
-* **License:** [Apache License 2.0](https://opencv.org/license.html)
+**Made with ❤️ for the gaming community**
-### ImGui
-
-* **License:** [MIT License](https://github.com/ocornut/imgui/blob/master/LICENSE)
+
diff --git a/README_ru.md b/README_ru.md
new file mode 100644
index 00000000..2b10391e
--- /dev/null
+++ b/README_ru.md
@@ -0,0 +1,226 @@
+# 🎯 RN_AI_cpp — AI Aim Assistant
+
+
+
+
+
+
+
+
+
+[🚀 Быстрый старт](#-быстрый-старт) • [📚 Документация](#-технические-детали) * [English README](README.md)
+
+
+
+
+
+
+## ✨ Возможности
+
+| | |
+|---|---|
+| **🎯 AI Detection** | Детектирование целей через нейросети с высокой точностью |
+| **🎨 Color Detection** | Определение цели по цвету через фильтрацию |
+| **📈 Real-time Stats** | FPS счетчик и информация о задержке |
+| **🖱️ Aim Simulator** | Визуализация предсказания движения цели |
+| **🎛️ ClassTable** | Динамическое управление классами в реальном времени |
+| **🔄 Kalman Filter** | Сглаживание движения без дрожания прицела |
+| **⚡ Multiple Backends** | DirectML, CUDA+TensorRT, Color Detection |
+
+---
+
+## 🚀 Быстрый старт
+
+### 1️⃣ Выберите сборку
+
+
+🟢 DirectML (Универсальная)
+
+**Для:** Любые GPU (NVIDIA, AMD, Intel, встроенная видеокарта)
+
+```
+✅ Windows 10/11 (x64)
+✅ Без необходимости CUDA
+✅ Авто-рекомендуется для старых GPU
+```
+
+**Рекомендуется для:**
+- GTX 10xx/9xx/7xx серии
+- AMD Radeon GPU
+- Intel Iris/Xe GPU
+- Ноутбуки и офисные ПК
+
+
+
+
+🟡 CUDA + TensorRT (Максимальная производительность)
+
+**Для:** NVIDIA GPU последних поколений
+
+```
+✅ RTX 2000/3000/4000 и новее
+✅ GTX 1660
+✅ CUDA 12.8 + TensorRT 10.8 (встроено)
+❌ Не поддерживает GTX 10xx/Pascal и старше
+```
+
+**Возможности:**
+- Переключение между CUDA+TensorRT и DML в настройках
+- Максимальный FPS и точность
+- Professional-grade производительность
+
+
+
+---
+
+## ⚙️ Настройки и параметры
+
+### 📦 ClassTable — Управление классами
+
+Динамическое управление классами целей с возможностью:
+- ✅ Переключать/добавлять классы в реальном времени
+- ✅ Автодобавление найденных классов
+- ✅ Настройка позиции Y1/Y2 для каждого класса
+
+---
+
+### 🎨 Colorbot — Определение цвета
+
+Расширенная система цветовой фильтрации:
+
+| Параметр | Значение | Описание |
+|----------|---------|---------|
+| `color_erode_iter` | 0-5 | Кол-во итераций эрозии (уменьшает шум) |
+| `color_dilate_iter` | 0-5 | Кол-во итераций дилатации (восстанавливает размер) |
+| `color_min_area` | 1-1000 | Минимальная площадь объекта |
+| `color_target` | Yellow/Red/etc | Целевой цвет для отслеживания |
+| `tinyArea` | 1-100 | Порог фильтрации мелких элементов |
+| `isOnlyTop` | true/false | Учитывать только верхние объекты |
+| `scanError` | 0-100 | Допустимая ошибка при поиске (0=точно) |
+
+**💡 Применение:** Точное выделение целей по цвету с игнорированием шума
+
+---
+
+### 🎯 Kalman Filter — Предсказание движения
+
+Сглаживающий фильтр для предсказания позиции цели:
+
+| Параметр | Описание |
+|----------|---------|
+| `kalman_process_noise` | Учет случайных изменений движения |
+| `kalman_measurement_noise` | Учет ошибок датчика/камеры |
+| `kalman_speed_multiplier_x/y` | Множитель скорости по осям |
+| `resetThreshold` | Порог переинициализации фильтра |
+
+**💡 Результат:** Гладкое наведение без дрожания
+
+---
+
+## 🖥️ Интерфейс и управление
+
+### ImGui Menu
+
+**Интерфейс меню включает:**
+
+- 🧭 Вертикальная навбар с иконками
+- 🖼️ Кастомный фон через `ui_bg.png`
+- 🎨 Темизация в `ui_theme.ini`
+- ⚙️ Таб `Components` для runtime-настройки
+
+#### 📸 Скриншоты интерфейса
+
+| Захват экрана | Статус целей |
+|---|---|
+|  |  |
+
+#### 🎛️ Контролы оверлея
+
+- **Overlay Opacity** — Прозрачность (слайдер или ±)
+- **UI Scale** — Масштаб интерфейса (± или ручной ввод)
+- **Window Width/Height** — Размер окна (ручной ввод)
+- **Resize Handles** — Изменение окна за края
+
+### 🎮 Game Overlay — Визуализация на экране
+
+Информация выводится прямо на рабочий стол поверх игры:
+
+- 📊 **Stats** — FPS счетчик и информация о задержке
+- 🎯 **Aim Simulator** — Визуализация предсказания наводки
+- 🔲 **Detection Boxes** — Боксы обнаруженных целей
+- 🎨 **Class Colors** — Автоматическая раскраска (класс 0 = зеленый)
+- 📝 **Text Size** — Настройка размера в Components → Advanced
+
+---
+
+## 🔧 Технические детали
+
+### 📁 Структура файлов
+
+| Файл | Назначение |
+|------|-----------|
+| **config.ini** | Основная конфигурация проекта |
+| **ui_theme.ini** | Цвета, размеры и параметры UI |
+| **ui_bg.png** | Фоновое изображение меню (можно заменить) |
+| **imgui.ini** | Состояние окон (локальный, не коммитится) |
+
+### 📦 Основные модули
+
+📹 **capture/** — Методы захвата экрана
+- DirectX Duplication API — `duplication_api_capture`
+- Windows Runtime capture — `winrt_capture`
+- [📖 OBS Capture](docs/obs/obs_ru.md) — `obs_capture`
+
+🧠 **detector/** — Система детекции целей
+- DirectML detector — `dml_detector`
+- TensorRT detector (NVIDIA) — `trt_detector`
+- Color-based detection — `color_detector`
+
+🎨 **overlay/** — Визуальный интерфейс
+- ImGui implementation — `imgui_impl_*`
+- 2D/3D rendering — `rendering`
+
+### ⚡ Методы управления
+
+- **WIN32 API** — Встроенные API Windows
+ ⚠️ **Внимание:** Не используйте в играх (моментальный детект)
+
+- **Makcu/Kmbox/KmboxNet** — Специализированные устройства ввода
+ ✅ Рекомендуется для игр (низкая задержка)
+
+---
+
+## 📚 Ссылки и ресурсы
+
+### 📖 Документация
+
+- 🔗 [TensorRT Docs](https://docs.nvidia.com/deeplearning/tensorrt/)
+- 🔗 [OpenCV Docs](https://docs.opencv.org/4.x/d1/dfb/intro.html)
+- 🔗 [CUDA 12.8](https://developer.nvidia.com/cuda-12-8-0-download-archive)
+- 🔗 [Config](docs\config_ru.md)
+
+### 🛠️ Использованные библиотеки
+
+| Библиотека | Назначение |
+|-----------|-----------|
+| [ImGui](https://github.com/ocornut/imgui) | Пользовательский интерфейс |
+| [OpenCV](https://opencv.org/) | Компьютерное зрение |
+| [TensorRT](https://developer.nvidia.com/tensorrt) | Инференс нейросетей (NVIDIA) |
+| [DirectML](https://github.com/microsoft/DirectML) | GPU computing (универсально) |
+| [CppWinRT](https://github.com/microsoft/cppwinrt) | Windows Runtime APIs |
+| [GLFW](https://www.glfw.org/) | Управление окнами |
+| [nlohmann/JSON](https://github.com/nlohmann/json) | JSON обработка |
+
+### 💡 Методы и вдохновение
+
+- 🔗 [WindMouse Algorithm](https://ben.land/post/2021/04/25/windmouse-human-mouse-movement/) — Натуральное движение мыши
+- 🔗 [KMBOX](https://www.kmbox.top/) — Интеграция устройств ввода
+- 🐍 [RN_AI (Python версия)](https://github.com/ReksarGames/RN_AI)
+- 🔀 [Original SunOne Aimbot](https://github.com/SunOner/sunone_aimbot_cpp) — RN_AI_cpp полностью переделана на его основе
+
+---
+
+
+**Made with ❤️ for the gaming community**
+
+
diff --git a/sunone_aimbot_cpp.sln b/RN_AI_cpp.sln
similarity index 84%
rename from sunone_aimbot_cpp.sln
rename to RN_AI_cpp.sln
index dda446ec..b90fd1eb 100644
--- a/sunone_aimbot_cpp.sln
+++ b/RN_AI_cpp.sln
@@ -1,9 +1,9 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35825.156
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sunone_aimbot_cpp", "sunone_aimbot_cpp\sunone_aimbot_cpp.vcxproj", "{A27FFC6C-5EC3-43D3-BE46-9925B722B3C8}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RN_AI_cpp", "RN_AI_cpp\RN_AI_cpp.vcxproj", "{A27FFC6C-5EC3-43D3-BE46-9925B722B3C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -23,3 +23,5 @@ Global
SolutionGuid = {4EA9F6E2-D68A-4A8E-B8A2-C04AEB67F9B1}
EndGlobalSection
EndGlobal
+
+
diff --git a/RN_AI_cpp/.vscode/settings.json b/RN_AI_cpp/.vscode/settings.json
new file mode 100644
index 00000000..ea486f65
--- /dev/null
+++ b/RN_AI_cpp/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "translation.targetLanguage": "ru",
+ "translation.api": "google"
+}
\ No newline at end of file
diff --git a/sunone_aimbot_cpp/Package.appxmanifest b/RN_AI_cpp/Package.appxmanifest
similarity index 100%
rename from sunone_aimbot_cpp/Package.appxmanifest
rename to RN_AI_cpp/Package.appxmanifest
diff --git a/RN_AI_cpp/README.md b/RN_AI_cpp/README.md
new file mode 100644
index 00000000..85ef8cdb
--- /dev/null
+++ b/RN_AI_cpp/README.md
@@ -0,0 +1,53 @@
+# RN_AI_cpp
+
+Черновой README с фиксацией текущих кастомных изменений проекта.
+Позже можно структурировать и оформить финальную документацию.
+
+## Текущий статус изменений
+
+### UI/Меню (ImGui Overlay)
+- Левый вертикальный навбар с кастомными иконками и изменяемой шириной.
+- Поддержка фоновой картинки меню через `ui_bg.png`.
+- Темизация через `ui_theme.ini` (цвета, размеры, часть runtime-параметров).
+- Добавлен таб `Components` для runtime-настройки UI (дизайн-токены и advanced-параметры).
+- В `Overlay`:
+ - `Overlay Opacity`: `-` / слайдер / `+` (без ручного поля ввода).
+ - `UI Scale`: `-` / `+` / ручной ввод (без слайдера).
+ - `Window Width` и `Window Height` для ручного изменения размера окна.
+- Убраны лишние проблемные скроллы, которые конфликтовали с основным layout.
+
+### Resize окна
+- Реализованы resize-хэндлы:
+ - правый край,
+ - нижний край,
+ - правый нижний угол.
+- Размер окна также можно менять через контролы в `Overlay`.
+
+### Game Overlay
+- Добавлены элементы визуализации поверх игры:
+ - FPS counter,
+ - latency,
+ - детект-боксы.
+- Цвета боксов по классам:
+ - класс `0` всегда зеленый,
+ - остальным классам цвет назначается автоматически.
+- Добавлены настройки размеров текста FPS/latency (через `Components -> Advanced`).
+
+### Target/Mouse связанные правки
+- Расширены визуальные параметры для target-correction в game overlay.
+- Актуализированы UI-контролы для target/smart блоков (исправления layout и элементов управления).
+
+### Makcu/Kmbox интеграция
+- Подключена работа с `modules/makcu/include/makcu.h`.
+- Исправлены конфликты интеграции и сборки, из-за которых Makcu не подключался корректно.
+- Сохранена рабочая логика для текущего пайплайна управления мышью.
+
+## Важные файлы
+- `ui_theme.ini` — текущая тема/настройки визуала меню.
+- `ui_bg.png` — фон меню.
+- `config.ini` — runtime-конфиг проекта.
+
+## Технические заметки
+- `imgui.ini` обычно локальный файл состояния окон и, как правило, не должен храниться в репозитории.
+- `runtime_console.log` — локальный лог-файл, также обычно не коммитится.
+
diff --git a/sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj b/RN_AI_cpp/RN_AI_cpp.vcxproj
similarity index 87%
rename from sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj
rename to RN_AI_cpp/RN_AI_cpp.vcxproj
index 8f992f82..a7785e16 100644
--- a/sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj
+++ b/RN_AI_cpp/RN_AI_cpp.vcxproj
@@ -39,20 +39,31 @@
+
+
+
+
+
+
+
+
+
+
+
-
+
true
@@ -90,12 +101,22 @@
+
+
+
+
+
+
+
+
+
+
-
+
true
@@ -120,7 +141,7 @@
16.0
Win32Proj
{a27ffc6c-5ec3-43d3-be46-9925b722b3c8}
- sunoneaimbotcpp
+ rn_ai_cpp
10.0.26100.0
@@ -153,12 +174,14 @@
false
+ $(Platform)\$(Configuration)\$(MSBuildProjectName)\
$(MSBuildProjectDirectory)\modules\serial\include;$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\imgui;$(MSBuildProjectDirectory)\keyboard;$(MSBuildProjectDirectory)\config;$(MSBuildProjectDirectory)\tensorrt;$(MSBuildProjectDirectory)\detector;$(MSBuildProjectDirectory)\mouse;$(MSBuildProjectDirectory)\overlay;$(MSBuildProjectDirectory)\capture;$(MSBuildProjectDirectory)\modules\opencv\build\install\include;$(WindowsSDK_IncludePath);$(WindowsSDK_IncludePath)\cppwinrt;$(MSBuildProjectDirectory)\modules\TensorRT-10.8.0.43\include;include;$(ProgramW6432)\NVIDIA GPU Computing Toolkit\CUDA\v12.8\include;$(ProgramW6432)\NVIDIA\CUDNN\v9.7\include\12.8;$(IncludePath)
$(MSBuildProjectDirectory)\modules\serial\visual_studio\x64\Release;$(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\lib-vc2019;$(MSBuildProjectDirectory)\modules\opencv\build\install\x64\vc16\lib;$(MSBuildProjectDirectory)\modules\\TensorRT-10.8.0.43\lib;$(ProgramW6432)\NVIDIA GPU Computing Toolkit\CUDA\v12.8\lib\x64;$(ProgramW6432)\NVIDIA\CUDNN\v9.7\lib\12.8;$(LibraryPath)
ai
false
+ $(Platform)\$(Configuration)\$(MSBuildProjectName)\
$(MSBuildProjectDirectory)\modules\serial\include;$(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\imgui;$(MSBuildProjectDirectory)\keyboard;$(MSBuildProjectDirectory)\config;$(MSBuildProjectDirectory)\detector;$(MSBuildProjectDirectory)\mouse;$(MSBuildProjectDirectory)\overlay;$(MSBuildProjectDirectory)\capture;$(MSBuildProjectDirectory)\modules\opencv\build\install\include;$(WindowsSDK_IncludePath);$(WindowsSDK_IncludePath)\cppwinrt;include;$(IncludePath)
$(MSBuildProjectDirectory)\modules\serial\visual_studio\x64\Release;$(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\lib-vc2019;$(MSBuildProjectDirectory)\modules\opencv\build\install\x64\vc16\lib;$(LibraryPath)
ai
@@ -171,7 +194,7 @@
true
NDEBUG;_CONSOLE;USE_CUDA;%(PreprocessorDefinitions)
true
- $(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\include;$(MSBuildProjectDirectory)\modules\stb;$(MSBuildProjectDirectory)\modules\imgui-1.91.2\backends;$(MSBuildProjectDirectory)\modules\imgui-1.91.2;E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules\vcpkg-master\installed\x64-windows\include;<VCPKG_ROOT>\installed\x64-windows\include;%(AdditionalIncludeDirectories)
+ $(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\include;$(MSBuildProjectDirectory)\modules\stb;$(MSBuildProjectDirectory)\modules\imgui-1.91.2\backends;$(MSBuildProjectDirectory)\modules\imgui-1.91.2;$(MSBuildProjectDirectory)\modules\makcu\include;$(MSBuildProjectDirectory)\modules\vcpkg-master\installed\x64-windows\include;<VCPKG_ROOT>\installed\x64-windows\include;%(AdditionalIncludeDirectories)
MultiThreadedDLL
NotUsing
pch.h
@@ -183,7 +206,7 @@
true
true
opencv_world4100.lib;nvinfer_10.lib;nvonnxparser_10.lib;WindowsApp.lib;d3d11.lib;dxgi.lib;d2d1.lib;cuda.lib;cudart.lib;glfw3_mt.lib;glfw3dll.lib;serial.lib;%(AdditionalDependencies)
- E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules\opencv\build\install\include\opencv2;E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules\opencv\build\install\x64\vc17\lib;E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules\opencv\build\install\x64\vc17\bin;E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules\vcpkg-master\installed\x64-windows\lib;E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules;%(AdditionalLibraryDirectories)
+ $(MSBuildProjectDirectory)\modules\opencv\build\install\include\opencv2;$(MSBuildProjectDirectory)\modules\opencv\build\install\x64\vc17\lib;$(MSBuildProjectDirectory)\modules\opencv\build\install\x64\vc17\bin;$(MSBuildProjectDirectory)\modules\vcpkg-master\installed\x64-windows\lib;$(MSBuildProjectDirectory)\modules;%(AdditionalLibraryDirectories)
false
@@ -200,7 +223,7 @@
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\include;$(MSBuildProjectDirectory)\modules\stb;$(MSBuildProjectDirectory)\modules\imgui-1.91.2\backends;$(MSBuildProjectDirectory)\modules\imgui-1.91.2;%(AdditionalIncludeDirectories)
+ $(MSBuildProjectDirectory)\modules\glfw-3.4.bin.WIN64\include;$(MSBuildProjectDirectory)\modules\stb;$(MSBuildProjectDirectory)\modules\imgui-1.91.2\backends;$(MSBuildProjectDirectory)\modules\imgui-1.91.2;$(MSBuildProjectDirectory)\modules\makcu\include;%(AdditionalIncludeDirectories)
MultiThreadedDLL
NotUsing
@@ -213,7 +236,7 @@
true
true
opencv_world4100.lib;WindowsApp.lib;d3d11.lib;dxgi.lib;d2d1.lib;glfw3_mt.lib;glfw3dll.lib;serial.lib;%(AdditionalDependencies)
- E:\sunone_aimbot_cpp\sunone_aimbot_cpp\modules;%(AdditionalLibraryDirectories)
+ $(MSBuildProjectDirectory)\modules;%(AdditionalLibraryDirectories)
false
@@ -241,3 +264,7 @@
+
+
+
+
diff --git a/sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj.filters b/RN_AI_cpp/RN_AI_cpp.vcxproj.filters
similarity index 78%
rename from sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj.filters
rename to RN_AI_cpp/RN_AI_cpp.vcxproj.filters
index d15295fa..f4c40106 100644
--- a/sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj.filters
+++ b/RN_AI_cpp/RN_AI_cpp.vcxproj.filters
@@ -1,4 +1,4 @@
-
+
@@ -21,22 +21,33 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -72,8 +83,15 @@
-
+
+
+
+
+
+
+
+
@@ -84,6 +102,9 @@
+
+
+
diff --git a/sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj.user b/RN_AI_cpp/RN_AI_cpp.vcxproj.user
similarity index 100%
rename from sunone_aimbot_cpp/sunone_aimbot_cpp.vcxproj.user
rename to RN_AI_cpp/RN_AI_cpp.vcxproj.user
diff --git a/sunone_aimbot_cpp/capture/capture.cpp b/RN_AI_cpp/capture/capture.cpp
similarity index 85%
rename from sunone_aimbot_cpp/capture/capture.cpp
rename to RN_AI_cpp/capture/capture.cpp
index 82ce76ee..6935865f 100644
--- a/sunone_aimbot_cpp/capture/capture.cpp
+++ b/RN_AI_cpp/capture/capture.cpp
@@ -1,4 +1,4 @@
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include
#include
@@ -10,12 +10,13 @@
#include
#include
#include
+#include
#include "capture.h"
#ifdef USE_CUDA
#include "trt_detector.h"
#endif
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "keycodes.h"
#include "keyboard_listener.h"
#include "other_tools.h"
@@ -65,9 +66,9 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
std::cout << "[Capture] OpenCV version: " << CV_VERSION << std::endl;
IScreenCapture* capturer = nullptr;
- if (config.capture_method == "duplication_api")
+ if (config.capture_method == "duplication_api" || config.capture_method == "obs")
{
- capturer = new DuplicationAPIScreenCapture(CAPTURE_WIDTH, CAPTURE_HEIGHT);
+ capturer = new DuplicationAPIScreenCapture(CAPTURE_WIDTH, CAPTURE_HEIGHT, config.monitor_idx);
if (config.verbose)
std::cout << "[Capture] Using Duplication API" << std::endl;
}
@@ -91,7 +92,7 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
{
config.capture_method = "duplication_api";
config.saveConfig();
- capturer = new DuplicationAPIScreenCapture(CAPTURE_WIDTH, CAPTURE_HEIGHT);
+ capturer = new DuplicationAPIScreenCapture(CAPTURE_WIDTH, CAPTURE_HEIGHT, config.monitor_idx);
std::cout << "[Capture] Unknown capture_method. Set to duplication_api by default." << std::endl;
}
@@ -137,7 +138,8 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
if (detection_resolution_changed.load() ||
capture_method_changed.load() ||
capture_cursor_changed.load() ||
- capture_borders_changed.load())
+ capture_borders_changed.load() ||
+ capture_window_changed.load())
{
delete capturer;
capturer = nullptr;
@@ -145,9 +147,9 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
int newWidth = config.detection_resolution;
int newHeight = config.detection_resolution;
- if (config.capture_method == "duplication_api")
+ if (config.capture_method == "duplication_api" || config.capture_method == "obs")
{
- capturer = new DuplicationAPIScreenCapture(newWidth, newHeight);
+ capturer = new DuplicationAPIScreenCapture(newWidth, newHeight, config.monitor_idx);
if (config.verbose)
std::cout << "[Capture] Re-init with Duplication API." << std::endl;
}
@@ -170,7 +172,7 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
{
config.capture_method = "duplication_api";
config.saveConfig();
- capturer = new DuplicationAPIScreenCapture(newWidth, newHeight);
+ capturer = new DuplicationAPIScreenCapture(newWidth, newHeight, config.monitor_idx);
std::cout << "[Capture] Unknown capture_method. Set to duplication_api." << std::endl;
}
@@ -178,9 +180,36 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
capture_method_changed.store(false);
capture_cursor_changed.store(false);
capture_borders_changed.store(false);
+ capture_window_changed.store(false);
}
cv::Mat screenshotCpu;
+ bool frameSubmittedToDetector = false;
+
+#ifdef USE_CUDA
+ const bool preferGpuCapturePath =
+ config.backend == "TRT" &&
+ config.capture_method == "duplication_api" &&
+ config.capture_use_cuda &&
+ !config.circle_mask;
+ if (preferGpuCapturePath)
+ {
+ std::lock_guard lock(capturerMutex);
+ auto* duplicationCapture = dynamic_cast(capturer);
+ if (duplicationCapture)
+ {
+ cv::cuda::GpuMat gpuFrame;
+ if (duplicationCapture->GetNextFrameGpu(gpuFrame))
+ {
+ trt_detector.processFrameGpu(gpuFrame);
+ frameSubmittedToDetector = true;
+ gpuFrame.download(screenshotCpu);
+ }
+ }
+ }
+#endif
+
+ if (!frameSubmittedToDetector)
{
std::lock_guard lock(capturerMutex);
screenshotCpu = capturer->GetNextFrameCpu();
@@ -215,7 +244,7 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
dml_detector->processFrame(screenshotCpu);
}
#ifdef USE_CUDA
- else if (config.backend == "TRT")
+ else if (config.backend == "TRT" && !frameSubmittedToDetector)
{
trt_detector.processFrame(screenshotCpu);
}
@@ -288,4 +317,4 @@ void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT)
{
std::cerr << "[Capture] Unhandled exception: " << e.what() << std::endl;
}
-}
\ No newline at end of file
+}
diff --git a/sunone_aimbot_cpp/capture/capture.h b/RN_AI_cpp/capture/capture.h
similarity index 82%
rename from sunone_aimbot_cpp/capture/capture.h
rename to RN_AI_cpp/capture/capture.h
index 31696fe6..4ddc1581 100644
--- a/sunone_aimbot_cpp/capture/capture.h
+++ b/RN_AI_cpp/capture/capture.h
@@ -7,12 +7,16 @@
#include
#include
#include
+#ifdef USE_CUDA
+#include
+#endif
extern std::atomic detection_resolution_changed;
extern std::atomic capture_method_changed;
extern std::atomic capture_cursor_changed;
extern std::atomic capture_borders_changed;
extern std::atomic capture_fps_changed;
+extern std::atomic capture_window_changed;
extern std::deque frameQueue;
void captureThread(int CAPTURE_WIDTH, int CAPTURE_HEIGHT);
@@ -35,6 +39,9 @@ class IScreenCapture
public:
virtual ~IScreenCapture() {}
virtual cv::Mat GetNextFrameCpu() = 0;
+#ifdef USE_CUDA
+ virtual bool GetNextFrameGpu(cv::cuda::GpuMat&) { return false; }
+#endif
};
-#endif // CAPTURE_H
\ No newline at end of file
+#endif // CAPTURE_H
diff --git a/sunone_aimbot_cpp/capture/capture.zip b/RN_AI_cpp/capture/capture.zip
similarity index 100%
rename from sunone_aimbot_cpp/capture/capture.zip
rename to RN_AI_cpp/capture/capture.zip
diff --git a/sunone_aimbot_cpp/capture/capture_utils.cpp b/RN_AI_cpp/capture/capture_utils.cpp
similarity index 100%
rename from sunone_aimbot_cpp/capture/capture_utils.cpp
rename to RN_AI_cpp/capture/capture_utils.cpp
diff --git a/sunone_aimbot_cpp/capture/capture_utils.h b/RN_AI_cpp/capture/capture_utils.h
similarity index 100%
rename from sunone_aimbot_cpp/capture/capture_utils.h
rename to RN_AI_cpp/capture/capture_utils.h
diff --git a/sunone_aimbot_cpp/capture/duplication_api_capture.cpp b/RN_AI_cpp/capture/duplication_api_capture.cpp
similarity index 57%
rename from sunone_aimbot_cpp/capture/duplication_api_capture.cpp
rename to RN_AI_cpp/capture/duplication_api_capture.cpp
index 086c35cd..94d496b9 100644
--- a/sunone_aimbot_cpp/capture/duplication_api_capture.cpp
+++ b/RN_AI_cpp/capture/duplication_api_capture.cpp
@@ -1,12 +1,18 @@
#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
#define _WINSOCKAPI_
#include
#include
+#include
+#include
+
+#ifdef USE_CUDA
+#include
+#include
+#endif
#include "duplication_api_capture.h"
-#include "sunone_aimbot_cpp.h"
-#include "config.h"
-#include "other_tools.h"
+#include "rn_ai_cpp.h"
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
@@ -24,6 +30,7 @@ inline void SafeRelease(T** ppInterface)
struct FrameContext
{
ID3D11Texture2D* texture = nullptr;
+ bool hasAcquiredFrame = false;
};
class DDAManager
@@ -34,6 +41,7 @@ class DDAManager
, m_context(nullptr)
, m_duplication(nullptr)
, m_output1(nullptr)
+ , m_frameAcquired(false)
{
ZeroMemory(&m_duplDesc, sizeof(m_duplDesc));
}
@@ -164,12 +172,16 @@ class DDAManager
HRESULT AcquireFrame(FrameContext& frameCtx, UINT timeout = 100)
{
+ frameCtx.texture = nullptr;
+ frameCtx.hasAcquiredFrame = false;
if (!m_duplication) return E_FAIL;
DXGI_OUTDUPL_FRAME_INFO frameInfo{};
IDXGIResource* resource = nullptr;
HRESULT hr = m_duplication->AcquireNextFrame(timeout, &frameInfo, &resource);
if (FAILED(hr)) return hr;
+ frameCtx.hasAcquiredFrame = true;
+ m_frameAcquired = true;
if (resource)
{
@@ -181,15 +193,19 @@ class DDAManager
void ReleaseFrame()
{
- if (m_duplication)
+ if (!m_duplication || !m_frameAcquired)
+ return;
+ if (m_duplication) {
m_duplication->ReleaseFrame();
+ m_frameAcquired = false;
+ }
}
void Release()
{
if (m_duplication)
{
- m_duplication->ReleaseFrame();
+ ReleaseFrame();
m_duplication->Release();
m_duplication = nullptr;
}
@@ -204,9 +220,10 @@ class DDAManager
IDXGIOutputDuplication* m_duplication;
IDXGIOutput1* m_output1;
DXGI_OUTDUPL_DESC m_duplDesc;
+ bool m_frameAcquired;
};
-DuplicationAPIScreenCapture::DuplicationAPIScreenCapture(int desiredWidth, int desiredHeight)
+DuplicationAPIScreenCapture::DuplicationAPIScreenCapture(int desiredWidth, int desiredHeight, int monitorIndex)
: d3dDevice(nullptr)
, d3dContext(nullptr)
, deskDupl(nullptr)
@@ -221,7 +238,7 @@ DuplicationAPIScreenCapture::DuplicationAPIScreenCapture(int desiredWidth, int d
m_ddaManager = std::make_unique();
HRESULT hr = m_ddaManager->Initialize(
- config.monitor_idx,
+ monitorIndex,
regionWidth,
regionHeight,
screenWidth,
@@ -235,11 +252,20 @@ DuplicationAPIScreenCapture::DuplicationAPIScreenCapture(int desiredWidth, int d
return;
}
+ regionWidth = std::clamp(regionWidth, 1, std::max(1, screenWidth));
+ regionHeight = std::clamp(regionHeight, 1, std::max(1, screenHeight));
+
createStagingTextureCPU();
+#ifdef USE_CUDA
+ createCudaInteropTexture();
+#endif
}
DuplicationAPIScreenCapture::~DuplicationAPIScreenCapture()
{
+#ifdef USE_CUDA
+ releaseCudaInteropTexture();
+#endif
if (m_ddaManager)
{
m_ddaManager->Release();
@@ -267,32 +293,38 @@ cv::Mat DuplicationAPIScreenCapture::GetNextFrameCpu()
{
return cv::Mat();
}
- else if (hr == DXGI_ERROR_ACCESS_LOST || hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED)
+ else if (hr == DXGI_ERROR_ACCESS_LOST || hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_INVALID_CALL)
{
capture_method_changed.store(true);
- m_ddaManager->ReleaseFrame();
return cv::Mat();
}
else if (FAILED(hr))
{
std::cerr << "[DuplicationAPIScreenCapture] AcquireNextFrame (CPU) failed hr=0x"
<< std::hex << hr << std::endl;
- m_ddaManager->ReleaseFrame();
+ if (frameCtx.hasAcquiredFrame)
+ m_ddaManager->ReleaseFrame();
return cv::Mat();
}
if (!frameCtx.texture)
{
- m_ddaManager->ReleaseFrame();
+ if (frameCtx.hasAcquiredFrame)
+ m_ddaManager->ReleaseFrame();
return cv::Mat();
}
+ const int copyWidth = std::min(regionWidth, std::max(1, screenWidth));
+ const int copyHeight = std::min(regionHeight, std::max(1, screenHeight));
+ const int left = std::max(0, (screenWidth - copyWidth) / 2);
+ const int top = std::max(0, (screenHeight - copyHeight) / 2);
+
D3D11_BOX sourceRegion;
- sourceRegion.left = (screenWidth - regionWidth) / 2;
- sourceRegion.top = (screenHeight - regionHeight) / 2;
+ sourceRegion.left = left;
+ sourceRegion.top = top;
sourceRegion.front = 0;
- sourceRegion.right = sourceRegion.left + regionWidth;
- sourceRegion.bottom = sourceRegion.top + regionHeight;
+ sourceRegion.right = sourceRegion.left + copyWidth;
+ sourceRegion.bottom = sourceRegion.top + copyHeight;
sourceRegion.back = 1;
d3dContext->CopySubresourceRegion(
@@ -312,6 +344,8 @@ cv::Mat DuplicationAPIScreenCapture::GetNextFrameCpu()
if (FAILED(hrMap))
{
std::cerr << "[DDA] Map stagingTextureCPU failed hr=" << std::hex << hrMap << std::endl;
+ if (hrMap == DXGI_ERROR_DEVICE_REMOVED || hrMap == DXGI_ERROR_DEVICE_RESET)
+ capture_method_changed.store(true);
return cv::Mat();
}
@@ -327,9 +361,156 @@ cv::Mat DuplicationAPIScreenCapture::GetNextFrameCpu()
return cpuFrame;
}
+#ifdef USE_CUDA
+bool DuplicationAPIScreenCapture::GetNextFrameGpu(cv::cuda::GpuMat& gpuFrameBgra)
+{
+ if (!m_ddaManager || !m_ddaManager->m_duplication || !interopTextureGPU || !cudaInteropResource || !cudaInteropReady)
+ return false;
+
+ FrameContext frameCtx;
+ HRESULT hr = m_ddaManager->AcquireFrame(frameCtx, 5);
+ if (hr == DXGI_ERROR_WAIT_TIMEOUT)
+ return false;
+ if (hr == DXGI_ERROR_ACCESS_LOST || hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_INVALID_CALL)
+ {
+ capture_method_changed.store(true);
+ return false;
+ }
+ if (FAILED(hr))
+ {
+ std::cerr << "[DuplicationAPIScreenCapture] AcquireNextFrame (GPU) failed hr=0x" << std::hex << hr << std::endl;
+ if (frameCtx.hasAcquiredFrame)
+ m_ddaManager->ReleaseFrame();
+ return false;
+ }
+ if (!frameCtx.texture)
+ {
+ if (frameCtx.hasAcquiredFrame)
+ m_ddaManager->ReleaseFrame();
+ return false;
+ }
+
+ const int copyWidth = std::min(regionWidth, std::max(1, screenWidth));
+ const int copyHeight = std::min(regionHeight, std::max(1, screenHeight));
+ const int left = std::max(0, (screenWidth - copyWidth) / 2);
+ const int top = std::max(0, (screenHeight - copyHeight) / 2);
+
+ D3D11_BOX sourceRegion{};
+ sourceRegion.left = left;
+ sourceRegion.top = top;
+ sourceRegion.front = 0;
+ sourceRegion.right = left + copyWidth;
+ sourceRegion.bottom = top + copyHeight;
+ sourceRegion.back = 1;
+
+ d3dContext->CopySubresourceRegion(interopTextureGPU, 0, 0, 0, 0, frameCtx.texture, 0, &sourceRegion);
+ m_ddaManager->ReleaseFrame();
+ frameCtx.texture->Release();
+
+ cudaError_t cuErr = cudaGraphicsMapResources(1, &cudaInteropResource, 0);
+ if (cuErr != cudaSuccess)
+ {
+ std::cerr << "[DDA] cudaGraphicsMapResources failed: " << cudaGetErrorString(cuErr) << std::endl;
+ cudaInteropReady = false;
+ return false;
+ }
+
+ cudaArray_t mappedArray = nullptr;
+ cuErr = cudaGraphicsSubResourceGetMappedArray(&mappedArray, cudaInteropResource, 0, 0);
+ if (cuErr != cudaSuccess)
+ {
+ std::cerr << "[DDA] cudaGraphicsSubResourceGetMappedArray failed: " << cudaGetErrorString(cuErr) << std::endl;
+ cudaGraphicsUnmapResources(1, &cudaInteropResource, 0);
+ cudaInteropReady = false;
+ return false;
+ }
+
+ gpuFrameBgra.create(regionHeight, regionWidth, CV_8UC4);
+ cuErr = cudaMemcpy2DFromArray(
+ gpuFrameBgra.ptr(),
+ gpuFrameBgra.step,
+ mappedArray,
+ 0,
+ 0,
+ static_cast(regionWidth) * 4,
+ static_cast(regionHeight),
+ cudaMemcpyDeviceToDevice);
+
+ cudaError_t unmapErr = cudaGraphicsUnmapResources(1, &cudaInteropResource, 0);
+ if (unmapErr != cudaSuccess)
+ {
+ std::cerr << "[DDA] cudaGraphicsUnmapResources failed: " << cudaGetErrorString(unmapErr) << std::endl;
+ cudaInteropReady = false;
+ }
+
+ if (cuErr != cudaSuccess)
+ {
+ std::cerr << "[DDA] cudaMemcpy2DFromArray failed: " << cudaGetErrorString(cuErr) << std::endl;
+ cudaInteropReady = false;
+ return false;
+ }
+
+ return true;
+}
+
+bool DuplicationAPIScreenCapture::createCudaInteropTexture()
+{
+ if (!d3dDevice)
+ return false;
+
+ releaseCudaInteropTexture();
+
+ D3D11_TEXTURE2D_DESC desc{};
+ desc.Width = regionWidth;
+ desc.Height = regionHeight;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT hr = d3dDevice->CreateTexture2D(&desc, nullptr, &interopTextureGPU);
+ if (FAILED(hr))
+ {
+ std::cerr << "[DDA] CreateTexture2D(interop) failed hr=" << std::hex << hr << std::endl;
+ return false;
+ }
+
+ cudaError_t cuErr = cudaGraphicsD3D11RegisterResource(&cudaInteropResource, interopTextureGPU, cudaGraphicsRegisterFlagsNone);
+ if (cuErr != cudaSuccess)
+ {
+ std::cerr << "[DDA] cudaGraphicsD3D11RegisterResource failed: " << cudaGetErrorString(cuErr) << std::endl;
+ SafeRelease(&interopTextureGPU);
+ cudaInteropResource = nullptr;
+ cudaInteropReady = false;
+ return false;
+ }
+
+ cudaInteropReady = true;
+ return true;
+}
+
+void DuplicationAPIScreenCapture::releaseCudaInteropTexture()
+{
+ if (cudaInteropResource)
+ {
+ cudaError_t cuErr = cudaGraphicsUnregisterResource(cudaInteropResource);
+ if (cuErr != cudaSuccess)
+ std::cerr << "[DDA] cudaGraphicsUnregisterResource failed: " << cudaGetErrorString(cuErr) << std::endl;
+ cudaInteropResource = nullptr;
+ }
+ SafeRelease(&interopTextureGPU);
+ cudaInteropReady = false;
+}
+#endif
+
bool DuplicationAPIScreenCapture::createStagingTextureCPU()
{
if (!d3dDevice) return false;
+ SafeRelease(&stagingTextureCPU);
D3D11_TEXTURE2D_DESC desc{};
desc.Width = regionWidth;
@@ -350,4 +531,4 @@ bool DuplicationAPIScreenCapture::createStagingTextureCPU()
return false;
}
return true;
-}
\ No newline at end of file
+}
diff --git a/sunone_aimbot_cpp/capture/duplication_api_capture.h b/RN_AI_cpp/capture/duplication_api_capture.h
similarity index 65%
rename from sunone_aimbot_cpp/capture/duplication_api_capture.h
rename to RN_AI_cpp/capture/duplication_api_capture.h
index 7e1aa16d..7c9d2741 100644
--- a/sunone_aimbot_cpp/capture/duplication_api_capture.h
+++ b/RN_AI_cpp/capture/duplication_api_capture.h
@@ -5,6 +5,11 @@
#include
#include
#include
+#ifdef USE_CUDA
+#include
+#include
+struct cudaGraphicsResource;
+#endif
#include "capture.h"
@@ -13,10 +18,13 @@ class DDAManager;
class DuplicationAPIScreenCapture : public IScreenCapture
{
public:
- DuplicationAPIScreenCapture(int desiredWidth, int desiredHeight);
+ DuplicationAPIScreenCapture(int desiredWidth, int desiredHeight, int monitorIndex);
~DuplicationAPIScreenCapture();
cv::Mat GetNextFrameCpu() override;
+#ifdef USE_CUDA
+ bool GetNextFrameGpu(cv::cuda::GpuMat& gpuFrameBgra) override;
+#endif
private:
std::unique_ptr m_ddaManager;
@@ -29,6 +37,11 @@ class DuplicationAPIScreenCapture : public IScreenCapture
ID3D11Texture2D* sharedTexture = nullptr;
ID3D11Texture2D* stagingTextureCPU = nullptr;
+#ifdef USE_CUDA
+ ID3D11Texture2D* interopTextureGPU = nullptr;
+ cudaGraphicsResource* cudaInteropResource = nullptr;
+ bool cudaInteropReady = false;
+#endif
int screenWidth = 0;
int screenHeight = 0;
@@ -36,6 +49,10 @@ class DuplicationAPIScreenCapture : public IScreenCapture
int regionHeight = 0;
bool createStagingTextureCPU();
+#ifdef USE_CUDA
+ bool createCudaInteropTexture();
+ void releaseCudaInteropTexture();
+#endif
};
#endif // DUPLICATION_API_CAPTURE_H
diff --git a/sunone_aimbot_cpp/capture/udp_capture.cpp b/RN_AI_cpp/capture/udp_capture.cpp
similarity index 100%
rename from sunone_aimbot_cpp/capture/udp_capture.cpp
rename to RN_AI_cpp/capture/udp_capture.cpp
diff --git a/sunone_aimbot_cpp/capture/udp_capture.h b/RN_AI_cpp/capture/udp_capture.h
similarity index 100%
rename from sunone_aimbot_cpp/capture/udp_capture.h
rename to RN_AI_cpp/capture/udp_capture.h
diff --git a/sunone_aimbot_cpp/capture/virtual_camera.cpp b/RN_AI_cpp/capture/virtual_camera.cpp
similarity index 100%
rename from sunone_aimbot_cpp/capture/virtual_camera.cpp
rename to RN_AI_cpp/capture/virtual_camera.cpp
diff --git a/sunone_aimbot_cpp/capture/virtual_camera.h b/RN_AI_cpp/capture/virtual_camera.h
similarity index 100%
rename from sunone_aimbot_cpp/capture/virtual_camera.h
rename to RN_AI_cpp/capture/virtual_camera.h
diff --git a/sunone_aimbot_cpp/capture/winrt_capture.cpp b/RN_AI_cpp/capture/winrt_capture.cpp
similarity index 99%
rename from sunone_aimbot_cpp/capture/winrt_capture.cpp
rename to RN_AI_cpp/capture/winrt_capture.cpp
index 19f15610..b895c0d2 100644
--- a/sunone_aimbot_cpp/capture/winrt_capture.cpp
+++ b/RN_AI_cpp/capture/winrt_capture.cpp
@@ -4,7 +4,7 @@
#include
#include "winrt_capture.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "config.h"
#include "other_tools.h"
diff --git a/sunone_aimbot_cpp/capture/winrt_capture.h b/RN_AI_cpp/capture/winrt_capture.h
similarity index 100%
rename from sunone_aimbot_cpp/capture/winrt_capture.h
rename to RN_AI_cpp/capture/winrt_capture.h
diff --git a/RN_AI_cpp/config.ini b/RN_AI_cpp/config.ini
new file mode 100644
index 00000000..7b8a7ca6
--- /dev/null
+++ b/RN_AI_cpp/config.ini
@@ -0,0 +1,232 @@
+# An explanation of the options can be found at:
+# https://github.com/RN-AI/RN_AI_cpp
+
+# Capture
+capture_method = duplication_api
+detection_resolution = 640
+capture_fps = 400
+monitor_idx = 0
+circle_mask = false
+capture_borders = true
+capture_cursor = true
+virtual_camera_name = None
+virtual_camera_width = 1920
+virtual_camera_heigth = 1080
+
+# Target
+disable_headshot = false
+body_y_offset = 0.15
+head_y_offset = 0.05
+ignore_third_person = false
+shooting_range_targets = false
+focusTarget = false
+auto_aim = false
+target_lock_enabled = true
+target_lock_distance = 40.0
+target_lock_reacquire_time = 0.10
+smart_target_lock = true
+target_reference_class = 0
+target_lock_fallback_class = -1
+target_switch_delay = 54
+aim_bot_scope = 226.3
+aim_bot_position = 0.50
+aim_bot_position2 = 0.50
+allowed_classes = 0-7
+class_priority_order =
+distance_scoring_weight = 1.00
+center_scoring_weight = 1.00
+size_scoring_weight = 1.00
+aim_weight_tiebreak_ratio = 0.10
+small_target_enhancement_enabled = false
+small_target_boost_factor = 0.10
+small_target_threshold = 0.02
+small_target_medium_threshold = 0.05
+small_target_medium_boost = 1.50
+small_target_smooth_enabled = true
+small_target_smooth_frames = 2
+
+# Mouse move
+fovX = 106
+fovY = 74
+minSpeedMultiplier = 0.50
+maxSpeedMultiplier = 0.70
+smoothness = 1
+use_smoothing = true
+tracking_smoothing = true
+use_kalman = false
+
+kalman_process_noise = 0.98
+kalman_measurement_noise = 0.40
+kalman_speed_multiplier_x = 1.00
+kalman_speed_multiplier_y = 1.00
+resetThreshold = 5.00
+
+predictionInterval = 0.01
+prediction_mode = 0
+prediction_kalman_lead_ms = 0.00
+prediction_kalman_max_lead_ms = 0.00
+prediction_velocity_smoothing = 0.40
+prediction_velocity_scale = 1.00
+prediction_kalman_process_noise = 0.01
+prediction_kalman_measurement_noise = 0.10
+prediction_use_future_for_aim = false
+prediction_futurePositions = 20
+draw_futurePositions = true
+camera_compensation_enabled = false
+camera_compensation_max_shift = 50.00
+camera_compensation_strength = 1.00
+snapRadius = 1.50
+nearRadius = 24.00
+speedCurveExponent = 3.00
+snapBoostFactor = 1.15
+easynorecoil = false
+easynorecoilstrength = 0.0
+# WIN32, ARDUINO, MAKCU, KMBOX_B, KMBOX_NET
+input_method = WIN32
+
+# Wind mouse
+wind_mouse_enabled = false
+wind_G = 18.0
+wind_W = 15.0
+wind_M = 10.0
+wind_D = 8.0
+
+# Makcu
+makcu_baudrate = 4000000
+makcu_port = COM14
+
+# Kmbox_B
+kmbox_baudrate = 115200
+kmbox_port = COM0
+
+# Mouse shooting
+auto_shoot = false
+triggerbot = true
+triggerbot_reaction_ms = 0
+triggerbot_interval = 0.00
+bScope_multiplier = 1.0
+triggerbot_bScope_multiplier = 1.0
+
+# AI
+backend = TRT
+dml_device_id = 0
+ai_model = sunxds_0.5.6.engine
+confidence_threshold = 0.10
+nms_threshold = 0.50
+adaptive_nms = true
+max_detections = 0
+postprocess = yolo10
+batch_size = 8
+export_enable_fp8 = false
+export_enable_fp16 = true
+fixed_input_size = false
+
+# CUDA
+use_cuda_graph = false
+use_pinned_memory = false
+capture_use_cuda = true
+
+# Buttons
+button_targeting = RightMouseButton
+button_shoot = LeftMouseButton
+button_triggerbot = X2MouseButton
+button_disable_headshot = M
+button_exit = F2
+button_pause = F3
+button_reload_config = F4
+button_open_overlay = Home
+enable_arrows_settings = false
+
+# Overlay
+overlay_opacity = 255
+overlay_snow_theme = true
+overlay_ui_scale = 2.13
+game_overlay_enabled = false
+game_overlay_max_fps = 57
+game_overlay_draw_boxes = true
+game_overlay_draw_future = true
+game_overlay_draw_wind_tail = true
+game_overlay_draw_frame = true
+game_overlay_show_target_correction = true
+game_overlay_show_fps_counter = true
+game_overlay_show_latency = true
+game_overlay_box_a = 255
+game_overlay_box_r = 0
+game_overlay_box_g = 255
+game_overlay_box_b = 0
+game_overlay_frame_a = 180
+game_overlay_frame_r = 255
+game_overlay_frame_g = 255
+game_overlay_frame_b = 255
+game_overlay_box_thickness = 4.70
+game_overlay_frame_thickness = 2.50
+game_overlay_future_point_radius = 5.00
+game_overlay_future_alpha_falloff = 1.00
+game_overlay_icon_enabled = true
+game_overlay_icon_path = icon.png
+game_overlay_icon_width = 64
+game_overlay_icon_height = 64
+game_overlay_icon_offset_x = 0.00
+game_overlay_icon_offset_y = 0.00
+game_overlay_icon_anchor = center
+game_overlay_icon_class = -1
+aim_sim_enabled = true
+aim_sim_x = 24
+aim_sim_y = 24
+aim_sim_width = 560
+aim_sim_height = 360
+aim_sim_fps_min = 90
+aim_sim_fps_max = 120
+aim_sim_fps_jitter = 0.15
+aim_sim_capture_delay_ms = 8.62
+aim_sim_inference_delay_ms = 2.40
+aim_sim_use_live_inference = true
+aim_sim_input_delay_ms = 2.00
+aim_sim_extra_delay_ms = 0.73
+aim_sim_target_max_speed = 560.00
+aim_sim_target_accel = 1850.00
+aim_sim_target_stop_chance = 0.25
+aim_sim_show_observed = true
+aim_sim_show_history = true
+
+# OBS
+is_obs = false
+obs_ip = 0.0.0.0
+obs_port = 4455
+obs_fps = 240
+
+# Color detection
+color_erode_iter = 1
+color_dilate_iter = 2
+color_min_area = 50
+color_target = Yellow
+tinyArea = 2
+isOnlyTop = 1
+scanError = 0.10
+
+# Debug
+show_window = true
+show_fps = false
+screenshot_button = None
+screenshot_delay = 500
+verbose = true
+
+# Active game profile
+active_game = dwa
+
+[Colors]
+Purple = 220,100,195,255,195,255
+Yellow = 30,125,150,30,255,255
+Yellow2 = 20,100,120,35,255,255
+
+[Games]
+dwa = 10.00,0.02,0.02
+UNIFIED = 1.00,0.02,0.02
+
+[ClassAim]
+0 = 0.10,0.10
+
+[ClassNames]
+0 = class_player
+7 = class_head
+
diff --git a/sunone_aimbot_cpp/config/config.cpp b/RN_AI_cpp/config/config.cpp
similarity index 50%
rename from sunone_aimbot_cpp/config/config.cpp
rename to RN_AI_cpp/config/config.cpp
index 7237bb96..a03fb7ec 100644
--- a/sunone_aimbot_cpp/config/config.cpp
+++ b/RN_AI_cpp/config/config.cpp
@@ -1,4 +1,4 @@
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define _WINSOCKAPI_
#include
#include
@@ -8,6 +8,8 @@
#include
#include
#include
+#include
+#include
#include "config.h"
#include "modules/SimpleIni.h"
@@ -69,6 +71,28 @@ bool Config::loadConfig(const std::string& filename)
target_lock_enabled = false;
target_lock_distance = 100.0f;
target_lock_reacquire_time = 0.30f;
+ smart_target_lock = true;
+ target_reference_class = 0;
+ target_lock_fallback_class = -1;
+ target_switch_delay = 0;
+ aim_bot_scope = 160.0f;
+ aim_bot_position = 0.5f;
+ aim_bot_position2 = 0.5f;
+ allowed_classes = "";
+ class_priority_order = "";
+ distance_scoring_weight = 1.0f;
+ center_scoring_weight = 1.0f;
+ size_scoring_weight = 1.0f;
+ aim_weight_tiebreak_ratio = 0.1f;
+ small_target_enhancement_enabled = true;
+ small_target_boost_factor = 0.1f;
+ small_target_threshold = 0.02f;
+ small_target_medium_threshold = 0.05f;
+ small_target_medium_boost = 1.5f;
+ small_target_smooth_enabled = true;
+ small_target_smooth_frames = 2;
+ class_aim_positions.clear();
+ custom_class_names.clear();
// Mouse
fovX = 106;
@@ -78,6 +102,7 @@ bool Config::loadConfig(const std::string& filename)
smoothness = 100;
use_smoothing = true;
+ tracking_smoothing = false;
use_kalman = false;
kalman_process_noise = 0.01f;
@@ -87,9 +112,21 @@ bool Config::loadConfig(const std::string& filename)
resetThreshold = 5;
predictionInterval = 0.01f;
+ prediction_mode = 0;
+ prediction_kalman_lead_ms = 0.0f;
+ prediction_kalman_max_lead_ms = 0.0f;
+ prediction_velocity_smoothing = 0.4f;
+ prediction_velocity_scale = 1.0f;
+ prediction_kalman_process_noise = 0.01f;
+ prediction_kalman_measurement_noise = 0.10f;
+ prediction_use_future_for_aim = false;
prediction_futurePositions = 20;
draw_futurePositions = true;
+ camera_compensation_enabled = false;
+ camera_compensation_max_shift = 50.0f;
+ camera_compensation_strength = 1.0f;
+
snapRadius = 1.5f;
nearRadius = 25.0f;
speedCurveExponent = 3.0f;
@@ -105,6 +142,9 @@ bool Config::loadConfig(const std::string& filename)
wind_W = 15.0f;
wind_M = 10.0f;
wind_D = 8.0f;
+ // Makcu
+ makcu_baudrate = 4000000;
+ makcu_port = "COM1";
// kmbox_B
kmbox_b_baudrate = 115200;
@@ -113,9 +153,7 @@ bool Config::loadConfig(const std::string& filename)
// Mouse shooting
auto_shoot = false;
triggerbot = false;
- triggerbot_interval = 0.0;
- triggerbot_predict_ms = 0.0;
- triggerbot_predict_alpha = 0.5;
+ triggerbot_reaction_ms = 0;
bScope_multiplier = 1.0f;
triggerbot_bScope_multiplier = 1.0f;
@@ -150,6 +188,7 @@ bool Config::loadConfig(const std::string& filename)
#ifdef USE_CUDA
use_cuda_graph = false;
use_pinned_memory = false;
+ capture_use_cuda = true;
#endif
// Buttons
@@ -167,6 +206,59 @@ bool Config::loadConfig(const std::string& filename)
overlay_opacity = 225;
overlay_snow_theme = true;
overlay_ui_scale = 1.0f;
+ game_overlay_enabled = false;
+ game_overlay_max_fps = 0;
+ game_overlay_draw_boxes = true;
+ game_overlay_draw_future = true;
+ game_overlay_draw_wind_tail = true;
+ game_overlay_draw_frame = true;
+ game_overlay_show_target_correction = true;
+ game_overlay_show_fps_counter = true;
+ game_overlay_show_latency = true;
+ game_overlay_box_a = 255;
+ game_overlay_box_r = 0;
+ game_overlay_box_g = 255;
+ game_overlay_box_b = 0;
+ game_overlay_frame_a = 180;
+ game_overlay_frame_r = 255;
+ game_overlay_frame_g = 255;
+ game_overlay_frame_b = 255;
+ game_overlay_box_thickness = 2.0f;
+ game_overlay_frame_thickness = 1.5f;
+ game_overlay_future_point_radius = 5.0f;
+ game_overlay_future_alpha_falloff = 1.0f;
+ game_overlay_icon_enabled = false;
+ game_overlay_icon_path = "icon.png";
+ game_overlay_icon_width = 64;
+ game_overlay_icon_height = 64;
+ game_overlay_icon_offset_x = 0.0f;
+ game_overlay_icon_offset_y = 0.0f;
+ game_overlay_icon_anchor = "center";
+ game_overlay_icon_class = -1;
+ aim_sim_enabled = false;
+ aim_sim_x = 24;
+ aim_sim_y = 24;
+ aim_sim_width = 560;
+ aim_sim_height = 360;
+ aim_sim_fps_min = 90;
+ aim_sim_fps_max = 120;
+ aim_sim_fps_jitter = 0.15f;
+ aim_sim_capture_delay_ms = 6.0f;
+ aim_sim_inference_delay_ms = 12.0f;
+ aim_sim_use_live_inference = true;
+ aim_sim_input_delay_ms = 2.0f;
+ aim_sim_extra_delay_ms = 2.0f;
+ aim_sim_target_max_speed = 560.0f;
+ aim_sim_target_accel = 1850.0f;
+ aim_sim_target_stop_chance = 0.25f;
+ aim_sim_show_observed = true;
+ aim_sim_show_history = true;
+
+ // OBS
+ is_obs = false;
+ obs_ip = "0.0.0.0";
+ obs_port = 4455;
+ obs_fps = 240;
// Custom classes
class_player = 0;
@@ -189,7 +281,7 @@ bool Config::loadConfig(const std::string& filename)
isOnlyTop = true;
scanError = 0.1f;
- // Заполняем дефолтные диапазоны HSV
+ // ????????? ????????? ????????? HSV
color_ranges.clear();
// Yellow
@@ -215,6 +307,7 @@ bool Config::loadConfig(const std::string& filename)
// Debug
show_window = true;
+ show_fps = false;
screenshot_button = splitString("None");
screenshot_delay = 500;
verbose = false;
@@ -232,25 +325,56 @@ bool Config::loadConfig(const std::string& filename)
return false;
}
+ auto get_raw_value_compat = [&](const char* key) -> const char*
+ {
+ const char* val = ini.GetValue("", key, nullptr);
+ if (val == nullptr)
+ val = ini.GetValue("ClassNames", key, nullptr);
+ if (val == nullptr)
+ val = ini.GetValue("Colors", key, nullptr);
+ return val;
+ };
+
auto get_string = [&](const char* key, const std::string& defval)
{
- const char* val = ini.GetValue("", key, defval.c_str());
+ const char* val = get_raw_value_compat(key);
return val ? std::string(val) : defval;
};
auto get_bool = [&](const char* key, bool defval)
{
- return ini.GetBoolValue("", key, defval);
+ std::string value = get_string(key, defval ? "true" : "false");
+ std::transform(value.begin(), value.end(), value.begin(),
+ [](unsigned char c) { return static_cast(std::tolower(c)); });
+ if (value == "1" || value == "true" || value == "yes" || value == "on")
+ return true;
+ if (value == "0" || value == "false" || value == "no" || value == "off")
+ return false;
+ return defval;
};
auto get_long = [&](const char* key, long defval)
{
- return (int)ini.GetLongValue("", key, defval);
+ try
+ {
+ return static_cast(std::stol(get_string(key, std::to_string(defval))));
+ }
+ catch (...)
+ {
+ return static_cast(defval);
+ }
};
auto get_double = [&](const char* key, double defval)
{
- return ini.GetDoubleValue("", key, defval);
+ try
+ {
+ return std::stod(get_string(key, std::to_string(defval)));
+ }
+ catch (...)
+ {
+ return defval;
+ }
};
game_profiles.clear();
@@ -328,6 +452,75 @@ bool Config::loadConfig(const std::string& filename)
target_lock_enabled = get_bool("target_lock_enabled", false);
target_lock_distance = static_cast(get_double("target_lock_distance", 100.0));
target_lock_reacquire_time = static_cast(get_double("target_lock_reacquire_time", 0.30));
+ smart_target_lock = get_bool("smart_target_lock", true);
+ target_reference_class = get_long("target_reference_class", 0);
+ target_lock_fallback_class = get_long("target_lock_fallback_class", -1);
+ target_switch_delay = get_long("target_switch_delay", 0);
+ aim_bot_scope = static_cast(get_double("aim_bot_scope", 160.0));
+ if (aim_bot_scope < 0.0f)
+ aim_bot_scope = 0.0f;
+ aim_bot_position = static_cast(get_double("aim_bot_position", 0.5));
+ aim_bot_position2 = static_cast(get_double("aim_bot_position2", 0.5));
+ allowed_classes = get_string("allowed_classes", "");
+ class_priority_order = get_string("class_priority_order", "");
+ distance_scoring_weight = static_cast(get_double("distance_scoring_weight", 1.0));
+ center_scoring_weight = static_cast(get_double("center_scoring_weight", 1.0));
+ size_scoring_weight = static_cast(get_double("size_scoring_weight", 1.0));
+ aim_weight_tiebreak_ratio = static_cast(get_double("aim_weight_tiebreak_ratio", 0.1));
+ small_target_enhancement_enabled = get_bool("small_target_enhancement_enabled", true);
+ small_target_boost_factor = static_cast(get_double("small_target_boost_factor", 0.1));
+ small_target_threshold = static_cast(get_double("small_target_threshold", 0.02));
+ small_target_medium_threshold = static_cast(get_double("small_target_medium_threshold", 0.05));
+ small_target_medium_boost = static_cast(get_double("small_target_medium_boost", 1.5));
+ small_target_smooth_enabled = get_bool("small_target_smooth_enabled", true);
+ small_target_smooth_frames = get_long("small_target_smooth_frames", 2);
+ if (small_target_smooth_frames < 1)
+ small_target_smooth_frames = 1;
+
+ class_aim_positions.clear();
+ CSimpleIniA::TNamesDepend classAimKeys;
+ ini.GetAllKeys("ClassAim", classAimKeys);
+ for (const auto& k : classAimKeys)
+ {
+ std::string key = k.pItem;
+ if (key.empty() || !std::all_of(key.begin(), key.end(),
+ [](unsigned char c) { return std::isdigit(c) != 0; }))
+ continue;
+ std::string val = ini.GetValue("ClassAim", key.c_str(), "");
+ auto parts = splitString(val, ',');
+ if (parts.size() < 2)
+ continue;
+ try
+ {
+ int class_id = std::stoi(key);
+ float pos1 = std::stof(parts[0]);
+ float pos2 = std::stof(parts[1]);
+ class_aim_positions[class_id] = { pos1, pos2 };
+ }
+ catch (...)
+ {
+ std::cerr << "[Config] Invalid ClassAim entry: " << key << " = " << val << std::endl;
+ }
+ }
+
+ custom_class_names.clear();
+ CSimpleIniA::TNamesDepend classNameKeys;
+ ini.GetAllKeys("ClassNames", classNameKeys);
+ for (const auto& k : classNameKeys)
+ {
+ std::string key = k.pItem;
+ if (key.empty() || !std::all_of(key.begin(), key.end(),
+ [](unsigned char c) { return std::isdigit(c) != 0; }))
+ continue;
+ std::string val = ini.GetValue("ClassNames", key.c_str(), "");
+ try
+ {
+ int class_id = std::stoi(key);
+ if (!val.empty())
+ custom_class_names[class_id] = val;
+ }
+ catch (...) {}
+ }
// Mouse
fovX = get_long("fovX", 106);
@@ -337,6 +530,7 @@ bool Config::loadConfig(const std::string& filename)
smoothness = get_long("smoothness", 100);
use_smoothing = get_bool("use_smoothing", true);
+ tracking_smoothing = get_bool("tracking_smoothing", false);
use_kalman = get_bool("use_kalman", false);
kalman_process_noise = (float)get_double("kalman_process_noise", 0.01);
@@ -346,8 +540,22 @@ bool Config::loadConfig(const std::string& filename)
resetThreshold = (float)get_double("resetThreshold", 5);
predictionInterval = (float)get_double("predictionInterval", 0.01);
+ prediction_mode = get_long("prediction_mode", 0);
+ if (prediction_mode < 0) prediction_mode = 0;
+ if (prediction_mode > 2) prediction_mode = 2;
+ prediction_kalman_lead_ms = (float)get_double("prediction_kalman_lead_ms", 0.0);
+ prediction_kalman_max_lead_ms = (float)get_double("prediction_kalman_max_lead_ms", 0.0);
+ prediction_velocity_smoothing = (float)get_double("prediction_velocity_smoothing", 0.4);
+ prediction_velocity_scale = (float)get_double("prediction_velocity_scale", 1.0);
+ prediction_kalman_process_noise = (float)get_double("prediction_kalman_process_noise", 0.01);
+ prediction_kalman_measurement_noise = (float)get_double("prediction_kalman_measurement_noise", 0.10);
+ prediction_use_future_for_aim = get_bool("prediction_use_future_for_aim", false);
prediction_futurePositions = get_long("prediction_futurePositions", 20);
draw_futurePositions = get_bool("draw_futurePositions", true);
+
+ camera_compensation_enabled = get_bool("camera_compensation_enabled", false);
+ camera_compensation_max_shift = (float)get_double("camera_compensation_max_shift", 50.0);
+ camera_compensation_strength = (float)get_double("camera_compensation_strength", 1.0);
snapRadius = (float)get_double("snapRadius", 1.5);
nearRadius = (float)get_double("nearRadius", 25.0);
@@ -365,6 +573,11 @@ bool Config::loadConfig(const std::string& filename)
wind_W = (float)get_double("wind_W", 15.0f);
wind_M = (float)get_double("wind_M", 10.0f);
wind_D = (float)get_double("wind_D", 8.0f);
+ // Makcu
+ makcu_baudrate = get_long("makcu_baudrate", 4000000);
+ makcu_port = get_string("makcu_port", "COM1");
+ if (makcu_port.empty() || makcu_port == "COM0")
+ makcu_port = "COM1";
// kmbox_B
kmbox_b_baudrate = get_long("kmbox_baudrate", 115200);
@@ -373,9 +586,18 @@ bool Config::loadConfig(const std::string& filename)
// Mouse shooting
auto_shoot = get_bool("auto_shoot", false);
triggerbot = get_bool("triggerbot", false);
- triggerbot_interval = get_double("triggerbot_interval", 0.0);
- triggerbot_predict_ms = get_double("triggerbot_predict_ms", 0.0);
- triggerbot_predict_alpha = get_double("triggerbot_predict_alpha", 0.5);
+ long reaction_ms_raw = get_long("triggerbot_reaction_ms", -1);
+ if (reaction_ms_raw >= 0)
+ {
+ triggerbot_reaction_ms = static_cast(reaction_ms_raw);
+ }
+ else
+ {
+ double legacy_interval_s = get_double("triggerbot_interval", 0.0);
+ triggerbot_reaction_ms = static_cast(legacy_interval_s * 1000.0 + 0.5);
+ }
+ if (triggerbot_reaction_ms < 0)
+ triggerbot_reaction_ms = 0;
bScope_multiplier = (float)get_double("bScope_multiplier", 1.2);
triggerbot_bScope_multiplier = (float)get_double("triggerbot_bScope_multiplier", 1.2);
@@ -386,7 +608,7 @@ bool Config::loadConfig(const std::string& filename)
color_target = get_string("color_target", "yellow");
tinyArea = get_long("tinyArea", 2);
isOnlyTop = get_bool("isOnlyTop", true);
- scanError = get_long("scanError", 0.1f);
+ scanError = static_cast(get_double("scanError", 0.1));
// HSV ranges
color_ranges.clear();
@@ -394,7 +616,7 @@ bool Config::loadConfig(const std::string& filename)
ini.GetAllKeys("Colors", colorKeys);
for (const auto& k : colorKeys) {
- std::string key = k.pItem; // например "Yellow"
+ std::string key = k.pItem; // ???????? "Yellow"
std::string val = ini.GetValue("Colors", key.c_str(), "");
auto parts = splitString(val, ',');
if (parts.size() == 6) {
@@ -424,7 +646,7 @@ bool Config::loadConfig(const std::string& filename)
#endif
);
- // Проверка допустимых значений (TRT / DML / COLOR)
+ // ???????? ?????????? ???????? (TRT / DML / COLOR)
if (backend != "TRT" && backend != "DML" && backend != "COLOR") {
#ifdef USE_CUDA
backend = "TRT";
@@ -461,6 +683,7 @@ bool Config::loadConfig(const std::string& filename)
#ifdef USE_CUDA
use_cuda_graph = get_bool("use_cuda_graph", false);
use_pinned_memory = get_bool("use_pinned_memory", true);
+ capture_use_cuda = get_bool("capture_use_cuda", true);
#endif
// Buttons
@@ -478,6 +701,85 @@ bool Config::loadConfig(const std::string& filename)
overlay_opacity = get_long("overlay_opacity", 225);
overlay_snow_theme = get_bool("overlay_snow_theme", true);
overlay_ui_scale = (float)get_double("overlay_ui_scale", 1.0);
+ game_overlay_enabled = get_bool("game_overlay_enabled", false);
+ game_overlay_max_fps = get_long("game_overlay_max_fps", 0);
+ game_overlay_draw_boxes = get_bool("game_overlay_draw_boxes", true);
+ game_overlay_draw_future = get_bool("game_overlay_draw_future", true);
+ game_overlay_draw_wind_tail = get_bool("game_overlay_draw_wind_tail", true);
+ game_overlay_draw_frame = get_bool("game_overlay_draw_frame", true);
+ game_overlay_show_target_correction = get_bool("game_overlay_show_target_correction", true);
+ game_overlay_show_fps_counter = get_bool("game_overlay_show_fps_counter", true);
+ game_overlay_show_latency = get_bool("game_overlay_show_latency", true);
+ game_overlay_box_a = get_long("game_overlay_box_a", 255);
+ game_overlay_box_r = get_long("game_overlay_box_r", 0);
+ game_overlay_box_g = get_long("game_overlay_box_g", 255);
+ game_overlay_box_b = get_long("game_overlay_box_b", 0);
+ game_overlay_frame_a = get_long("game_overlay_frame_a", 180);
+ game_overlay_frame_r = get_long("game_overlay_frame_r", 255);
+ game_overlay_frame_g = get_long("game_overlay_frame_g", 255);
+ game_overlay_frame_b = get_long("game_overlay_frame_b", 255);
+ game_overlay_box_thickness = static_cast(get_double("game_overlay_box_thickness", 2.0));
+ game_overlay_frame_thickness = static_cast(get_double("game_overlay_frame_thickness", 1.5));
+ game_overlay_future_point_radius = static_cast(get_double("game_overlay_future_point_radius", 5.0));
+ game_overlay_future_alpha_falloff = static_cast(get_double("game_overlay_future_alpha_falloff", 1.0));
+ game_overlay_icon_enabled = get_bool("game_overlay_icon_enabled", false);
+ game_overlay_icon_path = get_string("game_overlay_icon_path", "icon.png");
+ game_overlay_icon_width = get_long("game_overlay_icon_width", 64);
+ game_overlay_icon_height = get_long("game_overlay_icon_height", 64);
+ game_overlay_icon_offset_x = static_cast(get_double("game_overlay_icon_offset_x", 0.0));
+ game_overlay_icon_offset_y = static_cast(get_double("game_overlay_icon_offset_y", 0.0));
+ game_overlay_icon_anchor = get_string("game_overlay_icon_anchor", "center");
+ game_overlay_icon_class = get_long("game_overlay_icon_class", -1);
+ clampGameOverlayColor();
+ aim_sim_enabled = get_bool("aim_sim_enabled", false);
+ aim_sim_x = get_long("aim_sim_x", 24);
+ aim_sim_y = get_long("aim_sim_y", 24);
+ aim_sim_width = get_long("aim_sim_width", 560);
+ aim_sim_height = get_long("aim_sim_height", 360);
+ aim_sim_fps_min = get_long("aim_sim_fps_min", 90);
+ aim_sim_fps_max = get_long("aim_sim_fps_max", 120);
+ aim_sim_fps_jitter = static_cast(get_double("aim_sim_fps_jitter", 0.15));
+ aim_sim_capture_delay_ms = static_cast(get_double("aim_sim_capture_delay_ms", 6.0));
+ aim_sim_inference_delay_ms = static_cast(get_double("aim_sim_inference_delay_ms", 12.0));
+ aim_sim_use_live_inference = get_bool("aim_sim_use_live_inference", true);
+ aim_sim_input_delay_ms = static_cast(get_double("aim_sim_input_delay_ms", 2.0));
+ aim_sim_extra_delay_ms = static_cast(get_double("aim_sim_extra_delay_ms", 2.0));
+ aim_sim_target_max_speed = static_cast(get_double("aim_sim_target_max_speed", 560.0));
+ aim_sim_target_accel = static_cast(get_double("aim_sim_target_accel", 1850.0));
+ aim_sim_target_stop_chance = static_cast(get_double("aim_sim_target_stop_chance", 0.25));
+ aim_sim_show_observed = get_bool("aim_sim_show_observed", true);
+ aim_sim_show_history = get_bool("aim_sim_show_history", true);
+ if (aim_sim_width < 220) aim_sim_width = 220;
+ if (aim_sim_width > 1920) aim_sim_width = 1920;
+ if (aim_sim_height < 180) aim_sim_height = 180;
+ if (aim_sim_height > 1080) aim_sim_height = 1080;
+ if (aim_sim_fps_min < 15) aim_sim_fps_min = 15;
+ if (aim_sim_fps_min > 360) aim_sim_fps_min = 360;
+ if (aim_sim_fps_max < 15) aim_sim_fps_max = 15;
+ if (aim_sim_fps_max > 360) aim_sim_fps_max = 360;
+ if (aim_sim_fps_min > aim_sim_fps_max) std::swap(aim_sim_fps_min, aim_sim_fps_max);
+ if (aim_sim_fps_jitter < 0.0f) aim_sim_fps_jitter = 0.0f;
+ if (aim_sim_fps_jitter > 0.8f) aim_sim_fps_jitter = 0.8f;
+ if (aim_sim_capture_delay_ms < 0.0f) aim_sim_capture_delay_ms = 0.0f;
+ if (aim_sim_capture_delay_ms > 80.0f) aim_sim_capture_delay_ms = 80.0f;
+ if (aim_sim_inference_delay_ms < 0.0f) aim_sim_inference_delay_ms = 0.0f;
+ if (aim_sim_inference_delay_ms > 120.0f) aim_sim_inference_delay_ms = 120.0f;
+ if (aim_sim_input_delay_ms < 0.0f) aim_sim_input_delay_ms = 0.0f;
+ if (aim_sim_input_delay_ms > 60.0f) aim_sim_input_delay_ms = 60.0f;
+ if (aim_sim_extra_delay_ms < 0.0f) aim_sim_extra_delay_ms = 0.0f;
+ if (aim_sim_extra_delay_ms > 60.0f) aim_sim_extra_delay_ms = 60.0f;
+ if (aim_sim_target_max_speed < 20.0f) aim_sim_target_max_speed = 20.0f;
+ if (aim_sim_target_max_speed > 2500.0f) aim_sim_target_max_speed = 2500.0f;
+ if (aim_sim_target_accel < 20.0f) aim_sim_target_accel = 20.0f;
+ if (aim_sim_target_accel > 10000.0f) aim_sim_target_accel = 10000.0f;
+ if (aim_sim_target_stop_chance < 0.0f) aim_sim_target_stop_chance = 0.0f;
+ if (aim_sim_target_stop_chance > 0.95f) aim_sim_target_stop_chance = 0.95f;
+
+ // OBS
+ is_obs = get_bool("is_obs", false);
+ obs_ip = get_string("obs_ip", "0.0.0.0");
+ obs_port = get_long("obs_port", 4455);
+ obs_fps = get_long("obs_fps", 240);
// Custom Classes
class_player = get_long("class_player", 0);
@@ -494,6 +796,7 @@ bool Config::loadConfig(const std::string& filename)
// Debug window
show_window = get_bool("show_window", true);
+ show_fps = get_bool("show_fps", false);
screenshot_button = splitString(get_string("screenshot_button", "None"));
screenshot_delay = get_long("screenshot_delay", 500);
verbose = get_bool("verbose", false);
@@ -511,7 +814,7 @@ bool Config::saveConfig(const std::string& filename)
}
file << "# An explanation of the options can be found at:\n";
- file << "# https://github.com/SunOner/sunone_aimbot_docs/blob/main/config/config_cpp.md\n\n";
+ file << "# https://github.com/RN-AI/RN_AI_cpp\n\n";
// Capture
file << "# Capture\n"
@@ -540,7 +843,29 @@ bool Config::saveConfig(const std::string& filename)
<< std::fixed << std::setprecision(1)
<< "target_lock_distance = " << target_lock_distance << "\n"
<< std::fixed << std::setprecision(2)
- << "target_lock_reacquire_time = " << target_lock_reacquire_time << "\n\n";
+ << "target_lock_reacquire_time = " << target_lock_reacquire_time << "\n"
+ << "smart_target_lock = " << (smart_target_lock ? "true" : "false") << "\n"
+ << "target_reference_class = " << target_reference_class << "\n"
+ << "target_lock_fallback_class = " << target_lock_fallback_class << "\n"
+ << "target_switch_delay = " << target_switch_delay << "\n"
+ << std::fixed << std::setprecision(1)
+ << "aim_bot_scope = " << aim_bot_scope << "\n"
+ << std::fixed << std::setprecision(2)
+ << "aim_bot_position = " << aim_bot_position << "\n"
+ << "aim_bot_position2 = " << aim_bot_position2 << "\n"
+ << "allowed_classes = " << allowed_classes << "\n"
+ << "class_priority_order = " << class_priority_order << "\n"
+ << "distance_scoring_weight = " << distance_scoring_weight << "\n"
+ << "center_scoring_weight = " << center_scoring_weight << "\n"
+ << "size_scoring_weight = " << size_scoring_weight << "\n"
+ << "aim_weight_tiebreak_ratio = " << aim_weight_tiebreak_ratio << "\n"
+ << "small_target_enhancement_enabled = " << (small_target_enhancement_enabled ? "true" : "false") << "\n"
+ << "small_target_boost_factor = " << small_target_boost_factor << "\n"
+ << "small_target_threshold = " << small_target_threshold << "\n"
+ << "small_target_medium_threshold = " << small_target_medium_threshold << "\n"
+ << "small_target_medium_boost = " << small_target_medium_boost << "\n"
+ << "small_target_smooth_enabled = " << (small_target_smooth_enabled ? "true" : "false") << "\n"
+ << "small_target_smooth_frames = " << small_target_smooth_frames << "\n\n";
// Mouse
file << "# Mouse move\n"
@@ -550,6 +875,7 @@ bool Config::saveConfig(const std::string& filename)
<< "maxSpeedMultiplier = " << maxSpeedMultiplier << "\n"
<< "smoothness = " << smoothness << "\n"
<< "use_smoothing = " << (use_smoothing ? "true" : "false") << "\n"
+ << "tracking_smoothing = " << (tracking_smoothing ? "true" : "false") << "\n"
<< "use_kalman = " << (use_kalman ? "true" : "false") << "\n\n"
<< "kalman_process_noise = " << kalman_process_noise << "\n"
<< "kalman_measurement_noise = " << kalman_measurement_noise << "\n"
@@ -559,9 +885,21 @@ bool Config::saveConfig(const std::string& filename)
<< std::fixed << std::setprecision(2)
<< "predictionInterval = " << predictionInterval << "\n"
+ << "prediction_mode = " << prediction_mode << "\n"
+ << "prediction_kalman_lead_ms = " << prediction_kalman_lead_ms << "\n"
+ << "prediction_kalman_max_lead_ms = " << prediction_kalman_max_lead_ms << "\n"
+ << "prediction_velocity_smoothing = " << prediction_velocity_smoothing << "\n"
+ << "prediction_velocity_scale = " << prediction_velocity_scale << "\n"
+ << "prediction_kalman_process_noise = " << prediction_kalman_process_noise << "\n"
+ << "prediction_kalman_measurement_noise = " << prediction_kalman_measurement_noise << "\n"
+ << "prediction_use_future_for_aim = " << (prediction_use_future_for_aim ? "true" : "false") << "\n"
<< "prediction_futurePositions = " << prediction_futurePositions << "\n"
<< "draw_futurePositions = " << (draw_futurePositions ? "true" : "false") << "\n"
+ << "camera_compensation_enabled = " << (camera_compensation_enabled ? "true" : "false") << "\n"
+ << "camera_compensation_max_shift = " << camera_compensation_max_shift << "\n"
+ << "camera_compensation_strength = " << camera_compensation_strength << "\n"
+
<< "snapRadius = " << snapRadius << "\n"
<< "nearRadius = " << nearRadius << "\n"
<< "speedCurveExponent = " << speedCurveExponent << "\n"
@@ -582,6 +920,10 @@ bool Config::saveConfig(const std::string& filename)
<< "wind_W = " << wind_W << "\n"
<< "wind_M = " << wind_M << "\n"
<< "wind_D = " << wind_D << "\n\n";
+ // Makcu
+ file << "# Makcu\n"
+ << "makcu_baudrate = " << makcu_baudrate << "\n"
+ << "makcu_port = " << makcu_port << "\n\n";
// kmbox_B
file << "# Kmbox_B\n"
@@ -592,10 +934,9 @@ bool Config::saveConfig(const std::string& filename)
file << "# Mouse shooting\n"
<< "auto_shoot = " << (auto_shoot ? "true" : "false") << "\n"
<< "triggerbot = " << (triggerbot ? "true" : "false") << "\n"
+ << "triggerbot_reaction_ms = " << triggerbot_reaction_ms << "\n"
<< std::fixed << std::setprecision(2)
- << "triggerbot_interval = " << triggerbot_interval << "\n"
- << "triggerbot_predict_ms = " << triggerbot_predict_ms << "\n"
- << "triggerbot_predict_alpha = " << triggerbot_predict_alpha << "\n"
+ << "triggerbot_interval = " << (static_cast(triggerbot_reaction_ms) / 1000.0) << "\n"
<< std::fixed << std::setprecision(1)
<< "bScope_multiplier = " << bScope_multiplier << "\n"
<< "triggerbot_bScope_multiplier = " << triggerbot_bScope_multiplier << "\n\n";
@@ -623,7 +964,8 @@ bool Config::saveConfig(const std::string& filename)
#ifdef USE_CUDA
file << "\n# CUDA\n"
<< "use_cuda_graph = " << (use_cuda_graph ? "true" : "false") << "\n"
- << "use_pinned_memory = " << (use_pinned_memory ? "true" : "false") << "\n\n";
+ << "use_pinned_memory = " << (use_pinned_memory ? "true" : "false") << "\n"
+ << "capture_use_cuda = " << (capture_use_cuda ? "true" : "false") << "\n\n";
#endif
// Buttons
@@ -643,21 +985,60 @@ bool Config::saveConfig(const std::string& filename)
<< "overlay_opacity = " << overlay_opacity << "\n"
<< "overlay_snow_theme = " << (overlay_snow_theme ? "true" : "false") << "\n"
<< std::fixed << std::setprecision(2)
- << "overlay_ui_scale = " << overlay_ui_scale << "\n\n";
-
- // Custom Classes
- file << "# Custom Classes\n"
- << "class_player = " << class_player << "\n"
- << "class_bot = " << class_bot << "\n"
- << "class_weapon = " << class_weapon << "\n"
- << "class_outline = " << class_outline << "\n"
- << "class_dead_body = " << class_dead_body << "\n"
- << "class_hideout_target_human = " << class_hideout_target_human << "\n"
- << "class_hideout_target_balls = " << class_hideout_target_balls << "\n"
- << "class_head = " << class_head << "\n"
- << "class_smoke = " << class_smoke << "\n"
- << "class_fire = " << class_fire << "\n"
- << "class_third_person = " << class_third_person << "\n\n";
+ << "overlay_ui_scale = " << overlay_ui_scale << "\n"
+ << "game_overlay_enabled = " << (game_overlay_enabled ? "true" : "false") << "\n"
+ << "game_overlay_max_fps = " << game_overlay_max_fps << "\n"
+ << "game_overlay_draw_boxes = " << (game_overlay_draw_boxes ? "true" : "false") << "\n"
+ << "game_overlay_draw_future = " << (game_overlay_draw_future ? "true" : "false") << "\n"
+ << "game_overlay_draw_wind_tail = " << (game_overlay_draw_wind_tail ? "true" : "false") << "\n"
+ << "game_overlay_draw_frame = " << (game_overlay_draw_frame ? "true" : "false") << "\n"
+ << "game_overlay_show_target_correction = " << (game_overlay_show_target_correction ? "true" : "false") << "\n"
+ << "game_overlay_show_fps_counter = " << (game_overlay_show_fps_counter ? "true" : "false") << "\n"
+ << "game_overlay_show_latency = " << (game_overlay_show_latency ? "true" : "false") << "\n"
+ << "game_overlay_box_a = " << game_overlay_box_a << "\n"
+ << "game_overlay_box_r = " << game_overlay_box_r << "\n"
+ << "game_overlay_box_g = " << game_overlay_box_g << "\n"
+ << "game_overlay_box_b = " << game_overlay_box_b << "\n"
+ << "game_overlay_frame_a = " << game_overlay_frame_a << "\n"
+ << "game_overlay_frame_r = " << game_overlay_frame_r << "\n"
+ << "game_overlay_frame_g = " << game_overlay_frame_g << "\n"
+ << "game_overlay_frame_b = " << game_overlay_frame_b << "\n"
+ << "game_overlay_box_thickness = " << game_overlay_box_thickness << "\n"
+ << "game_overlay_frame_thickness = " << game_overlay_frame_thickness << "\n"
+ << "game_overlay_future_point_radius = " << game_overlay_future_point_radius << "\n"
+ << "game_overlay_future_alpha_falloff = " << game_overlay_future_alpha_falloff << "\n"
+ << "game_overlay_icon_enabled = " << (game_overlay_icon_enabled ? "true" : "false") << "\n"
+ << "game_overlay_icon_path = " << game_overlay_icon_path << "\n"
+ << "game_overlay_icon_width = " << game_overlay_icon_width << "\n"
+ << "game_overlay_icon_height = " << game_overlay_icon_height << "\n"
+ << "game_overlay_icon_offset_x = " << game_overlay_icon_offset_x << "\n"
+ << "game_overlay_icon_offset_y = " << game_overlay_icon_offset_y << "\n"
+ << "game_overlay_icon_anchor = " << game_overlay_icon_anchor << "\n"
+ << "game_overlay_icon_class = " << game_overlay_icon_class << "\n"
+ << "aim_sim_enabled = " << (aim_sim_enabled ? "true" : "false") << "\n"
+ << "aim_sim_x = " << aim_sim_x << "\n"
+ << "aim_sim_y = " << aim_sim_y << "\n"
+ << "aim_sim_width = " << aim_sim_width << "\n"
+ << "aim_sim_height = " << aim_sim_height << "\n"
+ << "aim_sim_fps_min = " << aim_sim_fps_min << "\n"
+ << "aim_sim_fps_max = " << aim_sim_fps_max << "\n"
+ << "aim_sim_fps_jitter = " << aim_sim_fps_jitter << "\n"
+ << "aim_sim_capture_delay_ms = " << aim_sim_capture_delay_ms << "\n"
+ << "aim_sim_inference_delay_ms = " << aim_sim_inference_delay_ms << "\n"
+ << "aim_sim_use_live_inference = " << (aim_sim_use_live_inference ? "true" : "false") << "\n"
+ << "aim_sim_input_delay_ms = " << aim_sim_input_delay_ms << "\n"
+ << "aim_sim_extra_delay_ms = " << aim_sim_extra_delay_ms << "\n"
+ << "aim_sim_target_max_speed = " << aim_sim_target_max_speed << "\n"
+ << "aim_sim_target_accel = " << aim_sim_target_accel << "\n"
+ << "aim_sim_target_stop_chance = " << aim_sim_target_stop_chance << "\n"
+ << "aim_sim_show_observed = " << (aim_sim_show_observed ? "true" : "false") << "\n"
+ << "aim_sim_show_history = " << (aim_sim_show_history ? "true" : "false") << "\n\n";
+
+ file << "# OBS\n"
+ << "is_obs = " << (is_obs ? "true" : "false") << "\n"
+ << "obs_ip = " << obs_ip << "\n"
+ << "obs_port = " << obs_port << "\n"
+ << "obs_fps = " << obs_fps << "\n\n";
// Color detection
file << "# Color detection\n";
@@ -669,15 +1050,6 @@ bool Config::saveConfig(const std::string& filename)
file << "isOnlyTop = " << isOnlyTop << "\n";
file << "scanError = " << scanError << "\n\n";
- file << "[Colors]\n";
- for (const auto& cr : color_ranges) {
- file << cr.name << " = "
- << cr.h_low << "," << cr.s_low << "," << cr.v_low << ","
- << cr.h_high << "," << cr.s_high << "," << cr.v_high << "\n";
- }
- file << "\n";
-
-
// Debug
file << "# Debug\n"
<< "show_window = " << (show_window ? "true" : "false") << "\n"
@@ -689,6 +1061,15 @@ bool Config::saveConfig(const std::string& filename)
// Active game
file << "# Active game profile\n";
file << "active_game = " << active_game << "\n\n";
+
+ file << "[Colors]\n";
+ for (const auto& cr : color_ranges) {
+ file << cr.name << " = "
+ << cr.h_low << "," << cr.s_low << "," << cr.v_low << ","
+ << cr.h_high << "," << cr.s_high << "," << cr.v_high << "\n";
+ }
+ file << "\n";
+
file << "[Games]\n";
for (auto& kv : game_profiles)
{
@@ -700,6 +1081,44 @@ bool Config::saveConfig(const std::string& filename)
file << ",true," << gp.baseFOV;
file << "\n";
}
+ file << "\n";
+
+ if (!class_aim_positions.empty())
+ {
+ std::vector class_ids;
+ class_ids.reserve(class_aim_positions.size());
+ for (const auto& kv : class_aim_positions)
+ class_ids.push_back(kv.first);
+ std::sort(class_ids.begin(), class_ids.end());
+ file << "[ClassAim]\n";
+ file << std::fixed << std::setprecision(2);
+ for (int class_id : class_ids)
+ {
+ auto it = class_aim_positions.find(class_id);
+ if (it == class_aim_positions.end())
+ continue;
+ file << class_id << " = " << it->second.first << "," << it->second.second << "\n";
+ }
+ file << "\n";
+ }
+
+ if (!custom_class_names.empty())
+ {
+ std::vector class_ids;
+ class_ids.reserve(custom_class_names.size());
+ for (const auto& kv : custom_class_names)
+ class_ids.push_back(kv.first);
+ std::sort(class_ids.begin(), class_ids.end());
+ file << "[ClassNames]\n";
+ for (int class_id : class_ids)
+ {
+ auto it = custom_class_names.find(class_id);
+ if (it == custom_class_names.end())
+ continue;
+ file << class_id << " = " << it->second << "\n";
+ }
+ file << "\n";
+ }
file.close();
return true;
@@ -724,3 +1143,6 @@ std::pair Config::degToCounts(double degX, double degY, double f
double cy = degY / (gp.sens * gp.pitch * scale);
return { cx, cy };
}
+
+
+
diff --git a/sunone_aimbot_cpp/config/config.h b/RN_AI_cpp/config/config.h
similarity index 58%
rename from sunone_aimbot_cpp/config/config.h
rename to RN_AI_cpp/config/config.h
index 83909c2d..06f7a958 100644
--- a/sunone_aimbot_cpp/config/config.h
+++ b/RN_AI_cpp/config/config.h
@@ -11,7 +11,7 @@ class Config
{
public:
// Capture
- std::string capture_method; // "duplication_api", "winrt", "virtual_camera"
+ std::string capture_method; // "duplication_api", "winrt", "virtual_camera", "obs"
int detection_resolution;
int capture_fps;
int monitor_idx;
@@ -33,6 +33,28 @@ class Config
bool target_lock_enabled;
float target_lock_distance;
float target_lock_reacquire_time;
+ bool smart_target_lock;
+ int target_reference_class;
+ int target_lock_fallback_class;
+ int target_switch_delay;
+ float aim_bot_scope;
+ float aim_bot_position;
+ float aim_bot_position2;
+ std::string allowed_classes;
+ std::string class_priority_order;
+ std::unordered_map custom_class_names;
+ float distance_scoring_weight;
+ float center_scoring_weight;
+ float size_scoring_weight;
+ float aim_weight_tiebreak_ratio;
+ bool small_target_enhancement_enabled;
+ float small_target_boost_factor;
+ float small_target_threshold;
+ float small_target_medium_threshold;
+ float small_target_medium_boost;
+ bool small_target_smooth_enabled;
+ int small_target_smooth_frames;
+ std::unordered_map> class_aim_positions;
// Mouse
int fovX;
@@ -42,6 +64,7 @@ class Config
int smoothness;
bool use_smoothing;
+ bool tracking_smoothing;
bool use_kalman;
float kalman_process_noise;
@@ -51,9 +74,21 @@ class Config
float resetThreshold;
float predictionInterval;
+ int prediction_mode;
+ float prediction_kalman_lead_ms;
+ float prediction_kalman_max_lead_ms;
+ float prediction_velocity_smoothing;
+ float prediction_velocity_scale;
+ float prediction_kalman_process_noise;
+ float prediction_kalman_measurement_noise;
+ bool prediction_use_future_for_aim;
int prediction_futurePositions;
bool draw_futurePositions;
+ bool camera_compensation_enabled;
+ float camera_compensation_max_shift;
+ float camera_compensation_strength;
+
float snapRadius;
float nearRadius;
float speedCurveExponent;
@@ -92,9 +127,7 @@ class Config
// Mouse shooting
bool auto_shoot;
bool triggerbot;
- double triggerbot_interval; // seconds between triggerbot shots (0 = continuous hold)
- double triggerbot_predict_ms; // prediction lead for triggerbot (ms, 0 = off)
- double triggerbot_predict_alpha; // smoothing factor for predicted velocity (0..1)
+ int triggerbot_reaction_ms; // delay between triggerbot shots in ms (0 = continuous hold)
float bScope_multiplier;
float triggerbot_bScope_multiplier;
@@ -118,6 +151,7 @@ class Config
#ifdef USE_CUDA
bool use_cuda_graph;
bool use_pinned_memory;
+ bool capture_use_cuda;
#endif
// Buttons
std::vector button_targeting;
@@ -135,6 +169,72 @@ class Config
int overlay_opacity;
bool overlay_snow_theme;
float overlay_ui_scale;
+ bool game_overlay_enabled;
+ int game_overlay_max_fps;
+ bool game_overlay_draw_boxes;
+ bool game_overlay_draw_future;
+ bool game_overlay_draw_wind_tail;
+ bool game_overlay_draw_frame;
+ bool game_overlay_show_target_correction;
+ bool game_overlay_show_fps_counter;
+ bool game_overlay_show_latency;
+ int game_overlay_box_a;
+ int game_overlay_box_r;
+ int game_overlay_box_g;
+ int game_overlay_box_b;
+ int game_overlay_frame_a;
+ int game_overlay_frame_r;
+ int game_overlay_frame_g;
+ int game_overlay_frame_b;
+ float game_overlay_box_thickness;
+ float game_overlay_frame_thickness;
+ float game_overlay_future_point_radius;
+ float game_overlay_future_alpha_falloff;
+ bool game_overlay_icon_enabled;
+ std::string game_overlay_icon_path;
+ int game_overlay_icon_width;
+ int game_overlay_icon_height;
+ float game_overlay_icon_offset_x;
+ float game_overlay_icon_offset_y;
+ std::string game_overlay_icon_anchor;
+ int game_overlay_icon_class;
+ bool aim_sim_enabled;
+ int aim_sim_x;
+ int aim_sim_y;
+ int aim_sim_width;
+ int aim_sim_height;
+ int aim_sim_fps_min;
+ int aim_sim_fps_max;
+ float aim_sim_fps_jitter;
+ float aim_sim_capture_delay_ms;
+ float aim_sim_inference_delay_ms;
+ bool aim_sim_use_live_inference;
+ float aim_sim_input_delay_ms;
+ float aim_sim_extra_delay_ms;
+ float aim_sim_target_max_speed;
+ float aim_sim_target_accel;
+ float aim_sim_target_stop_chance;
+ bool aim_sim_show_observed;
+ bool aim_sim_show_history;
+
+ void clampGameOverlayColor()
+ {
+ auto clamp255 = [](int& v) { if (v < 0) v = 0; if (v > 255) v = 255; };
+ clamp255(game_overlay_box_a);
+ clamp255(game_overlay_box_r);
+ clamp255(game_overlay_box_g);
+ clamp255(game_overlay_box_b);
+ clamp255(game_overlay_frame_a);
+ clamp255(game_overlay_frame_r);
+ clamp255(game_overlay_frame_g);
+ clamp255(game_overlay_frame_b);
+ }
+
+ // OBS
+ bool is_obs;
+ std::string obs_ip;
+ int obs_port;
+ int obs_fps;
// Custom Classes
int class_player; // 0
diff --git a/sunone_aimbot_cpp/detector/color_detector.cpp b/RN_AI_cpp/detector/color_detector.cpp
similarity index 57%
rename from sunone_aimbot_cpp/detector/color_detector.cpp
rename to RN_AI_cpp/detector/color_detector.cpp
index b8e0c7b9..33775e4c 100644
--- a/sunone_aimbot_cpp/detector/color_detector.cpp
+++ b/RN_AI_cpp/detector/color_detector.cpp
@@ -1,5 +1,5 @@
-#include "color_detector.h"
-#include "sunone_aimbot_cpp.h"
+#include "color_detector.h"
+#include "rn_ai_cpp.h"
ColorDetector::ColorDetector()
: erodeIter(1), dilateIter(2), minArea(50),
@@ -13,7 +13,7 @@ ColorDetector::~ColorDetector() {
void ColorDetector::initializeFromConfig(const Config& cfg) {
colorRanges.clear();
- // Если выбран конкретный цвет — берём его
+ // ???? ?????? ?????????? ???? ????? ???
for (const auto& cr : cfg.color_ranges) {
if (cr.name == cfg.color_target) {
colorRanges.push_back({
@@ -25,7 +25,7 @@ void ColorDetector::initializeFromConfig(const Config& cfg) {
}
}
- // Если не нашли — fallback: берём все
+ // ???? ?? ????? fallback: ????? ???
if (colorRanges.empty()) {
for (const auto& cr : cfg.color_ranges) {
colorRanges.push_back({
@@ -76,7 +76,7 @@ void ColorDetector::inferenceThread() {
#include // std::clamp
void ColorDetector::detectColors(const cv::Mat& frame) {
- // Преобразуем изображение в формат BGR (если оно в формате BGRA)
+ // ??????????? ??????????? ? ?????? BGR (???? ??? ? ??????? BGRA)
cv::Mat bgr;
if (frame.channels() == 4) {
cv::cvtColor(frame, bgr, cv::COLOR_BGRA2BGR);
@@ -85,96 +85,96 @@ void ColorDetector::detectColors(const cv::Mat& frame) {
bgr = frame;
}
- // Преобразуем изображение в цветовую модель HSV
+ // ??????????? ??????????? ? ???????? ?????? HSV
cv::Mat hsv;
cv::cvtColor(bgr, hsv, cv::COLOR_BGR2HSV);
- // Создаем пустую маску для всех выбранных цветовых диапазонов
+ // ??????? ?????? ????? ??? ???? ????????? ???????? ??????????
cv::Mat combinedMask = cv::Mat::zeros(bgr.size(), CV_8UC1);
- // Собираем все выбранные диапазоны
+ // ???????? ??? ????????? ?????????
for (const auto& range : colorRanges) {
cv::Mat mask;
- cv::inRange(hsv, range.lower, range.upper, mask); // Находим пиксели, попадающие в диапазон
- combinedMask |= mask; // Объединяем маски (сейчас все диапазоны объединены в один)
+ cv::inRange(hsv, range.lower, range.upper, mask); // ??????? ???????, ?????????? ? ????????
+ combinedMask |= mask; // ?????????? ????? (?????? ??? ????????? ?????????? ? ????)
}
- // Немного расширим пятна, чтобы мелкие объекты не пропали
+ // ??????? ???????? ?????, ????? ?????? ??????? ?? ???????
cv::dilate(combinedMask, combinedMask, cv::Mat(), cv::Point(-1, -1), dilateIter);
- // Находим контуры на маске
+ // ??????? ??????? ?? ?????
std::vector> contours;
cv::findContours(combinedMask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
- // Вектор для хранения найденных прямоугольников
+ // ?????? ??? ???????? ????????? ???????????????
std::vector boxes;
- // Переменная для хранения самого верхнего объекта
+ // ?????????? ??? ???????? ?????? ???????? ???????
cv::Rect topObject;
bool foundTopObject = false;
- // Если TopHead = true, ищем только самый верхний объект
+ // ???? TopHead = true, ???? ?????? ????? ??????? ??????
if (isOnlyTop) {
for (auto& c : contours) {
- double area = cv::contourArea(c); // Вычисляем площадь контура
+ double area = cv::contourArea(c); // ????????? ??????? ???????
- // Если площадь достаточна и объект не слишком маленький
+ // ???? ??????? ?????????? ? ?????? ?? ??????? ?????????
if (area >= minArea) {
- cv::Rect boundingBox = cv::boundingRect(c); // Получаем ограничивающий прямоугольник
+ cv::Rect boundingBox = cv::boundingRect(c); // ???????? ?????????????? ?????????????
- // Пропускаем слишком маленькие объекты
+ // ?????????? ??????? ????????? ???????
if (area < tinyArea) {
continue;
}
- // Если это первый объект, или он выше всех по Y, сохраняем его
+ // ???? ??? ?????? ??????, ??? ?? ???? ???? ?? Y, ????????? ???
if (topObject.area() == 0 || boundingBox.y < topObject.y) {
topObject = boundingBox;
- foundTopObject = true; // Устанавливаем флаг, что верхний объект найден
+ foundTopObject = true; // ????????????? ????, ??? ??????? ?????? ??????
}
}
}
- // Если был найден верхний объект, добавляем его в список
+ // ???? ??? ?????? ??????? ??????, ????????? ??? ? ??????
if (foundTopObject) {
boxes.push_back(topObject);
}
}
else {
- // Если TopHead = false, обрабатываем все объекты как раньше
+ // ???? TopHead = false, ???????????? ??? ??????? ??? ??????
for (auto& c : contours) {
- double area = cv::contourArea(c); // Вычисляем площадь контура
+ double area = cv::contourArea(c); // ????????? ??????? ???????
- // Если площадь достаточна и объект не слишком маленький
+ // ???? ??????? ?????????? ? ?????? ?? ??????? ?????????
if (area >= minArea) {
- cv::Rect boundingBox = cv::boundingRect(c); // Получаем ограничивающий прямоугольник
+ cv::Rect boundingBox = cv::boundingRect(c); // ???????? ?????????????? ?????????????
- // Пропускаем слишком маленькие объекты
+ // ?????????? ??????? ????????? ???????
if (area < tinyArea) {
continue;
}
- boxes.push_back(boundingBox); // Добавляем прямоугольник в список
+ boxes.push_back(boundingBox); // ????????? ????????????? ? ??????
}
}
}
- // Обрабатываем результаты
+ // ???????????? ??????????
postProcess(boxes);
// === DEBUG WINDOW ===
if (debug_show_window) {
cv::Mat dbg = bgr.clone();
- // Рисуем контуры на изображении для отладки
+ // ?????? ??????? ?? ??????????? ??? ???????
cv::drawContours(dbg, contours, -1, { 0, 0, 255 }, 1);
- // Рисуем прямоугольники для каждого найденного объекта
+ // ?????? ?????????????? ??? ??????? ?????????? ???????
for (auto& b : boxes) {
cv::rectangle(dbg, b, debug_bgr, 2);
}
- // Показываем FPS
+ // ?????????? FPS
if (debug_show_fps) {
auto now = std::chrono::steady_clock::now();
double dt = std::chrono::duration(now - dbg_prev_ts).count();
@@ -185,7 +185,7 @@ void ColorDetector::detectColors(const cv::Mat& frame) {
cv::putText(dbg, buf, { 10, 30 }, cv::FONT_HERSHEY_SIMPLEX, 0.8, debug_bgr, 2);
}
- // Показываем изображение с отрисованными результатами
+ // ?????????? ??????????? ? ????????????? ????????????
cv::imshow(debug_window_name, dbg);
cv::waitKey(1);
}
diff --git a/sunone_aimbot_cpp/detector/color_detector.h b/RN_AI_cpp/detector/color_detector.h
similarity index 100%
rename from sunone_aimbot_cpp/detector/color_detector.h
rename to RN_AI_cpp/detector/color_detector.h
diff --git a/sunone_aimbot_cpp/detector/cuda_12_8_fused_preprocess.cu b/RN_AI_cpp/detector/cuda_12_8_fused_preprocess.cu
similarity index 100%
rename from sunone_aimbot_cpp/detector/cuda_12_8_fused_preprocess.cu
rename to RN_AI_cpp/detector/cuda_12_8_fused_preprocess.cu
diff --git a/sunone_aimbot_cpp/detector/detection_buffer.cpp b/RN_AI_cpp/detector/detection_buffer.cpp
similarity index 100%
rename from sunone_aimbot_cpp/detector/detection_buffer.cpp
rename to RN_AI_cpp/detector/detection_buffer.cpp
diff --git a/sunone_aimbot_cpp/detector/detection_buffer.h b/RN_AI_cpp/detector/detection_buffer.h
similarity index 100%
rename from sunone_aimbot_cpp/detector/detection_buffer.h
rename to RN_AI_cpp/detector/detection_buffer.h
diff --git a/sunone_aimbot_cpp/detector/detector.zip b/RN_AI_cpp/detector/detector.zip
similarity index 100%
rename from sunone_aimbot_cpp/detector/detector.zip
rename to RN_AI_cpp/detector/detector.zip
diff --git a/sunone_aimbot_cpp/detector/dml_detector.cpp b/RN_AI_cpp/detector/dml_detector.cpp
similarity index 95%
rename from sunone_aimbot_cpp/detector/dml_detector.cpp
rename to RN_AI_cpp/detector/dml_detector.cpp
index 46caebf9..e227732d 100644
--- a/sunone_aimbot_cpp/detector/dml_detector.cpp
+++ b/RN_AI_cpp/detector/dml_detector.cpp
@@ -11,7 +11,7 @@
#include
#include "dml_detector.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "postProcess.h"
#include "capture.h"
@@ -232,7 +232,11 @@ void DirectMLDetector::dmlInferenceThread()
const std::vector& detections = detectionsBatch.back();
auto end = std::chrono::steady_clock::now();
+ lastPreprocessTimeDML = std::chrono::duration(0.0);
lastInferenceTimeDML = end - start;
+ lastCopyTimeDML = std::chrono::duration(0.0);
+ lastPostprocessTimeDML = std::chrono::duration(0.0);
+ lastNmsTimeDML = std::chrono::duration(0.0);
std::lock_guard lock(detectionBuffer.mutex);
detectionBuffer.boxes.clear();
@@ -245,4 +249,4 @@ void DirectMLDetector::dmlInferenceThread()
detectionBuffer.cv.notify_all();
}
}
-}
\ No newline at end of file
+}
diff --git a/sunone_aimbot_cpp/detector/dml_detector.h b/RN_AI_cpp/detector/dml_detector.h
similarity index 79%
rename from sunone_aimbot_cpp/detector/dml_detector.h
rename to RN_AI_cpp/detector/dml_detector.h
index e08f4920..cec6901c 100644
--- a/sunone_aimbot_cpp/detector/dml_detector.h
+++ b/RN_AI_cpp/detector/dml_detector.h
@@ -21,7 +21,11 @@ class DirectMLDetector
int getNumberOfClasses();
+ std::chrono::duration lastPreprocessTimeDML;
std::chrono::duration lastInferenceTimeDML;
+ std::chrono::duration lastCopyTimeDML;
+ std::chrono::duration lastPostprocessTimeDML;
+ std::chrono::duration lastNmsTimeDML;
std::condition_variable inferenceCV;
std::atomic shouldExit = false;
@@ -43,4 +47,4 @@ class DirectMLDetector
Ort::MemoryInfo memory_info;
};
-#endif // DIRECTML_DETECTOR_H
\ No newline at end of file
+#endif // DIRECTML_DETECTOR_H
diff --git a/sunone_aimbot_cpp/detector/fused_preprocess.h b/RN_AI_cpp/detector/fused_preprocess.h
similarity index 100%
rename from sunone_aimbot_cpp/detector/fused_preprocess.h
rename to RN_AI_cpp/detector/fused_preprocess.h
diff --git a/sunone_aimbot_cpp/detector/postProcess.cpp b/RN_AI_cpp/detector/postProcess.cpp
similarity index 99%
rename from sunone_aimbot_cpp/detector/postProcess.cpp
rename to RN_AI_cpp/detector/postProcess.cpp
index ade514fe..c7deabc0 100644
--- a/sunone_aimbot_cpp/detector/postProcess.cpp
+++ b/RN_AI_cpp/detector/postProcess.cpp
@@ -3,7 +3,7 @@
#include
#include "postProcess.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#ifdef USE_CUDA
#include "trt_detector.h"
#endif
diff --git a/sunone_aimbot_cpp/detector/postProcess.h b/RN_AI_cpp/detector/postProcess.h
similarity index 100%
rename from sunone_aimbot_cpp/detector/postProcess.h
rename to RN_AI_cpp/detector/postProcess.h
diff --git a/sunone_aimbot_cpp/detector/sunone_aimbot_cpp.cpp b/RN_AI_cpp/detector/rn_ai_cpp.cpp
similarity index 99%
rename from sunone_aimbot_cpp/detector/sunone_aimbot_cpp.cpp
rename to RN_AI_cpp/detector/rn_ai_cpp.cpp
index 9d1c13c8..4f391c75 100644
--- a/sunone_aimbot_cpp/detector/sunone_aimbot_cpp.cpp
+++ b/RN_AI_cpp/detector/rn_ai_cpp.cpp
@@ -1,4 +1,4 @@
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define _WINSOCKAPI_
#include
#include
@@ -13,7 +13,7 @@
#include "capture.h"
#include "mouse.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "keyboard_listener.h"
#include "overlay.h"
#include "other_tools.h"
diff --git a/sunone_aimbot_cpp/detector/trt_detector.cpp b/RN_AI_cpp/detector/trt_detector.cpp
similarity index 90%
rename from sunone_aimbot_cpp/detector/trt_detector.cpp
rename to RN_AI_cpp/detector/trt_detector.cpp
index f3f0348d..8d872e87 100644
--- a/sunone_aimbot_cpp/detector/trt_detector.cpp
+++ b/RN_AI_cpp/detector/trt_detector.cpp
@@ -20,7 +20,7 @@
#include "trt_detector.h"
#include "nvinf.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "other_tools.h"
#include "postProcess.h"
#include "fused_preprocess.h"
@@ -39,7 +39,8 @@ TrtDetector::TrtDetector()
shouldExit(false),
inputBufferDevice(nullptr),
img_scale(1.0f),
- numClasses(0)
+ numClasses(0),
+ pendingFrameType(PendingFrameType::None)
{
cudaStreamCreate(&stream);
cudaEventCreate(&inferStartEvent);
@@ -429,6 +430,28 @@ void TrtDetector::processFrame(const cv::Mat& frame)
std::unique_lock lock(inferenceMutex);
currentFrame = frame.clone();
+ currentFrameGpu.release();
+ pendingFrameType = PendingFrameType::Cpu;
+ frameReady = true;
+ inferenceCV.notify_one();
+}
+
+void TrtDetector::processFrameGpu(const cv::cuda::GpuMat& frame)
+{
+ if (config.backend == "DML") return;
+
+ if (detectionPaused)
+ {
+ std::lock_guard lock(detectionBuffer.mutex);
+ detectionBuffer.boxes.clear();
+ detectionBuffer.classes.clear();
+ return;
+ }
+
+ std::unique_lock lock(inferenceMutex);
+ currentFrame.release();
+ currentFrameGpu = frame;
+ pendingFrameType = PendingFrameType::Gpu;
frameReady = true;
inferenceCV.notify_one();
}
@@ -449,6 +472,10 @@ void TrtDetector::inferenceThread()
for (auto& binding : outputBindings)
if (binding.second) cudaFree(binding.second);
outputBindings.clear();
+ currentFrame.release();
+ currentFrameGpu.release();
+ frameReady = false;
+ pendingFrameType = PendingFrameType::None;
}
initialize("models/" + config.ai_model);
detection_resolution_changed.store(true);
@@ -456,6 +483,8 @@ void TrtDetector::inferenceThread()
}
cv::Mat frame;
+ cv::cuda::GpuMat frameGpu;
+ PendingFrameType frameType = PendingFrameType::None;
bool hasNewFrame = false;
{
@@ -467,7 +496,19 @@ void TrtDetector::inferenceThread()
if (frameReady)
{
- frame = std::move(currentFrame);
+ frameType = pendingFrameType;
+ if (frameType == PendingFrameType::Gpu)
+ {
+ frameGpu = currentFrameGpu;
+ currentFrameGpu.release();
+ currentFrame.release();
+ }
+ else
+ {
+ frame = std::move(currentFrame);
+ currentFrameGpu.release();
+ }
+ pendingFrameType = PendingFrameType::None;
frameReady = false;
hasNewFrame = true;
}
@@ -488,12 +529,19 @@ void TrtDetector::inferenceThread()
error_logged = false;
}
- if (hasNewFrame && !frame.empty())
+ if (hasNewFrame)
{
+ const bool hasCpuFrame = (frameType == PendingFrameType::Cpu && !frame.empty());
+ const bool hasGpuFrame = (frameType == PendingFrameType::Gpu && !frameGpu.empty());
+ if (!hasCpuFrame && !hasGpuFrame)
+ continue;
try
{
auto t0 = std::chrono::steady_clock::now();
- preProcess(frame);
+ if (hasGpuFrame)
+ preProcess(frameGpu);
+ else
+ preProcess(frame);
auto t1 = std::chrono::steady_clock::now();
if (useCudaGraph && !cudaGraphCaptured)
@@ -715,6 +763,15 @@ void TrtDetector::preProcess(const cv::Mat& frame)
{
if (frame.empty()) return;
+ cv::cuda::Stream cvStream = cv::cuda::StreamAccessor::wrapStream(stream);
+ gpuFrame.upload(frame, cvStream);
+ preProcess(gpuFrame);
+}
+
+void TrtDetector::preProcess(const cv::cuda::GpuMat& frame)
+{
+ if (frame.empty()) return;
+
void* inputBuffer = inputBindings[inputName];
if (!inputBuffer) return;
@@ -722,21 +779,24 @@ void TrtDetector::preProcess(const cv::Mat& frame)
int h = dims.d[2];
int w = dims.d[3];
- cv::cuda::Stream cvStream = cv::cuda::StreamAccessor::wrapStream(stream);
- gpuFrame.upload(frame, cvStream);
-
const cv::cuda::GpuMat* src = &gpuFrame;
if (frame.channels() == 4)
{
- cv::cuda::cvtColor(gpuFrame, gpuBgr, cv::COLOR_BGRA2BGR, 0, cvStream);
+ cv::cuda::Stream cvStream = cv::cuda::StreamAccessor::wrapStream(stream);
+ cv::cuda::cvtColor(frame, gpuBgr, cv::COLOR_BGRA2BGR, 0, cvStream);
src = &gpuBgr;
}
else if (frame.channels() == 1)
{
- cv::cuda::cvtColor(gpuFrame, gpuBgr, cv::COLOR_GRAY2BGR, 0, cvStream);
+ cv::cuda::Stream cvStream = cv::cuda::StreamAccessor::wrapStream(stream);
+ cv::cuda::cvtColor(frame, gpuBgr, cv::COLOR_GRAY2BGR, 0, cvStream);
src = &gpuBgr;
}
- else if (frame.channels() != 3)
+ else if (frame.channels() == 3)
+ {
+ src = &frame;
+ }
+ else
{
return;
}
diff --git a/sunone_aimbot_cpp/detector/trt_detector.h b/RN_AI_cpp/detector/trt_detector.h
similarity index 90%
rename from sunone_aimbot_cpp/detector/trt_detector.h
rename to RN_AI_cpp/detector/trt_detector.h
index fa0e941a..a11e06ed 100644
--- a/sunone_aimbot_cpp/detector/trt_detector.h
+++ b/RN_AI_cpp/detector/trt_detector.h
@@ -28,6 +28,7 @@ class TrtDetector
~TrtDetector();
void initialize(const std::string& modelFile);
void processFrame(const cv::Mat& frame);
+ void processFrameGpu(const cv::cuda::GpuMat& frame);
void inferenceThread();
float img_scale;
@@ -67,11 +68,21 @@ class TrtDetector
std::condition_variable inferenceCV;
std::atomic shouldExit;
cv::Mat currentFrame;
+ cv::cuda::GpuMat currentFrameGpu;
bool frameReady;
+ enum class PendingFrameType
+ {
+ None = 0,
+ Cpu = 1,
+ Gpu = 2
+ };
+ PendingFrameType pendingFrameType = PendingFrameType::None;
+
void loadEngine(const std::string& engineFile);
void preProcess(const cv::Mat& frame);
+ void preProcess(const cv::cuda::GpuMat& frame);
void postProcess(
const float* output,
diff --git a/RN_AI_cpp/imgui.ini b/RN_AI_cpp/imgui.ini
new file mode 100644
index 00000000..d1fd161e
--- /dev/null
+++ b/RN_AI_cpp/imgui.ini
@@ -0,0 +1,22 @@
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+
+[Window][Options]
+Pos=0,0
+Size=1448,1022
+
+[Table][0xA73256D8,4]
+RefScale=30.42
+Column 0 Width=94
+Column 1 Weight=1.0000
+Column 2 Width=365
+Column 3 Width=650
+
+[Table][0xCB8CBC28,4]
+RefScale=26.91
+Column 0 Width=90
+Column 1 Weight=1.0000
+Column 2 Width=90
+Column 3 Width=90
+
diff --git a/sunone_aimbot_cpp/imgui/imconfig.h b/RN_AI_cpp/imgui/imconfig.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imconfig.h
rename to RN_AI_cpp/imgui/imconfig.h
diff --git a/sunone_aimbot_cpp/imgui/imgui.cpp b/RN_AI_cpp/imgui/imgui.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui.cpp
rename to RN_AI_cpp/imgui/imgui.cpp
diff --git a/sunone_aimbot_cpp/imgui/imgui.h b/RN_AI_cpp/imgui/imgui.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui.h
rename to RN_AI_cpp/imgui/imgui.h
diff --git a/sunone_aimbot_cpp/imgui/imgui_draw.cpp b/RN_AI_cpp/imgui/imgui_draw.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_draw.cpp
rename to RN_AI_cpp/imgui/imgui_draw.cpp
diff --git a/sunone_aimbot_cpp/imgui/imgui_impl_dx11.cpp b/RN_AI_cpp/imgui/imgui_impl_dx11.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_impl_dx11.cpp
rename to RN_AI_cpp/imgui/imgui_impl_dx11.cpp
diff --git a/sunone_aimbot_cpp/imgui/imgui_impl_dx11.h b/RN_AI_cpp/imgui/imgui_impl_dx11.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_impl_dx11.h
rename to RN_AI_cpp/imgui/imgui_impl_dx11.h
diff --git a/sunone_aimbot_cpp/imgui/imgui_impl_win32.cpp b/RN_AI_cpp/imgui/imgui_impl_win32.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_impl_win32.cpp
rename to RN_AI_cpp/imgui/imgui_impl_win32.cpp
diff --git a/sunone_aimbot_cpp/imgui/imgui_impl_win32.h b/RN_AI_cpp/imgui/imgui_impl_win32.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_impl_win32.h
rename to RN_AI_cpp/imgui/imgui_impl_win32.h
diff --git a/sunone_aimbot_cpp/imgui/imgui_internal.h b/RN_AI_cpp/imgui/imgui_internal.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_internal.h
rename to RN_AI_cpp/imgui/imgui_internal.h
diff --git a/sunone_aimbot_cpp/imgui/imgui_tables.cpp b/RN_AI_cpp/imgui/imgui_tables.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_tables.cpp
rename to RN_AI_cpp/imgui/imgui_tables.cpp
diff --git a/sunone_aimbot_cpp/imgui/imgui_widgets.cpp b/RN_AI_cpp/imgui/imgui_widgets.cpp
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imgui_widgets.cpp
rename to RN_AI_cpp/imgui/imgui_widgets.cpp
diff --git a/sunone_aimbot_cpp/imgui/imstb_rectpack.h b/RN_AI_cpp/imgui/imstb_rectpack.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imstb_rectpack.h
rename to RN_AI_cpp/imgui/imstb_rectpack.h
diff --git a/sunone_aimbot_cpp/imgui/imstb_textedit.h b/RN_AI_cpp/imgui/imstb_textedit.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imstb_textedit.h
rename to RN_AI_cpp/imgui/imstb_textedit.h
diff --git a/sunone_aimbot_cpp/imgui/imstb_truetype.h b/RN_AI_cpp/imgui/imstb_truetype.h
similarity index 100%
rename from sunone_aimbot_cpp/imgui/imstb_truetype.h
rename to RN_AI_cpp/imgui/imstb_truetype.h
diff --git a/sunone_aimbot_cpp/include/memory_images.h b/RN_AI_cpp/include/memory_images.h
similarity index 100%
rename from sunone_aimbot_cpp/include/memory_images.h
rename to RN_AI_cpp/include/memory_images.h
diff --git a/sunone_aimbot_cpp/include/other_tools.h b/RN_AI_cpp/include/other_tools.h
similarity index 100%
rename from sunone_aimbot_cpp/include/other_tools.h
rename to RN_AI_cpp/include/other_tools.h
diff --git a/sunone_aimbot_cpp/keyboard/keyboard_listener.cpp b/RN_AI_cpp/keyboard/keyboard_listener.cpp
similarity index 68%
rename from sunone_aimbot_cpp/keyboard/keyboard_listener.cpp
rename to RN_AI_cpp/keyboard/keyboard_listener.cpp
index 91810536..f83f0d9e 100644
--- a/sunone_aimbot_cpp/keyboard/keyboard_listener.cpp
+++ b/RN_AI_cpp/keyboard/keyboard_listener.cpp
@@ -1,4 +1,4 @@
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define _WINSOCKAPI_
#include
#include
@@ -13,7 +13,7 @@
#include "keyboard_listener.h"
#include "mouse.h"
#include "keycodes.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "capture.h"
#include "KmboxNetConnection.h"
@@ -45,6 +45,12 @@ bool prevRightArrow = false;
bool isAnyKeyPressed(const std::vector& keys)
{
+ bool usePhysicalDevice =
+ (kmboxNetSerial && kmboxNetSerial->isOpen()) ||
+ (kmboxSerial && kmboxSerial->isOpen()) ||
+ (makcu_conn && makcu_conn->isOpen()) ||
+ (config.arduino_enable_keys && arduinoSerial && arduinoSerial->isOpen());
+
for (const auto& key_name : keys)
{
int key_code = KeyCodes::getKeyCode(key_name);
@@ -61,15 +67,54 @@ bool isAnyKeyPressed(const std::vector& keys)
else if(key_name == "X2MouseButton") pressed = kmboxNetSerial->monitorMouseSide2() == 1;
}
- // local mouse
- if (!pressed && key_code != -1 && (GetAsyncKeyState(key_code) & 0x8000))
- pressed = true;
+ // kmbox_b button monitor
+ if (!pressed && kmboxSerial && kmboxSerial->isOpen())
+ {
+ if (key_name == "LeftMouseButton") pressed = kmboxSerial->left_active;
+ else if(key_name == "RightMouseButton") pressed = kmboxSerial->right_active;
+ else if(key_name == "MiddleMouseButton") pressed = kmboxSerial->middle_active;
+ else if(key_name == "X1MouseButton") pressed = kmboxSerial->side1_active;
+ else if(key_name == "X2MouseButton") pressed = kmboxSerial->side2_active;
+ }
+
+ // makcu button monitor
+ if (!pressed && makcu_conn && makcu_conn->isOpen())
+ {
+ if (key_name == "LeftMouseButton") pressed = makcu_conn->left_active;
+ else if(key_name == "RightMouseButton") pressed = makcu_conn->right_active;
+ else if(key_name == "MiddleMouseButton") pressed = makcu_conn->middle_active;
+ else if(key_name == "X1MouseButton") pressed = makcu_conn->side1_active;
+ else if(key_name == "X2MouseButton") pressed = makcu_conn->side2_active;
+ }
+
+ // arduino button monitor
+ if (!pressed && config.arduino_enable_keys && arduinoSerial && arduinoSerial->isOpen())
+ {
+ if (key_name == "LeftMouseButton") pressed = arduinoSerial->shooting_active;
+ else if(key_name == "RightMouseButton") pressed = arduinoSerial->zooming_active;
+ else if(key_name == "X2MouseButton") pressed = arduinoSerial->aiming_active;
+ }
+
+ // local win32 keyboard/mouse
+ if (!pressed && key_code != -1)
+ {
+ const bool is_mouse_key =
+ (key_name == "LeftMouseButton") ||
+ (key_name == "RightMouseButton") ||
+ (key_name == "MiddleMouseButton") ||
+ (key_name == "X1MouseButton") ||
+ (key_name == "X2MouseButton");
+
+ if (!is_mouse_key || !usePhysicalDevice)
+ {
+ pressed = (GetAsyncKeyState(key_code) & 0x8000) != 0;
+ }
+ }
if (pressed) return true;
}
return false;
}
-
void keyboardListener()
{
while (!shouldExit)
@@ -77,33 +122,22 @@ void keyboardListener()
// Aiming
if (!config.auto_aim)
{
- aiming = isAnyKeyPressed(config.button_targeting) ||
- (config.arduino_enable_keys && arduinoSerial && arduinoSerial->isOpen() && arduinoSerial->aiming_active) ||
- (kmboxSerial && kmboxSerial->isOpen() && kmboxSerial->aiming_active) ||
- (kmboxNetSerial && kmboxNetSerial->isOpen() && kmboxNetSerial->aiming_active);
+ // Respect only configured targeting keys (from UI/config).
+ aiming = isAnyKeyPressed(config.button_targeting);
}
else
{
aiming = true;
}
- // Shooting
- shooting = isAnyKeyPressed(config.button_shoot) ||
- (config.arduino_enable_keys && arduinoSerial && arduinoSerial->isOpen() && arduinoSerial->shooting_active) ||
- (kmboxSerial && kmboxSerial->isOpen() && kmboxSerial->shooting_active) ||
- (kmboxNetSerial && kmboxNetSerial->isOpen() && kmboxNetSerial->shooting_active);
+ // Respect only configured key lists for shoot/zoom as well.
+ shooting = isAnyKeyPressed(config.button_shoot);
+ zooming = isAnyKeyPressed(config.button_zoom);
- // Zooming
- zooming = isAnyKeyPressed(config.button_zoom) ||
- (config.arduino_enable_keys && arduinoSerial && arduinoSerial->isOpen() && arduinoSerial->zooming_active) ||
- (kmboxSerial && kmboxSerial->isOpen() && kmboxSerial->zooming_active);
-
- // Triggerbot button (клавиатура/макку дополняют состояние, которое ставит kmbox_b)
+ // Triggerbot button should reflect current physical state (no latch).
{
- const bool kb_trigger = isAnyKeyPressed(config.button_triggerbot);
- const bool makcu_trigger = (makcu && makcu->isOpen() && makcu->triggerbot_active);
- const bool current = triggerbot_button.load();
- triggerbot_button = current || kb_trigger || makcu_trigger;
+ const bool trigger_pressed = isAnyKeyPressed(config.button_triggerbot);
+ triggerbot_button.store(trigger_pressed);
}
// Disable Headshot toggle
@@ -234,3 +268,7 @@ void keyboardListener()
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
+
+
+
+
diff --git a/sunone_aimbot_cpp/keyboard/keyboard_listener.h b/RN_AI_cpp/keyboard/keyboard_listener.h
similarity index 100%
rename from sunone_aimbot_cpp/keyboard/keyboard_listener.h
rename to RN_AI_cpp/keyboard/keyboard_listener.h
diff --git a/sunone_aimbot_cpp/keyboard/keycodes.cpp b/RN_AI_cpp/keyboard/keycodes.cpp
similarity index 100%
rename from sunone_aimbot_cpp/keyboard/keycodes.cpp
rename to RN_AI_cpp/keyboard/keycodes.cpp
diff --git a/sunone_aimbot_cpp/keyboard/keycodes.h b/RN_AI_cpp/keyboard/keycodes.h
similarity index 100%
rename from sunone_aimbot_cpp/keyboard/keycodes.h
rename to RN_AI_cpp/keyboard/keycodes.h
diff --git a/sunone_aimbot_cpp/manual_map_injector.cpp b/RN_AI_cpp/manual_map_injector.cpp
similarity index 100%
rename from sunone_aimbot_cpp/manual_map_injector.cpp
rename to RN_AI_cpp/manual_map_injector.cpp
diff --git a/RN_AI_cpp/models/sunxds_0.5.6.engine b/RN_AI_cpp/models/sunxds_0.5.6.engine
new file mode 100644
index 00000000..155d9c86
Binary files /dev/null and b/RN_AI_cpp/models/sunxds_0.5.6.engine differ
diff --git a/RN_AI_cpp/models/sunxds_0.5.6.onnx b/RN_AI_cpp/models/sunxds_0.5.6.onnx
new file mode 100644
index 00000000..96bcc324
Binary files /dev/null and b/RN_AI_cpp/models/sunxds_0.5.6.onnx differ
diff --git a/RN_AI_cpp/models/sunxds_0.7.6.engine b/RN_AI_cpp/models/sunxds_0.7.6.engine
new file mode 100644
index 00000000..fe640d7c
Binary files /dev/null and b/RN_AI_cpp/models/sunxds_0.7.6.engine differ
diff --git a/RN_AI_cpp/models/sunxds_0.7.6.onnx b/RN_AI_cpp/models/sunxds_0.7.6.onnx
new file mode 100644
index 00000000..2776bec5
Binary files /dev/null and b/RN_AI_cpp/models/sunxds_0.7.6.onnx differ
diff --git a/sunone_aimbot_cpp/mouse/AimbotTarget.cpp b/RN_AI_cpp/mouse/AimbotTarget.cpp
similarity index 99%
rename from sunone_aimbot_cpp/mouse/AimbotTarget.cpp
rename to RN_AI_cpp/mouse/AimbotTarget.cpp
index 9eeb753b..c5f6977f 100644
--- a/sunone_aimbot_cpp/mouse/AimbotTarget.cpp
+++ b/RN_AI_cpp/mouse/AimbotTarget.cpp
@@ -7,7 +7,7 @@
#include
#include
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "AimbotTarget.h"
#include "config.h"
diff --git a/sunone_aimbot_cpp/mouse/AimbotTarget.h b/RN_AI_cpp/mouse/AimbotTarget.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/AimbotTarget.h
rename to RN_AI_cpp/mouse/AimbotTarget.h
diff --git a/sunone_aimbot_cpp/mouse/Kmbox_b.cpp b/RN_AI_cpp/mouse/Kmbox_b.cpp
similarity index 70%
rename from sunone_aimbot_cpp/mouse/Kmbox_b.cpp
rename to RN_AI_cpp/mouse/Kmbox_b.cpp
index 5e711501..671867d3 100644
--- a/sunone_aimbot_cpp/mouse/Kmbox_b.cpp
+++ b/RN_AI_cpp/mouse/Kmbox_b.cpp
@@ -8,13 +8,13 @@
#include "Kmbox_b.h"
#include "config.h"
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
-/* ---------------- Makcu-константы ---------------- */
-static const uint32_t BOOT_BAUD = 115200; // при подключении
-static const uint32_t WORK_BAUD = 4000000; // рабочая 4 Мбит/с
+/* ---------------- Makcu-????????? ---------------- */
+static const uint32_t BOOT_BAUD = 115200; // ??? ???????????
+static const uint32_t WORK_BAUD = 4000000; // ??????? 4 ????/?
-/* секретный пакет смены скорости */
+/* ????????? ????? ????? ???????? */
static const uint8_t BAUD_CHANGE_CMD[9] =
{ 0xDE,0xAD,0x05,0x00,0xA5,0x00,0x09,0x3D,0x00 };
@@ -25,22 +25,27 @@ KmboxConnection::KmboxConnection(const std::string& port, unsigned int /*baud_ra
listening_(false),
aiming_active(false),
shooting_active(false),
- zooming_active(false)
+ zooming_active(false),
+ side1_active(false),
+ side2_active(false),
+ left_active(false),
+ right_active(false),
+ middle_active(false)
{
try {
- /* 1. открываем порт @115 200 */
+ /* 1. ????????? ???? @115 200 */
serial_.setPort(port);
serial_.setBaudrate(BOOT_BAUD);
serial_.open();
if (!serial_.isOpen())
throw std::runtime_error("open failed");
- /* 2. посылаем пакет — MCU перезапускается @4 Мбит */
+ /* 2. ???????? ????? — MCU ??????????????? @4 ???? */
serial_.write(BAUD_CHANGE_CMD, sizeof(BAUD_CHANGE_CMD));
serial_.close();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
- /* 3. открываем заново @4 Мбит */
+ /* 3. ????????? ?????? @4 ???? */
serial_.setBaudrate(WORK_BAUD);
serial_.open();
if (!serial_.isOpen())
@@ -49,7 +54,7 @@ KmboxConnection::KmboxConnection(const std::string& port, unsigned int /*baud_ra
is_open_ = true;
std::cout << "[Makcu] Connected @4 Mbps on " << port << '\n';
- /* 4. убираем echo и включаем поток кнопок */
+ /* 4. ??????? echo ? ???????? ????? ?????? */
sendCommand("km.echo(0)");
sendCommand("km.buttons(1)");
@@ -97,7 +102,7 @@ std::string KmboxConnection::read()
return {};
}
-/* --- команды km.* ---------------------------------------------------- */
+/* --- ??????? km.* ---------------------------------------------------- */
void KmboxConnection::move(int x, int y)
{
@@ -133,7 +138,7 @@ void KmboxConnection::sendCommand(const std::string& cmd) { write(cmd + "\r\n");
std::vector KmboxConnection::splitValue(int value) { return {}; }
-/* --------------------------- Слушатель -------------------------- */
+/* --------------------------- ????????? -------------------------- */
void KmboxConnection::startListening()
{
@@ -145,14 +150,8 @@ void KmboxConnection::startListening()
void KmboxConnection::listeningThreadFunc()
{
- // биты 0..5: ЛКМ/ПКМ/СКМ/Side4/Side5 (+ запас 0x20)
- constexpr uint8_t button_mask = 0x3F;
- auto popcount8 = [](uint8_t v) {
- v = (v & 0x55) + ((v >> 1) & 0x55);
- v = (v & 0x33) + ((v >> 2) & 0x33);
- return static_cast((v + (v >> 4)) & 0x0F);
- };
- uint8_t last_buttons = 0;
+ // allowed bits: 0x01 (LMB), 0x02 (RMB), 0x10 (side2)
+ constexpr uint8_t allowed_mask = 0x01 | 0x02 | 0x10;
while (listening_ && is_open_) {
try {
@@ -163,30 +162,25 @@ void KmboxConnection::listeningThreadFunc()
uint8_t b = 0;
serial_.read(&b, 1);
- const uint8_t filtered = b & button_mask;
- const int bit_cnt = popcount8(filtered);
- const bool valid_empty = filtered == 0x00;
- const bool valid_single = (filtered <= 0x1F) && (bit_cnt == 1);
-
- if (valid_empty) {
- last_buttons = 0;
- }
- else if (valid_single) {
- last_buttons = filtered;
- }
- else {
- // шумовой пакет — не трогаем состояние
+ // drop byte if it contains unexpected bits
+ if (b & ~allowed_mask)
continue;
- }
- /* обновляем флаги */
- shooting_active = last_buttons & 0x01; // ЛКМ
- aiming_active = last_buttons & 0x10; // боковая (mouse5)
- triggerbot_button.store(static_cast(last_buttons & 0x08)); // mouse4 -> триггербот
+ // update state flags
+ shooting_active = (b & 0x01) != 0; // LMB
+ zooming_active = (b & 0x02) != 0; // RMB
+ aiming_active = (b & 0x10) != 0; // side2
+
+ left_active = shooting_active;
+ right_active = zooming_active;
+ middle_active = false;
+ side1_active = false;
+ side2_active = aiming_active;
+
shooting.store(shooting_active);
aiming.store(aiming_active);
- /* отладочный вывод */
+ // debug output
std::cout << "LMB: " << (shooting_active ? "PRESS" : "release")
<< " | SIDE: " << (aiming_active ? "PRESS" : "release")
<< '\n';
@@ -195,7 +189,7 @@ void KmboxConnection::listeningThreadFunc()
}
}
-/* ---------- старый парсер строк (остаётся без изменений) ------------- */
+/* ---------- ?????? ?????? ????? (???????? ??? ?????????) ------------- */
void KmboxConnection::processIncomingLine(const std::string& line)
{
try {
diff --git a/sunone_aimbot_cpp/mouse/Kmbox_b.h b/RN_AI_cpp/mouse/Kmbox_b.h
similarity index 90%
rename from sunone_aimbot_cpp/mouse/Kmbox_b.h
rename to RN_AI_cpp/mouse/Kmbox_b.h
index bd0e101b..e0b22c9a 100644
--- a/sunone_aimbot_cpp/mouse/Kmbox_b.h
+++ b/RN_AI_cpp/mouse/Kmbox_b.h
@@ -35,6 +35,11 @@ class KmboxConnection
bool aiming_active;
bool shooting_active;
bool zooming_active;
+ bool side1_active;
+ bool side2_active;
+ bool left_active;
+ bool right_active;
+ bool middle_active;
private:
void sendCommand(const std::string& command);
@@ -53,3 +58,6 @@ class KmboxConnection
};
#endif // KMBOXCONNECTION_H
+
+
+
diff --git a/RN_AI_cpp/mouse/MakcuConnection.cpp b/RN_AI_cpp/mouse/MakcuConnection.cpp
new file mode 100644
index 00000000..89776d79
--- /dev/null
+++ b/RN_AI_cpp/mouse/MakcuConnection.cpp
@@ -0,0 +1,691 @@
+#define WIN32_LEAN_AND_MEAN
+#define _WINSOCKAPI_
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "MakcuConnection.h"
+#include "config.h"
+#include "rn_ai_cpp.h"
+#ifdef makcu
+#undef makcu
+#endif
+
+namespace {
+std::mutex g_makcu_state_log_mutex;
+
+void logMakcuButtons(const char* source, const MakcuConnection& connection, int raw_value = -1)
+{
+ std::lock_guard lock(g_makcu_state_log_mutex);
+ std::cout << "[Makcu][" << source << "]";
+ if (raw_value >= 0) {
+ std::cout << " raw=" << raw_value;
+ }
+ std::cout
+ << " L=" << (connection.left_active ? 1 : 0)
+ << " R=" << (connection.right_active ? 1 : 0)
+ << " M=" << (connection.middle_active ? 1 : 0)
+ << " S1=" << (connection.side1_active ? 1 : 0)
+ << " S2=" << (connection.side2_active ? 1 : 0)
+ << " shoot=" << (connection.shooting_active ? 1 : 0)
+ << " aim=" << (connection.aiming_active ? 1 : 0)
+ << " zoom=" << (connection.zooming_active ? 1 : 0)
+ << " trig=" << (connection.triggerbot_active ? 1 : 0)
+ << std::endl;
+}
+} // namespace
+
+#if RN_MAKCU_SDK_AVAILABLE
+
+MakcuConnection::MakcuConnection(const std::string& port, unsigned int baud_rate)
+ : is_open_(false)
+ , sdk_listening_(false)
+ , aiming_active(false)
+ , shooting_active(false)
+ , zooming_active(false)
+ , triggerbot_active(false)
+ , side1_active(false)
+ , side2_active(false)
+ , left_active(false)
+ , right_active(false)
+ , middle_active(false)
+{
+ try
+ {
+ device_.setMouseButtonCallback([this](makcu::MouseButton button, bool pressed) {
+ onButtonCallback(button, pressed);
+ });
+
+ device_.enableButtonMonitoring(true);
+
+ if (device_.connect(port))
+ {
+ if (baud_rate > 0)
+ {
+ if (!device_.setBaudRate(baud_rate, true))
+ {
+ std::cerr << "[Makcu] Failed to set baud rate to " << baud_rate
+ << ", continuing with current baud rate." << std::endl;
+ }
+ }
+
+ is_open_ = true;
+ std::cout << "[Makcu] Connected! PORT: " << port << std::endl;
+ startSdkPolling();
+ }
+ else
+ {
+ std::cerr << "[Makcu] Unable to connect to the port: " << port << std::endl;
+ }
+ }
+ catch (const makcu::MakcuException& e)
+ {
+ std::cerr << "[Makcu] Error: " << e.what() << std::endl;
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "[Makcu] Error: " << e.what() << std::endl;
+ }
+}
+
+MakcuConnection::~MakcuConnection()
+{
+ stopSdkPolling();
+ try
+ {
+ device_.enableButtonMonitoring(false);
+ device_.disconnect();
+ }
+ catch (...)
+ {
+ }
+ is_open_ = false;
+}
+
+bool MakcuConnection::isOpen() const
+{
+ return is_open_ && device_.isConnected();
+}
+
+void MakcuConnection::write(const std::string&)
+{
+}
+
+std::string MakcuConnection::read()
+{
+ return std::string();
+}
+
+void MakcuConnection::move(int x, int y)
+{
+ if (!isOpen())
+ return;
+
+ std::lock_guard lock(write_mutex_);
+ try
+ {
+ device_.mouseMove(x, y);
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ }
+}
+
+makcu::MouseButton MakcuConnection::toMouseButton(int button) const
+{
+ switch (button)
+ {
+ case 1: return makcu::MouseButton::RIGHT;
+ case 2: return makcu::MouseButton::MIDDLE;
+ case 3: return makcu::MouseButton::SIDE1;
+ case 4: return makcu::MouseButton::SIDE2;
+ case 0:
+ default:
+ return makcu::MouseButton::LEFT;
+ }
+}
+
+void MakcuConnection::click(int button)
+{
+ if (!isOpen())
+ return;
+
+ std::lock_guard lock(write_mutex_);
+ try
+ {
+ device_.click(toMouseButton(button));
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ }
+}
+
+void MakcuConnection::press(int button)
+{
+ if (!isOpen())
+ return;
+
+ std::lock_guard lock(write_mutex_);
+ try
+ {
+ device_.mouseDown(toMouseButton(button));
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ }
+}
+
+void MakcuConnection::release(int button)
+{
+ if (!isOpen())
+ return;
+
+ std::lock_guard lock(write_mutex_);
+ try
+ {
+ device_.mouseUp(toMouseButton(button));
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ }
+}
+
+void MakcuConnection::start_boot()
+{
+}
+
+void MakcuConnection::reboot()
+{
+}
+
+void MakcuConnection::send_stop()
+{
+}
+
+void MakcuConnection::onButtonCallback(makcu::MouseButton button, bool pressed)
+{
+ switch (button)
+ {
+ case makcu::MouseButton::LEFT:
+ left_active = pressed;
+ shooting_active = pressed;
+ shooting.store(pressed);
+ break;
+
+ case makcu::MouseButton::RIGHT:
+ right_active = pressed;
+ zooming_active = pressed;
+ zooming.store(pressed);
+ break;
+
+ case makcu::MouseButton::MIDDLE:
+ middle_active = pressed;
+ break;
+
+ case makcu::MouseButton::SIDE1:
+ side1_active = pressed;
+ triggerbot_active = pressed;
+ triggerbot_button.store(pressed);
+ break;
+
+ case makcu::MouseButton::SIDE2:
+ side2_active = pressed;
+ aiming_active = pressed;
+ aiming.store(pressed);
+ break;
+
+ default:
+ break;
+ }
+
+ logMakcuButtons("callback", *this, static_cast(button));
+}
+
+void MakcuConnection::applyButtonMask(uint8_t mask, const char* source)
+{
+ left_active = (mask & 0x01) != 0;
+ right_active = (mask & 0x02) != 0;
+ middle_active = (mask & 0x04) != 0;
+ side1_active = (mask & 0x08) != 0;
+ side2_active = (mask & 0x10) != 0;
+
+ shooting_active = left_active;
+ zooming_active = right_active;
+ triggerbot_active = side1_active;
+ aiming_active = side2_active;
+
+ shooting.store(shooting_active);
+ zooming.store(zooming_active);
+ triggerbot_button.store(triggerbot_active);
+ aiming.store(aiming_active);
+
+ logMakcuButtons(source, *this, static_cast(mask));
+}
+
+void MakcuConnection::startSdkPolling()
+{
+ sdk_listening_ = true;
+ if (sdk_listening_thread_.joinable())
+ sdk_listening_thread_.join();
+ sdk_listening_thread_ = std::thread(&MakcuConnection::sdkPollingThreadFunc, this);
+}
+
+void MakcuConnection::stopSdkPolling()
+{
+ sdk_listening_ = false;
+ if (sdk_listening_thread_.joinable())
+ sdk_listening_thread_.join();
+}
+
+void MakcuConnection::sdkPollingThreadFunc()
+{
+ uint8_t last_mask = 0xFF;
+ while (sdk_listening_ && isOpen())
+ {
+ try
+ {
+ const uint8_t mask = device_.getButtonMask();
+ if (mask != last_mask)
+ {
+ applyButtonMask(mask, "sdk-mask");
+ last_mask = mask;
+ }
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+}
+
+#else
+
+/* ---------- Serial fallback constants ---------------------------- */
+static const uint32_t BOOT_BAUD = 115200;
+static const uint32_t WORK_BAUD = 4000000;
+static const uint8_t FRAME_START = 0x50;
+
+static const uint8_t BAUD_CHANGE_CMD[9] =
+{ 0xDE, 0xAD, 0x05, 0x00, 0xA5, 0x00, 0x09, 0x3D, 0x00 };
+
+static const uint8_t CMD_LEFT = 0x08;
+static const uint8_t CMD_RIGHT = 0x11;
+static const uint8_t CMD_MIDDLE = 0x0A;
+static const uint8_t CMD_SIDE1 = 0x12;
+static const uint8_t CMD_SIDE2 = 0x13;
+
+MakcuConnection::MakcuConnection(const std::string& port, unsigned int /*baud_rate*/)
+ : is_open_(false)
+ , listening_(false)
+ , aiming_active(false)
+ , shooting_active(false)
+ , zooming_active(false)
+ , triggerbot_active(false)
+ , side1_active(false)
+ , side2_active(false)
+ , left_active(false)
+ , right_active(false)
+ , middle_active(false)
+{
+ std::cerr << "[Makcu] SDK header not found. Using serial fallback (byte parser)." << std::endl;
+
+ try {
+ serial_.setPort(port);
+ serial_.setBaudrate(BOOT_BAUD);
+ serial_.open();
+ if (!serial_.isOpen())
+ throw std::runtime_error("open failed");
+
+ serial_.write(BAUD_CHANGE_CMD, sizeof(BAUD_CHANGE_CMD));
+ serial_.close();
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ serial_.setBaudrate(WORK_BAUD);
+ serial_.open();
+ if (!serial_.isOpen())
+ throw std::runtime_error("re-open @4M failed");
+
+ is_open_ = true;
+ std::cout << "[Makcu] Connected @4 Mbps on " << port << '\n';
+
+ sendCommand("km.echo(0)");
+ sendCommand("km.buttons(1)");
+
+ startListening();
+ }
+ catch (const std::exception& e) {
+ std::cerr << "[Makcu] Error: " << e.what() << '\n';
+ }
+}
+
+MakcuConnection::~MakcuConnection()
+{
+ listening_ = false;
+ if (serial_.isOpen()) {
+ try { serial_.close(); } catch (...) {}
+ }
+ if (listening_thread_.joinable())
+ listening_thread_.join();
+ is_open_ = false;
+}
+
+bool MakcuConnection::isOpen() const { return is_open_; }
+
+void MakcuConnection::write(const std::string& data)
+{
+ std::lock_guard lock(write_mutex_);
+ if (!is_open_) return;
+ try { serial_.write(data); }
+ catch (...) { is_open_ = false; }
+}
+
+std::string MakcuConnection::read()
+{
+ if (!is_open_)
+ return std::string();
+
+ std::string result;
+ try
+ {
+ result = serial_.readline(65536, "\n");
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ }
+ return result;
+}
+
+void MakcuConnection::move(int x, int y)
+{
+ if (!is_open_)
+ return;
+
+ std::string cmd = "km.move(" + std::to_string(x) + "," + std::to_string(y) + ")\r\n";
+ write(cmd);
+}
+
+void MakcuConnection::click(int button)
+{
+ (void)button;
+ sendCommand("km.click(0)");
+}
+
+void MakcuConnection::press(int button)
+{
+ (void)button;
+ sendCommand("km.left(1)");
+}
+
+void MakcuConnection::release(int button)
+{
+ (void)button;
+ sendCommand("km.left(0)");
+}
+
+void MakcuConnection::start_boot()
+{
+ write("\x03\x03");
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ write("exec(open('boot.py').read(),globals())\r\n");
+}
+
+void MakcuConnection::reboot()
+{
+ write("\x03\x03");
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ write("km.reboot()");
+}
+
+void MakcuConnection::send_stop()
+{
+ write("\x03\x03");
+}
+
+void MakcuConnection::writeBinaryCommand(uint8_t cmd, const std::vector& payload)
+{
+ if (!is_open_)
+ return;
+
+ const uint16_t len = static_cast(payload.size());
+ std::vector frame;
+ frame.reserve(4 + payload.size());
+ frame.push_back(FRAME_START);
+ frame.push_back(cmd);
+ frame.push_back(static_cast(len & 0xFF));
+ frame.push_back(static_cast((len >> 8) & 0xFF));
+ frame.insert(frame.end(), payload.begin(), payload.end());
+ serial_.write(frame.data(), frame.size());
+}
+
+bool MakcuConnection::readBinaryFrame(uint8_t expected_cmd, std::vector& payload, int timeout_ms)
+{
+ payload.clear();
+ auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
+
+ enum class ParseState { WaitStart, WaitCmd, WaitLenLo, WaitLenHi, WaitPayload };
+ ParseState state = ParseState::WaitStart;
+ uint16_t length = 0;
+ size_t read_count = 0;
+
+ while (std::chrono::steady_clock::now() < deadline)
+ {
+ if (!serial_.available())
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ continue;
+ }
+
+ uint8_t byte = 0;
+ serial_.read(&byte, 1);
+
+ switch (state)
+ {
+ case ParseState::WaitStart:
+ if (byte == FRAME_START)
+ state = ParseState::WaitCmd;
+ break;
+
+ case ParseState::WaitCmd:
+ if (byte != expected_cmd)
+ {
+ state = (byte == FRAME_START) ? ParseState::WaitCmd : ParseState::WaitStart;
+ break;
+ }
+ state = ParseState::WaitLenLo;
+ break;
+
+ case ParseState::WaitLenLo:
+ length = byte;
+ state = ParseState::WaitLenHi;
+ break;
+
+ case ParseState::WaitLenHi:
+ length |= static_cast(byte) << 8;
+ payload.assign(length, 0);
+ read_count = 0;
+ if (length == 0)
+ return true;
+ state = ParseState::WaitPayload;
+ break;
+
+ case ParseState::WaitPayload:
+ payload[read_count++] = byte;
+ if (read_count >= length)
+ return true;
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool MakcuConnection::queryButtonStateBinary(uint8_t cmd, bool& pressed)
+{
+ pressed = false;
+ if (!is_open_)
+ return false;
+
+ try
+ {
+ std::lock_guard lock(write_mutex_);
+ writeBinaryCommand(cmd, {});
+
+ std::vector payload;
+ if (!readBinaryFrame(cmd, payload, 30))
+ return false;
+
+ if (payload.empty())
+ return false;
+
+ // 0=none, 1=raw, 2=injected, 3=both
+ pressed = payload[0] != 0;
+ return true;
+ }
+ catch (...)
+ {
+ is_open_ = false;
+ return false;
+ }
+}
+
+void MakcuConnection::sendCommand(const std::string& cmd) { write(cmd + "\r\n"); }
+std::vector MakcuConnection::splitValue(int) { return {}; }
+
+void MakcuConnection::startListening()
+{
+ listening_ = true;
+ if (listening_thread_.joinable())
+ listening_thread_.join();
+
+ listening_thread_ = std::thread(&MakcuConnection::listeningThreadFunc, this);
+}
+
+void MakcuConnection::listeningThreadFunc()
+{
+ // Kmbox-like parser logic for Makcu fallback.
+ // Allowed bits: 0x01 (LMB), 0x02 (RMB), 0x08 (side1 trigger), 0x10 (side2 aim)
+ constexpr uint8_t allowed_mask = 0x01 | 0x02 | 0x08 | 0x10;
+
+ while (listening_ && is_open_) {
+ try {
+ if (!serial_.available()) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ continue;
+ }
+
+ uint8_t b = 0;
+ serial_.read(&b, 1);
+
+ // Drop byte if it contains unexpected bits.
+ if (b & ~allowed_mask)
+ continue;
+
+ left_active = (b & 0x01) != 0;
+ right_active = (b & 0x02) != 0;
+ middle_active = false;
+ side1_active = (b & 0x08) != 0;
+ side2_active = (b & 0x10) != 0;
+
+ shooting_active = left_active;
+ zooming_active = right_active;
+ triggerbot_active = side1_active;
+ aiming_active = side2_active;
+
+ shooting.store(shooting_active);
+ zooming.store(zooming_active);
+ triggerbot_button.store(triggerbot_active);
+ aiming.store(aiming_active);
+
+ logMakcuButtons("serial", *this, static_cast(b));
+
+ }
+ catch (...) {
+ is_open_ = false;
+ break;
+ }
+ }
+}
+
+void MakcuConnection::processIncomingLine(const std::string& line)
+{
+ std::string token;
+ token.reserve(8);
+
+ for (char ch : line)
+ {
+ const unsigned char c = static_cast(ch);
+ if (std::isdigit(c))
+ {
+ token.push_back(static_cast(c));
+ continue;
+ }
+
+ if (!token.empty())
+ break;
+ }
+
+ if (token.empty())
+ return;
+
+ int value = -1;
+ try
+ {
+ value = std::stoi(token);
+ }
+ catch (...)
+ {
+ return;
+ }
+
+ if (value < 0 || value > 63)
+ return;
+
+ const uint8_t last_buttons = static_cast(value & 0x3F);
+ const uint8_t previous_buttons = static_cast((left_active ? 0x01 : 0x00) |
+ (right_active ? 0x02 : 0x00) |
+ (middle_active ? 0x04 : 0x00) |
+ (side1_active ? 0x08 : 0x00) |
+ (side2_active ? 0x10 : 0x00));
+
+ left_active = (last_buttons & 0x01) != 0;
+ right_active = (last_buttons & 0x02) != 0;
+ middle_active = (last_buttons & 0x04) != 0;
+ side1_active = (last_buttons & 0x08) != 0;
+ side2_active = (last_buttons & 0x10) != 0;
+
+ shooting_active = left_active;
+ aiming_active = side2_active;
+ zooming_active = right_active;
+ triggerbot_active = side1_active;
+
+ triggerbot_button.store(triggerbot_active);
+ shooting.store(shooting_active);
+ aiming.store(aiming_active);
+ zooming.store(zooming_active);
+
+ const uint8_t current_buttons = static_cast((left_active ? 0x01 : 0x00) |
+ (right_active ? 0x02 : 0x00) |
+ (middle_active ? 0x04 : 0x00) |
+ (side1_active ? 0x08 : 0x00) |
+ (side2_active ? 0x10 : 0x00));
+
+ if (current_buttons != previous_buttons)
+ logMakcuButtons("serial", *this, value);
+}
+
+#endif
diff --git a/RN_AI_cpp/mouse/MakcuConnection.h b/RN_AI_cpp/mouse/MakcuConnection.h
new file mode 100644
index 00000000..ad6b5352
--- /dev/null
+++ b/RN_AI_cpp/mouse/MakcuConnection.h
@@ -0,0 +1,80 @@
+#ifndef MAKCU_CONNECTION_H
+#define MAKCU_CONNECTION_H
+
+#include
+#include
+#include
+#include
+#include
+
+#if __has_include("../modules/makcu/include/makcu.h")
+#include "../modules/makcu/include/makcu.h"
+#define RN_MAKCU_SDK_AVAILABLE 1
+#else
+#define RN_MAKCU_SDK_AVAILABLE 0
+#include
+#include "serial/serial.h"
+#endif
+
+class MakcuConnection
+{
+public:
+ MakcuConnection(const std::string& port, unsigned int baud_rate);
+ ~MakcuConnection();
+
+ bool isOpen() const;
+
+ void write(const std::string& data);
+ std::string read();
+
+ void click(int button);
+ void press(int button);
+ void release(int button);
+ void move(int x, int y);
+
+ void start_boot();
+ void reboot();
+ void send_stop();
+
+ bool aiming_active;
+ bool shooting_active;
+ bool zooming_active;
+ bool triggerbot_active;
+ bool side1_active;
+ bool side2_active;
+ bool left_active;
+ bool right_active;
+ bool middle_active;
+
+private:
+#if RN_MAKCU_SDK_AVAILABLE
+ void startSdkPolling();
+ void stopSdkPolling();
+ void sdkPollingThreadFunc();
+ void applyButtonMask(uint8_t mask, const char* source);
+ void onButtonCallback(makcu::MouseButton button, bool pressed);
+ makcu::MouseButton toMouseButton(int button) const;
+ makcu::Device device_;
+ std::atomic sdk_listening_;
+ std::thread sdk_listening_thread_;
+#else
+ bool queryButtonStateBinary(uint8_t cmd, bool& pressed);
+ bool readBinaryFrame(uint8_t expected_cmd, std::vector& payload, int timeout_ms);
+ void writeBinaryCommand(uint8_t cmd, const std::vector& payload);
+
+ void sendCommand(const std::string& command);
+ std::vector splitValue(int value);
+ void startListening();
+ void listeningThreadFunc();
+ void processIncomingLine(const std::string& line);
+
+ serial::Serial serial_;
+ std::atomic listening_;
+ std::thread listening_thread_;
+#endif
+
+ std::atomic is_open_;
+ std::mutex write_mutex_;
+};
+
+#endif // MAKCU_CONNECTION_H
diff --git a/sunone_aimbot_cpp/mouse/SerialConnection.cpp b/RN_AI_cpp/mouse/SerialConnection.cpp
similarity index 99%
rename from sunone_aimbot_cpp/mouse/SerialConnection.cpp
rename to RN_AI_cpp/mouse/SerialConnection.cpp
index 852b888b..df579d39 100644
--- a/sunone_aimbot_cpp/mouse/SerialConnection.cpp
+++ b/RN_AI_cpp/mouse/SerialConnection.cpp
@@ -1,11 +1,11 @@
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define _WINSOCKAPI_
#include
#include
#include
#include
-#include "sunone_aimbot_cpp.h"
+#include "rn_ai_cpp.h"
#include "SerialConnection.h"
SerialConnection::SerialConnection(const std::string& port, unsigned int baud_rate)
diff --git a/sunone_aimbot_cpp/mouse/SerialConnection.h b/RN_AI_cpp/mouse/SerialConnection.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/SerialConnection.h
rename to RN_AI_cpp/mouse/SerialConnection.h
diff --git a/sunone_aimbot_cpp/mouse/kmboxNetConnection.cpp b/RN_AI_cpp/mouse/kmboxNetConnection.cpp
similarity index 99%
rename from sunone_aimbot_cpp/mouse/kmboxNetConnection.cpp
rename to RN_AI_cpp/mouse/kmboxNetConnection.cpp
index dffb174a..8f010ed8 100644
--- a/sunone_aimbot_cpp/mouse/kmboxNetConnection.cpp
+++ b/RN_AI_cpp/mouse/kmboxNetConnection.cpp
@@ -4,7 +4,7 @@
#include "kmbox_net/kmboxNet.h"
#include "KmboxNetConnection.h"
-#include
+#include
KmboxNetConnection::KmboxNetConnection(const std::string& ip, const std::string& port, const std::string& uuid)
: is_open_(false), ip_(ip), port_(port), uuid_(uuid), monitor_(false)
diff --git a/sunone_aimbot_cpp/mouse/kmboxNetConnection.h b/RN_AI_cpp/mouse/kmboxNetConnection.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/kmboxNetConnection.h
rename to RN_AI_cpp/mouse/kmboxNetConnection.h
diff --git a/sunone_aimbot_cpp/mouse/kmbox_net/HidTable.h b/RN_AI_cpp/mouse/kmbox_net/HidTable.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/kmbox_net/HidTable.h
rename to RN_AI_cpp/mouse/kmbox_net/HidTable.h
diff --git a/sunone_aimbot_cpp/mouse/kmbox_net/kmboxNet.cpp b/RN_AI_cpp/mouse/kmbox_net/kmboxNet.cpp
similarity index 100%
rename from sunone_aimbot_cpp/mouse/kmbox_net/kmboxNet.cpp
rename to RN_AI_cpp/mouse/kmbox_net/kmboxNet.cpp
diff --git a/sunone_aimbot_cpp/mouse/kmbox_net/kmboxNet.h b/RN_AI_cpp/mouse/kmbox_net/kmboxNet.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/kmbox_net/kmboxNet.h
rename to RN_AI_cpp/mouse/kmbox_net/kmboxNet.h
diff --git a/sunone_aimbot_cpp/mouse/kmbox_net/picture.h b/RN_AI_cpp/mouse/kmbox_net/picture.h
similarity index 100%
rename from sunone_aimbot_cpp/mouse/kmbox_net/picture.h
rename to RN_AI_cpp/mouse/kmbox_net/picture.h
diff --git a/RN_AI_cpp/mouse/mouse.cpp b/RN_AI_cpp/mouse/mouse.cpp
new file mode 100644
index 00000000..3ae7ba17
--- /dev/null
+++ b/RN_AI_cpp/mouse/mouse.cpp
@@ -0,0 +1,1163 @@
+#define WIN32_LEAN_AND_MEAN
+#define _WINSOCKAPI_
+#include
+#include
+
+#define _USE_MATH_DEFINES
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mouse.h"
+#include "capture.h"
+#include "SerialConnection.h"
+#include "rn_ai_cpp.h"
+#ifdef makcu
+#undef makcu
+#endif
+
+MouseThread::MouseThread(
+ int resolution,
+ int fovX,
+ int fovY,
+ double minSpeedMultiplier,
+ double maxSpeedMultiplier,
+ double predictionInterval,
+ bool auto_shoot,
+ float bScope_multiplier,
+ float triggerbot_bScope_multiplier,
+ SerialConnection* serialConnection,
+ KmboxConnection* kmboxConnection,
+ KmboxNetConnection* Kmbox_Net_Connection,
+ MakcuConnection* makcu)
+ : screen_width(resolution),
+ screen_height(resolution),
+ prediction_interval(predictionInterval),
+ fov_x(fovX),
+ fov_y(fovY),
+ max_distance(std::hypot(resolution, resolution) / 2.0),
+ min_speed_multiplier(minSpeedMultiplier),
+ max_speed_multiplier(maxSpeedMultiplier),
+ center_x(resolution / 2.0),
+ center_y(resolution / 2.0),
+ auto_shoot(auto_shoot),
+ bScope_multiplier(bScope_multiplier),
+ triggerbot_bScope_multiplier(triggerbot_bScope_multiplier),
+ serial(serialConnection),
+ kmbox(kmboxConnection),
+ kmbox_net(Kmbox_Net_Connection),
+ makcu(makcu),
+
+ prev_velocity_x(0.0),
+ prev_velocity_y(0.0),
+ prev_x(0.0),
+ prev_y(0.0)
+{
+ prev_time = std::chrono::steady_clock::time_point();
+ last_target_time = std::chrono::steady_clock::now();
+
+ wind_mouse_enabled = config.wind_mouse_enabled;
+ wind_G = config.wind_G;
+ wind_W = config.wind_W;
+ wind_M = config.wind_M;
+ wind_D = config.wind_D;
+
+ use_smoothing = config.use_smoothing;
+ use_kalman = config.use_kalman;
+
+ kfX = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ kfY = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ last_kalman_q = config.kalman_process_noise;
+ last_kalman_r = config.kalman_measurement_noise;
+
+ last_prediction_q = config.prediction_kalman_process_noise;
+ last_prediction_r = config.prediction_kalman_measurement_noise;
+ resetAimState();
+
+ moveWorker = std::thread(&MouseThread::moveWorkerLoop, this);
+}
+
+void MouseThread::updateConfig(
+ int resolution,
+ int fovX,
+ int fovY,
+ double minSpeedMultiplier,
+ double maxSpeedMultiplier,
+ double predictionInterval,
+ bool auto_shoot,
+ float bScope_multiplier,
+ float triggerbot_bScope_multiplier
+)
+{
+ screen_width = screen_height = resolution;
+ fov_x = fovX; fov_y = fovY;
+ min_speed_multiplier = minSpeedMultiplier;
+ max_speed_multiplier = maxSpeedMultiplier;
+ prediction_interval = predictionInterval;
+ this->auto_shoot = auto_shoot;
+ this->bScope_multiplier = bScope_multiplier;
+ this->triggerbot_bScope_multiplier = triggerbot_bScope_multiplier;
+
+ center_x = center_y = resolution / 2.0;
+ max_distance = std::hypot(resolution, resolution) / 2.0;
+
+ wind_mouse_enabled = config.wind_mouse_enabled;
+ wind_G = config.wind_G; wind_W = config.wind_W;
+ wind_M = config.wind_M; wind_D = config.wind_D;
+
+ use_smoothing = config.use_smoothing;
+ use_kalman = config.use_kalman;
+
+ kfX = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ kfY = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ last_kalman_q = config.kalman_process_noise;
+ last_kalman_r = config.kalman_measurement_noise;
+
+}
+
+MouseThread::~MouseThread()
+{
+ workerStop = true;
+ queueCv.notify_all();
+ if (moveWorker.joinable()) moveWorker.join();
+}
+
+void MouseThread::queueMove(int dx, int dy)
+{
+ std::lock_guard lg(queueMtx);
+ if (moveQueue.size() >= queueLimit) moveQueue.pop();
+ moveQueue.push({ dx,dy });
+ queueCv.notify_one();
+}
+
+void MouseThread::moveWorkerLoop()
+{
+ while (!workerStop)
+ {
+ std::unique_lock ul(queueMtx);
+ queueCv.wait(ul, [&] { return workerStop || !moveQueue.empty(); });
+
+ while (!moveQueue.empty())
+ {
+ Move m = moveQueue.front();
+ moveQueue.pop();
+ ul.unlock();
+ sendMovementToDriver(m.dx, m.dy);
+ ul.lock();
+ }
+ }
+}
+
+void MouseThread::windMouseMoveRelative(int dx, int dy)
+{
+ if (dx == 0 && dy == 0) return;
+
+ constexpr double SQRT3 = 1.7320508075688772;
+ constexpr double SQRT5 = 2.23606797749979;
+
+ double sx = 0, sy = 0;
+ double dxF = static_cast(dx);
+ double dyF = static_cast(dy);
+ double vx = 0, vy = 0, wX = 0, wY = 0;
+ int cx = 0, cy = 0;
+
+ while (std::hypot(dxF - sx, dyF - sy) >= 1.0)
+ {
+ double dist = std::hypot(dxF - sx, dyF - sy);
+ double wMag = std::min(wind_W, dist);
+
+ if (dist >= wind_D)
+ {
+ wX = wX / SQRT3 + ((double)rand() / RAND_MAX * 2.0 - 1.0) * wMag / SQRT5;
+ wY = wY / SQRT3 + ((double)rand() / RAND_MAX * 2.0 - 1.0) * wMag / SQRT5;
+ }
+ else
+ {
+ wX /= SQRT3; wY /= SQRT3;
+ wind_M = wind_M < 3.0 ? ((double)rand() / RAND_MAX) * 3.0 + 3.0 : wind_M / SQRT5;
+ }
+
+ vx += wX + wind_G * (dxF - sx) / dist;
+ vy += wY + wind_G * (dyF - sy) / dist;
+
+ double vMag = std::hypot(vx, vy);
+ if (vMag > wind_M)
+ {
+ double vClip = wind_M / 2.0 + ((double)rand() / RAND_MAX) * wind_M / 2.0;
+ vx = (vx / vMag) * vClip;
+ vy = (vy / vMag) * vClip;
+ }
+
+ sx += vx; sy += vy;
+ int rx = static_cast(std::round(sx));
+ int ry = static_cast(std::round(sy));
+ int step_x = rx - cx;
+ int step_y = ry - cy;
+ if (step_x || step_y)
+ {
+ queueMove(step_x, step_y);
+ cx = rx; cy = ry;
+ }
+ }
+}
+
+double MouseThread::clampValue(double v, double lo, double hi)
+{
+ return std::max(lo, std::min(hi, v));
+}
+
+void MouseThread::resetPredictionState()
+{
+ prediction_prev_time = std::chrono::steady_clock::time_point{};
+ prediction_prev_x = 0.0;
+ prediction_prev_y = 0.0;
+ prediction_smoothed_velocity_x = 0.0;
+ prediction_smoothed_velocity_y = 0.0;
+ prediction_velocity_x = 0.0;
+ prediction_velocity_y = 0.0;
+ prediction_initialized = false;
+ prediction_kalman_time = std::chrono::steady_clock::time_point{};
+ prediction_kalman_initialized = false;
+ last_prediction_mode = -1;
+ last_raw_velocity_x = 0.0;
+ last_raw_velocity_y = 0.0;
+
+ double q = (last_prediction_q > 0.0) ? last_prediction_q : 0.01;
+ double r = (last_prediction_r > 0.0) ? last_prediction_r : 0.1;
+ prediction_kf_x = Kalman1D(q, r);
+ prediction_kf_y = Kalman1D(q, r);
+}
+
+void MouseThread::resetKalmanState()
+{
+ kfX = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ kfY = Kalman1D(config.kalman_process_noise, config.kalman_measurement_noise);
+ prevKalmanTime = std::chrono::steady_clock::time_point{};
+ kalman_smoothing_initialized = false;
+ last_raw_kalman_x = 0.0;
+ last_raw_kalman_y = 0.0;
+ last_kx = 0.0;
+ last_ky = 0.0;
+}
+
+void MouseThread::resetSmoothingState()
+{
+ move_overflow_x = 0.0;
+ move_overflow_y = 0.0;
+ smooth_frame = 0;
+ smooth_start_x = 0.0;
+ smooth_start_y = 0.0;
+ smooth_prev_x = 0.0;
+ smooth_prev_y = 0.0;
+ smooth_last_tx = 0.0;
+ smooth_last_ty = 0.0;
+
+ tracking_initialized = false;
+ track_x = 0.0;
+ track_y = 0.0;
+ track_prev_x = 0.0;
+ track_prev_y = 0.0;
+ track_time = std::chrono::steady_clock::time_point{};
+ last_tracking_mode = -1;
+}
+
+void MouseThread::resetAimState()
+{
+ prev_time = std::chrono::steady_clock::time_point{};
+ prev_x = 0.0;
+ prev_y = 0.0;
+ prev_velocity_x = 0.0;
+ prev_velocity_y = 0.0;
+ last_target_time = std::chrono::steady_clock::time_point{};
+ target_detected.store(false);
+ resetPredictionState();
+ resetKalmanState();
+ resetSmoothingState();
+}
+
+void MouseThread::markTargetSeen()
+{
+ last_target_time = std::chrono::steady_clock::now();
+ target_detected.store(true);
+}
+
+void MouseThread::resetIfStale(double timeout_s)
+{
+ if (!target_detected.load())
+ return;
+ auto now = std::chrono::steady_clock::now();
+ double elapsed = std::chrono::duration(now - last_target_time).count();
+ if (elapsed > timeout_s)
+ {
+ resetAimState();
+ }
+}
+
+void MouseThread::ensurePredictionKalman(double q, double r)
+{
+ q = std::max(q, 1e-6);
+ r = std::max(r, 1e-6);
+ if (q != last_prediction_q || r != last_prediction_r)
+ {
+ last_prediction_q = q;
+ last_prediction_r = r;
+ resetPredictionState();
+ }
+}
+
+void MouseThread::ensureKalman(double q, double r)
+{
+ q = std::max(q, 1e-6);
+ r = std::max(r, 1e-6);
+ if (q != last_kalman_q || r != last_kalman_r)
+ {
+ kfX = Kalman1D(q, r);
+ kfY = Kalman1D(q, r);
+ last_kalman_q = q;
+ last_kalman_r = r;
+ kalman_smoothing_initialized = false;
+ prevKalmanTime = std::chrono::steady_clock::time_point{};
+ }
+}
+
+std::pair MouseThread::cameraVelocity(double camera_dx, double camera_dy, double dt)
+{
+ if (!config.camera_compensation_enabled || dt <= 0.0)
+ return { 0.0, 0.0 };
+ double max_shift = std::max(0.0, static_cast(config.camera_compensation_max_shift));
+ double strength = std::max(0.0, static_cast(config.camera_compensation_strength));
+ double dx = clampValue(camera_dx, -max_shift, max_shift) * strength;
+ double dy = clampValue(camera_dy, -max_shift, max_shift) * strength;
+ return { dx / dt, dy / dt };
+}
+
+std::pair MouseThread::updateStandardVelocity(
+ double targetX, double targetY, double camera_dx, double camera_dy)
+{
+ auto now = std::chrono::steady_clock::now();
+ if (prev_time.time_since_epoch().count() == 0 || !target_detected.load())
+ {
+ prev_time = now;
+ prev_x = targetX;
+ prev_y = targetY;
+ prev_velocity_x = 0.0;
+ prev_velocity_y = 0.0;
+ return { 0.0, 0.0 };
+ }
+ double dt = std::max(std::chrono::duration(now - prev_time).count(), 1e-8);
+ auto cam = cameraVelocity(camera_dx, camera_dy, dt);
+ double vx = (targetX - prev_x) / dt - cam.first;
+ double vy = (targetY - prev_y) / dt - cam.second;
+ prev_time = now;
+ prev_x = targetX;
+ prev_y = targetY;
+ prev_velocity_x = clampValue(vx, -20000.0, 20000.0);
+ prev_velocity_y = clampValue(vy, -20000.0, 20000.0);
+ return { prev_velocity_x, prev_velocity_y };
+}
+
+std::pair MouseThread::updatePredictionState(
+ double pivotX, double pivotY, double camera_dx, double camera_dy)
+{
+ int mode = config.prediction_mode;
+ if (mode != last_prediction_mode)
+ {
+ resetPredictionState();
+ last_prediction_mode = mode;
+ }
+
+ auto now = std::chrono::steady_clock::now();
+ const double max_gap = 0.25;
+ if (prediction_prev_time.time_since_epoch().count() == 0)
+ {
+ prediction_prev_time = now;
+ prediction_prev_x = pivotX;
+ prediction_prev_y = pivotY;
+ if (mode != 0)
+ {
+ prediction_kf_x.reset(pivotX, 0.0);
+ prediction_kf_y.reset(pivotY, 0.0);
+ prediction_kalman_time = now;
+ prediction_kalman_initialized = true;
+ }
+ return { pivotX, pivotY };
+ }
+
+ double dt = std::chrono::duration(now - prediction_prev_time).count();
+ if (dt > max_gap)
+ {
+ resetPredictionState();
+ prediction_prev_time = now;
+ prediction_prev_x = pivotX;
+ prediction_prev_y = pivotY;
+ if (mode != 0)
+ {
+ prediction_kf_x.reset(pivotX, 0.0);
+ prediction_kf_y.reset(pivotY, 0.0);
+ prediction_kalman_time = now;
+ prediction_kalman_initialized = true;
+ }
+ return { pivotX, pivotY };
+ }
+
+ dt = std::max(dt, 1e-8);
+ auto cam = cameraVelocity(camera_dx, camera_dy, dt);
+ double raw_vx = (pivotX - prediction_prev_x) / dt - cam.first;
+ double raw_vy = (pivotY - prediction_prev_y) / dt - cam.second;
+ raw_vx = clampValue(raw_vx, -20000.0, 20000.0);
+ raw_vy = clampValue(raw_vy, -20000.0, 20000.0);
+ prediction_prev_x = pivotX;
+ prediction_prev_y = pivotY;
+ prediction_prev_time = now;
+ last_raw_velocity_x = raw_vx;
+ last_raw_velocity_y = raw_vy;
+
+ double base_vx = raw_vx;
+ double base_vy = raw_vy;
+ double filt_x = pivotX;
+ double filt_y = pivotY;
+
+ if (mode != 0)
+ {
+ double reset_threshold = std::max(1.0, static_cast(config.resetThreshold));
+ if (!prediction_kalman_initialized ||
+ std::hypot(pivotX - prediction_kf_x.x, pivotY - prediction_kf_y.x) > reset_threshold)
+ {
+ prediction_kf_x.reset(pivotX, 0.0);
+ prediction_kf_y.reset(pivotY, 0.0);
+ prediction_kalman_time = now;
+ prediction_kalman_initialized = true;
+ }
+
+ double kdt = dt;
+ if (prediction_kalman_time.time_since_epoch().count() != 0)
+ kdt = std::max(std::chrono::duration(now - prediction_kalman_time).count(), 1e-8);
+ prediction_kalman_time = now;
+
+ filt_x = prediction_kf_x.update(pivotX, kdt);
+ filt_y = prediction_kf_y.update(pivotY, kdt);
+ base_vx = prediction_kf_x.v - cam.first;
+ base_vy = prediction_kf_y.v - cam.second;
+ }
+
+ double alpha = clampValue(config.prediction_velocity_smoothing, 0.0, 1.0);
+ if (!prediction_initialized)
+ {
+ prediction_smoothed_velocity_x = base_vx;
+ prediction_smoothed_velocity_y = base_vy;
+ prediction_initialized = true;
+ }
+ else
+ {
+ prediction_smoothed_velocity_x += (base_vx - prediction_smoothed_velocity_x) * alpha;
+ prediction_smoothed_velocity_y += (base_vy - prediction_smoothed_velocity_y) * alpha;
+ }
+
+ double scale = std::max(0.0, static_cast(config.prediction_velocity_scale));
+ prediction_velocity_x = prediction_smoothed_velocity_x * scale;
+ prediction_velocity_y = prediction_smoothed_velocity_y * scale;
+
+ if (mode == 0)
+ return { pivotX, pivotY };
+
+ double lead_ms = std::max(0.0, static_cast(config.prediction_kalman_lead_ms));
+ double max_lead_ms = std::max(0.0, static_cast(config.prediction_kalman_max_lead_ms));
+ if (max_lead_ms > 0.0 && lead_ms > max_lead_ms)
+ lead_ms = max_lead_ms;
+ double lead_s = lead_ms / 1000.0;
+
+ return { filt_x + prediction_velocity_x * lead_s,
+ filt_y + prediction_velocity_y * lead_s };
+}
+
+std::vector> MouseThread::predictFuturePositionsInternal(
+ double pivotX, double pivotY, int frames, double fps)
+{
+ std::vector> result;
+ if (frames <= 0)
+ return result;
+ if (prediction_prev_time.time_since_epoch().count() == 0)
+ return result;
+
+ double dt = std::chrono::duration(
+ std::chrono::steady_clock::now() - prediction_prev_time).count();
+ if (dt > 0.5)
+ return result;
+
+ double frame_time = 1.0 / std::max(fps, 1.0);
+ double vx = prediction_initialized ? prediction_velocity_x : 0.0;
+ double vy = prediction_initialized ? prediction_velocity_y : 0.0;
+
+ result.reserve(frames);
+ for (int i = 1; i <= frames; ++i)
+ {
+ double t = frame_time * i;
+ result.push_back({ pivotX + vx * t, pivotY + vy * t });
+ }
+ return result;
+}
+
+std::pair MouseThread::predict_target_position(double target_x, double target_y)
+{
+ ensurePredictionKalman(config.prediction_kalman_process_noise,
+ config.prediction_kalman_measurement_noise);
+ ensureKalman(config.kalman_process_noise, config.kalman_measurement_noise);
+
+ double infer_ms = 0.0;
+ if (config.backend == "DML" && dml_detector)
+ {
+ infer_ms = dml_detector->lastInferenceTimeDML.count();
+ }
+#ifdef USE_CUDA
+ else if (config.backend != "COLOR")
+ {
+ infer_ms = trt_detector.lastInferenceTime.count();
+ }
+#endif
+
+ auto pred = updatePredictionState(target_x, target_y, 0.0, 0.0);
+ double predX = pred.first;
+ double predY = pred.second;
+
+ int mode = config.prediction_mode;
+ double interval = std::max(0.0, static_cast(config.predictionInterval));
+ if (mode == 0)
+ {
+ auto vel = updateStandardVelocity(target_x, target_y, 0.0, 0.0);
+ double latency_s = std::max(0.0, infer_ms) / 1000.0;
+ predX = target_x + vel.first * (interval + latency_s);
+ predY = target_y + vel.second * (interval + latency_s);
+ }
+ else if (mode == 2)
+ {
+ predX += last_raw_velocity_x * interval;
+ predY += last_raw_velocity_y * interval;
+ }
+
+ double latency_s = std::max(0.0, infer_ms) / 1000.0;
+ double extra_lead_s = latency_s;
+ if (mode == 1)
+ extra_lead_s += interval;
+ if ((mode == 1 || mode == 2) && extra_lead_s > 0.0)
+ {
+ predX += prediction_velocity_x * extra_lead_s;
+ predY += prediction_velocity_y * extra_lead_s;
+ }
+
+ return { predX, predY };
+}
+
+void MouseThread::sendMovementToDriver(int dx, int dy)
+{
+ std::lock_guard lock(input_method_mutex);
+ if (makcu)
+ {
+ makcu->move(dx, dy);
+ }
+ else if (kmbox)
+ {
+ kmbox->move(dx, dy);
+ }
+ else if (kmbox_net)
+ {
+ kmbox_net->move(dx, dy);
+ }
+ else if (serial)
+ {
+ serial->move(dx, dy);
+ }
+ else
+ {
+ INPUT in{ 0 };
+ in.type = INPUT_MOUSE;
+ in.mi.dx = dx; in.mi.dy = dy;
+ in.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
+ SendInput(1, &in, sizeof(INPUT));
+ }
+}
+
+std::pair MouseThread::calc_movement(double tx, double ty)
+{
+ double offx = tx - center_x;
+ double offy = ty - center_y;
+ double dist = std::hypot(offx, offy);
+ double speed = calculate_speed_multiplier(dist);
+
+ double degPerPxX = fov_x / screen_width;
+ double degPerPxY = fov_y / screen_height;
+
+ double mmx = offx * degPerPxX;
+ double mmy = offy * degPerPxY;
+
+ double corr = 1.0;
+ double fps = static_cast(captureFps.load());
+ if (fps > 30.0) corr = 30.0 / fps;
+
+ auto counts_pair = config.degToCounts(mmx, mmy, fov_x);
+ double move_x = counts_pair.first * speed * corr;
+ double move_y = counts_pair.second * speed * corr;
+
+ return { move_x, move_y };
+}
+
+double MouseThread::calculate_speed_multiplier(double distance)
+{
+ if (distance < config.snapRadius)
+ return min_speed_multiplier * config.snapBoostFactor;
+
+ if (distance < config.nearRadius)
+ {
+ double t = distance / config.nearRadius;
+ double curve = 1.0 - std::pow(1.0 - t, config.speedCurveExponent);
+ return min_speed_multiplier +
+ (max_speed_multiplier - min_speed_multiplier) * curve;
+ }
+
+ double norm = std::clamp(distance / max_distance, 0.0, 1.0);
+ return min_speed_multiplier +
+ (max_speed_multiplier - min_speed_multiplier) * norm;
+}
+
+bool MouseThread::check_target_in_scope(double target_x, double target_y, double target_w, double target_h, double reduction_factor)
+{
+ double center_target_x = target_x + target_w / 2.0;
+ double center_target_y = target_y + target_h / 2.0;
+
+ double reduced_w = target_w * (reduction_factor / 2.0);
+ double reduced_h = target_h * (reduction_factor / 2.0);
+
+ double x1 = center_target_x - reduced_w;
+ double x2 = center_target_x + reduced_w;
+ double y1 = center_target_y - reduced_h;
+ double y2 = center_target_y + reduced_h;
+
+ return (center_x > x1 && center_x < x2 && center_y > y1 && center_y < y2);
+}
+
+void MouseThread::pressMouse(const AimbotTarget& target, float scope_multiplier)
+{
+ std::lock_guard lock(input_method_mutex);
+
+ double multiplier = scope_multiplier > 0.0f ? scope_multiplier : bScope_multiplier;
+ bool bScope = check_target_in_scope(target.x, target.y, target.w, target.h, multiplier);
+ if (bScope && !mouse_pressed)
+ {
+ if (makcu)
+ {
+ makcu->press(0);
+ }
+ else if (kmbox)
+ {
+ kmbox->press(0);
+ }
+ else if (kmbox_net)
+ {
+ kmbox_net->keyDown(0);
+ }
+ else if (serial)
+ {
+ serial->press();
+ }
+ else
+ {
+ INPUT input = { 0 };
+ input.type = INPUT_MOUSE;
+ input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
+ SendInput(1, &input, sizeof(INPUT));
+ }
+ mouse_pressed = true;
+ }
+ else if (!bScope && mouse_pressed)
+ {
+ if (makcu)
+ {
+ makcu->release(0);
+ }
+ else if (kmbox)
+ {
+ kmbox->release(0);
+ }
+ else if (kmbox_net)
+ {
+ kmbox_net->keyUp(0);
+ }
+ else if (serial)
+ {
+ serial->release();
+ }
+ else
+ {
+ INPUT input = { 0 };
+ input.type = INPUT_MOUSE;
+ input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
+ SendInput(1, &input, sizeof(INPUT));
+ }
+ mouse_pressed = false;
+ }
+}
+
+void MouseThread::releaseMouse()
+{
+ std::lock_guard lock(input_method_mutex);
+
+ if (mouse_pressed)
+ {
+ if (makcu)
+ {
+ makcu->release(0);
+ }
+ else if (kmbox)
+ {
+ kmbox->release(0);
+ }
+ else if (kmbox_net)
+ {
+ kmbox_net->keyUp(0);
+ }
+ else if (serial)
+ {
+ serial->release();
+ }
+ else
+ {
+ INPUT input = { 0 };
+ input.type = INPUT_MOUSE;
+ input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
+ SendInput(1, &input, sizeof(INPUT));
+ }
+ mouse_pressed = false;
+ }
+}
+
+void MouseThread::resetPrediction()
+{
+ resetAimState();
+}
+
+void MouseThread::checkAndResetPredictions()
+{
+ resetIfStale(0.5);
+}
+
+std::vector> MouseThread::predictFuturePositions(double pivotX, double pivotY, int frames)
+{
+ double fps = static_cast(captureFps.load());
+ return predictFuturePositionsInternal(pivotX, pivotY, frames, fps);
+}
+
+void MouseThread::storeFuturePositions(const std::vector>& positions)
+{
+ std::lock_guard lock(futurePositionsMutex);
+ futurePositions = positions;
+}
+
+void MouseThread::clearFuturePositions()
+{
+ std::lock_guard lock(futurePositionsMutex);
+ futurePositions.clear();
+}
+
+std::vector> MouseThread::getFuturePositions()
+{
+ std::lock_guard lock(futurePositionsMutex);
+ return futurePositions;
+}
+
+void MouseThread::setSerialConnection(SerialConnection* newSerial)
+{
+ std::lock_guard lock(input_method_mutex);
+ serial = newSerial;
+}
+
+void MouseThread::setKmboxConnection(KmboxConnection* newKmbox)
+{
+ std::lock_guard lock(input_method_mutex);
+ kmbox = newKmbox;
+}
+
+void MouseThread::setKmboxNetConnection(KmboxNetConnection* newKmbox_net)
+{
+ std::lock_guard lock(input_method_mutex);
+ kmbox_net = newKmbox_net;
+}
+
+void MouseThread::setMakcuConnection(MakcuConnection* newMakcu)
+{
+ std::lock_guard lock( input_method_mutex);
+ makcu = newMakcu;
+}
+std::pair MouseThread::moveWithSmoothing(double targetX, double targetY, double fps)
+{
+ int N = smoothness > 0 ? smoothness : 1;
+ bool tracking = config.tracking_smoothing;
+
+ int tracking_flag = tracking ? 1 : 0;
+ if (last_tracking_mode == -1 || last_tracking_mode != tracking_flag)
+ {
+ resetSmoothingState();
+ last_tracking_mode = tracking_flag;
+ }
+
+ if (tracking)
+ {
+ auto now = std::chrono::steady_clock::now();
+ double dt;
+ if (track_time.time_since_epoch().count() == 0)
+ dt = 1.0 / std::max(fps, 1.0);
+ else
+ dt = std::max(std::chrono::duration(now - track_time).count(), 1e-8);
+ dt = std::min(dt, 0.25);
+ track_time = now;
+
+ if (!tracking_initialized)
+ {
+ track_x = center_x;
+ track_y = center_y;
+ track_prev_x = track_x;
+ track_prev_y = track_y;
+ tracking_initialized = true;
+ }
+
+ double delta = std::hypot(targetX - track_x, targetY - track_y);
+ double reset_threshold = std::max(1.0, static_cast(config.resetThreshold));
+ double base_alpha = 1.0 - std::exp(-dt * std::max(fps, 1.0) / N);
+ double catchup = clampValue(delta / std::max(reset_threshold, 1e-3), 0.0, 1.0);
+ double alpha = clampValue(base_alpha + (0.65 - base_alpha) * catchup, base_alpha, 0.65);
+
+ track_x += (targetX - track_x) * alpha;
+ track_y += (targetY - track_y) * alpha;
+
+ double dx = track_x - track_prev_x;
+ double dy = track_y - track_prev_y;
+
+ auto mv = addOverflow(dx, dy, move_overflow_x, move_overflow_y);
+ int ix = static_cast(mv.first);
+ int iy = static_cast(mv.second);
+
+ track_prev_x = track_x;
+ track_prev_y = track_y;
+ smooth_last_tx = targetX;
+ smooth_last_ty = targetY;
+ return { ix, iy };
+ }
+
+ if (smooth_frame == 0 ||
+ std::hypot(targetX - smooth_last_tx, targetY - smooth_last_ty) > 1.0)
+ {
+ smooth_start_x = center_x;
+ smooth_start_y = center_y;
+ smooth_prev_x = smooth_start_x;
+ smooth_prev_y = smooth_start_y;
+ smooth_frame = 0;
+ }
+
+ smooth_last_tx = targetX;
+ smooth_last_ty = targetY;
+ smooth_frame = std::min(smooth_frame + 1, N);
+ double t = static_cast(smooth_frame) / N;
+ double p = easeInOut(t);
+
+ double curX = smooth_start_x + (targetX - smooth_start_x) * p;
+ double curY = smooth_start_y + (targetY - smooth_start_y) * p;
+
+ double dx = curX - smooth_prev_x;
+ double dy = curY - smooth_prev_y;
+
+ auto mv = addOverflow(dx, dy, move_overflow_x, move_overflow_y);
+ int ix = static_cast(mv.first);
+ int iy = static_cast(mv.second);
+
+ smooth_prev_x = curX;
+ smooth_prev_y = curY;
+ return { ix, iy };
+}
+
+std::pair MouseThread::moveWithKalman(double targetX, double targetY, double fps)
+{
+ double reset_threshold = std::max(1.0, static_cast(config.resetThreshold));
+ auto now = std::chrono::steady_clock::now();
+
+ if (prevKalmanTime.time_since_epoch().count() == 0 ||
+ std::hypot(targetX - last_raw_kalman_x, targetY - last_raw_kalman_y) > reset_threshold)
+ {
+ kfX.reset(targetX, 0.0);
+ kfY.reset(targetY, 0.0);
+ prevKalmanTime = now;
+ }
+
+ last_raw_kalman_x = targetX;
+ last_raw_kalman_y = targetY;
+
+ auto now2 = std::chrono::steady_clock::now();
+ double dt;
+ if (prevKalmanTime.time_since_epoch().count() == 0)
+ dt = 1.0 / std::max(fps, 1.0);
+ else
+ dt = std::max(std::chrono::duration(now2 - prevKalmanTime).count(), 1e-8);
+ prevKalmanTime = now2;
+
+ double filtX = kfX.update(targetX, dt);
+ double filtY = kfY.update(targetY, dt);
+
+ auto mv = calc_movement(filtX, filtY);
+ double mvX = mv.first * kalman_speed_multiplier_x;
+ double mvY = mv.second * kalman_speed_multiplier_y;
+
+ return { static_cast(std::round(mvX)), static_cast(std::round(mvY)) };
+}
+
+std::pair MouseThread::moveWithKalmanAndSmoothing(double targetX, double targetY, double fps)
+{
+ double reset_threshold = std::max(1.0, static_cast(config.resetThreshold));
+ auto now = std::chrono::steady_clock::now();
+ const double max_dt = 0.25;
+
+ bool need_reset = !kalman_smoothing_initialized;
+ if (!need_reset)
+ {
+ double jump = std::hypot(targetX - last_raw_kalman_x, targetY - last_raw_kalman_y);
+ if (jump > reset_threshold)
+ need_reset = true;
+ if (prevKalmanTime.time_since_epoch().count() != 0)
+ {
+ double since_last = std::chrono::duration(now - prevKalmanTime).count();
+ if (since_last > max_dt)
+ need_reset = true;
+ }
+ }
+
+ if (need_reset || prevKalmanTime.time_since_epoch().count() == 0)
+ {
+ kfX.reset(targetX, 0.0);
+ kfY.reset(targetY, 0.0);
+ prevKalmanTime = now;
+ last_kx = targetX;
+ last_ky = targetY;
+ move_overflow_x = 0.0;
+ move_overflow_y = 0.0;
+ kalman_smoothing_initialized = true;
+ }
+
+ last_raw_kalman_x = targetX;
+ last_raw_kalman_y = targetY;
+
+ double dt;
+ if (prevKalmanTime.time_since_epoch().count() == 0 || need_reset)
+ dt = 1.0 / std::max(fps, 1.0);
+ else
+ dt = std::chrono::duration(now - prevKalmanTime).count();
+ prevKalmanTime = now;
+ dt = clampValue(dt, 1e-8, max_dt);
+
+ double filtX = kfX.update(targetX, dt);
+ double filtY = kfY.update(targetY, dt);
+
+ int N = smoothness > 0 ? smoothness : 1;
+ double base_alpha = 1.0 - std::exp(-dt * std::max(fps, 1.0) / N);
+ double delta = std::hypot(filtX - last_kx, filtY - last_ky);
+ double catchup = clampValue(delta / std::max(reset_threshold, 1e-3), 0.0, 1.0);
+ double max_alpha = config.tracking_smoothing ? 0.65 : 0.45;
+ double alpha = clampValue(base_alpha + (max_alpha - base_alpha) * catchup, base_alpha, max_alpha);
+
+ if (delta > reset_threshold)
+ {
+ last_kx = filtX;
+ last_ky = filtY;
+ }
+ else
+ {
+ last_kx += (filtX - last_kx) * alpha;
+ last_ky += (filtY - last_ky) * alpha;
+ }
+
+ auto mv = calc_movement(last_kx, last_ky);
+ double mvX = mv.first * kalman_speed_multiplier_x;
+ double mvY = mv.second * kalman_speed_multiplier_y;
+
+ auto step = addOverflow(mvX, mvY, move_overflow_x, move_overflow_y);
+ return { static_cast(step.first), static_cast(step.second) };
+}
+
+std::pair MouseThread::computeMove(
+ double targetX, double targetY, double fps, double infer_latency_ms,
+ double camera_dx, double camera_dy)
+{
+ markTargetSeen();
+ ensurePredictionKalman(config.prediction_kalman_process_noise,
+ config.prediction_kalman_measurement_noise);
+ ensureKalman(config.kalman_process_noise, config.kalman_measurement_noise);
+
+ auto pred = updatePredictionState(targetX, targetY, camera_dx, camera_dy);
+ double predX = pred.first;
+ double predY = pred.second;
+
+ int mode = config.prediction_mode;
+ double interval = std::max(0.0, static_cast(config.predictionInterval));
+
+ if (mode == 0)
+ {
+ auto vel = updateStandardVelocity(targetX, targetY, camera_dx, camera_dy);
+ double latency_s = std::max(0.0, infer_latency_ms) / 1000.0;
+ predX = targetX + vel.first * (interval + latency_s);
+ predY = targetY + vel.second * (interval + latency_s);
+ }
+ else if (mode == 2)
+ {
+ predX += last_raw_velocity_x * interval;
+ predY += last_raw_velocity_y * interval;
+ }
+
+ double latency_s = std::max(0.0, infer_latency_ms) / 1000.0;
+ double extra_lead_s = latency_s;
+ if (mode == 1)
+ extra_lead_s += interval;
+ if ((mode == 1 || mode == 2) && extra_lead_s > 0.0)
+ {
+ predX += prediction_velocity_x * extra_lead_s;
+ predY += prediction_velocity_y * extra_lead_s;
+ }
+
+ bool use_future_for_aim = config.prediction_use_future_for_aim;
+ bool need_future = use_future_for_aim || config.draw_futurePositions;
+ if (need_future)
+ {
+ auto future = predictFuturePositionsInternal(
+ predX, predY, config.prediction_futurePositions, fps);
+ if (use_future_for_aim && !future.empty())
+ {
+ predX = future.back().first;
+ predY = future.back().second;
+ }
+ storeFuturePositions(future);
+ }
+ else
+ {
+ clearFuturePositions();
+ }
+
+ if (use_kalman && use_smoothing)
+ return moveWithKalmanAndSmoothing(predX, predY, fps);
+ if (use_kalman)
+ return moveWithKalman(predX, predY, fps);
+ if (use_smoothing)
+ return moveWithSmoothing(predX, predY, fps);
+
+ auto mv = calc_movement(predX, predY);
+ return { static_cast(std::round(mv.first)), static_cast(std::round(mv.second)) };
+}
+
+// Kalman (public wrappers)
+void MouseThread::moveMouseWithKalman(double targetX, double targetY)
+{
+ double fps = std::max(1.0, static_cast(captureFps.load()));
+ auto delta = moveWithKalman(targetX, targetY, fps);
+ if (delta.first || delta.second)
+ {
+ if (wind_mouse_enabled)
+ windMouseMoveRelative(delta.first, delta.second);
+ else
+ queueMove(delta.first, delta.second);
+ }
+}
+
+// Kalman + smoothing (public wrappers)
+void MouseThread::moveMouseWithKalmanAndSmoothing(double targetX, double targetY)
+{
+ double fps = std::max(1.0, static_cast(captureFps.load()));
+ auto delta = moveWithKalmanAndSmoothing(targetX, targetY, fps);
+ if (delta.first || delta.second)
+ {
+ if (wind_mouse_enabled)
+ windMouseMoveRelative(delta.first, delta.second);
+ else
+ queueMove(delta.first, delta.second);
+ }
+}
+
+
+// easing-??????? ??? ?????????
+double MouseThread::easeInOut(double t) {
+ return -0.5 * (std::cos(M_PI * t) - 1.0);
+}
+
+// ?????????? ??????? ??????, ????? ?? ?????? ???????
+std::pair MouseThread::addOverflow(
+ double dx, double dy,
+ double& overflow_x, double& overflow_y)
+{
+ double int_x = 0.0, int_y = 0.0;
+ double frac_x = std::modf(dx + overflow_x, &int_x);
+ double frac_y = std::modf(dy + overflow_y, &int_y);
+
+ if (std::abs(frac_x) > 1.0) {
+ double extra = 0.0;
+ frac_x = std::modf(frac_x, &extra);
+ int_x += extra;
+ }
+ if (std::abs(frac_y) > 1.0) {
+ double extra = 0.0;
+ frac_y = std::modf(frac_y, &extra);
+ int_y += extra;
+ }
+
+ overflow_x = frac_x;
+ overflow_y = frac_y;
+ return { int_x, int_y };
+}
+
+void MouseThread::setKalmanParams(double processNoise, double measurementNoise) {
+ std::lock_guard lg(input_method_mutex);
+ // ?????? ????????????? ??????? ? ?????? Q/R
+ kfX = Kalman1D(processNoise, measurementNoise);
+ kfY = Kalman1D(processNoise, measurementNoise);
+ last_kalman_q = processNoise;
+ last_kalman_r = measurementNoise;
+ kalman_smoothing_initialized = false;
+ prevKalmanTime = std::chrono::steady_clock::time_point{};
+}
+
+void MouseThread::moveMouse(const AimbotTarget& target)
+{
+ double fps = std::max(1.0, static_cast(captureFps.load()));
+ double infer_ms = 0.0;
+ if (config.backend == "DML" && dml_detector)
+ infer_ms = dml_detector->lastInferenceTimeDML.count();
+#ifdef USE_CUDA
+ else if (config.backend != "COLOR")
+ infer_ms = trt_detector.lastInferenceTime.count();
+#endif
+
+ auto delta = computeMove(target.pivotX, target.pivotY, fps, infer_ms, 0.0, 0.0);
+ if (delta.first || delta.second)
+ {
+ if (wind_mouse_enabled)
+ windMouseMoveRelative(delta.first, delta.second);
+ else
+ queueMove(delta.first, delta.second);
+ }
+}
+
+// ?????????? ??? moveMousePivot
+void MouseThread::moveMousePivot(double pivotX, double pivotY)
+{
+ double fps = std::max(1.0, static_cast(captureFps.load()));
+ double infer_ms = 0.0;
+ if (config.backend == "DML" && dml_detector)
+ infer_ms = dml_detector->lastInferenceTimeDML.count();
+#ifdef USE_CUDA
+ else if (config.backend != "COLOR")
+ infer_ms = trt_detector.lastInferenceTime.count();
+#endif
+
+ auto delta = computeMove(pivotX, pivotY, fps, infer_ms, 0.0, 0.0);
+ if (delta.first || delta.second)
+ {
+ if (wind_mouse_enabled)
+ windMouseMoveRelative(delta.first, delta.second);
+ else
+ queueMove(delta.first, delta.second);
+ }
+}
diff --git a/sunone_aimbot_cpp/mouse/mouse.h b/RN_AI_cpp/mouse/mouse.h
similarity index 66%
rename from sunone_aimbot_cpp/mouse/mouse.h
rename to RN_AI_cpp/mouse/mouse.h
index 5d21d112..a6e02e79 100644
--- a/sunone_aimbot_cpp/mouse/mouse.h
+++ b/RN_AI_cpp/mouse/mouse.h
@@ -1,4 +1,4 @@
-// mouse.h
+// mouse.h
#ifndef MOUSE_H
#define MOUSE_H
@@ -26,7 +26,7 @@
class MouseThread
{
private:
- // Основные параметры
+ // ???????? ?????????
double screen_width, screen_height;
double prediction_interval;
double fov_x, fov_y;
@@ -37,7 +37,7 @@ class MouseThread
float bScope_multiplier;
float triggerbot_bScope_multiplier;
- // Для предсказания
+ // ??? ????????????
double prev_x, prev_y;
double prev_velocity_x, prev_velocity_y;
std::chrono::time_point prev_time;
@@ -45,13 +45,13 @@ class MouseThread
std::atomic target_detected{ false };
std::atomic mouse_pressed{ false };
- // Интерфейсы ввода
+ // ?????????? ?????
SerialConnection* serial;
KmboxConnection* kmbox;
KmboxNetConnection* kmbox_net;
MakcuConnection* makcu;
- // Отправка движений
+ // ???????? ????????
void sendMovementToDriver(int dx, int dy);
struct Move { int dx, dy; };
std::queue moveQueue;
@@ -61,40 +61,45 @@ class MouseThread
std::thread moveWorker;
std::atomic