mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 20:33:35 +08:00
Add better support for handling disconnection at the ranked play queue screen (#37658)
Until now the queue screen basically did nothing to let the user knowing they were disconnected from the server. Now the various components will correctly clear state and show a roughly competent "i'm trying to reconnect" state. https://github.com/user-attachments/assets/bff1b241-a6a2-445a-9ffa-b5682f2a3656 --- Can be tested using the following patch (hit `F7` to reconnect, with a 5 second delay to show the disconnected state too): ```diff diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 7064906be4..ae539aba8d 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -99,6 +99,8 @@ private async Task connect() // this will also create a new cancellation token source. await disconnect(false).ConfigureAwait(false); + await Task.Delay(5000).ConfigureAwait(false); + // this token will be valid for the scope of this connection. // if cancelled, we can be sure that a disconnect or reconnect is handled elsewhere. var cancellationToken = connectCancelSource.Token; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 703444a92f..fb467472d3 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -22,6 +22,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Input; +using osu.Framework.Input.Events; using osu.Framework.Input.Handlers; using osu.Framework.Input.Handlers.Joystick; using osu.Framework.Input.Handlers.Midi; @@ -65,6 +66,7 @@ using osu.Game.Scoring; using osu.Game.Skinning; using osu.Game.Utils; +using osuTK.Input; using RuntimeInfo = osu.Framework.RuntimeInfo; namespace osu.Game @@ -104,7 +106,7 @@ public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncPro /// </summary> private const double global_track_volume_adjust = 0.8; - public virtual bool UseDevelopmentServer => DebugUtils.IsDebugBuild; + public virtual bool UseDevelopmentServer => false; public virtual EndpointConfiguration CreateEndpoints() => UseDevelopmentServer ? new DevelopmentEndpointConfiguration() : new ProductionEndpointConfiguration(); @@ -466,6 +468,20 @@ private void addFilesWarning() } } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Key == Key.F7) + { + Logger.Log("Forcing reconnect!", level: LogLevel.Important); + + ((IStatefulUserHubClient)MultiplayerClient).ServerShuttingDown(); + ((IStatefulUserHubClient)SpectatorClient).ServerShuttingDown(); + ((IStatefulUserHubClient)metadataClient).ServerShuttingDown(); + } + + return base.OnKeyDown(e); + } + private void onTrackChanged(WorkingBeatmap beatmap, TrackChangeDirection direction) => beatmapClock.ChangeSource(beatmap.Track); protected virtual void InitialiseFonts() ```
This commit is contained in:
committed by
GitHub
Unverified
parent
3f5c113394
commit
7f385c7873
@@ -34,7 +34,13 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
set
|
||||
{
|
||||
users = value;
|
||||
if (IsLoaded)
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
foreach (var u in usersContainer)
|
||||
u.Delay(RNG.Next(0, 1000)).FadeOut(500).Expire();
|
||||
|
||||
@@ -49,7 +55,6 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
usersContainer.AddRange(avatars);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
@@ -64,6 +69,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
};
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
public partial class MovingAvatar : MatchmakingAvatar
|
||||
|
||||
@@ -24,25 +24,36 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
private const float icon_size = 34;
|
||||
|
||||
public readonly Bindable<MatchmakingPool[]> AvailablePools = new Bindable<MatchmakingPool[]>([]);
|
||||
public readonly Bindable<MatchmakingPool[]?> AvailablePools = new Bindable<MatchmakingPool[]?>([]);
|
||||
public readonly Bindable<MatchmakingPool?> SelectedPool = new Bindable<MatchmakingPool?>();
|
||||
|
||||
private FillFlowContainer<SelectorButton> poolFlow = null!;
|
||||
private LoadingSpinner loading = null!;
|
||||
|
||||
public PoolSelector()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
AutoSizeAxes = Axes.X;
|
||||
Height = SelectorButton.SIZE.Y + 10;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = poolFlow = new FillFlowContainer<SelectorButton>
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
poolFlow = new FillFlowContainer<SelectorButton>
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = SelectorButton.SIZE.Y + 10,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
},
|
||||
loading = new LoadingSpinner(withBox: true)
|
||||
{
|
||||
Size = new Vector2(50),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,6 +65,14 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
poolFlow.Clear();
|
||||
|
||||
if (pools.NewValue == null)
|
||||
{
|
||||
loading.Show();
|
||||
return;
|
||||
}
|
||||
|
||||
loading.Hide();
|
||||
|
||||
foreach (var p in pools.NewValue)
|
||||
{
|
||||
poolFlow.Add(new SelectorButton(p)
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
|
||||
private readonly IBindable<MatchmakingScreenState> currentState = new Bindable<MatchmakingScreenState>();
|
||||
|
||||
private readonly Bindable<MatchmakingPool[]> availablePools = new Bindable<MatchmakingPool[]>([]);
|
||||
private readonly Bindable<MatchmakingPool[]?> availablePools = new Bindable<MatchmakingPool[]?>();
|
||||
private readonly Bindable<MatchmakingPool?> selectedPool = new Bindable<MatchmakingPool?>();
|
||||
|
||||
private readonly MatchmakingPoolType poolType;
|
||||
@@ -99,6 +99,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
|
||||
private GridContainer mainGrid = null!;
|
||||
|
||||
private IBindable<bool> isConnected = null!;
|
||||
|
||||
public ScreenQueue(MatchmakingPoolType poolType)
|
||||
{
|
||||
this.poolType = poolType;
|
||||
@@ -339,9 +341,22 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
currentState.BindValueChanged(s => SetState(s.NewValue));
|
||||
|
||||
selectedPool.BindTo(queue.SelectedPool);
|
||||
selectedPool.BindValueChanged(onSelectedPoolChanged, true);
|
||||
selectedPool.BindValueChanged(e => refreshLobbyData());
|
||||
|
||||
isConnected = client.IsConnected.GetBoundCopy();
|
||||
isConnected.BindValueChanged(connected => Schedule(() =>
|
||||
{
|
||||
if (connected.NewValue)
|
||||
{
|
||||
populateAvailablePools().FireAndForget();
|
||||
refreshLobbyData();
|
||||
}
|
||||
else
|
||||
{
|
||||
availablePools.Value = null;
|
||||
clearLobbyData();
|
||||
}
|
||||
}), true);
|
||||
}
|
||||
|
||||
private async Task populateAvailablePools()
|
||||
@@ -367,7 +382,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
APIUser?[] users = result.GetResultSafely();
|
||||
if (!cancellation.IsCancellationRequested)
|
||||
Users = users.OfType<APIUser>().ToArray();
|
||||
cloud.Users = users.OfType<APIUser>().ToArray();
|
||||
}), cancellation.Token);
|
||||
|
||||
// Global (incremental) updates will not contain the user rating, so keep the one we already received from initial status data.
|
||||
@@ -402,15 +417,11 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
});
|
||||
}
|
||||
|
||||
private void onSelectedPoolChanged(ValueChangedEvent<MatchmakingPool?> e)
|
||||
private void refreshLobbyData()
|
||||
{
|
||||
userRating = null;
|
||||
ratingGraph.SetData([], null);
|
||||
clearLobbyData();
|
||||
|
||||
resultPanelContainer.Clear();
|
||||
resultPanelContainer.LayoutDuration = 0;
|
||||
|
||||
if (e.NewValue == null)
|
||||
if (selectedPool.Value == null)
|
||||
{
|
||||
client.MatchmakingLeaveLobby().FireAndForget();
|
||||
return;
|
||||
@@ -418,10 +429,20 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
|
||||
client.MatchmakingJoinLobbyWithParams(new MatchmakingJoinLobbyRequest
|
||||
{
|
||||
PoolId = e.NewValue.Id
|
||||
PoolId = selectedPool.Value.Id
|
||||
}).FireAndForget();
|
||||
}
|
||||
|
||||
private void clearLobbyData()
|
||||
{
|
||||
resultPanelContainer.Clear();
|
||||
resultPanelContainer.LayoutDuration = 0;
|
||||
userRating = null;
|
||||
ratingGraph.SetData([], null);
|
||||
|
||||
cloud.Users = Array.Empty<APIUser>();
|
||||
}
|
||||
|
||||
public override void OnEntering(ScreenTransitionEvent e)
|
||||
{
|
||||
base.OnEntering(e);
|
||||
@@ -470,11 +491,6 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
}
|
||||
}
|
||||
|
||||
public APIUser[] Users
|
||||
{
|
||||
set => cloud.Users = value;
|
||||
}
|
||||
|
||||
public void SetState(MatchmakingScreenState newState)
|
||||
{
|
||||
mainContent.FadeInFromZero(500, Easing.OutQuint);
|
||||
@@ -515,6 +531,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Width = 200,
|
||||
Enabled = { BindTarget = isConnected },
|
||||
SelectedPool = { BindTarget = selectedPool },
|
||||
Action = () =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user