- Added edward850's patch to cope with stalled network games.

SVN r4285 (trunk)
This commit is contained in:
Randy Heit 2013-05-25 22:01:26 +00:00
parent 167ee9e7fb
commit 78437d917c
4 changed files with 76 additions and 0 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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<DHUDMessage> Messages[NUM_HUDMSGLAYERS];
bool ShowLog;

View File

@ -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)
{
}