From 6054901c62e3e0b472d5b8e80d6708ada15d15f9 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Fri, 15 Feb 2019 20:51:44 -0600 Subject: [PATCH] Ping kick changes + other quality of life improvements [REDO] --- src/d_clisrv.c | 43 +++++++++++++++++++++++++++++++++++++------ src/d_clisrv.h | 1 + src/d_netcmd.c | 10 ++++++++++ src/d_netcmd.h | 2 ++ src/hu_stuff.c | 28 ++++++++++++++++++++++++++-- src/m_menu.c | 20 ++++++++++++-------- 6 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 961c1e59..04816fd1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -93,6 +93,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. +tic_t servermaxping = 800; // server's max ping. Defaults to 800 #endif SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) @@ -4355,6 +4356,9 @@ FILESTAMP for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i]; + + servermaxping = (tic_t)netbuffer->u.pingtable[i++]; + CONS_Printf("got server maxping: %d\n", servermaxping); } break; @@ -4997,6 +5001,18 @@ void TryRunTics(tic_t realtics) } #ifdef NEWPING + +/* 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. + + Why do we do that? Well, I'm a person with unfortunately sometimes unstable internet and happen to keep getting kicked very unconveniently for very short high spikes. (700+ ms) + Because my spikes are so high, the average ping is exponentially higher too (700s really add up...!) which leads me to getting kicked for a short burst of spiking. + With this change here, this doesn't happen anymore as it checks if my ping has been CONSISTENTLY bad for long enough before killing me. +*/ + +static INT32 pingtimeout[MAXPLAYERS]; + static inline void PingUpdate(void) { INT32 i; @@ -5017,6 +5033,9 @@ static inline void PingUpdate(void) laggers[i] = true; numlaggers++; } + else + pingtimeout[i] = 0; + } //kick lagging players... unless everyone but the server's ping sucks. @@ -5027,12 +5046,21 @@ static inline void PingUpdate(void) { if (playeringame[i] && laggers[i]) { - XBOXSTATIC char buf[2]; + pingtimeout[i]++; + CONS_Printf("Player %d is lagging, incrementing timeout... %d/%d\n", i, pingtimeout[i], cv_pingtimeout.value); // debug print, don't forget to remove this... - buf[0] = (char)i; - buf[1] = KICK_MSG_PING_HIGH; - SendNetXCmd(XD_KICK, &buf, 2); + if (pingtimeout[i] > cv_pingtimeout.value) // ok your net has been bad for too long, you deserve to die. + { + pingtimeout[i] = 0; + XBOXSTATIC char buf[2]; + + buf[0] = (char)i; + buf[1] = KICK_MSG_PING_HIGH; + SendNetXCmd(XD_KICK, &buf, 2); + } } + else // 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). + pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1); } } } @@ -5047,10 +5075,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[i++] = 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 } @@ -5064,7 +5095,7 @@ static void UpdatePingTable(void) INT32 i; 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++) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 62bd8bc1..04569198 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -519,6 +519,7 @@ extern tic_t jointimeout; extern UINT16 pingmeasurecount; extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; +extern tic_t servermaxping; #endif extern consvar_t diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 438cdcd5..ce54960d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -435,6 +435,14 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co #ifdef NEWPING static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, 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", "15", 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}; + #endif // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; @@ -664,6 +672,8 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_sleep); #ifdef NEWPING CV_RegisterVar(&cv_maxping); + CV_RegisterVar(&cv_pingtimeout); + CV_RegisterVar(&cv_showping); #endif #ifdef SEENAMES diff --git a/src/d_netcmd.h b/src/d_netcmd.h index c590eee6..54c00484 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -145,6 +145,8 @@ extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionb #ifdef NEWPING extern consvar_t cv_maxping; +extern consvar_t cv_pingtimeout; +extern consvar_t cv_showping; #endif extern consvar_t cv_skipmapcheck; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3d8f2383..216d14b0 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2178,6 +2178,22 @@ static void HU_DrawSongCredits(void) V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans< servermaxping)) // only show 2 (warning) if our ping is at a bad level + { + INT32 dispx = cv_ticrate.value ? 260 : 290; + HU_drawPing(dispx, 190, ping, false); + } +} + // Heads up displays drawer, call each frame // void HU_Drawer(void) @@ -2290,6 +2306,9 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } + + // draw the ping if the user wishes to + HU_drawLocalPing(); } //====================================================================== @@ -2376,6 +2395,7 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) SINT8 i = 0; SINT8 yoffset = 6; INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2); + boolean highping = (servermaxping && ping > servermaxping) ? true : false; if (ping < 128) { @@ -2387,13 +2407,17 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext) numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. barcolor = 103; } + else if (highping) // yikes...! + { + numbars = 0; + } if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. - V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping)); + V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|((highping && hu_tick < 4) ? V_REDMAP : 0), va("%dms", ping)); for (i=0; (i<3); i++) // Draw the ping bar { - V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31); + V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, (highping && hu_tick < 4) ? 128 : 31); if (i < numbars) V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor); diff --git a/src/m_menu.c b/src/m_menu.c index d8b1c2d7..966f4fa7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1390,7 +1390,7 @@ static menuitem_t OP_HUDOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "HUD Visibility", &cv_translucenthud, 20}, - {IT_STRING | IT_SUBMENU, NULL, "Online chat options...",&OP_ChatOptionsDef, 35}, + {IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 35}, {IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, @@ -1404,6 +1404,7 @@ static menuitem_t OP_HUDOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120}, }; +// Ok it's still called chatoptions but we'll put ping display in here to be clean static menuitem_t OP_ChatOptionsMenu[] = { // will ANYONE who doesn't know how to use the console want to touch this one? @@ -1417,6 +1418,8 @@ static menuitem_t OP_ChatOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50}, {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 60}, {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70}, + + {IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 90}, // shows ping next to framerate if we want to. }; static menuitem_t OP_GameOptionsMenu[] = @@ -1469,15 +1472,16 @@ static menuitem_t OP_AdvServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40}, {IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", &cv_maxping, 50}, - {IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60}, - {IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70}, + {IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", &cv_pingtimeout, 60}, + {IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 70}, + {IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 80}, - {IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 90}, - {IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 100}, + {IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 100}, + {IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 110}, - {IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 120}, - {IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130}, - {IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140}, + {IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 130}, + {IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 140}, + {IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 150}, }; #endif