From e681a2d29a5a60b94ec37e1565b844f31b447361 Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Wed, 1 Mar 2017 16:40:07 -0300 Subject: [PATCH] Clients that are waiting for very old events are kicked --- Subsurface/Source/GameMain.cs | 1 + Subsurface/Source/Networking/GameServer.cs | 4 ++-- .../Networking/NetEntityEvent/NetEntityEvent.cs | 8 ++++++++ .../NetEntityEvent/ServerEntityEventManager.cs | 11 ++++++++++- Subsurface/Source/Timing.cs | 2 ++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs index a0aa514ef..727c2c07b 100644 --- a/Subsurface/Source/GameMain.cs +++ b/Subsurface/Source/GameMain.cs @@ -298,6 +298,7 @@ namespace Barotrauma /// Provides a snapshot of timing values. protected override void Update(GameTime gameTime) { + Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds; Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; PlayerInput.UpdateVariable(); diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 866af908c..770a77d10 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -1327,7 +1327,7 @@ namespace Barotrauma.Networking } } - private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "") + public void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "") { Client client = connectedClients.Find(x => x.Connection == senderConnection); if (client == null) return; @@ -1335,7 +1335,7 @@ namespace Barotrauma.Networking DisconnectClient(client, msg, targetmsg); } - private void DisconnectClient(Client client, string msg = "", string targetmsg = "") + public void DisconnectClient(Client client, string msg = "", string targetmsg = "") { if (client == null) return; diff --git a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs index 403dcdbd6..c89abf9f0 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs @@ -67,10 +67,18 @@ namespace Barotrauma.Networking public bool Sent; + private double createTime; + public double CreateTime + { + get { return createTime; } + } + public ServerEntityEvent(IServerSerializable entity, UInt32 id) : base(entity, id) { serializable = entity; + + createTime = Timing.TotalTime; } public void Write(NetBuffer msg, Client recipient) diff --git a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index f4a872aae..dc1222dee 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -75,7 +75,7 @@ namespace Barotrauma.Networking var newEvent = new ServerEntityEvent(entity, ID + 1); if (extraData != null) newEvent.SetData(extraData); - events.RemoveAll(e => e.ID <= lastSentToAll); //remove events that , they are redundant now + events.RemoveAll(e => e.ID <= lastSentToAll); //remove events that have been sent to all clients, they are redundant now for (int i = events.Count - 1; i >= 0; i--) { //we already have an identical event that's waiting to be sent @@ -128,6 +128,15 @@ namespace Barotrauma.Networking { lastSentToAll = clients[0].lastRecvEntityEventID; clients.ForEach(c => { if (c.inGame) lastSentToAll = Math.Min(lastSentToAll, c.lastRecvEntityEventID); }); + + ServerEntityEvent firstEventToResend = events.Find(e => e.ID == (lastSentToAll + 1)); + if (firstEventToResend != null && (Timing.TotalTime-firstEventToResend.CreateTime)>10.0f) + { + //it's been 10 seconds since this event was created + //kick everyone that hasn't received it yet, this is way too old + List toKick = clients.FindAll(c => c.inGame && c.lastRecvEntityEventID <= lastSentToAll); + toKick.ForEach(c => GameMain.Server.DisconnectClient(c,"","You have been disconnected because of excessive desync.")); + } } bufferedEvents.RemoveAll(b => b.IsProcessed); diff --git a/Subsurface/Source/Timing.cs b/Subsurface/Source/Timing.cs index c63382813..a2b21c62f 100644 --- a/Subsurface/Source/Timing.cs +++ b/Subsurface/Source/Timing.cs @@ -11,6 +11,8 @@ namespace Barotrauma { private static double alpha; + public static double TotalTime; + public static double Accumulator; public static double Step = 1.0 / 60.0;