mirror of https://github.com/ppy/osu
Export and import `TotalScoreWithoutMods` to replays (or recalculate if it missing)
This commit is contained in:
parent
e0178802b8
commit
2f1a4cdaa4
|
@ -412,6 +412,80 @@ public void AccuracyAndRankOfLazerScoreWithoutLegacyReplaySoloScoreInfoUsesBestE
|
|||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTotalScoreWithoutModsReadIfPresent()
|
||||
{
|
||||
var ruleset = new OsuRuleset().RulesetInfo;
|
||||
|
||||
var scoreInfo = TestResources.CreateTestScoreInfo(ruleset);
|
||||
scoreInfo.Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime { SpeedChange = { Value = 1.1 } }
|
||||
};
|
||||
scoreInfo.OnlineID = 123123;
|
||||
scoreInfo.ClientVersion = "2023.1221.0";
|
||||
scoreInfo.TotalScoreWithoutMods = 1_000_000;
|
||||
scoreInfo.TotalScore = 1_020_000;
|
||||
|
||||
var beatmap = new TestBeatmap(ruleset);
|
||||
var score = new Score
|
||||
{
|
||||
ScoreInfo = scoreInfo,
|
||||
Replay = new Replay
|
||||
{
|
||||
Frames = new List<ReplayFrame>
|
||||
{
|
||||
new OsuReplayFrame(2000, OsuPlayfield.BASE_SIZE / 2, OsuAction.LeftButton)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var decodedAfterEncode = encodeThenDecode(LegacyBeatmapDecoder.LATEST_VERSION, score, beatmap);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(decodedAfterEncode.ScoreInfo.TotalScoreWithoutMods, Is.EqualTo(1_000_000));
|
||||
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(1_020_000));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTotalScoreWithoutModsBackwardsPopulatedIfMissing()
|
||||
{
|
||||
var ruleset = new OsuRuleset().RulesetInfo;
|
||||
|
||||
var scoreInfo = TestResources.CreateTestScoreInfo(ruleset);
|
||||
scoreInfo.Mods = new Mod[]
|
||||
{
|
||||
new OsuModDoubleTime { SpeedChange = { Value = 1.1 } }
|
||||
};
|
||||
scoreInfo.OnlineID = 123123;
|
||||
scoreInfo.ClientVersion = "2023.1221.0";
|
||||
scoreInfo.TotalScoreWithoutMods = 0;
|
||||
scoreInfo.TotalScore = 1_020_000;
|
||||
|
||||
var beatmap = new TestBeatmap(ruleset);
|
||||
var score = new Score
|
||||
{
|
||||
ScoreInfo = scoreInfo,
|
||||
Replay = new Replay
|
||||
{
|
||||
Frames = new List<ReplayFrame>
|
||||
{
|
||||
new OsuReplayFrame(2000, OsuPlayfield.BASE_SIZE / 2, OsuAction.LeftButton)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var decodedAfterEncode = encodeThenDecode(LegacyBeatmapDecoder.LATEST_VERSION, score, beatmap);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(decodedAfterEncode.ScoreInfo.TotalScoreWithoutMods, Is.EqualTo(1_000_000));
|
||||
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(1_020_000));
|
||||
});
|
||||
}
|
||||
|
||||
private static Score encodeThenDecode(int beatmapVersion, Score score, TestBeatmap beatmap)
|
||||
{
|
||||
var encodeStream = new MemoryStream();
|
||||
|
|
|
@ -1113,14 +1113,7 @@ void convertOnlineIDs<T>() where T : RealmObject
|
|||
|
||||
case 41:
|
||||
foreach (var score in migration.NewRealm.All<ScoreInfo>())
|
||||
{
|
||||
double modMultiplier = 1;
|
||||
|
||||
foreach (var mod in score.Mods)
|
||||
modMultiplier *= mod.ScoreMultiplier;
|
||||
|
||||
score.TotalScoreWithoutMods = (long)Math.Round(score.TotalScore / modMultiplier);
|
||||
}
|
||||
LegacyScoreDecoder.PopulateTotalScoreWithoutMods(score);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ public class LegacyReplaySoloScoreInfo
|
|||
[JsonProperty("client_version")]
|
||||
public string ClientVersion = string.Empty;
|
||||
|
||||
[JsonProperty("total_score_without_mods")]
|
||||
public long? TotalScoreWithoutMods { get; set; }
|
||||
|
||||
public static LegacyReplaySoloScoreInfo FromScore(ScoreInfo score) => new LegacyReplaySoloScoreInfo
|
||||
{
|
||||
OnlineID = score.OnlineID,
|
||||
|
@ -45,6 +48,7 @@ public class LegacyReplaySoloScoreInfo
|
|||
Statistics = score.Statistics.Where(kvp => kvp.Value != 0).ToDictionary(),
|
||||
MaximumStatistics = score.MaximumStatistics.Where(kvp => kvp.Value != 0).ToDictionary(),
|
||||
ClientVersion = score.ClientVersion,
|
||||
TotalScoreWithoutMods = score.TotalScoreWithoutMods > 0 ? score.TotalScoreWithoutMods : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,11 @@ public Score Parse(Stream stream)
|
|||
score.ScoreInfo.MaximumStatistics = readScore.MaximumStatistics;
|
||||
score.ScoreInfo.Mods = readScore.Mods.Select(m => m.ToMod(currentRuleset)).ToArray();
|
||||
score.ScoreInfo.ClientVersion = readScore.ClientVersion;
|
||||
|
||||
if (readScore.TotalScoreWithoutMods is long totalScoreWithoutMods)
|
||||
score.ScoreInfo.TotalScoreWithoutMods = totalScoreWithoutMods;
|
||||
else
|
||||
PopulateTotalScoreWithoutMods(score.ScoreInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +242,16 @@ public static void PopulateMaximumStatistics(ScoreInfo score, WorkingBeatmap wor
|
|||
#pragma warning restore CS0618
|
||||
}
|
||||
|
||||
public static void PopulateTotalScoreWithoutMods(ScoreInfo score)
|
||||
{
|
||||
double modMultiplier = 1;
|
||||
|
||||
foreach (var mod in score.Mods)
|
||||
modMultiplier *= mod.ScoreMultiplier;
|
||||
|
||||
score.TotalScoreWithoutMods = (long)Math.Round(score.TotalScore / modMultiplier);
|
||||
}
|
||||
|
||||
private void readLegacyReplay(Replay replay, StreamReader reader)
|
||||
{
|
||||
float lastTime = beatmapOffset;
|
||||
|
|
Loading…
Reference in New Issue