From d4fb0bef95cd9ede8cb8da9df98dfc07c7791833 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Jul 2023 19:29:36 +0900 Subject: [PATCH 1/4] Fix osu!mania scores failing to convert to new standardised score due to cast failure Regressed in https://github.com/ppy/osu/pull/23917. Closes #24217. --- .../Scoring/ManiaScoreProcessor.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index a0f6ac572d..16e10006e3 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -22,7 +22,7 @@ public ManiaScoreProcessor() } protected override IEnumerable EnumerateHitObjects(IBeatmap beatmap) - => base.EnumerateHitObjects(beatmap).OrderBy(ho => (ManiaHitObject)ho, JudgementOrderComparer.DEFAULT); + => base.EnumerateHitObjects(beatmap).OrderBy(ho => ho, JudgementOrderComparer.DEFAULT); protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion) { @@ -34,11 +34,11 @@ protected override double ComputeTotalScore(double comboProgress, double accurac protected override double GetComboScoreChange(JudgementResult result) => Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(400, combo_base)); - private class JudgementOrderComparer : IComparer + private class JudgementOrderComparer : IComparer { public static readonly JudgementOrderComparer DEFAULT = new JudgementOrderComparer(); - public int Compare(ManiaHitObject? x, ManiaHitObject? y) + public int Compare(HitObject? x, HitObject? y) { if (ReferenceEquals(x, y)) return 0; if (ReferenceEquals(x, null)) return -1; @@ -48,11 +48,14 @@ public int Compare(ManiaHitObject? x, ManiaHitObject? y) if (result != 0) return result; - // due to the way input is handled in mania, notes take precedence over ticks in judging order. - if (x is Note && y is not Note) return -1; - if (x is not Note && y is Note) return 1; + var xNote = x as Note; + var yNote = y as Note; - return x.Column.CompareTo(y.Column); + // due to the way input is handled in mania, notes take precedence over ticks in judging order. + if (xNote != null && yNote == null) return -1; + if (xNote == null && yNote != null) return 1; + + return xNote!.Column.CompareTo(yNote!.Column); } } } From 480259b8d2b4cfc2f2e06e13eaab6ea1f2162dd1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Jul 2023 20:02:25 +0900 Subject: [PATCH 2/4] Ensure migration is never run on scores with new-enough `TotalScoreVersion`s --- osu.Game/Database/StandardisedScoreMigrationTools.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Database/StandardisedScoreMigrationTools.cs b/osu.Game/Database/StandardisedScoreMigrationTools.cs index b8afdad294..11a5e252a3 100644 --- a/osu.Game/Database/StandardisedScoreMigrationTools.cs +++ b/osu.Game/Database/StandardisedScoreMigrationTools.cs @@ -26,6 +26,9 @@ public static bool ShouldMigrateToNewStandardised(ScoreInfo score) if (score.IsLegacyScore) return false; + if (score.TotalScoreVersion > 30000002) + return false; + // Recalculate the old-style standardised score to see if this was an old lazer score. bool oldScoreMatchesExpectations = GetOldStandardised(score) == score.TotalScore; // Some older scores don't have correct statistics populated, so let's give them benefit of doubt. From e58488d04a64acb9a08cee6253da5973d2c2c9bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 15 Jul 2023 11:19:34 +0900 Subject: [PATCH 3/4] Fix incorrect comparer implementation --- .../Scoring/ManiaScoreProcessor.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 16e10006e3..c53f3c3e07 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -48,14 +48,13 @@ public int Compare(HitObject? x, HitObject? y) if (result != 0) return result; - var xNote = x as Note; - var yNote = y as Note; - // due to the way input is handled in mania, notes take precedence over ticks in judging order. - if (xNote != null && yNote == null) return -1; - if (xNote == null && yNote != null) return 1; + if (x is Note && y is not Note) return -1; + if (x is not Note && y is Note) return 1; - return xNote!.Column.CompareTo(yNote!.Column); + return x is ManiaHitObject maniaX && y is ManiaHitObject maniaY + ? maniaX.Column.CompareTo(maniaY.Column) + : 0; } } } From eb81eac635401bde3c923f03a1a7238c9b03caf3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 15 Jul 2023 12:19:18 +0900 Subject: [PATCH 4/4] Flag decoded scores more correctly --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index c6461840aa..8c00110909 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -49,6 +49,13 @@ public Score Parse(Stream stream) scoreInfo.IsLegacyScore = version < LegacyScoreEncoder.FIRST_LAZER_VERSION; + // TotalScoreVersion gets initialised to LATEST_VERSION. + // In the case where the incoming score has either an osu!stable or old lazer version, we need + // to mark it with the correct version increment to trigger reprocessing to new standardised scoring. + // + // See StandardisedScoreMigrationTools.ShouldMigrateToNewStandardised(). + scoreInfo.TotalScoreVersion = version < 30000002 ? 30000001 : LegacyScoreEncoder.LATEST_VERSION; + string beatmapHash = sr.ReadString(); workingBeatmap = GetBeatmap(beatmapHash);