Split helper method for populations from replay

This commit is contained in:
Bartłomiej Dach 2023-07-10 21:10:01 +02:00
parent e12255bbe5
commit 9e4ffc8c12
No known key found for this signature in database
2 changed files with 63 additions and 65 deletions

View File

@ -26,7 +26,6 @@
using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Input.Bindings;
using osu.Game.IO.Legacy;
using osu.Game.Models;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
@ -914,31 +913,13 @@ void convertOnlineIDs<T>() where T : RealmObject
foreach (var score in scores)
{
string? replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(@".osr", StringComparison.InvariantCultureIgnoreCase))?.File.GetStoragePath();
if (replayFilename == null)
continue;
try
{
using (var stream = files.Store.GetStream(replayFilename))
{
if (stream == null)
continue;
// Trimmed down logic from LegacyScoreDecoder to extract the version from replays.
using (SerializationReader sr = new SerializationReader(stream))
score.PopulateFromReplay(files, sr =>
{
sr.ReadByte(); // Ruleset.
int version = sr.ReadInt32();
if (version < LegacyScoreEncoder.FIRST_LAZER_VERSION)
score.IsLegacyScore = true;
}
}
}
catch (Exception e)
{
Logger.Error(e, $"Failed to read replay {replayFilename} during score migration", LoggingTarget.Database);
}
});
}
break;
@ -999,19 +980,7 @@ void convertOnlineIDs<T>() where T : RealmObject
if (!score.IsLegacyScore || !score.Ruleset.IsLegacyRuleset())
continue;
string? replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(@".osr", StringComparison.InvariantCultureIgnoreCase))?.File.GetStoragePath();
if (replayFilename == null)
continue;
try
{
using (var stream = files.Store.GetStream(replayFilename))
{
if (stream == null)
continue;
// Trimmed down logic from LegacyScoreDecoder to extract the mods bitmask.
using (SerializationReader sr = new SerializationReader(stream))
score.PopulateFromReplay(files, sr =>
{
sr.ReadByte(); // Ruleset.
sr.ReadInt32(); // Version.
@ -1034,17 +1003,11 @@ void convertOnlineIDs<T>() where T : RealmObject
var legacyMods = (LegacyMods)sr.ReadInt32();
if (!legacyMods.HasFlagFast(LegacyMods.ScoreV2) || score.APIMods.Any(mod => mod.Acronym == @"SV2"))
continue;
return;
score.APIMods = score.APIMods.Append(new APIMod(new ModScoreV2())).ToArray();
score.LegacyTotalScore = score.TotalScore = totalScore;
}
}
}
catch (Exception e)
{
Logger.Error(e, $"Failed to read replay {replayFilename} during score migration", LoggingTarget.Database);
}
});
}
break;

View File

@ -5,7 +5,10 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
using osu.Game.IO.Legacy;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Judgements;
@ -287,6 +290,38 @@ public static long ConvertFromLegacyTotalScore(ScoreInfo score, DifficultyAttrib
}
}
/// <summary>
/// Used to populate the <paramref name="score"/> model using data parsed from its corresponding replay file.
/// </summary>
/// <param name="score">The score to run population from replay for.</param>
/// <param name="files">A <see cref="RealmFileStore"/> instance to use for fetching replay.</param>
/// <param name="populationFunc">
/// Delegate describing the population to execute.
/// The delegate's argument is a <see cref="SerializationReader"/> instance which permits to read data from the replay stream.
/// </param>
public static void PopulateFromReplay(this ScoreInfo score, RealmFileStore files, Action<SerializationReader> populationFunc)
{
string? replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(@".osr", StringComparison.InvariantCultureIgnoreCase))?.File.GetStoragePath();
if (replayFilename == null)
return;
try
{
using (var stream = files.Store.GetStream(replayFilename))
{
if (stream == null)
return;
using (SerializationReader sr = new SerializationReader(stream))
populationFunc.Invoke(sr);
}
}
catch (Exception e)
{
Logger.Error(e, $"Failed to read replay {replayFilename} during score migration", LoggingTarget.Database);
}
}
private class FakeHit : HitObject
{
private readonly Judgement judgement;