Make resyncing a bit more resilient

This commit is contained in:
smoogipoo
2021-04-13 22:10:35 +09:00
parent 627dd960b0
commit 20823abb30
2 changed files with 61 additions and 7 deletions

View File

@ -1,12 +1,15 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Framework.Utils;
@ -153,6 +156,27 @@ namespace osu.Game.Tests.Visual.Multiplayer
checkPausedInstant(55, false);
}
[Test]
public void TestPlayerStartsCatchingUpOnlyAfterExceedingMaxOffset()
{
start(new[] { 55, 56 });
loadSpectateScreen();
sendFrames(55, 1000);
sendFrames(56, 1000);
Bindable<double> slowDownAdjustment;
AddStep("slow down player 2", () =>
{
slowDownAdjustment = new Bindable<double>(0.99);
getInstance(56).Beatmap.Track.AddAdjustment(AdjustableProperty.Frequency, slowDownAdjustment);
});
AddUntilStep("exceeded min offset but not catching up", () => getGameplayOffset(55, 56) > PlayerInstance.MAX_OFFSET && !getInstance(56).IsCatchingUp);
AddUntilStep("catching up or caught up", () => getInstance(56).IsCatchingUp || Math.Abs(getGameplayOffset(55, 56)) < PlayerInstance.SYNC_TARGET * 2);
}
[Test]
public void TestPlayersCatchUpAfterFallingBehind()
{
@ -174,7 +198,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
checkPausedInstant(56, false);
// Player 2 should catch up to player 1 after unpausing.
AddUntilStep("player 1 time == player 2 time", () => Precision.AlmostEquals(getGameplayTime(55), getGameplayTime(56), 16));
AddUntilStep("player 2 not catching up", () => !getInstance(56).IsCatchingUp);
AddAssert("player 1 time == player 2 time", () => Math.Abs(getGameplayOffset(55, 56)) <= 2 * PlayerInstance.SYNC_TARGET);
AddWaitStep("wait a bit", 5);
}
private void loadSpectateScreen()
@ -236,6 +262,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void checkPausedInstant(int userId, bool state) =>
AddAssert($"{userId} is {(state ? "paused" : "playing")}", () => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().First().IsPaused.Value == state);
/// <summary>
/// Returns time(user1) - time(user2).
/// </summary>
private double getGameplayOffset(int user1, int user2) => getGameplayTime(user1) - getGameplayTime(user2);
private double getGameplayTime(int userId) => getPlayer(userId).ChildrenOfType<GameplayClockContainer>().Single().GameplayClock.CurrentTime;
private Player getPlayer(int userId) => getInstance(userId).ChildrenOfType<Player>().Single();