Fixed mid-round joining clients automatically getting kicked out because they're missing old events
Now they're kicked out if they're not in sync within 10 seconds of joining, TODO: calculate a reasonable timeout based on the amount of events and/or give the client more time if they keep receiving events
This commit is contained in:
@@ -47,6 +47,8 @@ namespace Barotrauma.Networking
|
|||||||
public float ChatSpamTimer;
|
public float ChatSpamTimer;
|
||||||
public int ChatSpamCount;
|
public int ChatSpamCount;
|
||||||
|
|
||||||
|
public double MidRoundSyncTimeOut;
|
||||||
|
|
||||||
public bool NeedsMidRoundSync;
|
public bool NeedsMidRoundSync;
|
||||||
//how many unique events the client missed before joining the server
|
//how many unique events the client missed before joining the server
|
||||||
public UInt16 UnreceivedEntityEventCount;
|
public UInt16 UnreceivedEntityEventCount;
|
||||||
|
|||||||
@@ -627,13 +627,16 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (gameStarted)
|
if (gameStarted)
|
||||||
{
|
{
|
||||||
if (!c.inGame && c.NeedsMidRoundSync)
|
if (!c.inGame)
|
||||||
{
|
{
|
||||||
//client joined mid-round and has just started up the game
|
if (c.NeedsMidRoundSync)
|
||||||
//check which unique messages they've missed
|
{
|
||||||
entityEventManager.InitClientMidRoundSync(c);
|
//client joined mid-round and has just started up the game
|
||||||
|
//check which unique messages they've missed
|
||||||
|
entityEventManager.InitClientMidRoundSync(c);
|
||||||
|
}
|
||||||
|
c.inGame = true;
|
||||||
}
|
}
|
||||||
c.inGame = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientNetObject objHeader;
|
ClientNetObject objHeader;
|
||||||
|
|||||||
@@ -124,21 +124,26 @@ namespace Barotrauma.Networking
|
|||||||
bufferedEvent.IsProcessed = true;
|
bufferedEvent.IsProcessed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clients.Count > 0)
|
var inGameClients = clients.FindAll(c => c.inGame && !c.NeedsMidRoundSync);
|
||||||
|
if (inGameClients.Count > 0)
|
||||||
{
|
{
|
||||||
lastSentToAll = clients[0].lastRecvEntityEventID;
|
lastSentToAll = inGameClients[0].lastRecvEntityEventID;
|
||||||
clients.ForEach(c => { if (c.inGame && NetIdUtils.IdMoreRecent(lastSentToAll,c.lastRecvEntityEventID)) lastSentToAll = c.lastRecvEntityEventID; });
|
inGameClients.ForEach(c => { if (NetIdUtils.IdMoreRecent(lastSentToAll, c.lastRecvEntityEventID)) lastSentToAll = c.lastRecvEntityEventID; });
|
||||||
|
|
||||||
ServerEntityEvent firstEventToResend = events.Find(e => e.ID == (lastSentToAll + 1));
|
ServerEntityEvent firstEventToResend = events.Find(e => e.ID == (lastSentToAll + 1));
|
||||||
if (firstEventToResend != null && (Timing.TotalTime-firstEventToResend.CreateTime)>10.0f)
|
if (firstEventToResend != null && (Timing.TotalTime - firstEventToResend.CreateTime) > 10.0f)
|
||||||
{
|
{
|
||||||
//it's been 10 seconds since this event was created
|
//it's been 10 seconds since this event was created
|
||||||
//kick everyone that hasn't received it yet, this is way too old
|
//kick everyone that hasn't received it yet, this is way too old
|
||||||
List<Client> toKick = clients.FindAll(c => c.inGame && NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll+1),c.lastRecvEntityEventID));
|
List<Client> toKick = inGameClients.FindAll(c => NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll + 1), c.lastRecvEntityEventID));
|
||||||
if (toKick!=null) toKick.ForEach(c => GameMain.Server.DisconnectClient(c,"","You have been disconnected because of excessive desync"));
|
if (toKick != null) toKick.ForEach(c => server.DisconnectClient(c, "", "You have been disconnected because of excessive desync"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: calculate a reasonable timeout period for midround syncing and/or give the client more time if they're receiving messages
|
||||||
|
var timedOutClients = clients.FindAll(c => c.inGame && c.NeedsMidRoundSync && Timing.TotalTime > c.MidRoundSyncTimeOut);
|
||||||
|
if (timedOutClients != null) timedOutClients.ForEach(c => GameMain.Server.DisconnectClient(c, "", "You have been disconnected because syncing your client with the server took too long."));
|
||||||
|
|
||||||
bufferedEvents.RemoveAll(b => b.IsProcessed);
|
bufferedEvents.RemoveAll(b => b.IsProcessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +254,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
|
client.UnreceivedEntityEventCount = (UInt16)uniqueEvents.Count;
|
||||||
client.NeedsMidRoundSync = true;
|
client.NeedsMidRoundSync = true;
|
||||||
|
client.MidRoundSyncTimeOut = Timing.TotalTime + 10.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user