diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9637427f9..51749ec94 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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; } } } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 0002cdb80..972dc45b6 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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); diff --git a/src/d_main.cpp b/src/d_main.cpp index 812347e0d..582b485ce 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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 diff --git a/src/m_menu.c b/src/m_menu.c index 17558333c..a94315b77 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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)*/ }