diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 92196219d..5668ab6b3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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++) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index d7c210895..b85bbfab6 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d750c81f2..f52008aa9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 4821aff46..b88d8c7bb 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -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; diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 6a7641174..56570b7bf 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -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); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 90f4ceedf..d022abd58 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -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) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 55b61d4b7..0860abb48 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -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); diff --git a/src/m_menu.c b/src/m_menu.c index 47ca7ccd4..13f21cd95 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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[] = diff --git a/src/screen.c b/src/screen.c index f1d91de66..659532303 100644 --- a/src/screen.c +++ b/src/screen.c @@ -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; diff --git a/src/screen.h b/src/screen.h index 79f21e8e4..6f03612c4 100644 --- a/src/screen.h +++ b/src/screen.h @@ -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__ diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index fb0f4b2ba..f22c79eca 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -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]) diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 11c7a6744..39a60cd93 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -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) {