2021-04-09 17:16:10 +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.
2022-06-17 15:37:17 +08:00
#nullable disable
2021-04-09 17:16:10 +08:00
using System.Collections.Generic ;
using System.Linq ;
using NUnit.Framework ;
2022-06-02 13:22:12 +08:00
using osu.Framework.Graphics ;
2021-04-09 17:16:10 +08:00
using osu.Framework.Testing ;
using osu.Framework.Timing ;
2021-11-04 17:02:44 +08:00
using osu.Game.Online.API.Requests.Responses ;
2021-08-10 17:39:20 +08:00
using osu.Game.Online.Multiplayer ;
2021-04-09 17:16:10 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate ;
using osu.Game.Screens.Play.HUD ;
namespace osu.Game.Tests.Visual.Multiplayer
{
2021-04-26 15:48:32 +08:00
public partial class TestSceneMultiSpectatorLeaderboard : MultiplayerTestScene
2021-04-09 17:16:10 +08:00
{
2021-06-25 14:00:10 +08:00
private Dictionary < int , ManualClock > clocks ;
2021-06-24 20:02:04 +08:00
private MultiSpectatorLeaderboard leaderboard ;
2021-04-09 17:16:10 +08:00
[SetUpSteps]
2022-07-29 14:27:39 +08:00
public override void SetUpSteps ( )
2021-04-09 17:16:10 +08:00
{
2022-07-29 14:27:39 +08:00
base . SetUpSteps ( ) ;
2021-04-09 17:16:10 +08:00
AddStep ( "reset" , ( ) = >
{
2022-06-02 13:22:12 +08:00
leaderboard ? . RemoveAndDisposeImmediately ( ) ;
2021-04-09 17:16:10 +08:00
2021-06-24 20:02:04 +08:00
clocks = new Dictionary < int , ManualClock >
2021-04-09 17:16:10 +08:00
{
2021-06-25 14:00:10 +08:00
{ PLAYER_1_ID , new ManualClock ( ) } ,
{ PLAYER_2_ID , new ManualClock ( ) }
2021-06-24 20:02:04 +08:00
} ;
2022-06-02 13:22:45 +08:00
foreach ( ( int userId , _ ) in clocks )
2021-08-09 18:05:23 +08:00
{
2022-02-22 16:56:07 +08:00
SpectatorClient . SendStartPlay ( userId , 0 ) ;
2022-06-02 13:22:45 +08:00
OnlinePlayDependencies . MultiplayerClient . AddUser ( new APIUser { Id = userId } , true ) ;
2021-08-09 18:05:23 +08:00
}
2021-04-09 17:16:10 +08:00
} ) ;
AddStep ( "create leaderboard" , ( ) = >
{
Beatmap . Value = CreateWorkingBeatmap ( Ruleset . Value ) ;
2022-05-30 18:18:38 +08:00
LoadComponentAsync ( leaderboard = new MultiSpectatorLeaderboard ( clocks . Keys . Select ( id = > new MultiplayerRoomUser ( id ) ) . ToArray ( ) )
2022-03-08 11:57:59 +08:00
{
2023-08-02 15:07:03 +08:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2022-03-08 11:57:59 +08:00
Expanded = { Value = true }
} , Add ) ;
2021-04-09 17:16:10 +08:00
} ) ;
AddUntilStep ( "wait for load" , ( ) = > leaderboard . IsLoaded ) ;
2021-12-30 22:35:18 +08:00
AddUntilStep ( "wait for user population" , ( ) = > leaderboard . ChildrenOfType < GameplayLeaderboardScore > ( ) . Count ( ) = = 2 ) ;
2021-04-09 17:16:10 +08:00
AddStep ( "add clock sources" , ( ) = >
{
2021-10-27 12:04:41 +08:00
foreach ( ( int userId , var clock ) in clocks )
2021-04-09 17:16:10 +08:00
leaderboard . AddClock ( userId , clock ) ;
} ) ;
}
[Test]
public void TestLeaderboardTracksCurrentTime ( )
{
AddStep ( "send frames" , ( ) = >
{
2021-04-26 16:22:16 +08:00
// For player 1, send frames in sets of 1.
// For player 2, send frames in sets of 10.
2021-04-09 17:16:10 +08:00
for ( int i = 0 ; i < 100 ; i + + )
{
2022-02-24 01:18:35 +08:00
SpectatorClient . SendFramesFromUser ( PLAYER_1_ID , 1 ) ;
2021-04-09 17:16:10 +08:00
if ( i % 10 = = 0 )
2022-02-24 01:18:35 +08:00
SpectatorClient . SendFramesFromUser ( PLAYER_2_ID , 10 ) ;
2021-04-09 17:16:10 +08:00
}
} ) ;
2021-04-26 16:22:16 +08:00
assertCombo ( PLAYER_1_ID , 1 ) ;
assertCombo ( PLAYER_2_ID , 10 ) ;
2021-04-09 17:16:10 +08:00
2021-04-26 16:22:16 +08:00
// Advance to a point where only user player 1's frame changes.
2021-04-09 17:16:10 +08:00
setTime ( 500 ) ;
2021-04-26 16:22:16 +08:00
assertCombo ( PLAYER_1_ID , 5 ) ;
assertCombo ( PLAYER_2_ID , 10 ) ;
2021-04-09 17:16:10 +08:00
2021-04-09 17:23:41 +08:00
// Advance to a point where both user's frame changes.
2021-04-09 17:16:10 +08:00
setTime ( 1100 ) ;
2021-04-26 16:22:16 +08:00
assertCombo ( PLAYER_1_ID , 11 ) ;
assertCombo ( PLAYER_2_ID , 20 ) ;
2021-04-09 17:23:41 +08:00
2021-04-26 16:22:16 +08:00
// 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 ) ;
2021-04-09 17:23:41 +08:00
// Advance both users beyond their last frame
setTime ( 101 * 100 ) ;
2021-04-26 16:22:16 +08:00
assertCombo ( PLAYER_1_ID , 100 ) ;
assertCombo ( PLAYER_2_ID , 100 ) ;
2021-04-09 17:16:10 +08:00
}
2021-04-09 17:18:23 +08:00
[Test]
public void TestNoFrames ( )
{
2021-04-26 16:22:16 +08:00
assertCombo ( PLAYER_1_ID , 0 ) ;
assertCombo ( PLAYER_2_ID , 0 ) ;
2021-04-09 17:18:23 +08:00
}
2021-04-09 17:16:10 +08:00
private void setTime ( double time ) = > AddStep ( $"set time {time}" , ( ) = >
{
foreach ( var ( _ , clock ) in clocks )
clock . CurrentTime = time ;
} ) ;
2021-04-09 17:23:41 +08:00
private void setTime ( int userId , double time )
= > AddStep ( $"set user {userId} time {time}" , ( ) = > clocks [ userId ] . CurrentTime = time ) ;
2021-04-09 17:16:10 +08:00
private void assertCombo ( int userId , int expectedCombo )
2022-09-13 15:56:19 +08:00
= > AddUntilStep ( $"player {userId} has {expectedCombo} combo" , ( ) = > this . ChildrenOfType < GameplayLeaderboardScore > ( ) . Single ( s = > s . User ? . OnlineID = = userId ) . Combo . Value = = expectedCombo ) ;
2021-04-09 17:16:10 +08:00
}
}