From 84ad07d7eb6eb8d15734899605d8ce13cb0836d0 Mon Sep 17 00:00:00 2001 From: minisbett <39670899+minisbett@users.noreply.github.com> Date: Sat, 27 Jul 2024 19:52:12 +0200 Subject: [PATCH 1/4] Fine-tune score simulation display --- huisbot/Models/Huis/HuisRework.cs | 10 ++++++ huisbot/Modules/Huis/Simulate.cs | 4 +-- huisbot/Utilities/Discord/Embeds.cs | 50 +++++++++++++++-------------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/huisbot/Models/Huis/HuisRework.cs b/huisbot/Models/Huis/HuisRework.cs index d75c31a..88e9f54 100644 --- a/huisbot/Models/Huis/HuisRework.cs +++ b/huisbot/Models/Huis/HuisRework.cs @@ -154,4 +154,14 @@ public string RulesetName _ => "Unknown" }; } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public override bool Equals(object? obj) + { + return obj is HuisRework rework && Id == rework.Id; + } } diff --git a/huisbot/Modules/Huis/Simulate.cs b/huisbot/Modules/Huis/Simulate.cs index 7ebffe1..c065b02 100644 --- a/huisbot/Modules/Huis/Simulate.cs +++ b/huisbot/Modules/Huis/Simulate.cs @@ -104,7 +104,7 @@ public async Task HandleAsync( }; // Display the simulation progress in an embed to the user. - IUserMessage msg = await FollowupAsync(embed: Embeds.Simulating(rework, refRework, false, rework.Id == refRework.Id)); + IUserMessage msg = await FollowupAsync(embed: Embeds.Simulating(rework, refRework, false, rework == refRework)); // Get the local result from the Huis API and check whether it was successful. HuisSimulationResponse? localScore = await SimulateScoreAsync(request); @@ -113,7 +113,7 @@ public async Task HandleAsync( // If the requested rework is the same as the reference, simulation is done here. HuisSimulationResponse? refScore = localScore; - if (rework.Id != refRework.Id) + if (rework != refRework) { // Switch the request to target the reference rework and update the simulation progress embed. request.Rework = refRework; diff --git a/huisbot/Utilities/Discord/Embeds.cs b/huisbot/Utilities/Discord/Embeds.cs index bfef54d..5106e36 100644 --- a/huisbot/Utilities/Discord/Embeds.cs +++ b/huisbot/Utilities/Discord/Embeds.cs @@ -182,7 +182,7 @@ public static Embed Info(bool osuV1Available, bool osuV2Available, bool huisAvai public static Embed Simulating(HuisRework local, HuisRework reference, bool localDone, bool localOnly = false) { // Build the status string. - string status = localDone ? "*Calculating reference score...*" : "*Calculating local score...*"; + string status = localDone ? "*Calculating reference score...*" : "*Calculating local score...*"; status += $"\n\n{new DEmoji(localDone ? "✅" : "⏳")} {local.Name}"; if (!localOnly) status += $"\n{new DEmoji(localDone ? "⏳" : "🕐")} {reference.Name}"; @@ -195,24 +195,29 @@ public static Embed Simulating(HuisRework local, HuisRework reference, bool loca /// /// Returns an embed for displaying the difference between two simulated scores. /// - /// The first simulated score for comparison. - /// The second simulated for score for comparison. + /// The local simulated score for comparison. + /// The simulated reference for score for comparison. /// The rework. /// The beatmap. - /// An embed for displaying a calculated score - public static Embed SimulatedScore(HuisSimulationResponse local, HuisSimulationResponse live, HuisRework rework, HuisRework referenceRework, OsuBeatmap beatmap) + /// An embed for displaying a the simulated score in comparison to the reference score. + public static Embed SimulatedScore(HuisSimulationResponse local, HuisSimulationResponse reference, HuisRework rework, HuisRework refRework, OsuBeatmap beatmap) { // Construct the PP info string. - string ppStr = $"▸ **PP**: {GetPPDifferenceText(live.PerformanceAttributes.PP, local.PerformanceAttributes.PP)}"; - ppStr += $"\n▸ **Aim**: {GetPPDifferenceText(live.PerformanceAttributes.AimPP, local.PerformanceAttributes.AimPP)}"; - ppStr += $"\n▸ **Tap**: {GetPPDifferenceText(live.PerformanceAttributes.TapPP, local.PerformanceAttributes.TapPP)}"; - ppStr += $"\n▸ **Acc**: {GetPPDifferenceText(live.PerformanceAttributes.AccPP, local.PerformanceAttributes.AccPP)}"; + string ppStr = $"▸ **PP**: {GetPPDifferenceText(reference.PerformanceAttributes.PP, local.PerformanceAttributes.PP)}"; + ppStr += $"\n▸ **Aim**: {GetPPDifferenceText(reference.PerformanceAttributes.AimPP, local.PerformanceAttributes.AimPP)}"; + ppStr += $"\n▸ **Tap**: {GetPPDifferenceText(reference.PerformanceAttributes.TapPP, local.PerformanceAttributes.TapPP)}"; + ppStr += $"\n▸ **Acc**: {GetPPDifferenceText(reference.PerformanceAttributes.AccPP, local.PerformanceAttributes.AccPP)}"; if (local.PerformanceAttributes.FLPP is not null) - ppStr += $"\n▸ **FL**: {GetPPDifferenceText(live.PerformanceAttributes.FLPP ?? 0, local.PerformanceAttributes.FLPP.Value)}"; + ppStr += $"\n▸ **FL**: {GetPPDifferenceText(reference.PerformanceAttributes.FLPP ?? 0, local.PerformanceAttributes.FLPP.Value)}"; if (local.PerformanceAttributes.CogPP is not null) - ppStr += $"\n▸ **Cog**: {GetPPDifferenceText(live.PerformanceAttributes.CogPP ?? 0, local.PerformanceAttributes.CogPP.Value)}"; + ppStr += $"\n▸ **Cog**: {GetPPDifferenceText(reference.PerformanceAttributes.CogPP ?? 0, local.PerformanceAttributes.CogPP.Value)}"; // Construct some more strings for the embed. + double refDiff = reference.DifficultyAttributes.DifficultyRating; + double localDiff = local.DifficultyAttributes.DifficultyRating; + string comparison1 = localDiff == refDiff ? localDiff.ToString("N2") : $"{refDiff:N2}→{localDiff:N2}"; + string comparison2 = rework == refRework ? "PP Overview" : "PP Comparison (Ref → Local)"; + string comparison3 = rework == refRework ? rework.Name! : $"{refRework.Name} → {rework.Name}"; string hits = $"{local.Score.Statistics.Count300} {_emojis["300"]} {local.Score.Statistics.Count100} {_emojis["100"]} {local.Score.Statistics.Count50} {_emojis["50"]} {local.Score.Statistics.Misses} {_emojis["miss"]}"; string combo = $"{local.Score.MaxCombo}/{beatmap.MaxCombo}x"; string stats1 = $"{beatmap.CircleCount} {_emojis["circles"]} {beatmap.SliderCount} {_emojis["sliders"]} {beatmap.SpinnerCount} {_emojis["spinners"]}"; @@ -227,12 +232,12 @@ public static Embed SimulatedScore(HuisSimulationResponse local, HuisSimulationR return BaseEmbed .WithColor(new Color(0x4061E9)) - .WithTitle($"{beatmap.Artist} - {beatmap.Title} [{beatmap.Version}]{local.Score.Mods.PlusString} ({live.DifficultyAttributes.DifficultyRating:N2}→{local.DifficultyAttributes.DifficultyRating:N2}★)") - .AddField("PP Comparison (Reference → Local)", $"{ppStr}\n\n{visualizer} • {osu}\n{huisRework} • {github}", true) + .WithTitle($"{beatmap.Artist} - {beatmap.Title} [{beatmap.Version}]{local.Score.Mods.PlusString} ({comparison1}★)") + .AddField(comparison2, $"{ppStr}\n\n{visualizer} • {osu}\n{huisRework} • {github}", true) .AddField("Score Info", $"▸ {local.Score.Accuracy:N2}% ▸ {combo}\n▸ {hits}\n▸ {stats1}\n▸ {stats2}\n▸ {stats3}\n▸ {stats4}", true) .WithUrl($"https://osu.ppy.sh/b/{beatmap.Id}") .WithImageUrl($"https://assets.ppy.sh/beatmaps/{beatmap.SetId}/covers/slimcover@2x.jpg") - .WithFooter($"{referenceRework.Name} → {rework.Name} • {BaseEmbed.Footer.Text}", BaseEmbed.Footer.IconUrl) + .WithFooter($"{comparison3} • {BaseEmbed.Footer.Text}", BaseEmbed.Footer.IconUrl) .Build(); } @@ -479,19 +484,16 @@ public static Embed Feedback(IUser user, HuisRework rework, string text) => Base /// A string representing the difference between two PP values. private static string GetPPDifferenceText(double oldPP, double newPP) { - // Round the PP values if they're above 1000, as that's irrelevant info and hurts the display flexibility. - if (oldPP >= 1000) - oldPP = Math.Round(oldPP); - if (newPP >= 1000) - newPP = Math.Round(newPP); - - // Calculate the difference between the two PP values. If it's less than 0.01, the PP values are the same. - double difference = newPP - oldPP; - if (Math.Abs(difference) < 0.01) + // Round the PP values, as decimals are irrelevant info and hurts the display flexibility. + oldPP = Math.Round(oldPP); + newPP = Math.Round(newPP); + + // If the PP do not differ, simply return the PP value. + if (newPP == oldPP) return $"**{newPP:0.##}pp**"; // Otherwise return the difference string. - return $"{oldPP:0.##} → **{newPP:0.##}pp** *({difference:+#,##0.##;-#,##0.##}pp)*"; + return $"{oldPP:0.##}pp → **{newPP:0.##}pp** ({newPP - oldPP:+#,##0.##;-#,##0.##}pp)"; } /// From 3eb61c75db655b911a8d6ddabd2a8f535a7d74f1 Mon Sep 17 00:00:00 2001 From: minisbett <39670899+minisbett@users.noreply.github.com> Date: Sat, 27 Jul 2024 19:52:27 +0200 Subject: [PATCH 2/4] Bump version --- huisbot/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/huisbot/Program.cs b/huisbot/Program.cs index 6743019..8e953e9 100644 --- a/huisbot/Program.cs +++ b/huisbot/Program.cs @@ -19,7 +19,7 @@ public class Program /// /// The version of the application. /// - public const string VERSION = "2.3.0"; + public const string VERSION = "2.3.1"; /// /// The startup time of the application. From 683f35892096631a5603f016c1e5a43aa29993ee Mon Sep 17 00:00:00 2001 From: minisbett <39670899+minisbett@users.noreply.github.com> Date: Sat, 27 Jul 2024 19:54:03 +0200 Subject: [PATCH 3/4] Add missing namespace to Program.cs --- huisbot/Program.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/huisbot/Program.cs b/huisbot/Program.cs index 8e953e9..2df77f1 100644 --- a/huisbot/Program.cs +++ b/huisbot/Program.cs @@ -14,6 +14,8 @@ using Newtonsoft.Json; using System.Globalization; +namespace huisbot; + public class Program { /// @@ -172,4 +174,4 @@ public static async Task MainAsync(string[] args) // Run the host. await host.RunAsync(); } -} +} \ No newline at end of file From 3ea33f949dfdf50b27c7eedecece1b3dad731fb2 Mon Sep 17 00:00:00 2001 From: minisbett <39670899+minisbett@users.noreply.github.com> Date: Sat, 27 Jul 2024 20:07:50 +0200 Subject: [PATCH 4/4] update osu api service to process lazer score ids instead --- huisbot/Modules/Alias.cs | 2 +- huisbot/Modules/Huis/Simulate.cs | 2 +- huisbot/Modules/ModuleBase.cs | 4 ++-- huisbot/Services/OsuApiService.cs | 20 +++++--------------- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/huisbot/Modules/Alias.cs b/huisbot/Modules/Alias.cs index 14c14b9..f43a86b 100644 --- a/huisbot/Modules/Alias.cs +++ b/huisbot/Modules/Alias.cs @@ -169,7 +169,7 @@ public async Task HandleAddAsync( } // Get the score. - OsuScore? score = await GetScoreAsync(0 /* TODO: Support for other rulsets */, scoreId.ToString()); + OsuScore? score = await GetScoreAsync(scoreId.ToString()); if (score is null) return; diff --git a/huisbot/Modules/Huis/Simulate.cs b/huisbot/Modules/Huis/Simulate.cs index c065b02..dd3044a 100644 --- a/huisbot/Modules/Huis/Simulate.cs +++ b/huisbot/Modules/Huis/Simulate.cs @@ -72,7 +72,7 @@ public async Task HandleAsync( // If a score was specified, get the score and fill the unset parameters with it's attributes. if (scoreId is not null) { - OsuScore? score = await GetScoreAsync(rework.RulesetId, scoreId); + OsuScore? score = await GetScoreAsync(scoreId); if (score is null) return; diff --git a/huisbot/Modules/ModuleBase.cs b/huisbot/Modules/ModuleBase.cs index e571534..4fc158a 100644 --- a/huisbot/Modules/ModuleBase.cs +++ b/huisbot/Modules/ModuleBase.cs @@ -299,7 +299,7 @@ public async Task QueuePlayerAsync(OsuUser player, int reworkId, ulong dis /// /// An identifier for the score. (Score ID or alias) /// The score. - public async Task GetScoreAsync(int rulesetId, string scoreId) + public async Task GetScoreAsync(string scoreId) { // If the identifier is not a number, try to find a score alias. if (!scoreId.All(char.IsDigit)) @@ -315,7 +315,7 @@ public async Task QueuePlayerAsync(OsuUser player, int reworkId, ulong dis scoreId = alias.ScoreId.ToString(); } // Get the score from the osu! API. If it failed or the score was not found, notify the user. - NotFoundOr? score = await _osu.GetScoreAsync(rulesetId, long.Parse(scoreId)); + NotFoundOr? score = await _osu.GetScoreAsync(long.Parse(scoreId)); if (score is null) await ModifyOriginalResponseAsync(x => x.Embed = Embeds.InternalError("Failed to get the score from the osu! API.")); else if (!score.Found) diff --git a/huisbot/Services/OsuApiService.cs b/huisbot/Services/OsuApiService.cs index 3380b1c..69cd379 100644 --- a/huisbot/Services/OsuApiService.cs +++ b/huisbot/Services/OsuApiService.cs @@ -198,30 +198,20 @@ public async Task EnsureAccessTokenAsync() } /// - /// Returns the score with the specified ID in the specified ruleset. + /// Returns the score with the specified ID. /// - /// The ruleset ID. /// The score ID. /// The score with the specified ID./returns> - public async Task?> GetScoreAsync(int rulesetId, long scoreId) + public async Task?> GetScoreAsync(long scoreId) { // Make sure a valid access token exists. If not, return null. if (!await EnsureAccessTokenAsync()) return null; - // Get the string version of the ruleset ID. - string ruleset = rulesetId switch - { - 1 => "taiko", - 2 => "fruits", - 3 => "mania", - _ => "osu" - }; - try { // Get the score from the API and check whether a 404 was returned. If so, the score was not found. - HttpResponseMessage response = await _http.GetAsync($"api/v2/scores/{ruleset}/{scoreId}"); + HttpResponseMessage response = await _http.GetAsync($"api/v2/scores/{scoreId}"); if (response.StatusCode == HttpStatusCode.NotFound) return NotFoundOr.NotFound; @@ -231,8 +221,8 @@ public async Task EnsureAccessTokenAsync() } catch (Exception ex) { - _logger.LogError("Failed to get the score with ID {Id} in ruleset {Ruleset} from the osu! API: {Message}", - scoreId, rulesetId, ex.Message); + _logger.LogError("Failed to get the score with ID {Id} from the osu! API: {Message}", + scoreId, ex.Message); return null; } }