diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 4585383ac..16f9d5121 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -99,6 +99,7 @@ namespace Barotrauma.Networking otherClients = new List(); + ChatMessage.LastID = 0; GameMain.NetLobbyScreen = new NetLobbyScreen(); } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 1be5e1019..6f3314422 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -712,9 +712,10 @@ namespace Barotrauma.Networking if (lastRecvEntityEventID > lastEntityEventID) DebugConsole.ThrowError("client.lastRecvEntityEventID > lastEntityEventID"); #endif + + if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastRecvChatMsgID)) c.lastRecvChatMsgID = lastRecvChatMsgID; + if (NetIdUtils.IdMoreRecent(c.lastRecvChatMsgID, c.lastChatMsgQueueID)) c.lastRecvChatMsgID = c.lastChatMsgQueueID; - c.lastRecvChatMsgID = NetIdUtils.Clamp(c.lastRecvChatMsgID, lastRecvChatMsgID, c.lastChatMsgQueueID); - if (NetIdUtils.IdMoreRecent(lastRecvEntitySpawnID, c.lastRecvEntitySpawnID)) c.lastRecvEntitySpawnID = lastRecvEntitySpawnID; if (NetIdUtils.IdMoreRecent(c.lastRecvEntitySpawnID, lastEntitySpawnID)) c.lastRecvEntitySpawnID = lastEntitySpawnID; diff --git a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index a7a0b419e..f07a0a1b3 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -72,8 +72,11 @@ namespace Barotrauma.Networking var newEvent = new ServerEntityEvent(entity, (UInt16)(ID + 1)); if (extraData != null) newEvent.SetData(extraData); - - events.RemoveAll(e => NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll+1),e.ID)); //remove events that have been sent to all clients, they are redundant now + + //remove events that have been sent to all clients, they are redundant now + //keep at least one event in the list (lastSentToAll == e.ID) so we can use it to keep track of the latest ID + events.RemoveAll(e => NetIdUtils.IdMoreRecent(lastSentToAll, e.ID)); + for (int i = events.Count - 1; i >= 0; i--) { //we already have an identical event that's waiting to be sent @@ -139,6 +142,14 @@ namespace Barotrauma.Networking if (toKick != null) toKick.ForEach(c => server.DisconnectClient(c, "", "You have been disconnected because of excessive desync")); } + + if (events.Count > 0) + { + //the client is waiting for an event that we don't have anymore + //(the ID they're expecting is smaller than the ID of the first event in our list) + List toKick = inGameClients.FindAll(c => NetIdUtils.IdMoreRecent(events[0].ID, (UInt16)(c.lastRecvEntityEventID+1))); + if (toKick != null) toKick.ForEach(c => server.DisconnectClient(c, "", "You have been disconnected because of excessive desync")); + } } var timedOutClients = clients.FindAll(c => c.inGame && c.NeedsMidRoundSync && Timing.TotalTime > c.MidRoundSyncTimeOut); @@ -229,7 +240,7 @@ namespace Barotrauma.Networking { startIndex--; } - + for (int i = startIndex; i < eventList.Count; i++) { //find the first event that hasn't been sent in 1.5 * roundtriptime or at all