mirror of
https://github.com/ppy/osu.git
synced 2025-03-10 22:17:20 +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:
commit
28be0e31c2
@ -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(() =>
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user