From e63b6aee00d48d9f9d2f580fe86d6498a6811ad2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 30 Jan 2019 19:18:51 +0000 Subject: [PATCH 1/4] Fix Connection Timeouts during Wipes Keep the connection alive with a specific packet to say we haven't timed out --- src/d_clisrv.c | 112 +++++++++++++++++++++++++++++++++++++++++-------- src/d_clisrv.h | 2 + src/d_net.c | 3 ++ src/f_wipe.c | 3 ++ 4 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c84faa72..71fdf6fb 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4083,6 +4083,21 @@ FILESTAMP else if (resynch_score[node]) --resynch_score[node]; 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_TEXTCMD2: case PT_TEXTCMD3: @@ -4586,6 +4601,15 @@ static INT16 Consistancy(void) 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 static void CL_SendClientCmd(void) { @@ -5032,9 +5056,77 @@ static inline void PingUpdate(void) } #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) { - static tic_t gametime = 0; static tic_t resptime = 0; tic_t nowtime; INT32 i; @@ -5056,16 +5148,7 @@ void NetUpdate(void) gametime = nowtime; #ifdef NEWPING - 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++; - } + UpdatePingTable(); #endif if (client) @@ -5133,12 +5216,7 @@ FILESTAMP } } Net_AckTicker(); - // Handle timeouts to prevent definitive freezes from happenning - if (server) - for (i = 1; i < MAXNETNODES; i++) - if (nodeingame[i] && freezetimeout[i] < I_GetTime()) - Net_ConnectionTimeout(i); - nowtime /= NEWTICRATERATIO; + HandleNodeTimeouts(); if (nowtime > resptime) { resptime = nowtime; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 39cb8c4d..af507739 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -71,6 +71,7 @@ typedef enum PT_CLIENT3MIS, PT_CLIENT4CMD, // 4P 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 // 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 // Create any new ticcmds and broadcast to other players. +void NetKeepAlive(void); void NetUpdate(void); void SV_StartSinglePlayerServer(void); diff --git a/src/d_net.c b/src/d_net.c index 62301dc1..7c8fc956 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -903,6 +903,9 @@ static void DebugPrintpacket(const char *header) (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); break; + case PT_WIPETIME: + fprintf(debugfile, " wipetime\n"); + break; case PT_TEXTCMD: case PT_TEXTCMD2: case PT_TEXTCMD3: diff --git a/src/f_wipe.c b/src/f_wipe.c index f7a5992a..eaa5a013 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -26,6 +26,7 @@ #include "console.h" #include "d_main.h" #include "m_misc.h" // movie mode +#include "d_clisrv.h" // So the network state can be updated during the wipe #ifdef HWRENDER #include "hardware/hw_main.h" @@ -375,6 +376,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) if (moviemode) M_SaveFrame(); + + NetKeepAlive(); // Update the network so we don't cause timeouts } WipeInAction = false; #endif From dff5cb049f221e474e8f4339bc3df8cb9b01e944 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 2 Feb 2019 21:53:27 +0000 Subject: [PATCH 2/4] rename PT_WIPETIME to PT_BASICKEEPALIVE to be more obvious what it does --- src/d_clisrv.c | 6 +++--- src/d_clisrv.h | 2 +- src/d_net.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 71fdf6fb..961c1e59 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4083,7 +4083,7 @@ FILESTAMP else if (resynch_score[node]) --resynch_score[node]; break; - case PT_WIPETIME: + case PT_BASICKEEPALIVE: if (client) break; @@ -4601,11 +4601,11 @@ static INT16 Consistancy(void) return (INT16)(ret & 0xFFFF); } -// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_WIPETIME +// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE // used during wipes to tell the server that a node is still connected static void CL_SendClientKeepAlive(void) { - netbuffer->packettype = PT_WIPETIME; + netbuffer->packettype = PT_BASICKEEPALIVE; HSendPacket(servernode, false, 0, 0); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index af507739..62bd8bc1 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -71,7 +71,7 @@ typedef enum PT_CLIENT3MIS, PT_CLIENT4CMD, // 4P PT_CLIENT4MIS, - PT_WIPETIME, // Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called + PT_BASICKEEPALIVE,// 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 // allows HSendPacket(*, true, *, *) to return false. diff --git a/src/d_net.c b/src/d_net.c index 7c8fc956..7e16297b 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -903,7 +903,7 @@ static void DebugPrintpacket(const char *header) (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); break; - case PT_WIPETIME: + case PT_BASICKEEPALIVE: fprintf(debugfile, " wipetime\n"); break; case PT_TEXTCMD: From caba5cb02e187aec46e4a8d5b18e7c0b2dfe801c Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 4 Feb 2019 21:54:10 +0000 Subject: [PATCH 3/4] P_NetKeepAlive should also be here because it potentially pauses mid-game! --- src/p_setup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 912791cf..58e13c2e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2857,6 +2857,9 @@ boolean P_SetupLevel(boolean skipprecip) lastwipetic = nowtime; if (moviemode) // make sure we save frames for the white hold too M_SaveFrame(); + + // Keep the network alive + NetKeepAlive(); } ranspecialwipe = 1; @@ -3435,7 +3438,7 @@ boolean P_AddWadFile(const char *wadfilename) // R_AddSkins(wadnum); // faB: wadfile index in wadfiles[] - // + // // edit music defs // S_LoadMusicDefs(wadnum); From 3b61cba1a762bfeb01bbb5899830d6ec97f5943a Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 4 Feb 2019 22:02:40 +0000 Subject: [PATCH 4/4] The string that got away from my memory --- src/d_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_net.c b/src/d_net.c index 7e16297b..6702a60a 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -904,7 +904,7 @@ static void DebugPrintpacket(const char *header) (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); break; case PT_BASICKEEPALIVE: - fprintf(debugfile, " wipetime\n"); + fprintf(debugfile, " keep alive\n"); break; case PT_TEXTCMD: case PT_TEXTCMD2: