diff --git a/PerformanceCalculator/Performance/ReplayPerformanceCommand.cs b/PerformanceCalculator/Performance/ReplayPerformanceCommand.cs index c8fe0f60b..96f736218 100644 --- a/PerformanceCalculator/Performance/ReplayPerformanceCommand.cs +++ b/PerformanceCalculator/Performance/ReplayPerformanceCommand.cs @@ -6,9 +6,11 @@ using JetBrains.Annotations; using McMaster.Extensions.CommandLineUtils; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Scoring; using osu.Game.Scoring.Legacy; @@ -30,17 +32,25 @@ public override void Execute() using (var stream = File.OpenRead(Replay)) score = scoreDecoder.Parse(stream); + var ruleset = score.ScoreInfo.Ruleset.CreateInstance(); + // At this point the beatmap will have been cached locally due to the lookup during decode, so this is practically free. var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(score.ScoreInfo.BeatmapInfo!.OnlineID.ToString()); + var playableBeatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.ScoreInfo.Mods); - var ruleset = score.ScoreInfo.Ruleset.CreateInstance(); - var difficultyCalculator = ruleset.CreateDifficultyCalculator(workingBeatmap); + Mod[] difficultyMods = score.ScoreInfo.Mods; - Mod[] mods = score.ScoreInfo.Mods; if (score.ScoreInfo.IsLegacyScore) - mods = LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, mods); + { + difficultyMods = LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, difficultyMods); + score.ScoreInfo.LegacyTotalScore = (int)score.ScoreInfo.TotalScore; + score.ScoreInfo.TotalScore = StandardisedScoreMigrationTools.ConvertFromLegacyTotalScore( + score.ScoreInfo, + LegacyBeatmapConversionDifficultyInfo.FromBeatmap(playableBeatmap), + ((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator().Simulate(workingBeatmap, playableBeatmap)); + } - var difficultyAttributes = difficultyCalculator.Calculate(mods); + var difficultyAttributes = ruleset.CreateDifficultyCalculator(workingBeatmap).Calculate(difficultyMods); var performanceCalculator = score.ScoreInfo.Ruleset.CreateInstance().CreatePerformanceCalculator(); var performanceAttributes = performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes); diff --git a/PerformanceCalculator/Performance/ScorePerformanceCommand.cs b/PerformanceCalculator/Performance/ScorePerformanceCommand.cs index 4176b93c5..d889224d2 100644 --- a/PerformanceCalculator/Performance/ScorePerformanceCommand.cs +++ b/PerformanceCalculator/Performance/ScorePerformanceCommand.cs @@ -4,9 +4,12 @@ using System.Linq; using McMaster.Extensions.CommandLineUtils; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.Models; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring.Legacy; namespace PerformanceCalculator.Performance { @@ -28,6 +31,7 @@ public override void Execute() var ruleset = LegacyHelper.GetRulesetFromLegacyID(apiScore.RulesetID); var score = apiScore.ToScoreInfo(apiScore.Mods.Select(m => m.ToMod(ruleset)).ToArray(), apiBeatmap); + score.Ruleset = ruleset.RulesetInfo; score.BeatmapInfo!.Metadata = new BeatmapMetadata { Title = apiBeatmap.Metadata.Title, @@ -35,10 +39,19 @@ public override void Execute() Author = new RealmUser { Username = apiBeatmap.Metadata.Author.Username }, }; + var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(score.BeatmapInfo!.OnlineID.ToString()); + if (apiScore.BuildID == null) + { score.Mods = score.Mods.Append(ruleset.CreateMod()).ToArray(); + score.IsLegacyScore = true; + score.LegacyTotalScore = (int)score.TotalScore; + score.TotalScore = StandardisedScoreMigrationTools.ConvertFromLegacyTotalScore( + score, + LegacyBeatmapConversionDifficultyInfo.FromAPIBeatmap(apiBeatmap), + ((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator().Simulate(workingBeatmap, workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods))); + } - var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(score.BeatmapInfo!.OnlineID.ToString()); var difficultyCalculator = ruleset.CreateDifficultyCalculator(workingBeatmap); var difficultyAttributes = difficultyCalculator.Calculate(LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, score.Mods)); var performanceCalculator = ruleset.CreatePerformanceCalculator(); diff --git a/PerformanceCalculator/ProcessorCommand.cs b/PerformanceCalculator/ProcessorCommand.cs index 24f9c4cde..deef8047b 100644 --- a/PerformanceCalculator/ProcessorCommand.cs +++ b/PerformanceCalculator/ProcessorCommand.cs @@ -50,7 +50,8 @@ public void OutputPerformance(ScoreInfo score, PerformanceAttributes performance BeatmapId = score.BeatmapInfo?.OnlineID ?? -1, Beatmap = score.BeatmapInfo?.ToString() ?? "Unknown beatmap", Mods = score.Mods.Select(m => new APIMod(m)).ToList(), - Score = score.TotalScore, + TotalScore = score.TotalScore, + LegacyTotalScore = score.LegacyTotalScore ?? 0, Accuracy = score.Accuracy * 100, Combo = score.MaxCombo, Statistics = score.Statistics @@ -76,7 +77,8 @@ public void OutputPerformance(ScoreInfo score, PerformanceAttributes performance document.Children.Add( FormatDocumentLine("beatmap", $"{result.Score.BeatmapId} - {result.Score.Beatmap}"), - FormatDocumentLine("score", result.Score.Score.ToString(CultureInfo.InvariantCulture)), + FormatDocumentLine("total score", result.Score.TotalScore.ToString(CultureInfo.InvariantCulture)), + FormatDocumentLine("legacy total score", result.Score.LegacyTotalScore.ToString(CultureInfo.InvariantCulture)), FormatDocumentLine("accuracy", result.Score.Accuracy.ToString("N2", CultureInfo.InvariantCulture)), FormatDocumentLine("combo", result.Score.Combo.ToString(CultureInfo.InvariantCulture)), FormatDocumentLine("mods", result.Score.Mods.Count > 0 ? result.Score.Mods.Select(m => m.ToString()).Aggregate((c, n) => $"{c}, {n}") : "None") @@ -168,7 +170,10 @@ private class ScoreStatistics public List Mods { get; set; } [JsonProperty("total_score")] - public long Score { get; set; } + public long TotalScore { get; set; } + + [JsonProperty("legacy_total_score")] + public long LegacyTotalScore { get; set; } [JsonProperty("accuracy")] public double Accuracy { get; set; }