mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Add support for gameplay abort/force start
This commit is contained in:
@ -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(IScreen last)
|
public override void OnResuming(IScreen last)
|
||||||
{
|
{
|
||||||
base.OnResuming(last);
|
base.OnResuming(last);
|
||||||
@ -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 (!(last is MultiplayerPlayerLoader playerLoader))
|
if (!(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)
|
||||||
{
|
{
|
||||||
|
@ -133,6 +133,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
failAndBail();
|
failAndBail();
|
||||||
}
|
}
|
||||||
}), true);
|
}), true);
|
||||||
|
|
||||||
|
client.ChangeState(MultiplayerUserState.Loaded)
|
||||||
|
.ContinueWith(task => failAndBail(task.Exception?.Message ?? "Server error"), TaskContinuationOptions.NotOnRanToCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -144,10 +147,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)
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
||||||
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 +13,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 +23,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ReadyForGameplay =>
|
||||||
|
base.ReadyForGameplay
|
||||||
|
// The server is forcefully starting gameplay.
|
||||||
|
|| multiplayerClient.LocalUser?.State == MultiplayerUserState.Playing;
|
||||||
|
|
||||||
public override void OnSuspending(IScreen next)
|
public override void OnSuspending(IScreen next)
|
||||||
{
|
{
|
||||||
base.OnSuspending(next);
|
base.OnSuspending(next);
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user