From 458c972580c2f9be9c0d64629be173eb697b6155 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Sun, 29 Jul 2018 22:28:56 +0300 Subject: [PATCH] More server-side EntityEvent error logging, Item.ServerWrite does some error checks and writes NetEntityEvent.Type.Invalid as the type of the event instead of attempting to write a potentially unreadable message. --- .../BarotraumaClient/Source/Items/Item.cs | 2 + .../BarotraumaShared/Source/Items/Item.cs | 56 ++++++++++++++++++- .../Source/Networking/GameServer.cs | 5 +- .../NetEntityEvent/NetEntityEvent.cs | 1 + 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 5544e8c3a..b360b4475 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -406,6 +406,8 @@ namespace Barotrauma case NetEntityEvent.Type.ChangeProperty: ReadPropertyChange(msg); break; + case NetEntityEvent.Type.Invalid: + break; } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 42fb6979a..515283a0b 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1284,18 +1284,58 @@ namespace Barotrauma { if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type)) { + string errorMsg = ""; + if (extraData == null) + { + errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was null."; + } + else if (extraData.Length == 0) + { + errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was empty."; + } + else + { + errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event type not set."; + } + msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)NetEntityEvent.Type.Invalid); + DebugConsole.Log(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return; } + long initialWritePos = msg.Position; + NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0]; msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)eventType); switch (eventType) { case NetEntityEvent.Type.ComponentState: + string componentErrorMsg = ""; + if (extraData.Length < 2 || !(extraData[1] is int)) + { + componentErrorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index not given."; + } int componentIndex = (int)extraData[1]; - msg.WriteRangedInteger(0, components.Count-1, componentIndex); - - (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData); + if (componentIndex < 0 || componentIndex >= components.Count) + { + componentErrorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index out of range (" + componentIndex + ")."; + } + else if (!(components[componentIndex] is IServerSerializable)) + { + componentErrorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component \"" + components[componentIndex] + "\" is not server serializable."; + } + if (string.IsNullOrEmpty(componentErrorMsg)) + { + msg.WriteRangedInteger(0, components.Count - 1, componentIndex); + (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData); + } + else + { + msg.Position = initialWritePos; + msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)NetEntityEvent.Type.Invalid); + DebugConsole.Log(componentErrorMsg); + GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidComponentData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, componentErrorMsg); + } break; case NetEntityEvent.Type.InventoryState: ownInventory.ServerWrite(msg, c, extraData); @@ -1321,6 +1361,16 @@ namespace Barotrauma case NetEntityEvent.Type.ChangeProperty: WritePropertyChange(msg, extraData); break; + default: + { + //event type not valid for items - rewind the write position and write invalid event type + msg.Position = initialWritePos; + msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)NetEntityEvent.Type.Invalid); + string errorMsg = "Failed to write a network event for the item \"" + Name + "\" - \"" + eventType + "\" is not a valid entity event type for items."; + DebugConsole.Log(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + } + break; } } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 6cd095e1a..cd34f1c6f 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -504,7 +504,10 @@ namespace Barotrauma.Networking } catch (Exception e) { - DebugConsole.ThrowError("Failed to write a network message for the client \""+c.Name+"\"!", e); + DebugConsole.ThrowError("Failed to write a network message for the client \"" + c.Name + "\"!", e); + GameAnalyticsManager.AddErrorEventOnce("GameServer.Update:ClientWriteFailed" + e.StackTrace, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + "Failed to write a network message for the client \"" + c.Name + "\"! (MidRoundSyncing: " + c.NeedsMidRoundSync + ")\n" + + e.Message + "\n" + e.StackTrace); } } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEvent.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEvent.cs index e074a78de..53b5af950 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEvent.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEvent.cs @@ -7,6 +7,7 @@ namespace Barotrauma.Networking { public enum Type { + Invalid, ComponentState, InventoryState, Status,