diff --git a/Osu.Patcher.Hook/Patches/LivePerformance/PatchUpdatePerformanceCalculator.cs b/Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackOnScoreHit.cs
similarity index 58%
rename from Osu.Patcher.Hook/Patches/LivePerformance/PatchUpdatePerformanceCalculator.cs
rename to Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackOnScoreHit.cs
index 0b2dccf..587e180 100644
--- a/Osu.Patcher.Hook/Patches/LivePerformance/PatchUpdatePerformanceCalculator.cs
+++ b/Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackOnScoreHit.cs
@@ -1,8 +1,6 @@
using System;
-using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
-using System.Threading;
using HarmonyLib;
using JetBrains.Annotations;
using Osu.Performance;
@@ -10,38 +8,14 @@
namespace Osu.Patcher.Hook.Patches.LivePerformance;
+///
+/// Hooks Ruleset::OnIncreaseScoreHit(...) to send score updates to our performance calculator
+/// so it can recalculate based on new HitObject judgements.
+///
[HarmonyPatch]
[UsedImplicitly]
-public static class PatchUpdatePerformanceCalculator
+public static class PatchTrackOnScoreHit
{
- private static OsuPerformance? _performance;
-
- internal static void ResetCalculator() => new Thread(() =>
- {
- Debug.WriteLine("Resetting performance calculator");
-
- _performance?.Dispose();
- _performance = null;
-
- var currentScore = Player.CurrentScore.Get();
- if (currentScore == null) return;
-
- var modsObfuscated = Score.EnabledMods.Get(currentScore);
- var mods = Score.EnabledModsGetValue.Invoke(modsObfuscated);
-
- // Clear relax mod for now (live pp calculations for relax are fucking garbage)
- mods &= ~(1 << 7);
-
- var beatmap = Score.Beatmap.Get(currentScore);
- if (beatmap == null) return;
-
- var beatmapPath = Beatmap.GetBeatmapPath(beatmap);
- if (beatmapPath == null) return;
-
- _performance = new OsuPerformance(beatmapPath, (uint)mods);
- _performance.OnNewCalculation += Console.WriteLine;
- }).Start();
-
[UsedImplicitly]
[HarmonyTargetMethod]
private static MethodBase Target() => Ruleset.OnIncreaseScoreHit.Reference;
@@ -54,7 +28,12 @@ private static void After(
[HarmonyArgument(0)] int increaseScoreType,
[HarmonyArgument(2)] bool increaseCombo)
{
- if (_performance == null) return;
+ Console.WriteLine(increaseScoreType);
+ if (!PerformanceCalculator.IsInitialized)
+ {
+ Console.WriteLine("OnIncreaseScoreHit called before performance calculator initialized!");
+ return;
+ }
var judgement = (increaseScoreType & ~IncreaseScoreType.OsuComboModifiers) switch
{
@@ -74,7 +53,7 @@ private static void After(
var CurrentScore = Ruleset.CurrentScore.Get(__instance);
var MaxCombo = Score.MaxCombo.Get(CurrentScore);
- _performance.AddJudgement(judgement, (uint)MaxCombo);
+ PerformanceCalculator.Calculator?.AddJudgement(judgement, (uint)MaxCombo);
}
[UsedImplicitly]
@@ -84,7 +63,7 @@ private static void Finalizer(Exception? __exception)
{
if (__exception != null)
{
- Console.WriteLine($"Exception due to {nameof(PatchUpdatePerformanceCalculator)}: {__exception}");
+ Console.WriteLine($"Exception due to {nameof(PatchTrackOnScoreHit)}: {__exception}");
}
}
}
\ No newline at end of file
diff --git a/Osu.Patcher.Hook/Patches/LivePerformance/PatchClearPerformanceCalculator.cs b/Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackResetScore.cs
similarity index 65%
rename from Osu.Patcher.Hook/Patches/LivePerformance/PatchClearPerformanceCalculator.cs
rename to Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackResetScore.cs
index 30c5e8a..e30e2a9 100644
--- a/Osu.Patcher.Hook/Patches/LivePerformance/PatchClearPerformanceCalculator.cs
+++ b/Osu.Patcher.Hook/Patches/LivePerformance/PatchTrackResetScore.cs
@@ -7,9 +7,12 @@
namespace Osu.Patcher.Hook.Patches.LivePerformance;
+///
+/// Hooks Ruleset::ResetScore() to also reset our performance calculator.
+///
[HarmonyPatch]
[UsedImplicitly]
-internal class PatchClearPerformanceCalculator
+internal class PatchTrackResetScore
{
[UsedImplicitly]
[HarmonyTargetMethod]
@@ -17,7 +20,7 @@ internal class PatchClearPerformanceCalculator
[UsedImplicitly]
[HarmonyPostfix]
- private static void After() => PatchUpdatePerformanceCalculator.ResetCalculator();
+ private static void After() => PerformanceCalculator.ResetCalculator();
[UsedImplicitly]
[HarmonyFinalizer]
@@ -26,7 +29,7 @@ private static void Finalizer(Exception? __exception)
{
if (__exception != null)
{
- Console.WriteLine($"Exception due to {nameof(PatchClearPerformanceCalculator)}: {__exception}");
+ Console.WriteLine($"Exception due to {nameof(PatchTrackResetScore)}: {__exception}");
}
}
}
\ No newline at end of file
diff --git a/Osu.Patcher.Hook/Patches/LivePerformance/PerformanceCalculator.cs b/Osu.Patcher.Hook/Patches/LivePerformance/PerformanceCalculator.cs
new file mode 100644
index 0000000..e2abaa2
--- /dev/null
+++ b/Osu.Patcher.Hook/Patches/LivePerformance/PerformanceCalculator.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Diagnostics;
+using Osu.Performance;
+using Osu.Stubs;
+
+namespace Osu.Patcher.Hook.Patches.LivePerformance;
+
+///
+/// Handles initializing and disposing the performance calculator based on current score and settings.
+///
+internal static class PerformanceCalculator
+{
+ public static OsuPerformance? Calculator { get; private set; }
+
+ public static bool IsInitialized => Calculator != null;
+
+ ///
+ /// Disposes the existing performance calculator, and initializes a new one according to the current score info.
+ /// This must be called after Ruleset::ResetScore()
+ ///
+ public static void ResetCalculator()
+ {
+ try
+ {
+ ResetCalculatorSync();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Failed to reset performance calculator: {e}");
+ }
+ }
+
+ private static void ResetCalculatorSync()
+ {
+ Debug.WriteLine("Resetting performance calculator");
+
+ // TODO: don't dispose it if the beatmap is the same, reuse parsed beatmap in native side
+ Calculator?.Dispose();
+ Calculator = null;
+
+ var currentScore = Player.CurrentScore.Get();
+ if (currentScore == null) return;
+
+ var modsObfuscated = Score.EnabledMods.Get(currentScore);
+ var mods = Score.EnabledModsGetValue.Invoke(modsObfuscated);
+
+ // Clear relax mod for now (live pp calculations for relax are fucking garbage)
+ mods &= ~(1 << 7);
+
+ var beatmap = Score.Beatmap.Get(currentScore);
+ if (beatmap == null) return;
+
+ var beatmapPath = Beatmap.GetBeatmapPath(beatmap);
+ if (beatmapPath == null) return;
+
+ Calculator = new OsuPerformance(beatmapPath, (uint)mods);
+ Calculator.OnNewCalculation += Console.WriteLine;
+
+ Debug.WriteLine("Initialized performance calculator!");
+ }
+}
\ No newline at end of file