2020-12-21 17:42:31 +08:00
// 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.
2021-05-11 18:31:32 +08:00
using System ;
2021-08-27 17:57:35 +08:00
using System.Diagnostics ;
2021-05-11 18:01:41 +08:00
using System.Linq ;
using NUnit.Framework ;
2021-03-03 20:54:34 +08:00
using osu.Framework.Allocation ;
2021-05-11 18:01:41 +08:00
using osu.Framework.Audio ;
2022-05-06 14:22:22 +08:00
using osu.Framework.Bindables ;
2022-01-03 16:02:15 +08:00
using osu.Framework.Extensions ;
2022-01-08 21:50:49 +08:00
using osu.Framework.Extensions.ObjectExtensions ;
2021-06-22 23:48:41 +08:00
using osu.Framework.Graphics.Containers ;
2021-07-19 19:55:14 +08:00
using osu.Framework.Graphics.UserInterface ;
2021-08-03 17:37:09 +08:00
using osu.Framework.Input ;
2021-05-11 18:01:41 +08:00
using osu.Framework.Platform ;
using osu.Framework.Screens ;
using osu.Framework.Testing ;
2021-08-27 17:44:44 +08:00
using osu.Framework.Utils ;
2021-05-11 18:01:41 +08:00
using osu.Game.Beatmaps ;
2022-05-06 14:22:22 +08:00
using osu.Game.Configuration ;
2021-06-22 23:48:41 +08:00
using osu.Game.Graphics.UserInterface ;
2022-02-15 15:01:14 +08:00
using osu.Game.Online.API ;
2021-11-04 17:02:44 +08:00
using osu.Game.Online.API.Requests.Responses ;
2021-03-03 20:54:34 +08:00
using osu.Game.Online.Multiplayer ;
2021-05-11 18:01:41 +08:00
using osu.Game.Online.Rooms ;
2021-06-22 23:48:41 +08:00
using osu.Game.Overlays.Mods ;
2021-05-11 18:01:41 +08:00
using osu.Game.Rulesets ;
2022-01-08 21:39:22 +08:00
using osu.Game.Rulesets.Catch ;
2022-01-08 21:50:49 +08:00
using osu.Game.Rulesets.Mods ;
2021-05-11 18:01:41 +08:00
using osu.Game.Rulesets.Osu ;
2021-06-22 23:48:41 +08:00
using osu.Game.Rulesets.Osu.Mods ;
2021-11-13 00:53:58 +08:00
using osu.Game.Screens.OnlinePlay.Components ;
2021-07-13 16:31:28 +08:00
using osu.Game.Screens.OnlinePlay.Lounge ;
2021-07-19 19:55:14 +08:00
using osu.Game.Screens.OnlinePlay.Lounge.Components ;
2021-08-13 13:04:43 +08:00
using osu.Game.Screens.OnlinePlay.Match ;
2021-05-11 18:31:32 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer ;
2021-05-11 18:01:41 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer.Match ;
2021-12-15 15:52:50 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist ;
2021-12-15 16:37:39 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate ;
2021-08-24 12:20:01 +08:00
using osu.Game.Screens.Play ;
using osu.Game.Screens.Ranking ;
2021-10-28 13:29:49 +08:00
using osu.Game.Screens.Spectate ;
2021-05-11 18:01:41 +08:00
using osu.Game.Tests.Resources ;
using osuTK.Input ;
2022-03-23 09:37:53 +08:00
using ReadyButton = osu . Game . Screens . OnlinePlay . Components . ReadyButton ;
2020-12-21 17:42:31 +08:00
2020-12-25 12:20:37 +08:00
namespace osu.Game.Tests.Visual.Multiplayer
2020-12-21 17:42:31 +08:00
{
2021-03-03 20:54:34 +08:00
public class TestSceneMultiplayer : ScreenTestScene
2020-12-21 17:42:31 +08:00
{
2022-07-07 16:51:49 +08:00
private BeatmapManager beatmaps = null ! ;
private RulesetStore rulesets = null ! ;
private BeatmapSetInfo importedSet = null ! ;
2021-05-11 18:01:41 +08:00
2022-07-07 16:51:49 +08:00
private TestMultiplayerComponents multiplayerComponents = null ! ;
2021-05-11 18:01:41 +08:00
2022-02-16 08:43:28 +08:00
private TestMultiplayerClient multiplayerClient = > multiplayerComponents . MultiplayerClient ;
2021-12-20 17:24:59 +08:00
private TestMultiplayerRoomManager roomManager = > multiplayerComponents . RoomManager ;
2021-08-17 08:45:10 +08:00
2022-05-06 14:22:22 +08:00
[Resolved]
2022-07-07 16:51:49 +08:00
private OsuConfigManager config { get ; set ; } = null ! ;
2022-05-06 14:22:22 +08:00
2021-05-11 18:01:41 +08:00
[BackgroundDependencyLoader]
private void load ( GameHost host , AudioManager audio )
{
2022-02-16 16:13:51 +08:00
Dependencies . Cache ( rulesets = new RealmRulesetStore ( Realm ) ) ;
2022-01-25 11:58:15 +08:00
Dependencies . Cache ( beatmaps = new BeatmapManager ( LocalStorage , Realm , rulesets , API , audio , Resources , host , Beatmap . Default ) ) ;
Dependencies . Cache ( Realm ) ;
2021-05-11 18:26:58 +08:00
}
2021-05-11 18:01:41 +08:00
2021-07-05 18:10:27 +08:00
public override void SetUpSteps ( )
2021-05-11 18:26:58 +08:00
{
2021-07-05 18:10:27 +08:00
base . SetUpSteps ( ) ;
AddStep ( "import beatmap" , ( ) = >
{
2022-01-03 16:02:15 +08:00
beatmaps . Import ( TestResources . GetQuickTestBeatmapForImport ( ) ) . WaitSafely ( ) ;
2021-12-17 17:26:12 +08:00
importedSet = beatmaps . GetAllUsableBeatmapSets ( ) . First ( ) ;
2021-07-05 18:10:27 +08:00
} ) ;
2021-12-20 17:24:59 +08:00
AddStep ( "load multiplayer" , ( ) = > LoadScreen ( multiplayerComponents = new TestMultiplayerComponents ( ) ) ) ;
AddUntilStep ( "wait for multiplayer to load" , ( ) = > multiplayerComponents . IsLoaded ) ;
2021-07-26 13:29:16 +08:00
AddUntilStep ( "wait for lounge to load" , ( ) = > this . ChildrenOfType < MultiplayerLoungeSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
2021-07-05 18:10:27 +08:00
}
2021-05-11 18:26:58 +08:00
[Test]
2021-07-05 18:10:27 +08:00
public void TestEmpty ( )
2021-05-11 18:26:58 +08:00
{
2021-07-05 18:10:27 +08:00
// used to test the flow of multiplayer from visual tests.
2021-08-06 18:40:29 +08:00
AddStep ( "empty step" , ( ) = > { } ) ;
2021-07-05 18:10:27 +08:00
}
2021-05-11 18:26:58 +08:00
2021-08-27 17:44:44 +08:00
[Test]
public void TestLobbyEvents ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-08-27 17:44:44 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-08-27 17:44:44 +08:00
}
}
} ) ;
AddRepeatStep ( "random stuff happens" , performRandomAction , 30 ) ;
// ensure we have a handful of players so the ready-up sounds good :9
AddRepeatStep ( "player joins" , addRandomPlayer , 5 ) ;
// all ready
AddUntilStep ( "all players ready" , ( ) = >
{
2022-07-01 17:58:22 +08:00
var nextUnready = multiplayerClient . ClientRoom ? . Users . FirstOrDefault ( c = > c . State = = MultiplayerUserState . Idle ) ;
2021-08-27 17:44:44 +08:00
if ( nextUnready ! = null )
2022-02-16 08:43:28 +08:00
multiplayerClient . ChangeUserState ( nextUnready . UserID , MultiplayerUserState . Ready ) ;
2021-08-27 17:44:44 +08:00
2022-07-01 17:58:22 +08:00
return multiplayerClient . ClientRoom ? . Users . All ( u = > u . State = = MultiplayerUserState . Ready ) = = true ;
2021-08-27 17:44:44 +08:00
} ) ;
2021-08-27 17:57:35 +08:00
AddStep ( "unready all players at once" , ( ) = >
{
2022-07-01 17:58:22 +08:00
Debug . Assert ( multiplayerClient . ServerRoom ! = null ) ;
2021-08-27 17:57:35 +08:00
2022-07-01 17:58:22 +08:00
foreach ( var u in multiplayerClient . ServerRoom . Users ) multiplayerClient . ChangeUserState ( u . UserID , MultiplayerUserState . Idle ) ;
2021-08-27 17:57:35 +08:00
} ) ;
AddStep ( "ready all players at once" , ( ) = >
{
2022-07-01 17:58:22 +08:00
Debug . Assert ( multiplayerClient . ServerRoom ! = null ) ;
2021-08-27 17:57:35 +08:00
2022-07-01 17:58:22 +08:00
foreach ( var u in multiplayerClient . ServerRoom . Users ) multiplayerClient . ChangeUserState ( u . UserID , MultiplayerUserState . Ready ) ;
2021-08-27 17:57:35 +08:00
} ) ;
2021-08-27 17:44:44 +08:00
}
private void addRandomPlayer ( )
{
int randomUser = RNG . Next ( 200000 , 500000 ) ;
2022-02-16 08:43:28 +08:00
multiplayerClient . AddUser ( new APIUser { Id = randomUser , Username = $"user {randomUser}" } ) ;
2021-08-27 17:44:44 +08:00
}
private void removeLastUser ( )
{
2022-07-07 16:51:49 +08:00
APIUser ? lastUser = multiplayerClient . ServerRoom ? . Users . Last ( ) . User ;
2021-08-27 17:44:44 +08:00
2022-02-16 08:43:28 +08:00
if ( lastUser = = null | | lastUser = = multiplayerClient . LocalUser ? . User )
2021-08-27 17:44:44 +08:00
return ;
2022-02-16 08:43:28 +08:00
multiplayerClient . RemoveUser ( lastUser ) ;
2021-08-27 17:44:44 +08:00
}
private void kickLastUser ( )
{
2022-07-07 16:51:49 +08:00
APIUser ? lastUser = multiplayerClient . ServerRoom ? . Users . Last ( ) . User ;
2021-08-27 17:44:44 +08:00
2022-02-16 08:43:28 +08:00
if ( lastUser = = null | | lastUser = = multiplayerClient . LocalUser ? . User )
2021-08-27 17:44:44 +08:00
return ;
2022-02-16 08:43:28 +08:00
multiplayerClient . KickUser ( lastUser . Id ) ;
2021-08-27 17:44:44 +08:00
}
private void markNextPlayerReady ( )
{
2022-07-01 17:58:22 +08:00
var nextUnready = multiplayerClient . ServerRoom ? . Users . FirstOrDefault ( c = > c . State = = MultiplayerUserState . Idle ) ;
2021-08-27 17:44:44 +08:00
if ( nextUnready ! = null )
2022-02-16 08:43:28 +08:00
multiplayerClient . ChangeUserState ( nextUnready . UserID , MultiplayerUserState . Ready ) ;
2021-08-27 17:44:44 +08:00
}
private void markNextPlayerIdle ( )
{
2022-07-01 17:58:22 +08:00
var nextUnready = multiplayerClient . ServerRoom ? . Users . FirstOrDefault ( c = > c . State = = MultiplayerUserState . Ready ) ;
2021-08-27 17:44:44 +08:00
if ( nextUnready ! = null )
2022-02-16 08:43:28 +08:00
multiplayerClient . ChangeUserState ( nextUnready . UserID , MultiplayerUserState . Idle ) ;
2021-08-27 17:44:44 +08:00
}
private void performRandomAction ( )
{
int eventToPerform = RNG . Next ( 1 , 6 ) ;
switch ( eventToPerform )
{
case 1 :
addRandomPlayer ( ) ;
break ;
case 2 :
removeLastUser ( ) ;
break ;
case 3 :
kickLastUser ( ) ;
break ;
case 4 :
markNextPlayerReady ( ) ;
break ;
case 5 :
markNextPlayerIdle ( ) ;
break ;
}
}
2021-08-03 17:37:09 +08:00
[Test]
public void TestCreateRoomViaKeyboard ( )
{
// create room dialog
AddStep ( "Press new document" , ( ) = > InputManager . Keys ( PlatformAction . DocumentNew ) ) ;
AddUntilStep ( "wait for settings" , ( ) = > InputManager . ChildrenOfType < MultiplayerMatchSettingsOverlay > ( ) . FirstOrDefault ( ) ! = null ) ;
// edit playlist item
AddStep ( "Press select" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
2021-11-25 20:11:13 +08:00
AddUntilStep ( "wait for song select" , ( ) = > InputManager . ChildrenOfType < MultiplayerMatchSongSelect > ( ) . FirstOrDefault ( ) ? . BeatmapSetsLoaded = = true ) ;
2021-08-03 17:37:09 +08:00
// select beatmap
AddStep ( "Press select" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for return to screen" , ( ) = > InputManager . ChildrenOfType < MultiplayerMatchSongSelect > ( ) . FirstOrDefault ( ) = = null ) ;
// create room
AddStep ( "Press select" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for room open" , ( ) = > this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for join" , ( ) = > multiplayerClient . RoomJoined ) ;
2021-08-03 17:37:09 +08:00
}
2021-07-19 19:55:14 +08:00
[Test]
public void TestCreateRoomWithoutPassword ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-19 19:55:14 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-19 19:55:14 +08:00
}
}
} ) ;
2021-11-02 16:11:34 +08:00
2022-07-01 18:46:46 +08:00
AddUntilStep ( "Check participant count correct" , ( ) = > multiplayerClient . ClientAPIRoom ? . ParticipantCount . Value = = 1 ) ;
AddUntilStep ( "Check participant list contains user" , ( ) = > multiplayerClient . ClientAPIRoom ? . RecentParticipants . Count ( u = > u . Id = = API . LocalUser . Value . Id ) = = 1 ) ;
2021-07-19 19:55:14 +08:00
}
2021-07-20 15:23:48 +08:00
[Test]
public void TestExitMidJoin ( )
{
AddStep ( "create room" , ( ) = >
{
2021-08-17 08:45:10 +08:00
roomManager . AddServerSideRoom ( new Room
2021-07-20 15:23:48 +08:00
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-20 15:23:48 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-20 15:23:48 +08:00
}
}
2021-11-26 16:23:50 +08:00
} , API . LocalUser . Value ) ;
2021-07-20 15:23:48 +08:00
} ) ;
2021-08-17 08:36:43 +08:00
AddStep ( "refresh rooms" , ( ) = > this . ChildrenOfType < LoungeSubScreen > ( ) . Single ( ) . UpdateFilter ( ) ) ;
AddUntilStep ( "wait for room" , ( ) = > this . ChildrenOfType < DrawableRoom > ( ) . Any ( ) ) ;
2021-07-20 15:23:48 +08:00
AddStep ( "select room" , ( ) = > InputManager . Key ( Key . Down ) ) ;
2021-08-17 08:36:43 +08:00
AddStep ( "join room and immediately exit select" , ( ) = >
2021-07-20 15:23:48 +08:00
{
2021-08-17 08:36:43 +08:00
InputManager . Key ( Key . Enter ) ;
2021-07-20 15:23:48 +08:00
Schedule ( ( ) = > Stack . CurrentScreen . Exit ( ) ) ;
} ) ;
}
2021-07-19 19:55:14 +08:00
[Test]
public void TestJoinRoomWithoutPassword ( )
{
AddStep ( "create room" , ( ) = >
{
2021-08-17 08:45:10 +08:00
roomManager . AddServerSideRoom ( new Room
2021-07-19 19:55:14 +08:00
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-19 19:55:14 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-19 19:55:14 +08:00
}
}
2021-11-26 16:23:50 +08:00
} , API . LocalUser . Value ) ;
2021-07-19 19:55:14 +08:00
} ) ;
2021-08-17 08:36:43 +08:00
AddStep ( "refresh rooms" , ( ) = > this . ChildrenOfType < LoungeSubScreen > ( ) . Single ( ) . UpdateFilter ( ) ) ;
AddUntilStep ( "wait for room" , ( ) = > this . ChildrenOfType < DrawableRoom > ( ) . Any ( ) ) ;
2021-07-19 19:55:14 +08:00
AddStep ( "select room" , ( ) = > InputManager . Key ( Key . Down ) ) ;
AddStep ( "join room" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for room open" , ( ) = > this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for join" , ( ) = > multiplayerClient . RoomJoined ) ;
2021-11-02 16:11:34 +08:00
2022-07-01 18:46:46 +08:00
AddUntilStep ( "Check participant count correct" , ( ) = > multiplayerClient . ClientAPIRoom ? . ParticipantCount . Value = = 1 ) ;
AddUntilStep ( "Check participant list contains user" , ( ) = > multiplayerClient . ClientAPIRoom ? . RecentParticipants . Count ( u = > u . Id = = API . LocalUser . Value . Id ) = = 1 ) ;
2021-07-19 19:55:14 +08:00
}
2021-07-19 19:08:29 +08:00
[Test]
public void TestCreateRoomWithPassword ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Password = { Value = "password" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-19 19:08:29 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-19 19:08:29 +08:00
}
}
} ) ;
2022-07-01 18:46:46 +08:00
AddUntilStep ( "room has password" , ( ) = > multiplayerClient . ClientAPIRoom ? . Password . Value = = "password" ) ;
2021-07-19 19:08:29 +08:00
}
2021-07-19 19:55:14 +08:00
[Test]
public void TestJoinRoomWithPassword ( )
{
AddStep ( "create room" , ( ) = >
{
2021-08-17 08:45:10 +08:00
roomManager . AddServerSideRoom ( new Room
2021-07-19 19:55:14 +08:00
{
Name = { Value = "Test Room" } ,
Password = { Value = "password" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-19 19:55:14 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-19 19:55:14 +08:00
}
}
2021-11-26 16:23:50 +08:00
} , API . LocalUser . Value ) ;
2021-07-19 19:55:14 +08:00
} ) ;
2021-08-17 08:36:43 +08:00
AddStep ( "refresh rooms" , ( ) = > this . ChildrenOfType < LoungeSubScreen > ( ) . Single ( ) . UpdateFilter ( ) ) ;
AddUntilStep ( "wait for room" , ( ) = > this . ChildrenOfType < DrawableRoom > ( ) . Any ( ) ) ;
2021-07-19 19:55:14 +08:00
AddStep ( "select room" , ( ) = > InputManager . Key ( Key . Down ) ) ;
AddStep ( "join room" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
2022-07-07 16:51:49 +08:00
DrawableLoungeRoom . PasswordEntryPopover ? passwordEntryPopover = null ;
2021-08-18 19:53:17 +08:00
AddUntilStep ( "password prompt appeared" , ( ) = > ( passwordEntryPopover = InputManager . ChildrenOfType < DrawableLoungeRoom . PasswordEntryPopover > ( ) . FirstOrDefault ( ) ) ! = null ) ;
2021-07-19 19:55:14 +08:00
AddStep ( "enter password in text box" , ( ) = > passwordEntryPopover . ChildrenOfType < TextBox > ( ) . First ( ) . Text = "password" ) ;
2021-08-04 16:27:44 +08:00
AddStep ( "press join room button" , ( ) = > passwordEntryPopover . ChildrenOfType < OsuButton > ( ) . First ( ) . TriggerClick ( ) ) ;
2021-07-20 15:44:51 +08:00
AddUntilStep ( "wait for room open" , ( ) = > this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for join" , ( ) = > multiplayerClient . RoomJoined ) ;
2021-07-19 19:55:14 +08:00
}
2021-07-19 19:20:08 +08:00
[Test]
public void TestLocalPasswordUpdatedWhenMultiplayerSettingsChange ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Password = { Value = "password" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-19 19:20:08 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-19 19:20:08 +08:00
}
}
} ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "change password" , ( ) = > multiplayerClient . ChangeSettings ( password : "password2" ) ) ;
2022-07-01 17:04:29 +08:00
AddUntilStep ( "local password changed" , ( ) = > multiplayerClient . ClientAPIRoom ? . Password . Value = = "password2" ) ;
2021-07-19 19:20:08 +08:00
}
2021-07-05 18:10:27 +08:00
[Test]
public void TestUserSetToIdleWhenBeatmapDeleted ( )
{
2021-05-11 18:31:32 +08:00
createRoom ( ( ) = > new Room
2021-05-11 18:26:58 +08:00
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-05-11 18:26:58 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-05-11 18:26:58 +08:00
}
}
} ) ;
2021-12-11 21:47:08 +08:00
pressReadyButton ( ) ;
2021-05-11 18:26:58 +08:00
2021-12-11 21:47:08 +08:00
AddStep ( "delete beatmap" , ( ) = > beatmaps . Delete ( importedSet ) ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "user state is idle" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Idle ) ;
2021-05-11 18:01:41 +08:00
}
2021-12-06 13:03:24 +08:00
[Test]
public void TestPlayStartsWithCorrectBeatmapWhileAtSongSelect ( )
{
2022-07-19 12:21:16 +08:00
PlaylistItem ? item = null ;
createRoom ( ( ) = >
2021-12-06 13:03:24 +08:00
{
2022-07-19 12:21:16 +08:00
item = new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-12-06 13:03:24 +08:00
{
2022-07-19 12:21:16 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
} ;
return new Room
{
Name = { Value = "Test Room" } ,
Playlist = { item }
} ;
2021-12-06 13:03:24 +08:00
} ) ;
2021-12-11 21:47:08 +08:00
pressReadyButton ( ) ;
2021-12-06 13:03:24 +08:00
AddStep ( "Enter song select" , ( ) = >
{
2021-12-20 17:24:59 +08:00
var currentSubScreen = ( ( Screens . OnlinePlay . Multiplayer . Multiplayer ) multiplayerComponents . CurrentScreen ) . CurrentSubScreen ;
2022-07-19 12:21:16 +08:00
( ( MultiplayerMatchSubScreen ) currentSubScreen ) . OpenSongSelection ( item ) ;
2021-12-06 13:03:24 +08:00
} ) ;
2021-12-06 14:03:17 +08:00
AddUntilStep ( "wait for song select" , ( ) = > this . ChildrenOfType < MultiplayerMatchSongSelect > ( ) . FirstOrDefault ( ) ? . BeatmapSetsLoaded = = true ) ;
2021-12-06 13:03:24 +08:00
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Beatmap matches current item" , ( ) = > Beatmap . Value . BeatmapInfo . OnlineID = = multiplayerClient . ClientRoom ? . Playlist . First ( ) . BeatmapID ) ;
2021-12-06 13:03:24 +08:00
AddStep ( "Select next beatmap" , ( ) = > InputManager . Key ( Key . Down ) ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Beatmap doesn't match current item" , ( ) = > Beatmap . Value . BeatmapInfo . OnlineID ! = multiplayerClient . ClientRoom ? . Playlist . First ( ) . BeatmapID ) ;
2021-12-06 13:03:24 +08:00
2022-03-22 15:46:42 +08:00
AddStep ( "start match externally" , ( ) = > multiplayerClient . StartMatch ( ) . WaitSafely ( ) ) ;
2021-12-06 13:03:24 +08:00
2021-12-20 17:24:59 +08:00
AddUntilStep ( "play started" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
2021-12-06 13:03:24 +08:00
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Beatmap matches current item" , ( ) = > Beatmap . Value . BeatmapInfo . OnlineID = = multiplayerClient . ClientRoom ? . Playlist . First ( ) . BeatmapID ) ;
2021-12-06 13:03:24 +08:00
}
2022-01-08 21:39:22 +08:00
[Test]
public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect ( )
{
2022-07-19 12:21:16 +08:00
PlaylistItem ? item = null ;
createRoom ( ( ) = >
2022-01-08 21:39:22 +08:00
{
2022-07-19 12:21:16 +08:00
item = new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2022-01-08 21:39:22 +08:00
{
2022-07-19 12:21:16 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
} ;
return new Room
{
Name = { Value = "Test Room" } ,
Playlist = { item }
} ;
2022-01-08 21:39:22 +08:00
} ) ;
pressReadyButton ( ) ;
AddStep ( "Enter song select" , ( ) = >
{
var currentSubScreen = ( ( Screens . OnlinePlay . Multiplayer . Multiplayer ) multiplayerComponents . CurrentScreen ) . CurrentSubScreen ;
2022-07-19 12:21:16 +08:00
( ( MultiplayerMatchSubScreen ) currentSubScreen ) . OpenSongSelection ( item ) ;
2022-01-08 21:39:22 +08:00
} ) ;
AddUntilStep ( "wait for song select" , ( ) = > this . ChildrenOfType < MultiplayerMatchSongSelect > ( ) . FirstOrDefault ( ) ? . BeatmapSetsLoaded = = true ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Ruleset matches current item" , ( ) = > Ruleset . Value . OnlineID = = multiplayerClient . ClientRoom ? . Playlist . First ( ) . RulesetID ) ;
2022-01-08 21:39:22 +08:00
AddStep ( "Switch ruleset" , ( ) = > ( ( MultiplayerMatchSongSelect ) multiplayerComponents . MultiplayerScreen . CurrentSubScreen ) . Ruleset . Value = new CatchRuleset ( ) . RulesetInfo ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Ruleset doesn't match current item" , ( ) = > Ruleset . Value . OnlineID ! = multiplayerClient . ClientRoom ? . Playlist . First ( ) . RulesetID ) ;
2022-01-08 21:39:22 +08:00
2022-03-22 15:46:42 +08:00
AddStep ( "start match externally" , ( ) = > multiplayerClient . StartMatch ( ) . WaitSafely ( ) ) ;
2022-01-08 21:39:22 +08:00
AddUntilStep ( "play started" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Ruleset matches current item" , ( ) = > Ruleset . Value . OnlineID = = multiplayerClient . ClientRoom ? . Playlist . First ( ) . RulesetID ) ;
2022-01-08 21:39:22 +08:00
}
2022-01-08 21:50:49 +08:00
[Test]
public void TestPlayStartsWithCorrectModsWhileAtSongSelect ( )
{
2022-07-19 12:21:16 +08:00
PlaylistItem ? item = null ;
createRoom ( ( ) = >
2022-01-08 21:50:49 +08:00
{
2022-07-19 12:21:16 +08:00
item = new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2022-01-08 21:50:49 +08:00
{
2022-07-19 12:21:16 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
} ;
return new Room
{
Name = { Value = "Test Room" } ,
Playlist = { item }
} ;
2022-01-08 21:50:49 +08:00
} ) ;
pressReadyButton ( ) ;
AddStep ( "Enter song select" , ( ) = >
{
var currentSubScreen = ( ( Screens . OnlinePlay . Multiplayer . Multiplayer ) multiplayerComponents . CurrentScreen ) . CurrentSubScreen ;
2022-07-19 12:21:16 +08:00
( ( MultiplayerMatchSubScreen ) currentSubScreen ) . OpenSongSelection ( item ) ;
2022-01-08 21:50:49 +08:00
} ) ;
AddUntilStep ( "wait for song select" , ( ) = > this . ChildrenOfType < MultiplayerMatchSongSelect > ( ) . FirstOrDefault ( ) ? . BeatmapSetsLoaded = = true ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Mods match current item" ,
( ) = > SelectedMods . Value . Select ( m = > m . Acronym ) . SequenceEqual ( multiplayerClient . ClientRoom . AsNonNull ( ) . Playlist . First ( ) . RequiredMods . Select ( m = > m . Acronym ) ) ) ;
2022-01-08 21:50:49 +08:00
AddStep ( "Switch required mods" , ( ) = > ( ( MultiplayerMatchSongSelect ) multiplayerComponents . MultiplayerScreen . CurrentSubScreen ) . Mods . Value = new Mod [ ] { new OsuModDoubleTime ( ) } ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Mods don't match current item" ,
( ) = > ! SelectedMods . Value . Select ( m = > m . Acronym ) . SequenceEqual ( multiplayerClient . ClientRoom . AsNonNull ( ) . Playlist . First ( ) . RequiredMods . Select ( m = > m . Acronym ) ) ) ;
2022-01-08 21:50:49 +08:00
2022-03-22 15:46:42 +08:00
AddStep ( "start match externally" , ( ) = > multiplayerClient . StartMatch ( ) . WaitSafely ( ) ) ;
2022-01-08 21:50:49 +08:00
AddUntilStep ( "play started" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "Mods match current item" ,
( ) = > SelectedMods . Value . Select ( m = > m . Acronym ) . SequenceEqual ( multiplayerClient . ClientRoom . AsNonNull ( ) . Playlist . First ( ) . RequiredMods . Select ( m = > m . Acronym ) ) ) ;
2022-01-08 21:50:49 +08:00
}
2021-05-11 18:01:41 +08:00
[Test]
2021-05-11 18:21:44 +08:00
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap ( )
2021-05-11 18:01:41 +08:00
{
2021-05-11 18:31:32 +08:00
createRoom ( ( ) = > new Room
2021-05-11 18:01:41 +08:00
{
2021-05-11 18:21:44 +08:00
Name = { Value = "Test Room" } ,
Playlist =
2021-05-11 18:01:41 +08:00
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-05-11 18:01:41 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-05-11 18:01:41 +08:00
}
2021-05-11 18:21:44 +08:00
}
2021-05-11 18:01:41 +08:00
} ) ;
2021-05-11 18:21:44 +08:00
AddStep ( "join other user (ready, host)" , ( ) = >
2021-05-11 18:01:41 +08:00
{
2022-02-16 08:43:28 +08:00
multiplayerClient . AddUser ( new APIUser { Id = MultiplayerTestScene . PLAYER_1_ID , Username = "Other" } ) ;
multiplayerClient . TransferHost ( MultiplayerTestScene . PLAYER_1_ID ) ;
multiplayerClient . ChangeUserState ( MultiplayerTestScene . PLAYER_1_ID , MultiplayerUserState . Ready ) ;
2021-05-11 18:21:44 +08:00
} ) ;
AddStep ( "delete beatmap" , ( ) = > beatmaps . Delete ( importedSet ) ) ;
2021-12-21 12:20:12 +08:00
ClickButtonWhenEnabled < MultiplayerSpectateButton > ( ) ;
2021-05-11 18:01:41 +08:00
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for spectating user state" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2021-08-13 12:54:52 +08:00
2022-03-22 15:46:42 +08:00
AddStep ( "start match externally" , ( ) = > multiplayerClient . StartMatch ( ) . WaitSafely ( ) ) ;
2021-05-11 18:21:44 +08:00
2021-12-20 17:24:59 +08:00
AddAssert ( "play not started" , ( ) = > multiplayerComponents . IsCurrentScreen ( ) ) ;
2021-05-11 18:21:44 +08:00
}
[Test]
public void TestLocalPlayStartsWhileSpectatingWhenBeatmapBecomesAvailable ( )
{
2021-05-11 18:31:32 +08:00
createRoom ( ( ) = > new Room
2021-05-11 18:21:44 +08:00
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-05-11 18:21:44 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-05-11 18:21:44 +08:00
}
}
} ) ;
AddStep ( "delete beatmap" , ( ) = > beatmaps . Delete ( importedSet ) ) ;
2021-05-11 18:01:41 +08:00
AddStep ( "join other user (ready, host)" , ( ) = >
{
2022-02-16 08:43:28 +08:00
multiplayerClient . AddUser ( new APIUser { Id = MultiplayerTestScene . PLAYER_1_ID , Username = "Other" } ) ;
multiplayerClient . TransferHost ( MultiplayerTestScene . PLAYER_1_ID ) ;
multiplayerClient . ChangeUserState ( MultiplayerTestScene . PLAYER_1_ID , MultiplayerUserState . Ready ) ;
2021-05-11 18:01:41 +08:00
} ) ;
2021-12-21 12:20:12 +08:00
ClickButtonWhenEnabled < MultiplayerSpectateButton > ( ) ;
2021-05-11 18:01:41 +08:00
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for spectating user state" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2021-08-13 12:54:52 +08:00
2022-03-22 15:46:42 +08:00
AddStep ( "start match externally" , ( ) = > multiplayerClient . StartMatch ( ) . WaitSafely ( ) ) ;
2021-05-11 18:01:41 +08:00
2021-05-11 18:21:44 +08:00
AddStep ( "restore beatmap" , ( ) = >
{
2022-01-03 16:02:15 +08:00
beatmaps . Import ( TestResources . GetQuickTestBeatmapForImport ( ) ) . WaitSafely ( ) ;
2021-12-17 17:26:12 +08:00
importedSet = beatmaps . GetAllUsableBeatmapSets ( ) . First ( ) ;
2021-05-11 18:21:44 +08:00
} ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "play started" , ( ) = > multiplayerComponents . CurrentScreen is SpectatorScreen ) ;
2021-05-11 18:21:44 +08:00
}
2021-07-13 16:31:28 +08:00
[Test]
public void TestSubScreenExitedWhenDisconnectedFromMultiplayerServer ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-07-13 16:31:28 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2021-07-13 16:31:28 +08:00
}
}
} ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "disconnect" , ( ) = > multiplayerClient . Disconnect ( ) ) ;
2021-07-13 16:31:28 +08:00
AddUntilStep ( "back in lounge" , ( ) = > this . ChildrenOfType < LoungeSubScreen > ( ) . FirstOrDefault ( ) ? . IsCurrentScreen ( ) = = true ) ;
}
2021-06-22 23:48:41 +08:00
[Test]
public void TestLeaveNavigation ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-06-22 23:48:41 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
AllowedMods = new [ ] { new APIMod ( new OsuModHidden ( ) ) }
2021-06-22 23:48:41 +08:00
}
}
} ) ;
2021-08-13 13:04:43 +08:00
AddStep ( "open mod overlay" , ( ) = > this . ChildrenOfType < RoomSubScreen . UserModSelectButton > ( ) . Single ( ) . TriggerClick ( ) ) ;
2021-06-22 23:48:41 +08:00
2021-12-20 17:24:59 +08:00
AddStep ( "invoke on back button" , ( ) = > multiplayerComponents . OnBackButton ( ) ) ;
2021-06-22 23:48:41 +08:00
2022-05-11 04:29:57 +08:00
AddAssert ( "mod overlay is hidden" , ( ) = > this . ChildrenOfType < UserModSelectOverlay > ( ) . Single ( ) . State . Value = = Visibility . Hidden ) ;
2021-06-22 23:48:41 +08:00
AddAssert ( "dialog overlay is hidden" , ( ) = > DialogOverlay . State . Value = = Visibility . Hidden ) ;
2021-12-20 17:24:59 +08:00
testLeave ( "back button" , ( ) = > multiplayerComponents . OnBackButton ( ) ) ;
2021-06-22 23:48:41 +08:00
// mimics home button and OS window close
2021-12-20 17:24:59 +08:00
testLeave ( "forced exit" , ( ) = > multiplayerComponents . Exit ( ) ) ;
2021-06-22 23:48:41 +08:00
void testLeave ( string actionName , Action action )
{
AddStep ( $"leave via {actionName}" , action ) ;
AddAssert ( "dialog overlay is visible" , ( ) = > DialogOverlay . State . Value = = Visibility . Visible ) ;
AddStep ( "close dialog overlay" , ( ) = > InputManager . Key ( Key . Escape ) ) ;
}
}
2021-08-24 12:20:01 +08:00
[Test]
public void TestGameplayFlow ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-08-24 12:20:01 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-08-24 12:20:01 +08:00
}
}
} ) ;
2021-12-15 15:52:50 +08:00
enterGameplay ( ) ;
2021-08-24 12:20:01 +08:00
// Gameplay runs in real-time, so we need to incrementally check if gameplay has finished in order to not time out.
for ( double i = 1000 ; i < TestResources . QUICK_BEATMAP_LENGTH ; i + = 1000 )
{
2021-10-27 12:04:41 +08:00
double time = i ;
2021-08-24 12:20:01 +08:00
AddUntilStep ( $"wait for time > {i}" , ( ) = > this . ChildrenOfType < GameplayClockContainer > ( ) . SingleOrDefault ( ) ? . GameplayClock . CurrentTime > time ) ;
}
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for results" , ( ) = > multiplayerComponents . CurrentScreen is ResultsScreen ) ;
2021-08-24 12:20:01 +08:00
}
2022-05-06 14:22:22 +08:00
[Test]
public void TestGameplayExitFlow ( )
{
2022-07-07 16:51:49 +08:00
Bindable < double > ? holdDelay = null ;
2022-05-06 14:22:22 +08:00
AddStep ( "Set hold delay to zero" , ( ) = >
{
holdDelay = config . GetBindable < double > ( OsuSetting . UIHoldActivationDelay ) ;
holdDelay . Value = 0 ;
} ) ;
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
{
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
}
}
} ) ;
enterGameplay ( ) ;
AddUntilStep ( "wait for playing" , ( ) = > this . ChildrenOfType < Player > ( ) . FirstOrDefault ( ) ? . LocalUserPlaying . Value = = true ) ;
AddStep ( "attempt exit without hold" , ( ) = > InputManager . Key ( Key . Escape ) ) ;
AddAssert ( "still in gameplay" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
AddStep ( "attempt exit with hold" , ( ) = > InputManager . PressKey ( Key . Escape ) ) ;
AddUntilStep ( "wait for lounge" , ( ) = > multiplayerComponents . CurrentScreen is Screens . OnlinePlay . Multiplayer . Multiplayer ) ;
AddStep ( "stop holding" , ( ) = > InputManager . ReleaseKey ( Key . Escape ) ) ;
2022-07-07 16:51:49 +08:00
AddStep ( "set hold delay to default" , ( ) = > holdDelay ? . SetDefault ( ) ) ;
2022-05-06 14:22:22 +08:00
}
2022-03-18 13:27:58 +08:00
[Test]
public void TestGameplayDoesntStartWithNonLoadedUser ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
{
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
}
}
} ) ;
pressReadyButton ( ) ;
AddStep ( "join other user and ready" , ( ) = >
{
multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ;
multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Ready ) ;
} ) ;
AddStep ( "start match" , ( ) = >
{
multiplayerClient . StartMatch ( ) ;
} ) ;
AddUntilStep ( "wait for player" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
AddWaitStep ( "wait some" , 20 ) ;
AddAssert ( "ensure gameplay hasn't started" , ( ) = > this . ChildrenOfType < GameplayClockContainer > ( ) . SingleOrDefault ( ) ? . IsRunning = = false ) ;
}
2021-11-13 00:53:58 +08:00
[Test]
public void TestRoomSettingsReQueriedWhenJoiningRoom ( )
{
AddStep ( "create room" , ( ) = >
{
roomManager . AddServerSideRoom ( new Room
{
Name = { Value = "Test Room" } ,
2021-11-19 17:28:43 +08:00
QueueMode = { Value = QueueMode . AllPlayers } ,
2021-11-13 00:53:58 +08:00
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-11-13 00:53:58 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-11-13 00:53:58 +08:00
}
}
2021-11-26 16:23:50 +08:00
} , API . LocalUser . Value ) ;
2021-11-13 00:53:58 +08:00
} ) ;
AddStep ( "refresh rooms" , ( ) = > this . ChildrenOfType < LoungeSubScreen > ( ) . Single ( ) . UpdateFilter ( ) ) ;
AddUntilStep ( "wait for room" , ( ) = > this . ChildrenOfType < DrawableRoom > ( ) . Any ( ) ) ;
AddStep ( "select room" , ( ) = > InputManager . Key ( Key . Down ) ) ;
AddStep ( "disable polling" , ( ) = > this . ChildrenOfType < ListingPollingComponent > ( ) . Single ( ) . TimeBetweenPolls . Value = 0 ) ;
AddStep ( "change server-side settings" , ( ) = >
{
roomManager . ServerSideRooms [ 0 ] . Name . Value = "New name" ;
2022-02-15 22:33:26 +08:00
roomManager . ServerSideRooms [ 0 ] . Playlist . Add ( new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-11-13 00:53:58 +08:00
{
ID = 2 ,
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-11-13 00:53:58 +08:00
} ) ;
} ) ;
AddStep ( "join room" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for room open" , ( ) = > this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for join" , ( ) = > multiplayerClient . RoomJoined ) ;
2021-11-13 00:53:58 +08:00
AddAssert ( "local room has correct settings" , ( ) = >
{
var localRoom = this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . Single ( ) . Room ;
return localRoom . Name . Value = = roomManager . ServerSideRooms [ 0 ] . Name . Value
& & localRoom . Playlist . SequenceEqual ( roomManager . ServerSideRooms [ 0 ] . Playlist ) ;
} ) ;
}
2021-12-15 16:37:39 +08:00
[Test]
public void TestSpectatingStateResetOnBackButtonDuringGameplay ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
QueueMode = { Value = QueueMode . AllPlayers } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-12-15 16:37:39 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-12-15 16:37:39 +08:00
}
}
} ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "set spectating state" , ( ) = > multiplayerClient . ChangeUserState ( API . LocalUser . Value . OnlineID , MultiplayerUserState . Spectating ) ) ;
AddUntilStep ( "state set to spectating" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2021-12-15 16:37:39 +08:00
2022-02-16 08:43:28 +08:00
AddStep ( "join other user" , ( ) = > multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ) ;
AddStep ( "set other user ready" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Ready ) ) ;
2021-12-15 16:37:39 +08:00
pressReadyButton ( 1234 ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for gameplay" , ( ) = > ( multiplayerComponents . CurrentScreen as MultiSpectatorScreen ) ? . IsLoaded = = true ) ;
2021-12-15 16:37:39 +08:00
AddStep ( "press back button and exit" , ( ) = >
{
2021-12-20 17:24:59 +08:00
multiplayerComponents . OnBackButton ( ) ;
multiplayerComponents . Exit ( ) ;
2021-12-15 16:37:39 +08:00
} ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for return to match subscreen" , ( ) = > multiplayerComponents . MultiplayerScreen . IsCurrentScreen ( ) ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "user state is idle" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Idle ) ;
2021-12-15 16:37:39 +08:00
}
[Test]
public void TestSpectatingStateNotResetOnBackButtonOutsideOfGameplay ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
QueueMode = { Value = QueueMode . AllPlayers } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-12-15 16:37:39 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-12-15 16:37:39 +08:00
}
}
} ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "set spectating state" , ( ) = > multiplayerClient . ChangeUserState ( API . LocalUser . Value . OnlineID , MultiplayerUserState . Spectating ) ) ;
AddUntilStep ( "state set to spectating" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2021-12-15 16:37:39 +08:00
2022-02-16 08:43:28 +08:00
AddStep ( "join other user" , ( ) = > multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ) ;
AddStep ( "set other user ready" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Ready ) ) ;
2021-12-15 16:37:39 +08:00
pressReadyButton ( 1234 ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for gameplay" , ( ) = > ( multiplayerComponents . CurrentScreen as MultiSpectatorScreen ) ? . IsLoaded = = true ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "set other user loaded" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Loaded ) ) ;
AddStep ( "set other user finished play" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . FinishedPlay ) ) ;
2021-12-15 16:37:39 +08:00
AddStep ( "press back button and exit" , ( ) = >
{
2021-12-20 17:24:59 +08:00
multiplayerComponents . OnBackButton ( ) ;
multiplayerComponents . Exit ( ) ;
2021-12-15 16:37:39 +08:00
} ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for return to match subscreen" , ( ) = > multiplayerComponents . MultiplayerScreen . IsCurrentScreen ( ) ) ;
2021-12-15 16:37:39 +08:00
AddWaitStep ( "wait for possible state change" , 5 ) ;
2022-02-16 08:43:28 +08:00
AddUntilStep ( "user state is spectating" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2021-12-15 16:37:39 +08:00
}
2021-12-15 16:30:09 +08:00
[Test]
public void TestItemAddedByOtherUserDuringGameplay ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
QueueMode = { Value = QueueMode . AllPlayers } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-12-15 16:30:09 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-12-15 16:30:09 +08:00
}
}
} ) ;
enterGameplay ( ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "join other user" , ( ) = > multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ) ;
2022-02-16 13:24:57 +08:00
AddStep ( "add item as other user" , ( ) = > multiplayerClient . AddUserPlaylistItem ( 1234 , new MultiplayerPlaylistItem (
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
{
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2022-02-16 13:24:57 +08:00
} ) ) . WaitSafely ( ) ) ;
2021-12-15 16:30:09 +08:00
2022-07-01 17:58:22 +08:00
AddUntilStep ( "item arrived in playlist" , ( ) = > multiplayerClient . ClientRoom ? . Playlist . Count = = 2 ) ;
2021-12-15 16:30:09 +08:00
2021-12-20 17:24:59 +08:00
AddStep ( "exit gameplay as initial user" , ( ) = > multiplayerComponents . MultiplayerScreen . MakeCurrent ( ) ) ;
2021-12-15 16:30:09 +08:00
AddUntilStep ( "queue contains item" , ( ) = > this . ChildrenOfType < MultiplayerQueueList > ( ) . Single ( ) . Items . Single ( ) . ID = = 2 ) ;
}
2021-12-15 15:52:50 +08:00
[Test]
public void TestItemAddedAndDeletedByOtherUserDuringGameplay ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
QueueMode = { Value = QueueMode . AllPlayers } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2021-12-15 15:52:50 +08:00
{
2022-02-15 22:33:26 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2021-12-15 15:52:50 +08:00
}
}
} ) ;
enterGameplay ( ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "join other user" , ( ) = > multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ) ;
2022-02-16 13:24:57 +08:00
AddStep ( "add item as other user" , ( ) = > multiplayerClient . AddUserPlaylistItem ( 1234 , new MultiplayerPlaylistItem (
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
{
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID ,
2022-02-16 13:24:57 +08:00
} ) ) . WaitSafely ( ) ) ;
2021-12-15 15:59:34 +08:00
2022-07-01 17:58:22 +08:00
AddUntilStep ( "item arrived in playlist" , ( ) = > multiplayerClient . ClientRoom ? . Playlist . Count = = 2 ) ;
2021-12-15 15:59:34 +08:00
2022-02-16 08:43:28 +08:00
AddStep ( "delete item as other user" , ( ) = > multiplayerClient . RemoveUserPlaylistItem ( 1234 , 2 ) . WaitSafely ( ) ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "item removed from playlist" , ( ) = > multiplayerClient . ClientRoom ? . Playlist . Count = = 1 ) ;
2021-12-15 15:52:50 +08:00
2021-12-20 17:24:59 +08:00
AddStep ( "exit gameplay as initial user" , ( ) = > multiplayerComponents . MultiplayerScreen . MakeCurrent ( ) ) ;
2021-12-15 15:52:50 +08:00
AddUntilStep ( "queue is empty" , ( ) = > this . ChildrenOfType < MultiplayerQueueList > ( ) . Single ( ) . Items . Count = = 0 ) ;
}
2022-02-03 22:18:22 +08:00
[Test]
public void TestGameplayStartsWhileInSpectatorScreen ( )
{
createRoom ( ( ) = > new Room
{
Name = { Value = "Test Room" } ,
Playlist =
{
2022-02-15 22:33:26 +08:00
new PlaylistItem ( beatmaps . GetWorkingBeatmap ( importedSet . Beatmaps . First ( b = > b . Ruleset . OnlineID = = 0 ) ) . BeatmapInfo )
2022-02-03 22:18:22 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2022-02-03 22:18:22 +08:00
}
}
} ) ;
AddStep ( "join other user and make host" , ( ) = >
{
2022-02-16 08:43:28 +08:00
multiplayerClient . AddUser ( new APIUser { Id = 1234 } ) ;
multiplayerClient . TransferHost ( 1234 ) ;
2022-02-03 22:18:22 +08:00
} ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "set local user spectating" , ( ) = > multiplayerClient . ChangeUserState ( API . LocalUser . Value . OnlineID , MultiplayerUserState . Spectating ) ) ;
AddUntilStep ( "wait for spectating state" , ( ) = > multiplayerClient . LocalUser ? . State = = MultiplayerUserState . Spectating ) ;
2022-02-03 22:18:22 +08:00
runGameplay ( ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "exit gameplay for other user" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Idle ) ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "wait for room to be idle" , ( ) = > multiplayerClient . ClientRoom ? . State = = MultiplayerRoomState . Open ) ;
2022-02-03 22:18:22 +08:00
runGameplay ( ) ;
void runGameplay ( )
{
AddStep ( "start match by other user" , ( ) = >
{
2022-02-16 08:43:28 +08:00
multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Ready ) ;
2022-03-22 15:46:42 +08:00
multiplayerClient . StartMatch ( ) . WaitSafely ( ) ;
2022-02-03 22:18:22 +08:00
} ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "wait for loading" , ( ) = > multiplayerClient . ClientRoom ? . State = = MultiplayerRoomState . WaitingForLoad ) ;
2022-02-16 08:43:28 +08:00
AddStep ( "set player loaded" , ( ) = > multiplayerClient . ChangeUserState ( 1234 , MultiplayerUserState . Loaded ) ) ;
2022-07-01 17:58:22 +08:00
AddUntilStep ( "wait for gameplay to start" , ( ) = > multiplayerClient . ClientRoom ? . State = = MultiplayerRoomState . Playing ) ;
2022-02-03 22:22:08 +08:00
AddUntilStep ( "wait for local user to enter spectator" , ( ) = > multiplayerComponents . CurrentScreen is MultiSpectatorScreen ) ;
2022-02-03 22:18:22 +08:00
}
}
2021-12-15 16:37:39 +08:00
private void enterGameplay ( )
{
pressReadyButton ( ) ;
pressReadyButton ( ) ;
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for player" , ( ) = > multiplayerComponents . CurrentScreen is Player ) ;
2021-12-15 16:37:39 +08:00
}
2021-12-11 21:47:08 +08:00
private ReadyButton readyButton = > this . ChildrenOfType < ReadyButton > ( ) . Single ( ) ;
2021-12-15 16:37:39 +08:00
private void pressReadyButton ( int? playingUserId = null )
2021-12-11 21:47:08 +08:00
{
2021-12-21 12:47:37 +08:00
// Can't use ClickButtonWhenEnabled<> due to needing to store the state after the button is enabled.
2021-12-11 21:47:08 +08:00
AddUntilStep ( "wait for ready button to be enabled" , ( ) = > readyButton . Enabled . Value ) ;
MultiplayerUserState lastState = MultiplayerUserState . Idle ;
2022-07-07 16:51:49 +08:00
MultiplayerRoomUser ? user = null ;
2021-12-11 21:47:08 +08:00
AddStep ( "click ready button" , ( ) = >
{
2022-07-01 17:58:22 +08:00
user = playingUserId = = null ? multiplayerClient . LocalUser : multiplayerClient . ServerRoom ? . Users . Single ( u = > u . UserID = = playingUserId ) ;
2021-12-15 16:37:39 +08:00
lastState = user ? . State ? ? MultiplayerUserState . Idle ;
2021-12-11 21:47:08 +08:00
InputManager . MoveMouseTo ( readyButton ) ;
InputManager . Click ( MouseButton . Left ) ;
} ) ;
2021-12-15 16:37:39 +08:00
AddUntilStep ( "wait for state change" , ( ) = > user ? . State ! = lastState ) ;
2021-12-11 21:47:08 +08:00
}
2021-10-14 14:58:42 +08:00
2021-05-11 18:31:32 +08:00
private void createRoom ( Func < Room > room )
2021-05-11 18:21:44 +08:00
{
2021-12-20 17:24:59 +08:00
AddUntilStep ( "wait for lounge" , ( ) = > multiplayerComponents . ChildrenOfType < LoungeSubScreen > ( ) . SingleOrDefault ( ) ? . IsLoaded = = true ) ;
AddStep ( "open room" , ( ) = > multiplayerComponents . ChildrenOfType < LoungeSubScreen > ( ) . Single ( ) . Open ( room ( ) ) ) ;
2021-05-11 18:21:44 +08:00
2021-05-11 18:31:32 +08:00
AddUntilStep ( "wait for room open" , ( ) = > this . ChildrenOfType < MultiplayerMatchSubScreen > ( ) . FirstOrDefault ( ) ? . IsLoaded = = true ) ;
AddWaitStep ( "wait for transition" , 2 ) ;
2021-12-21 12:20:12 +08:00
ClickButtonWhenEnabled < MultiplayerMatchSettingsOverlay . CreateOrUpdateButton > ( ) ;
2021-05-11 18:21:44 +08:00
2022-02-16 08:43:28 +08:00
AddUntilStep ( "wait for join" , ( ) = > multiplayerClient . RoomJoined ) ;
2021-05-11 18:01:41 +08:00
}
2020-12-21 17:42:31 +08:00
}
}