mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 23:53:51 +09:00
Merge pull request #17933 from smoogipoo/multiplayer-force-start-2
Force start/abort multiplayer games after a timeout
This commit is contained in:
@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
|
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
|
||||||
AddStep("start gameplay", () => ((IMultiplayerClient)MultiplayerClient).MatchStarted());
|
AddStep("start gameplay", () => ((IMultiplayerClient)MultiplayerClient).GameplayStarted());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
17
osu.Game/Online/Multiplayer/ForceGameplayStartCountdown.cs
Normal file
17
osu.Game/Online/Multiplayer/ForceGameplayStartCountdown.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using MessagePack;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Multiplayer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="MultiplayerCountdown"/> started by the server when clients being to load.
|
||||||
|
/// Indicates how long until gameplay will forcefully start, excluding any users which have not completed loading,
|
||||||
|
/// and forcing progression of any clients that are blocking load due to user interaction.
|
||||||
|
/// </summary>
|
||||||
|
[MessagePackObject]
|
||||||
|
public class ForceGameplayStartCountdown : MultiplayerCountdown
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -93,14 +93,20 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Task UserModsChanged(int userId, IEnumerable<APIMod> mods);
|
Task UserModsChanged(int userId, IEnumerable<APIMod> mods);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that a match is to be started. This will *only* be sent to clients which are to begin loading at this point.
|
/// Signals that the match is starting and the loading of gameplay should be started. This will *only* be sent to clients which are to begin loading at this point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task LoadRequested();
|
Task LoadRequested();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that a match has started. All users in the <see cref="MultiplayerUserState.Loaded"/> state should begin gameplay as soon as possible.
|
/// Signals that loading of gameplay is to be aborted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task MatchStarted();
|
Task LoadAborted();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals that gameplay has started.
|
||||||
|
/// All users in the <see cref="MultiplayerUserState.Loaded"/> or <see cref="MultiplayerUserState.ReadyForGameplay"/> states should begin gameplay as soon as possible.
|
||||||
|
/// </summary>
|
||||||
|
Task GameplayStarted();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that the match has ended, all players have finished and results are ready to be displayed.
|
/// Signals that the match has ended, all players have finished and results are ready to be displayed.
|
||||||
|
@ -69,10 +69,15 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual event Action? LoadRequested;
|
public virtual event Action? LoadRequested;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when the multiplayer server requests loading of play to be aborted.
|
||||||
|
/// </summary>
|
||||||
|
public event Action? LoadAborted;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the multiplayer server requests gameplay to be started.
|
/// Invoked when the multiplayer server requests gameplay to be started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action? MatchStarted;
|
public event Action? GameplayStarted;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the multiplayer server has finished collating results.
|
/// Invoked when the multiplayer server has finished collating results.
|
||||||
@ -604,14 +609,27 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task IMultiplayerClient.MatchStarted()
|
Task IMultiplayerClient.LoadAborted()
|
||||||
{
|
{
|
||||||
Scheduler.Add(() =>
|
Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (Room == null)
|
if (Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MatchStarted?.Invoke();
|
LoadAborted?.Invoke();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task IMultiplayerClient.GameplayStarted()
|
||||||
|
{
|
||||||
|
Scheduler.Add(() =>
|
||||||
|
{
|
||||||
|
if (Room == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GameplayStarted?.Invoke();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
@ -14,6 +14,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
[Union(0, typeof(MatchStartCountdown))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
|
[Union(0, typeof(MatchStartCountdown))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
|
||||||
|
[Union(1, typeof(ForceGameplayStartCountdown))]
|
||||||
public abstract class MultiplayerCountdown
|
public abstract class MultiplayerCountdown
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -65,5 +65,21 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => UserID.GetHashCode();
|
public override int GetHashCode() => UserID.GetHashCode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this user has finished loading and can start gameplay.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanStartGameplay()
|
||||||
|
{
|
||||||
|
switch (State)
|
||||||
|
{
|
||||||
|
case MultiplayerUserState.Loaded:
|
||||||
|
case MultiplayerUserState.ReadyForGameplay:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,16 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
WaitingForLoad,
|
WaitingForLoad,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user's client has marked itself as loaded and ready to begin gameplay.
|
/// The user has marked itself as loaded, but may still be adjusting settings prior to being ready for gameplay.
|
||||||
|
/// Players remaining in this state for an extended period of time will be automatically transitioned to the <see cref="Playing"/> state by the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Loaded,
|
Loaded,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user has finished adjusting settings and is ready to start gameplay.
|
||||||
|
/// </summary>
|
||||||
|
ReadyForGameplay,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user is currently playing in a game. This is a reserved state, and is set by the server.
|
/// The user is currently playing in a game. This is a reserved state, and is set by the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -54,7 +54,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
connection.On<MultiplayerRoomSettings>(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged);
|
connection.On<MultiplayerRoomSettings>(nameof(IMultiplayerClient.SettingsChanged), ((IMultiplayerClient)this).SettingsChanged);
|
||||||
connection.On<int, MultiplayerUserState>(nameof(IMultiplayerClient.UserStateChanged), ((IMultiplayerClient)this).UserStateChanged);
|
connection.On<int, MultiplayerUserState>(nameof(IMultiplayerClient.UserStateChanged), ((IMultiplayerClient)this).UserStateChanged);
|
||||||
connection.On(nameof(IMultiplayerClient.LoadRequested), ((IMultiplayerClient)this).LoadRequested);
|
connection.On(nameof(IMultiplayerClient.LoadRequested), ((IMultiplayerClient)this).LoadRequested);
|
||||||
connection.On(nameof(IMultiplayerClient.MatchStarted), ((IMultiplayerClient)this).MatchStarted);
|
connection.On(nameof(IMultiplayerClient.GameplayStarted), ((IMultiplayerClient)this).GameplayStarted);
|
||||||
|
connection.On(nameof(IMultiplayerClient.LoadAborted), ((IMultiplayerClient)this).LoadAborted);
|
||||||
connection.On(nameof(IMultiplayerClient.ResultsReady), ((IMultiplayerClient)this).ResultsReady);
|
connection.On(nameof(IMultiplayerClient.ResultsReady), ((IMultiplayerClient)this).ResultsReady);
|
||||||
connection.On<int, IEnumerable<APIMod>>(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged);
|
connection.On<int, IEnumerable<APIMod>>(nameof(IMultiplayerClient.UserModsChanged), ((IMultiplayerClient)this).UserModsChanged);
|
||||||
connection.On<int, BeatmapAvailability>(nameof(IMultiplayerClient.UserBeatmapAvailabilityChanged), ((IMultiplayerClient)this).UserBeatmapAvailabilityChanged);
|
connection.On<int, BeatmapAvailability>(nameof(IMultiplayerClient.UserBeatmapAvailabilityChanged), ((IMultiplayerClient)this).UserBeatmapAvailabilityChanged);
|
||||||
|
@ -24,7 +24,8 @@ namespace osu.Game.Online
|
|||||||
(typeof(CountdownChangedEvent), typeof(MatchServerEvent)),
|
(typeof(CountdownChangedEvent), typeof(MatchServerEvent)),
|
||||||
(typeof(TeamVersusRoomState), typeof(MatchRoomState)),
|
(typeof(TeamVersusRoomState), typeof(MatchRoomState)),
|
||||||
(typeof(TeamVersusUserState), typeof(MatchUserState)),
|
(typeof(TeamVersusUserState), typeof(MatchUserState)),
|
||||||
(typeof(MatchStartCountdown), typeof(MultiplayerCountdown))
|
(typeof(MatchStartCountdown), typeof(MultiplayerCountdown)),
|
||||||
|
(typeof(ForceGameplayStartCountdown), typeof(MultiplayerCountdown))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
|
|
||||||
private void onRoomUpdated() => Scheduler.AddOnce(() =>
|
private void onRoomUpdated() => Scheduler.AddOnce(() =>
|
||||||
{
|
{
|
||||||
bool countdownActive = multiplayerClient.Room?.Countdown != null;
|
bool countdownActive = multiplayerClient.Room?.Countdown is MatchStartCountdown;
|
||||||
|
|
||||||
if (countdownActive)
|
if (countdownActive)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,21 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
|
|
||||||
private void onRoomUpdated() => Scheduler.AddOnce(() =>
|
private void onRoomUpdated() => Scheduler.AddOnce(() =>
|
||||||
{
|
{
|
||||||
if (countdown != room?.Countdown)
|
MultiplayerCountdown newCountdown;
|
||||||
|
|
||||||
|
switch (room?.Countdown)
|
||||||
|
{
|
||||||
|
case MatchStartCountdown _:
|
||||||
|
newCountdown = room.Countdown;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Clear the countdown with any other (including non-null) countdown values.
|
||||||
|
default:
|
||||||
|
newCountdown = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newCountdown != countdown)
|
||||||
{
|
{
|
||||||
countdown = room?.Countdown;
|
countdown = room?.Countdown;
|
||||||
countdownChangeTime = Time.Current;
|
countdownChangeTime = Time.Current;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
@ -20,6 +21,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
client.RoomUpdated += onRoomUpdated;
|
client.RoomUpdated += onRoomUpdated;
|
||||||
|
client.LoadAborted += onLoadAborted;
|
||||||
onRoomUpdated();
|
onRoomUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +37,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
transitionFromResults();
|
transitionFromResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onLoadAborted()
|
||||||
|
{
|
||||||
|
// If the server aborts gameplay for this user (due to loading too slow), exit gameplay screens.
|
||||||
|
if (!this.IsCurrentScreen())
|
||||||
|
{
|
||||||
|
Logger.Log("Gameplay aborted because loading the beatmap took too long.", LoggingTarget.Runtime, LogLevel.Important);
|
||||||
|
this.MakeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnResuming(ScreenTransitionEvent e)
|
public override void OnResuming(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
base.OnResuming(e);
|
base.OnResuming(e);
|
||||||
@ -42,9 +54,15 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
if (client.Room == null)
|
if (client.Room == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Debug.Assert(client.LocalUser != null);
|
||||||
|
|
||||||
if (!(e.Last is MultiplayerPlayerLoader playerLoader))
|
if (!(e.Last is MultiplayerPlayerLoader playerLoader))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Nothing needs to be done if already in the idle state (e.g. via load being aborted by the server).
|
||||||
|
if (client.LocalUser.State == MultiplayerUserState.Idle)
|
||||||
|
return;
|
||||||
|
|
||||||
// If gameplay wasn't finished, then we have a simple path back to the idle state by aborting gameplay.
|
// If gameplay wasn't finished, then we have a simple path back to the idle state by aborting gameplay.
|
||||||
if (!playerLoader.GameplayPassed)
|
if (!playerLoader.GameplayPassed)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
if (!ValidForResume)
|
if (!ValidForResume)
|
||||||
return; // token retrieval may have failed.
|
return; // token retrieval may have failed.
|
||||||
|
|
||||||
client.MatchStarted += onMatchStarted;
|
client.GameplayStarted += onGameplayStarted;
|
||||||
client.ResultsReady += onResultsReady;
|
client.ResultsReady += onResultsReady;
|
||||||
|
|
||||||
ScoreProcessor.HasCompleted.BindValueChanged(completed =>
|
ScoreProcessor.HasCompleted.BindValueChanged(completed =>
|
||||||
@ -144,10 +144,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
protected override void StartGameplay()
|
protected override void StartGameplay()
|
||||||
{
|
{
|
||||||
// block base call, but let the server know we are ready to start.
|
if (client.LocalUser?.State == MultiplayerUserState.Loaded)
|
||||||
loadingDisplay.Show();
|
{
|
||||||
|
// block base call, but let the server know we are ready to start.
|
||||||
client.ChangeState(MultiplayerUserState.Loaded).ContinueWith(task => failAndBail(task.Exception?.Message ?? "Server error"), TaskContinuationOptions.NotOnRanToCompletion);
|
loadingDisplay.Show();
|
||||||
|
client.ChangeState(MultiplayerUserState.ReadyForGameplay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void failAndBail(string message = null)
|
private void failAndBail(string message = null)
|
||||||
@ -175,7 +177,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
leaderboardFlow.Position = new Vector2(padding, padding + HUDOverlay.TopScoringElementsHeight);
|
leaderboardFlow.Position = new Vector2(padding, padding + HUDOverlay.TopScoringElementsHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onMatchStarted() => Scheduler.Add(() =>
|
private void onGameplayStarted() => Scheduler.Add(() =>
|
||||||
{
|
{
|
||||||
if (!this.IsCurrentScreen())
|
if (!this.IsCurrentScreen())
|
||||||
return;
|
return;
|
||||||
@ -223,7 +225,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
client.MatchStarted -= onMatchStarted;
|
client.GameplayStarted -= onGameplayStarted;
|
||||||
client.ResultsReady -= onResultsReady;
|
client.ResultsReady -= onResultsReady;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||||
@ -11,6 +15,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
public bool GameplayPassed => player?.GameplayState.HasPassed == true;
|
public bool GameplayPassed => player?.GameplayState.HasPassed == true;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private MultiplayerClient multiplayerClient { get; set; }
|
||||||
|
|
||||||
private Player player;
|
private Player player;
|
||||||
|
|
||||||
public MultiplayerPlayerLoader(Func<Player> createPlayer)
|
public MultiplayerPlayerLoader(Func<Player> createPlayer)
|
||||||
@ -18,6 +25,31 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ReadyForGameplay =>
|
||||||
|
base.ReadyForGameplay
|
||||||
|
// The server is forcefully starting gameplay.
|
||||||
|
|| multiplayerClient.LocalUser?.State == MultiplayerUserState.Playing;
|
||||||
|
|
||||||
|
protected override void OnPlayerLoaded()
|
||||||
|
{
|
||||||
|
base.OnPlayerLoaded();
|
||||||
|
|
||||||
|
multiplayerClient.ChangeState(MultiplayerUserState.Loaded)
|
||||||
|
.ContinueWith(task => failAndBail(task.Exception?.Message ?? "Server error"), TaskContinuationOptions.NotOnRanToCompletion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failAndBail(string message = null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(message))
|
||||||
|
Logger.Log(message, LoggingTarget.Runtime, LogLevel.Important);
|
||||||
|
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
if (this.IsCurrentScreen())
|
||||||
|
this.Exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnSuspending(ScreenTransitionEvent e)
|
public override void OnSuspending(ScreenTransitionEvent e)
|
||||||
{
|
{
|
||||||
base.OnSuspending(e);
|
base.OnSuspending(e);
|
||||||
|
@ -112,6 +112,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MultiplayerUserState.Loaded:
|
case MultiplayerUserState.Loaded:
|
||||||
|
case MultiplayerUserState.ReadyForGameplay:
|
||||||
text.Text = "loaded";
|
text.Text = "loaded";
|
||||||
icon.Icon = FontAwesome.Solid.DotCircle;
|
icon.Icon = FontAwesome.Solid.DotCircle;
|
||||||
icon.Colour = colours.YellowLight;
|
icon.Colour = colours.YellowLight;
|
||||||
|
@ -92,11 +92,15 @@ namespace osu.Game.Screens.Play
|
|||||||
!playerConsumed
|
!playerConsumed
|
||||||
// don't push unless the player is completely loaded
|
// don't push unless the player is completely loaded
|
||||||
&& CurrentPlayer?.LoadState == LoadState.Ready
|
&& CurrentPlayer?.LoadState == LoadState.Ready
|
||||||
// don't push if the user is hovering one of the panes, unless they are idle.
|
// don't push unless the player is ready to start gameplay
|
||||||
&& (IsHovered || idleTracker.IsIdle.Value)
|
&& ReadyForGameplay;
|
||||||
// don't push if the user is dragging a slider or otherwise.
|
|
||||||
|
protected virtual bool ReadyForGameplay =>
|
||||||
|
// not ready if the user is hovering one of the panes, unless they are idle.
|
||||||
|
(IsHovered || idleTracker.IsIdle.Value)
|
||||||
|
// not ready if the user is dragging a slider or otherwise.
|
||||||
&& inputManager.DraggedDrawable == null
|
&& inputManager.DraggedDrawable == null
|
||||||
// don't push if a focused overlay is visible, like settings.
|
// not ready if a focused overlay is visible, like settings.
|
||||||
&& inputManager.FocusedDrawable == null;
|
&& inputManager.FocusedDrawable == null;
|
||||||
|
|
||||||
private readonly Func<Player> createPlayer;
|
private readonly Func<Player> createPlayer;
|
||||||
@ -364,7 +368,15 @@ namespace osu.Game.Screens.Play
|
|||||||
CurrentPlayer.RestartCount = restartCount++;
|
CurrentPlayer.RestartCount = restartCount++;
|
||||||
CurrentPlayer.RestartRequested = restartRequested;
|
CurrentPlayer.RestartRequested = restartRequested;
|
||||||
|
|
||||||
LoadTask = LoadComponentAsync(CurrentPlayer, _ => MetadataInfo.Loading = false);
|
LoadTask = LoadComponentAsync(CurrentPlayer, _ =>
|
||||||
|
{
|
||||||
|
MetadataInfo.Loading = false;
|
||||||
|
OnPlayerLoaded();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPlayerLoaded()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartRequested()
|
private void restartRequested()
|
||||||
|
@ -155,7 +155,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.Loaded))
|
foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.Loaded))
|
||||||
ChangeUserState(u.UserID, MultiplayerUserState.Playing);
|
ChangeUserState(u.UserID, MultiplayerUserState.Playing);
|
||||||
|
|
||||||
((IMultiplayerClient)this).MatchStarted();
|
((IMultiplayerClient)this).GameplayStarted();
|
||||||
|
|
||||||
ChangeRoomState(MultiplayerRoomState.Playing);
|
ChangeRoomState(MultiplayerRoomState.Playing);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user