Better ping implementation.

This commit is contained in:
Steel Titanium 2019-11-17 20:22:47 -05:00
parent 144502729a
commit 2584241a44
No known key found for this signature in database
GPG Key ID: 924BA411F18DFDBE
12 changed files with 99 additions and 32 deletions

View File

@ -90,6 +90,7 @@ SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen
boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
tic_t servermaxping = 800; // server's max ping. Defaults to 800
static tic_t nettics[MAXNETNODES]; // what tic the client have received
static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet
static UINT8 nodewaiting[MAXNETNODES];
@ -4208,10 +4209,12 @@ static void HandlePacketFromPlayer(SINT8 node)
//Update client ping table from the server.
if (client)
{
INT32 i;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS];
}
break;
@ -4733,6 +4736,14 @@ void TryRunTics(tic_t realtics)
}
}
/*
Ping Update except better:
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
*/
static INT32 pingtimeout[MAXPLAYERS];
static inline void PingUpdate(void)
{
INT32 i;
@ -4753,6 +4764,8 @@ static inline void PingUpdate(void)
laggers[i] = true;
numlaggers++;
}
else
pingtimeout[i] = 0;
}
//kick lagging players... unless everyone but the server's ping sucks.
@ -4763,12 +4776,27 @@ static inline void PingUpdate(void)
{
if (playeringame[i] && laggers[i])
{
char buf[2];
pingtimeout[i]++;
if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die.
{
char buf[2];
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
pingtimeout[i] = 0;
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
}
}
/*
you aren't lagging,
but you aren't free yet.
In case you'll keep spiking,
we just make the timer go back down. (Very unstable net must still get kicked).
*/
else
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
}
}
}
@ -4783,10 +4811,13 @@ static inline void PingUpdate(void)
realpingtable[i] = 0; //Reset each as we go.
}
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value;
//send out our ping packets
for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
pingmeasurecount = 1; //Reset count
}
@ -4816,7 +4847,7 @@ void NetUpdate(void)
if (server)
{
if (netgame && !(gametime % 255))
if (netgame && !(gametime % 35)) // update once per second.
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)

View File

@ -423,9 +423,9 @@ typedef struct
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes
msaskinfo_pak msaskinfo; // 22 bytes
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
} u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t;
@ -487,6 +487,7 @@ extern tic_t jointimeout;
extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;

View File

@ -341,6 +341,14 @@ consvar_t cv_nettimeout = {"nettimeout", "350", CV_CALL|CV_SAVE, nettimeout_cons
static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_maxping = {"maxping", "0", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Warning", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_inttime = {"inttime", "10", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -577,6 +585,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_skipmapcheck);
CV_RegisterVar(&cv_sleep);
CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#ifdef SEENAMES
CV_RegisterVar(&cv_allowseenames);

View File

@ -106,6 +106,9 @@ extern consvar_t cv_ringslinger, cv_soundtest;
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping;
extern consvar_t cv_skipmapcheck;

View File

@ -98,6 +98,9 @@ void I_FinishUpdate (void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//blast it to the screen
// this code sucks
//memcpy(dascreen,screens[0],screenwidth*screenheight);

View File

@ -2322,7 +2322,7 @@ void HU_Erase(void)
//
// HU_drawPing
//
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext)
{
UINT8 numbars = 1; // how many ping bars do we draw?
UINT8 barcolor = 35; // color we use for the bars (green, yellow or red)

View File

@ -113,7 +113,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);

View File

@ -1224,32 +1224,33 @@ static menuitem_t OP_VideoOptionsMenu[] =
NULL, "HUD Transparency", &cv_translucenthud, 66},
{IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71},
{IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to.
#ifdef SEENAMES
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81},
{IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86},
#endif
{IT_HEADER, NULL, "Console", NULL, 90},
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96},
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101},
{IT_HEADER, NULL, "Console", NULL, 95},
{IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101},
{IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 106},
{IT_HEADER, NULL, "Chat", NULL, 110},
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 116},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 121},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 126},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 131},
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 136},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 141},
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 146},
{IT_HEADER, NULL, "Chat", NULL, 115},
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 121},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Width", &cv_chatwidth, 126},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 131},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 136},
{IT_STRING | IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 141},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 146},
{IT_STRING | IT_CVAR, NULL, "Chat background tint", &cv_chatbacktint, 151},
{IT_HEADER, NULL, "Level", NULL, 155},
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 161},
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 166},
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 171},
{IT_HEADER, NULL, "Level", NULL, 160},
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 166},
{IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 171},
{IT_STRING | IT_CVAR, NULL, "NiGHTS Hoop Draw Dist.", &cv_drawdist_nights, 176},
{IT_HEADER, NULL, "Diagnostic", NULL, 180},
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 186},
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 191},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 196},
{IT_HEADER, NULL, "Diagnostic", NULL, 184},
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 190},
{IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 195},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 200},
};
static menuitem_t OP_VideoModeMenu[] =

View File

@ -428,6 +428,17 @@ void SCR_DisplayTicRate(void)
lasttic = ontic;
}
void SCR_DisplayLocalPing(void)
{
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
if (cv_showping.value == 1 || (cv_showping.value == 2 && servermaxping && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = cv_ticrate.value ? 181 : 190;
HU_drawPing(307, dispy, ping, true);
}
}
void SCR_ClosedCaptions(void)
{
UINT8 i;

View File

@ -167,5 +167,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
void SCR_ClosedCaptions(void);
void SCR_DisplayLocalPing(void);
#undef DNWH
#endif //__SCREEN_H__

View File

@ -1180,6 +1180,9 @@ void I_FinishUpdate(void)
{
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
}
if (rendermode == render_soft && screens[0])

View File

@ -371,6 +371,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//
if (bDIBMode)
{