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 @@
+