Fix Connection Timeouts during Wipes

Keep the connection alive with a specific packet to say we haven't timed out
This commit is contained in:
Sryder 2019-01-30 19:18:51 +00:00
parent 2c6799c52a
commit e63b6aee00
4 changed files with 103 additions and 17 deletions

View file

@ -4083,6 +4083,21 @@ FILESTAMP
else if (resynch_score[node]) else if (resynch_score[node])
--resynch_score[node]; --resynch_score[node];
break; break;
case PT_WIPETIME:
if (client)
break;
// This should probably still timeout though, as the node should always have a player 1 number
if (netconsole == -1)
break;
// If a client sends this it should mean they are done receiving the savegame
sendingsavegame[node] = false;
// As long as clients send keep alives, the server can keep running, so reset the timeout
/// \todo Use a separate cvar for that kind of timeout?
freezetimeout[node] = I_GetTime() + connectiontimeout;
break;
case PT_TEXTCMD: case PT_TEXTCMD:
case PT_TEXTCMD2: case PT_TEXTCMD2:
case PT_TEXTCMD3: case PT_TEXTCMD3:
@ -4586,6 +4601,15 @@ static INT16 Consistancy(void)
return (INT16)(ret & 0xFFFF); return (INT16)(ret & 0xFFFF);
} }
// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_WIPETIME
// used during wipes to tell the server that a node is still connected
static void CL_SendClientKeepAlive(void)
{
netbuffer->packettype = PT_WIPETIME;
HSendPacket(servernode, false, 0, 0);
}
// send the client packet to the server // send the client packet to the server
static void CL_SendClientCmd(void) static void CL_SendClientCmd(void)
{ {
@ -5032,9 +5056,77 @@ static inline void PingUpdate(void)
} }
#endif #endif
static tic_t gametime = 0;
#ifdef NEWPING
static void UpdatePingTable(void)
{
INT32 i;
if (server)
{
if (netgame && !(gametime % 255))
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
pingmeasurecount++;
}
}
#endif
// Handle timeouts to prevent definitive freezes from happenning
static void HandleNodeTimeouts(void)
{
INT32 i;
if (server)
for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
Net_ConnectionTimeout(i);
}
// Keep the network alive while not advancing tics!
void NetKeepAlive(void)
{
tic_t nowtime;
INT32 realtics;
nowtime = I_GetTime();
realtics = nowtime - gametime;
// return if there's no time passed since the last call
if (realtics <= 0) // nothing new to update
return;
#ifdef NEWPING
UpdatePingTable();
#endif
if (server)
CL_SendClientKeepAlive();
// Sryder: What is FILESTAMP???
FILESTAMP
GetPackets();
FILESTAMP
MasterClient_Ticker();
if (client)
{
// send keep alive
CL_SendClientKeepAlive();
// No need to check for resynch because we aren't running any tics
}
// No else because no tics are being run and we can't resynch during this
Net_AckTicker();
HandleNodeTimeouts();
SV_FileSendTicker();
}
void NetUpdate(void) void NetUpdate(void)
{ {
static tic_t gametime = 0;
static tic_t resptime = 0; static tic_t resptime = 0;
tic_t nowtime; tic_t nowtime;
INT32 i; INT32 i;
@ -5056,16 +5148,7 @@ void NetUpdate(void)
gametime = nowtime; gametime = nowtime;
#ifdef NEWPING #ifdef NEWPING
if (server) UpdatePingTable();
{
if (netgame && !(gametime % 255))
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
pingmeasurecount++;
}
#endif #endif
if (client) if (client)
@ -5133,12 +5216,7 @@ FILESTAMP
} }
} }
Net_AckTicker(); Net_AckTicker();
// Handle timeouts to prevent definitive freezes from happenning HandleNodeTimeouts();
if (server)
for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
Net_ConnectionTimeout(i);
nowtime /= NEWTICRATERATIO;
if (nowtime > resptime) if (nowtime > resptime)
{ {
resptime = nowtime; resptime = nowtime;

View file

@ -71,6 +71,7 @@ typedef enum
PT_CLIENT3MIS, PT_CLIENT3MIS,
PT_CLIENT4CMD, // 4P PT_CLIENT4CMD, // 4P
PT_CLIENT4MIS, PT_CLIENT4MIS,
PT_WIPETIME, // Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
// allows HSendPacket(*, true, *, *) to return false. // allows HSendPacket(*, true, *, *) to return false.
@ -538,6 +539,7 @@ void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen
void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player
// Create any new ticcmds and broadcast to other players. // Create any new ticcmds and broadcast to other players.
void NetKeepAlive(void);
void NetUpdate(void); void NetUpdate(void);
void SV_StartSinglePlayerServer(void); void SV_StartSinglePlayerServer(void);

View file

@ -903,6 +903,9 @@ static void DebugPrintpacket(const char *header)
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic),
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom));
break; break;
case PT_WIPETIME:
fprintf(debugfile, " wipetime\n");
break;
case PT_TEXTCMD: case PT_TEXTCMD:
case PT_TEXTCMD2: case PT_TEXTCMD2:
case PT_TEXTCMD3: case PT_TEXTCMD3:

View file

@ -26,6 +26,7 @@
#include "console.h" #include "console.h"
#include "d_main.h" #include "d_main.h"
#include "m_misc.h" // movie mode #include "m_misc.h" // movie mode
#include "d_clisrv.h" // So the network state can be updated during the wipe
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
@ -375,6 +376,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
if (moviemode) if (moviemode)
M_SaveFrame(); M_SaveFrame();
NetKeepAlive(); // Update the network so we don't cause timeouts
} }
WipeInAction = false; WipeInAction = false;
#endif #endif