diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs index ef8f3d12..b11b8415 100644 --- a/QSB/Events/QSBEvent.cs +++ b/QSB/Events/QSBEvent.cs @@ -36,6 +36,12 @@ namespace QSB.Events () => _eventHandler.SendToServer(message)); } + /// + /// Checks whether the message should be processed by the executing client/server. + /// + /// True if the message should be processed. + public virtual bool CheckMessage(bool isServer, T message) => true; + private void OnReceive(bool isServer, T message) { /* Explanation : @@ -45,6 +51,12 @@ namespace QSB.Events * onto all clients. This way, the server *server* just acts as the ditribution * hub for all events. */ + + if (!CheckMessage(isServer, message)) + { + return; + } + if (isServer) { _eventHandler.SendToAll(message); diff --git a/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs b/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs index 8970d5bb..2d78da57 100644 --- a/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs +++ b/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs @@ -1,5 +1,6 @@ using OWML.Common; using QSB.Events; +using QSB.Player; using QSB.Utility; using QSB.WorldSync; using System.Linq; @@ -22,6 +23,22 @@ namespace QSB.QuantumSync.Events AuthorityOwner = authorityOwner }; + public override bool CheckMessage(bool isServer, QuantumAuthorityMessage message) + { + var objects = QSBWorldSync.GetWorldObjects(); + var obj = objects.ToList()[message.ObjectId]; + + return obj.ControllingPlayer == 0 || message.AuthorityOwner == 0; + } + + public override void OnReceiveLocal(bool server, QuantumAuthorityMessage message) + { + var objects = QSBWorldSync.GetWorldObjects(); + var obj = objects.ToList()[message.ObjectId]; + obj.ControllingPlayer = message.AuthorityOwner; + DebugLog.DebugWrite($"Set {message.ObjectId} to owner {message.AuthorityOwner} - From local"); + } + public override void OnReceiveRemote(bool server, QuantumAuthorityMessage message) { var objects = QSBWorldSync.GetWorldObjects(); @@ -32,6 +49,11 @@ namespace QSB.QuantumSync.Events } obj.ControllingPlayer = message.AuthorityOwner; DebugLog.DebugWrite($"Set {message.ObjectId} to owner {message.AuthorityOwner} - From {message.FromId}"); + if (obj.ControllingPlayer == 0 && obj.IsEnabled) + { + // object has no owner, but is still active for this player. request ownership + GlobalMessenger.FireEvent(EventNames.QSBQuantumAuthority, message.ObjectId, QSBPlayerManager.LocalPlayerId); + } } } } \ No newline at end of file diff --git a/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs b/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs index d16b9ca5..486b292c 100644 --- a/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs +++ b/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs @@ -1,5 +1,6 @@ using QSB.Patches; using QSB.Player; +using QSB.Utility; using System.Linq; using System.Reflection; using UnityEngine; diff --git a/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs b/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs index e436d9bc..2d8dee2c 100644 --- a/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs +++ b/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs @@ -3,5 +3,6 @@ public interface IQSBQuantumObject { uint ControllingPlayer { get; set; } + bool IsEnabled { get; set; } } } diff --git a/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs b/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs index 4de6fa08..f10b5a1d 100644 --- a/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs +++ b/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs @@ -11,6 +11,7 @@ namespace QSB.QuantumSync.WorldObjects where T : MonoBehaviour { public uint ControllingPlayer { get; set; } + public bool IsEnabled { get; set; } public override void Init(T attachedObject, int id) { @@ -18,11 +19,12 @@ namespace QSB.QuantumSync.WorldObjects tracker.AttachedComponent = AttachedObject.gameObject.GetComponent(); tracker.OnEnableEvent += OnEnable; tracker.OnDisableEvent += OnDisable; - ControllingPlayer = QSBCore.IsServer ? 1u : 0u; + ControllingPlayer = 0u; } private void OnEnable() { + IsEnabled = true; if (ControllingPlayer != 0) { // controlled by another player, dont care that we activate it @@ -31,11 +33,11 @@ namespace QSB.QuantumSync.WorldObjects var id = QSBWorldSync.GetWorldObjects().ToList().IndexOf(this); // no one is controlling this object right now, request authority GlobalMessenger.FireEvent(EventNames.QSBQuantumAuthority, id, QSBPlayerManager.LocalPlayerId); - ControllingPlayer = QSBPlayerManager.LocalPlayerId; } private void OnDisable() { + IsEnabled = false; if (ControllingPlayer != QSBPlayerManager.LocalPlayerId) { // not being controlled by us, don't care if we leave area @@ -44,7 +46,6 @@ namespace QSB.QuantumSync.WorldObjects var id = QSBWorldSync.GetWorldObjects().ToList().IndexOf(this); // send event to other players that we're releasing authority GlobalMessenger.FireEvent(EventNames.QSBQuantumAuthority, id, 0); - ControllingPlayer = 0; } } } diff --git a/QSB/QuantumSync/WorldObjects/QSBSocketedQuantumObject.cs b/QSB/QuantumSync/WorldObjects/QSBSocketedQuantumObject.cs index 9e18fd7f..65b16498 100644 --- a/QSB/QuantumSync/WorldObjects/QSBSocketedQuantumObject.cs +++ b/QSB/QuantumSync/WorldObjects/QSBSocketedQuantumObject.cs @@ -1,10 +1,13 @@ using OWML.Common; +using OWML.Utils; using QSB.Player; using QSB.QuantumSync.Events; using QSB.Utility; using QSB.WorldSync; +using System; using System.Reflection; using UnityEngine; +using UnityEngine.UI; namespace QSB.QuantumSync.WorldObjects { diff --git a/QSB/TransformSync/PlayerCameraSync.cs b/QSB/TransformSync/PlayerCameraSync.cs index 6cba2b7f..4694d034 100644 --- a/QSB/TransformSync/PlayerCameraSync.cs +++ b/QSB/TransformSync/PlayerCameraSync.cs @@ -43,7 +43,7 @@ namespace QSB.TransformSync private void OnRenderObject() { - if (!QSBCore.HasWokenUp || !Player.IsReady) + if (!QSBCore.HasWokenUp || !Player.IsReady || !QSBCore.DebugMode) { return; } diff --git a/QSB/TransformSync/PlayerTransformSync.cs b/QSB/TransformSync/PlayerTransformSync.cs index de3849c5..7de5df99 100644 --- a/QSB/TransformSync/PlayerTransformSync.cs +++ b/QSB/TransformSync/PlayerTransformSync.cs @@ -54,7 +54,7 @@ namespace QSB.TransformSync private void OnRenderObject() { - if (!QSBCore.HasWokenUp || !Player.IsReady) + if (!QSBCore.HasWokenUp || !Player.IsReady || !QSBCore.DebugMode) { return; }