mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
Further refinements to network balancing
- Added delay times of all players to the scoreboard - Removed balancing from packet-server (tried it, didn't work) - Calculations remove an extra tic to account for possible bias
This commit is contained in:
parent
542b8a7171
commit
97586c317e
5 changed files with 41 additions and 30 deletions
|
@ -110,6 +110,7 @@ unsigned int lastrecvtime[MAXPLAYERS]; // [RH] Used for pings
|
||||||
unsigned int currrecvtime[MAXPLAYERS];
|
unsigned int currrecvtime[MAXPLAYERS];
|
||||||
unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved.
|
unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved.
|
||||||
bool hadlate;
|
bool hadlate;
|
||||||
|
int netdelay[MAXNETNODES]; // Used for storing network delay times.
|
||||||
|
|
||||||
int nodeforplayer[MAXPLAYERS];
|
int nodeforplayer[MAXPLAYERS];
|
||||||
int playerfornode[MAXNETNODES];
|
int playerfornode[MAXNETNODES];
|
||||||
|
@ -117,7 +118,6 @@ int playerfornode[MAXNETNODES];
|
||||||
int maketic;
|
int maketic;
|
||||||
int skiptics;
|
int skiptics;
|
||||||
int ticdup;
|
int ticdup;
|
||||||
int arb_maketic; // Arbitrators maketic difference
|
|
||||||
|
|
||||||
void D_ProcessEvents (void);
|
void D_ProcessEvents (void);
|
||||||
void G_BuildTiccmd (ticcmd_t *cmd);
|
void G_BuildTiccmd (ticcmd_t *cmd);
|
||||||
|
@ -152,7 +152,7 @@ CUSTOM_CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CVAR(Bool, net_loadbalance, true, CVAR_SERVERINFO)
|
CVAR(Bool, net_ticbalance, false, CVAR_SERVERINFO)
|
||||||
|
|
||||||
// [RH] Special "ticcmds" get stored in here
|
// [RH] Special "ticcmds" get stored in here
|
||||||
static struct TicSpecial
|
static struct TicSpecial
|
||||||
|
@ -350,7 +350,7 @@ int NetbufferSize ()
|
||||||
k += netbuffer[k] + 1;
|
k += netbuffer[k] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doomcom.remotenode == nodeforplayer[Net_Arbitrator])
|
// Network delay byte
|
||||||
k++;
|
k++;
|
||||||
|
|
||||||
if (netbuffer[0] & NCMD_MULTI)
|
if (netbuffer[0] & NCMD_MULTI)
|
||||||
|
@ -791,10 +791,8 @@ void GetPackets (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netconsole == Net_Arbitrator)
|
// Pull current network delay from node
|
||||||
{
|
netdelay[netnode] = netbuffer[k++];
|
||||||
arb_maketic = netbuffer[k++];
|
|
||||||
}
|
|
||||||
|
|
||||||
playerbytes[0] = netconsole;
|
playerbytes[0] = netconsole;
|
||||||
if (netbuffer[0] & NCMD_MULTI)
|
if (netbuffer[0] & NCMD_MULTI)
|
||||||
|
@ -1204,11 +1202,9 @@ void NetUpdate (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consoleplayer == Net_Arbitrator)
|
// Send current network delay
|
||||||
{
|
|
||||||
// The number of tics we just made should be removed from the count.
|
// The number of tics we just made should be removed from the count.
|
||||||
netbuffer[k++] = ((maketic - newtics - gametic) / ticdup);
|
netbuffer[k++] = ((maketic - numtics - gametic) / ticdup);
|
||||||
}
|
|
||||||
|
|
||||||
if (numtics > 0)
|
if (numtics > 0)
|
||||||
{
|
{
|
||||||
|
@ -1319,16 +1315,16 @@ void NetUpdate (void)
|
||||||
// that it won't adapt. Fortunately, player prediction helps
|
// that it won't adapt. Fortunately, player prediction helps
|
||||||
// alleviate the lag somewhat.
|
// alleviate the lag somewhat.
|
||||||
int average = 0;
|
int average = 0;
|
||||||
if (net_loadbalance)
|
|
||||||
average = (((maketic - newtics - gametic) / ticdup) + arb_maketic) / 2;
|
|
||||||
if (NetMode == NET_PeerToPeer)
|
if (NetMode == NET_PeerToPeer)
|
||||||
{
|
{
|
||||||
|
// Try to guess ahead the time it takes to send responses to the arbitrator
|
||||||
|
// [ED850] It seems that there is a bias based on network adaption (which the netwrok arbitrator doesn't do),
|
||||||
|
// so I have set this up to assume one less tic, which appears to balance it out.
|
||||||
|
if (net_ticbalance)
|
||||||
|
average = ((netdelay[0] + ARBITRATOR_DELAY) / 2) - 1;
|
||||||
mastertics = nettics[nodeforplayer[Net_Arbitrator]] + average;
|
mastertics = nettics[nodeforplayer[Net_Arbitrator]] + average;
|
||||||
}
|
}
|
||||||
else if (NetMode == NET_PacketServer)
|
|
||||||
{
|
|
||||||
mastertics = mastertics + average;
|
|
||||||
}
|
|
||||||
if (nettics[0] <= mastertics)
|
if (nettics[0] <= mastertics)
|
||||||
{
|
{
|
||||||
gametime--;
|
gametime--;
|
||||||
|
@ -2739,7 +2735,7 @@ void Net_SkipCommand (int type, BYTE **stream)
|
||||||
CCMD (pings)
|
CCMD (pings)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Printf("%d (%d ms) arbitrator buffer time\n", arb_maketic * ticdup, (arb_maketic * ticdup) * (1000 / TICRATE));
|
Printf("%d (%d ms) arbitrator buffer time\n", ARBITRATOR_DELAY * ticdup, (ARBITRATOR_DELAY * ticdup) * (1000 / TICRATE));
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i],
|
Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i],
|
||||||
|
|
|
@ -143,7 +143,9 @@ extern struct ticcmd_t localcmds[LOCALCMDTICS];
|
||||||
|
|
||||||
extern int maketic;
|
extern int maketic;
|
||||||
extern int nettics[MAXNETNODES];
|
extern int nettics[MAXNETNODES];
|
||||||
extern int arb_maketic;
|
extern int netdelay[MAXNETNODES];
|
||||||
|
extern int nodeforplayer[MAXPLAYERS];
|
||||||
|
#define ARBITRATOR_DELAY netdelay[nodeforplayer[Net_Arbitrator]]
|
||||||
|
|
||||||
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
||||||
extern int ticdup;
|
extern int ticdup;
|
||||||
|
|
|
@ -935,8 +935,8 @@ static void DrawLatency()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int localdelay = (maketic - gametic) * (1000 / TICRATE);
|
int localdelay = (netdelay[0] * ticdup) * (1000 / TICRATE);
|
||||||
int arbitratordelay = (arb_maketic * ticdup) * (1000 / TICRATE);
|
int arbitratordelay = (ARBITRATOR_DELAY * ticdup) * (1000 / TICRATE);
|
||||||
int color = CR_GREEN;
|
int color = CR_GREEN;
|
||||||
if (MAX(localdelay, arbitratordelay) > 200)
|
if (MAX(localdelay, arbitratordelay) > 200)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "gstrings.h"
|
#include "gstrings.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@
|
||||||
|
|
||||||
static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]);
|
static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]);
|
||||||
static void HU_DrawTimeRemaining (int y);
|
static void HU_DrawTimeRemaining (int y);
|
||||||
static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int, int);
|
static void HU_DrawPlayer(player_t *, bool, int, int, int, int, int, int, int, int, int);
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
|
@ -228,7 +229,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
||||||
int maxnamewidth, maxscorewidth, maxiconheight;
|
int maxnamewidth, maxscorewidth, maxiconheight;
|
||||||
int numTeams = 0;
|
int numTeams = 0;
|
||||||
int x, y, ypadding, bottom;
|
int x, y, ypadding, bottom;
|
||||||
int col2, col3, col4;
|
int col2, col3, col4, col5;
|
||||||
|
|
||||||
if (deathmatch)
|
if (deathmatch)
|
||||||
{
|
{
|
||||||
|
@ -309,12 +310,14 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
||||||
|
|
||||||
const char *text_color = GStrings("SCORE_COLOR"),
|
const char *text_color = GStrings("SCORE_COLOR"),
|
||||||
*text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"),
|
*text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"),
|
||||||
*text_name = GStrings("SCORE_NAME");
|
*text_name = GStrings("SCORE_NAME"),
|
||||||
|
*text_delay = GStrings("SCORE_DELAY");
|
||||||
|
|
||||||
col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac;
|
col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac;
|
||||||
col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac;
|
col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac;
|
||||||
col4 = col3 + maxscorewidth * CleanXfac;
|
col4 = col3 + maxscorewidth * CleanXfac;
|
||||||
x = (SCREENWIDTH >> 1) - ((maxnamewidth * CleanXfac + col4) >> 1);
|
col5 = col4 + (maxnamewidth + 8) * CleanXfac;
|
||||||
|
x = (SCREENWIDTH >> 1) - (((SmallFont->StringWidth(text_delay) * CleanXfac) + col5) >> 1);
|
||||||
|
|
||||||
screen->DrawText (SmallFont, color, x, y, text_color,
|
screen->DrawText (SmallFont, color, x, y, text_color,
|
||||||
DTA_CleanNoMove, true, TAG_DONE);
|
DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
@ -325,6 +328,9 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
||||||
screen->DrawText (SmallFont, color, x + col4, y, text_name,
|
screen->DrawText (SmallFont, color, x + col4, y, text_name,
|
||||||
DTA_CleanNoMove, true, TAG_DONE);
|
DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
|
||||||
|
screen->DrawText(SmallFont, color, x + col5, y, text_delay,
|
||||||
|
DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
|
||||||
y += height + 6 * CleanYfac;
|
y += height + 6 * CleanYfac;
|
||||||
bottom -= height;
|
bottom -= height;
|
||||||
|
|
||||||
|
@ -332,7 +338,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
|
||||||
{
|
{
|
||||||
if (playeringame[sortedplayers[i] - players])
|
if (playeringame[sortedplayers[i] - players])
|
||||||
{
|
{
|
||||||
HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, ypadding, lineheight);
|
HU_DrawPlayer(sortedplayers[i], player == sortedplayers[i], x, col2, col3, col4, col5, maxnamewidth, y, ypadding, lineheight);
|
||||||
y += lineheight + CleanYfac;
|
y += lineheight + CleanYfac;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,7 +383,7 @@ static void HU_DrawTimeRemaining (int y)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int ypadding, int height)
|
static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int col5, int maxnamewidth, int y, int ypadding, int height)
|
||||||
{
|
{
|
||||||
int color;
|
int color;
|
||||||
char str[80];
|
char str[80];
|
||||||
|
@ -387,12 +393,13 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
||||||
// The teamplay mode uses colors to show teams, so we need some
|
// The teamplay mode uses colors to show teams, so we need some
|
||||||
// other way to do highlighting. And it may as well be used for
|
// other way to do highlighting. And it may as well be used for
|
||||||
// all modes for the sake of consistancy.
|
// all modes for the sake of consistancy.
|
||||||
screen->Dim(MAKERGB(200,245,255), 0.125f, col1 - 12*CleanXfac, y - 1, col4 + (maxnamewidth + 24)*CleanXfac, height + 2);
|
screen->Dim(MAKERGB(200,245,255), 0.125f, col1 - 12*CleanXfac, y - 1, col5 + (maxnamewidth + 24)*CleanXfac, height + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
col2 += col1;
|
col2 += col1;
|
||||||
col3 += col1;
|
col3 += col1;
|
||||||
col4 += col1;
|
col4 += col1;
|
||||||
|
col5 += col1;
|
||||||
|
|
||||||
color = HU_GetRowColor(player, highlight);
|
color = HU_GetRowColor(player, highlight);
|
||||||
HU_DrawColorBar(col1, y, height, (int)(player - players));
|
HU_DrawColorBar(col1, y, height, (int)(player - players));
|
||||||
|
@ -412,6 +419,11 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
|
||||||
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(),
|
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(),
|
||||||
DTA_CleanNoMove, true, TAG_DONE);
|
DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
|
||||||
|
mysnprintf(str, countof(str), "%d", (netdelay[nodeforplayer[(int)(player - players)]] * ticdup) * (1000 / TICRATE));
|
||||||
|
|
||||||
|
screen->DrawText(SmallFont, color, col5, y + ypadding, str,
|
||||||
|
DTA_CleanNoMove, true, TAG_DONE);
|
||||||
|
|
||||||
if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ())
|
if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ())
|
||||||
{
|
{
|
||||||
FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()];
|
FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()];
|
||||||
|
|
|
@ -836,6 +836,7 @@ SCORE_BONUS = "BONUS";
|
||||||
SCORE_COLOR = "COLOR";
|
SCORE_COLOR = "COLOR";
|
||||||
SCORE_SECRET = "SECRET";
|
SCORE_SECRET = "SECRET";
|
||||||
SCORE_NAME = "NAME";
|
SCORE_NAME = "NAME";
|
||||||
|
SCORE_DELAY = "DELAY(ms)";
|
||||||
SCORE_KILLS = "KILLS";
|
SCORE_KILLS = "KILLS";
|
||||||
SCORE_FRAGS = "FRAGS";
|
SCORE_FRAGS = "FRAGS";
|
||||||
SCORE_DEATHS = "DEATHS";
|
SCORE_DEATHS = "DEATHS";
|
||||||
|
|
Loading…
Reference in a new issue