Skip to content

Commit e387265

Browse files
authored
Merge pull request #216 from minisbett/fix-mods-masking
Reconsider mods filtering in `PerformanceCalculator` looking forward to Lazer
2 parents 856c911 + bdc154b commit e387265

10 files changed

Lines changed: 58 additions & 84 deletions

PerformanceCalculator/Difficulty/DifficultyCommand.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ public class DifficultyCommand : ProcessorCommand
3636
+ "Values: hr, dt, hd, fl, ez, 4k, 5k, etc...")]
3737
public string[] Mods { get; }
3838

39-
[UsedImplicitly]
40-
[Option(Template = "-nc|--no-classic", Description = "Excludes the classic mod.")]
41-
public bool NoClassicMod { get; }
42-
4339
public override void Execute()
4440
{
4541
var resultSet = new ResultSet();
@@ -124,7 +120,7 @@ private Result processBeatmap(WorkingBeatmap beatmap)
124120
{
125121
// Get the ruleset
126122
var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? beatmap.BeatmapInfo.Ruleset.OnlineID);
127-
var mods = NoClassicMod ? getMods(ruleset) : LegacyHelper.FilterDifficultyAdjustmentMods(beatmap.BeatmapInfo, ruleset, getMods(ruleset));
123+
var mods = getMods(ruleset);
128124
var attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(mods);
129125

130126
return new Result

PerformanceCalculator/Difficulty/LegacyScoreAttributesCommand.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,8 @@ public override void Execute()
115115

116116
private Result processBeatmap(WorkingBeatmap beatmap)
117117
{
118-
// Get the ruleset
119118
var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset ?? beatmap.BeatmapInfo.Ruleset.OnlineID);
120-
121-
// bit of a hack to discard non-legacy mods.
122-
var mods = ruleset.ConvertFromLegacyMods(ruleset.ConvertToLegacyMods(getMods(ruleset))).ToList();
119+
var mods = getMods(ruleset);
123120

124121
var legacyRuleset = (ILegacyRuleset)ruleset;
125122
var simulator = legacyRuleset.CreateLegacyScoreSimulator();

PerformanceCalculator/Difficulty/LegacyScoreConversionCommand.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@ public virtual void OnExecute(CommandLineApplication app, IConsole console)
6666
var ruleset = LegacyHelper.GetRulesetFromLegacyID(Ruleset);
6767

6868
var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(Beatmap);
69-
// bit of a hack to discard non-legacy mods.
70-
var mods = ruleset.ConvertFromLegacyMods(ruleset.ConvertToLegacyMods(getMods(ruleset)))
71-
.Append(ruleset.CreateMod<ModClassic>())
72-
.ToArray();
69+
Mod[] mods = [ruleset.CreateMod<ModClassic>(), .. getMods(ruleset)];
70+
7371
var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);
7472

7573
var scoreInfo = new ScoreInfo(beatmap.BeatmapInfo, ruleset.RulesetInfo)

PerformanceCalculator/Leaderboard/LeaderboardCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public override void Execute()
6262
var score = new ProcessorScoreDecoder(working).Parse(scoreInfo);
6363

6464
var difficultyCalculator = ruleset.CreateDifficultyCalculator(working);
65-
var difficultyAttributes = difficultyCalculator.Calculate(LegacyHelper.FilterDifficultyAdjustmentMods(working.BeatmapInfo, ruleset, scoreInfo.Mods).ToArray());
65+
var difficultyAttributes = difficultyCalculator.Calculate(scoreInfo.Mods);
6666
var performanceCalculator = ruleset.CreatePerformanceCalculator();
6767

6868
plays.Add((performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes).Total ?? 0, play.PP ?? 0.0));

PerformanceCalculator/LegacyHelper.cs

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22
// See the LICENCE file in the repository root for full licence text.
33

44
using System;
5-
using System.Linq;
6-
using osu.Game.Beatmaps;
7-
using osu.Game.Beatmaps.Legacy;
85
using osu.Game.Rulesets;
96
using osu.Game.Rulesets.Catch;
107
using osu.Game.Rulesets.Catch.Difficulty;
118
using osu.Game.Rulesets.Difficulty;
129
using osu.Game.Rulesets.Mania;
1310
using osu.Game.Rulesets.Mania.Difficulty;
14-
using osu.Game.Rulesets.Mods;
1511
using osu.Game.Rulesets.Osu;
1612
using osu.Game.Rulesets.Osu.Difficulty;
1713
using osu.Game.Rulesets.Taiko;
@@ -63,54 +59,6 @@ public static string GetRulesetShortNameFromId(int id)
6359
}
6460
}
6561

66-
public const LegacyMods KEY_MODS = LegacyMods.Key1 | LegacyMods.Key2 | LegacyMods.Key3 | LegacyMods.Key4 | LegacyMods.Key5 | LegacyMods.Key6 | LegacyMods.Key7 | LegacyMods.Key8
67-
| LegacyMods.Key9 | LegacyMods.KeyCoop;
68-
69-
// See: https://github.com/ppy/osu-queue-score-statistics/blob/2264bfa68e14bb16ec71a7cac2072bdcfaf565b6/osu.Server.Queues.ScoreStatisticsProcessor/Helpers/LegacyModsHelper.cs
70-
public static LegacyMods MaskRelevantMods(LegacyMods mods, bool isConvertedBeatmap, int rulesetId)
71-
{
72-
LegacyMods relevantMods = LegacyMods.DoubleTime | LegacyMods.HalfTime | LegacyMods.HardRock | LegacyMods.Easy;
73-
74-
switch (rulesetId)
75-
{
76-
case 0:
77-
if ((mods & LegacyMods.Flashlight) > 0)
78-
relevantMods |= LegacyMods.Flashlight | LegacyMods.Hidden | LegacyMods.TouchDevice;
79-
else
80-
relevantMods |= LegacyMods.Flashlight | LegacyMods.TouchDevice;
81-
break;
82-
83-
case 3:
84-
if (isConvertedBeatmap)
85-
relevantMods |= KEY_MODS;
86-
break;
87-
}
88-
89-
return mods & relevantMods;
90-
}
91-
92-
/// <summary>
93-
/// Transforms a given <see cref="Mod"/> combination into one which is applicable to legacy scores.
94-
/// This is used to match osu!stable/osu!web calculations for the time being, until such a point that these mods do get considered.
95-
/// </summary>
96-
public static LegacyMods ConvertToLegacyDifficultyAdjustmentMods(BeatmapInfo beatmapInfo, Ruleset ruleset, Mod[] mods)
97-
{
98-
var legacyMods = ruleset.ConvertToLegacyMods(mods);
99-
100-
// mods that are not represented in `LegacyMods` (but we can approximate them well enough with others)
101-
if (mods.Any(mod => mod is ModDaycore))
102-
legacyMods |= LegacyMods.HalfTime;
103-
104-
return MaskRelevantMods(legacyMods, ruleset.RulesetInfo.OnlineID != beatmapInfo.Ruleset.OnlineID, ruleset.RulesetInfo.OnlineID);
105-
}
106-
107-
/// <summary>
108-
/// Transforms a given <see cref="Mod"/> combination into one which is applicable to legacy scores.
109-
/// This is used to match osu!stable/osu!web calculations for the time being, until such a point that these mods do get considered.
110-
/// </summary>
111-
public static Mod[] FilterDifficultyAdjustmentMods(BeatmapInfo beatmapInfo, Ruleset ruleset, Mod[] mods)
112-
=> ruleset.ConvertFromLegacyMods(ConvertToLegacyDifficultyAdjustmentMods(beatmapInfo, ruleset, mods)).ToArray();
113-
11462
public static DifficultyAttributes CreateDifficultyAttributes(int legacyId)
11563
{
11664
switch (legacyId)

PerformanceCalculator/Performance/ReplayPerformanceCommand.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using osu.Game.Database;
1010
using osu.Game.Online.API.Requests.Responses;
1111
using osu.Game.Rulesets;
12-
using osu.Game.Rulesets.Mods;
1312
using osu.Game.Rulesets.Scoring.Legacy;
1413
using osu.Game.Scoring;
1514
using osu.Game.Scoring.Legacy;
@@ -38,11 +37,8 @@ public override void Execute()
3837
var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(score.ScoreInfo.BeatmapInfo!.OnlineID.ToString());
3938
var playableBeatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.ScoreInfo.Mods);
4039

41-
Mod[] difficultyMods = score.ScoreInfo.Mods;
42-
4340
if (score.ScoreInfo.IsLegacyScore)
4441
{
45-
difficultyMods = LegacyHelper.FilterDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, difficultyMods);
4642
score.ScoreInfo.LegacyTotalScore = (int)score.ScoreInfo.TotalScore;
4743
LegacyScoreDecoder.PopulateMaximumStatistics(score.ScoreInfo, workingBeatmap);
4844
StandardisedScoreMigrationTools.UpdateFromLegacy(
@@ -52,7 +48,7 @@ public override void Execute()
5248
((ILegacyRuleset)ruleset).CreateLegacyScoreSimulator().Simulate(workingBeatmap, playableBeatmap));
5349
}
5450

55-
var difficultyAttributes = ruleset.CreateDifficultyCalculator(workingBeatmap).Calculate(difficultyMods);
51+
var difficultyAttributes = ruleset.CreateDifficultyCalculator(workingBeatmap).Calculate(score.ScoreInfo.Mods);
5652
var performanceCalculator = score.ScoreInfo.Ruleset.CreateInstance().CreatePerformanceCalculator();
5753
var performanceAttributes = performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes);
5854

PerformanceCalculator/Performance/ScorePerformanceCommand.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using osu.Game.Rulesets.Catch.Difficulty;
1717
using osu.Game.Rulesets.Difficulty;
1818
using osu.Game.Rulesets.Mania.Difficulty;
19+
using osu.Game.Rulesets.Mods;
1920
using osu.Game.Rulesets.Osu.Difficulty;
2021
using osu.Game.Rulesets.Taiko.Difficulty;
2122
using osu.Game.Scoring;
@@ -46,13 +47,13 @@ public override void Execute()
4647

4748
if (OnlineAttributes)
4849
{
49-
LegacyMods legacyMods = LegacyHelper.ConvertToLegacyDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, score.Mods);
50+
LegacyMods legacyMods = convertToLegacyMods(workingBeatmap.BeatmapInfo, ruleset, score.Mods);
5051
attributes = queryApiAttributes(apiScore.BeatmapID, apiScore.RulesetID, legacyMods);
5152
}
5253
else
5354
{
5455
var difficultyCalculator = ruleset.CreateDifficultyCalculator(workingBeatmap);
55-
attributes = difficultyCalculator.Calculate(LegacyHelper.FilterDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, score.Mods));
56+
attributes = difficultyCalculator.Calculate(score.Mods);
5657
}
5758

5859
var performanceCalculator = ruleset.CreatePerformanceCalculator();
@@ -121,6 +122,47 @@ DifficultyAttributes getMergedAttributes<TAttributes>(APIBeatmap apiBeatmap)
121122
}
122123
}
123124

125+
/// <summary>
126+
/// Transforms a given <see cref="Mod"/> combination into one which is applicable to legacy scores.
127+
/// This should only be used to match performance calculations using databased attributes.
128+
/// </summary>
129+
private static LegacyMods convertToLegacyMods(BeatmapInfo beatmapInfo, Ruleset ruleset, Mod[] mods)
130+
{
131+
var legacyMods = ruleset.ConvertToLegacyMods(mods);
132+
133+
// mods that are not represented in `LegacyMods` (but we can approximate them well enough with others)
134+
if (mods.Any(mod => mod is ModDaycore))
135+
legacyMods |= LegacyMods.HalfTime;
136+
137+
// See: https://github.com/ppy/osu-queue-score-statistics/blob/2264bfa68e14bb16ec71a7cac2072bdcfaf565b6/osu.Server.Queues.ScoreStatisticsProcessor/Helpers/LegacyModsHelper.cs
138+
static LegacyMods maskRelevantMods(LegacyMods mods, bool isConvertedBeatmap, int rulesetId)
139+
{
140+
const LegacyMods key_mods = LegacyMods.Key1 | LegacyMods.Key2 | LegacyMods.Key3 | LegacyMods.Key4 | LegacyMods.Key5 | LegacyMods.Key6 | LegacyMods.Key7 | LegacyMods.Key8
141+
| LegacyMods.Key9 | LegacyMods.KeyCoop;
142+
143+
LegacyMods relevantMods = LegacyMods.DoubleTime | LegacyMods.HalfTime | LegacyMods.HardRock | LegacyMods.Easy;
144+
145+
switch (rulesetId)
146+
{
147+
case 0:
148+
if ((mods & LegacyMods.Flashlight) > 0)
149+
relevantMods |= LegacyMods.Flashlight | LegacyMods.Hidden | LegacyMods.TouchDevice;
150+
else
151+
relevantMods |= LegacyMods.Flashlight | LegacyMods.TouchDevice;
152+
break;
153+
154+
case 3:
155+
if (isConvertedBeatmap)
156+
relevantMods |= key_mods;
157+
break;
158+
}
159+
160+
return mods & relevantMods;
161+
}
162+
163+
return maskRelevantMods(legacyMods, ruleset.RulesetInfo.OnlineID != beatmapInfo.Ruleset.OnlineID, ruleset.RulesetInfo.OnlineID);
164+
}
165+
124166
[JsonObject(MemberSerialization.OptIn)]
125167
private class AttributesResponse<T>
126168
where T : DifficultyAttributes

PerformanceCalculator/PerformanceCalculator.csproj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net8.0</TargetFramework>
6+
<LangVersion>12.0</LangVersion>
67
</PropertyGroup>
78
<ItemGroup>
89
<PackageReference Include="Alba.CsConsoleFormat" Version="1.0.0" />
910
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.0" />
10-
<PackageReference Include="ppy.osu.Game" Version="2024.130.2" />
11-
<PackageReference Include="ppy.osu.Game.Rulesets.Osu" Version="2024.130.2" />
12-
<PackageReference Include="ppy.osu.Game.Rulesets.Taiko" Version="2024.130.2" />
13-
<PackageReference Include="ppy.osu.Game.Rulesets.Catch" Version="2024.130.2" />
14-
<PackageReference Include="ppy.osu.Game.Rulesets.Mania" Version="2024.130.2" />
11+
<PackageReference Include="ppy.osu.Game" Version="2024.1009.1" />
12+
<PackageReference Include="ppy.osu.Game.Rulesets.Osu" Version="2024.1009.1" />
13+
<PackageReference Include="ppy.osu.Game.Rulesets.Taiko" Version="2024.1009.1" />
14+
<PackageReference Include="ppy.osu.Game.Rulesets.Catch" Version="2024.1009.1" />
15+
<PackageReference Include="ppy.osu.Game.Rulesets.Mania" Version="2024.1009.1" />
1516
</ItemGroup>
1617
</Project>

PerformanceCalculator/Profile/ProfileCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public override void Execute()
5252
var score = new ProcessorScoreDecoder(working).Parse(scoreInfo);
5353

5454
var difficultyCalculator = ruleset.CreateDifficultyCalculator(working);
55-
var difficultyAttributes = difficultyCalculator.Calculate(LegacyHelper.FilterDifficultyAdjustmentMods(working.BeatmapInfo, ruleset, scoreInfo.Mods).ToArray());
55+
var difficultyAttributes = difficultyCalculator.Calculate(scoreInfo.Mods);
5656
var performanceCalculator = ruleset.CreatePerformanceCalculator();
5757

5858
var ppAttributes = performanceCalculator?.Calculate(score.ScoreInfo, difficultyAttributes);

PerformanceCalculator/Simulate/SimulateCommand.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,12 @@ public abstract class SimulateCommand : ProcessorCommand
4848
[UsedImplicitly]
4949
public virtual int? Goods { get; }
5050

51-
[UsedImplicitly]
52-
[Option(Template = "-nc|--no-classic", Description = "Excludes the classic mod.")]
53-
public bool NoClassicMod { get; }
54-
5551
public override void Execute()
5652
{
5753
var ruleset = Ruleset;
5854

5955
var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(Beatmap);
60-
var mods = NoClassicMod ? GetMods(ruleset) : LegacyHelper.FilterDifficultyAdjustmentMods(workingBeatmap.BeatmapInfo, ruleset, GetMods(ruleset));
56+
var mods = GetMods(ruleset);
6157
var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);
6258

6359
var beatmapMaxCombo = GetMaxCombo(beatmap);

0 commit comments

Comments
 (0)