1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-13 16:47:46 +08:00

Add capability to export ordered object policy test cases for stable crosscheck

This commit is contained in:
Bartłomiej Dach 2023-08-22 18:04:20 +02:00
parent 9fd59b807f
commit a1b4a56215
No known key found for this signature in database

View File

@ -3,12 +3,17 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats;
using osu.Game.Replays;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
@ -20,6 +25,7 @@ using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
using osuTK;
@ -30,6 +36,13 @@ namespace osu.Game.Rulesets.Osu.Tests
{
private readonly OsuHitWindows referenceHitWindows;
/// <summary>
/// This is provided as a convenience for testing note lock behaviour against osu!stable.
/// Setting this field to a non-null path will cause beatmap files and replays used in all test cases
/// to be exported to disk so that they can be cross-checked against stable.
/// </summary>
private readonly string? exportLocation = null;
public TestSceneObjectOrderedHitPolicy()
{
referenceHitWindows = new OsuHitWindows();
@ -401,12 +414,21 @@ namespace osu.Game.Rulesets.Osu.Tests
private ScoreAccessibleReplayPlayer currentPlayer = null!;
private List<JudgementResult> judgementResults = null!;
private void performTest(List<OsuHitObject> hitObjects, List<ReplayFrame> frames)
private void performTest(List<OsuHitObject> hitObjects, List<ReplayFrame> frames, [CallerMemberName] string testCaseName = "")
{
AddStep("load player", () =>
IBeatmap playableBeatmap = null!;
Score score = null!;
AddStep("create beatmap", () =>
{
var cpi = new ControlPointInfo();
cpi.Add(0, new TimingControlPoint { BeatLength = 1000 });
Beatmap.Value = CreateWorkingBeatmap(new Beatmap<OsuHitObject>
{
Metadata =
{
Title = testCaseName
},
HitObjects = hitObjects,
Difficulty = new BeatmapDifficulty
{
@ -417,11 +439,69 @@ namespace osu.Game.Rulesets.Osu.Tests
{
Ruleset = new OsuRuleset().RulesetInfo
},
ControlPointInfo = cpi
});
playableBeatmap = Beatmap.Value.GetPlayableBeatmap(new OsuRuleset().RulesetInfo);
});
AddStep("create score", () =>
{
score = new Score
{
Replay = new Replay
{
Frames = new List<ReplayFrame>
{
// required for correct playback in stable
new OsuReplayFrame(0, new Vector2(256, -500)),
new OsuReplayFrame(0, new Vector2(256, -500))
}.Concat(frames).ToList()
},
ScoreInfo =
{
Ruleset = new OsuRuleset().RulesetInfo,
BeatmapInfo = playableBeatmap.BeatmapInfo
}
};
});
if (exportLocation != null)
{
AddStep("create beatmap", () =>
{
var beatmapEncoder = new LegacyBeatmapEncoder(playableBeatmap, null);
using (var stream = File.Open(Path.Combine(exportLocation, $"{testCaseName}.osu"), FileMode.Create))
{
var memoryStream = new MemoryStream();
using (var writer = new StreamWriter(memoryStream, Encoding.UTF8, leaveOpen: true))
beatmapEncoder.Encode(writer);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(stream);
memoryStream.Seek(0, SeekOrigin.Begin);
playableBeatmap.BeatmapInfo.MD5Hash = memoryStream.ComputeMD5Hash();
}
});
AddStep("export score", () =>
{
var scoreToEncode = score.DeepClone();
scoreToEncode.Replay.Frames = scoreToEncode.Replay.Frames.Cast<OsuReplayFrame>()
.Select(frame => new OsuReplayFrame(frame.Time + LegacyBeatmapDecoder.EARLY_VERSION_TIMING_OFFSET, frame.Position, frame.Actions.ToArray()))
.ToList<ReplayFrame>();
using var stream = File.Open(Path.Combine(exportLocation, $"{testCaseName}.osr"), FileMode.Create);
var encoder = new LegacyScoreEncoder(scoreToEncode, playableBeatmap);
encoder.Encode(stream);
});
}
AddStep("load player", () =>
{
SelectedMods.Value = new[] { new OsuModClassic() };
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
var p = new ScoreAccessibleReplayPlayer(score);
p.OnLoadComplete += _ =>
{