From 78437d917c37e4a18a294294f53422aa116a4b83 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 25 May 2013 22:01:26 +0000 Subject: [PATCH] - Added edward850's patch to cope with stalled network games. SVN r4285 (trunk) --- src/d_net.cpp | 40 ++++++++++++++++++++++++++++++++++++ src/d_player.h | 1 + src/g_shared/sbar.h | 1 + src/g_shared/shared_sbar.cpp | 34 ++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/src/d_net.cpp b/src/d_net.cpp index 902d912bb..0ea8e58c5 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -108,6 +108,8 @@ int resendcount[MAXNETNODES]; unsigned int lastrecvtime[MAXPLAYERS]; // [RH] Used for pings unsigned int currrecvtime[MAXPLAYERS]; +unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved. +bool hadlate; int nodeforplayer[MAXPLAYERS]; int playerfornode[MAXNETNODES]; @@ -311,6 +313,8 @@ void Net_ClearBuffers () oldentertics = entertic; gametic = 0; maketic = 0; + + lastglobalrecvtime = 0; } // @@ -700,6 +704,8 @@ void GetPackets (void) } continue; // extra setup packet } + + lastglobalrecvtime = I_GetTime (false); //Update the last time a packet was recieved netnode = doomcom.remotenode; netconsole = playerfornode[netnode] & ~PL_DRONE; @@ -1820,6 +1826,33 @@ void TryRunTics (void) if (lowtic < gametic) I_Error ("TryRunTics: lowtic < gametic"); + // [Ed850] Check to see the last time a packet was recieved. + // If it's longer then 3 seconds, a node has likely stalled. Check which one and re-request its last packet. + if(I_GetTime(false) - lastglobalrecvtime >= TICRATE*3) + { + int latenode = 0; // Node 0 is the local player, and should always be the highest + lastglobalrecvtime = I_GetTime(false); //Bump the count + + if(NetMode == NET_PeerToPeer || consoleplayer == Net_Arbitrator) + { + for (i = 0; i < doomcom.numnodes; i++) + if (nodeingame[i] && nettics[i] < nettics[latenode]) + latenode = i; + } + else if (nodeingame[nodeforplayer[Net_Arbitrator]] && + nettics[nodeforplayer[Net_Arbitrator]] < nettics[0]) + { // Likely a packet server game. Only check the packet host. + latenode = Net_Arbitrator; + } + + if (debugfile) + fprintf (debugfile, "lost tics from %i (%i to %i)\n", + latenode, nettics[latenode], gametic); + + if(latenode != 0) // Send resend request to late node (if not yourself... somehow). Also mark the node as waiting to display it in the hud. + remoteresend[latenode] = players[playerfornode[latenode]].waiting = hadlate = true; + } + // don't stay in here forever -- give the menu a chance to work if (I_GetTime (false) - entertic >= TICRATE/3) { @@ -1829,6 +1862,13 @@ void TryRunTics (void) } } + if (hadlate) + { + hadlate = false; + for (i = 0; i < MAXPLAYERS; i++) + players[i].waiting = false; + } + // run the count tics if (counts > 0) { diff --git a/src/d_player.h b/src/d_player.h index e8c183141..6169dcebf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -404,6 +404,7 @@ public: int timefreezer; // Player has an active time freezer short refire; // refired shots are less accurate short inconsistant; + bool waiting; int killcount, itemcount, secretcount; // for intermission int damagecount, bonuscount;// for screen flashing int hazardcount; // for delayed Strife damage diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 230e457d8..3d8c62001 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -424,6 +424,7 @@ private: bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const; void DrawMessages (int layer, int bottom); void DrawConsistancy () const; + void DrawWaiting () const; TObjPtr Messages[NUM_HUDMSGLAYERS]; bool ShowLog; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index fd543f194..0ceea11a0 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1511,6 +1511,7 @@ void DBaseStatusBar::DrawTopStuff (EHudState state) } DrawMessages (HUDMSGLayer_OverHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); DrawConsistancy (); + DrawWaiting (); if (ShowLog && MustDrawLog(state)) DrawLog (); if (noisedebug) @@ -1612,6 +1613,39 @@ void DBaseStatusBar::DrawConsistancy () const } } +void DBaseStatusBar::DrawWaiting () const +{ + int i; + char conbuff[64], *buff_p; + + if (!netgame) + return; + + buff_p = NULL; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].waiting) + { + if (buff_p == NULL) + { + strcpy (conbuff, "Waiting for:"); + buff_p = conbuff + 12; + } + *buff_p++ = ' '; + *buff_p++ = '1' + i; + *buff_p = 0; + } + } + + if (buff_p != NULL) + { + screen->DrawText (SmallFont, CR_ORANGE, + (screen->GetWidth() - SmallFont->StringWidth (conbuff)*CleanXfac) / 2, + SmallFont->GetHeight()*CleanYfac, conbuff, DTA_CleanNoMove, true, TAG_DONE); + BorderTopRefresh = screen->GetPageCount (); + } +} + void DBaseStatusBar::FlashItem (const PClass *itemtype) { }