From 62e7ea19062ae53d2703f0796a91df162ed91a44 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sun, 5 Dec 2021 23:47:09 -0800 Subject: [PATCH 1/8] - add ForId and OnlySendToSpecific - dont send ForId or OnlySendToSpecific if we dont have to - fix message type check (`this is not PlayerInformationEvent or PlayerReadyEvent`) --- QSB/Events/QSBEvent.cs | 30 +++++++++++------- QSB/Messaging/MessageHandler.cs | 31 +++++++++++++++++-- QSB/Messaging/PlayerMessage.cs | 28 ++++++++++++++++- .../Events/QuantumAuthorityEvent.cs | 4 +-- 4 files changed, 75 insertions(+), 18 deletions(-) diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs index 5194bf7c..d0d9134f 100644 --- a/QSB/Events/QSBEvent.cs +++ b/QSB/Events/QSBEvent.cs @@ -43,10 +43,10 @@ namespace QSB.Events } /// - /// Checks whether the message should be processed by the executing client/server. + /// Checks whether the message should be processed by the executing client. /// /// True if the message should be processed. - public virtual bool CheckMessage(bool isServer, T message) + public virtual bool CheckMessage(T message) => !RequireWorldObjectsReady || WorldObjectManager.AllObjectsReady; private void OnReceive(bool isServer, T message) @@ -59,18 +59,24 @@ namespace QSB.Events * hub for all events. */ - if (!CheckMessage(isServer, message)) - { - return; - } - if (isServer) { - _eventHandler.SendToAll(message); + if (message.OnlySendToHost) + { + _eventHandler.SendToLocalClient(message); + } + else if (message.OnlySendToSpecific) + { + _eventHandler.SendToClient(message.ForId, message); + } + else + { + _eventHandler.SendToAllClients(message); + } return; } - if (message.OnlySendToHost && !QSBCore.IsHost) + if (!CheckMessage(message)) { return; } @@ -87,8 +93,8 @@ namespace QSB.Events if (!player.IsReady && player.PlayerId != LocalPlayerId - && (player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem) - && (message is not PlayerInformationEvent or PlayerReadyEvent)) + && player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem + && this is not PlayerInformationEvent or PlayerReadyEvent) { DebugLog.ToConsole($"Warning - Got message from player {message.FromId}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning); QSBEventManager.FireEvent(EventNames.QSBRequestStateResync); @@ -98,7 +104,7 @@ namespace QSB.Events try { if (message.FromId == QSBPlayerManager.LocalPlayerId || - QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId)) + QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId)) { OnReceiveLocal(QSBCore.IsHost, message); return; diff --git a/QSB/Messaging/MessageHandler.cs b/QSB/Messaging/MessageHandler.cs index a66bf53b..61a99e2b 100644 --- a/QSB/Messaging/MessageHandler.cs +++ b/QSB/Messaging/MessageHandler.cs @@ -1,5 +1,4 @@ -using QSB.Events; -using QSB.Utility; +using QSB.Utility; using QuantumUNET; using QuantumUNET.Components; using QuantumUNET.Messages; @@ -48,7 +47,7 @@ namespace QSB.Messaging QNetworkManager.singleton.client.RegisterHandler(_eventType, OnClientReceiveMessageHandler); } - public void SendToAll(T message) + public void SendToAllClients(T message) { if (!QSBNetworkManager.Instance.IsReady) { @@ -58,6 +57,32 @@ namespace QSB.Messaging QNetworkServer.SendToAll(_eventType, message); } + public void SendToLocalClient(T message) + { + if (!QSBNetworkManager.Instance.IsReady) + { + return; + } + + QNetworkServer.SendToClient(0, _eventType, message); + } + + public void SendToClient(uint id, T message) + { + if (!QSBNetworkManager.Instance.IsReady) + { + return; + } + + var conn = QNetworkServer.connections.FirstOrDefault(x => x.GetPlayerId() == id); + if (conn == null) + { + DebugLog.ToConsole($"SendTo unknown player! id: {id}, message: {message.GetType().Name}", OWML.Common.MessageType.Error); + return; + } + QNetworkServer.SendToClient(conn.connectionId, _eventType, message); + } + public void SendToServer(T message) { if (!QSBNetworkManager.Instance.IsReady) diff --git a/QSB/Messaging/PlayerMessage.cs b/QSB/Messaging/PlayerMessage.cs index dc22a948..634bb776 100644 --- a/QSB/Messaging/PlayerMessage.cs +++ b/QSB/Messaging/PlayerMessage.cs @@ -21,11 +21,29 @@ namespace QSB.Messaging /// public bool OnlySendToHost { get; set; } + /// + /// If true, only send this message to ForId + /// + public bool OnlySendToSpecific { get; set; } + + /// + /// The Player ID that this message is for + /// + public uint ForId { get; set; } + public override void Deserialize(QNetworkReader reader) { FromId = reader.ReadUInt32(); AboutId = reader.ReadUInt32(); OnlySendToHost = reader.ReadBoolean(); + if (!OnlySendToHost) + { + OnlySendToSpecific = reader.ReadBoolean(); + if (OnlySendToSpecific) + { + ForId = reader.ReadUInt32(); + } + } } public override void Serialize(QNetworkWriter writer) @@ -33,6 +51,14 @@ namespace QSB.Messaging writer.Write(FromId); writer.Write(AboutId); writer.Write(OnlySendToHost); + if (!OnlySendToHost) + { + writer.Write(OnlySendToSpecific); + if (OnlySendToSpecific) + { + writer.Write(ForId); + } + } } } -} \ No newline at end of file +} diff --git a/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs b/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs index c1749fb2..a52e02d5 100644 --- a/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs +++ b/QSB/QuantumSync/Events/QuantumAuthorityEvent.cs @@ -20,9 +20,9 @@ namespace QSB.QuantumSync.Events AuthorityOwner = authorityOwner }; - public override bool CheckMessage(bool isServer, QuantumAuthorityMessage message) + public override bool CheckMessage(QuantumAuthorityMessage message) { - if (!base.CheckMessage(isServer, message)) + if (!base.CheckMessage(message)) { return false; } From 4b4c142e20ae09295af11805206a4a79a5c8168e Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 00:02:51 -0800 Subject: [PATCH 2/8] goofs --- QSB/Events/QSBEvent.cs | 16 ++++++++-------- QSB/Messaging/MessageHandler.cs | 6 +++--- QSB/Player/Events/RequestStateResyncEvent.cs | 9 ++++----- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs index d0d9134f..b01be631 100644 --- a/QSB/Events/QSBEvent.cs +++ b/QSB/Events/QSBEvent.cs @@ -63,15 +63,15 @@ namespace QSB.Events { if (message.OnlySendToHost) { - _eventHandler.SendToLocalClient(message); + _eventHandler.SendToHost(message); } else if (message.OnlySendToSpecific) { - _eventHandler.SendToClient(message.ForId, message); + _eventHandler.SendTo(message.ForId, message); } else { - _eventHandler.SendToAllClients(message); + _eventHandler.SendToAll(message); } return; } @@ -103,14 +103,14 @@ namespace QSB.Events try { - if (message.FromId == QSBPlayerManager.LocalPlayerId || - QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId)) + if (QSBPlayerManager.IsBelongingToLocalPlayer(message.FromId)) { OnReceiveLocal(QSBCore.IsHost, message); - return; } - - OnReceiveRemote(QSBCore.IsHost, message); + else + { + OnReceiveRemote(QSBCore.IsHost, message); + } } catch (Exception ex) { diff --git a/QSB/Messaging/MessageHandler.cs b/QSB/Messaging/MessageHandler.cs index 61a99e2b..545f6607 100644 --- a/QSB/Messaging/MessageHandler.cs +++ b/QSB/Messaging/MessageHandler.cs @@ -47,7 +47,7 @@ namespace QSB.Messaging QNetworkManager.singleton.client.RegisterHandler(_eventType, OnClientReceiveMessageHandler); } - public void SendToAllClients(T message) + public void SendToAll(T message) { if (!QSBNetworkManager.Instance.IsReady) { @@ -57,7 +57,7 @@ namespace QSB.Messaging QNetworkServer.SendToAll(_eventType, message); } - public void SendToLocalClient(T message) + public void SendToHost(T message) { if (!QSBNetworkManager.Instance.IsReady) { @@ -67,7 +67,7 @@ namespace QSB.Messaging QNetworkServer.SendToClient(0, _eventType, message); } - public void SendToClient(uint id, T message) + public void SendTo(uint id, T message) { if (!QSBNetworkManager.Instance.IsReady) { diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index ab1f32f1..3d8cd289 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -31,19 +31,18 @@ namespace QSB.Player.Events public override void OnReceiveRemote(bool isHost, PlayerMessage message) { // if host, send worldobject and server states - if (isHost) { QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); SendWorldObjectInfo(); - - return; } - // if client, send player and client states - QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); + else + { + QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); + } } private void SendWorldObjectInfo() From 45537b8636bbed9c78d276c307876917c688327e Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 00:11:55 -0800 Subject: [PATCH 3/8] remove OnlySendToSpecific, just use uint.MaxValue to denote no ForId --- QSB/Events/QSBEvent.cs | 2 +- QSB/Messaging/PlayerMessage.cs | 25 +++++++------------------ 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs index b01be631..30e377d9 100644 --- a/QSB/Events/QSBEvent.cs +++ b/QSB/Events/QSBEvent.cs @@ -65,7 +65,7 @@ namespace QSB.Events { _eventHandler.SendToHost(message); } - else if (message.OnlySendToSpecific) + else if (message.ForId != uint.MaxValue) { _eventHandler.SendTo(message.ForId, message); } diff --git a/QSB/Messaging/PlayerMessage.cs b/QSB/Messaging/PlayerMessage.cs index 634bb776..b14eb553 100644 --- a/QSB/Messaging/PlayerMessage.cs +++ b/QSB/Messaging/PlayerMessage.cs @@ -16,20 +16,17 @@ namespace QSB.Messaging public uint AboutId { get; set; } /// - /// If true, only send this message to the host of the current session + /// If true, only send this message to the host of the current session /// (OnReceiveLocal/Remote is not called on any other client) /// public bool OnlySendToHost { get; set; } /// - /// If true, only send this message to ForId + /// The Player ID that this message is for. + /// By default, this is uint.MaxValue, + /// which means this is ignored and the message is sent to all clients /// - public bool OnlySendToSpecific { get; set; } - - /// - /// The Player ID that this message is for - /// - public uint ForId { get; set; } + public uint ForId { get; set; } = uint.MaxValue; public override void Deserialize(QNetworkReader reader) { @@ -38,11 +35,7 @@ namespace QSB.Messaging OnlySendToHost = reader.ReadBoolean(); if (!OnlySendToHost) { - OnlySendToSpecific = reader.ReadBoolean(); - if (OnlySendToSpecific) - { - ForId = reader.ReadUInt32(); - } + reader.ReadUInt32(); } } @@ -53,11 +46,7 @@ namespace QSB.Messaging writer.Write(OnlySendToHost); if (!OnlySendToHost) { - writer.Write(OnlySendToSpecific); - if (OnlySendToSpecific) - { - writer.Write(ForId); - } + writer.Write(ForId); } } } From ed14c30f9e55ea5cd20cb83468ccb5c919187119 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 00:15:47 -0800 Subject: [PATCH 4/8] with request resync, server should only send requesting client the info, rather than sending it to everyone --- QSB/Messaging/PlayerMessage.cs | 6 +++++- QSB/Player/Events/RequestStateResyncEvent.cs | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/QSB/Messaging/PlayerMessage.cs b/QSB/Messaging/PlayerMessage.cs index b14eb553..1be3da98 100644 --- a/QSB/Messaging/PlayerMessage.cs +++ b/QSB/Messaging/PlayerMessage.cs @@ -28,6 +28,10 @@ namespace QSB.Messaging /// public uint ForId { get; set; } = uint.MaxValue; + /// used to force set ForId. + /// primarily used for state resyncing, when the server needs to send a specific client a bunch of events + public static uint ForIdOverride = uint.MaxValue; + public override void Deserialize(QNetworkReader reader) { FromId = reader.ReadUInt32(); @@ -46,7 +50,7 @@ namespace QSB.Messaging writer.Write(OnlySendToHost); if (!OnlySendToHost) { - writer.Write(ForId); + writer.Write(ForIdOverride != uint.MaxValue ? ForIdOverride : ForId); } } } diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index 3d8cd289..57d0a231 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -30,15 +30,19 @@ namespace QSB.Player.Events public override void OnReceiveRemote(bool isHost, PlayerMessage message) { - // if host, send worldobject and server states + // if host, send worldobject and server states TO THE REQUESTING CLIENT if (isHost) { + PlayerMessage.ForIdOverride = message.FromId; + QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); SendWorldObjectInfo(); + + PlayerMessage.ForIdOverride = uint.MaxValue; } - // if client, send player and client states + // if client, send player and client states TO EVERYONE else { QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); From 36547dfe5864007aac48951db99df78eb4db09b7 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 00:49:56 -0800 Subject: [PATCH 5/8] fix ForIdOverride --- QSB/Events/QSBEvent.cs | 21 +++++++++++++------- QSB/Messaging/PlayerMessage.cs | 6 +----- QSB/Player/Events/RequestStateResyncEvent.cs | 11 +++++++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs index 30e377d9..ad4f0243 100644 --- a/QSB/Events/QSBEvent.cs +++ b/QSB/Events/QSBEvent.cs @@ -34,13 +34,20 @@ namespace QSB.Events public abstract bool RequireWorldObjectsReady { get; } - public void SendEvent(T message) - { - message.FromId = QSBPlayerManager.LocalPlayerId; - QSBCore.UnityEvents.RunWhen( - () => PlayerTransformSync.LocalInstance != null, - () => _eventHandler.SendToServer(message)); - } + /// used to force set ForId for every sent event + protected static uint ForIdOverride = uint.MaxValue; + + public void SendEvent(T message) => QSBCore.UnityEvents.RunWhen( + () => PlayerTransformSync.LocalInstance != null, + () => + { + message.FromId = LocalPlayerId; + if (ForIdOverride != uint.MaxValue) + { + message.ForId = ForIdOverride; + } + _eventHandler.SendToServer(message); + }); /// /// Checks whether the message should be processed by the executing client. diff --git a/QSB/Messaging/PlayerMessage.cs b/QSB/Messaging/PlayerMessage.cs index 1be3da98..b14eb553 100644 --- a/QSB/Messaging/PlayerMessage.cs +++ b/QSB/Messaging/PlayerMessage.cs @@ -28,10 +28,6 @@ namespace QSB.Messaging /// public uint ForId { get; set; } = uint.MaxValue; - /// used to force set ForId. - /// primarily used for state resyncing, when the server needs to send a specific client a bunch of events - public static uint ForIdOverride = uint.MaxValue; - public override void Deserialize(QNetworkReader reader) { FromId = reader.ReadUInt32(); @@ -50,7 +46,7 @@ namespace QSB.Messaging writer.Write(OnlySendToHost); if (!OnlySendToHost) { - writer.Write(ForIdOverride != uint.MaxValue ? ForIdOverride : ForId); + writer.Write(ForId); } } } diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index 57d0a231..ee79bf8b 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -33,14 +33,17 @@ namespace QSB.Player.Events // if host, send worldobject and server states TO THE REQUESTING CLIENT if (isHost) { - PlayerMessage.ForIdOverride = message.FromId; + ForIdOverride = message.FromId; QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); - SendWorldObjectInfo(); + if (WorldObjectManager.AllObjectsReady) + { + SendWorldObjectInfo(); + } - PlayerMessage.ForIdOverride = uint.MaxValue; + ForIdOverride = uint.MaxValue; } // if client, send player and client states TO EVERYONE else @@ -51,6 +54,8 @@ namespace QSB.Player.Events private void SendWorldObjectInfo() { + DebugLog.DebugWrite("SendWorldObjectInfo..."); + QSBWorldSync.DialogueConditions.ForEach(condition => QSBEventManager.FireEvent(EventNames.DialogueConditionChanged, condition.Key, condition.Value)); From 940d01f81bc97505fff1b445d5cddc34168993b7 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 01:00:56 -0800 Subject: [PATCH 6/8] buh --- QSB/Player/Events/RequestStateResyncEvent.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index ee79bf8b..cfe98ff7 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -30,11 +30,12 @@ namespace QSB.Player.Events public override void OnReceiveRemote(bool isHost, PlayerMessage message) { - // if host, send worldobject and server states TO THE REQUESTING CLIENT + // send response only to the requesting client + ForIdOverride = message.FromId; + + // if host, send worldobject and server states if (isHost) { - ForIdOverride = message.FromId; - QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); @@ -42,14 +43,14 @@ namespace QSB.Player.Events { SendWorldObjectInfo(); } - - ForIdOverride = uint.MaxValue; } - // if client, send player and client states TO EVERYONE + // if client, send player and client states else { QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); } + + ForIdOverride = uint.MaxValue; } private void SendWorldObjectInfo() From 4db0df852755ab7a83a37e2bf953186d8ad63c8c Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 01:29:47 -0800 Subject: [PATCH 7/8] log-o remove-o --- QSB/Player/Events/RequestStateResyncEvent.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index cfe98ff7..877a790e 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -55,8 +55,6 @@ namespace QSB.Player.Events private void SendWorldObjectInfo() { - DebugLog.DebugWrite("SendWorldObjectInfo..."); - QSBWorldSync.DialogueConditions.ForEach(condition => QSBEventManager.FireEvent(EventNames.DialogueConditionChanged, condition.Key, condition.Value)); From 8ae21ede3d27dcc5a5cafafaf2108b2b3a8ce972 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 6 Dec 2021 01:43:06 -0800 Subject: [PATCH 8/8] finally block so ForIdOverride is returned to normal --- QSB/Player/Events/RequestStateResyncEvent.cs | 30 +++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/QSB/Player/Events/RequestStateResyncEvent.cs b/QSB/Player/Events/RequestStateResyncEvent.cs index 877a790e..26750419 100644 --- a/QSB/Player/Events/RequestStateResyncEvent.cs +++ b/QSB/Player/Events/RequestStateResyncEvent.cs @@ -32,25 +32,29 @@ namespace QSB.Player.Events { // send response only to the requesting client ForIdOverride = message.FromId; - - // if host, send worldobject and server states - if (isHost) + try { - QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); - QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); - - if (WorldObjectManager.AllObjectsReady) + // if host, send worldobject and server states + if (isHost) { - SendWorldObjectInfo(); + QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState()); + QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); + + if (WorldObjectManager.AllObjectsReady) + { + SendWorldObjectInfo(); + } + } + // if client, send player and client states + else + { + QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); } } - // if client, send player and client states - else + finally { - QSBEventManager.FireEvent(EventNames.QSBPlayerInformation); + ForIdOverride = uint.MaxValue; } - - ForIdOverride = uint.MaxValue; } private void SendWorldObjectInfo()