add server state

This commit is contained in:
Mister_Nebula 2021-08-08 19:59:40 +01:00
parent 31f7557ba7
commit 11c167dd6a
8 changed files with 189 additions and 0 deletions

View File

@ -0,0 +1,30 @@
using QSB.Events;
using QSB.Messaging;
namespace QSB.ClientServerStateSync.Events
{
internal class ServerStateEvent : QSBEvent<EnumMessage<ServerState>>
{
public override EventType Type => EventType.ServerState;
public override void SetupListener()
=> GlobalMessenger<ServerState>.AddListener(EventNames.QSBServerState, Handler);
public override void CloseListener()
=> GlobalMessenger<ServerState>.RemoveListener(EventNames.QSBServerState, Handler);
private void Handler(ServerState state) => SendEvent(CreateMessage(state));
private EnumMessage<ServerState> CreateMessage(ServerState state) => new EnumMessage<ServerState>
{
AboutId = LocalPlayerId,
EnumValue = state
};
public override void OnReceiveLocal(bool server, EnumMessage<ServerState> message)
=> OnReceiveRemote(server, message);
public override void OnReceiveRemote(bool server, EnumMessage<ServerState> message)
=> ServerStateManager.Instance.ChangeServerState(message.EnumValue);
}
}

View File

@ -0,0 +1,26 @@
namespace QSB.ClientServerStateSync
{
public enum ServerState
{
// When in menus
NotLoaded,
// When in any credits
Credits,
// For normal play in SolarSystem
InSolarSystem,
// For normal play in EyeOfTheUniverse
InEye,
// At end of loop, waiting for everyone to be ready to reload the scene
WaitingForDeath,
// At start of loop, waiting for everybody to be ready to start playing
AwaitingPlayConfirmation,
// When the statue has been activated
InStatueCutscene
}
}

View File

@ -0,0 +1,126 @@
using QSB.Events;
using QSB.Player;
using QSB.Player.TransformSync;
using QSB.Utility;
using System.Linq;
using UnityEngine;
namespace QSB.ClientServerStateSync
{
class ServerStateManager : MonoBehaviour
{
public static ServerStateManager Instance { get; private set; }
public event ChangeStateEvent OnChangeState;
public delegate void ChangeStateEvent(ServerState newState);
private ServerState _currentState;
private void Awake()
=> Instance = this;
private void Start()
{
if (!QSBCore.IsHost)
{
return;
}
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova);
QSBCore.UnityEvents.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => QSBEventManager.FireEvent(EventNames.QSBServerState, ForceGetCurrentState()));
}
public void ChangeServerState(ServerState newState)
{
if (_currentState == newState)
{
return;
}
DebugLog.DebugWrite($"CHANGE SERVER STATE FROM {_currentState} to {newState}");
_currentState = newState;
OnChangeState?.Invoke(newState);
}
public ServerState GetServerState()
=> _currentState;
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
{
switch (newScene)
{
case OWScene.Credits_Fast:
case OWScene.Credits_Final:
case OWScene.PostCreditsScene:
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.Credits);
break;
case OWScene.TitleScreen:
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
break;
case OWScene.SolarSystem:
if (oldScene == OWScene.SolarSystem)
{
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
}
else
{
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
}
break;
case OWScene.EyeOfTheUniverse:
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
break;
case OWScene.None:
case OWScene.Undefined:
default:
DebugLog.ToConsole($"Warning - newScene is {newScene}!", OWML.Common.MessageType.Warning);
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
break;
}
}
private void OnTriggerSupernova()
{
DebugLog.DebugWrite($"TriggerSupernova");
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForDeath);
}
private ServerState ForceGetCurrentState()
{
var currentScene = LoadManager.GetCurrentScene();
var lastScene = LoadManager.GetPreviousScene();
switch (currentScene)
{
case OWScene.SolarSystem:
return ServerState.InSolarSystem;
case OWScene.EyeOfTheUniverse:
return ServerState.InEye;
default:
return ServerState.NotLoaded;
}
}
private void Update()
{
if (!QSBCore.IsHost)
{
return;
}
if (_currentState == ServerState.AwaitingPlayConfirmation)
{
if (QSBPlayerManager.PlayerList.All(x => x.State == ClientState.WaitingForOthersToReadyInSolarSystem))
{
DebugLog.DebugWrite($"All ready!!");
QSBEventManager.FireEvent(EventNames.QSBStartLoop);
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
}
}
}
}
}

View File

@ -83,6 +83,7 @@
public static string QSBLaunchProbe = "QSBLaunchProbe";
public static string QSBPlayerLaunchProbe = "QSBPlayerLaunchProbe";
public static string QSBEndLoop = "QSBEndLoop";
public static string QSBServerState = "QSBServerState";
public static string QSBClientState = "QSBClientState";
}
}

View File

@ -6,6 +6,7 @@
ServerTime,
StartStatue,
EndLoop,
ServerState,
ClientState,
/*

View File

@ -64,6 +64,7 @@ namespace QSB.Events
new PlayerRetrieveProbeEvent(),
new PlayerLaunchProbeEvent(),
new EndLoopEvent(),
new ServerStateEvent(),
new ClientStateEvent(),
// World Objects
new ElevatorEvent(),

View File

@ -256,6 +256,9 @@
<Compile Include="QuantumSync\Patches\QuantumVisibilityPatches.cs" />
<Compile Include="QuantumSync\Patches\ServerQuantumPatches.cs" />
<Compile Include="SectorSync\TargetType.cs" />
<Compile Include="ClientServerStateSync\Events\ServerStateEvent.cs" />
<Compile Include="ClientServerStateSync\ServerState.cs" />
<Compile Include="ClientServerStateSync\ServerStateManager.cs" />
<Compile Include="ShipSync\ComponentType.cs" />
<Compile Include="ShipSync\Events\Component\ComponentDamagedEvent.cs" />
<Compile Include="ShipSync\Events\Component\ComponentRepairedEvent.cs" />

View File

@ -152,6 +152,7 @@ namespace QSB
QSBEventManager.Init();
gameObject.AddComponent<RespawnOnDeath>();
gameObject.AddComponent<ServerStateManager>();
gameObject.AddComponent<ClientStateManager>();
if (QSBSceneManager.IsInUniverse)