1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 12:02:55 +08:00

Merge branch 'multiplayer-spectator-screen' of https://github.com/smoogipoo/osu into multiplayer-spectator-screen

This commit is contained in:
smoogipoo 2021-04-26 17:35:37 +09:00
commit 4c5a5c449a
7 changed files with 100 additions and 99 deletions

View File

@ -53,9 +53,9 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
Client.RoomSetupAction = room =>
{
room.State = MultiplayerRoomState.Playing;
room.Users.Add(new MultiplayerRoomUser(55)
room.Users.Add(new MultiplayerRoomUser(PLAYER_1_ID)
{
User = new User { Id = 55 },
User = new User { Id = PLAYER_1_ID },
State = MultiplayerUserState.Playing
});
};

View File

@ -23,6 +23,7 @@ using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO;
using osu.Game.Tests.Visual.Multiplayer;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.Gameplay
@ -238,7 +239,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public class TestSpectatorStreamingClient : SpectatorStreamingClient
{
public readonly User StreamingUser = new User { Id = 55, Username = "Test user" };
public readonly User StreamingUser = new User { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Test user" };
public new BindableList<int> PlayingUsers => (BindableList<int>)base.PlayingUsers;

View File

@ -37,8 +37,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
private readonly Dictionary<int, ManualClock> clocks = new Dictionary<int, ManualClock>
{
{ 55, new ManualClock() },
{ 56, new ManualClock() }
{ PLAYER_1_ID, new ManualClock() },
{ PLAYER_2_ID, new ManualClock() }
};
public TestSceneMultiSpectatorLeaderboard()
@ -95,46 +95,46 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("send frames", () =>
{
// For user 55, send frames in sets of 1.
// For user 56, send frames in sets of 10.
// For player 1, send frames in sets of 1.
// For player 2, send frames in sets of 10.
for (int i = 0; i < 100; i++)
{
streamingClient.SendFrames(55, i, 1);
streamingClient.SendFrames(PLAYER_1_ID, i, 1);
if (i % 10 == 0)
streamingClient.SendFrames(56, i, 10);
streamingClient.SendFrames(PLAYER_2_ID, i, 10);
}
});
assertCombo(55, 1);
assertCombo(56, 10);
assertCombo(PLAYER_1_ID, 1);
assertCombo(PLAYER_2_ID, 10);
// Advance to a point where only user 55's frame changes.
// Advance to a point where only user player 1's frame changes.
setTime(500);
assertCombo(55, 5);
assertCombo(56, 10);
assertCombo(PLAYER_1_ID, 5);
assertCombo(PLAYER_2_ID, 10);
// Advance to a point where both user's frame changes.
setTime(1100);
assertCombo(55, 11);
assertCombo(56, 20);
assertCombo(PLAYER_1_ID, 11);
assertCombo(PLAYER_2_ID, 20);
// Advance user 56 only to a point where its frame changes.
setTime(56, 2100);
assertCombo(55, 11);
assertCombo(56, 30);
// Advance user player 2 only to a point where its frame changes.
setTime(PLAYER_2_ID, 2100);
assertCombo(PLAYER_1_ID, 11);
assertCombo(PLAYER_2_ID, 30);
// Advance both users beyond their last frame
setTime(101 * 100);
assertCombo(55, 100);
assertCombo(56, 100);
assertCombo(PLAYER_1_ID, 100);
assertCombo(PLAYER_2_ID, 100);
}
[Test]
public void TestNoFrames()
{
assertCombo(55, 0);
assertCombo(56, 0);
assertCombo(PLAYER_1_ID, 0);
assertCombo(PLAYER_2_ID, 0);
}
private void setTime(double time) => AddStep($"set time {time}", () =>

View File

@ -47,9 +47,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
private BeatmapInfo importedBeatmap;
private int importedBeatmapId;
private const int player_1_id = 55;
private const int player_2_id = 56;
[BackgroundDependencyLoader]
private void load()
{
@ -83,29 +80,29 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("start players silently", () =>
{
Client.CurrentMatchPlayingUserIds.Add(player_1_id);
Client.CurrentMatchPlayingUserIds.Add(player_2_id);
playingUserIds.Add(player_1_id);
playingUserIds.Add(player_2_id);
nextFrame[player_1_id] = 0;
nextFrame[player_2_id] = 0;
Client.CurrentMatchPlayingUserIds.Add(PLAYER_1_ID);
Client.CurrentMatchPlayingUserIds.Add(PLAYER_2_ID);
playingUserIds.Add(PLAYER_1_ID);
playingUserIds.Add(PLAYER_2_ID);
nextFrame[PLAYER_1_ID] = 0;
nextFrame[PLAYER_2_ID] = 0;
});
loadSpectateScreen(false);
AddWaitStep("wait a bit", 10);
AddStep("load player first_player_id", () => streamingClient.StartPlay(player_1_id, importedBeatmapId));
AddStep("load player first_player_id", () => streamingClient.StartPlay(PLAYER_1_ID, importedBeatmapId));
AddUntilStep("one player added", () => spectatorScreen.ChildrenOfType<Player>().Count() == 1);
AddWaitStep("wait a bit", 10);
AddStep("load player second_player_id", () => streamingClient.StartPlay(player_2_id, importedBeatmapId));
AddStep("load player second_player_id", () => streamingClient.StartPlay(PLAYER_2_ID, importedBeatmapId));
AddUntilStep("two players added", () => spectatorScreen.ChildrenOfType<Player>().Count() == 2);
}
[Test]
public void TestGeneral()
{
int[] userIds = Enumerable.Range(0, 4).Select(i => player_1_id + i).ToArray();
int[] userIds = Enumerable.Range(0, 4).Select(i => PLAYER_1_ID + i).ToArray();
start(userIds);
loadSpectateScreen();
@ -117,123 +114,123 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestPlayersMustStartSimultaneously()
{
start(new[] { player_1_id, player_2_id });
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
loadSpectateScreen();
// Send frames for one player only, both should remain paused.
sendFrames(player_1_id, 20);
checkPausedInstant(player_1_id, true);
checkPausedInstant(player_2_id, true);
sendFrames(PLAYER_1_ID, 20);
checkPausedInstant(PLAYER_1_ID, true);
checkPausedInstant(PLAYER_2_ID, true);
// Send frames for the other player, both should now start playing.
sendFrames(player_2_id, 20);
checkPausedInstant(player_1_id, false);
checkPausedInstant(player_2_id, false);
sendFrames(PLAYER_2_ID, 20);
checkPausedInstant(PLAYER_1_ID, false);
checkPausedInstant(PLAYER_2_ID, false);
}
[Test]
public void TestPlayersDoNotStartSimultaneouslyIfBufferingForMaximumStartDelay()
{
start(new[] { player_1_id, player_2_id });
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
loadSpectateScreen();
// Send frames for one player only, both should remain paused.
sendFrames(player_1_id, 1000);
checkPausedInstant(player_1_id, true);
checkPausedInstant(player_2_id, true);
sendFrames(PLAYER_1_ID, 1000);
checkPausedInstant(PLAYER_1_ID, true);
checkPausedInstant(PLAYER_2_ID, true);
// Wait for the start delay seconds...
AddWaitStep("wait maximum start delay seconds", (int)(CatchUpSyncManager.MAXIMUM_START_DELAY / TimePerAction));
// Player 1 should start playing by itself, player 2 should remain paused.
checkPausedInstant(player_1_id, false);
checkPausedInstant(player_2_id, true);
checkPausedInstant(PLAYER_1_ID, false);
checkPausedInstant(PLAYER_2_ID, true);
}
[Test]
public void TestPlayersContinueWhileOthersBuffer()
{
start(new[] { player_1_id, player_2_id });
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
loadSpectateScreen();
// Send initial frames for both players. A few more for player 1.
sendFrames(player_1_id, 20);
sendFrames(player_2_id, 10);
checkPausedInstant(player_1_id, false);
checkPausedInstant(player_2_id, false);
sendFrames(PLAYER_1_ID, 20);
sendFrames(PLAYER_2_ID, 10);
checkPausedInstant(PLAYER_1_ID, false);
checkPausedInstant(PLAYER_2_ID, false);
// Eventually player 2 will pause, player 1 must remain running.
checkPaused(player_2_id, true);
checkPausedInstant(player_1_id, false);
checkPaused(PLAYER_2_ID, true);
checkPausedInstant(PLAYER_1_ID, false);
// Eventually both players will run out of frames and should pause.
checkPaused(player_1_id, true);
checkPausedInstant(player_2_id, true);
checkPaused(PLAYER_1_ID, true);
checkPausedInstant(PLAYER_2_ID, true);
// Send more frames for the first player only. Player 1 should start playing with player 2 remaining paused.
sendFrames(player_1_id, 20);
checkPausedInstant(player_2_id, true);
checkPausedInstant(player_1_id, false);
sendFrames(PLAYER_1_ID, 20);
checkPausedInstant(PLAYER_2_ID, true);
checkPausedInstant(PLAYER_1_ID, false);
// Send more frames for the second player. Both should be playing
sendFrames(player_2_id, 20);
checkPausedInstant(player_2_id, false);
checkPausedInstant(player_1_id, false);
sendFrames(PLAYER_2_ID, 20);
checkPausedInstant(PLAYER_2_ID, false);
checkPausedInstant(PLAYER_1_ID, false);
}
[Test]
public void TestPlayersCatchUpAfterFallingBehind()
{
start(new[] { player_1_id, player_2_id });
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
loadSpectateScreen();
// Send initial frames for both players. A few more for player 1.
sendFrames(player_1_id, 1000);
sendFrames(player_2_id, 10);
checkPausedInstant(player_1_id, false);
checkPausedInstant(player_2_id, false);
sendFrames(PLAYER_1_ID, 1000);
sendFrames(PLAYER_2_ID, 10);
checkPausedInstant(PLAYER_1_ID, false);
checkPausedInstant(PLAYER_2_ID, false);
// Eventually player 2 will run out of frames and should pause.
checkPaused(player_2_id, true);
checkPaused(PLAYER_2_ID, true);
AddWaitStep("wait a few more frames", 10);
// Send more frames for player 2. It should unpause.
sendFrames(player_2_id, 1000);
checkPausedInstant(player_2_id, false);
sendFrames(PLAYER_2_ID, 1000);
checkPausedInstant(PLAYER_2_ID, false);
// Player 2 should catch up to player 1 after unpausing.
waitForCatchup(player_2_id);
waitForCatchup(PLAYER_2_ID);
AddWaitStep("wait a bit", 10);
}
[Test]
public void TestMostInSyncUserIsAudioSource()
{
start(new[] { player_1_id, player_2_id });
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
loadSpectateScreen();
assertVolume(player_1_id, 0);
assertVolume(player_2_id, 0);
assertVolume(PLAYER_1_ID, 0);
assertVolume(PLAYER_2_ID, 0);
sendFrames(player_1_id, 10);
sendFrames(player_2_id, 20);
assertVolume(player_1_id, 1);
assertVolume(player_2_id, 0);
sendFrames(PLAYER_1_ID, 10);
sendFrames(PLAYER_2_ID, 20);
assertVolume(PLAYER_1_ID, 1);
assertVolume(PLAYER_2_ID, 0);
checkPaused(player_1_id, true);
assertVolume(player_1_id, 0);
assertVolume(player_2_id, 1);
checkPaused(PLAYER_1_ID, true);
assertVolume(PLAYER_1_ID, 0);
assertVolume(PLAYER_2_ID, 1);
sendFrames(player_1_id, 100);
waitForCatchup(player_1_id);
checkPaused(player_2_id, true);
assertVolume(player_1_id, 1);
assertVolume(player_2_id, 0);
sendFrames(PLAYER_1_ID, 100);
waitForCatchup(PLAYER_1_ID);
checkPaused(PLAYER_2_ID, true);
assertVolume(PLAYER_1_ID, 1);
assertVolume(PLAYER_2_ID, 0);
sendFrames(player_2_id, 100);
waitForCatchup(player_2_id);
assertVolume(player_1_id, 1);
assertVolume(player_2_id, 0);
sendFrames(PLAYER_2_ID, 100);
waitForCatchup(PLAYER_2_ID);
assertVolume(PLAYER_1_ID, 1);
assertVolume(PLAYER_2_ID, 0);
}
private void loadSpectateScreen(bool waitForPlayerLoad = true)

View File

@ -119,8 +119,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("join other user (ready)", () =>
{
Client.AddUser(new User { Id = 55 });
Client.ChangeUserState(55, MultiplayerUserState.Ready);
Client.AddUser(new User { Id = PLAYER_1_ID });
Client.ChangeUserState(PLAYER_1_ID, MultiplayerUserState.Ready);
});
AddStep("click spectate button", () =>

View File

@ -157,8 +157,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestReadyButtonEnabledWhenHostAndUsersReady()
{
AddStep("add user", () => Client.AddUser(new User { Id = 55 }));
AddStep("set user ready", () => Client.ChangeUserState(55, MultiplayerUserState.Ready));
AddStep("add user", () => Client.AddUser(new User { Id = PLAYER_1_ID }));
AddStep("set user ready", () => Client.ChangeUserState(PLAYER_1_ID, MultiplayerUserState.Ready));
addClickSpectateButtonStep();
assertReadyButtonEnablement(true);
@ -169,11 +169,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("add user and transfer host", () =>
{
Client.AddUser(new User { Id = 55 });
Client.TransferHost(55);
Client.AddUser(new User { Id = PLAYER_1_ID });
Client.TransferHost(PLAYER_1_ID);
});
AddStep("set user ready", () => Client.ChangeUserState(55, MultiplayerUserState.Ready));
AddStep("set user ready", () => Client.ChangeUserState(PLAYER_1_ID, MultiplayerUserState.Ready));
addClickSpectateButtonStep();
assertReadyButtonEnablement(false);

View File

@ -16,6 +16,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public abstract class MultiplayerTestScene : RoomTestScene
{
public const int PLAYER_1_ID = 55;
public const int PLAYER_2_ID = 56;
[Cached(typeof(StatefulMultiplayerClient))]
public TestMultiplayerClient Client { get; }