-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for computing performance of non-legacy scores #195
Conversation
| LegacyMods.Key9 | LegacyMods.KeyCoop; | ||
|
||
// See: https://github.com/ppy/osu-performance/blob/83c02f50315a4ef7feea80acb84c66ee437d7210/include/pp/Common.h#L109-L129 | ||
public static LegacyMods MaskRelevantMods(LegacyMods mods, bool isConvertedBeatmap, int rulesetId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could at least link back to the osu-queue-score-statistics
version of this.
I tested this some and there's a bit of an issue with legacy scores. They can be queried through both of these commands, but if they are queried through the non-legacy one, then the score gets all sorts of weird things wrong like two classic mods applied and an incorrect legacy total score. Compare output of
That is because this block:
is basically invalid for new scores, since the import process would have done all that already server-side. A fix to this could look something like so: diff --git a/PerformanceCalculator/Performance/LegacyScorePerformanceCommand.cs b/PerformanceCalculator/Performance/LegacyScorePerformanceCommand.cs
index a125c96..846a283 100644
--- a/PerformanceCalculator/Performance/LegacyScorePerformanceCommand.cs
+++ b/PerformanceCalculator/Performance/LegacyScorePerformanceCommand.cs
@@ -1,8 +1,16 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Linq;
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;
namespace PerformanceCalculator.Performance
{
@@ -13,5 +21,22 @@ public class LegacyScorePerformanceCommand : ScorePerformanceCommand
public int RulesetId { get; set; }
protected override SoloScoreInfo QueryScore() => GetJsonFromApi<SoloScoreInfo>($"scores/{LegacyHelper.GetRulesetShortNameFromId(RulesetId)}/{ScoreId}");
+
+ protected override ScoreInfo CreateScore(SoloScoreInfo apiScore, Ruleset ruleset, APIBeatmap apiBeatmap, WorkingBeatmap workingBeatmap)
+ {
+ var score = base.CreateScore(apiScore, ruleset, apiBeatmap, workingBeatmap);
+
+ score.Mods = score.Mods.Append(ruleset.CreateMod<ModClassic>()).ToArray();
+ score.IsLegacyScore = true;
+ score.LegacyTotalScore = (int)score.TotalScore;
+ LegacyScoreDecoder.PopulateMaximumStatistics(score, workingBeatmap);
+ StandardisedScoreMigrationTools.UpdateFromLegacy(
+ score,
+ ruleset,
+ LegacyBeatmapConversionDifficultyInfo.FromAPIBeatmap(apiBeatmap),
+ ((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator().Simulate(workingBeatmap, workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods)));
+
+ return score;
+ }
}
}
diff --git a/PerformanceCalculator/Performance/ScorePerformanceCommand.cs b/PerformanceCalculator/Performance/ScorePerformanceCommand.cs
index 7385497..7ee184b 100644
--- a/PerformanceCalculator/Performance/ScorePerformanceCommand.cs
+++ b/PerformanceCalculator/Performance/ScorePerformanceCommand.cs
@@ -10,18 +10,15 @@
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Legacy;
-using osu.Game.Database;
using osu.Game.Models;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch.Difficulty;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mania.Difficulty;
-using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty;
-using osu.Game.Rulesets.Scoring.Legacy;
using osu.Game.Rulesets.Taiko.Difficulty;
-using osu.Game.Scoring.Legacy;
+using osu.Game.Scoring;
namespace PerformanceCalculator.Performance
{
@@ -42,29 +39,8 @@ public override void Execute()
APIBeatmap apiBeatmap = GetJsonFromApi<APIBeatmap>($"beatmaps/lookup?id={apiScore.BeatmapID}");
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,
- Artist = apiBeatmap.Metadata.Artist,
- 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<ModClassic>()).ToArray();
- score.IsLegacyScore = true;
- score.LegacyTotalScore = (int)score.TotalScore;
- LegacyScoreDecoder.PopulateMaximumStatistics(score, workingBeatmap);
- StandardisedScoreMigrationTools.UpdateFromLegacy(
- score,
- ruleset,
- LegacyBeatmapConversionDifficultyInfo.FromAPIBeatmap(apiBeatmap),
- ((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator().Simulate(workingBeatmap, workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods)));
- }
+ var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(apiScore.BeatmapID.ToString());
+ var score = CreateScore(apiScore, ruleset, apiBeatmap, workingBeatmap);
DifficultyAttributes attributes;
@@ -85,6 +61,20 @@ public override void Execute()
OutputPerformance(score, performanceAttributes, attributes);
}
+ protected virtual ScoreInfo CreateScore(SoloScoreInfo apiScore, Ruleset ruleset, APIBeatmap apiBeatmap, WorkingBeatmap workingBeatmap)
+ {
+ 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,
+ Artist = apiBeatmap.Metadata.Artist,
+ Author = new RealmUser { Username = apiBeatmap.Metadata.Author.Username },
+ };
+
+ return score;
+ }
+
protected virtual SoloScoreInfo QueryScore() => GetJsonFromApi<SoloScoreInfo>($"scores/{ScoreId}");
private DifficultyAttributes queryApiAttributes(int beatmapId, int rulesetId, LegacyMods mods)
This resolves all that, except for a remaining small niggle in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think this can be merged now, ppy/osu#27069 can bubble down here whenever most convenient
Shouldn't conflict (apart from
using
s) with #194 .LegacyHelper
implementation taken from https://github.com/ppy/osu-queue-score-statistics/blob/master/osu.Server.Queues.ScoreStatisticsProcessor/Helpers/LegacyModsHelper.cs Not sure if this needs to be moved intoosu.Game
at this point.Commands:
Note that the order of arguments in the
legacy-score
command differs frommaster
in which it is currently<ruleset-id> <score-id>
.This also adds support for the
-a|--online-attributes
option, which allows database attributes to be used instead by querying thebeatmap/{id}/attributes
endpoint.Can be tested with: