Improvements to restoring stalled netgames

- The waiting message is now always cleared, regardless if it needed to
be in the first place. It's a rather simple for-loop so I doubt it
matters.
- Nodes are also cleared from the list if they catch up while other
nodes are still behind.
- "lastglobalrecvtime" is now bumped after the waiting loop if a tic was
successful, rather then bumping it every time a packet was received. It
appears that you can receive a packet before the game knows it stalled,
thus stalling it anyway.
- Instead of comparing the nettics to the local node, all nodes are
tested against gametic+counts (the real reason why the game has
stopped).
- More then one node can be marked as late at any one time.
- In a packet-server game, the arbitrator is now assumed slow, rather
then testing it. There is no point, seeing as we already know the game
has stalled because of it.
This commit is contained in:
Edward Richardson 2013-11-11 20:42:54 +13:00
parent 34457ce737
commit a967b05290

View file

@ -705,8 +705,6 @@ 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;
@ -1827,30 +1825,39 @@ void TryRunTics (void)
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 it's longer then 3 seconds, a node has likely stalled.
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)
{
//Keep the local node in the for loop so we can still log any cases where the local node is /somehow/ late.
//However, we don't send a resend request for sanity reasons.
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 (nodeingame[i] && nettics[i] < gametic + counts)
{
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;
fprintf (debugfile, "%i is slow (%i to %i)\n",
i, nettics[i], gametic+counts);
//Send resend request to the late node. Also mark the node as waiting to display it in the hud.
if(i != 0)
remoteresend[i] = players[playerfornode[i]].waiting = hadlate = true;
}
else
players[playerfornode[i]].waiting = false;
}
}
else
{ //Send a resend request to the Arbitrator, as it's obvious we are stuck here.
if (debugfile)
fprintf (debugfile, "Arbitrator is slow (%i to %i)\n",
Net_Arbitrator, nettics[Net_Arbitrator], gametic+counts);
//Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud.
if(i != 0)
remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true;
}
}
// don't stay in here forever -- give the menu a chance to work
@ -1862,12 +1869,11 @@ void TryRunTics (void)
}
}
if (hadlate)
{
//Tic lowtic is high enough to process this gametic. Clear all possible waiting info
hadlate = false;
for (i = 0; i < MAXPLAYERS; i++)
players[i].waiting = false;
}
lastglobalrecvtime = I_GetTime (false); //Update the last time the game tic'd over
// run the count tics
if (counts > 0)