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;