1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 09:32:55 +08:00

Fix MultiplayerMatchSubScreen erroneously pushing exit dialog on API failure

If `IAPIProvider.State` changes from `Online` at any point when being on
an `OnlinePlayScreen`, it will be forcefully exited from. However,
`MultiplayerMatchSubScreen` had local logic that suppressed the exit in
order to show a confirmation dialog.

The problem is, that in the suppression logic,
`MultiplayerMatchSubScreen` was checking
`MultiplayerClient.IsConnected`, which is a SignalR flag, and was not
checking `IAPIAccess.State`, which is maintained separately. Due to
differing timeouts and failure thresholds, it is not impossible to have
`MultiplayerClient.IsConnected == true` but `IAPIAccess.State !=
APIState.Online`.

In such a case, the match subscreen would wrongly consider itself to be
still online and due to that, push useless confirmation dialogs, while
being in the process of being forcefully exited. This then caused the
dialog to cause a crash, as it was calling `.Exit()` on the screen which
would already have been exited by that point, by the force-exit flow.
This commit is contained in:
Bartłomiej Dach 2023-07-16 19:56:22 +02:00
parent cd02a8a9ca
commit 7fbd47e9ee
No known key found for this signature in database

View File

@ -17,6 +17,7 @@ using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics.Cursor;
using osu.Game.Online;
using osu.Game.Online.API;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
@ -49,6 +50,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
[Resolved]
private MultiplayerClient client { get; set; }
[Resolved]
private IAPIProvider api { get; set; }
[Resolved(canBeNull: true)]
private OsuGame game { get; set; }
@ -251,10 +255,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
public override bool OnExiting(ScreenExitEvent e)
{
// the room may not be left immediately after a disconnection due to async flow,
// so checking the IsConnected status is also required.
if (client.Room == null || !client.IsConnected.Value)
// so checking the MultiplayerClient / IAPIAccess statuses is also required.
if (client.Room == null || !client.IsConnected.Value || api.State.Value != APIState.Online)
{
// room has not been created yet; exit immediately.
// room has not been created yet or we're offline; exit immediately.
return base.OnExiting(e);
}