diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 841bbb13ea787324c95dd7b65277c535699ae0ee..bb2364c5c655df2dad61c602100b2a96baa48c6b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1959,6 +1959,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) { @@ -1971,6 +1975,8 @@ static void SL_ClearServerList(INT32 connectedserver) serverlist[i].node = 0; } serverlistcount = 0; + + memset(resendserverlistnode, 0, sizeof resendserverlistnode); } static UINT32 SL_SearchServer(INT32 node) @@ -1987,6 +1993,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) @@ -2044,6 +2052,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 @@ -2056,19 +2066,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 ee05761566fb3216cdaef0fc0e8c2ac2876d09b6..4f8d098e31691ac6b0678e48c567752ceb8fc550 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -502,6 +502,7 @@ typedef struct extern serverelem_t serverlist[MAXSERVERLIST]; extern UINT32 serverlistcount; +extern UINT32 serverlistultimatecount; extern INT32 mapchangepending; // Points inside doomcom @@ -594,6 +595,7 @@ void CL_ClearPlayer(INT32 playernum); void CL_RemovePlayer(INT32 playernum, INT32 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/m_menu.c b/src/m_menu.c index ab0f20208a92417d3e896cbbe5cc320ef0bdf7bf..f01703016a0068a03475a64176df9e8f0b73ea73 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -157,6 +157,8 @@ UINT8 maplistoption = 0; static char joystickInfo[8][29]; #ifndef NONET static UINT32 serverlistpage; +static UINT32 oldserverlistpage; +static float serverlistslidex; #endif //static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games. @@ -3479,6 +3481,8 @@ void M_Ticker(void) } I_unlock_mutex(ms_ServerList_mutex); #endif + + CL_TimeoutServerList(); } // @@ -8569,12 +8573,18 @@ static void M_HandleServerPage(INT32 choice) case KEY_RIGHTARROW: S_StartSound(NULL, sfx_menu1); if ((serverlistpage + 1) * SERVERS_PER_PAGE < serverlistcount) - serverlistpage++; + { + oldserverlistpage = serverlistpage++; + serverlistslidex = BASEVIDWIDTH; + } break; case KEY_LEFTARROW: S_StartSound(NULL, sfx_menu1); if (serverlistpage > 0) - serverlistpage--; + { + oldserverlistpage = serverlistpage--; + serverlistslidex = -(BASEVIDWIDTH); + } break; default: @@ -8601,119 +8611,160 @@ static void M_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, 0, "Searching for servers..."); - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, 0, "Please wait."); - I_OsPolling(); - I_UpdateNoBlit(); - if (rendermode == render_soft) - I_FinishUpdate(); // page flip or blit buffer - // first page of servers serverlistpage = 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*/ } -static void M_DrawConnectMenu(void) +static void M_DrawServerCountAndHorizontalBar(void) { - UINT16 i; - const char *gt = "Unknown"; - const char *spd = ""; - INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; - int waiting; - int mservflags = V_ALLOWLOWERCASE; + const char *text; + INT32 radius; + INT32 center = BASEVIDWIDTH/2; - for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) - MP_ConnectMenu[i].status = IT_STRING | IT_SPACE; + switch (M_GetWaitingMode()) + { + case M_WAITING_VERSION: + text = "Checking for updates"; + break; - if (!numPages) - numPages = 1; + case M_WAITING_SERVERS: + text = "Loading server list"; + break; - // Page num - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_page].alphaKey, - highlightflags, va("%u of %d", serverlistpage+1, numPages)); + default: + if (serverlistultimatecount > serverlistcount) + { + text = va("%d/%d servers found%.*s", + serverlistcount, + serverlistultimatecount, + I_GetTime() / NEWTICRATE % 4, "..."); + } + else if (serverlistcount > 0) + { + text = va("%d servers found", serverlistcount); + } + else + { + text = "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 - mservflags = mservflags|warningflags; - V_DrawRightAlignedSmallString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+14 + MP_ConnectMenu[mp_connect_page].alphaKey, - mservflags, va("MS: %s", cv_masterserver.string)); + radius = V_StringWidth(text, 0) / 2; + + V_DrawCenteredString(center, currentMenu->y+28, 0, text); // Horizontal line! - V_DrawFill(1, currentMenu->y+32, 318, 1, 0); + V_DrawFill(1, currentMenu->y+32, center - radius - 2, 1, 0); + V_DrawFill(center + radius + 2, currentMenu->y+32, BASEVIDWIDTH - 1, 1, 0); +} - if (serverlistcount <= 0) - V_DrawString(currentMenu->x,currentMenu->y+SERVERHEADERHEIGHT, 0, "No servers found"); - else - for (i = 0; i < min(serverlistcount - serverlistpage * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++) +static void M_DrawServerLines(INT32 x, INT32 page) +{ + UINT16 i; + const char *gt = "Unknown"; + const char *spd = ""; + + for (i = 0; i < min(serverlistcount - page * SERVERS_PER_PAGE, SERVERS_PER_PAGE); i++) { - INT32 slindex = i + serverlistpage * SERVERS_PER_PAGE; + INT32 slindex = i + page * SERVERS_PER_PAGE; UINT32 globalflags = ((serverlist[slindex].info.numberofplayer >= serverlist[slindex].info.maxplayer) ? V_TRANSLUCENT : 0) |((itemOn == FIRSTSERVERLINE+i) ? highlightflags : 0)|V_ALLOWLOWERCASE; - V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); + V_DrawString(x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); // 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+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); + V_DrawSmallString(x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); if (serverlist[slindex].info.cheatsenabled) - V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); + V_DrawSmallString(x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); - V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, + V_DrawSmallString(x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); gt = "Unknown"; if (serverlist[slindex].info.gametype < NUMGAMETYPES) gt = Gametype_Names[serverlist[slindex].info.gametype]; - V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, + V_DrawSmallString(x+46,S_LINEY(i)+8, globalflags, va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); - V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); + V_DrawSmallString(x+112, S_LINEY(i)+8, globalflags, gt); // display game speed for race gametypes if (serverlist[slindex].info.gametype == GT_RACE) { spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue; - V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); + V_DrawSmallString(x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); } MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; } +} - localservercount = serverlistcount; +static void M_DrawConnectMenu(void) +{ + UINT16 i; + INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; + INT32 mservflags = V_ALLOWLOWERCASE; - M_DrawGenericMenu(); + for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) + MP_ConnectMenu[i].status = IT_STRING | IT_SPACE; + + if (!numPages) + numPages = 1; + + // Page num + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_page].alphaKey, + highlightflags, va("%u of %d", serverlistpage+1, numPages)); - waiting = M_GetWaitingMode(); + // Did you change the Server Browser address? Have a little reminder. + if (CV_IsSetToDefault(&cv_masterserver)) + mservflags = mservflags|highlightflags|V_30TRANS; + else + mservflags = mservflags|warningflags; + V_DrawRightAlignedSmallString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+3 + MP_ConnectMenu[mp_connect_refresh].alphaKey, + mservflags, va("MS: %s", cv_masterserver.string)); + + M_DrawServerCountAndHorizontalBar(); - if (waiting) + // When switching pages, slide the old page and the + // new page across the screen + if (oldserverlistpage != serverlistpage) { - const char *message; + const float ease = serverlistslidex / 2.f; + const INT32 offx = serverlistslidex > 0 ? BASEVIDWIDTH : -(BASEVIDWIDTH); + const INT32 x = (FLOAT_TO_FIXED(serverlistslidex) + ease * rendertimefrac) / FRACUNIT; - if (waiting == M_WAITING_VERSION) - message = "Checking for updates..."; - else - message = "Searching for servers..."; + M_DrawServerLines(currentMenu->x + x - offx, oldserverlistpage); + M_DrawServerLines(currentMenu->x + x, serverlistpage); + + if (interpTimerHackAllow) + { + serverlistslidex -= ease; - // Display a little "please wait" message. - M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, message); - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, 0, "Please wait."); + if ((INT32)serverlistslidex == 0) + oldserverlistpage = serverlistpage; + } + } + else + { + M_DrawServerLines(currentMenu->x, serverlistpage); } + + localservercount = serverlistcount; + + M_DrawGenericMenu(); } static boolean M_CancelConnect(void) @@ -8840,6 +8891,9 @@ static void M_ConnectMenu(INT32 choice) // first page of servers serverlistpage = 0; + + CL_UpdateServerList(); + M_SetupNextMenu(&MP_ConnectDef); itemOn = 0;