From 873cff447483c8f396456fbeae7b007b87d30546 Mon Sep 17 00:00:00 2001 From: Indev Date: Tue, 10 Mar 2026 02:27:36 +0300 Subject: [PATCH 1/3] Display information about addon types loaded on server when joining (WIP) --- src/d_clisrv.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netfil.c | 49 +++++++++++++++++++++++++++++++++++ src/d_netfil.h | 12 +++++++++ 3 files changed, 131 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f5e32b2e0..fb665a943 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1154,6 +1154,64 @@ static void CV_LoadPlayerNames(UINT8 **p) } } +static void CL_DrawAddonTypes(void) +{ + INT32 y = 0; + + INT32 addontypes_downloaded[NUMADDONTYPES] = {0}; + + for (INT32 i = 0; i < fileneedednum; ++i) + { + switch (fileneeded[i].status) + { + case FS_FOUND: + case FS_OPEN: + addontypes_downloaded[fileneeded[i].type]++; + break; + + default: + break; + } + } + + for (addontype_t type = 0; type < NUMADDONTYPES; ++type) + { + if (addontypes[type] == 0) + continue; + + INT32 flags = V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE; + + if (addontypes[type] == addontypes_downloaded[type]) + flags |= V_GREENMAP; + else + flags |= V_YELLOWMAP; + + const char *typestr = "Misc"; + + switch (type) + { + case ADDON_SCRIPT: + typestr = "Script"; + break; + + case ADDON_MAP: + typestr = "Map"; + break; + + case ADDON_CHARACTER: + typestr = "Character"; + break; + + default: + break; + } + + V_DrawSmallString(4, 4 + y, flags, va("%s addons", typestr)); + V_DrawRightAlignedSmallString(100, 4 + y, flags, va("%d/%d", addontypes_downloaded[type], addontypes[type])); + y += 6; + } +} + // // CL_DrawConnectionStatus // @@ -1269,6 +1327,8 @@ static void CL_DrawConnectionStatus(void) V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va(" %2u/%2u Files", checkednum, fileneedednum)); + + CL_DrawAddonTypes(); } else if (cl_mode == CL_LOADFILES) { @@ -1292,6 +1352,8 @@ static void CL_DrawConnectionStatus(void) V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va(" %2u/%2u Files", loadcompletednum, fileneedednum)); + + CL_DrawAddonTypes(); } else if (cl_mode == CL_VIEWSERVER) { @@ -1495,6 +1557,8 @@ static void CL_DrawConnectionStatus(void) V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va("%2u/%2u Files ", filedownload.completednum, filedownload.totalnum)); + + CL_DrawAddonTypes(); } else { @@ -1511,6 +1575,8 @@ static void CL_DrawConnectionStatus(void) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP|MENUCAPS, M_GetText("Waiting to download files...")); + + CL_DrawAddonTypes(); } } } @@ -2559,6 +2625,7 @@ static void CL_ServerConnectionSearchTicker(tic_t *asksent) } cl_mode = cv_serverinfoscreen.value ? CL_VIEWSERVER : CL_CHECKFILES; + CL_CheckAddonTypes(); } else { @@ -2612,7 +2679,10 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic case CL_ASKFULLFILELIST: if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved + { cl_mode = cv_serverinfoscreen.value ? CL_VIEWSERVER : CL_CHECKFILES; + CL_CheckAddonTypes(); + } else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent) { if (CL_AskFileList(fileneedednum)) diff --git a/src/d_netfil.c b/src/d_netfil.c index aca8f35ba..8865ab618 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -116,6 +116,8 @@ static I_mutex downloadmutex; #endif char downloaddir[512] = "DOWNLOAD"; +INT32 addontypes[NUMADDONTYPES] = {0}; + file_download_t filedownload = {}; #ifdef HAVE_CURL @@ -135,6 +137,8 @@ HTTP_login *curl_logins = NULL; static void CURLGetFile(void); #endif +static addontype_t GetAddonType(const char *name); + /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. @@ -227,6 +231,9 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi fileneeded[i].file = NULL; // The file isn't open yet READSTRINGL(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum + + // Should be good place to calculate that? + fileneeded[i].type = GetAddonType(fileneeded[i].filename); } } @@ -575,6 +582,48 @@ INT32 CL_CheckFiles(void) return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading } +static addontype_t GetAddonType(const char *name) +{ + const char *prefix = strchr(name, '_'); + + // Doesn't have prefix (no '_' character or it is too far and is probably not for prefix but for something like version) + // KRBCL_ is longest prefix i can think of so this should be enough + if (prefix == NULL || prefix - name > 5) + return ADDON_MISC; + + // Skip 'K' + if (*name == 'K') + ++name; + + switch (*name) + { + case 'L': + return ADDON_SCRIPT; + break; + + case 'R': + case 'B': + return ADDON_MAP; + break; + + case 'C': + return ADDON_CHARACTER; + break; + } + + return ADDON_MISC; +} + +void CL_CheckAddonTypes(void) +{ + memset(&addontypes, 0, sizeof(addontypes)); + + for (INT32 i = 0; i < fileneedednum; i++) + { + addontypes[fileneeded[i].type]++; + } +} + // Load it now boolean CL_LoadServerFiles(void) { diff --git a/src/d_netfil.h b/src/d_netfil.h index 268cd80be..4d4cdba74 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -40,6 +40,15 @@ typedef enum FS_FALLBACK, // HTTP failed } filestatus_t; +typedef enum addontype_e +{ + ADDON_SCRIPT, + ADDON_MAP, + ADDON_CHARACTER, + ADDON_MISC, + NUMADDONTYPES, +} addontype_t; + typedef struct { UINT8 willsend; // Is the server willing to send it? @@ -51,11 +60,13 @@ typedef struct UINT32 totalsize; filestatus_t status; // The value returned by recsearch boolean justdownloaded; // To prevent late fragments from causing an I_Error + addontype_t type; } fileneeded_t; extern INT32 fileneedednum; extern fileneeded_t fileneeded[MAX_WADFILES]; extern char downloaddir[512]; +extern INT32 addontypes[NUMADDONTYPES]; typedef struct { @@ -91,6 +102,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi void CL_PrepareDownloadSaveGame(const char *tmpsave); INT32 CL_CheckFiles(void); +void CL_CheckAddonTypes(void); boolean CL_LoadServerFiles(void); void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid); -- 2.54.0 From 42fa435a0ba12a55a080fa2a1b381636b030b952 Mon Sep 17 00:00:00 2001 From: Indev Date: Wed, 11 Mar 2026 17:26:12 +0300 Subject: [PATCH 2/3] Add toggle for server addon info --- src/d_clisrv.c | 5 +++++ src/d_clisrv.h | 2 ++ src/d_netcmd.c | 1 + 3 files changed, 8 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index fb665a943..d9419a15b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1156,6 +1156,9 @@ static void CV_LoadPlayerNames(UINT8 **p) static void CL_DrawAddonTypes(void) { + if (!cv_serveraddoninfo.value) + return; + INT32 y = 0; INT32 addontypes_downloaded[NUMADDONTYPES] = {0}; @@ -4284,6 +4287,8 @@ consvar_t cv_connectawaittime = {"connectawaittime", "5", CV_SAVE, connectawaitt consvar_t cv_serverinfoscreen = {"serverinfoscreen", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_serveraddoninfo = {"serveraddoninfo", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void Got_AddPlayer(const UINT8 **p, INT32 playernum); static void Got_RemovePlayer(const UINT8 **p, INT32 playernum); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e6741b949..8392f13a1 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -600,6 +600,8 @@ extern consvar_t cv_discordinvites; extern consvar_t cv_serverinfoscreen; +extern consvar_t cv_serveraddoninfo; + // Used in d_net, the only dependence //tic_t ExpandTics(INT32 low, tic_t basetic); void D_ClientServerInit(void); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index aee7f20d4..828ad136a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -900,6 +900,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_mindelay); CV_RegisterVar(&cv_gentlemens); CV_RegisterVar(&cv_serverinfoscreen); + CV_RegisterVar(&cv_serveraddoninfo); #ifdef NETGAME_DEVMODE CV_RegisterVar(&cv_fishcake); -- 2.54.0 From b84e6d89e20776174a50e9dfe949dd51668d25be Mon Sep 17 00:00:00 2001 From: Indev Date: Sat, 4 Apr 2026 17:24:58 +0300 Subject: [PATCH 3/3] Add toggle for server addons info hud into settings --- src/m_menudefs.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 0b176fab3..e2fd3305f 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1694,29 +1694,30 @@ static menuitem_t OP_SaturnMenu[] = {IT_STRING | IT_CVAR, NULL, "Minimum Input Delay", &cv_mindelay, 20}, {IT_STRING | IT_CVAR, NULL, "Gentlemens Ping", &cv_gentlemens, 25}, {IT_STRING | IT_CVAR, NULL, "Server Info Screen", &cv_serverinfoscreen, 30}, + {IT_STRING | IT_CVAR, NULL, "Server Addons Info", &cv_serveraddoninfo, 35}, - {IT_STRING | IT_CVAR, NULL, "Skin Select Spinning Speed", &cv_skinselectspin, 40}, + {IT_STRING | IT_CVAR, NULL, "Skin Select Spinning Speed", &cv_skinselectspin, 45}, - {IT_STRING | IT_CVAR, NULL, "Colorized Speedlines", &cv_coloredspeedlines, 50}, - {IT_STRING | IT_CVAR, NULL, "Colorized Sneakertrails", &cv_coloredsneakertrail, 55}, + {IT_STRING | IT_CVAR, NULL, "Colorized Speedlines", &cv_coloredspeedlines, 55}, + {IT_STRING | IT_CVAR, NULL, "Colorized Sneakertrails", &cv_coloredsneakertrail, 60}, - {IT_STRING | IT_CVAR, NULL, "Player Blendeffects", &cv_playerblendeffects, 65}, + {IT_STRING | IT_CVAR, NULL, "Player Blendeffects", &cv_playerblendeffects, 70}, - {IT_STRING | IT_CVAR, NULL, "Bananadrag Jitter", &cv_bananajitter, 75}, + {IT_STRING | IT_CVAR, NULL, "Bananadrag Jitter", &cv_bananajitter, 80}, - {IT_STRING | IT_CVAR, NULL, "Midair Driftsparks", &cv_airsparks, 85}, + {IT_STRING | IT_CVAR, NULL, "Midair Driftsparks", &cv_airsparks, 90}, - {IT_STRING | IT_CVAR, NULL, "Show Localskin Menus", &cv_showlocalskinmenus, 95}, + {IT_STRING | IT_CVAR, NULL, "Show Localskin Menus", &cv_showlocalskinmenus, 100}, - {IT_STRING | IT_CVAR, NULL, "Uppercase Menu", &cv_menucaps, 105}, + {IT_STRING | IT_CVAR, NULL, "Uppercase Menu", &cv_menucaps, 110}, - {IT_STRING | IT_CVAR, NULL, "Keyboard Layout", &cv_keyboardlayout, 115}, + {IT_STRING | IT_CVAR, NULL, "Keyboard Layout", &cv_keyboardlayout, 120}, - {IT_STRING | IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 125}, + {IT_STRING | IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 130}, - {IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 135}, - {IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 140}, - {IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 145}, // uwu + {IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 140}, + {IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 145}, + {IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 150}, // uwu }; static const char* OP_SaturnTooltips[] = @@ -1726,6 +1727,7 @@ static const char* OP_SaturnTooltips[] = "Practice for online play! 0 = instant response.", "Simulate online input delay when hosting a server.\nValue choosen by Player with the lowest ping", "Show a screen before joining a server displaying important information about it", + "Show a amount and types of addons loaded by server when joining", "How much speen do you want?", "Colourize the speedlines in your skincolor if you go fast enough!", "Colourize the sneaker flame trails in your skincolor!", -- 2.54.0