From ae71f94ed2679ac7c8ba45ea83ace50896aa222c Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 5 Oct 2014 18:04:11 +1300 Subject: [PATCH] Remove disconnecting players safely Players who were disconnecting would be removed outside of the playsims control, causing problems with sector lists. --- src/d_net.cpp | 75 ++++++++++++++------------------------------------ src/d_player.h | 3 +- src/g_game.cpp | 63 ++++++++++++++++++++++++++++++++++++++++-- src/g_game.h | 1 + 4 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index d33f47e38..0e057369c 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -39,7 +39,6 @@ #include "cmdlib.h" #include "s_sound.h" #include "m_cheat.h" -#include "p_effect.h" #include "p_local.h" #include "c_dispatch.h" #include "sbar.h" @@ -670,6 +669,9 @@ void PlayerIsGone (int netnode, int netconsole) { int i; + if (!nodeingame[netnode]) + return; + for (i = netnode + 1; i < doomcom.numnodes; ++i) { if (nodeingame[i]) @@ -680,55 +682,17 @@ void PlayerIsGone (int netnode, int netconsole) doomcom.numnodes = netnode; } + if (playeringame[netconsole]) + { + players[netconsole].playerstate = PST_GONE; + } nodeingame[netnode] = false; - playeringame[netconsole] = false; nodejustleft[netnode] = false; - if (deathmatch) - { - Printf ("%s left the game with %d frags\n", - players[netconsole].userinfo.GetName(), - players[netconsole].fragcount); - } - else - { - Printf ("%s left the game\n", players[netconsole].userinfo.GetName()); - } - - // [RH] Revert each player to their own view if spying through the player who left - for (int ii = 0; ii < MAXPLAYERS; ++ii) - { - if (playeringame[ii] && players[ii].camera == players[netconsole].mo) - { - players[ii].camera = players[ii].mo; - if (ii == consoleplayer && StatusBar != NULL) - { - StatusBar->AttachToPlayer (&players[ii]); - } - } - } - - // [RH] Make the player disappear - FBehavior::StaticStopMyScripts (players[netconsole].mo); - if (players[netconsole].mo != NULL) - { - P_DisconnectEffect (players[netconsole].mo); - players[netconsole].mo->player = NULL; - players[netconsole].mo->Destroy (); - if (!(players[netconsole].mo->ObjectFlags & OF_EuthanizeMe)) - { // We just destroyed a morphed player, so now the original player - // has taken their place. Destroy that one too. - players[netconsole].mo->Destroy(); - } - players[netconsole].mo = NULL; - players[netconsole].camera = NULL; - } - // [RH] Let the scripts know the player left - FBehavior::StaticStartTypedScripts (SCRIPT_Disconnect, NULL, true, netconsole); if (netconsole == Net_Arbitrator) { - bglobal.RemoveAllBots (true); - Printf ("Removed all bots\n"); + bglobal.RemoveAllBots(true); + Printf("Removed all bots\n"); // Pick a new network arbitrator for (int i = 0; i < MAXPLAYERS; i++) @@ -737,20 +701,21 @@ void PlayerIsGone (int netnode, int netconsole) { Net_Arbitrator = i; players[i].settings_controller = true; - Printf ("%s is the new arbitrator\n", players[i].userinfo.GetName()); + Printf("%s is the new arbitrator\n", players[i].userinfo.GetName()); break; } } - if (debugfile && NetMode == NET_PacketServer) + } + + if (debugfile && NetMode == NET_PacketServer) + { + if (Net_Arbitrator == consoleplayer) { - if (Net_Arbitrator == consoleplayer) - { - fprintf (debugfile, "I am the new master!\n"); - } - else - { - fprintf (debugfile, "Node %d is the new master!\n", nodeforplayer[Net_Arbitrator]); - } + fprintf(debugfile, "I am the new master!\n"); + } + else + { + fprintf(debugfile, "Node %d is the new master!\n", nodeforplayer[Net_Arbitrator]); } } diff --git a/src/d_player.h b/src/d_player.h index f50db97b1..4ee147dfe 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -176,7 +176,8 @@ typedef enum PST_LIVE, // Playing or camping. PST_DEAD, // Dead on the ground, view follows killer. PST_REBORN, // Ready to restart/respawn??? - PST_ENTER // [BC] Entered the game + PST_ENTER, // [BC] Entered the game + PST_GONE // Player has left the game } playerstate_t; diff --git a/src/g_game.cpp b/src/g_game.cpp index 2058c2df0..95b0f587d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -76,6 +76,7 @@ #include "d_net.h" #include "d_event.h" #include "p_acs.h" +#include "p_effect.h" #include "m_joy.h" #include "farchive.h" #include "r_renderer.h" @@ -1013,10 +1014,16 @@ void G_Ticker () // do player reborns if needed for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && - (players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER)) + if (playeringame[i]) { - G_DoReborn (i, false); + if ((players[i].playerstate == PST_GONE)) + { + G_DoPlayerPop(i); + } + if ((players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER)) + { + G_DoReborn(i, false); + } } } @@ -1658,6 +1665,56 @@ void G_DoReborn (int playernum, bool freshbot) } } +// +// G_DoReborn +// +void G_DoPlayerPop(int playernum) +{ + playeringame[playernum] = false; + + if (deathmatch) + { + Printf("%s left the game with %d frags\n", + players[playernum].userinfo.GetName(), + players[playernum].fragcount); + } + else + { + Printf("%s left the game\n", players[playernum].userinfo.GetName()); + } + + // [RH] Revert each player to their own view if spying through the player who left + for (int ii = 0; ii < MAXPLAYERS; ++ii) + { + if (playeringame[ii] && players[ii].camera == players[playernum].mo) + { + players[ii].camera = players[ii].mo; + if (ii == consoleplayer && StatusBar != NULL) + { + StatusBar->AttachToPlayer(&players[ii]); + } + } + } + + // [RH] Make the player disappear + FBehavior::StaticStopMyScripts(players[playernum].mo); + if (players[playernum].mo != NULL) + { + P_DisconnectEffect(players[playernum].mo); + players[playernum].mo->player = NULL; + players[playernum].mo->Destroy(); + if (!(players[playernum].mo->ObjectFlags & OF_EuthanizeMe)) + { // We just destroyed a morphed player, so now the original player + // has taken their place. Destroy that one too. + players[playernum].mo->Destroy(); + } + players[playernum].mo = NULL; + players[playernum].camera = NULL; + } + // [RH] Let the scripts know the player left + FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, NULL, true, playernum); +} + void G_ScreenShot (char *filename) { shotfile = filename; diff --git a/src/g_game.h b/src/g_game.h index 051be86b1..4714d8b55 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -81,6 +81,7 @@ enum EFinishLevelType void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags); void G_DoReborn (int playernum, bool freshbot); +void G_DoPlayerPop(int playernum); // Adds pitch to consoleplayer's viewpitch and clamps it void G_AddViewPitch (int look);