diff --git a/AimmyWPF/AIModel.cs b/AimmyWPF/AIModel.cs
index ffa59e4c..b67948dc 100644
--- a/AimmyWPF/AIModel.cs
+++ b/AimmyWPF/AIModel.cs
@@ -11,6 +11,7 @@
using System.Windows.Forms;
using System;
using System.Runtime.InteropServices;
+using System.Diagnostics;
namespace AimmyAimbot
{
@@ -35,24 +36,46 @@ public class AIModel
public AIModel(string modelPath)
{
- try
+ _modeloptions = new RunOptions();
+
+ var sessionOptions = new SessionOptions
{
- _modeloptions = new RunOptions();
+ EnableCpuMemArena = true,
+ EnableMemoryPattern = true,
+ GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL,
+ ExecutionMode = ExecutionMode.ORT_PARALLEL
+ };
- var sessionOptions = new SessionOptions();
- sessionOptions.EnableCpuMemArena = true;
- sessionOptions.EnableMemoryPattern = true;
- sessionOptions.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL;
- sessionOptions.ExecutionMode = ExecutionMode.ORT_PARALLEL;
+ try
+ {
sessionOptions.AppendExecutionProvider_DML();
-
_onnxModel = new InferenceSession(modelPath, sessionOptions);
_outputNames = _onnxModel.OutputMetadata.Keys.ToList();
}
catch (Exception ex)
{
- MessageBox.Show($"There was an error starting the OnnxModel: {ex}");
- System.Windows.Application.Current.Shutdown();
+ MessageBox.Show($"There was an error starting the OnnxModel via DirectML: {ex}\n\nProgram will attempt to use CPU only, performance may be poor.", "Model Error");
+ try
+ {
+ sessionOptions.AppendExecutionProvider_CPU();
+ _onnxModel = new InferenceSession(modelPath, sessionOptions);
+ _outputNames = _onnxModel.OutputMetadata.Keys.ToList();
+ }
+ catch (Exception innerEx)
+ {
+ MessageBox.Show($"There was an error starting the model via CPU: {innerEx}", "Model Error");
+ System.Windows.Application.Current.Shutdown();
+ }
+ }
+
+ // Checking output shape
+ foreach (var output in _onnxModel.OutputMetadata)
+ {
+ var shape = _onnxModel.OutputMetadata[output.Key].Dimensions;
+ if (shape.Length != 3 || shape[0] != 1 || shape[1] != 5 || shape[2] != 8400)
+ {
+ MessageBox.Show($"Output shape {string.Join("x", shape)} does not match the expected shape of 1x5x8400.\n\nThis model will not work with Aimmy, please use an ONNX V8 model.", "Model Error");
+ }
}
}
diff --git a/AimmyWPF/AimmyWPF.csproj b/AimmyWPF/AimmyWPF.csproj
index dfe3e764..f5d3065f 100644
--- a/AimmyWPF/AimmyWPF.csproj
+++ b/AimmyWPF/AimmyWPF.csproj
@@ -32,6 +32,8 @@
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -65,5 +67,5 @@
Settings.Designer.cs
-
+
diff --git a/AimmyWPF/Class/Bools.cs b/AimmyWPF/Class/Bools.cs
index 45a96064..35a52d81 100644
--- a/AimmyWPF/Class/Bools.cs
+++ b/AimmyWPF/Class/Bools.cs
@@ -9,6 +9,7 @@ namespace AimmyWPF.Class
class Bools
{
public static bool AIAimAligner = false;
+ public static bool AIPredictions = false;
public static bool ThirdPersonAim = false;
public static bool Triggerbot = false;
public static bool CollectDataWhilePlaying = false;
diff --git a/AimmyWPF/MainWindow.xaml.cs b/AimmyWPF/MainWindow.xaml.cs
index 44e43d9a..a6a8007e 100644
--- a/AimmyWPF/MainWindow.xaml.cs
+++ b/AimmyWPF/MainWindow.xaml.cs
@@ -16,19 +16,25 @@
using AimmyAimbot;
using Class;
using Newtonsoft.Json;
+using System.Diagnostics;
namespace AimmyWPF
{
public partial class MainWindow : Window
{
+ private PredictionManager predictionManager;
private OverlayWindow FOVOverlay;
private FileSystemWatcher fileWatcher;
+ private FileSystemWatcher ConfigfileWatcher;
+
private string lastLoadedModel = "N/A";
+ private string lastLoadedConfig = "N/A";
private readonly BrushConverter brushcolor = new BrushConverter();
private int TimeSinceLastClick = 0;
private DateTime LastClickTime = DateTime.MinValue;
+
private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
private const uint MOUSEEVENTF_LEFTUP = 0x0004;
private const uint MOUSEEVENTF_MOVE = 0x0001; // Movement flag
@@ -63,6 +69,7 @@ private enum MenuPosition
private Dictionary toggleState = new Dictionary
{
{ "AimbotToggle", false },
+ { "PredictionToggle", false },
{ "AimViewToggle", false },
{ "TriggerBot", false },
{ "CollectData", false },
@@ -95,20 +102,20 @@ public MainWindow()
RequirementsManager RM = new RequirementsManager();
if (!RM.IsVCRedistInstalled())
{
- System.Windows.MessageBox.Show("Visual C++ Redistributables x64 are not installed on this device, please install them before using Aimmy to avoid issues.");
+ System.Windows.MessageBox.Show("Visual C++ Redistributables x64 are not installed on this device, please install them before using Aimmy to avoid issues.", "Load Error");
System.Diagnostics.Process.Start("https://aka.ms/vs/17/release/vc_redist.x64.exe");
}
// Check for required folders
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
- string[] dirs = { "bin", "bin/models", "bin/images" };
+ string[] dirs = { "bin", "bin/models", "bin/images", "bin/configs" };
foreach (string dir in dirs)
{
string fullPath = Path.Combine(baseDir, dir);
if (!Directory.Exists(fullPath))
{
- System.Windows.MessageBox.Show($"The '{dir}' folder does not exist, please ensure the folder is in the same directory as the exe.");
+ System.Windows.MessageBox.Show($"The '{dir}' folder does not exist, please ensure the folder is in the same directory as the exe.", "Load Error");
System.Windows.Application.Current.Shutdown();
}
}
@@ -145,16 +152,22 @@ public MainWindow()
InitializeFileWatcher();
InitializeConfigWatcher();
+ // Load PredictionManager
+ predictionManager = new PredictionManager();
+ predictionManager.InitializeKalmanFilter();
+
// Load all models into listbox
LoadModelsIntoListBox();
LoadConfigsIntoListBox();
- //InitializeModel();
+
SelectorListBox.SelectionChanged += new SelectionChangedEventHandler(SelectorListBox_SelectionChanged);
ConfigSelectorListBox.SelectionChanged += new SelectionChangedEventHandler(ConfigSelectorListBox_SelectionChanged);
+ // Create FOV Overlay
FOVOverlay = new OverlayWindow();
FOVOverlay.Hide();
FOVOverlay.FovSize = (int)aimmySettings["FOV_Size"];
+
// Start the loop that runs the model
Task.Run(() => StartModelCaptureLoop());
}
@@ -246,7 +259,6 @@ public async Task ModelCapture(bool TriggerOnly = false)
if (!TriggerOnly)
{
- // Scale the coordinates from the 640x640 image to the actual screen size
float scaleX = (float)ScreenWidth / 640f;
float scaleY = (float)ScreenHeight / 640f;
@@ -255,9 +267,19 @@ public async Task ModelCapture(bool TriggerOnly = false)
int detectedX = (int)((closestPrediction.Rectangle.X * scaleX) + XOffset);
int detectedY = (int)((closestPrediction.Rectangle.Y * scaleY) + YOffset);
- MoveCrosshair(detectedX, detectedY);
+ // Handle Prediction
+ if (toggleState["PredictionToggle"])
+ {
+ predictionManager.UpdateKalmanFilter(detectedX, detectedY);
+ var predictedPosition = predictionManager.GetEstimatedPosition();
+ MoveCrosshair(predictedPosition.X, predictedPosition.Y);
+ }
+ else
+ {
+ MoveCrosshair(detectedX, detectedY);
+ }
}
- else
+ else
{
Task.Run(() => DoTriggerClick());
}
@@ -324,7 +346,7 @@ private void SetToggleState(AToggle toggle)
// Stop them from turning on anything until model has been selected.
if ((toggle.Reader.Name == "AimbotToggle" || toggle.Reader.Name == "TriggerBot" || toggle.Reader.Name == "CollectData") && lastLoadedModel == "N/A")
{
- System.Windows.MessageBox.Show("Please select a model in the Model Selector before toggling.");
+ System.Windows.MessageBox.Show("Please select a model in the Model Selector before toggling.", "Toggle Error");
return;
}
@@ -458,11 +480,6 @@ void LoadAimMenu()
SetupToggle(Enable_AIAimAligner, state => Bools.AIAimAligner = state, Bools.AIAimAligner);
AimScroller.Children.Add(Enable_AIAimAligner);
- /*AToggle ThirdPersonAim = new AToggle("Enable Third Person Aim");
- ThirdPersonAim.Reader.Name = "AimViewToggle";
- SetupToggle(ThirdPersonAim, state => Bools.ThirdPersonAim = state, Bools.ThirdPersonAim);
- AimScroller.Children.Add(ThirdPersonAim);*/
-
AKeyChanger Change_KeyPress = new AKeyChanger("Change Keybind", "Right");
Change_KeyPress.Reader.Click += (s, x) =>
{
@@ -477,6 +494,12 @@ void LoadAimMenu()
AimScroller.Children.Add(Change_KeyPress);
+ AToggle Enable_AIPredictions = new AToggle(this, "Enable Predictions",
+ "This will use a KalmanFilter algorithm to predict aim patterns for better tracing of enemies.");
+ Enable_AIPredictions.Reader.Name = "PredictionToggle";
+ SetupToggle(Enable_AIPredictions, state => Bools.AIPredictions = state, Bools.AIPredictions);
+ AimScroller.Children.Add(Enable_AIPredictions);
+
AToggle Show_FOV = new AToggle(this, "Show FOV",
"This will show a circle around your screen that show what the AI is considering on the screen at a given moment.");
Show_FOV.Reader.Name = "ShowFOV";
@@ -626,7 +649,6 @@ private void LoadModelsIntoListBox()
SelectorListBox.Items.Add(fileName);
}
- // Preselect the first file in the ListBox
if (SelectorListBox.Items.Count > 0)
{
if (!SelectorListBox.Items.Contains(lastLoadedModel) && lastLoadedModel != "N/A")
@@ -640,11 +662,6 @@ private void LoadModelsIntoListBox()
}
SelectedModelNotifier.Content = "Loaded Model: " + lastLoadedModel;
}
- else
- {
- System.Windows.MessageBox.Show("No models found, please put a .onnx model in bin/models.");
- System.Windows.Application.Current.Shutdown();
- }
}
private void SelectorListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -652,13 +669,9 @@ private void SelectorListBox_SelectionChanged(object sender, SelectionChangedEve
InitializeModel();
}
- // nori's config stuff, might need optimization later
-
- #region N4ri's Config Code (god please fix this)
-
void LoadConfig(string path)
{
- if (ConfigSelectorListBox.SelectedItem != null)
+ if (ConfigSelectorListBox.SelectedItem != null && lastLoadedModel != "N/A")
{
dynamic AimmyJSON = JsonConvert.DeserializeObject(File.ReadAllText(path));
@@ -666,14 +679,28 @@ void LoadConfig(string path)
"\n" +
AimmyJSON.Suggested_Model, "Suggested Model - Aimmy");
- aimmySettings["FOV_Size"] = AimmyJSON.FOV_Size;
+ aimmySettings["FOV_Size"] = (int)AimmyJSON.FOV_Size;
+ FOVOverlay.FovSize = (int)aimmySettings["FOV_Size"];
+ _onnxModel.FovSize = (int)aimmySettings["FOV_Size"];
+
aimmySettings["Mouse_Sens"] = AimmyJSON.Mouse_Sensitivity;
aimmySettings["Y_Offset"] = AimmyJSON.Y_Offset;
aimmySettings["X_Offset"] = AimmyJSON.X_Offset;
aimmySettings["Trigger_Delay"] = AimmyJSON.Auto_Trigger_Delay;
+
aimmySettings["AI_Min_Conf"] = AimmyJSON.AI_Minimum_Confidence;
+ _onnxModel.ConfidenceThreshold = (float)(aimmySettings["AI_Min_Conf"] / 100.0f);
+
+ lastLoadedConfig = ConfigSelectorListBox.SelectedItem.ToString();
+
+ // Reload the UI
ReloadMenu();
}
+ else
+ {
+ ConfigSelectorListBox.SelectedItem = null;
+ System.Windows.MessageBox.Show("Please select a model in the Model Selector before loading a config.", "Config Error");
+ }
}
void ReloadMenu()
@@ -697,13 +724,13 @@ private void ConfigWatcher_Reload(object sender, FileSystemEventArgs e)
private void InitializeConfigWatcher()
{
- fileWatcher = new FileSystemWatcher();
- fileWatcher.Path = "bin/configs";
- fileWatcher.Filter = "*.json";
- fileWatcher.EnableRaisingEvents = true;
- fileWatcher.Created += ConfigWatcher_Reload;
- fileWatcher.Deleted += ConfigWatcher_Reload;
- fileWatcher.Renamed += ConfigWatcher_Reload;
+ ConfigfileWatcher = new FileSystemWatcher();
+ ConfigfileWatcher.Path = "bin/configs";
+ ConfigfileWatcher.Filter = "*.json";
+ ConfigfileWatcher.EnableRaisingEvents = true;
+ ConfigfileWatcher.Created += ConfigWatcher_Reload;
+ ConfigfileWatcher.Deleted += ConfigWatcher_Reload;
+ ConfigfileWatcher.Renamed += ConfigWatcher_Reload;
}
private void LoadConfigsIntoListBox()
@@ -717,42 +744,42 @@ private void LoadConfigsIntoListBox()
ConfigSelectorListBox.Items.Add(fileName);
}
- // Preselect the first file in the ListBox
if (ConfigSelectorListBox.Items.Count > 0)
{
- if (!ConfigSelectorListBox.Items.Contains(lastLoadedModel) && lastLoadedModel != "N/A")
+ if (!ConfigSelectorListBox.Items.Contains(lastLoadedConfig) && lastLoadedConfig != "N/A")
{
ConfigSelectorListBox.SelectedIndex = 0;
- lastLoadedModel = ConfigSelectorListBox.Items[0].ToString();
+ lastLoadedConfig = ConfigSelectorListBox.Items[0].ToString();
}
else
{
- SelectorListBox.SelectedItem = lastLoadedModel;
+ ConfigSelectorListBox.SelectedItem = lastLoadedConfig;
}
- SelectedModelNotifier.Content = "Loaded Model: " + lastLoadedModel;
- }
- else
- {
- System.Windows.MessageBox.Show("No configs found, please put a .json file in bin/configs.");
- System.Windows.Application.Current.Shutdown();
+ SelectedConfigNotifier.Content = "Loaded Config: " + lastLoadedConfig;
}
}
private void ConfigSelectorListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
- LoadConfig($"bin/configs/{ConfigSelectorListBox.SelectedItem.ToString()}");
+ if (ConfigSelectorListBox.SelectedItem != null)
+ {
+ LoadConfig($"bin/configs/{ConfigSelectorListBox.SelectedItem.ToString()}");
+ }
}
- #endregion
void LoadModelStoreMenu()
{
if (AvailableModels.Count > 0)
{
foreach (var entries in AvailableModels)
+ {
ModelStoreScroller.Children.Add(new ADownloadGateway(entries));
+ }
}
else
+ {
LackOfModelsText.Visibility = Visibility.Visible;
+ }
}
void LoadSettingsMenu()
@@ -786,7 +813,7 @@ void LoadSettingsMenu()
// Prevent double messageboxes..
if (AIMinimumConfidence.Slider.Value != aimmySettings["AI_Min_Conf"])
{
- System.Windows.MessageBox.Show("Unable to set confidence, please select a model and try again.");
+ System.Windows.MessageBox.Show("Unable to set confidence, please select a model and try again.", "Slider Error");
AIMinimumConfidence.Slider.Value = aimmySettings["AI_Min_Conf"];
}
}
diff --git a/AimmyWPF/OverlayWindow.xaml.cs b/AimmyWPF/OverlayWindow.xaml.cs
index 43f79f0d..2074c982 100644
--- a/AimmyWPF/OverlayWindow.xaml.cs
+++ b/AimmyWPF/OverlayWindow.xaml.cs
@@ -1,16 +1,11 @@
using System;
using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
using System.Windows.Media;
-using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
+using static AimmyWPF.MainWindow;
namespace AimmyWPF
{
@@ -25,7 +20,7 @@ public OverlayWindow()
{
InitializeComponent();
var timer = new DispatcherTimer();
- timer.Interval = TimeSpan.FromMilliseconds(100);
+ timer.Interval = TimeSpan.FromMilliseconds(250);
timer.Tick += Timer_Tick;
timer.Start();
}
diff --git a/AimmyWPF/PredictionManager.cs b/AimmyWPF/PredictionManager.cs
new file mode 100644
index 00000000..a40d7ee3
--- /dev/null
+++ b/AimmyWPF/PredictionManager.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Accord.Math;
+using Accord.Statistics.Filters;
+using Accord.Statistics.Running;
+using static Accord.Math.FourierTransform;
+
+namespace AimmyWPF
+{
+ internal class PredictionManager
+ {
+ public struct Detection
+ {
+ public int X;
+ public int Y;
+ public DateTime Timestamp;
+ }
+
+ KalmanFilter2D kalmanFilter;
+
+ public void InitializeKalmanFilter()
+ {
+ kalmanFilter = new KalmanFilter2D();
+ }
+
+ public void UpdateKalmanFilter(double detectedX, double detectedY)
+ {
+ kalmanFilter.Push(detectedX, detectedY);
+ }
+
+ public Detection GetEstimatedPosition()
+ {
+ // Current estimated position
+ double currentX = kalmanFilter.X;
+ double currentY = kalmanFilter.Y;
+
+ // Current velocity
+ double velocityX = kalmanFilter.XAxisVelocity;
+ double velocityY = kalmanFilter.YAxisVelocity;
+
+ // Predict next position based on current position and velocity
+ double timeStep = 0.01;
+ double predictedX = currentX + velocityX * timeStep;
+ double predictedY = currentY + velocityY * timeStep;
+
+ return new Detection { X = (int)predictedX, Y = (int)predictedY };
+ }
+ }
+}
diff --git a/AimmyWPF/UserController/AInfoSection.xaml b/AimmyWPF/UserController/AInfoSection.xaml
index 40df5785..03569871 100644
--- a/AimmyWPF/UserController/AInfoSection.xaml
+++ b/AimmyWPF/UserController/AInfoSection.xaml
@@ -91,7 +91,7 @@
materialDesign:ButtonAssist.CornerRadius="5" />