mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 07:06:35 +09:00
Merge branch 'master' into fix-legacy-skin-texture-loader-store
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
@ -12,11 +13,7 @@ namespace osu.Game.Tests.Visual
|
||||
[Cached]
|
||||
private readonly Bindable<Room> currentRoom = new Bindable<Room>();
|
||||
|
||||
protected Room Room
|
||||
{
|
||||
get => currentRoom.Value;
|
||||
set => currentRoom.Value = value;
|
||||
}
|
||||
protected Room Room => currentRoom.Value;
|
||||
|
||||
private CachedModelDependencyContainer<Room> dependencies;
|
||||
|
||||
@ -26,5 +23,11 @@ namespace osu.Game.Tests.Visual
|
||||
dependencies.Model.BindTo(currentRoom);
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
currentRoom.Value = new Room();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.RealtimeMultiplayer;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Screens.Multi.RealtimeMultiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.RealtimeMultiplayer
|
||||
{
|
||||
public abstract class RealtimeMultiplayerTestScene : MultiplayerTestScene
|
||||
{
|
||||
[Cached(typeof(StatefulMultiplayerClient))]
|
||||
public TestRealtimeMultiplayerClient Client { get; }
|
||||
|
||||
[Cached(typeof(RealtimeRoomManager))]
|
||||
public TestRealtimeRoomManager RoomManager { get; }
|
||||
|
||||
[Cached]
|
||||
public Bindable<FilterCriteria> Filter { get; }
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly TestRealtimeRoomContainer content;
|
||||
|
||||
private readonly bool joinRoom;
|
||||
|
||||
protected RealtimeMultiplayerTestScene(bool joinRoom = true)
|
||||
{
|
||||
this.joinRoom = joinRoom;
|
||||
base.Content.Add(content = new TestRealtimeRoomContainer { RelativeSizeAxes = Axes.Both });
|
||||
|
||||
Client = content.Client;
|
||||
RoomManager = content.RoomManager;
|
||||
Filter = content.Filter;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public new void Setup() => Schedule(() =>
|
||||
{
|
||||
RoomManager.Schedule(() => RoomManager.PartRoom());
|
||||
|
||||
if (joinRoom)
|
||||
RoomManager.Schedule(() => RoomManager.CreateRoom(Room));
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
// 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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.RealtimeMultiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.RealtimeMultiplayer
|
||||
{
|
||||
public class TestRealtimeMultiplayerClient : StatefulMultiplayerClient
|
||||
{
|
||||
public override IBindable<bool> IsConnected => isConnected;
|
||||
private readonly Bindable<bool> isConnected = new Bindable<bool>(true);
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
public void Connect() => isConnected.Value = true;
|
||||
|
||||
public void Disconnect() => isConnected.Value = false;
|
||||
|
||||
public void AddUser(User user) => ((IMultiplayerClient)this).UserJoined(new MultiplayerRoomUser(user.Id) { User = user });
|
||||
|
||||
public void RemoveUser(User user)
|
||||
{
|
||||
Debug.Assert(Room != null);
|
||||
((IMultiplayerClient)this).UserLeft(Room.Users.Single(u => u.User == user));
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
if (Room.Users.Any())
|
||||
TransferHost(Room.Users.First().UserID);
|
||||
});
|
||||
}
|
||||
|
||||
public void ChangeUserState(int userId, MultiplayerUserState newState)
|
||||
{
|
||||
Debug.Assert(Room != null);
|
||||
|
||||
((IMultiplayerClient)this).UserStateChanged(userId, newState);
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
switch (newState)
|
||||
{
|
||||
case MultiplayerUserState.Loaded:
|
||||
if (Room.Users.All(u => u.State != MultiplayerUserState.WaitingForLoad))
|
||||
{
|
||||
foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.Loaded))
|
||||
ChangeUserState(u.UserID, MultiplayerUserState.Playing);
|
||||
|
||||
((IMultiplayerClient)this).MatchStarted();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MultiplayerUserState.FinishedPlay:
|
||||
if (Room.Users.All(u => u.State != MultiplayerUserState.Playing))
|
||||
{
|
||||
foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.FinishedPlay))
|
||||
ChangeUserState(u.UserID, MultiplayerUserState.Results);
|
||||
|
||||
((IMultiplayerClient)this).ResultsReady();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override Task<MultiplayerRoom> JoinRoom(long roomId)
|
||||
{
|
||||
var user = new MultiplayerRoomUser(api.LocalUser.Value.Id) { User = api.LocalUser.Value };
|
||||
|
||||
var room = new MultiplayerRoom(roomId);
|
||||
room.Users.Add(user);
|
||||
|
||||
if (room.Users.Count == 1)
|
||||
room.Host = user;
|
||||
|
||||
return Task.FromResult(room);
|
||||
}
|
||||
|
||||
public override Task TransferHost(int userId) => ((IMultiplayerClient)this).HostChanged(userId);
|
||||
|
||||
public override async Task ChangeSettings(MultiplayerRoomSettings settings)
|
||||
{
|
||||
Debug.Assert(Room != null);
|
||||
|
||||
await ((IMultiplayerClient)this).SettingsChanged(settings);
|
||||
|
||||
foreach (var user in Room.Users.Where(u => u.State == MultiplayerUserState.Ready))
|
||||
ChangeUserState(user.UserID, MultiplayerUserState.Idle);
|
||||
}
|
||||
|
||||
public override Task ChangeState(MultiplayerUserState newState)
|
||||
{
|
||||
ChangeUserState(api.LocalUser.Value.Id, newState);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task StartMatch()
|
||||
{
|
||||
Debug.Assert(Room != null);
|
||||
|
||||
foreach (var user in Room.Users.Where(u => u.State == MultiplayerUserState.Ready))
|
||||
ChangeUserState(user.UserID, MultiplayerUserState.WaitingForLoad);
|
||||
|
||||
return ((IMultiplayerClient)this).LoadRequested();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.RealtimeMultiplayer;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Screens.Multi.RealtimeMultiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.RealtimeMultiplayer
|
||||
{
|
||||
public class TestRealtimeRoomContainer : Container
|
||||
{
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container content;
|
||||
|
||||
[Cached(typeof(StatefulMultiplayerClient))]
|
||||
public readonly TestRealtimeMultiplayerClient Client;
|
||||
|
||||
[Cached(typeof(RealtimeRoomManager))]
|
||||
public readonly TestRealtimeRoomManager RoomManager;
|
||||
|
||||
[Cached]
|
||||
public readonly Bindable<FilterCriteria> Filter = new Bindable<FilterCriteria>(new FilterCriteria());
|
||||
|
||||
public TestRealtimeRoomContainer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
Client = new TestRealtimeMultiplayerClient(),
|
||||
RoomManager = new TestRealtimeRoomManager(),
|
||||
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Screens.Multi.RealtimeMultiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.RealtimeMultiplayer
|
||||
{
|
||||
public class TestRealtimeRoomManager : RealtimeRoomManager
|
||||
{
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private OsuGameBase game { get; set; }
|
||||
|
||||
[Cached]
|
||||
public readonly Bindable<FilterCriteria> Filter = new Bindable<FilterCriteria>(new FilterCriteria());
|
||||
|
||||
private readonly List<Room> rooms = new List<Room>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
int currentScoreId = 0;
|
||||
int currentRoomId = 0;
|
||||
|
||||
((DummyAPIAccess)api).HandleRequest = req =>
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case CreateRoomRequest createRoomRequest:
|
||||
var createdRoom = new APICreatedRoom();
|
||||
|
||||
createdRoom.CopyFrom(createRoomRequest.Room);
|
||||
createdRoom.RoomID.Value ??= currentRoomId++;
|
||||
|
||||
rooms.Add(createdRoom);
|
||||
createRoomRequest.TriggerSuccess(createdRoom);
|
||||
break;
|
||||
|
||||
case JoinRoomRequest joinRoomRequest:
|
||||
joinRoomRequest.TriggerSuccess();
|
||||
break;
|
||||
|
||||
case PartRoomRequest partRoomRequest:
|
||||
partRoomRequest.TriggerSuccess();
|
||||
break;
|
||||
|
||||
case GetRoomsRequest getRoomsRequest:
|
||||
var roomsWithoutParticipants = new List<Room>();
|
||||
|
||||
foreach (var r in rooms)
|
||||
{
|
||||
var newRoom = new Room();
|
||||
|
||||
newRoom.CopyFrom(r);
|
||||
newRoom.RecentParticipants.Clear();
|
||||
|
||||
roomsWithoutParticipants.Add(newRoom);
|
||||
}
|
||||
|
||||
getRoomsRequest.TriggerSuccess(roomsWithoutParticipants);
|
||||
break;
|
||||
|
||||
case GetRoomRequest getRoomRequest:
|
||||
getRoomRequest.TriggerSuccess(rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId));
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case CreateRoomScoreRequest createRoomScoreRequest:
|
||||
createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 });
|
||||
break;
|
||||
|
||||
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>()
|
||||
});
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public new void ClearRooms() => base.ClearRooms();
|
||||
|
||||
public new void Schedule(Action action) => base.Schedule(action);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user