1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 17:27:24 +08:00

Add test coverage of judgements not being synced when resuming a replay

This commit is contained in:
Dean Herbert 2024-09-18 15:03:55 +09:00
parent ea94f903c1
commit 2d993645af
No known key found for this signature in database
3 changed files with 33 additions and 6 deletions

View File

@ -19,6 +19,7 @@ using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD.JudgementCounter;
using osu.Game.Tests.Beatmaps.IO;
using osu.Game.Tests.Gameplay;
using osu.Game.Tests.Visual.Multiplayer;
@ -167,14 +168,16 @@ namespace osu.Game.Tests.Visual.Gameplay
public void TestSpectatingDuringGameplay()
{
start();
sendFrames(300);
sendFrames(300, initialResultCount: 100);
loadSpectatingScreen();
waitForPlayerCurrent();
sendFrames(300);
sendFrames(300, initialResultCount: 100);
AddUntilStep("playing from correct point in time", () => player.ChildrenOfType<DrawableRuleset>().First().FrameStableClock.CurrentTime, () => Is.GreaterThan(30000));
AddAssert("check judgement counts are correct", () => player.ChildrenOfType<JudgementCountController>().Single().Counters.Sum(c => c.ResultCount.Value),
() => Is.GreaterThanOrEqualTo(100));
}
[Test]
@ -405,9 +408,9 @@ namespace osu.Game.Tests.Visual.Gameplay
private void checkPaused(bool state) =>
AddUntilStep($"game is {(state ? "paused" : "playing")}", () => player.ChildrenOfType<DrawableRuleset>().First().IsPaused.Value == state);
private void sendFrames(int count = 10, double startTime = 0)
private void sendFrames(int count = 10, double startTime = 0, int initialResultCount = 0)
{
AddStep("send frames", () => spectatorClient.SendFramesFromUser(streamingUser.Id, count, startTime));
AddStep("send frames", () => spectatorClient.SendFramesFromUser(streamingUser.Id, count, startTime, initialResultCount));
}
private void loadSpectatingScreen()

View File

@ -181,6 +181,8 @@ namespace osu.Game.Rulesets.Scoring
}
}
public IReadOnlyDictionary<HitResult, int> Statistics => ScoreResultCounts;
private bool beatmapApplied;
protected readonly Dictionary<HitResult, int> ScoreResultCounts = new Dictionary<HitResult, int>();

View File

@ -13,6 +13,8 @@ using osu.Game.Online.API;
using osu.Game.Online.Spectator;
using osu.Game.Replays.Legacy;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
@ -99,13 +101,24 @@ namespace osu.Game.Tests.Visual.Spectator
/// <param name="userId">The user to send frames for.</param>
/// <param name="count">The total number of frames to send.</param>
/// <param name="startTime">The time to start gameplay frames from.</param>
public void SendFramesFromUser(int userId, int count, double startTime = 0)
/// <param name="initialResultCount">Add a number of misses to frame header data for testing purposes.</param>
public void SendFramesFromUser(int userId, int count, double startTime = 0, int initialResultCount = 0)
{
var frames = new List<LegacyReplayFrame>();
int currentFrameIndex = userNextFrameDictionary[userId];
int lastFrameIndex = currentFrameIndex + count - 1;
var scoreProcessor = new ScoreProcessor(rulesetStore.GetRuleset(0)!.CreateInstance());
for (int i = 0; i < initialResultCount; i++)
{
scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new Judgement())
{
Type = HitResult.Miss,
});
}
for (; currentFrameIndex <= lastFrameIndex; currentFrameIndex++)
{
// This is done in the next frame so that currentFrameIndex is updated to the correct value.
@ -130,7 +143,16 @@ namespace osu.Game.Tests.Visual.Spectator
Combo = currentFrameIndex,
TotalScore = (long)(currentFrameIndex * 123478 * RNG.NextDouble(0.99, 1.01)),
Accuracy = RNG.NextDouble(0.98, 1),
}, new ScoreProcessor(rulesetStore.GetRuleset(0)!.CreateInstance()), frames.ToArray());
Statistics = scoreProcessor.Statistics.ToDictionary(),
}, scoreProcessor, frames.ToArray());
if (initialResultCount > 0)
{
foreach (var f in frames)
f.Header = bundle.Header;
}
scoreProcessor.ResetFromReplayFrame(frames.Last());
((ISpectatorClient)this).UserSentFrames(userId, bundle);
frames.Clear();