1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-10 21:40:34 +08:00

Merge pull request #32214 from smoogipoo/fix-multi-user-kick-threading

Fix thread safety when kicking multiplayer users
This commit is contained in:
Bartłomiej Dach 2025-03-04 09:24:08 +01:00 committed by GitHub
commit 28be0e31c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 34 deletions

View File

@ -487,18 +487,44 @@ namespace osu.Game.Online.Multiplayer
}, false);
}
Task IMultiplayerClient.UserLeft(MultiplayerRoomUser user) =>
handleUserLeft(user, UserLeft);
Task IMultiplayerClient.UserLeft(MultiplayerRoomUser user)
{
Scheduler.Add(() => handleUserLeft(user, UserLeft), false);
return Task.CompletedTask;
}
Task IMultiplayerClient.UserKicked(MultiplayerRoomUser user)
{
if (LocalUser == null)
return Task.CompletedTask;
Scheduler.Add(() =>
{
if (LocalUser == null)
return;
if (user.Equals(LocalUser))
LeaveRoom();
if (user.Equals(LocalUser))
LeaveRoom();
return handleUserLeft(user, UserKicked);
handleUserLeft(user, UserKicked);
}, false);
return Task.CompletedTask;
}
private void handleUserLeft(MultiplayerRoomUser user, Action<MultiplayerRoomUser>? callback)
{
Debug.Assert(ThreadSafety.IsUpdateThread);
if (Room == null)
return;
Room.Users.Remove(user);
PlayingUserIds.Remove(user.UserID);
Debug.Assert(APIRoom != null);
APIRoom.RecentParticipants = APIRoom.RecentParticipants.Where(u => u.Id != user.UserID).ToArray();
APIRoom.ParticipantCount--;
callback?.Invoke(user);
RoomUpdated?.Invoke();
}
async Task IMultiplayerClient.Invited(int invitedBy, long roomID, string password)
@ -545,27 +571,6 @@ namespace osu.Game.Online.Multiplayer
APIRoom.ParticipantCount++;
}
private Task handleUserLeft(MultiplayerRoomUser user, Action<MultiplayerRoomUser>? callback)
{
Scheduler.Add(() =>
{
if (Room == null)
return;
Room.Users.Remove(user);
PlayingUserIds.Remove(user.UserID);
Debug.Assert(APIRoom != null);
APIRoom.RecentParticipants = APIRoom.RecentParticipants.Where(u => u.Id != user.UserID).ToArray();
APIRoom.ParticipantCount--;
callback?.Invoke(user);
RoomUpdated?.Invoke();
}, false);
return Task.CompletedTask;
}
Task IMultiplayerClient.HostChanged(int userId)
{
Scheduler.Add(() =>

View File

@ -28,11 +28,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
private void onRoomUpdated()
{
if (client.Room == null)
if (client.Room == null || client.LocalUser == null)
return;
Debug.Assert(client.LocalUser != null);
// If the user exits gameplay before score submission completes, we'll transition to idle when results has been prepared.
if (client.LocalUser.State == MultiplayerUserState.Results && this.IsCurrentScreen())
transitionFromResults();
@ -62,11 +60,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
base.OnResuming(e);
if (client.Room == null)
if (client.Room == null || client.LocalUser == null)
return;
Debug.Assert(client.LocalUser != null);
if (!(e.Last is MultiplayerPlayerLoader playerLoader))
return;