mirror of
https://github.com/ppy/osu.git
synced 2025-03-28 10:17:19 +08:00
Merge branch 'master' into patch/11310
This commit is contained in:
commit
a1af749b4b
@ -4,8 +4,10 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -31,7 +33,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when any change occurs to the multiplayer room.
|
/// Invoked when any change occurs to the multiplayer room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action? RoomChanged;
|
public event Action? RoomUpdated;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the multiplayer server requests the current beatmap to be loaded into play.
|
/// Invoked when the multiplayer server requests the current beatmap to be loaded into play.
|
||||||
@ -108,8 +110,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
Debug.Assert(Room != null);
|
Debug.Assert(Room != null);
|
||||||
|
|
||||||
foreach (var user in Room.Users)
|
var users = getRoomUsers();
|
||||||
await PopulateUser(user);
|
|
||||||
|
await Task.WhenAll(users.Select(PopulateUser));
|
||||||
|
|
||||||
updateLocalRoomSettings(Room.Settings);
|
updateLocalRoomSettings(Room.Settings);
|
||||||
}
|
}
|
||||||
@ -123,13 +126,16 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
public virtual Task LeaveRoom()
|
public virtual Task LeaveRoom()
|
||||||
{
|
{
|
||||||
if (Room == null)
|
Scheduler.Add(() =>
|
||||||
return Task.CompletedTask;
|
{
|
||||||
|
if (Room == null)
|
||||||
|
return;
|
||||||
|
|
||||||
apiRoom = null;
|
apiRoom = null;
|
||||||
Room = null;
|
Room = null;
|
||||||
|
|
||||||
Schedule(() => RoomChanged?.Invoke());
|
RoomUpdated?.Invoke();
|
||||||
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -184,7 +190,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -208,8 +214,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -221,7 +227,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
await PopulateUser(user);
|
await PopulateUser(user);
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -232,8 +238,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
Room.Users.Add(user);
|
Room.Users.Add(user);
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Task IMultiplayerClient.UserLeft(MultiplayerRoomUser user)
|
Task IMultiplayerClient.UserLeft(MultiplayerRoomUser user)
|
||||||
@ -241,7 +247,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -249,8 +255,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Users.Remove(user);
|
Room.Users.Remove(user);
|
||||||
PlayingUsers.Remove(user.UserID);
|
PlayingUsers.Remove(user.UserID);
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -260,7 +266,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -272,8 +278,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Host = user;
|
Room.Host = user;
|
||||||
apiRoom.Host.Value = user?.User;
|
apiRoom.Host.Value = user?.User;
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -289,7 +295,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -299,8 +305,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (state != MultiplayerUserState.Playing)
|
if (state != MultiplayerUserState.Playing)
|
||||||
PlayingUsers.Remove(userId);
|
PlayingUsers.Remove(userId);
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -310,13 +316,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LoadRequested?.Invoke();
|
LoadRequested?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -326,7 +332,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -334,7 +340,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
PlayingUsers.AddRange(Room.Users.Where(u => u.State == MultiplayerUserState.Playing).Select(u => u.UserID));
|
PlayingUsers.AddRange(Room.Users.Where(u => u.State == MultiplayerUserState.Playing).Select(u => u.UserID));
|
||||||
|
|
||||||
MatchStarted?.Invoke();
|
MatchStarted?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -344,13 +350,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ResultsReady?.Invoke();
|
ResultsReady?.Invoke();
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -361,6 +367,31 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <param name="multiplayerUser">The <see cref="MultiplayerRoomUser"/> to populate.</param>
|
/// <param name="multiplayerUser">The <see cref="MultiplayerRoomUser"/> to populate.</param>
|
||||||
protected async Task PopulateUser(MultiplayerRoomUser multiplayerUser) => multiplayerUser.User ??= await userLookupCache.GetUserAsync(multiplayerUser.UserID);
|
protected async Task PopulateUser(MultiplayerRoomUser multiplayerUser) => multiplayerUser.User ??= await userLookupCache.GetUserAsync(multiplayerUser.UserID);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a copy of users currently in the joined <see cref="Room"/> in a thread-safe manner.
|
||||||
|
/// This should be used whenever accessing users from outside of an Update thread context (ie. when not calling <see cref="Drawable.Schedule"/>).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A copy of users in the current room, or null if unavailable.</returns>
|
||||||
|
private List<MultiplayerRoomUser>? getRoomUsers()
|
||||||
|
{
|
||||||
|
List<MultiplayerRoomUser>? users = null;
|
||||||
|
|
||||||
|
ManualResetEventSlim resetEvent = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
// at some point we probably want to replace all these schedule calls with Room.LockForUpdate.
|
||||||
|
// for now, as this would require quite some consideration due to the number of accesses to the room instance,
|
||||||
|
// let's just add a manual schedule for the non-scheduled usages instead.
|
||||||
|
Scheduler.Add(() =>
|
||||||
|
{
|
||||||
|
users = Room?.Users.ToList();
|
||||||
|
resetEvent.Set();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
resetEvent.Wait(100);
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the local room settings with the given <see cref="MultiplayerRoomSettings"/>.
|
/// Updates the local room settings with the given <see cref="MultiplayerRoomSettings"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -373,7 +404,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Schedule(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
@ -388,13 +419,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
// In-order for the client to not display an outdated beatmap, the playlist is forcefully cleared here.
|
// In-order for the client to not display an outdated beatmap, the playlist is forcefully cleared here.
|
||||||
apiRoom.Playlist.Clear();
|
apiRoom.Playlist.Clear();
|
||||||
|
|
||||||
RoomChanged?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
||||||
req.Success += res => updatePlaylist(settings, res);
|
req.Success += res => updatePlaylist(settings, res);
|
||||||
|
|
||||||
api.Queue(req);
|
api.Queue(req);
|
||||||
});
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlaylist(MultiplayerRoomSettings settings, APIBeatmapSet onlineSet)
|
private void updatePlaylist(MultiplayerRoomSettings settings, APIBeatmapSet onlineSet)
|
||||||
|
@ -56,11 +56,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
sampleReadyCount = audio.Samples.Get(@"SongSelect/select-difficulty");
|
sampleReadyCount = audio.Samples.Get(@"SongSelect/select-difficulty");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRoomChanged()
|
protected override void OnRoomUpdated()
|
||||||
{
|
{
|
||||||
base.OnRoomChanged();
|
base.OnRoomUpdated();
|
||||||
|
|
||||||
|
// this method is called on leaving the room, so the local user may not exist in the room any more.
|
||||||
|
localUser = Room?.Users.SingleOrDefault(u => u.User?.Id == api.LocalUser.Value.Id);
|
||||||
|
|
||||||
localUser = Room?.Users.Single(u => u.User?.Id == api.LocalUser.Value.Id);
|
|
||||||
button.Enabled.Value = Client.Room?.State == MultiplayerRoomState.Open;
|
button.Enabled.Value = Client.Room?.State == MultiplayerRoomState.Open;
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,21 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Client.RoomChanged += OnRoomChanged;
|
Client.RoomUpdated += OnRoomUpdated;
|
||||||
OnRoomChanged();
|
OnRoomUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnRoomChanged()
|
/// <summary>
|
||||||
|
/// Invoked when any change occurs to the multiplayer room.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnRoomUpdated()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
if (Client != null)
|
if (Client != null)
|
||||||
Client.RoomChanged -= OnRoomChanged;
|
Client.RoomUpdated -= OnRoomUpdated;
|
||||||
|
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
|
@ -135,9 +135,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRoomChanged()
|
protected override void OnRoomUpdated()
|
||||||
{
|
{
|
||||||
base.OnRoomChanged();
|
base.OnRoomUpdated();
|
||||||
|
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
@ -36,9 +36,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRoomChanged()
|
protected override void OnRoomUpdated()
|
||||||
{
|
{
|
||||||
base.OnRoomChanged();
|
base.OnRoomUpdated();
|
||||||
|
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
panels.Clear();
|
panels.Clear();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user