ppy / osu

rhythm is just a *click* away!
https://osu.ppy.sh
MIT License
15.38k stars 2.29k forks source link

ParticipantsPanel null reference #11302

Closed peppy closed 3 years ago

peppy commented 3 years ago
2020-12-25 06:31:19 [error]: An unhandled error has occurred.
2020-12-25 06:31:19 [error]: System.NullReferenceException: Object reference not set to an instance of an object.
2020-12-25 06:31:19 [error]: at osu.Game.Screens.Multi.RealtimeMultiplayer.Participants.ParticipantPanel.load()
2020-12-25 06:31:19 [error]: --- End of stack trace from previous location where exception was thrown ---
2020-12-25 06:31:19 [error]: at osu.Framework.Allocation.BackgroundDependencyLoaderAttribute.<>c__DisplayClass6_0.<CreateActivator>b__4(Object target, IReadOnlyDependencyContainer dc)
2020-12-25 06:31:19 [error]: at osu.Framework.Allocation.DependencyActivator.activate(Object obj, IReadOnlyDependencyContainer dependencies)
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Drawable.load(IFrameBasedClock clock, IReadOnlyDependencyContainer dependencies)
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Drawable.Load(IFrameBasedClock clock, IReadOnlyDependencyContainer dependencies, Boolean isDirectAsyncContext)
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.loadChild(Drawable child)
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.AddInternal(Drawable drawable)
2020-12-25 06:31:19 [error]: at osu.Game.Screens.Multi.RealtimeMultiplayer.Participants.ParticipantsList.OnRoomChanged()
2020-12-25 06:31:19 [error]: at osu.Game.Online.RealtimeMultiplayer.StatefulMultiplayerClient.<>c__DisplayClass43_0.<osu.Game.Online.RealtimeMultiplayer.IMultiplayerClient.UserJoined>b__0()
2020-12-25 06:31:19 [error]: at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
2020-12-25 06:31:19 [error]: at osu.Framework.Threading.Scheduler.Update()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Drawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree()
2020-12-25 06:31:19 [error]: at osu.Framework.Platform.GameHost.UpdateFrame()
2020-12-25 06:31:19 [error]: at osu.Framework.Threading.GameThread.ProcessFrame()

Reproduced while sitting in a room as they played.

frenzibyte commented 3 years ago

Taking #11304 as an example, it appears that someone has joined the room with nonexistent/no-longer-existing user ID, causing everyone's clients inside that room to crash due to thinking that the ID exists then fetching it and using it without checks.

request for User by the nonexistent user ID, probably came from the await PopulateUser(user) call inside UserJoined:

2020-12-25 07:48:20 [verbose]: Performing request osu.Game.Online.API.Requests.GetUsersRequest
2020-12-25 07:48:20 [verbose]: Request to https://osu.ppy.sh/api/v2/users/?ids[]=12814551 successfully completed!

leading to ParticipantPanel using the null result User after being set to MultiplayerRoomUser:

2020-12-25 07:48:20 [verbose]: Unhandled exception has been allowed with 0 more allowable exceptions .
2020-12-25 07:48:20 [error]: An unhandled error has occurred.
2020-12-25 07:48:20 [error]: System.NullReferenceException: Object reference not set to an instance of an object.
2020-12-25 07:48:20 [error]: at osu.Game.Screens.Multi.RealtimeMultiplayer.Participants.ParticipantPanel.load()
2020-12-25 07:48:20 [error]: --- End of stack trace from previous location where exception was thrown ---
2020-12-25 07:48:20 [error]: at osu.Framework.Allocation.BackgroundDependencyLoaderAttribute.<>c__DisplayClass6_0.<CreateActivator>b__4(Object target, IReadOnlyDependencyContainer dc)
2020-12-25 07:48:20 [error]: at osu.Framework.Allocation.DependencyActivator.activate(Object obj, IReadOnlyDependencyContainer dependencies)
...

It's unlikely that the user really joined with a nonexistent ID, maybe it got deleted during the join request. Client should probably check for null Users and not attempt to add them, or handle that server-side from the database or otherwise.

peppy commented 3 years ago

This was a restricted user. Needs to be handled server side (disallow outwards propagating events) and client side (fallback to showing an "unknown user" card or similar).

frenzibyte commented 3 years ago

Will do the client-side handling.