diff --git a/osu.Game/Online/Multiplayer/IMultiplayerClient.cs b/osu.Game/Online/Multiplayer/IMultiplayerClient.cs
index b97fcc9ae7..5410fbc030 100644
--- a/osu.Game/Online/Multiplayer/IMultiplayerClient.cs
+++ b/osu.Game/Online/Multiplayer/IMultiplayerClient.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Threading.Tasks;
+using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer
{
@@ -47,6 +48,13 @@ namespace osu.Game.Online.Multiplayer
/// The new state of the user.
Task UserStateChanged(int userId, MultiplayerUserState state);
+ ///
+ /// Signals that a user in this room has their beatmap availability state changed.
+ ///
+ /// The ID of the user whose beatmap availability state has changed.
+ /// The new beatmap availability state of the user.
+ Task UserBeatmapAvailabilityChanged(int userId, BeatmapAvailability beatmapAvailability);
+
///
/// Signals that a match is to be started. This will *only* be sent to clients which are to begin loading at this point.
///
diff --git a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs
index 481e3fb1de..7fda526faf 100644
--- a/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs
+++ b/osu.Game/Online/Multiplayer/IMultiplayerRoomServer.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Threading.Tasks;
+using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer
{
@@ -40,6 +41,13 @@ namespace osu.Game.Online.Multiplayer
/// If the user is not in a room.
Task ChangeState(MultiplayerUserState newState);
+ ///
+ /// Change the user's local availability state of the beatmap set in joined room.
+ /// This will also force user state back to .
+ ///
+ /// The proposed new beatmap availability state.
+ Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
+
///
/// As the host of a room, start the match.
///
diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs
index 7cd1ef78f7..50dc8f661c 100644
--- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs
+++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs
@@ -14,6 +14,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Logging;
using osu.Game.Online.API;
+using osu.Game.Online.Rooms;
namespace osu.Game.Online.Multiplayer
{
@@ -173,6 +174,14 @@ namespace osu.Game.Online.Multiplayer
return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeState), newState);
}
+ public override Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability)
+ {
+ if (!isConnected.Value)
+ return Task.CompletedTask;
+
+ return connection.InvokeAsync(nameof(IMultiplayerServer.ChangeBeatmapAvailability), newBeatmapAvailability);
+ }
+
public override Task StartMatch()
{
if (!isConnected.Value)
diff --git a/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs b/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs
index dc80488d39..c1818de87a 100644
--- a/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs
+++ b/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs
@@ -184,6 +184,8 @@ namespace osu.Game.Online.Multiplayer
public abstract Task ChangeState(MultiplayerUserState newState);
+ public abstract Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability);
+
public abstract Task StartMatch();
Task IMultiplayerClient.RoomStateChanged(MultiplayerRoomState state)
@@ -311,6 +313,24 @@ namespace osu.Game.Online.Multiplayer
return Task.CompletedTask;
}
+ Task IMultiplayerClient.UserBeatmapAvailabilityChanged(int userId, BeatmapAvailability beatmapAvailability)
+ {
+ if (Room == null)
+ return Task.CompletedTask;
+
+ Scheduler.Add(() =>
+ {
+ if (Room == null)
+ return;
+
+ Room.Users.Single(u => u.UserID == userId).BeatmapAvailability = beatmapAvailability;
+
+ RoomUpdated?.Invoke();
+ }, false);
+
+ return Task.CompletedTask;
+ }
+
Task IMultiplayerClient.LoadRequested()
{
if (Room == null)
diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs
index 2ce5211757..c155447f8c 100644
--- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs
+++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs
@@ -10,6 +10,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Online.API;
using osu.Game.Online.Multiplayer;
+using osu.Game.Online.Rooms;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
@@ -77,6 +78,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
});
}
+ public void ChangeUserBeatmapAvailability(int userId, BeatmapAvailability newBeatmapAvailability)
+ {
+ Debug.Assert(Room != null);
+
+ ((IMultiplayerClient)this).UserBeatmapAvailabilityChanged(userId, newBeatmapAvailability);
+ ChangeUserState(userId, MultiplayerUserState.Idle);
+ }
+
protected override Task JoinRoom(long roomId)
{
var user = new MultiplayerRoomUser(api.LocalUser.Value.Id) { User = api.LocalUser.Value };
@@ -108,6 +117,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
return Task.CompletedTask;
}
+ public override Task ChangeBeatmapAvailability(BeatmapAvailability newBeatmapAvailability)
+ {
+ ChangeUserBeatmapAvailability(api.LocalUser.Value.Id, newBeatmapAvailability);
+ return Task.CompletedTask;
+ }
+
public override Task StartMatch()
{
Debug.Assert(Room != null);