diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index d84759b42..f4251ef08 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1280,6 +1280,7 @@ static void UpdatePingTable(void) } } +// Handle idle and disconnected player timers static void IdleUpdate(void) { INT32 i; @@ -1302,7 +1303,26 @@ static void IdleUpdate(void) } } else + { players[i].lastinputtime = 0; + + if (players[i].quittime && playeringame[i]) + { + players[i].quittime++; + + if (players[i].quittime == 30 * TICRATE && G_TagGametype()) + P_CheckSurvivors(); + + if (server && players[i].quittime >= (tic_t)FixedMul(cv_rejointimeout.value, 60 * TICRATE) + && !(players[i].quittime % TICRATE)) + { + if (D_NumNodes(true) > 0) + SendKick(i, KICK_MSG_PLAYER_QUIT); + else // If the server is empty, don't send a NetXCmd - that would wake an idling dedicated server + CL_RemovePlayer(i, KICK_MSG_PLAYER_QUIT); + } + } + } } } @@ -1623,12 +1643,15 @@ INT32 D_NumPlayers(void) return num; } -/** Returns the number of nodes on the server. +/** Returns the number of currently-connected nodes in a netgame. + * Not necessarily equivalent to D_NumPlayers() minus D_NumBots(). + * + * \param skiphost Skip the server's own node. */ -INT32 D_NumNodes(void) +INT32 D_NumNodes(boolean skiphost) { INT32 num = 0; - for (INT32 ix = 0; ix < MAXNETNODES; ix++) + for (INT32 ix = skiphost ? 1 : 0; ix < MAXNETNODES; ix++) if (netnodes[ix].ingame) num++; return num; diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index f9cbf8876..61823e65d 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -121,7 +121,7 @@ extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; INT32 D_NumPlayers(void); -INT32 D_NumNodes(void); +INT32 D_NumNodes(boolean skiphost); INT32 D_NumBots(void); tic_t GetLag(INT32 node); diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index bfbe30a08..376700f0d 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -109,7 +109,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); // Exclude bots from both counts - netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumNodes() - (dedicated ? 1 : 0)); + netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumNodes(dedicated); netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots()); netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); diff --git a/src/p_tick.c b/src/p_tick.c index 143fa7e36..4ab388486 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -701,25 +701,11 @@ void P_Ticker(boolean run) { INT32 i; - // Increment jointime and quittime even if paused + // Increment jointime even if paused for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) - { players[i].jointime++; - if (players[i].quittime) - { - players[i].quittime++; - - if (players[i].quittime == 30 * TICRATE && G_TagGametype()) - P_CheckSurvivors(); - - if (server && players[i].quittime >= (tic_t)FixedMul(cv_rejointimeout.value, 60 * TICRATE) - && !(players[i].quittime % TICRATE)) - SendKick(i, KICK_MSG_PLAYER_QUIT); - } - } - if (objectplacing) { if (OP_FreezeObjectplace())