From 13dc008cb534a4e76a473c8c2bc9ea923ab65d97 Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Tue, 16 Oct 2018 17:11:20 -0300 Subject: [PATCH] Client communicates event syncing errors to the server This should help --- .../Source/Networking/GameClient.cs | 18 ++++++++ .../ClientEntityEventManager.cs | 12 +++-- .../Source/Networking/GameServer.cs | 44 +++++++++++++++++++ .../Source/Networking/NetworkMember.cs | 10 ++++- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index fe097d88c..ef11cde37 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1646,5 +1646,23 @@ namespace Barotrauma.Networking Vote(VoteType.EndRound, tickBox.Selected); return false; } + + public void ReportError(ClientNetError error,UInt16 expectedID=0,UInt16 eventID=0,UInt16 entityID=0) + { + NetOutgoingMessage outMsg = client.CreateMessage(); + outMsg.Write((byte)error); + switch (error) + { + case ClientNetError.MISSING_EVENT: + outMsg.Write(expectedID); + outMsg.Write(eventID); + break; + case ClientNetError.MISSING_ENTITY: + outMsg.Write(eventID); + outMsg.Write(entityID); + break; + } + client.SendMessage(outMsg, NetDeliveryMethod.ReliableUnordered); + } } } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs index e25b575a4..469e0950c 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs @@ -170,9 +170,14 @@ namespace Barotrauma.Networking { DebugConsole.NewMessage( "Received msg " + thisEventID + " (waiting for " + (lastReceivedID + 1) + ")", - thisEventID < lastReceivedID + 1 - ? Microsoft.Xna.Framework.Color.Yellow - : Microsoft.Xna.Framework.Color.Red); + NetIdUtils.IdMoreRecent(thisEventID, (UInt16)(lastReceivedID + 1)) + ? Microsoft.Xna.Framework.Color.Red + : Microsoft.Xna.Framework.Color.Yellow); + } + + if (NetIdUtils.IdMoreRecent(thisEventID, (UInt16)(lastReceivedID + 1))) + { + GameMain.Client.ReportError(ClientNetError.MISSING_EVENT, expectedID: (UInt16)(lastReceivedID + 1), eventID: thisEventID); } } else if (entity == null) @@ -180,6 +185,7 @@ namespace Barotrauma.Networking DebugConsole.NewMessage( "Received msg " + thisEventID + ", entity " + entityID + " not found", Microsoft.Xna.Framework.Color.Red); + GameMain.Client.ReportError(ClientNetError.MISSING_ENTITY, eventID: thisEventID, entityID: entityID); } msg.Position += msgLength * 8; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 1f5e1f4e5..2eb44d022 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -590,6 +590,9 @@ namespace Barotrauma.Networking fileSender.ReadFileRequest(inc); } break; + case ClientPacketHeader.ERROR: + HandleClientError(inc); + break; } } @@ -608,6 +611,47 @@ namespace Barotrauma.Networking return userID; } + private void HandleClientError(NetIncomingMessage inc) + { + Client c = ConnectedClients.Find(x => x.Connection == inc.SenderConnection); + + string errorStr = "Unhandled error report"; + + ClientNetError error = (ClientNetError)inc.ReadByte(); + switch (error) + { + case ClientNetError.MISSING_EVENT: + UInt16 expectedID = inc.ReadUInt16(); + UInt16 receivedID = inc.ReadUInt16(); + errorStr = "Expecting event id " + expectedID.ToString() + ", received " + receivedID.ToString(); + break; + case ClientNetError.MISSING_ENTITY: + UInt16 eventID = inc.ReadUInt16(); + UInt16 entityID = inc.ReadUInt16(); + Entity entity = Entity.FindEntityByID(entityID); + if (entity == null) + { + errorStr = "Received an update for an entity that doesn't exist (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ")"; + } + else if (entity is Character character) + { + errorStr = "Missing character " + character.Name + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ")"; + } + else if (entity is Item item) + { + errorStr = "Missing item " + item.Name + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ")"; + } + else + { + errorStr = "Missing entity " + entity.ToString() + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ")"; + } + break; + } + + GameServer.Log(c.Name+" has reported an error: "+errorStr, ServerLog.MessageType.Error); + KickClient(c, errorStr); + } + private void ClientReadLobby(NetIncomingMessage inc) { Client c = ConnectedClients.Find(x => x.Connection == inc.SenderConnection); diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs index 2aad99fba..aabf4f4aa 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs @@ -17,7 +17,9 @@ namespace Barotrauma.Networking FILE_REQUEST, //request a (submarine) file from the server RESPONSE_STARTGAME, //tell the server whether you're ready to start - SERVER_COMMAND //tell the server to end a round or kick/ban someone (special permissions required) + SERVER_COMMAND, //tell the server to end a round or kick/ban someone (special permissions required) + + ERROR //tell the server that an error occurred } enum ClientNetObject { @@ -29,6 +31,12 @@ namespace Barotrauma.Networking ENTITY_STATE } + enum ClientNetError + { + MISSING_EVENT, //client was expecting a previous event + MISSING_ENTITY //client can't find an entity of a certain ID + } + enum ServerPacketHeader { AUTH_RESPONSE, //tell the player if they require a password to log in