Merge branch 'mindelay-client' into 'master'

Fix delay indicator online

See merge request KartKrew/Kart!2311
This commit is contained in:
Oni 2024-05-02 12:58:20 +00:00
commit 32c43044cb
9 changed files with 130 additions and 118 deletions

View file

@ -400,7 +400,6 @@ consvar_t cv_menuframeskip = Player("menuframeskip", "Off").values({
{144, "MAX"}, {144, "MAX"},
{0, "Off"}, {0, "Off"},
}); });
consvar_t cv_mindelay = Player("mindelay", "2").min_max(0, 30);
consvar_t cv_movebob = Player("movebob", "1.0").floating_point().min_max(0, 4*FRACUNIT); consvar_t cv_movebob = Player("movebob", "1.0").floating_point().min_max(0, 4*FRACUNIT);
consvar_t cv_netstat = Player("netstat", "Off").on_off().dont_save(); // show bandwidth statistics consvar_t cv_netstat = Player("netstat", "Off").on_off().dont_save(); // show bandwidth statistics
consvar_t cv_netticbuffer = Player("netticbuffer", "1").min_max(0, 3); consvar_t cv_netticbuffer = Player("netticbuffer", "1").min_max(0, 3);
@ -1202,6 +1201,8 @@ consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = {
Player("kickstartaccel4", "Off").on_off().onchange(weaponPrefChange4) Player("kickstartaccel4", "Off").on_off().onchange(weaponPrefChange4)
}; };
consvar_t cv_mindelay = Player("mindelay", "2").min_max(0, 30).onchange(weaponPrefChange);
extern CV_PossibleValue_t Color_cons_t[]; extern CV_PossibleValue_t Color_cons_t[];
void Color1_OnChange(void); void Color1_OnChange(void);
void Color2_OnChange(void); void Color2_OnChange(void);

View file

@ -123,6 +123,7 @@ UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
UINT32 playerpacketlosstable[MAXPLAYERS]; UINT32 playerpacketlosstable[MAXPLAYERS];
UINT32 playerdelaytable[MAXPLAYERS]; // mindelay values.
#define GENTLEMANSMOOTHING (TICRATE) #define GENTLEMANSMOOTHING (TICRATE)
static tic_t reference_lag; static tic_t reference_lag;
@ -3345,6 +3346,7 @@ void SV_ResetServer(void)
memset(realpingtable, 0, sizeof realpingtable); memset(realpingtable, 0, sizeof realpingtable);
memset(playerpingtable, 0, sizeof playerpingtable); memset(playerpingtable, 0, sizeof playerpingtable);
memset(playerpacketlosstable, 0, sizeof playerpacketlosstable); memset(playerpacketlosstable, 0, sizeof playerpacketlosstable);
memset(playerdelaytable, 0, sizeof playerdelaytable);
ClearAdminPlayers(); ClearAdminPlayers();
Schedule_Clear(); Schedule_Clear();
@ -5279,6 +5281,7 @@ static void HandlePacketFromPlayer(SINT8 node)
{ {
playerpingtable[i] = (tic_t)netbuffer->u.netinfo.pingtable[i]; playerpingtable[i] = (tic_t)netbuffer->u.netinfo.pingtable[i];
playerpacketlosstable[i] = netbuffer->u.netinfo.packetloss[i]; playerpacketlosstable[i] = netbuffer->u.netinfo.packetloss[i];
playerdelaytable[i] = netbuffer->u.netinfo.delay[i];
} }
} }
@ -6263,6 +6266,7 @@ static inline void PingUpdate(void)
} }
netbuffer->u.netinfo.packetloss[i] = lost; netbuffer->u.netinfo.packetloss[i] = lost;
netbuffer->u.netinfo.delay[i] = playerdelaytable[i];
} }
// 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. // 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.
@ -6297,55 +6301,42 @@ static void UpdatePingTable(void)
{ {
if (playeringame[i] && playernode[i] > 0) if (playeringame[i] && playernode[i] > 0)
{ {
if (! server_lagless && playernode[i] > 0 && !players[i].spectator) // TicsToMilliseconds can't handle pings over 1000ms lol
{ realpingtable[i] += GetLag(playernode[i]);
lag = GetLag(playernode[i]);
realpingtable[i] += lag;
if (!players[i].spectator)
{
lag = playerpingtable[i];
if (! fastest || lag < fastest) if (! fastest || lag < fastest)
fastest = lag; fastest = lag;
} }
else
{
// TicsToMilliseconds can't handle pings over 1000ms lol
realpingtable[i] += GetLag(playernode[i]);
}
} }
} }
// Don't gentleman below your mindelay
if (fastest < (tic_t)cv_mindelay.value)
fastest = (tic_t)cv_mindelay.value;
pingmeasurecount++;
if (server_lagless) if (server_lagless)
lowest_lag = 0; lowest_lag = 0;
else else
{
lowest_lag = fastest; lowest_lag = fastest;
if (fastest) // Don't gentleman below your mindelay
lag = fastest; if (lowest_lag < (tic_t)cv_mindelay.value)
else lowest_lag = (tic_t)cv_mindelay.value;
lag = GetLag(0);
lag = ( realpingtable[0] + lag ); pingmeasurecount++;
switch (playerpernode[0]) switch (playerpernode[0])
{ {
case 4: case 4:
realpingtable[nodetoplayer4[0]] = lag; playerdelaytable[nodetoplayer4[0]] = lowest_lag;
/*FALLTHRU*/ /*FALLTHRU*/
case 3: case 3:
realpingtable[nodetoplayer3[0]] = lag; playerdelaytable[nodetoplayer3[0]] = lowest_lag;
/*FALLTHRU*/ /*FALLTHRU*/
case 2: case 2:
realpingtable[nodetoplayer2[0]] = lag; playerdelaytable[nodetoplayer2[0]] = lowest_lag;
/*FALLTHRU*/ /*FALLTHRU*/
case 1: case 1:
realpingtable[nodetoplayer[0]] = lag; playerdelaytable[nodetoplayer[0]] = lowest_lag;
}
} }
} }
else // We're a client, handle mindelay on the way out. else // We're a client, handle mindelay on the way out.

View file

@ -405,6 +405,7 @@ struct netinfo_pak
{ {
UINT32 pingtable[MAXPLAYERS+1]; UINT32 pingtable[MAXPLAYERS+1];
UINT32 packetloss[MAXPLAYERS+1]; UINT32 packetloss[MAXPLAYERS+1];
UINT32 delay[MAXPLAYERS+1];
} ATTRPACK; } ATTRPACK;
// //
@ -546,6 +547,7 @@ extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS];
extern UINT32 playerpacketlosstable[MAXPLAYERS]; extern UINT32 playerpacketlosstable[MAXPLAYERS];
extern UINT32 playerdelaytable[MAXPLAYERS];
extern tic_t servermaxping; extern tic_t servermaxping;
extern boolean server_lagless; extern boolean server_lagless;

View file

@ -1276,7 +1276,11 @@ void WeaponPref_Send(UINT8 ssplayer)
if (gamecontrolflags[ssplayer] & GCF_ANALOGSTICK) if (gamecontrolflags[ssplayer] & GCF_ANALOGSTICK)
prefs |= WP_ANALOGSTICK; prefs |= WP_ANALOGSTICK;
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, &prefs, 1); UINT8 buf[2];
buf[0] = prefs;
buf[1] = cv_mindelay.value;
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, sizeof buf);
} }
void WeaponPref_Save(UINT8 **cp, INT32 playernum) void WeaponPref_Save(UINT8 **cp, INT32 playernum)
@ -1338,6 +1342,13 @@ static void Got_WeaponPref(const UINT8 **cp,INT32 playernum)
{ {
*cp += WeaponPref_Parse(*cp, playernum); *cp += WeaponPref_Parse(*cp, playernum);
UINT8 mindelay = READUINT8(*cp);
if (server)
{
for (UINT8 i = 0; i < G_LocalSplitscreenPartySize(playernum); ++i)
playerdelaytable[G_LocalSplitscreenPartyMember(playernum, i)] = mindelay;
}
// SEE ALSO g_demo.c // SEE ALSO g_demo.c
demo_extradata[playernum] |= DXD_WEAPONPREF; demo_extradata[playernum] |= DXD_WEAPONPREF;
} }

View file

@ -2183,6 +2183,31 @@ Ping_gfx_color (int lag)
return SKINCOLOR_MAGENTA; return SKINCOLOR_MAGENTA;
} }
static const UINT8 *
Ping_gfx_colormap (UINT32 ping, UINT32 lag)
{
const UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
if (servermaxping && ping > servermaxping && hu_tick < 4)
{
// flash ping red if too high
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
}
return colormap;
}
static UINT32
Ping_conversion (UINT32 lag)
{
if (cv_pingmeasurement.value)
{
lag = (INT32)(lag * (1000.00f / TICRATE));
}
return lag;
}
static int static int
PL_gfx_color (int pl) PL_gfx_color (int pl)
{ {
@ -2199,30 +2224,20 @@ PL_gfx_color (int pl)
// //
// HU_drawPing // HU_drawPing
// //
void HU_drawPing(fixed_t x, fixed_t y, UINT32 lag, UINT32 pl, INT32 flags, boolean offline, SINT8 toside) void HU_drawPing(fixed_t x, fixed_t y, UINT32 ping, UINT32 mindelay, UINT32 pl, INT32 flags, SINT8 toside)
{ {
UINT8 *colormap = NULL; const UINT8 *colormap = NULL;
INT32 measureid = cv_pingmeasurement.value ? 1 : 0; INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
INT32 gfxnum; // gfx to draw patch_t *gfx; // gfx to draw
boolean drawlocal = (offline && cv_mindelay.value && lag <= (tic_t)cv_mindelay.value);
fixed_t x2, y2; fixed_t x2, y2;
UINT32 lag = max(ping, mindelay);
if (!server && lag <= (tic_t)cv_mindelay.value)
{
lag = cv_mindelay.value;
drawlocal = true;
}
x2 = x; x2 = x;
y2 = y + FRACUNIT; y2 = y + FRACUNIT;
if (toside == 0) if (toside == 0)
{ {
if (measureid == 1) if (measureid == 0)
{
x2 += ((11 - pingmeasure[measureid]->width) * FRACUNIT);
}
else
{ {
x2 += (10 * FRACUNIT); x2 += (10 * FRACUNIT);
} }
@ -2231,11 +2246,50 @@ void HU_drawPing(fixed_t x, fixed_t y, UINT32 lag, UINT32 pl, INT32 flags, boole
} }
else if (toside > 0) else if (toside > 0)
{ {
x2 += (20 * FRACUNIT); // V_DrawPingNum
} const fixed_t w = (fontv[PINGNUM_FONT].font[0]->width) * FRACUNIT - FRACUNIT;
//else if (toside < 0) x2 += (16 * FRACUNIT) + (int)(log(Ping_conversion(lag)) / log(10)) * w;
gfxnum = Ping_gfx_num(lag); if (measureid == 0)
{
x2 += (4 * FRACUNIT);
}
}
else if (toside < 0)
{
if (measureid == 1)
{
x2 -= (pingmeasure[measureid]->width * FRACUNIT);
}
}
if (ping <= mindelay)
{
gfx = pinglocal[0];
}
else
{
gfx = pinggfx[Ping_gfx_num(ping)];
}
if (pl)
{
V_DrawFill(
-gfx->leftoffset + x/FRACUNIT + 2 - 1,
-gfx->topoffset + y/FRACUNIT - 1,
gfx->width + 2,
gfx->height + 2,
PL_gfx_color(pl) | flags
);
}
V_DrawFixedPatch(
x + (2 * FRACUNIT),
y,
FRACUNIT, flags,
gfx,
NULL
);
if (measureid == 1) if (measureid == 1)
{ {
@ -2248,55 +2302,12 @@ void HU_drawPing(fixed_t x, fixed_t y, UINT32 lag, UINT32 pl, INT32 flags, boole
); );
} }
if (pl) colormap = Ping_gfx_colormap(ping, lag);
{
V_DrawFill(
x/FRACUNIT + 2 - 1,
y/FRACUNIT - 1,
pinggfx[gfxnum]->width + 2,
pinggfx[gfxnum]->height + 2,
PL_gfx_color(pl) | flags
);
}
if (drawlocal)
{
V_DrawFixedPatch(
x + (2 * FRACUNIT),
y,
FRACUNIT, flags,
pinglocal[0],
NULL
);
}
else
{
V_DrawFixedPatch(
x + (2 * FRACUNIT),
y,
FRACUNIT, flags,
pinggfx[gfxnum],
NULL
);
}
colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
if (servermaxping && lag > servermaxping && hu_tick < 4)
{
// flash ping red if too high
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
}
if (cv_pingmeasurement.value)
{
lag = (INT32)(lag * (1000.00f / TICRATE));
}
x2 = V_DrawPingNum( x2 = V_DrawPingNum(
x2, x2,
y2, y2,
flags, lag, flags, Ping_conversion(lag),
colormap colormap
); );
@ -2313,7 +2324,7 @@ void HU_drawPing(fixed_t x, fixed_t y, UINT32 lag, UINT32 pl, INT32 flags, boole
} }
void void
HU_drawMiniPing (INT32 x, INT32 y, UINT32 lag, INT32 flags) HU_drawMiniPing (INT32 x, INT32 y, UINT32 ping, UINT32 mindelay, INT32 flags)
{ {
patch_t *patch; patch_t *patch;
INT32 w = BASEVIDWIDTH; INT32 w = BASEVIDWIDTH;
@ -2323,16 +2334,10 @@ HU_drawMiniPing (INT32 x, INT32 y, UINT32 lag, INT32 flags)
w /= 2; w /= 2;
} }
// This looks kinda dumb, but basically: if (ping <= mindelay)
// Servers with mindelay set modify the ping table. patch = pinglocal[1]; // stone shoe
// Clients with mindelay unset don't, because they can't.
// Both are affected by mindelay, but a client's lag value is pre-adjustment.
if (server && cv_mindelay.value && (tic_t)cv_mindelay.value <= lag)
patch = pinglocal[1];
else if (!server && cv_mindelay.value && (tic_t)cv_mindelay.value >= lag)
patch = pinglocal[1];
else else
patch = mping[Ping_gfx_num(lag)]; patch = mping[Ping_gfx_num(ping)];
if (( flags & V_SNAPTORIGHT )) if (( flags & V_SNAPTORIGHT ))
x += ( w - SHORT (patch->width) ); x += ( w - SHORT (patch->width) );

View file

@ -156,8 +156,8 @@ void HU_TickSongCredits(void);
char HU_dequeueChatChar(void); char HU_dequeueChatChar(void);
void HU_Erase(void); void HU_Erase(void);
void HU_clearChatChars(void); void HU_clearChatChars(void);
void HU_drawPing(fixed_t x, fixed_t y, UINT32 ping, UINT32 packetloss, INT32 flags, boolean offline, SINT8 toside); // Lat': Ping drawer for scoreboard. void HU_drawPing(fixed_t x, fixed_t y, UINT32 ping, UINT32 lag, UINT32 packetloss, INT32 flags, SINT8 toside); // Lat': Ping drawer for scoreboard.
void HU_drawMiniPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); void HU_drawMiniPing(INT32 x, INT32 y, UINT32 ping, UINT32 lag, INT32 flags);
// CECHO interface. // CECHO interface.
void HU_ClearCEcho(void); void HU_ClearCEcho(void);

View file

@ -5538,7 +5538,9 @@ void K_drawKartFreePlay(void)
static void static void
Draw_party_ping (int ss, INT32 snap) Draw_party_ping (int ss, INT32 snap)
{ {
HU_drawMiniPing(0, 0, playerpingtable[displayplayers[ss]], V_SPLITSCREEN|V_SNAPTOTOP|snap); UINT32 ping = playerpingtable[displayplayers[ss]];
UINT32 mindelay = playerdelaytable[displayplayers[ss]];
HU_drawMiniPing(0, 0, ping, mindelay, V_SPLITSCREEN|V_SNAPTOTOP|snap);
} }
static void static void

View file

@ -577,13 +577,13 @@ void SCR_DisplayLocalPing(void)
return; return;
} }
UINT32 mindelay = playerdelaytable[consoleplayer];
UINT32 ping = playerpingtable[consoleplayer]; UINT32 ping = playerpingtable[consoleplayer];
UINT32 pl = playerpacketlosstable[consoleplayer]; UINT32 pl = playerpacketlosstable[consoleplayer];
INT32 dispy = cv_ticrate.value ? 170 : 181; INT32 dispy = cv_ticrate.value ? 170 : 181;
boolean offline = (consoleplayer == serverplayer);
HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, pl, V_SNAPTORIGHT | V_SNAPTOBOTTOM, offline, 0); HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, mindelay, pl, V_SNAPTORIGHT | V_SNAPTOBOTTOM, 0);
} }

View file

@ -716,14 +716,14 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset)
kp_cpu kp_cpu
);*/ );*/
} }
else if (pnum != serverplayer || !server_lagless) else
{ {
HU_drawPing( HU_drawPing(
(x2 - 2) * FRACUNIT, (y-2) * FRACUNIT, (x2 - 2) * FRACUNIT, (y-2) * FRACUNIT,
playerpingtable[pnum], playerpingtable[pnum],
playerdelaytable[pnum],
playerpacketlosstable[pnum], playerpacketlosstable[pnum],
0, 0,
false,
(datarightofcolumn ? 1 : -1) (datarightofcolumn ? 1 : -1)
); );
} }