Update in-game server browser

Based on https://git.do.srb2.org/KartKrew/Kart-Public/-/merge_requests/313 with some tweaks to match our codebase. No page switch animation cus lazy and don't feel like adpating it to cvars
This commit is contained in:
NepDisk 2025-09-21 20:36:38 -04:00
parent 76c17ec7b9
commit 7a86b59fc8
4 changed files with 181 additions and 86 deletions

View file

@ -1424,6 +1424,10 @@ static void SendAskInfo(INT32 node)
serverelem_t serverlist[MAXSERVERLIST];
UINT32 serverlistcount = 0;
UINT32 serverlistultimatecount = 0;
static boolean resendserverlistnode[MAXNETNODES];
static tic_t serverlistepoch;
static void SL_ClearServerList(INT32 connectedserver)
{
@ -1436,6 +1440,7 @@ static void SL_ClearServerList(INT32 connectedserver)
serverlist[i].node = 0;
}
serverlistcount = 0;
memset(resendserverlistnode, 0, sizeof resendserverlistnode);
M_UpdateNumServerPages();
}
@ -1453,6 +1458,8 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
{
UINT32 i;
resendserverlistnode[node] = false;
// search if not already on it
i = SL_SearchServer(node);
if (i == UINT32_MAX)
@ -1493,6 +1500,8 @@ void CL_QueryServerList (msg_server_t *server_list)
CL_UpdateServerList();
serverlistepoch = I_GetTime();
for (i = 0; server_list[i].header.buffer[0]; i++)
{
// Make sure MS version matches our own, to
@ -1505,19 +1514,42 @@ void CL_QueryServerList (msg_server_t *server_list)
if (node == -1)
break; // no more node free
SendAskInfo(node);
// Force close the connection so that servers can't eat
// up nodes forever if we never get a reply back from them
// (usually when they've not forwarded their ports).
//
// Don't worry, we'll get in contact with the working
// servers again when they send SERVERINFO to us later!
//
// (Note: as a side effect this probably means every
// server in the list will probably be using the same node (e.g. node 1),
// not that it matters which nodes they use when
// the connections are closed afterwards anyway)
// -- Monster Iestyn 12/11/18
Net_CloseConnection(node|FORCECLOSE);
resendserverlistnode[node] = true;
// Leave this node open. It'll be closed if the
// request times out (CL_TimeoutServerList).
}
}
serverlistultimatecount = i;
}
#define SERVERLISTRESENDRATE NEWTICRATE
void CL_TimeoutServerList(void)
{
if (netgame && serverlistultimatecount > serverlistcount)
{
const tic_t timediff = I_GetTime() - serverlistepoch;
const tic_t timetoresend = timediff % SERVERLISTRESENDRATE;
const boolean timedout = timediff > connectiontimeout;
if (timedout || (timediff > 0 && timetoresend == 0))
{
INT32 node;
for (node = 1; node < MAXNETNODES; ++node)
{
if (resendserverlistnode[node])
{
if (timedout)
Net_CloseConnection(node|FORCECLOSE);
else
SendAskInfo(node);
}
}
if (timedout)
serverlistultimatecount = serverlistcount;
}
}
}

View file

@ -425,6 +425,7 @@ struct serverelem_t
extern serverelem_t serverlist[MAXSERVERLIST];
extern UINT32 serverlistcount;
extern UINT32 serverlistultimatecount;
extern INT32 mapchangepending;
// Points inside doomcom
@ -569,6 +570,7 @@ void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(void);
void CL_TimeoutServerList(void);
// Is there a game running
boolean Playing(void);

View file

@ -90,8 +90,8 @@
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
#define ASSET_HASH_MAIN_PK3 0xeaa452402eb0fcc9
#define ASSET_HASH_MAPPATCH_PK3 0xefe28bb9de73a31c
#define ASSET_HASH_MAIN_PK3 0xbc84ba70b57f39b4
#define ASSET_HASH_MAPPATCH_PK3 0xb15b03c61e08d93b
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
#ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 0x0000000000000000

View file

@ -2124,6 +2124,8 @@ void M_Ticker(void)
}
I_unlock_mutex(ms_ServerList_mutex);
#endif
CL_TimeoutServerList();
}
//
@ -6169,10 +6171,6 @@ INT32 MR_Refresh(INT32 choice)
{
(void)choice;
// Display a little "please wait" message.
M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, MENUCAPS, "Searching for servers...");
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, MENUCAPS, "Please wait.");
I_OsPolling();
I_UpdateNoBlit();
if (rendermode == render_soft)
@ -6181,102 +6179,162 @@ INT32 MR_Refresh(INT32 choice)
// first page of servers
CV_SetValue(&cv_dummyserverpage, 0);
CL_UpdateServerList();
#ifdef MASTERSERVER
#ifdef HAVE_THREADS
Spawn_masterserver_thread("fetch-servers", Fetch_servers_thread);
#else/*HAVE_THREADS*/
Fetch_servers_thread(NULL);
#endif/*HAVE_THREADS*/
#else/*MASTERSERVER*/
CL_UpdateServerList();
#endif/*MASTERSERVER*/
return true;
}
static void MD_DrawServerCountAndHorizontalBar(void)
{
const char *text;
INT32 radius;
INT32 center = BASEVIDWIDTH/2;
switch (M_GetWaitingMode())
{
case M_WAITING_VERSION:
text = "Checking for updates";
break;
case M_WAITING_SERVERS:
text = "Loading server list";
break;
default:
if (serverlistultimatecount > serverlistcount)
{
text = va("%d/%d servers found%.*s",
serverlistcount,
serverlistultimatecount,
I_GetTime() / NEWTICRATE % 4, "...");
}
else if (serverlistcount > 0)
{
text = va("%d server%s found", serverlistcount, serverlistcount > 1 ? "s" : "");
}
else
{
text = "No servers found";
}
}
radius = V_StringWidth(text, 0) / 2;
V_DrawCenteredString(center, currentMenu->y+28, 0, text);
// Horizontal line!
V_DrawFill(1, currentMenu->y+32, center - radius - 2, 1, 0);
V_DrawFill(center + radius + 2, currentMenu->y+32, BASEVIDWIDTH - 1, 1, 0);
}
static void M_DrawServerLines(INT32 x, INT32 page)
{
UINT16 i;
char gametype[30];
char pwr[13];
INT16 firstserverline = M_GetMenuIndex(MN_MP_CONNECT, "LINE1");
UINT32 serversperpage = M_ServersPerPage(); // server sperpage?
menu_t *conmenu = &menudefs[MN_MP_CONNECT]; // meh, whatever
for (i = 0; i < min(serverlistcount - page * serversperpage, serversperpage); i++)
{
INT32 slindex = i + page * serversperpage;
UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0)
|((itemOn == firstserverline+i) ? highlightflags : 0)|V_ALLOWLOWERCASE;
// min width is probably like 268px (sorry for shitty formatting)
V_DrawFill(x - 3,
S_LINEY(i) - (i == 0 ? 3 : 0),
268 + 6, (i == 0 ? 15 : 12),
(itemOn == firstserverline+i) ? 153 : ((i & 1) ? 159 : 156)
);
V_DrawString(x, S_LINEY(i), globalflags, serverlist[slindex].info.servername);
V_DrawSmallString(x, S_LINEY(i)+8, globalflags,
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
V_DrawSmallString(x+44,S_LINEY(i)+8, globalflags,
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
sprintf(gametype, "%s (%s)", serverlist[slindex].info.gametypename, kartspeed_cons_t[(serverlist[slindex].info.kartvars & SV_SPEEDMASK)+1].strvalue);
V_DrawSmallString(x+108, S_LINEY(i)+8, globalflags, gametype);
if (serverlist[slindex].info.avgpwrlv == -1)
sprintf(pwr, "PWR.LV: Off");
else if (serverlist[slindex].info.avgpwrlv > 0)
sprintf(pwr, "PWR.LV: %04d", serverlist[slindex].info.avgpwrlv);
else
sprintf(pwr, "PWR.LV: ----");
V_DrawSmallString(x+181, S_LINEY(i)+8, globalflags, pwr);
// Don't use color flags intentionally, the global yellow color will auto override the text color code
if (serverlist[slindex].info.modifiedgame)
V_DrawSmallString(x+228, S_LINEY(i)+8, globalflags, "\x85" "Mod");
if (serverlist[slindex].info.cheatsenabled)
V_DrawSmallString(x+244, S_LINEY(i)+8, globalflags, "\x83" "Cheats");
conmenu->menuitems[i+firstserverline].status &= ~IT_HIDDEN;
}
}
//static float serverlistslidex;
//INT32 oldserverlistpage;
void MD_DrawConnectMenu(void)
{
UINT16 i;
//const char *gt = "Unknown";
//const char *spd = "";
const char *pwr = "----";
INT16 firstserverline = M_GetMenuIndex(MN_MP_CONNECT, "LINE1");
UINT32 serversperpage = M_ServersPerPage(); // server sperpage?
int waiting;
INT32 mservflags = V_ALLOWLOWERCASE;
menu_t *conmenu = &menudefs[MN_MP_CONNECT]; // meh, whatever
for (i = firstserverline; i < firstserverline+serversperpage; i++)
conmenu->menuitems[i].status |= IT_HIDDEN;
if (serverlistcount <= 0)
V_DrawString(currentMenu->x,currentMenu->y+SERVERHEADERHEIGHT, MENUCAPS, "No servers found");
// Did you change the Server Browser address? Have a little reminder.
if (CV_IsSetToDefault(&cv_masterserver))
mservflags = mservflags|highlightflags|V_30TRANS;
else
for (i = 0; i < min(serverlistcount - cv_dummyserverpage.value * serversperpage, serversperpage); i++)
mservflags = mservflags|warningflags;
V_DrawRightAlignedSmallString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+3 + M_GetMenuItem(MN_MP_CONNECT, "REFRESH")->y,
mservflags, va("MS: %s", cv_masterserver.string));
// When switching pages, slide the old page and the
// new page across the screen
/*if (oldserverlistpage != cv_dummyserverpage.value)
{
INT32 slindex = i + cv_dummyserverpage.value * serversperpage;
UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0)
|((itemOn == firstserverline+i) ? highlightflags : 0)|V_ALLOWLOWERCASE;
const float ease = serverlistslidex / 2.f;
const INT32 offx = serverlistslidex > 0 ? BASEVIDWIDTH : -(BASEVIDWIDTH);
const INT32 x = (FLOAT_TO_FIXED(serverlistslidex) + ease * rendertimefrac) / FRACUNIT;
// min width is probably like 268px (sorry for shitty formatting)
V_DrawFill(currentMenu->x - 3,
S_LINEY(i) - (i == 0 ? 3 : 0),
268 + 6, (i == 0 ? 15 : 12),
(itemOn == firstserverline+i) ? 153 : ((i & 1) ? 159 : 156)
);
M_DrawServerLines(currentMenu->x + x - offx, oldserverlistpage);
M_DrawServerLines(currentMenu->x + x, cv_dummyserverpage.value);
V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername);
V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags,
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
V_DrawSmallString(currentMenu->x+44,S_LINEY(i)+8, globalflags,
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
V_DrawSmallString(currentMenu->x+108, S_LINEY(i)+8, globalflags, serverlist[slindex].info.gametypename);
// display game speed for race gametypes
/* todo: send if the gametype is GTR_CIRCUIT, and uses game speed
if (serverlist[slindex].info.gametype == GT_RACE)
if (renderisnewtic)
{
spd = kartspeed_cons_t[(serverlist[slindex].info.kartvars & SV_SPEEDMASK)+1].strvalue;
V_DrawSmallString(currentMenu->x+128, S_LINEY(i)+8, globalflags, va("(%s)", spd));
serverlistslidex -= ease;
if ((INT32)serverlistslidex == 0)
oldserverlistpage = serverlistpage;
}
*/
pwr = "----";
if (serverlist[slindex].info.avgpwrlv == -1)
pwr = "Off";
else if (serverlist[slindex].info.avgpwrlv > 0)
pwr = va("%04d", serverlist[slindex].info.avgpwrlv);
V_DrawSmallString(currentMenu->x+171, S_LINEY(i)+8, globalflags, va("Power Level: %s", pwr));
// Don't use color flags intentionally, the global yellow color will auto override the text color code
if (serverlist[slindex].info.modifiedgame)
V_DrawSmallString(currentMenu->x+245, S_LINEY(i)+8, globalflags, "\x85" "Mod");
if (serverlist[slindex].info.cheatsenabled)
V_DrawSmallString(currentMenu->x+265, S_LINEY(i)+8, globalflags, "\x83" "Cheats");
conmenu->menuitems[i+firstserverline].status &= ~IT_HIDDEN;
}
else*/
{
M_DrawServerLines(currentMenu->x, cv_dummyserverpage.value);
}
MD_DrawServerCountAndHorizontalBar();
MD_DrawGenericMenu();
waiting = M_GetWaitingMode();
if (waiting)
{
const char *message;
if (waiting == M_WAITING_VERSION)
message = "Checking for updates...";
else
message = "Searching for servers...";
// Display a little "please wait" message.
M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, MENUCAPS, message);
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, MENUCAPS, "Please wait.");
}
}
INT32 MR_CancelConnect(INT32 choice)
@ -6409,6 +6467,9 @@ static void M_ConnectMenu(INT32 choice)
// first page of servers
CV_SetValue(&cv_dummyserverpage, 0);
CL_UpdateServerList();
M_EnterMenu(MN_MP_CONNECT, true, 0);
M_SetItemOn(MN_MP_CONNECT, "SORTING");
@ -6438,7 +6499,7 @@ static void M_ConnectMenu(INT32 choice)
#ifdef UPDATE_ALERT
M_CheckMODVersion(0);
#endif/*UPDATE_ALERT*/
M_Refresh(0);
MR_Refresh(0);
#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/
}