From 0b4155f30281a4c1bcb05e125c2e3a54647d337e Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 29 May 2024 22:23:05 +0900 Subject: [PATCH 1/7] Simplify callbacks --- .../ServerDifficultyCalculator.cs | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index b3d5aa0..52d4132 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -67,19 +67,19 @@ public void Process(WorkingBeatmap beatmap, ProcessingMode mode) public void ProcessLegacyAttributes(WorkingBeatmap beatmap) => run(beatmap, processLegacyAttributes); - private void run(WorkingBeatmap beatmap, Action callback) + private void run(WorkingBeatmap beatmap, Action callback) { - int beatmapId = beatmap.BeatmapInfo.OnlineID; - try { - if (beatmap.Beatmap.HitObjects.Count == 0) + using (var conn = Database.GetSlaveConnection()) { - using (var conn = Database.GetSlaveConnection()) + bool ranked = conn.QuerySingleOrDefault("SELECT `approved` FROM `osu_beatmaps` WHERE `beatmap_id` = @BeatmapId", new { - if (conn.QuerySingleOrDefault("SELECT `approved` FROM `osu_beatmaps` WHERE `beatmap_id` = @BeatmapId", new { BeatmapId = beatmapId }) > 0) - throw new ArgumentException($"Ranked beatmap {beatmapId} has 0 hitobjects!"); - } + BeatmapId = beatmap.BeatmapInfo.OnlineID + }) > 0; + + if (ranked && beatmap.Beatmap.HitObjects.Count == 0) + throw new ArgumentException($"Ranked beatmap {beatmap.BeatmapInfo.OnlineInfo} has 0 hitobjects!"); } using (var conn = Database.GetConnection()) @@ -87,26 +87,26 @@ private void run(WorkingBeatmap beatmap, Action r.RulesetInfo.OnlineID == beatmap.BeatmapInfo.Ruleset.OnlineID)) - callback(beatmapId, beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance(), conn); + callback(new ProcessableItem(beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance()), conn); } } catch (Exception e) { - throw new Exception($"{beatmapId} failed with: {e.Message}"); + throw new Exception($"{beatmap.BeatmapInfo.OnlineID} failed with: {e.Message}"); } } - private void processDifficulty(int beatmapId, WorkingBeatmap beatmap, Ruleset ruleset, MySqlConnection conn) + private void processDifficulty(ProcessableItem item, MySqlConnection conn) { - foreach (var attribute in ruleset.CreateDifficultyCalculator(beatmap).CalculateAllLegacyCombinations()) + foreach (var attribute in item.Ruleset.CreateDifficultyCalculator(item.Beatmap).CalculateAllLegacyCombinations()) { if (dryRun) continue; - LegacyMods legacyMods = ruleset.ConvertToLegacyMods(attribute.Mods); + LegacyMods legacyMods = item.Ruleset.ConvertToLegacyMods(attribute.Mods); conn.Execute( "INSERT INTO `osu_beatmap_difficulty` (`beatmap_id`, `mode`, `mods`, `diff_unified`) " @@ -114,8 +114,8 @@ private void processDifficulty(int beatmapId, WorkingBeatmap beatmap, Ruleset ru + "ON DUPLICATE KEY UPDATE `diff_unified` = @Diff", new { - BeatmapId = beatmapId, - Mode = ruleset.RulesetInfo.OnlineID, + BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, + Mode = item.Ruleset.RulesetInfo.OnlineID, Mods = (int)legacyMods, Diff = attribute.StarRating }); @@ -128,8 +128,8 @@ private void processDifficulty(int beatmapId, WorkingBeatmap beatmap, Ruleset ru { parameters.Add(new { - BeatmapId = beatmapId, - Mode = ruleset.RulesetInfo.OnlineID, + BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, + Mode = item.Ruleset.RulesetInfo.OnlineID, Mods = (int)legacyMods, Attribute = mapping.attributeId, Value = Convert.ToSingle(mapping.value) @@ -143,19 +143,19 @@ private void processDifficulty(int beatmapId, WorkingBeatmap beatmap, Ruleset ru parameters.ToArray()); } - if (legacyMods == LegacyMods.None && ruleset.RulesetInfo.Equals(beatmap.BeatmapInfo.Ruleset)) + if (legacyMods == LegacyMods.None && item.Ruleset.RulesetInfo.Equals(item.Beatmap.BeatmapInfo.Ruleset)) { - double beatLength = beatmap.Beatmap.GetMostCommonBeatLength(); + double beatLength = item.Beatmap.Beatmap.GetMostCommonBeatLength(); double bpm = beatLength > 0 ? 60000 / beatLength : 0; object param = new { - BeatmapId = beatmapId, + BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, Diff = attribute.StarRating, - AR = beatmap.Beatmap.BeatmapInfo.Difficulty.ApproachRate, - OD = beatmap.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, - HP = beatmap.Beatmap.BeatmapInfo.Difficulty.DrainRate, - CS = beatmap.Beatmap.BeatmapInfo.Difficulty.CircleSize, + AR = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.ApproachRate, + OD = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, + HP = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.DrainRate, + CS = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.CircleSize, BPM = Math.Round(bpm, 2), MaxCombo = attribute.MaxCombo, }; @@ -179,13 +179,13 @@ private void processDifficulty(int beatmapId, WorkingBeatmap beatmap, Ruleset ru } } - private void processLegacyAttributes(int beatmapId, WorkingBeatmap beatmap, Ruleset ruleset, MySqlConnection conn) + private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) { - Mod? classicMod = ruleset.CreateMod(); + Mod? classicMod = item.Ruleset.CreateMod(); Mod[] mods = classicMod != null ? new[] { classicMod } : Array.Empty(); - ILegacyScoreSimulator simulator = ((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator(); - LegacyScoreAttributes attributes = simulator.Simulate(beatmap, beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods)); + ILegacyScoreSimulator simulator = ((ILegacyRuleset)item.Ruleset).CreateLegacyScoreSimulator(); + LegacyScoreAttributes attributes = simulator.Simulate(item.Beatmap, item.Beatmap.GetPlayableBeatmap(item.Ruleset.RulesetInfo, mods)); if (dryRun) return; @@ -196,8 +196,8 @@ private void processLegacyAttributes(int beatmapId, WorkingBeatmap beatmap, Rule + "ON DUPLICATE KEY UPDATE `legacy_accuracy_score` = @AccuracyScore, `legacy_combo_score` = @ComboScore, `legacy_bonus_score_ratio` = @BonusScoreRatio, `legacy_bonus_score` = @BonusScore, `max_combo` = @MaxCombo", new { - BeatmapId = beatmapId, - Mode = ruleset.RulesetInfo.OnlineID, + BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, + Mode = item.Ruleset.RulesetInfo.OnlineID, AccuracyScore = attributes.AccuracyScore, ComboScore = attributes.ComboScore, BonusScoreRatio = attributes.BonusScoreRatio, @@ -228,5 +228,7 @@ private static List getRulesets() return rulesetsToProcess; } + + private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset); } } From 428eeec514406cb6273d9da50a344fc6891c0aac Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 29 May 2024 22:30:35 +0900 Subject: [PATCH 2/7] Don't insert scoring attributes for unranked beatmaps --- .../ServerDifficultyCalculator.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index 52d4132..0539852 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -71,9 +71,11 @@ private void run(WorkingBeatmap beatmap, Action("SELECT `approved` FROM `osu_beatmaps` WHERE `beatmap_id` = @BeatmapId", new + ranked = conn.QuerySingleOrDefault("SELECT `approved` FROM `osu_beatmaps` WHERE `beatmap_id` = @BeatmapId", new { BeatmapId = beatmap.BeatmapInfo.OnlineID }) > 0; @@ -87,10 +89,10 @@ private void run(WorkingBeatmap beatmap, Action r.RulesetInfo.OnlineID == beatmap.BeatmapInfo.Ruleset.OnlineID)) - callback(new ProcessableItem(beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance()), conn); + callback(new ProcessableItem(beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance(), ranked), conn); } } catch (Exception e) @@ -181,6 +183,9 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) { + if (!item.Ranked) + return; + Mod? classicMod = item.Ruleset.CreateMod(); Mod[] mods = classicMod != null ? new[] { classicMod } : Array.Empty(); @@ -229,6 +234,6 @@ private static List getRulesets() return rulesetsToProcess; } - private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset); + private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset, bool Ranked); } } From 19e17aca9c733927074e12217da2669f5e05c3aa Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 29 May 2024 22:31:09 +0900 Subject: [PATCH 3/7] Don't insert difficulty attributes for unranked beatmaps --- osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index 0539852..7ed3d7d 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -122,7 +122,7 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) Diff = attribute.StarRating }); - if (!AppSettings.SKIP_INSERT_ATTRIBUTES) + if (item.Ranked && !AppSettings.SKIP_INSERT_ATTRIBUTES) { var parameters = new List(); From 4e045d146cb82e14f7bdb62948b8563413ef5d29 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 29 May 2024 22:42:34 +0900 Subject: [PATCH 4/7] Add helper properties for beatmap/ruleset id --- .../ServerDifficultyCalculator.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index 7ed3d7d..972a361 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -116,8 +116,8 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) + "ON DUPLICATE KEY UPDATE `diff_unified` = @Diff", new { - BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, - Mode = item.Ruleset.RulesetInfo.OnlineID, + BeatmapId = item.BeatmapID, + Mode = item.RulesetID, Mods = (int)legacyMods, Diff = attribute.StarRating }); @@ -130,8 +130,8 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) { parameters.Add(new { - BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, - Mode = item.Ruleset.RulesetInfo.OnlineID, + BeatmapId = item.BeatmapID, + Mode = item.RulesetID, Mods = (int)legacyMods, Attribute = mapping.attributeId, Value = Convert.ToSingle(mapping.value) @@ -152,7 +152,7 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) object param = new { - BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, + BeatmapId = item.BeatmapID, Diff = attribute.StarRating, AR = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.ApproachRate, OD = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, @@ -201,8 +201,8 @@ private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) + "ON DUPLICATE KEY UPDATE `legacy_accuracy_score` = @AccuracyScore, `legacy_combo_score` = @ComboScore, `legacy_bonus_score_ratio` = @BonusScoreRatio, `legacy_bonus_score` = @BonusScore, `max_combo` = @MaxCombo", new { - BeatmapId = item.Beatmap.BeatmapInfo.OnlineID, - Mode = item.Ruleset.RulesetInfo.OnlineID, + BeatmapId = item.BeatmapID, + Mode = item.RulesetID, AccuracyScore = attributes.AccuracyScore, ComboScore = attributes.ComboScore, BonusScoreRatio = attributes.BonusScoreRatio, @@ -234,6 +234,10 @@ private static List getRulesets() return rulesetsToProcess; } - private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset, bool Ranked); + private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset, bool Ranked) + { + public int BeatmapID => Beatmap.BeatmapInfo.OnlineID; + public int RulesetID => Ruleset.RulesetInfo.OnlineID; + } } } From 038811659fe7eef5a910d5c784117c3e868b0484 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 29 May 2024 22:43:38 +0900 Subject: [PATCH 5/7] Remove unnecessary inner Beatmap reference --- .../ServerDifficultyCalculator.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index 972a361..9e2ac3b 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -154,10 +154,10 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) { BeatmapId = item.BeatmapID, Diff = attribute.StarRating, - AR = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.ApproachRate, - OD = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, - HP = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.DrainRate, - CS = item.Beatmap.Beatmap.BeatmapInfo.Difficulty.CircleSize, + AR = item.Beatmap.BeatmapInfo.Difficulty.ApproachRate, + OD = item.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, + HP = item.Beatmap.BeatmapInfo.Difficulty.DrainRate, + CS = item.Beatmap.BeatmapInfo.Difficulty.CircleSize, BPM = Math.Round(bpm, 2), MaxCombo = attribute.MaxCombo, }; From c83f8003ebc8a854c1c3be2b7d0c3229118bd572 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 30 May 2024 00:35:49 +0900 Subject: [PATCH 6/7] Keep writing unranked scoring attributes for now --- osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index 9e2ac3b..d4d24a5 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -183,9 +183,6 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) { - if (!item.Ranked) - return; - Mod? classicMod = item.Ruleset.CreateMod(); Mod[] mods = classicMod != null ? new[] { classicMod } : Array.Empty(); From 535a3071b6cbac0d565040cbecfa0949d7618f8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 May 2024 13:28:23 +0900 Subject: [PATCH 7/7] Rename record class to less generic name --- .../ServerDifficultyCalculator.cs | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs index d4d24a5..15e28ce 100644 --- a/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs +++ b/osu.Server.DifficultyCalculator/ServerDifficultyCalculator.cs @@ -67,7 +67,7 @@ public void Process(WorkingBeatmap beatmap, ProcessingMode mode) public void ProcessLegacyAttributes(WorkingBeatmap beatmap) => run(beatmap, processLegacyAttributes); - private void run(WorkingBeatmap beatmap, Action callback) + private void run(WorkingBeatmap beatmap, Action callback) { try { @@ -89,10 +89,10 @@ private void run(WorkingBeatmap beatmap, Action r.RulesetInfo.OnlineID == beatmap.BeatmapInfo.Ruleset.OnlineID)) - callback(new ProcessableItem(beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance(), ranked), conn); + callback(new ProcessableBeatmap(beatmap, beatmap.BeatmapInfo.Ruleset.CreateInstance(), ranked), conn); } } catch (Exception e) @@ -101,14 +101,14 @@ private void run(WorkingBeatmap beatmap, Action(); @@ -130,8 +130,8 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) { parameters.Add(new { - BeatmapId = item.BeatmapID, - Mode = item.RulesetID, + BeatmapId = beatmap.BeatmapID, + Mode = beatmap.RulesetID, Mods = (int)legacyMods, Attribute = mapping.attributeId, Value = Convert.ToSingle(mapping.value) @@ -145,19 +145,19 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) parameters.ToArray()); } - if (legacyMods == LegacyMods.None && item.Ruleset.RulesetInfo.Equals(item.Beatmap.BeatmapInfo.Ruleset)) + if (legacyMods == LegacyMods.None && beatmap.Ruleset.RulesetInfo.Equals(beatmap.Beatmap.BeatmapInfo.Ruleset)) { - double beatLength = item.Beatmap.Beatmap.GetMostCommonBeatLength(); + double beatLength = beatmap.Beatmap.Beatmap.GetMostCommonBeatLength(); double bpm = beatLength > 0 ? 60000 / beatLength : 0; object param = new { - BeatmapId = item.BeatmapID, + BeatmapId = beatmap.BeatmapID, Diff = attribute.StarRating, - AR = item.Beatmap.BeatmapInfo.Difficulty.ApproachRate, - OD = item.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, - HP = item.Beatmap.BeatmapInfo.Difficulty.DrainRate, - CS = item.Beatmap.BeatmapInfo.Difficulty.CircleSize, + AR = beatmap.Beatmap.BeatmapInfo.Difficulty.ApproachRate, + OD = beatmap.Beatmap.BeatmapInfo.Difficulty.OverallDifficulty, + HP = beatmap.Beatmap.BeatmapInfo.Difficulty.DrainRate, + CS = beatmap.Beatmap.BeatmapInfo.Difficulty.CircleSize, BPM = Math.Round(bpm, 2), MaxCombo = attribute.MaxCombo, }; @@ -181,13 +181,13 @@ private void processDifficulty(ProcessableItem item, MySqlConnection conn) } } - private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) + private void processLegacyAttributes(ProcessableBeatmap beatmap, MySqlConnection conn) { - Mod? classicMod = item.Ruleset.CreateMod(); + Mod? classicMod = beatmap.Ruleset.CreateMod(); Mod[] mods = classicMod != null ? new[] { classicMod } : Array.Empty(); - ILegacyScoreSimulator simulator = ((ILegacyRuleset)item.Ruleset).CreateLegacyScoreSimulator(); - LegacyScoreAttributes attributes = simulator.Simulate(item.Beatmap, item.Beatmap.GetPlayableBeatmap(item.Ruleset.RulesetInfo, mods)); + ILegacyScoreSimulator simulator = ((ILegacyRuleset)beatmap.Ruleset).CreateLegacyScoreSimulator(); + LegacyScoreAttributes attributes = simulator.Simulate(beatmap.Beatmap, beatmap.Beatmap.GetPlayableBeatmap(beatmap.Ruleset.RulesetInfo, mods)); if (dryRun) return; @@ -198,8 +198,8 @@ private void processLegacyAttributes(ProcessableItem item, MySqlConnection conn) + "ON DUPLICATE KEY UPDATE `legacy_accuracy_score` = @AccuracyScore, `legacy_combo_score` = @ComboScore, `legacy_bonus_score_ratio` = @BonusScoreRatio, `legacy_bonus_score` = @BonusScore, `max_combo` = @MaxCombo", new { - BeatmapId = item.BeatmapID, - Mode = item.RulesetID, + BeatmapId = beatmap.BeatmapID, + Mode = beatmap.RulesetID, AccuracyScore = attributes.AccuracyScore, ComboScore = attributes.ComboScore, BonusScoreRatio = attributes.BonusScoreRatio, @@ -231,7 +231,7 @@ private static List getRulesets() return rulesetsToProcess; } - private readonly record struct ProcessableItem(WorkingBeatmap Beatmap, Ruleset Ruleset, bool Ranked) + private readonly record struct ProcessableBeatmap(WorkingBeatmap Beatmap, Ruleset Ruleset, bool Ranked) { public int BeatmapID => Beatmap.BeatmapInfo.OnlineID; public int RulesetID => Ruleset.RulesetInfo.OnlineID;