1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 21:52:55 +08:00

Merge pull request #24071 from peppy/availability-fixes

Add handling of "unknown" beatmap availability in multiplayer flow
This commit is contained in:
Bartłomiej Dach 2023-07-02 21:32:40 +02:00 committed by GitHub
commit f6939223b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 10 deletions

View File

@ -107,6 +107,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test] [Test]
public void TestBeatmapDownloadingStates() public void TestBeatmapDownloadingStates()
{ {
AddStep("set to unknown", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.Unknown()));
AddStep("set to no map", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.NotDownloaded())); AddStep("set to no map", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.NotDownloaded()));
AddStep("set to downloading map", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.Downloading(0))); AddStep("set to downloading map", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.Downloading(0)));
@ -382,6 +383,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
}); });
AddUntilStep("wait for list to load", () => participantsList?.IsLoaded == true); AddUntilStep("wait for list to load", () => participantsList?.IsLoaded == true);
AddStep("set beatmap available", () => MultiplayerClient.ChangeBeatmapAvailability(BeatmapAvailability.LocallyAvailable()));
} }
private void checkProgressBarVisibility(bool visible) => private void checkProgressBarVisibility(bool visible) =>

View File

@ -29,7 +29,7 @@ namespace osu.Game.Online.Multiplayer
/// The availability state of the current beatmap. /// The availability state of the current beatmap.
/// </summary> /// </summary>
[Key(2)] [Key(2)]
public BeatmapAvailability BeatmapAvailability { get; set; } = BeatmapAvailability.LocallyAvailable(); public BeatmapAvailability BeatmapAvailability { get; set; } = BeatmapAvailability.Unknown();
/// <summary> /// <summary>
/// Any mods applicable only to the local user. /// Any mods applicable only to the local user.

View File

@ -34,6 +34,7 @@ namespace osu.Game.Online.Rooms
DownloadProgress = downloadProgress; DownloadProgress = downloadProgress;
} }
public static BeatmapAvailability Unknown() => new BeatmapAvailability(DownloadState.Unknown);
public static BeatmapAvailability NotDownloaded() => new BeatmapAvailability(DownloadState.NotDownloaded); public static BeatmapAvailability NotDownloaded() => new BeatmapAvailability(DownloadState.NotDownloaded);
public static BeatmapAvailability Downloading(float progress) => new BeatmapAvailability(DownloadState.Downloading, progress); public static BeatmapAvailability Downloading(float progress) => new BeatmapAvailability(DownloadState.Downloading, progress);
public static BeatmapAvailability Importing() => new BeatmapAvailability(DownloadState.Importing); public static BeatmapAvailability Importing() => new BeatmapAvailability(DownloadState.Importing);

View File

@ -60,6 +60,15 @@ namespace osu.Game.Online.Rooms
if (item.NewValue == null) if (item.NewValue == null)
return; return;
// Initially set to unknown until we have attained a good state.
// This has the wanted side effect of forcing a state change when the current playlist
// item changes at the server but our local availability doesn't necessarily change
// (ie. we have both the previous and next item LocallyAvailable).
//
// Note that even without this, the server will trigger a state change and things will work.
// This is just for safety.
availability.Value = BeatmapAvailability.Unknown();
downloadTracker?.RemoveAndDisposeImmediately(); downloadTracker?.RemoveAndDisposeImmediately();
selectedBeatmap = null; selectedBeatmap = null;
@ -115,6 +124,9 @@ namespace osu.Game.Online.Rooms
switch (downloadTracker.State.Value) switch (downloadTracker.State.Value)
{ {
case DownloadState.Unknown: case DownloadState.Unknown:
availability.Value = BeatmapAvailability.Unknown();
break;
case DownloadState.NotDownloaded: case DownloadState.NotDownloaded:
availability.Value = BeatmapAvailability.NotDownloaded(); availability.Value = BeatmapAvailability.NotDownloaded();
break; break;

View File

@ -313,16 +313,26 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
client.ChangeBeatmapAvailability(availability.NewValue).FireAndForget(); client.ChangeBeatmapAvailability(availability.NewValue).FireAndForget();
if (availability.NewValue.State != DownloadState.LocallyAvailable) switch (availability.NewValue.State)
{ {
// while this flow is handled server-side, this covers the edge case of the local user being in a ready state and then deleting the current beatmap. case DownloadState.LocallyAvailable:
if (client.LocalUser?.State == MultiplayerUserState.Ready) if (client.LocalUser?.State == MultiplayerUserState.Spectating
client.ChangeState(MultiplayerUserState.Idle); && (client.Room?.State == MultiplayerRoomState.WaitingForLoad || client.Room?.State == MultiplayerRoomState.Playing))
} {
else if (client.LocalUser?.State == MultiplayerUserState.Spectating onLoadRequested();
&& (client.Room?.State == MultiplayerRoomState.WaitingForLoad || client.Room?.State == MultiplayerRoomState.Playing)) }
{
onLoadRequested(); break;
case DownloadState.Unknown:
// Don't do anything rash in an unknown state.
break;
default:
// while this flow is handled server-side, this covers the edge case of the local user being in a ready state and then deleting the current beatmap.
if (client.LocalUser?.State == MultiplayerUserState.Ready)
client.ChangeState(MultiplayerUserState.Idle);
break;
} }
} }

View File

@ -154,6 +154,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
this.FadeOut(fade_time); this.FadeOut(fade_time);
break; break;
case DownloadState.Unknown:
text.Text = "checking availability";
icon.Icon = FontAwesome.Solid.Question;
icon.Colour = colours.Orange0;
break;
case DownloadState.NotDownloaded: case DownloadState.NotDownloaded:
text.Text = "no map"; text.Text = "no map";
icon.Icon = FontAwesome.Solid.MinusCircle; icon.Icon = FontAwesome.Solid.MinusCircle;