more tabs

This commit is contained in:
Mister_Nebula 2020-12-02 21:29:53 +00:00
parent c6c76cb395
commit 7925b637a0
27 changed files with 2196 additions and 2196 deletions

View File

@ -8,237 +8,237 @@ using UnityEngine;
namespace QSB.Animation
{
public class AnimationSync : PlayerSyncObject
{
private Animator _anim;
private Animator _bodyAnim;
private QSBNetworkAnimator _netAnim;
public class AnimationSync : PlayerSyncObject
{
private Animator _anim;
private Animator _bodyAnim;
private QSBNetworkAnimator _netAnim;
private RuntimeAnimatorController _suitedAnimController;
private AnimatorOverrideController _unsuitedAnimController;
private GameObject _suitedGraphics;
private GameObject _unsuitedGraphics;
private PlayerCharacterController _playerController;
private CrouchSync _crouchSync;
private RuntimeAnimatorController _suitedAnimController;
private AnimatorOverrideController _unsuitedAnimController;
private GameObject _suitedGraphics;
private GameObject _unsuitedGraphics;
private PlayerCharacterController _playerController;
private CrouchSync _crouchSync;
private RuntimeAnimatorController _chertController;
private RuntimeAnimatorController _eskerController;
private RuntimeAnimatorController _feldsparController;
private RuntimeAnimatorController _gabbroController;
private RuntimeAnimatorController _riebeckController;
private RuntimeAnimatorController _chertController;
private RuntimeAnimatorController _eskerController;
private RuntimeAnimatorController _feldsparController;
private RuntimeAnimatorController _gabbroController;
private RuntimeAnimatorController _riebeckController;
public AnimatorMirror Mirror { get; private set; }
public AnimationType CurrentType = AnimationType.PlayerUnsuited;
public Animator Animator
{
get { return _bodyAnim; }
}
public AnimatorMirror Mirror { get; private set; }
public AnimationType CurrentType = AnimationType.PlayerUnsuited;
public Animator Animator
{
get { return _bodyAnim; }
}
private void Awake()
{
_anim = gameObject.AddComponent<Animator>();
_netAnim = gameObject.AddComponent<QSBNetworkAnimator>();
_netAnim.enabled = false;
_netAnim.animator = _anim;
private void Awake()
{
_anim = gameObject.AddComponent<Animator>();
_netAnim = gameObject.AddComponent<QSBNetworkAnimator>();
_netAnim.enabled = false;
_netAnim.animator = _anim;
QSBSceneManager.OnUniverseSceneLoaded += (OWScene scene) => LoadControllers();
}
QSBSceneManager.OnUniverseSceneLoaded += (OWScene scene) => LoadControllers();
}
private void OnDestroy()
{
_netAnim.enabled = false;
if (_playerController == null)
{
return;
}
_playerController.OnJump -= OnJump;
_playerController.OnBecomeGrounded -= OnBecomeGrounded;
_playerController.OnBecomeUngrounded -= OnBecomeUngrounded;
private void OnDestroy()
{
_netAnim.enabled = false;
if (_playerController == null)
{
return;
}
_playerController.OnJump -= OnJump;
_playerController.OnBecomeGrounded -= OnBecomeGrounded;
_playerController.OnBecomeUngrounded -= OnBecomeUngrounded;
QSBSceneManager.OnUniverseSceneLoaded -= (OWScene scene) => LoadControllers();
}
QSBSceneManager.OnUniverseSceneLoaded -= (OWScene scene) => LoadControllers();
}
private void LoadControllers()
{
var bundle = QSB.InstrumentAssetBundle;
_chertController = bundle.LoadAsset("assets/Chert/Traveller_Chert.controller") as RuntimeAnimatorController;
_riebeckController = bundle.LoadAsset("assets/Riebeck/Traveller_Riebeck.controller") as RuntimeAnimatorController;
}
private void LoadControllers()
{
var bundle = QSB.InstrumentAssetBundle;
_chertController = bundle.LoadAsset("assets/Chert/Traveller_Chert.controller") as RuntimeAnimatorController;
_riebeckController = bundle.LoadAsset("assets/Riebeck/Traveller_Riebeck.controller") as RuntimeAnimatorController;
}
private void InitCommon(Transform body)
{
if (QSBSceneManager.IsInUniverse)
{
LoadControllers();
}
_netAnim.enabled = true;
_bodyAnim = body.GetComponent<Animator>();
Mirror = body.gameObject.AddComponent<AnimatorMirror>();
if (IsLocalPlayer)
{
Mirror.Init(_bodyAnim, _anim);
}
else
{
Mirror.Init(_anim, _bodyAnim);
}
private void InitCommon(Transform body)
{
if (QSBSceneManager.IsInUniverse)
{
LoadControllers();
}
_netAnim.enabled = true;
_bodyAnim = body.GetComponent<Animator>();
Mirror = body.gameObject.AddComponent<AnimatorMirror>();
if (IsLocalPlayer)
{
Mirror.Init(_bodyAnim, _anim);
}
else
{
Mirror.Init(_anim, _bodyAnim);
}
QSBPlayerManager.PlayerSyncObjects.Add(this);
QSBPlayerManager.PlayerSyncObjects.Add(this);
for (var i = 0; i < _anim.parameterCount; i++)
{
_netAnim.SetParameterAutoSend(i, true);
}
for (var i = 0; i < _anim.parameterCount; i++)
{
_netAnim.SetParameterAutoSend(i, true);
}
var playerAnimController = body.GetComponent<PlayerAnimController>();
_suitedAnimController = AnimControllerPatch.SuitedAnimController;
_unsuitedAnimController = playerAnimController.GetValue<AnimatorOverrideController>("_unsuitedAnimOverride");
_suitedGraphics = playerAnimController.GetValue<GameObject>("_suitedGroup");
_unsuitedGraphics = playerAnimController.GetValue<GameObject>("_unsuitedGroup");
}
var playerAnimController = body.GetComponent<PlayerAnimController>();
_suitedAnimController = AnimControllerPatch.SuitedAnimController;
_unsuitedAnimController = playerAnimController.GetValue<AnimatorOverrideController>("_unsuitedAnimOverride");
_suitedGraphics = playerAnimController.GetValue<GameObject>("_suitedGroup");
_unsuitedGraphics = playerAnimController.GetValue<GameObject>("_unsuitedGroup");
}
public void InitLocal(Transform body)
{
InitCommon(body);
public void InitLocal(Transform body)
{
InitCommon(body);
_playerController = body.parent.GetComponent<PlayerCharacterController>();
_playerController.OnJump += OnJump;
_playerController.OnBecomeGrounded += OnBecomeGrounded;
_playerController.OnBecomeUngrounded += OnBecomeUngrounded;
_playerController = body.parent.GetComponent<PlayerCharacterController>();
_playerController.OnJump += OnJump;
_playerController.OnBecomeGrounded += OnBecomeGrounded;
_playerController.OnBecomeUngrounded += OnBecomeUngrounded;
InitCrouchSync();
}
InitCrouchSync();
}
public void InitRemote(Transform body)
{
InitCommon(body);
public void InitRemote(Transform body)
{
InitCommon(body);
var playerAnimController = body.GetComponent<PlayerAnimController>();
playerAnimController.enabled = false;
var playerAnimController = body.GetComponent<PlayerAnimController>();
playerAnimController.enabled = false;
playerAnimController.SetValue("_suitedGroup", new GameObject());
playerAnimController.SetValue("_unsuitedGroup", new GameObject());
playerAnimController.SetValue("_baseAnimController", null);
playerAnimController.SetValue("_unsuitedAnimOverride", null);
playerAnimController.SetValue("_rightArmHidden", false);
playerAnimController.SetValue("_suitedGroup", new GameObject());
playerAnimController.SetValue("_unsuitedGroup", new GameObject());
playerAnimController.SetValue("_baseAnimController", null);
playerAnimController.SetValue("_unsuitedAnimOverride", null);
playerAnimController.SetValue("_rightArmHidden", false);
var rightArmObjects = playerAnimController.GetValue<GameObject[]>("_rightArmObjects").ToList();
rightArmObjects.ForEach(rightArmObject => rightArmObject.layer = LayerMask.NameToLayer("Default"));
var rightArmObjects = playerAnimController.GetValue<GameObject[]>("_rightArmObjects").ToList();
rightArmObjects.ForEach(rightArmObject => rightArmObject.layer = LayerMask.NameToLayer("Default"));
body.Find("player_mesh_noSuit:Traveller_HEA_Player/player_mesh_noSuit:Player_Head").gameObject.layer = 0;
body.Find("Traveller_Mesh_v01:Traveller_Geo/Traveller_Mesh_v01:PlayerSuit_Helmet").gameObject.layer = 0;
body.Find("player_mesh_noSuit:Traveller_HEA_Player/player_mesh_noSuit:Player_Head").gameObject.layer = 0;
body.Find("Traveller_Mesh_v01:Traveller_Geo/Traveller_Mesh_v01:PlayerSuit_Helmet").gameObject.layer = 0;
InitCrouchSync();
InitCrouchSync();
var ikSync = body.gameObject.AddComponent<PlayerHeadRotationSync>();
QSB.Helper.Events.Unity.RunWhen(() => Player.Camera != null, () => ikSync.Init(Player.Camera.transform));
}
var ikSync = body.gameObject.AddComponent<PlayerHeadRotationSync>();
QSB.Helper.Events.Unity.RunWhen(() => Player.Camera != null, () => ikSync.Init(Player.Camera.transform));
}
private void InitCrouchSync()
{
_crouchSync = gameObject.AddComponent<CrouchSync>();
_crouchSync.Init(this, _playerController, _bodyAnim);
}
private void InitCrouchSync()
{
_crouchSync = gameObject.AddComponent<CrouchSync>();
_crouchSync.Init(this, _playerController, _bodyAnim);
}
private void OnJump() => _netAnim.SetTrigger("Jump");
private void OnBecomeGrounded() => _netAnim.SetTrigger("Grounded");
private void OnBecomeUngrounded() => _netAnim.SetTrigger("Ungrounded");
private void OnJump() => _netAnim.SetTrigger("Jump");
private void OnBecomeGrounded() => _netAnim.SetTrigger("Grounded");
private void OnBecomeUngrounded() => _netAnim.SetTrigger("Ungrounded");
public void SendCrouch(float value = 0)
{
GlobalMessenger<float>.FireEvent(EventNames.QSBCrouch, value);
}
public void SendCrouch(float value = 0)
{
GlobalMessenger<float>.FireEvent(EventNames.QSBCrouch, value);
}
public void HandleCrouch(float value)
{
_crouchSync.CrouchParam.Target = value;
}
public void HandleCrouch(float value)
{
_crouchSync.CrouchParam.Target = value;
}
private void SuitUp()
{
GlobalMessenger<uint, AnimationType>.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerSuited);
SetAnimationType(AnimationType.PlayerSuited);
}
private void SuitUp()
{
GlobalMessenger<uint, AnimationType>.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerSuited);
SetAnimationType(AnimationType.PlayerSuited);
}
private void SuitDown()
{
GlobalMessenger<uint, AnimationType>.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerUnsuited);
SetAnimationType(AnimationType.PlayerUnsuited);
}
private void SuitDown()
{
GlobalMessenger<uint, AnimationType>.FireEvent(EventNames.QSBChangeAnimType, PlayerId, AnimationType.PlayerUnsuited);
SetAnimationType(AnimationType.PlayerUnsuited);
}
public void SetSuitState(bool state)
{
if (state)
{
SuitUp();
return;
}
SuitDown();
}
public void SetSuitState(bool state)
{
if (state)
{
SuitUp();
return;
}
SuitDown();
}
public void SetAnimationType(AnimationType type)
{
if (CurrentType == type)
{
return;
}
CurrentType = type;
if (_unsuitedAnimController == null)
{
DebugLog.DebugWrite($"Error - Unsuited controller is null. ({PlayerId})", MessageType.Error);
}
if (_suitedAnimController == null)
{
DebugLog.DebugWrite($"Error - Suited controller is null. ({PlayerId})", MessageType.Error);
}
RuntimeAnimatorController controller = default;
switch (type)
{
case AnimationType.PlayerSuited:
controller = _suitedAnimController;
_unsuitedGraphics?.SetActive(false);
_suitedGraphics?.SetActive(true);
break;
case AnimationType.PlayerUnsuited:
controller = _unsuitedAnimController;
_unsuitedGraphics?.SetActive(true);
_suitedGraphics?.SetActive(false);
break;
case AnimationType.Chert:
controller = _chertController;
break;
case AnimationType.Esker:
controller = _eskerController;
break;
case AnimationType.Feldspar:
controller = _feldsparController;
break;
case AnimationType.Gabbro:
controller = _gabbroController;
break;
case AnimationType.Riebeck:
controller = _riebeckController;
break;
}
_anim.runtimeAnimatorController = controller;
_bodyAnim.runtimeAnimatorController = controller;
if (type != AnimationType.PlayerSuited && type != AnimationType.PlayerUnsuited)
{
_bodyAnim.SetTrigger("Playing");
_anim.SetTrigger("Playing");
}
else
{
// Avoids "jumping" when exiting instrument and putting on suit
_bodyAnim.SetTrigger("Grounded");
_anim.SetTrigger("Grounded");
}
_netAnim.animator = _anim; // Probably not needed.
Mirror.RebuildFloatParams();
for (var i = 0; i < _anim.parameterCount; i++)
{
_netAnim.SetParameterAutoSend(i, true);
}
}
}
public void SetAnimationType(AnimationType type)
{
if (CurrentType == type)
{
return;
}
CurrentType = type;
if (_unsuitedAnimController == null)
{
DebugLog.DebugWrite($"Error - Unsuited controller is null. ({PlayerId})", MessageType.Error);
}
if (_suitedAnimController == null)
{
DebugLog.DebugWrite($"Error - Suited controller is null. ({PlayerId})", MessageType.Error);
}
RuntimeAnimatorController controller = default;
switch (type)
{
case AnimationType.PlayerSuited:
controller = _suitedAnimController;
_unsuitedGraphics?.SetActive(false);
_suitedGraphics?.SetActive(true);
break;
case AnimationType.PlayerUnsuited:
controller = _unsuitedAnimController;
_unsuitedGraphics?.SetActive(true);
_suitedGraphics?.SetActive(false);
break;
case AnimationType.Chert:
controller = _chertController;
break;
case AnimationType.Esker:
controller = _eskerController;
break;
case AnimationType.Feldspar:
controller = _feldsparController;
break;
case AnimationType.Gabbro:
controller = _gabbroController;
break;
case AnimationType.Riebeck:
controller = _riebeckController;
break;
}
_anim.runtimeAnimatorController = controller;
_bodyAnim.runtimeAnimatorController = controller;
if (type != AnimationType.PlayerSuited && type != AnimationType.PlayerUnsuited)
{
_bodyAnim.SetTrigger("Playing");
_anim.SetTrigger("Playing");
}
else
{
// Avoids "jumping" when exiting instrument and putting on suit
_bodyAnim.SetTrigger("Grounded");
_anim.SetTrigger("Grounded");
}
_netAnim.animator = _anim; // Probably not needed.
Mirror.RebuildFloatParams();
for (var i = 0; i < _anim.parameterCount; i++)
{
_netAnim.SetParameterAutoSend(i, true);
}
}
}
}

View File

@ -4,69 +4,69 @@ using UnityEngine;
namespace QSB.Animation
{
public class CrouchSync : QSBNetworkBehaviour
{
public AnimFloatParam CrouchParam { get; } = new AnimFloatParam();
public class CrouchSync : QSBNetworkBehaviour
{
public AnimFloatParam CrouchParam { get; } = new AnimFloatParam();
private const float CrouchSendInterval = 0.1f;
private const float CrouchChargeThreshold = 0.01f;
private const float CrouchSmoothTime = 0.05f;
private const int CrouchLayerIndex = 1;
private const float CrouchSendInterval = 0.1f;
private const float CrouchChargeThreshold = 0.01f;
private const float CrouchSmoothTime = 0.05f;
private const int CrouchLayerIndex = 1;
private float _sendTimer;
private float _lastSentJumpChargeFraction;
private float _sendTimer;
private float _lastSentJumpChargeFraction;
private AnimationSync _animationSync;
private PlayerCharacterController _playerController;
private Animator _bodyAnim;
private AnimationSync _animationSync;
private PlayerCharacterController _playerController;
private Animator _bodyAnim;
public void Init(AnimationSync animationSync, PlayerCharacterController playerController, Animator bodyAnim)
{
_animationSync = animationSync;
_playerController = playerController;
_bodyAnim = bodyAnim;
}
public void Init(AnimationSync animationSync, PlayerCharacterController playerController, Animator bodyAnim)
{
_animationSync = animationSync;
_playerController = playerController;
_bodyAnim = bodyAnim;
}
private void Update()
{
if (IsLocalPlayer)
{
SyncLocalCrouch();
return;
}
SyncRemoteCrouch();
}
private void Update()
{
if (IsLocalPlayer)
{
SyncLocalCrouch();
return;
}
SyncRemoteCrouch();
}
private void SyncLocalCrouch()
{
if (_playerController == null)
{
return;
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer < CrouchSendInterval)
{
return;
}
var jumpChargeFraction = _playerController.GetJumpChargeFraction();
if (Math.Abs(jumpChargeFraction - _lastSentJumpChargeFraction) < CrouchChargeThreshold)
{
return;
}
_animationSync.SendCrouch(jumpChargeFraction);
_lastSentJumpChargeFraction = jumpChargeFraction;
_sendTimer = 0;
}
private void SyncLocalCrouch()
{
if (_playerController == null)
{
return;
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer < CrouchSendInterval)
{
return;
}
var jumpChargeFraction = _playerController.GetJumpChargeFraction();
if (Math.Abs(jumpChargeFraction - _lastSentJumpChargeFraction) < CrouchChargeThreshold)
{
return;
}
_animationSync.SendCrouch(jumpChargeFraction);
_lastSentJumpChargeFraction = jumpChargeFraction;
_sendTimer = 0;
}
private void SyncRemoteCrouch()
{
if (_bodyAnim == null)
{
return;
}
CrouchParam.Smooth(CrouchSmoothTime);
var jumpChargeFraction = CrouchParam.Current;
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
}
}
private void SyncRemoteCrouch()
{
if (_bodyAnim == null)
{
return;
}
CrouchParam.Smooth(CrouchSmoothTime);
var jumpChargeFraction = CrouchParam.Current;
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
}
}
}

View File

@ -5,370 +5,370 @@ using UnityEngine.Networking;
namespace QSB.Animation
{
// Cleaned up unity code. UNET is so broken I gave up and fixed it myself.
// Cleaned up unity code. UNET is so broken I gave up and fixed it myself.
class QSBNetworkAnimator : QSBNetworkBehaviour
{
private static QSBAnimationMessage AnimationMessage = new QSBAnimationMessage();
private static QSBAnimationParametersMessage ParametersMessage = new QSBAnimationParametersMessage();
private static QSBAnimationTriggerMessage TriggersMessage = new QSBAnimationTriggerMessage();
class QSBNetworkAnimator : QSBNetworkBehaviour
{
private static QSBAnimationMessage AnimationMessage = new QSBAnimationMessage();
private static QSBAnimationParametersMessage ParametersMessage = new QSBAnimationParametersMessage();
private static QSBAnimationTriggerMessage TriggersMessage = new QSBAnimationTriggerMessage();
private Animator m_Animator;
private uint m_ParameterSendBits;
private int m_AnimationHash;
private int m_TransitionHash;
private NetworkWriter m_ParameterWriter;
private float m_SendTimer;
private Animator m_Animator;
private uint m_ParameterSendBits;
private int m_AnimationHash;
private int m_TransitionHash;
private NetworkWriter m_ParameterWriter;
private float m_SendTimer;
public Animator animator
{
get
{
return m_Animator;
}
set
{
m_Animator = value;
m_ParameterSendBits = 0U;
}
}
public Animator animator
{
get
{
return m_Animator;
}
set
{
m_Animator = value;
m_ParameterSendBits = 0U;
}
}
public void SetParameterAutoSend(int index, bool value)
{
if (value)
m_ParameterSendBits |= (uint)(1 << index);
else
m_ParameterSendBits &= (uint)~(1 << index);
}
public void SetParameterAutoSend(int index, bool value)
{
if (value)
m_ParameterSendBits |= (uint)(1 << index);
else
m_ParameterSendBits &= (uint)~(1 << index);
}
public bool GetParameterAutoSend(int index)
{
return ((int)m_ParameterSendBits & 1 << index) != 0;
}
public bool GetParameterAutoSend(int index)
{
return ((int)m_ParameterSendBits & 1 << index) != 0;
}
public override void OnStartAuthority()
{
m_ParameterWriter = new NetworkWriter();
}
public override void OnStartAuthority()
{
m_ParameterWriter = new NetworkWriter();
}
private void FixedUpdate()
{
if (m_ParameterWriter == null)
{
return;
}
CheckSendRate();
if (!CheckAnimStateChanged(out var stateHash, out var normalizedTime))
{
return;
}
var animationMessage = new QSBAnimationMessage
{
netId = NetId,
stateHash = stateHash,
normalizedTime = normalizedTime
};
private void FixedUpdate()
{
if (m_ParameterWriter == null)
{
return;
}
CheckSendRate();
if (!CheckAnimStateChanged(out var stateHash, out var normalizedTime))
{
return;
}
var animationMessage = new QSBAnimationMessage
{
netId = NetId,
stateHash = stateHash,
normalizedTime = normalizedTime
};
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, false);
animationMessage.parameters = m_ParameterWriter.ToArray();
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, false);
animationMessage.parameters = m_ParameterWriter.ToArray();
if (HasAuthority || QSBClientScene.readyConnection != null)
{
QSBClientScene.readyConnection.Send(40, animationMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
QSBNetworkServer.SendToReady(gameObject, 40, animationMessage);
}
}
if (HasAuthority || QSBClientScene.readyConnection != null)
{
QSBClientScene.readyConnection.Send(40, animationMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
QSBNetworkServer.SendToReady(gameObject, 40, animationMessage);
}
}
private bool CheckAnimStateChanged(out int stateHash, out float normalizedTime)
{
stateHash = 0;
normalizedTime = 0.0f;
if (m_Animator.IsInTransition(0))
{
var animatorTransitionInfo = m_Animator.GetAnimatorTransitionInfo(0);
if (animatorTransitionInfo.fullPathHash == m_TransitionHash)
{
return false;
}
m_TransitionHash = animatorTransitionInfo.fullPathHash;
m_AnimationHash = 0;
return true;
}
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
if (animatorStateInfo.fullPathHash == m_AnimationHash)
{
return false;
}
if (m_AnimationHash != 0)
{
stateHash = animatorStateInfo.fullPathHash;
normalizedTime = animatorStateInfo.normalizedTime;
}
m_TransitionHash = 0;
m_AnimationHash = animatorStateInfo.fullPathHash;
return true;
}
private bool CheckAnimStateChanged(out int stateHash, out float normalizedTime)
{
stateHash = 0;
normalizedTime = 0.0f;
if (m_Animator.IsInTransition(0))
{
var animatorTransitionInfo = m_Animator.GetAnimatorTransitionInfo(0);
if (animatorTransitionInfo.fullPathHash == m_TransitionHash)
{
return false;
}
m_TransitionHash = animatorTransitionInfo.fullPathHash;
m_AnimationHash = 0;
return true;
}
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
if (animatorStateInfo.fullPathHash == m_AnimationHash)
{
return false;
}
if (m_AnimationHash != 0)
{
stateHash = animatorStateInfo.fullPathHash;
normalizedTime = animatorStateInfo.normalizedTime;
}
m_TransitionHash = 0;
m_AnimationHash = animatorStateInfo.fullPathHash;
return true;
}
private void CheckSendRate()
{
if (GetNetworkSendInterval() == 0.0 || m_SendTimer >= Time.time)
{
return;
}
m_SendTimer = Time.time + GetNetworkSendInterval();
var parametersMessage = new QSBAnimationParametersMessage
{
netId = NetId
};
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, true);
parametersMessage.parameters = m_ParameterWriter.ToArray();
if (HasAuthority && QSBClientScene.readyConnection != null)
{
QSBClientScene.readyConnection.Send(41, parametersMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
return;
QSBNetworkServer.SendToReady(gameObject, 41, parametersMessage);
}
}
private void CheckSendRate()
{
if (GetNetworkSendInterval() == 0.0 || m_SendTimer >= Time.time)
{
return;
}
m_SendTimer = Time.time + GetNetworkSendInterval();
var parametersMessage = new QSBAnimationParametersMessage
{
netId = NetId
};
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, true);
parametersMessage.parameters = m_ParameterWriter.ToArray();
if (HasAuthority && QSBClientScene.readyConnection != null)
{
QSBClientScene.readyConnection.Send(41, parametersMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
return;
QSBNetworkServer.SendToReady(gameObject, 41, parametersMessage);
}
}
internal void HandleAnimMsg(QSBAnimationMessage msg, NetworkReader reader)
{
if (HasAuthority)
{
return;
}
if (msg.stateHash != 0)
{
m_Animator.Play(msg.stateHash, 0, msg.normalizedTime);
}
ReadParameters(reader, false);
}
internal void HandleAnimMsg(QSBAnimationMessage msg, NetworkReader reader)
{
if (HasAuthority)
{
return;
}
if (msg.stateHash != 0)
{
m_Animator.Play(msg.stateHash, 0, msg.normalizedTime);
}
ReadParameters(reader, false);
}
internal void HandleAnimParamsMsg(QSBAnimationParametersMessage msg, NetworkReader reader)
{
if (HasAuthority)
{
return;
}
ReadParameters(reader, true);
}
internal void HandleAnimParamsMsg(QSBAnimationParametersMessage msg, NetworkReader reader)
{
if (HasAuthority)
{
return;
}
ReadParameters(reader, true);
}
internal void HandleAnimTriggerMsg(int hash)
{
m_Animator.SetTrigger(hash);
}
internal void HandleAnimTriggerMsg(int hash)
{
m_Animator.SetTrigger(hash);
}
private void WriteParameters(NetworkWriter writer, bool autoSend)
{
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
writer.WritePackedUInt32((uint)m_Animator.GetInteger(parameter.nameHash));
break;
case AnimatorControllerParameterType.Float:
writer.Write(m_Animator.GetFloat(parameter.nameHash));
break;
case AnimatorControllerParameterType.Bool:
writer.Write(m_Animator.GetBool(parameter.nameHash));
break;
}
}
}
}
private void WriteParameters(NetworkWriter writer, bool autoSend)
{
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
writer.WritePackedUInt32((uint)m_Animator.GetInteger(parameter.nameHash));
break;
case AnimatorControllerParameterType.Float:
writer.Write(m_Animator.GetFloat(parameter.nameHash));
break;
case AnimatorControllerParameterType.Bool:
writer.Write(m_Animator.GetBool(parameter.nameHash));
break;
}
}
}
}
private void ReadParameters(NetworkReader reader, bool autoSend)
{
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
if (reader.Length == reader.Position)
{
return;
}
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
var num = (int)reader.ReadPackedUInt32();
m_Animator.SetInteger(parameter.nameHash, num);
break;
case AnimatorControllerParameterType.Float:
var single = reader.ReadSingle();
m_Animator.SetFloat(parameter.nameHash, single);
break;
case AnimatorControllerParameterType.Bool:
var flag = reader.ReadBoolean();
m_Animator.SetBool(parameter.nameHash, flag);
break;
}
}
}
}
private void ReadParameters(NetworkReader reader, bool autoSend)
{
for (int index = 0; index < m_Animator.parameters.Length; ++index)
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
if (reader.Length == reader.Position)
{
return;
}
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
var num = (int)reader.ReadPackedUInt32();
m_Animator.SetInteger(parameter.nameHash, num);
break;
case AnimatorControllerParameterType.Float:
var single = reader.ReadSingle();
m_Animator.SetFloat(parameter.nameHash, single);
break;
case AnimatorControllerParameterType.Bool:
var flag = reader.ReadBoolean();
m_Animator.SetBool(parameter.nameHash, flag);
break;
}
}
}
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (!forceAll)
{
return false;
}
if (m_Animator.IsInTransition(0))
{
var animatorStateInfo = m_Animator.GetNextAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
else
{
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
WriteParameters(writer, false);
return true;
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (!forceAll)
{
return false;
}
if (m_Animator.IsInTransition(0))
{
var animatorStateInfo = m_Animator.GetNextAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
else
{
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
WriteParameters(writer, false);
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (!initialState)
{
return;
}
var stateNameHash = reader.ReadInt32();
var normalizedTime = reader.ReadSingle();
ReadParameters(reader, false);
m_Animator.Play(stateNameHash, 0, normalizedTime);
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (!initialState)
{
return;
}
var stateNameHash = reader.ReadInt32();
var normalizedTime = reader.ReadSingle();
ReadParameters(reader, false);
m_Animator.Play(stateNameHash, 0, normalizedTime);
}
public void SetTrigger(string triggerName)
{
SetTrigger(Animator.StringToHash(triggerName));
}
public void SetTrigger(string triggerName)
{
SetTrigger(Animator.StringToHash(triggerName));
}
public void SetTrigger(int hash)
{
var animationTriggerMessage = new QSBAnimationTriggerMessage
{
netId = NetId,
hash = hash
};
if (HasAuthority && LocalPlayerAuthority)
{
if (QSBNetworkClient.allClients.Count <= 0)
{
return;
}
var readyConnection = QSBClientScene.readyConnection;
if (readyConnection == null)
{
return;
}
readyConnection.Send(42, animationTriggerMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
QSBNetworkServer.SendToReady(gameObject, 42, animationTriggerMessage);
}
}
public void SetTrigger(int hash)
{
var animationTriggerMessage = new QSBAnimationTriggerMessage
{
netId = NetId,
hash = hash
};
if (HasAuthority && LocalPlayerAuthority)
{
if (QSBNetworkClient.allClients.Count <= 0)
{
return;
}
var readyConnection = QSBClientScene.readyConnection;
if (readyConnection == null)
{
return;
}
readyConnection.Send(42, animationTriggerMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
QSBNetworkServer.SendToReady(gameObject, 42, animationTriggerMessage);
}
}
internal static void OnAnimationServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(AnimationMessage);
var localObject = QSBNetworkServer.FindLocalObject(AnimationMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
var reader = new NetworkReader(AnimationMessage.parameters);
component?.HandleAnimMsg(AnimationMessage, reader);
QSBNetworkServer.SendToReady(localObject, 40, AnimationMessage);
}
internal static void OnAnimationServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(AnimationMessage);
var localObject = QSBNetworkServer.FindLocalObject(AnimationMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
var reader = new NetworkReader(AnimationMessage.parameters);
component?.HandleAnimMsg(AnimationMessage, reader);
QSBNetworkServer.SendToReady(localObject, 40, AnimationMessage);
}
internal static void OnAnimationParametersServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(ParametersMessage);
var localObject = QSBNetworkServer.FindLocalObject(ParametersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
var reader = new NetworkReader(ParametersMessage.parameters);
component?.HandleAnimParamsMsg(ParametersMessage, reader);
QSBNetworkServer.SendToReady(localObject, 41, ParametersMessage);
}
internal static void OnAnimationParametersServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(ParametersMessage);
var localObject = QSBNetworkServer.FindLocalObject(ParametersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
var reader = new NetworkReader(ParametersMessage.parameters);
component?.HandleAnimParamsMsg(ParametersMessage, reader);
QSBNetworkServer.SendToReady(localObject, 41, ParametersMessage);
}
internal static void OnAnimationTriggerServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(TriggersMessage);
var localObject = QSBNetworkServer.FindLocalObject(TriggersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
component?.HandleAnimTriggerMsg(TriggersMessage.hash);
QSBNetworkServer.SendToReady(localObject, 42, TriggersMessage);
}
internal static void OnAnimationTriggerServerMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(TriggersMessage);
var localObject = QSBNetworkServer.FindLocalObject(TriggersMessage.netId);
if (localObject == null)
{
return;
}
var component = localObject.GetComponent<QSBNetworkAnimator>();
component?.HandleAnimTriggerMsg(TriggersMessage.hash);
QSBNetworkServer.SendToReady(localObject, 42, TriggersMessage);
}
internal static void OnAnimationClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(AnimationMessage);
var localObject = QSBClientScene.FindLocalObject(AnimationMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
var reader = new NetworkReader(AnimationMessage.parameters);
component.HandleAnimMsg(AnimationMessage, reader);
}
internal static void OnAnimationClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(AnimationMessage);
var localObject = QSBClientScene.FindLocalObject(AnimationMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
var reader = new NetworkReader(AnimationMessage.parameters);
component.HandleAnimMsg(AnimationMessage, reader);
}
internal static void OnAnimationParametersClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(ParametersMessage);
var localObject = QSBClientScene.FindLocalObject(ParametersMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
var reader = new NetworkReader(ParametersMessage.parameters);
component.HandleAnimParamsMsg(ParametersMessage, reader);
}
internal static void OnAnimationParametersClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(ParametersMessage);
var localObject = QSBClientScene.FindLocalObject(ParametersMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
var reader = new NetworkReader(ParametersMessage.parameters);
component.HandleAnimParamsMsg(ParametersMessage, reader);
}
internal static void OnAnimationTriggerClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(TriggersMessage);
var localObject = QSBClientScene.FindLocalObject(TriggersMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
component.HandleAnimTriggerMsg(TriggersMessage.hash);
}
}
internal static void OnAnimationTriggerClientMessage(QSBNetworkMessage netMsg)
{
netMsg.ReadMessage(TriggersMessage);
var localObject = QSBClientScene.FindLocalObject(TriggersMessage.netId);
if (localObject == null)
return;
var component = localObject.GetComponent<QSBNetworkAnimator>();
if (component == null)
return;
component.HandleAnimTriggerMsg(TriggersMessage.hash);
}
}
}

View File

@ -5,64 +5,64 @@ using QSB.TransformSync;
namespace QSB.EventsCore
{
public abstract class QSBEvent<T> : IQSBEvent where T : PlayerMessage, new()
{
public abstract EventType Type { get; }
public uint LocalPlayerId => QSBPlayerManager.LocalPlayerId;
private readonly MessageHandler<T> _eventHandler;
public abstract class QSBEvent<T> : IQSBEvent where T : PlayerMessage, new()
{
public abstract EventType Type { get; }
public uint LocalPlayerId => QSBPlayerManager.LocalPlayerId;
private readonly MessageHandler<T> _eventHandler;
protected QSBEvent()
{
_eventHandler = new MessageHandler<T>(Type);
_eventHandler.OnClientReceiveMessage += OnClientReceive;
_eventHandler.OnServerReceiveMessage += OnServerReceive;
}
protected QSBEvent()
{
_eventHandler = new MessageHandler<T>(Type);
_eventHandler.OnClientReceiveMessage += OnClientReceive;
_eventHandler.OnServerReceiveMessage += OnServerReceive;
}
public abstract void SetupListener();
public abstract void SetupListener();
public abstract void CloseListener();
public abstract void CloseListener();
public virtual void OnReceiveRemote(T message)
{
}
public virtual void OnReceiveRemote(T message)
{
}
public virtual void OnReceiveLocal(T message)
{
}
public virtual void OnReceiveLocal(T message)
{
}
public virtual void OnServerReceive(T message)
{
_eventHandler.SendToAll(message);
}
public virtual void OnServerReceive(T message)
{
_eventHandler.SendToAll(message);
}
public void SendEvent(T message)
{
message.FromId = QSBPlayerManager.LocalPlayerId;
QSB.Helper.Events.Unity.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => Send(message));
}
public void SendEvent(T message)
{
message.FromId = QSBPlayerManager.LocalPlayerId;
QSB.Helper.Events.Unity.RunWhen(() => PlayerTransformSync.LocalInstance != null, () => Send(message));
}
private void Send(T message)
{
if (QSBNetworkServer.active)
{
_eventHandler.SendToAll(message);
}
else
{
_eventHandler.SendToServer(message);
}
}
private void Send(T message)
{
if (QSBNetworkServer.active)
{
_eventHandler.SendToAll(message);
}
else
{
_eventHandler.SendToServer(message);
}
}
private void OnClientReceive(T message)
{
if (message.FromId == QSBPlayerManager.LocalPlayerId ||
QSBPlayerManager.IsBelongingToLocalPlayer(message.AboutId))
{
OnReceiveLocal(message);
return;
}
private void OnClientReceive(T message)
{
if (message.FromId == QSBPlayerManager.LocalPlayerId ||
QSBPlayerManager.IsBelongingToLocalPlayer(message.AboutId))
{
OnReceiveLocal(message);
return;
}
OnReceiveRemote(message);
}
}
OnReceiveRemote(message);
}
}
}

View File

@ -4,37 +4,37 @@ using QSB.WorldSync;
namespace QSB.GeyserSync
{
public class QSBGeyser : WorldObject
{
private GeyserController _geyserController;
public class QSBGeyser : WorldObject
{
private GeyserController _geyserController;
public void Init(GeyserController geyserController, int id)
{
ObjectId = id;
_geyserController = geyserController;
public void Init(GeyserController geyserController, int id)
{
ObjectId = id;
_geyserController = geyserController;
geyserController.OnGeyserActivateEvent += () => HandleEvent(true);
geyserController.OnGeyserDeactivateEvent += () => HandleEvent(false);
}
geyserController.OnGeyserActivateEvent += () => HandleEvent(true);
geyserController.OnGeyserDeactivateEvent += () => HandleEvent(false);
}
private void HandleEvent(bool state)
{
if (QSBNetworkServer.active)
{
GlobalMessenger<int, bool>.FireEvent(EventNames.QSBGeyserState, ObjectId, state);
}
}
private void HandleEvent(bool state)
{
if (QSBNetworkServer.active)
{
GlobalMessenger<int, bool>.FireEvent(EventNames.QSBGeyserState, ObjectId, state);
}
}
public void SetState(bool state)
{
if (state)
{
_geyserController?.ActivateGeyser();
}
else
{
_geyserController?.DeactivateGeyser();
}
}
}
public void SetState(bool state)
{
if (state)
{
_geyserController?.ActivateGeyser();
}
else
{
_geyserController?.DeactivateGeyser();
}
}
}
}

View File

@ -8,68 +8,68 @@ using UnityEngine.Networking;
namespace QSB.Messaging
{
// Extend this to create new message handlers.
public class MessageHandler<T> where T : MessageBase, new()
{
public event Action<T> OnClientReceiveMessage;
public event Action<T> OnServerReceiveMessage;
// Extend this to create new message handlers.
public class MessageHandler<T> where T : MessageBase, new()
{
public event Action<T> OnClientReceiveMessage;
public event Action<T> OnServerReceiveMessage;
private readonly EventType _eventType;
private readonly EventType _eventType;
public MessageHandler(EventType eventType)
{
_eventType = eventType + MsgType.Highest + 1;
if (QSBNetworkManager.Instance.IsReady)
{
Init();
}
else
{
QSBNetworkManager.Instance.OnNetworkManagerReady += Init;
}
}
public MessageHandler(EventType eventType)
{
_eventType = eventType + MsgType.Highest + 1;
if (QSBNetworkManager.Instance.IsReady)
{
Init();
}
else
{
QSBNetworkManager.Instance.OnNetworkManagerReady += Init;
}
}
private void Init()
{
var eventName = Enum.GetName(typeof(EventType), _eventType - 1 - MsgType.Highest).ToUpper();
if (QSBNetworkServer.handlers.Keys.Contains((short)_eventType))
{
DebugLog.ToConsole($"Warning - NetworkServer already contains a handler for EventType {_eventType}", MessageType.Warning);
QSBNetworkServer.handlers.Remove((short)_eventType);
}
QSBNetworkServer.RegisterHandler((short)_eventType, OnServerReceiveMessageHandler);
QSBNetworkManager.singleton.client.RegisterHandler((short)_eventType, OnClientReceiveMessageHandler);
}
private void Init()
{
var eventName = Enum.GetName(typeof(EventType), _eventType - 1 - MsgType.Highest).ToUpper();
if (QSBNetworkServer.handlers.Keys.Contains((short)_eventType))
{
DebugLog.ToConsole($"Warning - NetworkServer already contains a handler for EventType {_eventType}", MessageType.Warning);
QSBNetworkServer.handlers.Remove((short)_eventType);
}
QSBNetworkServer.RegisterHandler((short)_eventType, OnServerReceiveMessageHandler);
QSBNetworkManager.singleton.client.RegisterHandler((short)_eventType, OnClientReceiveMessageHandler);
}
public void SendToAll(T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
QSBNetworkServer.SendToAll((short)_eventType, message);
}
public void SendToAll(T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
QSBNetworkServer.SendToAll((short)_eventType, message);
}
public void SendToServer(T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
QSBNetworkManager.singleton.client.Send((short)_eventType, message);
}
public void SendToServer(T message)
{
if (!QSBNetworkManager.Instance.IsReady)
{
return;
}
QSBNetworkManager.singleton.client.Send((short)_eventType, message);
}
private void OnClientReceiveMessageHandler(QSBNetworkMessage netMsg)
{
var message = netMsg.ReadMessage<T>();
OnClientReceiveMessage?.Invoke(message);
}
private void OnClientReceiveMessageHandler(QSBNetworkMessage netMsg)
{
var message = netMsg.ReadMessage<T>();
OnClientReceiveMessage?.Invoke(message);
}
private void OnServerReceiveMessageHandler(QSBNetworkMessage netMsg)
{
var message = netMsg.ReadMessage<T>();
OnServerReceiveMessage?.Invoke(message);
}
private void OnServerReceiveMessageHandler(QSBNetworkMessage netMsg)
{
var message = netMsg.ReadMessage<T>();
OnServerReceiveMessage?.Invoke(message);
}
}
}
}

View File

@ -5,28 +5,28 @@ using QSB.WorldSync.Events;
namespace QSB.OrbSync.Events
{
public class OrbSlotEvent : QSBEvent<BoolWorldObjectMessage>
{
public override EventType Type => EventType.OrbSlot;
public class OrbSlotEvent : QSBEvent<BoolWorldObjectMessage>
{
public override EventType Type => EventType.OrbSlot;
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBOrbSlot, Handler);
public override void SetupListener() => GlobalMessenger<int, bool>.AddListener(EventNames.QSBOrbSlot, Handler);
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBOrbSlot, Handler);
public override void CloseListener() => GlobalMessenger<int, bool>.RemoveListener(EventNames.QSBOrbSlot, Handler);
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id,
State = state
};
private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id,
State = state
};
public override void OnReceiveRemote(BoolWorldObjectMessage message)
{
DebugLog.DebugWrite($"receive slot {message.ObjectId} to {message.State}");
var orbSlot = WorldRegistry.GetObject<QSBOrbSlot>(message.ObjectId);
orbSlot?.SetState(message.State);
}
}
public override void OnReceiveRemote(BoolWorldObjectMessage message)
{
DebugLog.DebugWrite($"receive slot {message.ObjectId} to {message.State}");
var orbSlot = WorldRegistry.GetObject<QSBOrbSlot>(message.ObjectId);
orbSlot?.SetState(message.State);
}
}
}

View File

@ -8,79 +8,79 @@ using System.Linq;
namespace QSB.OrbSync.Events
{
public class OrbUserEvent : QSBEvent<WorldObjectMessage>
{
public override EventType Type => EventType.OrbUser;
public class OrbUserEvent : QSBEvent<WorldObjectMessage>
{
public override EventType Type => EventType.OrbUser;
public override void SetupListener() => GlobalMessenger<int>.AddListener(EventNames.QSBOrbUser, Handler);
public override void SetupListener() => GlobalMessenger<int>.AddListener(EventNames.QSBOrbUser, Handler);
public override void CloseListener() => GlobalMessenger<int>.RemoveListener(EventNames.QSBOrbUser, Handler);
public override void CloseListener() => GlobalMessenger<int>.RemoveListener(EventNames.QSBOrbUser, Handler);
private void Handler(int id) => SendEvent(CreateMessage(id));
private void Handler(int id) => SendEvent(CreateMessage(id));
private WorldObjectMessage CreateMessage(int id) => new WorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id
};
private WorldObjectMessage CreateMessage(int id) => new WorldObjectMessage
{
AboutId = LocalPlayerId,
ObjectId = id
};
public override void OnServerReceive(WorldObjectMessage message)
{
var fromPlayer = QSBNetworkServer.connections.First(x => x.GetPlayer().PlayerId == message.FromId);
foreach (var item in QSBNetworkServer.connections)
{
DebugLog.DebugWrite(item.GetPlayer().PlayerId.ToString());
}
if (WorldRegistry.OrbSyncList.Count == 0)
{
DebugLog.ToConsole($"Error - OrbSyncList is empty. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (fromPlayer == null)
{
DebugLog.DebugWrite("Error - FromPlayer is null!", MessageType.Error);
}
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
if (orb == null)
{
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
return;
}
var orbIdentity = orb.GetComponent<QSBNetworkIdentity>();
if (orbIdentity == null)
{
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (orbIdentity.ClientAuthorityOwner != null && orbIdentity.ClientAuthorityOwner != fromPlayer)
{
DebugLog.DebugWrite($"Removed authority of orb {message.ObjectId} from {orbIdentity.ClientAuthorityOwner.GetPlayer().PlayerId}");
orbIdentity.RemoveClientAuthority(orbIdentity.ClientAuthorityOwner);
}
DebugLog.DebugWrite($"Assigned authority of orb {message.ObjectId} to player {message.FromId}.");
orbIdentity.AssignClientAuthority(fromPlayer);
orb.enabled = true;
}
public override void OnServerReceive(WorldObjectMessage message)
{
var fromPlayer = QSBNetworkServer.connections.First(x => x.GetPlayer().PlayerId == message.FromId);
foreach (var item in QSBNetworkServer.connections)
{
DebugLog.DebugWrite(item.GetPlayer().PlayerId.ToString());
}
if (WorldRegistry.OrbSyncList.Count == 0)
{
DebugLog.ToConsole($"Error - OrbSyncList is empty. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (fromPlayer == null)
{
DebugLog.DebugWrite("Error - FromPlayer is null!", MessageType.Error);
}
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
if (orb == null)
{
DebugLog.ToConsole($"Error - No orb found for user event. (ID {message.ObjectId})", MessageType.Error);
return;
}
var orbIdentity = orb.GetComponent<QSBNetworkIdentity>();
if (orbIdentity == null)
{
DebugLog.ToConsole($"Error - Orb identity is null. (ID {message.ObjectId})", MessageType.Error);
return;
}
if (orbIdentity.ClientAuthorityOwner != null && orbIdentity.ClientAuthorityOwner != fromPlayer)
{
DebugLog.DebugWrite($"Removed authority of orb {message.ObjectId} from {orbIdentity.ClientAuthorityOwner.GetPlayer().PlayerId}");
orbIdentity.RemoveClientAuthority(orbIdentity.ClientAuthorityOwner);
}
DebugLog.DebugWrite($"Assigned authority of orb {message.ObjectId} to player {message.FromId}.");
orbIdentity.AssignClientAuthority(fromPlayer);
orb.enabled = true;
}
public override void OnReceiveRemote(WorldObjectMessage message)
{
if (WorldRegistry.OrbSyncList.Count < message.ObjectId)
{
DebugLog.DebugWrite($"Error - Orb id {message.ObjectId} out of range of orb sync list {WorldRegistry.OrbSyncList.Count}.", MessageType.Error);
return;
}
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
orb.enabled = true;
}
public override void OnReceiveRemote(WorldObjectMessage message)
{
if (WorldRegistry.OrbSyncList.Count < message.ObjectId)
{
DebugLog.DebugWrite($"Error - Orb id {message.ObjectId} out of range of orb sync list {WorldRegistry.OrbSyncList.Count}.", MessageType.Error);
return;
}
var orb = WorldRegistry.OrbSyncList
.First(x => x.AttachedOrb == WorldRegistry.OldOrbList[message.ObjectId]);
orb.enabled = true;
}
public override void OnReceiveLocal(WorldObjectMessage message)
{
if (QSBNetworkServer.active)
{
OnServerReceive(message);
}
}
}
public override void OnReceiveLocal(WorldObjectMessage message)
{
if (QSBNetworkServer.active)
{
OnServerReceive(message);
}
}
}
}

View File

@ -7,54 +7,54 @@ using UnityEngine;
namespace QSB.OrbSync
{
public class OrbManager : MonoBehaviour
{
public static OrbManager Instance { get; private set; }
public class OrbManager : MonoBehaviour
{
public static OrbManager Instance { get; private set; }
private void Awake()
{
Instance = this;
}
private void Awake()
{
Instance = this;
}
private void BuildOrbSlots()
{
DebugLog.DebugWrite("Building QSBOrbSlots...", MessageType.Info);
WorldRegistry.RemoveObjects<QSBOrbSlot>();
var orbSlots = Resources.FindObjectsOfTypeAll<NomaiInterfaceSlot>();
for (var id = 0; id < orbSlots.Length; id++)
{
var qsbOrbSlot = WorldRegistry.GetObject<QSBOrbSlot>(id) ?? new QSBOrbSlot();
qsbOrbSlot.Init(orbSlots[id], id);
}
private void BuildOrbSlots()
{
DebugLog.DebugWrite("Building QSBOrbSlots...", MessageType.Info);
WorldRegistry.RemoveObjects<QSBOrbSlot>();
var orbSlots = Resources.FindObjectsOfTypeAll<NomaiInterfaceSlot>();
for (var id = 0; id < orbSlots.Length; id++)
{
var qsbOrbSlot = WorldRegistry.GetObject<QSBOrbSlot>(id) ?? new QSBOrbSlot();
qsbOrbSlot.Init(orbSlots[id], id);
}
DebugLog.DebugWrite($"Finished orb slot build with {orbSlots.Length} slots.", MessageType.Success);
}
DebugLog.DebugWrite($"Finished orb slot build with {orbSlots.Length} slots.", MessageType.Success);
}
public void BuildOrbs()
{
DebugLog.DebugWrite("Building orb syncs...", MessageType.Info);
WorldRegistry.OldOrbList.Clear();
WorldRegistry.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
if (QSBNetworkServer.active)
{
DebugLog.DebugWrite("- Is server, instantiating orb prefabs.");
WorldRegistry.OrbSyncList.ForEach(x => QSBNetworkServer.Destroy(x.gameObject));
WorldRegistry.OrbSyncList.Clear();
WorldRegistry.OldOrbList.ForEach(x => QSBNetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
}
DebugLog.DebugWrite($"Finished orb build with {WorldRegistry.OldOrbList.Count} orbs.", MessageType.Success);
}
public void BuildOrbs()
{
DebugLog.DebugWrite("Building orb syncs...", MessageType.Info);
WorldRegistry.OldOrbList.Clear();
WorldRegistry.OldOrbList = Resources.FindObjectsOfTypeAll<NomaiInterfaceOrb>().ToList();
if (QSBNetworkServer.active)
{
DebugLog.DebugWrite("- Is server, instantiating orb prefabs.");
WorldRegistry.OrbSyncList.ForEach(x => QSBNetworkServer.Destroy(x.gameObject));
WorldRegistry.OrbSyncList.Clear();
WorldRegistry.OldOrbList.ForEach(x => QSBNetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
}
DebugLog.DebugWrite($"Finished orb build with {WorldRegistry.OldOrbList.Count} orbs.", MessageType.Success);
}
public void QueueBuildSlots()
{
DebugLog.DebugWrite("Queueing build of QSBOrbSlots...", MessageType.Info);
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, BuildOrbSlots);
}
public void QueueBuildSlots()
{
DebugLog.DebugWrite("Queueing build of QSBOrbSlots...", MessageType.Info);
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, BuildOrbSlots);
}
public void QueueBuildOrbs()
{
DebugLog.DebugWrite("Queueing build of NetworkOrbs...", MessageType.Info);
QSB.Helper.Events.Unity.RunWhen(() => QSBNetworkServer.active, BuildOrbs);
}
}
public void QueueBuildOrbs()
{
DebugLog.DebugWrite("Queueing build of NetworkOrbs...", MessageType.Info);
QSB.Helper.Events.Unity.RunWhen(() => QSBNetworkServer.active, BuildOrbs);
}
}
}

View File

@ -4,60 +4,60 @@ using UnityEngine;
namespace QSB.OrbSync
{
public class OrbPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
public class OrbPatches : QSBPatch
{
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
public static void StartDragCallEvent(bool __result, NomaiInterfaceOrb __instance)
{
if (__result)
{
GlobalMessenger<int>.FireEvent(EventNames.QSBOrbUser, WorldRegistry.OldOrbList.FindIndex(x => x == __instance));
}
}
public static void StartDragCallEvent(bool __result, NomaiInterfaceOrb __instance)
{
if (__result)
{
GlobalMessenger<int>.FireEvent(EventNames.QSBOrbUser, WorldRegistry.OldOrbList.FindIndex(x => x == __instance));
}
}
public static bool CheckOrbCollision(ref bool __result, NomaiInterfaceSlot __instance, NomaiInterfaceOrb orb,
bool ____ignoreDraggedOrbs, float ____radius, float ____exitRadius, ref NomaiInterfaceOrb ____occupyingOrb)
{
if (____ignoreDraggedOrbs && orb.IsBeingDragged())
{
__result = false;
return false;
}
var orbDistance = Vector3.Distance(orb.transform.position, __instance.transform.position);
var triggerRadius = orb.IsBeingDragged() ? ____exitRadius : ____radius;
if (____occupyingOrb == null && orbDistance < ____radius)
{
____occupyingOrb = orb;
if (Time.timeSinceLevelLoad > 1f)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, true);
WorldRegistry.RaiseEvent(__instance, "OnSlotActivated");
}
__result = true;
return false;
}
if (____occupyingOrb == null || ____occupyingOrb != orb)
{
__result = false;
return false;
}
if (orbDistance > triggerRadius)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, false);
____occupyingOrb = null;
WorldRegistry.RaiseEvent(__instance, "OnSlotDeactivated");
__result = false;
return false;
}
__result = true;
return false;
}
public static bool CheckOrbCollision(ref bool __result, NomaiInterfaceSlot __instance, NomaiInterfaceOrb orb,
bool ____ignoreDraggedOrbs, float ____radius, float ____exitRadius, ref NomaiInterfaceOrb ____occupyingOrb)
{
if (____ignoreDraggedOrbs && orb.IsBeingDragged())
{
__result = false;
return false;
}
var orbDistance = Vector3.Distance(orb.transform.position, __instance.transform.position);
var triggerRadius = orb.IsBeingDragged() ? ____exitRadius : ____radius;
if (____occupyingOrb == null && orbDistance < ____radius)
{
____occupyingOrb = orb;
if (Time.timeSinceLevelLoad > 1f)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, true);
WorldRegistry.RaiseEvent(__instance, "OnSlotActivated");
}
__result = true;
return false;
}
if (____occupyingOrb == null || ____occupyingOrb != orb)
{
__result = false;
return false;
}
if (orbDistance > triggerRadius)
{
WorldRegistry.HandleSlotStateChange(__instance, orb, false);
____occupyingOrb = null;
WorldRegistry.RaiseEvent(__instance, "OnSlotDeactivated");
__result = false;
return false;
}
__result = true;
return false;
}
public override void DoPatches()
{
QSB.Helper.HarmonyHelper.AddPostfix<NomaiInterfaceOrb>("StartDragFromPosition", typeof(OrbPatches), nameof(StartDragCallEvent));
QSB.Helper.HarmonyHelper.AddPrefix<NomaiInterfaceSlot>("CheckOrbCollision", typeof(OrbPatches), nameof(CheckOrbCollision));
}
}
public override void DoPatches()
{
QSB.Helper.HarmonyHelper.AddPostfix<NomaiInterfaceOrb>("StartDragFromPosition", typeof(OrbPatches), nameof(StartDragCallEvent));
QSB.Helper.HarmonyHelper.AddPrefix<NomaiInterfaceSlot>("CheckOrbCollision", typeof(OrbPatches), nameof(CheckOrbCollision));
}
}
}

View File

@ -12,38 +12,38 @@ using System.Linq;
namespace QSB.Patches
{
public delegate void PatchEvent(QSBPatchTypes type);
public delegate void PatchEvent(QSBPatchTypes type);
public static class QSBPatchManager
{
public static List<QSBPatch> _patchList = new List<QSBPatch>();
public static class QSBPatchManager
{
public static List<QSBPatch> _patchList = new List<QSBPatch>();
public static event PatchEvent OnPatchType;
public static event PatchEvent OnPatchType;
public static void Init()
{
_patchList = new List<QSBPatch>
{
new ConversationPatches(),
new DeathPatches(),
new ElevatorPatches(),
new OrbPatches(),
new WakeUpPatches(),
new ProbePatches()
};
public static void Init()
{
_patchList = new List<QSBPatch>
{
new ConversationPatches(),
new DeathPatches(),
new ElevatorPatches(),
new OrbPatches(),
new WakeUpPatches(),
new ProbePatches()
};
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
}
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
}
public static void DoPatchType(QSBPatchTypes type)
{
OnPatchType?.Invoke(type);
DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
foreach (var patch in _patchList.Where(x => x.Type == type))
{
DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
patch.DoPatches();
}
}
}
public static void DoPatchType(QSBPatchTypes type)
{
OnPatchType?.Invoke(type);
DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
foreach (var patch in _patchList.Where(x => x.Type == type))
{
DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
patch.DoPatches();
}
}
}
}

View File

@ -2,11 +2,11 @@
namespace QSB.Player
{
public abstract class PlayerSyncObject : QSBNetworkBehaviour
{
public uint AttachedNetId => GetComponent<QSBNetworkIdentity>()?.NetId.Value ?? uint.MaxValue;
public uint PlayerId => this.GetPlayerOfObject();
public uint PreviousPlayerId { get; set; }
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
}
public abstract class PlayerSyncObject : QSBNetworkBehaviour
{
public uint AttachedNetId => GetComponent<QSBNetworkIdentity>()?.NetId.Value ?? uint.MaxValue;
public uint PlayerId => this.GetPlayerOfObject();
public uint PreviousPlayerId { get; set; }
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
}
}

View File

@ -8,142 +8,142 @@ using System.Linq;
namespace QSB.Player
{
public static class QSBPlayerManager
{
public static uint LocalPlayerId => PlayerTransformSync.LocalInstance.GetComponent<QSBNetworkIdentity>()?.NetId.Value ?? uint.MaxValue;
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
public static class QSBPlayerManager
{
public static uint LocalPlayerId => PlayerTransformSync.LocalInstance.GetComponent<QSBNetworkIdentity>()?.NetId.Value ?? uint.MaxValue;
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
public static List<PlayerSyncObject> PlayerSyncObjects { get; } = new List<PlayerSyncObject>();
public static List<PlayerSyncObject> PlayerSyncObjects { get; } = new List<PlayerSyncObject>();
public static PlayerInfo GetPlayer(uint id)
{
if (id == uint.MaxValue || id == 0U)
{
return default;
}
var player = PlayerList.FirstOrDefault(x => x.PlayerId == id);
if (player != null)
{
return player;
}
DebugLog.DebugWrite($"Creating player id {id}", MessageType.Info);
player = new PlayerInfo(id);
PlayerList.Add(player);
return player;
}
public static PlayerInfo GetPlayer(uint id)
{
if (id == uint.MaxValue || id == 0U)
{
return default;
}
var player = PlayerList.FirstOrDefault(x => x.PlayerId == id);
if (player != null)
{
return player;
}
DebugLog.DebugWrite($"Creating player id {id}", MessageType.Info);
player = new PlayerInfo(id);
PlayerList.Add(player);
return player;
}
public static void RemovePlayer(uint id)
{
DebugLog.DebugWrite($"Removing player {GetPlayer(id).Name} id {id}", MessageType.Info);
PlayerList.Remove(GetPlayer(id));
}
public static void RemovePlayer(uint id)
{
DebugLog.DebugWrite($"Removing player {GetPlayer(id).Name} id {id}", MessageType.Info);
PlayerList.Remove(GetPlayer(id));
}
public static void RemoveAllPlayers()
{
DebugLog.DebugWrite($"Removing all players.", MessageType.Info);
PlayerList.Clear();
}
public static void RemoveAllPlayers()
{
DebugLog.DebugWrite($"Removing all players.", MessageType.Info);
PlayerList.Clear();
}
public static bool PlayerExists(uint id)
{
return id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
}
public static bool PlayerExists(uint id)
{
return id != uint.MaxValue && PlayerList.Any(x => x.PlayerId == id);
}
public static void HandleFullStateMessage(PlayerStateMessage message)
{
var player = GetPlayer(message.AboutId);
player.Name = message.PlayerName;
player.IsReady = message.PlayerReady;
player.State = message.PlayerState;
if (LocalPlayer.IsReady)
{
player.UpdateStateObjects();
}
}
public static void HandleFullStateMessage(PlayerStateMessage message)
{
var player = GetPlayer(message.AboutId);
player.Name = message.PlayerName;
player.IsReady = message.PlayerReady;
player.State = message.PlayerState;
if (LocalPlayer.IsReady)
{
player.UpdateStateObjects();
}
}
public static IEnumerable<T> GetSyncObjects<T>() where T : PlayerSyncObject
{
return PlayerSyncObjects.OfType<T>().Where(x => x != null);
}
public static IEnumerable<T> GetSyncObjects<T>() where T : PlayerSyncObject
{
return PlayerSyncObjects.OfType<T>().Where(x => x != null);
}
public static T GetSyncObject<T>(uint id) where T : PlayerSyncObject
{
return GetSyncObjects<T>().FirstOrDefault(x => x != null && x.AttachedNetId == id);
}
public static T GetSyncObject<T>(uint id) where T : PlayerSyncObject
{
return GetSyncObjects<T>().FirstOrDefault(x => x != null && x.AttachedNetId == id);
}
public static bool IsBelongingToLocalPlayer(uint id)
{
return id == LocalPlayerId ||
PlayerSyncObjects.Any(x => x != null && x.AttachedNetId == id && x.IsLocalPlayer);
}
public static bool IsBelongingToLocalPlayer(uint id)
{
return id == LocalPlayerId ||
PlayerSyncObjects.Any(x => x != null && x.AttachedNetId == id && x.IsLocalPlayer);
}
public static uint GetPlayerOfObject(this PlayerSyncObject syncObject)
{
if (PlayerList.Count == 0)
{
DebugLog.ToConsole($"Error - No players exist to find owner of object. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Error);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// Get all Player IDs
var playerIds = PlayerList.Select(x => x.PlayerId).ToList();
// Get highest ID below the given syncobject's netid. A netid cannot belong to a playerid above it, only below or equal to it.
var lowerBound = playerIds.Where(x => x <= syncObject.AttachedNetId).ToList().Max();
if (playerIds.Min() > syncObject.AttachedNetId)
{
DebugLog.ToConsole($"Warning - Minimum playerid is greater than syncobject's netid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// If the player list count is not the same as the count of the same type syncobject (eg. 3 players and 4 PlayerTransformSyncs)
// and the highest ID below the syncobject's id is the same as the highest player id.
if (PlayerList.Count != PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType()) && lowerBound == playerIds.Max())
{
// If the previous player id was not the error value, return it. To smooth over discrepancies between player list and object list.
if (syncObject.PreviousPlayerId != uint.MaxValue)
{
return syncObject.PreviousPlayerId;
}
// If the syncobject is a PlayerTransformSync, make a player.
if (syncObject.GetType() == typeof(PlayerTransformSync) && syncObject.AttachedNetId != 0U)
{
return GetPlayer(syncObject.AttachedNetId).PlayerId;
}
DebugLog.ToConsole($"Warning - Unequal player:syncobject count. ({PlayerList.Count}:{PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType())}) (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
if (syncObject.PreviousPlayerId == uint.MaxValue)
{
DebugLog.ToConsole($"Warning - Syncobject previously had uint.MaxValue as it's playerid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
}
syncObject.PreviousPlayerId = lowerBound;
return lowerBound;
}
public static uint GetPlayerOfObject(this PlayerSyncObject syncObject)
{
if (PlayerList.Count == 0)
{
DebugLog.ToConsole($"Error - No players exist to find owner of object. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Error);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// Get all Player IDs
var playerIds = PlayerList.Select(x => x.PlayerId).ToList();
// Get highest ID below the given syncobject's netid. A netid cannot belong to a playerid above it, only below or equal to it.
var lowerBound = playerIds.Where(x => x <= syncObject.AttachedNetId).ToList().Max();
if (playerIds.Min() > syncObject.AttachedNetId)
{
DebugLog.ToConsole($"Warning - Minimum playerid is greater than syncobject's netid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
// If the player list count is not the same as the count of the same type syncobject (eg. 3 players and 4 PlayerTransformSyncs)
// and the highest ID below the syncobject's id is the same as the highest player id.
if (PlayerList.Count != PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType()) && lowerBound == playerIds.Max())
{
// If the previous player id was not the error value, return it. To smooth over discrepancies between player list and object list.
if (syncObject.PreviousPlayerId != uint.MaxValue)
{
return syncObject.PreviousPlayerId;
}
// If the syncobject is a PlayerTransformSync, make a player.
if (syncObject.GetType() == typeof(PlayerTransformSync) && syncObject.AttachedNetId != 0U)
{
return GetPlayer(syncObject.AttachedNetId).PlayerId;
}
DebugLog.ToConsole($"Warning - Unequal player:syncobject count. ({PlayerList.Count}:{PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType())}) (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
syncObject.PreviousPlayerId = uint.MaxValue;
return uint.MaxValue;
}
if (syncObject.PreviousPlayerId == uint.MaxValue)
{
DebugLog.ToConsole($"Warning - Syncobject previously had uint.MaxValue as it's playerid. (Attached NetID : {syncObject.AttachedNetId})", MessageType.Warning);
}
syncObject.PreviousPlayerId = lowerBound;
return lowerBound;
}
public static List<uint> GetPlayerNetIds(PlayerInfo player)
{
if (PlayerSyncObjects.Count == 0)
{
return default;
}
int count = 0;
int totalCount = PlayerSyncObjects.Count;
PlayerSyncObjects.RemoveAll(x => x == null);
PlayerSyncObjects.RemoveAll(x => x.GetComponent<QSBNetworkIdentity>() == null);
if (PlayerSyncObjects.Count != totalCount)
{
DebugLog.ToConsole($"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects.", MessageType.Warning);
}
foreach (var item in PlayerSyncObjects.DistinctBy(x => x.AttachedNetId))
{
if (item.PlayerId == player.PlayerId)
{
count++;
}
}
return Enumerable.Range((int)player.PlayerId, count).Select(x => (uint)x).ToList();
}
}
public static List<uint> GetPlayerNetIds(PlayerInfo player)
{
if (PlayerSyncObjects.Count == 0)
{
return default;
}
int count = 0;
int totalCount = PlayerSyncObjects.Count;
PlayerSyncObjects.RemoveAll(x => x == null);
PlayerSyncObjects.RemoveAll(x => x.GetComponent<QSBNetworkIdentity>() == null);
if (PlayerSyncObjects.Count != totalCount)
{
DebugLog.ToConsole($"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects.", MessageType.Warning);
}
foreach (var item in PlayerSyncObjects.DistinctBy(x => x.AttachedNetId))
{
if (item.PlayerId == player.PlayerId)
{
count++;
}
}
return Enumerable.Range((int)player.PlayerId, count).Select(x => (uint)x).ToList();
}
}
}

View File

@ -15,92 +15,92 @@ using UnityEngine.Networking;
namespace QSB
{
public class QSB : ModBehaviour
{
public static IModBehaviour ModBehaviour { get; private set; }
public static IModHelper Helper { get; private set; }
public static string DefaultServerIP { get; private set; }
public static int Port { get; private set; }
public static bool DebugMode { get; private set; }
public static AssetBundle NetworkAssetBundle { get; private set; }
public static AssetBundle InstrumentAssetBundle { get; private set; }
public static bool HasWokenUp { get; set; }
public class QSB : ModBehaviour
{
public static IModBehaviour ModBehaviour { get; private set; }
public static IModHelper Helper { get; private set; }
public static string DefaultServerIP { get; private set; }
public static int Port { get; private set; }
public static bool DebugMode { get; private set; }
public static AssetBundle NetworkAssetBundle { get; private set; }
public static AssetBundle InstrumentAssetBundle { get; private set; }
public static bool HasWokenUp { get; set; }
private void Awake()
{
Application.runInBackground = true;
private void Awake()
{
Application.runInBackground = true;
var instance = TextTranslation.Get().GetValue<TextTranslation.TranslationTable>("m_table");
instance.theUITable[(int)UITextType.PleaseUseController] =
"<color=orange>Quantum Space Buddies</color> is best experienced with friends...";
var instance = TextTranslation.Get().GetValue<TextTranslation.TranslationTable>("m_table");
instance.theUITable[(int)UITextType.PleaseUseController] =
"<color=orange>Quantum Space Buddies</color> is best experienced with friends...";
ModBehaviour = this;
ModBehaviour = this;
LogFilter.currentLogLevel = LogFilter.Debug;
LogFilter.currentLogLevel = LogFilter.Debug;
// Application.logMessageReceived += Application_logMessageReceived;
}
// Application.logMessageReceived += Application_logMessageReceived;
}
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
switch (type)
{
case LogType.Assert:
DebugLog.DebugWrite($"Assert - {condition}", MessageType.Message);
break;
case LogType.Log:
DebugLog.DebugWrite($"Log - {condition}", MessageType.Message);
break;
case LogType.Warning:
DebugLog.DebugWrite($"Warning - {condition}", MessageType.Warning);
break;
}
}
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
{
switch (type)
{
case LogType.Assert:
DebugLog.DebugWrite($"Assert - {condition}", MessageType.Message);
break;
case LogType.Log:
DebugLog.DebugWrite($"Log - {condition}", MessageType.Message);
break;
case LogType.Warning:
DebugLog.DebugWrite($"Warning - {condition}", MessageType.Warning);
break;
}
}
private void Start()
{
Helper = ModHelper;
DebugLog.ToConsole($"* Start of QSB version {Helper.Manifest.Version} - authored by {Helper.Manifest.Author}", MessageType.Info);
private void Start()
{
Helper = ModHelper;
DebugLog.ToConsole($"* Start of QSB version {Helper.Manifest.Version} - authored by {Helper.Manifest.Author}", MessageType.Info);
NetworkAssetBundle = Helper.Assets.LoadBundle("assets/network");
InstrumentAssetBundle = Helper.Assets.LoadBundle("assets/instruments");
NetworkAssetBundle = Helper.Assets.LoadBundle("assets/network");
InstrumentAssetBundle = Helper.Assets.LoadBundle("assets/instruments");
QSBPatchManager.Init();
QSBPatchManager.Init();
QSBPatchManager.DoPatchType(QSBPatchTypes.OnModStart);
QSBPatchManager.DoPatchType(QSBPatchTypes.OnModStart);
// Turns out these are very finicky about what order they go. QSBNetworkManager seems to
// want to go first-ish, otherwise the NetworkManager complains about the PlayerPrefab being
// null (even though it isn't...)
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<QSBNetworkManagerHUD>();
gameObject.AddComponent<DebugActions>();
gameObject.AddComponent<ElevatorManager>();
gameObject.AddComponent<GeyserManager>();
gameObject.AddComponent<OrbManager>();
gameObject.AddComponent<QSBSectorManager>();
gameObject.AddComponent<ConversationManager>();
gameObject.AddComponent<QSBInputManager>();
gameObject.AddComponent<TimeSyncUI>();
// Turns out these are very finicky about what order they go. QSBNetworkManager seems to
// want to go first-ish, otherwise the NetworkManager complains about the PlayerPrefab being
// null (even though it isn't...)
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<QSBNetworkManagerHUD>();
gameObject.AddComponent<DebugActions>();
gameObject.AddComponent<ElevatorManager>();
gameObject.AddComponent<GeyserManager>();
gameObject.AddComponent<OrbManager>();
gameObject.AddComponent<QSBSectorManager>();
gameObject.AddComponent<ConversationManager>();
gameObject.AddComponent<QSBInputManager>();
gameObject.AddComponent<TimeSyncUI>();
// Stop players being able to pause
Helper.HarmonyHelper.EmptyMethod(typeof(OWTime).GetMethod("Pause"));
}
// Stop players being able to pause
Helper.HarmonyHelper.EmptyMethod(typeof(OWTime).GetMethod("Pause"));
}
void Update()
{
QSBNetworkIdentity.UNetStaticUpdate();
}
void Update()
{
QSBNetworkIdentity.UNetStaticUpdate();
}
public override void Configure(IModConfig config)
{
DefaultServerIP = config.GetSettingsValue<string>("defaultServerIP");
Port = config.GetSettingsValue<int>("port");
if (QSBNetworkManager.Instance != null)
{
QSBNetworkManager.Instance.networkPort = Port;
}
DebugMode = config.GetSettingsValue<bool>("debugMode");
}
}
public override void Configure(IModConfig config)
{
DefaultServerIP = config.GetSettingsValue<string>("defaultServerIP");
Port = config.GetSettingsValue<int>("port");
if (QSBNetworkManager.Instance != null)
{
QSBNetworkManager.Instance.networkPort = Port;
}
DebugMode = config.GetSettingsValue<bool>("debugMode");
}
}
}

View File

@ -2,53 +2,53 @@
namespace QSB
{
public delegate void InputEvent();
public delegate void InputEvent();
public class QSBInputManager : MonoBehaviour
{
public static QSBInputManager Instance;
public class QSBInputManager : MonoBehaviour
{
public static QSBInputManager Instance;
public static event InputEvent ChertTaunt;
public static event InputEvent EskerTaunt;
public static event InputEvent RiebeckTaunt;
public static event InputEvent GabbroTaunt;
public static event InputEvent FeldsparTaunt;
public static event InputEvent ExitTaunt;
public static event InputEvent ChertTaunt;
public static event InputEvent EskerTaunt;
public static event InputEvent RiebeckTaunt;
public static event InputEvent GabbroTaunt;
public static event InputEvent FeldsparTaunt;
public static event InputEvent ExitTaunt;
public void Awake() => Instance = this;
public void Awake() => Instance = this;
public void Update()
{
if (Input.GetKey(KeyCode.T))
{
// Listed order is from sun to dark bramble
if (Input.GetKeyDown(KeyCode.Alpha1))
{
ChertTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha2))
{
EskerTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha5))
{
RiebeckTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha4))
{
GabbroTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha3))
{
FeldsparTaunt?.Invoke();
}
}
public void Update()
{
if (Input.GetKey(KeyCode.T))
{
// Listed order is from sun to dark bramble
if (Input.GetKeyDown(KeyCode.Alpha1))
{
ChertTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha2))
{
EskerTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha5))
{
RiebeckTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha4))
{
GabbroTaunt?.Invoke();
}
else if (Input.GetKeyDown(KeyCode.Alpha3))
{
FeldsparTaunt?.Invoke();
}
}
if (OWInput.GetValue(InputLibrary.moveXZ, InputMode.None) != Vector2.zero
|| OWInput.GetValue(InputLibrary.jump, InputMode.None) != 0f)
{
ExitTaunt?.Invoke();
}
}
}
if (OWInput.GetValue(InputLibrary.moveXZ, InputMode.None) != Vector2.zero
|| OWInput.GetValue(InputLibrary.jump, InputMode.None) != 0f)
{
ExitTaunt?.Invoke();
}
}
}
}

View File

@ -6,65 +6,65 @@ using UnityEngine.Networking;
namespace QSB
{
public class QSBNetworkLobby : NetworkBehaviour
{
public bool CanEditName { get; set; }
public string PlayerName { get; private set; }
public class QSBNetworkLobby : NetworkBehaviour
{
public bool CanEditName { get; set; }
public string PlayerName { get; private set; }
private readonly string[] _defaultNames = {
"Arkose",
"Chert",
"Esker",
"Hal",
"Hornfels",
"Feldspar",
"Gabbro",
"Galena",
"Gneiss",
"Gossan",
"Marl",
"Mica",
"Moraine",
"Porphy",
"Riebeck",
"Rutile",
"Slate",
"Spinel",
"Tektite",
"Tephra",
"Tuff",
"Jinha"
};
private readonly string[] _defaultNames = {
"Arkose",
"Chert",
"Esker",
"Hal",
"Hornfels",
"Feldspar",
"Gabbro",
"Galena",
"Gneiss",
"Gossan",
"Marl",
"Mica",
"Moraine",
"Porphy",
"Riebeck",
"Rutile",
"Slate",
"Spinel",
"Tektite",
"Tephra",
"Tuff",
"Jinha"
};
private void Awake()
{
PlayerName = GetPlayerName();
CanEditName = true;
QSB.Helper.HarmonyHelper.EmptyMethod<NetworkManagerHUD>("Update");
}
private void Awake()
{
PlayerName = GetPlayerName();
CanEditName = true;
QSB.Helper.HarmonyHelper.EmptyMethod<NetworkManagerHUD>("Update");
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile?.profileName;
return !string.IsNullOrEmpty(profileName)
? profileName
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile?.profileName;
return !string.IsNullOrEmpty(profileName)
? profileName
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
}
private void OnGUI()
{
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
if (CanEditName)
{
PlayerName = GUI.TextField(new Rect(60, 10, 145, 20f), PlayerName);
}
else
{
GUI.Label(new Rect(60, 10, 145, 20f), PlayerName);
}
}
}
private void OnGUI()
{
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
if (CanEditName)
{
PlayerName = GUI.TextField(new Rect(60, 10, 145, 20f), PlayerName);
}
else
{
GUI.Label(new Rect(60, 10, 145, 20f), PlayerName);
}
}
}
}

View File

@ -22,291 +22,291 @@ using UnityEngine.Networking;
namespace QSB
{
public class QSBNetworkManager : QSBNetworkManagerUNET
{
private const int MaxConnections = 128;
private const int MaxBufferedPackets = 64;
public class QSBNetworkManager : QSBNetworkManagerUNET
{
private const int MaxConnections = 128;
private const int MaxBufferedPackets = 64;
public static QSBNetworkManager Instance { get; private set; }
public static QSBNetworkManager Instance { get; private set; }
public event Action OnNetworkManagerReady;
public bool IsReady { get; private set; }
public event Action OnNetworkManagerReady;
public bool IsReady { get; private set; }
private QSBNetworkLobby _lobby;
private AssetBundle _assetBundle;
private GameObject _shipPrefab;
private GameObject _cameraPrefab;
private GameObject _probePrefab;
public GameObject OrbPrefab;
private QSBNetworkLobby _lobby;
private AssetBundle _assetBundle;
private GameObject _shipPrefab;
private GameObject _cameraPrefab;
private GameObject _probePrefab;
public GameObject OrbPrefab;
private void Awake()
{
DebugLog.DebugWrite("AWAKE");
Instance = this;
private void Awake()
{
DebugLog.DebugWrite("AWAKE");
Instance = this;
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
_assetBundle = QSB.NetworkAssetBundle;
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
_assetBundle = QSB.NetworkAssetBundle;
DebugLog.DebugWrite("player");
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkplayer.prefab");
var ident = playerPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", playerPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", playerPrefab.GetComponent<NetworkIdentity>().sceneId);
playerPrefab.AddComponent<PlayerTransformSync>();
playerPrefab.AddComponent<AnimationSync>();
playerPrefab.AddComponent<WakeUpSync>();
playerPrefab.AddComponent<InstrumentsManager>();
DebugLog.DebugWrite("player");
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkplayer.prefab");
var ident = playerPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", playerPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", playerPrefab.GetComponent<NetworkIdentity>().sceneId);
playerPrefab.AddComponent<PlayerTransformSync>();
playerPrefab.AddComponent<AnimationSync>();
playerPrefab.AddComponent<WakeUpSync>();
playerPrefab.AddComponent<InstrumentsManager>();
DebugLog.DebugWrite("ship");
_shipPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkship.prefab");
ident = _shipPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _shipPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _shipPrefab.GetComponent<NetworkIdentity>().sceneId);
_shipPrefab.AddComponent<ShipTransformSync>();
spawnPrefabs.Add(_shipPrefab);
DebugLog.DebugWrite("ship");
_shipPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkship.prefab");
ident = _shipPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _shipPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _shipPrefab.GetComponent<NetworkIdentity>().sceneId);
_shipPrefab.AddComponent<ShipTransformSync>();
spawnPrefabs.Add(_shipPrefab);
DebugLog.DebugWrite("camera");
_cameraPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkcameraroot.prefab");
ident = _cameraPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _cameraPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _cameraPrefab.GetComponent<NetworkIdentity>().sceneId);
_cameraPrefab.AddComponent<PlayerCameraSync>();
spawnPrefabs.Add(_cameraPrefab);
DebugLog.DebugWrite("camera");
_cameraPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkcameraroot.prefab");
ident = _cameraPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _cameraPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _cameraPrefab.GetComponent<NetworkIdentity>().sceneId);
_cameraPrefab.AddComponent<PlayerCameraSync>();
spawnPrefabs.Add(_cameraPrefab);
DebugLog.DebugWrite("probe");
_probePrefab = _assetBundle.LoadAsset<GameObject>("assets/networkprobe.prefab");
ident = _probePrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _probePrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _probePrefab.GetComponent<NetworkIdentity>().sceneId);
_probePrefab.AddComponent<PlayerProbeSync>();
spawnPrefabs.Add(_probePrefab);
DebugLog.DebugWrite("probe");
_probePrefab = _assetBundle.LoadAsset<GameObject>("assets/networkprobe.prefab");
ident = _probePrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", _probePrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", _probePrefab.GetComponent<NetworkIdentity>().sceneId);
_probePrefab.AddComponent<PlayerProbeSync>();
spawnPrefabs.Add(_probePrefab);
DebugLog.DebugWrite("orb");
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
ident = OrbPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", OrbPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", OrbPrefab.GetComponent<NetworkIdentity>().sceneId);
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
spawnPrefabs.Add(OrbPrefab);
DebugLog.DebugWrite("orb");
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
ident = OrbPrefab.AddComponent<QSBNetworkIdentity>();
ident.LocalPlayerAuthority = true;
ident.SetValue("m_AssetId", OrbPrefab.GetComponent<NetworkIdentity>().assetId);
ident.SetValue("m_SceneId", OrbPrefab.GetComponent<NetworkIdentity>().sceneId);
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
spawnPrefabs.Add(OrbPrefab);
ConfigureNetworkManager();
QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
}
ConfigureNetworkManager();
QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
=> QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
private void OnDestroy()
=> QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
private void OnSceneLoaded(OWScene scene)
{
DebugLog.DebugWrite("scene loaded");
OrbManager.Instance.BuildOrbs();
OrbManager.Instance.QueueBuildSlots();
WorldRegistry.OldDialogueTrees.Clear();
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
}
private void OnSceneLoaded(OWScene scene)
{
DebugLog.DebugWrite("scene loaded");
OrbManager.Instance.BuildOrbs();
OrbManager.Instance.QueueBuildSlots();
WorldRegistry.OldDialogueTrees.Clear();
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
}
private void ConfigureNetworkManager()
{
networkAddress = QSB.DefaultServerIP;
networkPort = QSB.Port;
maxConnections = MaxConnections;
customConfig = true;
connectionConfig.AddChannel(QosType.Reliable);
connectionConfig.AddChannel(QosType.Unreliable);
this.SetValue("m_MaxBufferedPackets", MaxBufferedPackets);
channels.Add(QosType.Reliable);
channels.Add(QosType.Unreliable);
private void ConfigureNetworkManager()
{
networkAddress = QSB.DefaultServerIP;
networkPort = QSB.Port;
maxConnections = MaxConnections;
customConfig = true;
connectionConfig.AddChannel(QosType.Reliable);
connectionConfig.AddChannel(QosType.Unreliable);
this.SetValue("m_MaxBufferedPackets", MaxBufferedPackets);
channels.Add(QosType.Reliable);
channels.Add(QosType.Unreliable);
DebugLog.DebugWrite("Network Manager ready.", MessageType.Success);
}
DebugLog.DebugWrite("Network Manager ready.", MessageType.Success);
}
public override void OnStartServer()
{
DebugLog.DebugWrite("OnStartServer", MessageType.Info);
if (WorldRegistry.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
{
OrbManager.Instance.QueueBuildOrbs();
}
if (WorldRegistry.OldDialogueTrees.Count == 0 && QSBSceneManager.IsInUniverse)
{
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
}
public override void OnStartServer()
{
DebugLog.DebugWrite("OnStartServer", MessageType.Info);
if (WorldRegistry.OrbSyncList.Count == 0 && QSBSceneManager.IsInUniverse)
{
OrbManager.Instance.QueueBuildOrbs();
}
if (WorldRegistry.OldDialogueTrees.Count == 0 && QSBSceneManager.IsInUniverse)
{
WorldRegistry.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
}
QSBNetworkServer.UnregisterHandler(40);
QSBNetworkServer.UnregisterHandler(41);
QSBNetworkServer.UnregisterHandler(42);
QSBNetworkServer.RegisterHandler(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationServerMessage));
QSBNetworkServer.RegisterHandler(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersServerMessage));
QSBNetworkServer.RegisterHandler(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerServerMessage));
}
QSBNetworkServer.UnregisterHandler(40);
QSBNetworkServer.UnregisterHandler(41);
QSBNetworkServer.UnregisterHandler(42);
QSBNetworkServer.RegisterHandler(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationServerMessage));
QSBNetworkServer.RegisterHandler(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersServerMessage));
QSBNetworkServer.RegisterHandler(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerServerMessage));
}
public override void OnServerAddPlayer(QSBNetworkConnection connection, short playerControllerId) // Called on the server when a client joins
{
DebugLog.DebugWrite("OnServerAddPlayer", MessageType.Info);
base.OnServerAddPlayer(connection, playerControllerId);
public override void OnServerAddPlayer(QSBNetworkConnection connection, short playerControllerId) // Called on the server when a client joins
{
DebugLog.DebugWrite("OnServerAddPlayer", MessageType.Info);
base.OnServerAddPlayer(connection, playerControllerId);
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
}
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_shipPrefab), connection);
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_cameraPrefab), connection);
QSBNetworkServer.SpawnWithClientAuthority(Instantiate(_probePrefab), connection);
}
public override void OnClientConnect(QSBNetworkConnection connection) // Called on the client when connecting to a server
{
DebugLog.DebugWrite("OnClientConnect", MessageType.Info);
base.OnClientConnect(connection);
public override void OnClientConnect(QSBNetworkConnection connection) // Called on the client when connecting to a server
{
DebugLog.DebugWrite("OnClientConnect", MessageType.Info);
base.OnClientConnect(connection);
gameObject.AddComponent<SectorSync.SectorSync>();
gameObject.AddComponent<RespawnOnDeath>();
gameObject.AddComponent<PreventShipDestruction>();
gameObject.AddComponent<SectorSync.SectorSync>();
gameObject.AddComponent<RespawnOnDeath>();
gameObject.AddComponent<PreventShipDestruction>();
if (QSBSceneManager.IsInUniverse)
{
QSBSectorManager.Instance.RebuildSectors();
OrbManager.Instance.QueueBuildSlots();
}
if (QSBSceneManager.IsInUniverse)
{
QSBSectorManager.Instance.RebuildSectors();
OrbManager.Instance.QueueBuildSlots();
}
if (!QSBNetworkServer.localClientActive)
{
QSBPatchManager.DoPatchType(QSBPatchTypes.OnNonServerClientConnect);
singleton.client.UnregisterHandler(40);
singleton.client.UnregisterHandler(41);
singleton.client.RegisterHandlerSafe(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
singleton.client.RegisterHandlerSafe(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
}
singleton.client.UnregisterHandler(42);
singleton.client.RegisterHandlerSafe(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
if (!QSBNetworkServer.localClientActive)
{
QSBPatchManager.DoPatchType(QSBPatchTypes.OnNonServerClientConnect);
singleton.client.UnregisterHandler(40);
singleton.client.UnregisterHandler(41);
singleton.client.RegisterHandlerSafe(40, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationClientMessage));
singleton.client.RegisterHandlerSafe(41, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationParametersClientMessage));
}
singleton.client.UnregisterHandler(42);
singleton.client.RegisterHandlerSafe(42, new QSBNetworkMessageDelegate(QSBNetworkAnimator.OnAnimationTriggerClientMessage));
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
_lobby.CanEditName = false;
_lobby.CanEditName = false;
OnNetworkManagerReady?.Invoke();
IsReady = true;
OnNetworkManagerReady?.Invoke();
IsReady = true;
QSB.Helper.Events.Unity.RunWhen(() => PlayerTransformSync.LocalInstance != null, QSBEventManager.Init);
QSB.Helper.Events.Unity.RunWhen(() => PlayerTransformSync.LocalInstance != null, QSBEventManager.Init);
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
() => GlobalMessenger<string>.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
() => GlobalMessenger<string>.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
() => GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest));
}
QSB.Helper.Events.Unity.RunWhen(() => QSBEventManager.Ready,
() => GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest));
}
public override void OnStopClient() // Called on the client when closing connection
{
DebugLog.DebugWrite("OnStopClient", MessageType.Info);
DebugLog.ToConsole("Disconnecting from server...", MessageType.Info);
Destroy(GetComponent<SectorSync.SectorSync>());
Destroy(GetComponent<RespawnOnDeath>());
Destroy(GetComponent<PreventShipDestruction>());
QSBEventManager.Reset();
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
public override void OnStopClient() // Called on the client when closing connection
{
DebugLog.DebugWrite("OnStopClient", MessageType.Info);
DebugLog.ToConsole("Disconnecting from server...", MessageType.Info);
Destroy(GetComponent<SectorSync.SectorSync>());
Destroy(GetComponent<RespawnOnDeath>());
Destroy(GetComponent<PreventShipDestruction>());
QSBEventManager.Reset();
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
foreach (var player in QSBPlayerManager.PlayerList)
{
QSBPlayerManager.GetPlayerNetIds(player).ForEach(CleanupNetworkBehaviour);
}
QSBPlayerManager.RemoveAllPlayers();
foreach (var player in QSBPlayerManager.PlayerList)
{
QSBPlayerManager.GetPlayerNetIds(player).ForEach(CleanupNetworkBehaviour);
}
QSBPlayerManager.RemoveAllPlayers();
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
WorldRegistry.OrbSyncList.Clear();
WorldRegistry.OldDialogueTrees.Clear();
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
WorldRegistry.OrbSyncList.Clear();
WorldRegistry.OldDialogueTrees.Clear();
_lobby.CanEditName = true;
}
_lobby.CanEditName = true;
}
public override void OnServerDisconnect(QSBNetworkConnection connection) // Called on the server when any client disconnects
{
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
var player = connection.GetPlayer();
var netIds = connection.ClientOwnedObjects.Select(x => x.Value).ToArray();
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, player.PlayerId, netIds);
public override void OnServerDisconnect(QSBNetworkConnection connection) // Called on the server when any client disconnects
{
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
var player = connection.GetPlayer();
var netIds = connection.ClientOwnedObjects.Select(x => x.Value).ToArray();
GlobalMessenger<uint, uint[]>.FireEvent(EventNames.QSBPlayerLeave, player.PlayerId, netIds);
foreach (var item in WorldRegistry.OrbSyncList)
{
var identity = item.GetComponent<QSBNetworkIdentity>();
if (identity.ClientAuthorityOwner == connection)
{
identity.RemoveClientAuthority(connection);
}
}
foreach (var item in WorldRegistry.OrbSyncList)
{
var identity = item.GetComponent<QSBNetworkIdentity>();
if (identity.ClientAuthorityOwner == connection)
{
identity.RemoveClientAuthority(connection);
}
}
player.HudMarker?.Remove();
CleanupConnection(connection);
}
player.HudMarker?.Remove();
CleanupConnection(connection);
}
public override void OnStopServer()
{
DebugLog.DebugWrite("OnStopServer", MessageType.Info);
Destroy(GetComponent<SectorSync.SectorSync>());
Destroy(GetComponent<RespawnOnDeath>());
Destroy(GetComponent<PreventShipDestruction>());
QSBEventManager.Reset();
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
QSBNetworkServer.connections.ToList().ForEach(CleanupConnection);
public override void OnStopServer()
{
DebugLog.DebugWrite("OnStopServer", MessageType.Info);
Destroy(GetComponent<SectorSync.SectorSync>());
Destroy(GetComponent<RespawnOnDeath>());
Destroy(GetComponent<PreventShipDestruction>());
QSBEventManager.Reset();
DebugLog.ToConsole("[S] Server stopped!", MessageType.Info);
QSBPlayerManager.PlayerList.ForEach(player => player.HudMarker?.Remove());
QSBNetworkServer.connections.ToList().ForEach(CleanupConnection);
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
WorldRegistry.RemoveObjects<QSBOrbSlot>();
WorldRegistry.RemoveObjects<QSBElevator>();
WorldRegistry.RemoveObjects<QSBGeyser>();
WorldRegistry.RemoveObjects<QSBSector>();
base.OnStopServer();
}
base.OnStopServer();
}
private void CleanupConnection(QSBNetworkConnection connection)
{
var player = connection.GetPlayer();
DebugLog.ToConsole($"{player.Name} disconnected.", MessageType.Info);
QSBPlayerManager.RemovePlayer(player.PlayerId);
private void CleanupConnection(QSBNetworkConnection connection)
{
var player = connection.GetPlayer();
DebugLog.ToConsole($"{player.Name} disconnected.", MessageType.Info);
QSBPlayerManager.RemovePlayer(player.PlayerId);
var netIds = connection.ClientOwnedObjects?.Select(x => x.Value).ToList();
netIds.ForEach(CleanupNetworkBehaviour);
}
var netIds = connection.ClientOwnedObjects?.Select(x => x.Value).ToList();
netIds.ForEach(CleanupNetworkBehaviour);
}
public void CleanupNetworkBehaviour(uint netId)
{
DebugLog.DebugWrite($"Cleaning up netId {netId}");
// Multiple networkbehaviours can use the same networkidentity (same netId), so get all of them
var networkBehaviours = FindObjectsOfType<QSBNetworkBehaviour>()
.Where(x => x != null && x.NetId.Value == netId);
foreach (var networkBehaviour in networkBehaviours)
{
var transformSync = networkBehaviour.GetComponent<TransformSync.TransformSync>();
public void CleanupNetworkBehaviour(uint netId)
{
DebugLog.DebugWrite($"Cleaning up netId {netId}");
// Multiple networkbehaviours can use the same networkidentity (same netId), so get all of them
var networkBehaviours = FindObjectsOfType<QSBNetworkBehaviour>()
.Where(x => x != null && x.NetId.Value == netId);
foreach (var networkBehaviour in networkBehaviours)
{
var transformSync = networkBehaviour.GetComponent<TransformSync.TransformSync>();
if (transformSync != null)
{
DebugLog.DebugWrite($" * Removing TransformSync from syncobjects");
QSBPlayerManager.PlayerSyncObjects.Remove(transformSync);
if (transformSync.SyncedTransform != null && netId != QSBPlayerManager.LocalPlayerId && !networkBehaviour.HasAuthority)
{
DebugLog.DebugWrite($" * Destroying {transformSync.SyncedTransform.gameObject.name}");
Destroy(transformSync.SyncedTransform.gameObject);
}
}
if (transformSync != null)
{
DebugLog.DebugWrite($" * Removing TransformSync from syncobjects");
QSBPlayerManager.PlayerSyncObjects.Remove(transformSync);
if (transformSync.SyncedTransform != null && netId != QSBPlayerManager.LocalPlayerId && !networkBehaviour.HasAuthority)
{
DebugLog.DebugWrite($" * Destroying {transformSync.SyncedTransform.gameObject.name}");
Destroy(transformSync.SyncedTransform.gameObject);
}
}
var animationSync = networkBehaviour.GetComponent<AnimationSync>();
var animationSync = networkBehaviour.GetComponent<AnimationSync>();
if (animationSync != null)
{
DebugLog.DebugWrite($" * Removing AnimationSync from syncobjects");
QSBPlayerManager.PlayerSyncObjects.Remove(animationSync);
}
if (animationSync != null)
{
DebugLog.DebugWrite($" * Removing AnimationSync from syncobjects");
QSBPlayerManager.PlayerSyncObjects.Remove(animationSync);
}
if (!networkBehaviour.HasAuthority)
{
DebugLog.DebugWrite($" * Destroying {networkBehaviour.gameObject.name}");
Destroy(networkBehaviour.gameObject);
}
}
}
}
if (!networkBehaviour.HasAuthority)
{
DebugLog.DebugWrite($" * Destroying {networkBehaviour.gameObject.name}");
Destroy(networkBehaviour.gameObject);
}
}
}
}
}

View File

@ -4,33 +4,33 @@ using System;
namespace QSB
{
public static class QSBSceneManager
{
public static OWScene CurrentScene => LoadManager.GetCurrentScene();
public static class QSBSceneManager
{
public static OWScene CurrentScene => LoadManager.GetCurrentScene();
public static bool IsInUniverse => InUniverse(CurrentScene);
public static bool IsInUniverse => InUniverse(CurrentScene);
public static event Action<OWScene, bool> OnSceneLoaded;
public static event Action<OWScene> OnUniverseSceneLoaded;
public static event Action<OWScene, bool> OnSceneLoaded;
public static event Action<OWScene> OnUniverseSceneLoaded;
static QSBSceneManager()
{
LoadManager.OnCompleteSceneLoad += OnCompleteSceneLoad;
DebugLog.DebugWrite("Scene Manager ready.", MessageType.Success);
}
static QSBSceneManager()
{
LoadManager.OnCompleteSceneLoad += OnCompleteSceneLoad;
DebugLog.DebugWrite("Scene Manager ready.", MessageType.Success);
}
private static void OnCompleteSceneLoad(OWScene oldScene, OWScene newScene)
{
DebugLog.DebugWrite($"COMPLETE SCENE LOAD ({oldScene} -> {newScene})", MessageType.Info);
var universe = InUniverse(newScene);
OnSceneLoaded?.Invoke(newScene, universe);
if (universe)
{
OnUniverseSceneLoaded?.Invoke(newScene);
}
}
private static void OnCompleteSceneLoad(OWScene oldScene, OWScene newScene)
{
DebugLog.DebugWrite($"COMPLETE SCENE LOAD ({oldScene} -> {newScene})", MessageType.Info);
var universe = InUniverse(newScene);
OnSceneLoaded?.Invoke(newScene, universe);
if (universe)
{
OnUniverseSceneLoaded?.Invoke(newScene);
}
}
private static bool InUniverse(OWScene scene)
=> scene == OWScene.SolarSystem || scene == OWScene.EyeOfTheUniverse;
}
private static bool InUniverse(OWScene scene)
=> scene == OWScene.SolarSystem || scene == OWScene.EyeOfTheUniverse;
}
}

View File

@ -3,23 +3,23 @@ using QSB.QuantumUNET;
namespace QSB.TimeSync
{
public class PreserveTimeScale : QSBNetworkBehaviour
{
private void Start()
{
QSB.Helper.Menus.PauseMenu.GetTitleButton("Button-EndCurrentLoop").Hide(); // Remove the meditation button
public class PreserveTimeScale : QSBNetworkBehaviour
{
private void Start()
{
QSB.Helper.Menus.PauseMenu.GetTitleButton("Button-EndCurrentLoop").Hide(); // Remove the meditation button
// Allow server to sleep at campfires
if (IsServer)
{
return;
}
// Allow server to sleep at campfires
if (IsServer)
{
return;
}
var campfires = FindObjectsOfType<Campfire>();
foreach (var campfire in campfires)
{
campfire.SetValue("_canSleepHere", false); // Stop players from sleeping at campfires
}
}
}
var campfires = FindObjectsOfType<Campfire>();
foreach (var campfire in campfires)
{
campfire.SetValue("_canSleepHere", false); // Stop players from sleeping at campfires
}
}
}
}

View File

@ -7,250 +7,250 @@ using UnityEngine;
namespace QSB.TimeSync
{
public class WakeUpSync : QSBNetworkBehaviour
{
public static WakeUpSync LocalInstance { get; private set; }
public class WakeUpSync : QSBNetworkBehaviour
{
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 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 }
private State _state = State.NotLoaded;
private enum State { NotLoaded, Loaded, FastForwarding, Pausing }
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;
private float _sendTimer;
private float _serverTime;
private float _timeScale;
private bool _isInputEnabled = true;
private bool _isFirstFastForward = true;
private int _localLoopCount;
private int _serverLoopCount;
public override void OnStartLocalPlayer()
{
LocalInstance = this;
}
public override void OnStartLocalPlayer()
{
LocalInstance = this;
}
private void Start()
{
if (!IsLocalPlayer)
{
return;
}
private void Start()
{
if (!IsLocalPlayer)
{
return;
}
if (QSBSceneManager.IsInUniverse)
{
Init();
}
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
if (QSBSceneManager.IsInUniverse)
{
Init();
}
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
GlobalMessenger.AddListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.AddListener(EventNames.WakeUp, OnWakeUp);
}
private void OnWakeUp()
{
DebugLog.DebugWrite("ON WAKE UP!");
if (QSBNetworkServer.active)
{
QSB.HasWokenUp = true;
}
}
private void OnWakeUp()
{
DebugLog.DebugWrite("ON WAKE UP!");
if (QSBNetworkServer.active)
{
QSB.HasWokenUp = true;
}
}
private void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
GlobalMessenger.RemoveListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.RemoveListener(EventNames.WakeUp, OnWakeUp);
}
private void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
GlobalMessenger.RemoveListener(EventNames.RestartTimeLoop, OnLoopStart);
GlobalMessenger.RemoveListener(EventNames.WakeUp, OnWakeUp);
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
QSB.HasWokenUp = (scene == OWScene.EyeOfTheUniverse);
if (isInUniverse)
{
Init();
}
else
{
_state = State.NotLoaded;
}
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
QSB.HasWokenUp = (scene == OWScene.EyeOfTheUniverse);
if (isInUniverse)
{
Init();
}
else
{
_state = State.NotLoaded;
}
}
private void OnLoopStart()
{
_localLoopCount++;
}
private void OnLoopStart()
{
_localLoopCount++;
}
private void Init()
{
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
_state = State.Loaded;
gameObject.AddComponent<PreserveTimeScale>();
if (IsServer)
{
SendServerTime();
}
else
{
WakeUpOrSleep();
}
}
private void Init()
{
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
_state = State.Loaded;
gameObject.AddComponent<PreserveTimeScale>();
if (IsServer)
{
SendServerTime();
}
else
{
WakeUpOrSleep();
}
}
private void SendServerTime()
{
GlobalMessenger<float, int>.FireEvent(EventNames.QSBServerTime, Time.timeSinceLevelLoad, _localLoopCount);
}
private void SendServerTime()
{
GlobalMessenger<float, int>.FireEvent(EventNames.QSBServerTime, Time.timeSinceLevelLoad, _localLoopCount);
}
public void OnClientReceiveMessage(ServerTimeMessage message)
{
_serverTime = message.ServerTime;
_serverLoopCount = message.LoopCount;
WakeUpOrSleep();
}
public void OnClientReceiveMessage(ServerTimeMessage message)
{
_serverTime = message.ServerTime;
_serverLoopCount = message.LoopCount;
WakeUpOrSleep();
}
private void WakeUpOrSleep()
{
if (_state == State.NotLoaded || _localLoopCount != _serverLoopCount)
{
return;
}
private void WakeUpOrSleep()
{
if (_state == State.NotLoaded || _localLoopCount != _serverLoopCount)
{
return;
}
var myTime = Time.timeSinceLevelLoad;
var diff = myTime - _serverTime;
var myTime = Time.timeSinceLevelLoad;
var diff = myTime - _serverTime;
if (diff > TimeThreshold)
{
StartPausing();
return;
}
if (diff > TimeThreshold)
{
StartPausing();
return;
}
if (diff < -TimeThreshold)
{
StartFastForwarding();
}
}
if (diff < -TimeThreshold)
{
StartFastForwarding();
}
}
private void StartFastForwarding()
{
if (_state == State.FastForwarding)
{
return;
}
_timeScale = MaxFastForwardSpeed;
_state = State.FastForwarding;
TimeSyncUI.Start(TimeSyncType.Fastforwarding);
}
private void StartFastForwarding()
{
if (_state == State.FastForwarding)
{
return;
}
_timeScale = MaxFastForwardSpeed;
_state = State.FastForwarding;
TimeSyncUI.Start(TimeSyncType.Fastforwarding);
}
private void StartPausing()
{
if (_state == State.Pausing)
{
return;
}
_timeScale = 0f;
_state = State.Pausing;
SpinnerUI.Show();
TimeSyncUI.Start(TimeSyncType.Pausing);
}
private void StartPausing()
{
if (_state == State.Pausing)
{
return;
}
_timeScale = 0f;
_state = State.Pausing;
SpinnerUI.Show();
TimeSyncUI.Start(TimeSyncType.Pausing);
}
private void ResetTimeScale()
{
_timeScale = 1f;
_state = State.Loaded;
private void ResetTimeScale()
{
_timeScale = 1f;
_state = State.Loaded;
if (!_isInputEnabled)
{
EnableInput();
}
_isFirstFastForward = false;
QSB.HasWokenUp = true;
Physics.SyncTransforms();
SpinnerUI.Hide();
TimeSyncUI.Stop();
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
RespawnOnDeath.Instance.Init();
}
if (!_isInputEnabled)
{
EnableInput();
}
_isFirstFastForward = false;
QSB.HasWokenUp = true;
Physics.SyncTransforms();
SpinnerUI.Hide();
TimeSyncUI.Stop();
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
RespawnOnDeath.Instance.Init();
}
private void DisableInput()
{
_isInputEnabled = false;
OWInput.ChangeInputMode(InputMode.None);
}
private void DisableInput()
{
_isInputEnabled = false;
OWInput.ChangeInputMode(InputMode.None);
}
private void EnableInput()
{
_isInputEnabled = true;
OWInput.ChangeInputMode(InputMode.Character);
}
private void EnableInput()
{
_isInputEnabled = true;
OWInput.ChangeInputMode(InputMode.Character);
}
private void Update()
{
if (IsServer)
{
UpdateServer();
}
else if (IsLocalPlayer)
{
UpdateLocal();
}
}
private void Update()
{
if (IsServer)
{
UpdateServer();
}
else if (IsLocalPlayer)
{
UpdateLocal();
}
}
private void UpdateServer()
{
if (_state != State.Loaded)
{
return;
}
private void UpdateServer()
{
if (_state != State.Loaded)
{
return;
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer > 1)
{
SendServerTime();
_sendTimer = 0;
}
}
_sendTimer += Time.unscaledDeltaTime;
if (_sendTimer > 1)
{
SendServerTime();
_sendTimer = 0;
}
}
private void UpdateLocal()
{
_serverTime += Time.unscaledDeltaTime;
private void UpdateLocal()
{
_serverTime += Time.unscaledDeltaTime;
if (_state == State.NotLoaded)
{
return;
}
if (_state == State.NotLoaded)
{
return;
}
if (_state == State.FastForwarding)
{
var diff = _serverTime - Time.timeSinceLevelLoad;
Time.timeScale = Mathf.Lerp(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff);
if (_state == State.FastForwarding)
{
var diff = _serverTime - Time.timeSinceLevelLoad;
Time.timeScale = Mathf.Lerp(MinFastForwardSpeed, MaxFastForwardSpeed, Mathf.Abs(diff) / MaxFastForwardDiff);
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;
}
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;
var isDoneFastForwarding = _state == State.FastForwarding && Time.timeSinceLevelLoad >= _serverTime;
var isDonePausing = _state == State.Pausing && Time.timeSinceLevelLoad < _serverTime;
if (isDoneFastForwarding || isDonePausing)
{
ResetTimeScale();
}
if (isDoneFastForwarding || isDonePausing)
{
ResetTimeScale();
}
if (!_isInputEnabled && OWInput.GetInputMode() != InputMode.None)
{
DisableInput();
}
}
}
if (!_isInputEnabled && OWInput.GetInputMode() != InputMode.None)
{
DisableInput();
}
}
}
}

View File

@ -5,95 +5,95 @@ using UnityEngine;
namespace QSB.TransformSync
{
public class NomaiOrbTransformSync : QSBNetworkBehaviour
{
public NomaiInterfaceOrb AttachedOrb { get; private set; }
public Transform OrbTransform { get; private set; }
public class NomaiOrbTransformSync : QSBNetworkBehaviour
{
public NomaiInterfaceOrb AttachedOrb { get; private set; }
public Transform OrbTransform { get; private set; }
private int Index => WorldRegistry.OrbSyncList.IndexOf(this);
private int Index => WorldRegistry.OrbSyncList.IndexOf(this);
private const int MaxUpdatesBeforeDisable = 5;
private const int MaxUpdatesBeforeDisable = 5;
private bool _isInitialized;
private bool _isReady;
private Transform _orbParent;
private int _updateCount;
private bool _isInitialized;
private bool _isReady;
private Transform _orbParent;
private int _updateCount;
public override void OnStartClient()
{
DontDestroyOnLoad(this);
WorldRegistry.OrbSyncList.Add(this);
public override void OnStartClient()
{
DontDestroyOnLoad(this);
WorldRegistry.OrbSyncList.Add(this);
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, () => QSB.Helper.Events.Unity.FireOnNextUpdate(OnReady));
}
QSB.Helper.Events.Unity.RunWhen(() => QSB.HasWokenUp, () => QSB.Helper.Events.Unity.FireOnNextUpdate(OnReady));
}
public override void OnStartAuthority()
{
DebugLog.DebugWrite("START AUTHORITY - has auth? : " + HasAuthority);
}
public override void OnStartAuthority()
{
DebugLog.DebugWrite("START AUTHORITY - has auth? : " + HasAuthority);
}
public override void OnStopAuthority()
{
DebugLog.DebugWrite("END AUTHORITY - has auth? : " + HasAuthority);
}
public override void OnStopAuthority()
{
DebugLog.DebugWrite("END AUTHORITY - has auth? : " + HasAuthority);
}
private void OnReady()
{
AttachedOrb = WorldRegistry.OldOrbList[Index];
_isReady = true;
}
private void OnReady()
{
AttachedOrb = WorldRegistry.OldOrbList[Index];
_isReady = true;
}
private void OnDestroy()
{
WorldRegistry.OrbSyncList.Remove(this);
}
private void OnDestroy()
{
WorldRegistry.OrbSyncList.Remove(this);
}
protected void Init()
{
OrbTransform = AttachedOrb.transform;
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
_isInitialized = true;
}
protected void Init()
{
OrbTransform = AttachedOrb.transform;
_orbParent = AttachedOrb.GetAttachedOWRigidbody().GetOrigParent();
_isInitialized = true;
}
private void Update()
{
if (!_isInitialized && _isReady)
{
Init();
}
else if (_isInitialized && !_isReady)
{
_isInitialized = false;
}
private void Update()
{
if (!_isInitialized && _isReady)
{
Init();
}
else if (_isInitialized && !_isReady)
{
_isInitialized = false;
}
if (OrbTransform == null || !_isInitialized)
{
return;
}
if (OrbTransform == null || !_isInitialized)
{
return;
}
UpdateTransform();
}
UpdateTransform();
}
protected virtual void UpdateTransform()
{
if (HasAuthority)
{
transform.position = _orbParent.InverseTransformPoint(OrbTransform.position);
transform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
return;
}
OrbTransform.position = _orbParent.TransformPoint(transform.position);
OrbTransform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
protected virtual void UpdateTransform()
{
if (HasAuthority)
{
transform.position = _orbParent.InverseTransformPoint(OrbTransform.position);
transform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
return;
}
OrbTransform.position = _orbParent.TransformPoint(transform.position);
OrbTransform.rotation = _orbParent.InverseTransformRotation(OrbTransform.rotation);
if (transform.localPosition == Vector3.zero)
{
_updateCount++;
}
if (_updateCount >= MaxUpdatesBeforeDisable)
{
enabled = false;
_updateCount = 0;
}
}
}
if (transform.localPosition == Vector3.zero)
{
_updateCount++;
}
if (_updateCount >= MaxUpdatesBeforeDisable)
{
enabled = false;
_updateCount = 0;
}
}
}
}

View File

@ -7,45 +7,45 @@ using UnityEngine;
namespace QSB.TransformSync
{
public class PlayerCameraSync : TransformSync
{
public static PlayerCameraSync LocalInstance { get; private set; }
public class PlayerCameraSync : TransformSync
{
public static PlayerCameraSync LocalInstance { get; private set; }
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
protected override Transform InitLocalTransform()
{
var body = Locator.GetPlayerCamera().gameObject.transform;
protected override Transform InitLocalTransform()
{
var body = Locator.GetPlayerCamera().gameObject.transform;
Player.Camera = body.gameObject;
Player.Camera = body.gameObject;
Player.IsReady = true;
GlobalMessenger<bool>.FireEvent(EventNames.QSBPlayerReady, true);
DebugLog.DebugWrite("PlayerCameraSync init done - Request state!");
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
Player.IsReady = true;
GlobalMessenger<bool>.FireEvent(EventNames.QSBPlayerReady, true);
DebugLog.DebugWrite("PlayerCameraSync init done - Request state!");
GlobalMessenger.FireEvent(EventNames.QSBPlayerStatesRequest);
return body;
}
return body;
}
protected override Transform InitRemoteTransform()
{
var body = new GameObject("RemotePlayerCamera");
protected override Transform InitRemoteTransform()
{
var body = new GameObject("RemotePlayerCamera");
PlayerToolsManager.Init(body.transform);
PlayerToolsManager.Init(body.transform);
Player.Camera = body;
Player.Camera = body;
return body.transform;
}
return body.transform;
}
public override bool IsReady => Locator.GetPlayerTransform() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
public override bool IsReady => Locator.GetPlayerTransform() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
}

View File

@ -6,96 +6,96 @@ using UnityEngine;
namespace QSB.TransformSync
{
public class PlayerProbeSync : TransformSync
{
public static PlayerProbeSync LocalInstance { get; private set; }
public class PlayerProbeSync : TransformSync
{
public static PlayerProbeSync LocalInstance { get; private set; }
private Transform _disabledSocket;
private Transform _disabledSocket;
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
private Transform GetProbe()
{
return Locator.GetProbe().transform.Find("CameraPivot").Find("Geometry");
}
private Transform GetProbe()
{
return Locator.GetProbe().transform.Find("CameraPivot").Find("Geometry");
}
protected override Transform InitLocalTransform()
{
var body = GetProbe();
protected override Transform InitLocalTransform()
{
var body = GetProbe();
SetSocket(Player.Camera.transform);
Player.ProbeBody = body.gameObject;
SetSocket(Player.Camera.transform);
Player.ProbeBody = body.gameObject;
return body;
}
return body;
}
protected override Transform InitRemoteTransform()
{
var probe = GetProbe();
protected override Transform InitRemoteTransform()
{
var probe = GetProbe();
if (probe == null)
{
DebugLog.ToConsole("Error - Probe is null!", MessageType.Error);
return default;
}
if (probe == null)
{
DebugLog.ToConsole("Error - Probe is null!", MessageType.Error);
return default;
}
var body = probe.InstantiateInactive();
body.name = "RemoteProbeTransform";
var body = probe.InstantiateInactive();
body.name = "RemoteProbeTransform";
Destroy(body.GetComponentInChildren<ProbeAnimatorController>());
Destroy(body.GetComponentInChildren<ProbeAnimatorController>());
PlayerToolsManager.CreateProbe(body, Player);
PlayerToolsManager.CreateProbe(body, Player);
QSB.Helper.Events.Unity.RunWhen(() => (Player.ProbeLauncher != null), () => SetSocket(Player.ProbeLauncher.ToolGameObject.transform));
Player.ProbeBody = body.gameObject;
QSB.Helper.Events.Unity.RunWhen(() => (Player.ProbeLauncher != null), () => SetSocket(Player.ProbeLauncher.ToolGameObject.transform));
Player.ProbeBody = body.gameObject;
return body;
}
return body;
}
private void SetSocket(Transform socket)
{
DebugLog.DebugWrite($"Setting DisabledSocket for {AttachedNetId} to {socket.name}");
_disabledSocket = socket;
}
private void SetSocket(Transform socket)
{
DebugLog.DebugWrite($"Setting DisabledSocket for {AttachedNetId} to {socket.name}");
_disabledSocket = socket;
}
protected override void UpdateTransform()
{
base.UpdateTransform();
if (Player == null)
{
DebugLog.ToConsole($"Player is null for {AttachedNetId}!", MessageType.Error);
return;
}
if (_disabledSocket == null)
{
DebugLog.ToConsole($"DisabledSocket is null for {AttachedNetId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
return;
}
if (Player.GetState(State.ProbeActive) || ReferenceSector?.Sector == null)
{
return;
}
if (HasAuthority)
{
transform.position = ReferenceSector.Transform.InverseTransformPoint(_disabledSocket.position);
return;
}
if (SyncedTransform.position == Vector3.zero)
{
return;
}
SyncedTransform.localPosition = ReferenceSector.Transform.InverseTransformPoint(_disabledSocket.position);
}
protected override void UpdateTransform()
{
base.UpdateTransform();
if (Player == null)
{
DebugLog.ToConsole($"Player is null for {AttachedNetId}!", MessageType.Error);
return;
}
if (_disabledSocket == null)
{
DebugLog.ToConsole($"DisabledSocket is null for {AttachedNetId}! (ProbeLauncher null? : {Player.ProbeLauncher == null})", MessageType.Error);
return;
}
if (Player.GetState(State.ProbeActive) || ReferenceSector?.Sector == null)
{
return;
}
if (HasAuthority)
{
transform.position = ReferenceSector.Transform.InverseTransformPoint(_disabledSocket.position);
return;
}
if (SyncedTransform.position == Vector3.zero)
{
return;
}
SyncedTransform.localPosition = ReferenceSector.Transform.InverseTransformPoint(_disabledSocket.position);
}
public override bool IsReady => Locator.GetProbe() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
public override bool IsReady => Locator.GetProbe() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
}

View File

@ -7,59 +7,59 @@ using UnityEngine;
namespace QSB.TransformSync
{
public class PlayerTransformSync : TransformSync
{
public static PlayerTransformSync LocalInstance { get; private set; }
public class PlayerTransformSync : TransformSync
{
public static PlayerTransformSync LocalInstance { get; private set; }
static PlayerTransformSync()
{
DebugLog.DebugWrite("Constructor", MessageType.Info);
AnimControllerPatch.Init();
}
static PlayerTransformSync()
{
DebugLog.DebugWrite("Constructor", MessageType.Info);
AnimControllerPatch.Init();
}
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
private Transform GetPlayerModel()
{
return Locator.GetPlayerTransform().Find("Traveller_HEA_Player_v2");
}
private Transform GetPlayerModel()
{
return Locator.GetPlayerTransform().Find("Traveller_HEA_Player_v2");
}
protected override Transform InitLocalTransform()
{
var body = GetPlayerModel();
protected override Transform InitLocalTransform()
{
var body = GetPlayerModel();
GetComponent<AnimationSync>().InitLocal(body);
GetComponent<InstrumentsManager>().InitLocal(body);
GetComponent<AnimationSync>().InitLocal(body);
GetComponent<InstrumentsManager>().InitLocal(body);
Player.Body = body.gameObject;
Player.Body = body.gameObject;
return body;
}
return body;
}
protected override Transform InitRemoteTransform()
{
var body = Instantiate(GetPlayerModel());
protected override Transform InitRemoteTransform()
{
var body = Instantiate(GetPlayerModel());
GetComponent<AnimationSync>().InitRemote(body);
GetComponent<InstrumentsManager>().InitRemote(body);
GetComponent<AnimationSync>().InitRemote(body);
GetComponent<InstrumentsManager>().InitRemote(body);
var marker = body.gameObject.AddComponent<PlayerHUDMarker>();
marker.Init(Player);
var marker = body.gameObject.AddComponent<PlayerHUDMarker>();
marker.Init(Player);
Player.Body = body.gameObject;
Player.Body = body.gameObject;
return body;
}
return body;
}
public override bool IsReady => Locator.GetPlayerTransform() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
public override bool IsReady => Locator.GetPlayerTransform() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
}

View File

@ -5,59 +5,59 @@ using UnityEngine;
namespace QSB.TransformSync
{
public class ShipTransformSync : TransformSync
{
public static ShipTransformSync LocalInstance { get; private set; }
public class ShipTransformSync : TransformSync
{
public static ShipTransformSync LocalInstance { get; private set; }
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
public override void OnStartLocalPlayer()
{
DebugLog.DebugWrite("OnStartLocalPlayer", MessageType.Info);
LocalInstance = this;
}
private Transform GetShipModel()
{
return Locator.GetShipTransform();
}
private Transform GetShipModel()
{
return Locator.GetShipTransform();
}
protected override Transform InitLocalTransform()
{
return GetShipModel().Find("Module_Cockpit/Geo_Cockpit/Cockpit_Geometry/Cockpit_Exterior");
}
protected override Transform InitLocalTransform()
{
return GetShipModel().Find("Module_Cockpit/Geo_Cockpit/Cockpit_Geometry/Cockpit_Exterior");
}
protected override Transform InitRemoteTransform()
{
var shipModel = GetShipModel();
protected override Transform InitRemoteTransform()
{
var shipModel = GetShipModel();
var remoteTransform = new GameObject("RemoteShipTransform").transform;
var remoteTransform = new GameObject("RemoteShipTransform").transform;
Instantiate(shipModel.Find("Module_Cockpit/Geo_Cockpit/Cockpit_Geometry/Cockpit_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Cabin/Geo_Cabin/Cabin_Geometry/Cabin_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Cabin/Geo_Cabin/Cabin_Tech/Cabin_Tech_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Supplies/Geo_Supplies/Supplies_Geometry/Supplies_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Engine/Geo_Engine/Engine_Geometry/Engine_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Cockpit/Geo_Cockpit/Cockpit_Geometry/Cockpit_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Cabin/Geo_Cabin/Cabin_Geometry/Cabin_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Cabin/Geo_Cabin/Cabin_Tech/Cabin_Tech_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Supplies/Geo_Supplies/Supplies_Geometry/Supplies_Exterior"), remoteTransform);
Instantiate(shipModel.Find("Module_Engine/Geo_Engine/Engine_Geometry/Engine_Exterior"), remoteTransform);
var landingGearFront = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Front/Geo_LandingGear_Front"), remoteTransform);
var landingGearLeft = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Left/Geo_LandingGear_Left"), remoteTransform);
var landingGearRight = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Right/Geo_LandingGear_Right"), remoteTransform);
var landingGearFront = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Front/Geo_LandingGear_Front"), remoteTransform);
var landingGearLeft = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Left/Geo_LandingGear_Left"), remoteTransform);
var landingGearRight = Instantiate(shipModel.Find("Module_LandingGear/LandingGear_Right/Geo_LandingGear_Right"), remoteTransform);
Destroy(landingGearFront.Find("LandingGear_FrontCollision").gameObject);
Destroy(landingGearLeft.Find("LandingGear_LeftCollision").gameObject);
Destroy(landingGearRight.Find("LandingGear_RightCollision").gameObject);
Destroy(landingGearFront.Find("LandingGear_FrontCollision").gameObject);
Destroy(landingGearLeft.Find("LandingGear_LeftCollision").gameObject);
Destroy(landingGearRight.Find("LandingGear_RightCollision").gameObject);
landingGearFront.localPosition
= landingGearLeft.localPosition
= landingGearRight.localPosition
+= Vector3.up * 3.762f;
landingGearFront.localPosition
= landingGearLeft.localPosition
= landingGearRight.localPosition
+= Vector3.up * 3.762f;
return remoteTransform;
}
return remoteTransform;
}
public override bool IsReady => GetShipModel() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
public override bool IsReady => GetShipModel() != null
&& Player != null
&& QSBPlayerManager.PlayerExists(Player.PlayerId)
&& Player.IsReady
&& NetId.Value != uint.MaxValue
&& NetId.Value != 0U;
}
}

View File

@ -6,131 +6,131 @@ using UnityEngine;
namespace QSB.TransformSync
{
public abstract class TransformSync : PlayerSyncObject
{
public abstract bool IsReady { get; }
protected abstract Transform InitLocalTransform();
protected abstract Transform InitRemoteTransform();
public abstract class TransformSync : PlayerSyncObject
{
public abstract bool IsReady { get; }
protected abstract Transform InitLocalTransform();
protected abstract Transform InitRemoteTransform();
public Transform SyncedTransform { get; private set; }
public QSBSector ReferenceSector { get; set; }
public Transform SyncedTransform { get; private set; }
public QSBSector ReferenceSector { get; set; }
private const float SmoothTime = 0.1f;
private bool _isInitialized;
private Vector3 _positionSmoothVelocity;
private Quaternion _rotationSmoothVelocity;
private bool _isVisible;
private const float SmoothTime = 0.1f;
private bool _isInitialized;
private Vector3 _positionSmoothVelocity;
private Quaternion _rotationSmoothVelocity;
private bool _isVisible;
protected virtual void Awake()
{
DebugLog.DebugWrite($"Awake of {GetType().Name}", MessageType.Info);
QSBPlayerManager.PlayerSyncObjects.Add(this);
DontDestroyOnLoad(gameObject);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
protected virtual void Awake()
{
DebugLog.DebugWrite($"Awake of {GetType().Name}", MessageType.Info);
QSBPlayerManager.PlayerSyncObjects.Add(this);
DontDestroyOnLoad(gameObject);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
protected virtual void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
protected virtual void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
_isInitialized = false;
}
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
_isInitialized = false;
}
protected void Init()
{
DebugLog.DebugWrite($"Init of {AttachedNetId} ({Player.PlayerId}.{GetType().Name})");
SyncedTransform = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
_isInitialized = true;
_isVisible = true;
}
protected void Init()
{
DebugLog.DebugWrite($"Init of {AttachedNetId} ({Player.PlayerId}.{GetType().Name})");
SyncedTransform = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
_isInitialized = true;
_isVisible = true;
}
private void Update()
{
if (!_isInitialized && IsReady)
{
Init();
}
else if (_isInitialized && !IsReady)
{
_isInitialized = false;
return;
}
private void Update()
{
if (!_isInitialized && IsReady)
{
Init();
}
else if (_isInitialized && !IsReady)
{
_isInitialized = false;
return;
}
if (!_isInitialized)
{
return;
}
if (!_isInitialized)
{
return;
}
if (SyncedTransform == null)
{
DebugLog.ToConsole($"Warning - SyncedTransform {Player.PlayerId}.{GetType().Name} is null.", MessageType.Warning);
return;
}
if (SyncedTransform == null)
{
DebugLog.ToConsole($"Warning - SyncedTransform {Player.PlayerId}.{GetType().Name} is null.", MessageType.Warning);
return;
}
UpdateTransform();
}
UpdateTransform();
}
protected virtual void UpdateTransform()
{
if (HasAuthority) // If this script is attached to the client's own body on the client's side.
{
if (ReferenceSector == null || ReferenceSector.Sector == null)
{
DebugLog.ToConsole($"Error - ReferenceSector has null value for {Player.PlayerId}.{GetType().Name}", MessageType.Error);
return;
}
transform.position = ReferenceSector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(SyncedTransform.rotation);
return;
}
protected virtual void UpdateTransform()
{
if (HasAuthority) // If this script is attached to the client's own body on the client's side.
{
if (ReferenceSector == null || ReferenceSector.Sector == null)
{
DebugLog.ToConsole($"Error - ReferenceSector has null value for {Player.PlayerId}.{GetType().Name}", MessageType.Error);
return;
}
transform.position = ReferenceSector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(SyncedTransform.rotation);
return;
}
// If this script is attached to any other body, eg the representations of other players
if (SyncedTransform.position == Vector3.zero)
{
Hide();
}
else
{
Show();
}
// If this script is attached to any other body, eg the representations of other players
if (SyncedTransform.position == Vector3.zero)
{
Hide();
}
else
{
Show();
}
SyncedTransform.localPosition = Vector3.SmoothDamp(SyncedTransform.localPosition, transform.position, ref _positionSmoothVelocity, SmoothTime);
SyncedTransform.localRotation = QuaternionHelper.SmoothDamp(SyncedTransform.localRotation, transform.rotation, ref _rotationSmoothVelocity, Time.deltaTime);
}
SyncedTransform.localPosition = Vector3.SmoothDamp(SyncedTransform.localPosition, transform.position, ref _positionSmoothVelocity, SmoothTime);
SyncedTransform.localRotation = QuaternionHelper.SmoothDamp(SyncedTransform.localRotation, transform.rotation, ref _rotationSmoothVelocity, Time.deltaTime);
}
public void SetReferenceSector(QSBSector sector)
{
DebugLog.DebugWrite($"Setting {Player.PlayerId}.{GetType().Name} to {sector.Name}", MessageType.Info);
_positionSmoothVelocity = Vector3.zero;
ReferenceSector = sector;
if (!HasAuthority)
{
SyncedTransform.SetParent(sector.Transform, true);
transform.position = sector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = sector.Transform.InverseTransformRotation(SyncedTransform.rotation);
}
}
public void SetReferenceSector(QSBSector sector)
{
DebugLog.DebugWrite($"Setting {Player.PlayerId}.{GetType().Name} to {sector.Name}", MessageType.Info);
_positionSmoothVelocity = Vector3.zero;
ReferenceSector = sector;
if (!HasAuthority)
{
SyncedTransform.SetParent(sector.Transform, true);
transform.position = sector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = sector.Transform.InverseTransformRotation(SyncedTransform.rotation);
}
}
private void Show()
{
if (!_isVisible)
{
SyncedTransform.gameObject.Show();
_isVisible = true;
}
}
private void Show()
{
if (!_isVisible)
{
SyncedTransform.gameObject.Show();
_isVisible = true;
}
}
private void Hide()
{
if (_isVisible)
{
SyncedTransform.gameObject.Hide();
_isVisible = false;
}
}
private void Hide()
{
if (_isVisible)
{
SyncedTransform.gameObject.Hide();
_isVisible = false;
}
}
}
}
}

View File

@ -9,75 +9,75 @@ using System.Reflection;
namespace QSB.WorldSync
{
public static class WorldRegistry
{
private static readonly List<WorldObject> WorldObjects = new List<WorldObject>();
public static List<NomaiOrbTransformSync> OrbSyncList = new List<NomaiOrbTransformSync>();
public static List<NomaiInterfaceOrb> OldOrbList = new List<NomaiInterfaceOrb>();
public static List<CharacterDialogueTree> OldDialogueTrees = new List<CharacterDialogueTree>();
public static class WorldRegistry
{
private static readonly List<WorldObject> WorldObjects = new List<WorldObject>();
public static List<NomaiOrbTransformSync> OrbSyncList = new List<NomaiOrbTransformSync>();
public static List<NomaiInterfaceOrb> OldOrbList = new List<NomaiInterfaceOrb>();
public static List<CharacterDialogueTree> OldDialogueTrees = new List<CharacterDialogueTree>();
public static void AddObject(WorldObject worldObject)
{
if (WorldObjects.Contains(worldObject))
{
return;
}
WorldObjects.Add(worldObject);
}
public static void AddObject(WorldObject worldObject)
{
if (WorldObjects.Contains(worldObject))
{
return;
}
WorldObjects.Add(worldObject);
}
public static IEnumerable<T> GetObjects<T>()
{
return WorldObjects.OfType<T>();
}
public static IEnumerable<T> GetObjects<T>()
{
return WorldObjects.OfType<T>();
}
public static T GetObject<T>(int id) where T : WorldObject
{
return GetObjects<T>().FirstOrDefault(x => x.ObjectId == id);
}
public static T GetObject<T>(int id) where T : WorldObject
{
return GetObjects<T>().FirstOrDefault(x => x.ObjectId == id);
}
public static void RemoveObjects<T>() where T : WorldObject
{
WorldObjects.RemoveAll(x => x.GetType() == typeof(T));
}
public static void RemoveObjects<T>() where T : WorldObject
{
WorldObjects.RemoveAll(x => x.GetType() == typeof(T));
}
public static void HandleSlotStateChange(NomaiInterfaceSlot slot, NomaiInterfaceOrb affectingOrb, bool state)
{
QSBOrbSlot qsbSlot = null;
NomaiOrbTransformSync orbSync = null;
var slotList = GetObjects<QSBOrbSlot>();
if (slotList.Count() == 0)
{
return;
}
try
{
qsbSlot = slotList.First(x => x.InterfaceSlot == slot);
orbSync = OrbSyncList.First(x => x.AttachedOrb == affectingOrb);
if (orbSync.HasAuthority)
{
qsbSlot.HandleEvent(state);
}
}
catch
{
DebugLog.DebugWrite("Error - Exception when handling slot state change."
+ Environment.NewLine + $"Slot name {slot.name} to {state}"
+ Environment.NewLine + $"SlotList count : {slotList?.Count()}"
+ Environment.NewLine + $"QSBOrbSlot null? : {qsbSlot == null}"
+ Environment.NewLine + $"NomaiOrbTransformSync null? : {orbSync == null}", MessageType.Error);
}
}
public static void HandleSlotStateChange(NomaiInterfaceSlot slot, NomaiInterfaceOrb affectingOrb, bool state)
{
QSBOrbSlot qsbSlot = null;
NomaiOrbTransformSync orbSync = null;
var slotList = GetObjects<QSBOrbSlot>();
if (slotList.Count() == 0)
{
return;
}
try
{
qsbSlot = slotList.First(x => x.InterfaceSlot == slot);
orbSync = OrbSyncList.First(x => x.AttachedOrb == affectingOrb);
if (orbSync.HasAuthority)
{
qsbSlot.HandleEvent(state);
}
}
catch
{
DebugLog.DebugWrite("Error - Exception when handling slot state change."
+ Environment.NewLine + $"Slot name {slot.name} to {state}"
+ Environment.NewLine + $"SlotList count : {slotList?.Count()}"
+ Environment.NewLine + $"QSBOrbSlot null? : {qsbSlot == null}"
+ Environment.NewLine + $"NomaiOrbTransformSync null? : {orbSync == null}", MessageType.Error);
}
}
public static void RaiseEvent(object instance, string eventName)
{
if (!(instance.GetType()
.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic)?
.GetValue(instance) is MulticastDelegate multiDelegate))
{
return;
}
var delegateList = multiDelegate.GetInvocationList().ToList();
delegateList.ForEach(x => x.DynamicInvoke(instance));
}
}
public static void RaiseEvent(object instance, string eventName)
{
if (!(instance.GetType()
.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic)?
.GetValue(instance) is MulticastDelegate multiDelegate))
{
return;
}
var delegateList = multiDelegate.GetInvocationList().ToList();
delegateList.ForEach(x => x.DynamicInvoke(instance));
}
}
}