diff --git a/AutoClicker/AutoClicker.csproj b/AutoClicker/AutoClicker.csproj index 3a284a6..e63cbe8 100644 --- a/AutoClicker/AutoClicker.csproj +++ b/AutoClicker/AutoClicker.csproj @@ -56,6 +56,9 @@ packages\CommonServiceLocator.2.0.6\lib\net48\CommonServiceLocator.dll + + packages\MathNet.Numerics.5.0.0\lib\net48\MathNet.Numerics.dll + packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll diff --git a/AutoClicker/Views/MainWindow.xaml.cs b/AutoClicker/Views/MainWindow.xaml.cs index f40181e..5960d6e 100644 --- a/AutoClicker/Views/MainWindow.xaml.cs +++ b/AutoClicker/Views/MainWindow.xaml.cs @@ -9,6 +9,7 @@ using AutoClicker.Models; using AutoClicker.Utils; using Serilog; +using MathNet.Numerics.Distributions; using CheckBox = System.Windows.Controls.CheckBox; using MouseAction = AutoClicker.Enums.MouseAction; using MouseButton = AutoClicker.Enums.MouseButton; @@ -32,7 +33,11 @@ public AutoClickerSettings AutoClickerSettings new UIPropertyMetadata(SettingsUtils.CurrentSettings.AutoClickerSettings)); private int timesRepeated = 0; - private readonly Timer clickTimer; + private Timer clickTimer; + private double cpsMean = 1.0; + private double cpsSDev = 0.25; + private MathNet.Numerics.Distributions.Normal cpsDistribution; + private readonly Uri runningIconUri = new Uri(Constants.RUNNING_ICON_RESOURCE_PATH, UriKind.Relative); @@ -118,10 +123,12 @@ protected override void OnClosed(EventArgs e) private void StartCommand_Execute(object sender, ExecutedRoutedEventArgs e) { int interval = CalculateInterval(); - Log.Information("Starting operation, interval={Interval}ms", interval); - + cpsMean = (interval <= 0) ? 0.5 : 1000 / (double)interval; + cpsDistribution = new Normal(cpsMean, cpsSDev); + clickTimer.Interval = (int)Math.Round(1000 / cpsDistribution.Sample()); timesRepeated = 0; - clickTimer.Interval = interval; + + Log.Information("Starting operation, cps_avg={cps}, cps_std_dev={dev}, interval={interval}ms", cpsMean, cpsSDev, clickTimer.Interval); clickTimer.Start(); Icon = new BitmapImage(runningIconUri); @@ -236,6 +243,13 @@ private bool IsIntervalValid() return CalculateInterval() > 0; } + private int DistributedInterval() + { + /* Instead of constant if/else checking to avoid zero division, just always skew my 1 ms. + * Shouldn't affect CPS meaningfully in practice. */ + return 1 + (int)Math.Round(1000 / cpsDistribution.Sample()); + } + private bool CanStartOperation() { return !clickTimer.Enabled && IsRepeatModeValid() && IsIntervalValid(); @@ -326,6 +340,7 @@ private void OnClickTimerElapsed(object sender, ElapsedEventArgs e) { InitMouseClick(); timesRepeated++; + clickTimer.Interval = DistributedInterval(); if (timesRepeated == GetTimesToRepeat()) { diff --git a/AutoClicker/packages.config b/AutoClicker/packages.config index a2e3b9f..a05b2a9 100644 --- a/AutoClicker/packages.config +++ b/AutoClicker/packages.config @@ -1,6 +1,7 @@  +