275 lines
6.3 KiB
C#
Raw Normal View History

2021-02-10 19:34:41 +00:00
using OWML.Common;
using QSB.DeathSync;
2020-12-14 16:24:52 +00:00
using QSB.Events;
2020-11-03 17:56:48 +00:00
using QSB.TimeSync.Events;
2021-02-10 19:34:41 +00:00
using QSB.Utility;
2020-12-04 22:15:41 +00:00
using QuantumUNET;
using UnityEngine;
namespace QSB.TimeSync
2020-02-15 20:48:02 +01:00
{
2020-12-23 12:58:45 +00:00
public class WakeUpSync : QNetworkBehaviour
2020-12-02 21:29:53 +00:00
{
public static WakeUpSync LocalInstance { get; private set; }
private const float TimeThreshold = 0.5f;
private const float MaxFastForwardSpeed = 60f;
private const float MaxFastForwardDiff = 20f;
private const float MinFastForwardSpeed = 2f;
private enum State { NotLoaded, Loaded, FastForwarding, Pausing }
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
private State _state = State.NotLoaded;
private float _sendTimer;
private float _serverTime;
private float _timeScale;
private bool _isInputEnabled = true;
private bool _isFirstFastForward = true;
private int _localLoopCount;
private int _serverLoopCount;
2021-02-28 14:43:05 +00:00
private InputMode _storedMode;
2020-12-02 21:29:53 +00:00
2020-12-18 20:28:22 +00:00
public override void OnStartLocalPlayer() => LocalInstance = this;
2020-12-02 21:29:53 +00:00
2020-12-14 21:41:56 +01:00
public void Start()
2020-12-02 21:29:53 +00:00
{
if (!IsLocalPlayer)
{
return;
}
if (QSBSceneManager.IsInUniverse)
{
Init();
}
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
private void OnWakeUp()
{
2021-02-14 09:43:36 +00:00
DebugLog.DebugWrite($"OnWakeUp", MessageType.Info);
2020-12-23 12:58:45 +00:00
if (QNetworkServer.active)
2020-12-02 21:29:53 +00:00
{
2020-12-14 16:24:52 +00:00
QSBCore.HasWokenUp = true;
2021-02-06 22:03:10 +00:00
RespawnOnDeath.Instance.Init();
2020-12-02 21:29:53 +00:00
}
}
2020-12-14 21:41:56 +01:00
public void OnDestroy()
2020-12-02 21:29:53 +00:00
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
GlobalMessenger.RemoveListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.RemoveListener(EventNames.WakeUp, OnWakeUp);
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
if (isInUniverse)
{
Init();
}
else
{
_state = State.NotLoaded;
}
}
2020-12-18 20:28:22 +00:00
private void OnLoopStart() => _localLoopCount++;
2020-12-02 21:29:53 +00:00
private void Init()
{
2021-02-10 19:34:41 +00:00
QSBEventManager.FireEvent(EventNames.QSBPlayerStatesRequest);
2020-12-02 21:29:53 +00:00
_state = State.Loaded;
gameObject.AddComponent<PreserveTimeScale>();
if (IsServer)
{
SendServerTime();
}
else
{
WakeUpOrSleep();
}
}
private void SendServerTime() => QSBEventManager.FireEvent(EventNames.QSBServerTime, Time.timeSinceLevelLoad, _localLoopCount);
2020-12-02 21:29:53 +00:00
public void OnClientReceiveMessage(ServerTimeMessage message)
{
_serverTime = message.ServerTime;
_serverLoopCount = message.LoopCount;
WakeUpOrSleep();
}
private void WakeUpOrSleep()
{
if (_state == State.NotLoaded || _localLoopCount != _serverLoopCount)
{
return;
}
var myTime = Time.timeSinceLevelLoad;
var diff = myTime - _serverTime;
if (diff > TimeThreshold)
{
StartPausing();
return;
}
if (diff < -TimeThreshold)
{
StartFastForwarding();
}
}
private void StartFastForwarding()
{
if (_state == State.FastForwarding)
{
2020-12-19 19:06:13 +00:00
TimeSyncUI.TargetTime = _serverTime;
2020-12-02 21:29:53 +00:00
return;
}
2021-02-10 19:34:41 +00:00
DebugLog.DebugWrite($"START FASTFORWARD (Target:{_serverTime} Current:{Time.timeSinceLevelLoad})", MessageType.Info);
2021-02-28 14:43:05 +00:00
if (Locator.GetPlayerCamera() != null)
{
Locator.GetPlayerCamera().enabled = false;
}
2020-12-02 21:29:53 +00:00
_timeScale = MaxFastForwardSpeed;
_state = State.FastForwarding;
2021-02-28 14:43:05 +00:00
OWTime.SetMaxDeltaTime(0.033333335f);
2020-12-19 19:06:13 +00:00
TimeSyncUI.TargetTime = _serverTime;
2020-12-02 21:29:53 +00:00
TimeSyncUI.Start(TimeSyncType.Fastforwarding);
2021-02-28 14:43:05 +00:00
DisableInput();
2020-12-02 21:29:53 +00:00
}
private void StartPausing()
{
if (_state == State.Pausing)
{
return;
}
2021-02-10 19:34:41 +00:00
DebugLog.DebugWrite($"START PAUSING (Target:{_serverTime} Current:{Time.timeSinceLevelLoad})", MessageType.Info);
2021-02-28 14:43:05 +00:00
Locator.GetPlayerCamera().enabled = false;
2020-12-02 21:29:53 +00:00
_timeScale = 0f;
_state = State.Pausing;
SpinnerUI.Show();
TimeSyncUI.Start(TimeSyncType.Pausing);
2021-02-28 14:43:05 +00:00
DisableInput();
2020-12-02 21:29:53 +00:00
}
private void ResetTimeScale()
{
_timeScale = 1f;
2021-02-28 14:43:05 +00:00
OWTime.SetMaxDeltaTime(0.06666667f);
Locator.GetPlayerCamera().enabled = true;
2020-12-02 21:29:53 +00:00
_state = State.Loaded;
if (!_isInputEnabled)
{
EnableInput();
}
2021-02-10 19:34:41 +00:00
DebugLog.DebugWrite($"RESET TIMESCALE", MessageType.Info);
2020-12-02 21:29:53 +00:00
_isFirstFastForward = false;
2020-12-14 16:24:52 +00:00
QSBCore.HasWokenUp = true;
2020-12-02 21:29:53 +00:00
Physics.SyncTransforms();
SpinnerUI.Hide();
TimeSyncUI.Stop();
2021-02-10 19:34:41 +00:00
QSBEventManager.FireEvent(EventNames.QSBPlayerStatesRequest);
2020-12-02 21:29:53 +00:00
RespawnOnDeath.Instance.Init();
}
private void DisableInput()
{
2021-02-28 14:43:05 +00:00
DebugLog.DebugWrite($"disable input - current:{OWInput.GetInputMode()}");
2020-12-02 21:29:53 +00:00
_isInputEnabled = false;
2021-02-28 14:43:05 +00:00
_storedMode = OWInput.GetInputMode();
2020-12-02 21:29:53 +00:00
OWInput.ChangeInputMode(InputMode.None);
}
private void EnableInput()
{
2021-02-28 14:43:05 +00:00
DebugLog.DebugWrite($"enable input - stored:{_storedMode}");
2020-12-02 21:29:53 +00:00
_isInputEnabled = true;
2021-02-28 14:43:05 +00:00
OWInput.ChangeInputMode(
2021-02-28 15:29:09 +00:00
_storedMode != InputMode.None
? _storedMode
2021-02-28 14:43:05 +00:00
: InputMode.Character);
2020-12-02 21:29:53 +00:00
}
2020-12-14 21:41:56 +01:00
public void Update()
2020-12-02 21:29:53 +00:00
{
if (IsServer)
{
UpdateServer();
}
else if (IsLocalPlayer)
{
UpdateLocal();
}
}
private void UpdateServer()
{
if (_state != State.Loaded)
{
return;
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer > 1)
{
SendServerTime();
_sendTimer = 0;
}
}
private void UpdateLocal()
{
_serverTime += Time.unscaledDeltaTime;
2021-02-28 14:43:05 +00:00
if (!_isInputEnabled && OWInput.GetInputMode() != InputMode.None)
{
DisableInput();
}
2020-12-02 21:29:53 +00:00
if (_state == State.NotLoaded)
{
return;
}
if (_state == State.FastForwarding)
{
2021-02-28 14:43:05 +00:00
if (Locator.GetPlayerCamera() != null && !Locator.GetPlayerCamera().enabled)
{
Locator.GetPlayerCamera().enabled = false;
}
2020-12-02 21:29:53 +00:00
var diff = _serverTime - Time.timeSinceLevelLoad;
2021-02-28 14:43:05 +00:00
Time.timeScale = Mathf.SmoothStep(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff);
2020-12-02 21:29:53 +00:00
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem && _isFirstFastForward)
{
var spawnPoint = Locator.GetPlayerBody().GetComponent<PlayerSpawner>().GetInitialSpawnPoint().transform;
Locator.GetPlayerTransform().position = spawnPoint.position;
Locator.GetPlayerTransform().rotation = spawnPoint.rotation;
Physics.SyncTransforms();
}
}
else
{
Time.timeScale = _timeScale;
}
var isDoneFastForwarding = _state == State.FastForwarding && Time.timeSinceLevelLoad >= _serverTime;
var isDonePausing = _state == State.Pausing && Time.timeSinceLevelLoad < _serverTime;
if (isDoneFastForwarding || isDonePausing)
{
ResetTimeScale();
}
}
}
2020-11-26 13:09:34 +00:00
}