From 064c8da7e7139e940ea0e5805faff066ea64c893 Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Thu, 21 Dec 2017 20:26:33 -0300 Subject: [PATCH] Unknown object headers will now crash the game with a copy of the previous object to be read --- .../Source/Networking/GameClient.cs | 44 ++++++++++++++++++- .../ClientEntityEventManager.cs | 5 ++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 8052b89d4..25a2ea8b8 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -974,8 +974,14 @@ namespace Barotrauma.Networking private void ReadIngameUpdate(NetIncomingMessage inc) { + List entities = new List(); + float sendingTime = inc.ReadFloat() - inc.SenderConnection.RemoteTimeOffset; + ServerNetObject? prevObjHeader = null; + long prevBitPos = 0; + long prevBytePos = 0; + ServerNetObject objHeader; while ((objHeader = (ServerNetObject)inc.ReadByte()) != ServerNetObject.END_OF_MESSAGE) { @@ -1004,15 +1010,51 @@ namespace Barotrauma.Networking break; case ServerNetObject.ENTITY_EVENT: case ServerNetObject.ENTITY_EVENT_INITIAL: - entityEventManager.Read(objHeader, inc, sendingTime); + entityEventManager.Read(objHeader, inc, sendingTime, entities); break; case ServerNetObject.CHAT_MESSAGE: ChatMessage.ClientRead(inc); break; default: DebugConsole.ThrowError("Error while reading update from server (unknown object header \""+objHeader+"\"!)"); + if (prevObjHeader != null) + { + DebugConsole.ThrowError("Previous object type: " + prevObjHeader.ToString()); + } + else + { + DebugConsole.ThrowError("Error occurred on the very first object!"); + } + DebugConsole.ThrowError("Previous object was " + (inc.Position - prevBitPos) + " bits long (" + (inc.PositionInBytes - prevBytePos) + " bytes)"); + if (prevObjHeader == ServerNetObject.ENTITY_EVENT || prevObjHeader == ServerNetObject.ENTITY_EVENT_INITIAL) + { + foreach (IServerSerializable ent in entities) + { + if (ent == null) + { + DebugConsole.ThrowError(" - NULL"); + continue; + } + Entity e = ent as Entity; + DebugConsole.ThrowError(" - "+e.ToString()); + } + } + DebugConsole.ThrowError("Writing object data to \"crashreport_object.bin\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues"); + + FileStream fl = File.Open("crashreport_object.bin", FileMode.Create); + BinaryWriter sw = new BinaryWriter(fl); + + sw.Write(inc.Data, (int)prevBytePos, (int)(inc.LengthBytes - prevBytePos)); + + sw.Close(); + fl.Close(); + + throw new Exception("Error while reading update from server: please send us \"crashreport_object.bin\"!"); break; } + prevObjHeader = objHeader; + prevBitPos = inc.Position; + prevBytePos = inc.PositionInBytes; } } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs index 464166a39..a66c0bf2b 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs @@ -100,7 +100,7 @@ namespace Barotrauma.Networking /// /// Read the events from the message, ignoring ones we've already received /// - public void Read(ServerNetObject type, NetIncomingMessage msg, float sendingTime) + public void Read(ServerNetObject type, NetIncomingMessage msg, float sendingTime, List entities) { UInt16 unreceivedEntityEventCount = 0; @@ -128,6 +128,8 @@ namespace Barotrauma.Networking firstNewID = null; } + entities.Clear(); + UInt16 firstEventID = msg.ReadUInt16(); int eventCount = msg.ReadByte(); @@ -146,6 +148,7 @@ namespace Barotrauma.Networking byte msgLength = msg.ReadByte(); IServerSerializable entity = Entity.FindEntityByID(entityID) as IServerSerializable; + entities.Add(entity); //skip the event if we've already received it or if the entity isn't found if (thisEventID != (UInt16)(lastReceivedID + 1) || entity == null)