2020-12-19 00:17:24 +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.
using System ;
using System.Collections.Generic ;
2020-12-19 00:22:52 +08:00
using System.Linq ;
2020-12-19 00:17:24 +08:00
using osu.Framework.Allocation ;
using osu.Game.Online.API ;
using osu.Game.Online.API.Requests ;
2020-12-25 12:38:11 +08:00
using osu.Game.Online.Rooms ;
2020-12-19 00:17:24 +08:00
using osu.Game.Rulesets.Scoring ;
using osu.Game.Scoring ;
2021-06-25 17:02:53 +08:00
using osu.Game.Screens.OnlinePlay.Components ;
2020-12-25 23:50:00 +08:00
using osu.Game.Screens.OnlinePlay.Multiplayer ;
2020-12-19 00:17:24 +08:00
2020-12-25 12:38:11 +08:00
namespace osu.Game.Tests.Visual.Multiplayer
2020-12-19 00:17:24 +08:00
{
2021-06-25 17:02:53 +08:00
/// <summary>
/// A <see cref="RoomManager"/> for use in multiplayer test scenes. Should generally not be used by itself outside of a <see cref="MultiplayerTestScene"/>.
/// </summary>
2021-07-26 14:47:13 +08:00
/// <remarks>
/// This implementation will pretend to be a server, handling room retrieval and manipulation requests
/// and returning a roughly expected state, without the need for a server to be running.
/// </remarks>
public class TestRequestHandlingMultiplayerRoomManager : MultiplayerRoomManager
2020-12-19 00:17:24 +08:00
{
[Resolved]
private IAPIProvider api { get ; set ; }
[Resolved]
private OsuGameBase game { get ; set ; }
2021-08-17 08:48:33 +08:00
public IReadOnlyList < Room > ServerSideRooms = > serverSideRooms ;
private readonly List < Room > serverSideRooms = new List < Room > ( ) ;
2020-12-19 00:17:24 +08:00
2021-07-26 14:47:13 +08:00
private int currentRoomId ;
private int currentPlaylistItemId ;
2021-06-25 14:00:10 +08:00
[BackgroundDependencyLoader]
private void load ( )
2020-12-19 00:17:24 +08:00
{
int currentScoreId = 0 ;
2021-07-26 14:47:13 +08:00
// Handling here is pretending to be a server, while also updating the local state to match
// how the server would eventually respond and update the RoomManager.
2020-12-19 00:17:24 +08:00
( ( DummyAPIAccess ) api ) . HandleRequest = req = >
{
switch ( req )
{
case CreateRoomRequest createRoomRequest :
2021-07-19 18:55:08 +08:00
var apiRoom = new Room ( ) ;
2020-12-19 00:17:24 +08:00
2021-07-19 18:55:08 +08:00
apiRoom . CopyFrom ( createRoomRequest . Room ) ;
2021-07-19 19:07:56 +08:00
// Passwords are explicitly not copied between rooms.
apiRoom . HasPassword . Value = ! string . IsNullOrEmpty ( createRoomRequest . Room . Password . Value ) ;
apiRoom . Password . Value = createRoomRequest . Room . Password . Value ;
2021-08-17 08:42:17 +08:00
AddServerSideRoom ( apiRoom ) ;
2020-12-19 00:17:24 +08:00
2021-07-19 18:55:08 +08:00
var responseRoom = new APICreatedRoom ( ) ;
responseRoom . CopyFrom ( createResponseRoom ( apiRoom , false ) ) ;
2021-03-01 16:24:05 +08:00
2021-07-19 18:55:08 +08:00
createRoomRequest . TriggerSuccess ( responseRoom ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
case JoinRoomRequest joinRoomRequest :
2021-07-19 18:55:08 +08:00
{
2021-08-17 08:42:17 +08:00
var room = ServerSideRooms . Single ( r = > r . RoomID . Value = = joinRoomRequest . Room . RoomID . Value ) ;
2021-07-19 18:55:08 +08:00
if ( joinRoomRequest . Password ! = room . Password . Value )
{
joinRoomRequest . TriggerFailure ( new InvalidOperationException ( "Invalid password." ) ) ;
return true ;
}
2020-12-19 00:17:24 +08:00
joinRoomRequest . TriggerSuccess ( ) ;
2021-03-23 17:08:32 +08:00
return true ;
2021-07-19 18:55:08 +08:00
}
2020-12-19 00:17:24 +08:00
case PartRoomRequest partRoomRequest :
partRoomRequest . TriggerSuccess ( ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
case GetRoomsRequest getRoomsRequest :
2020-12-19 00:22:52 +08:00
var roomsWithoutParticipants = new List < Room > ( ) ;
2021-08-17 08:42:17 +08:00
foreach ( var r in ServerSideRooms )
2021-07-19 18:55:08 +08:00
roomsWithoutParticipants . Add ( createResponseRoom ( r , false ) ) ;
2020-12-19 00:22:52 +08:00
getRoomsRequest . TriggerSuccess ( roomsWithoutParticipants ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:22:52 +08:00
case GetRoomRequest getRoomRequest :
2021-08-17 08:42:17 +08:00
getRoomRequest . TriggerSuccess ( createResponseRoom ( ServerSideRooms . Single ( r = > r . RoomID . Value = = getRoomRequest . RoomId ) , true ) ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
case GetBeatmapSetRequest getBeatmapSetRequest :
var onlineReq = new GetBeatmapSetRequest ( getBeatmapSetRequest . ID , getBeatmapSetRequest . Type ) ;
onlineReq . Success + = res = > getBeatmapSetRequest . TriggerSuccess ( res ) ;
onlineReq . Failure + = e = > getBeatmapSetRequest . TriggerFailure ( e ) ;
// Get the online API from the game's dependencies.
game . Dependencies . Get < IAPIProvider > ( ) . Queue ( onlineReq ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
case CreateRoomScoreRequest createRoomScoreRequest :
createRoomScoreRequest . TriggerSuccess ( new APIScoreToken { ID = 1 } ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
case SubmitRoomScoreRequest submitRoomScoreRequest :
submitRoomScoreRequest . TriggerSuccess ( new MultiplayerScore
{
ID = currentScoreId + + ,
Accuracy = 1 ,
EndedAt = DateTimeOffset . Now ,
Passed = true ,
Rank = ScoreRank . S ,
MaxCombo = 1000 ,
TotalScore = 1000000 ,
User = api . LocalUser . Value ,
Statistics = new Dictionary < HitResult , int > ( )
} ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-12-19 00:17:24 +08:00
}
2021-03-23 17:08:32 +08:00
return false ;
2020-12-19 00:17:24 +08:00
} ;
}
2021-08-17 08:42:17 +08:00
public void AddServerSideRoom ( Room room )
2021-07-26 14:47:13 +08:00
{
room . RoomID . Value ? ? = currentRoomId + + ;
for ( int i = 0 ; i < room . Playlist . Count ; i + + )
room . Playlist [ i ] . ID = currentPlaylistItemId + + ;
2021-08-17 08:48:33 +08:00
serverSideRooms . Add ( room ) ;
2021-07-26 14:47:13 +08:00
}
2021-07-19 18:55:08 +08:00
private Room createResponseRoom ( Room room , bool withParticipants )
{
var responseRoom = new Room ( ) ;
responseRoom . CopyFrom ( room ) ;
responseRoom . Password . Value = null ;
if ( ! withParticipants )
responseRoom . RecentParticipants . Clear ( ) ;
return responseRoom ;
}
2020-12-19 00:17:24 +08:00
}
}