From 7ebde22b7743420fe1d9ff3892aa05d8ce38d9f7 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 26 Apr 2020 19:46:35 -0700 Subject: [PATCH] Make mod update, room list and server list multithreaded This took fucking ages and it still fails sometimes in edge cases, but I don't give a FUCK right now. --- src/d_clisrv.c | 157 +++++++++++++++++++++++---------- src/d_clisrv.h | 2 + src/d_main.c | 21 ++++- src/f_finale.c | 7 ++ src/f_wipe.c | 9 ++ src/hms123311.c | 71 ++++++++++++++- src/m_menu.c | 226 +++++++++++++++++++++++++++++++++++++++++------- src/m_menu.h | 23 ++++- src/mserv.c | 50 +++++++++-- src/mserv.h | 20 +++-- 10 files changed, 493 insertions(+), 93 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 2a40b1f25..cf1b387a6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1801,8 +1801,92 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) M_SortServerList(); } +#ifdef HAVE_THREADS +struct Fetch_servers_ctx +{ + int room; + int id; +}; + +static void +Fetch_servers_thread (struct Fetch_servers_ctx *ctx) +{ + msg_server_t *server_list; + + server_list = GetShortServersList(ctx->room, ctx->id); + + if (server_list) + { + I_lock_mutex(&ms_QueryId_mutex); + { + if (ctx->id != ms_QueryId) + { + free(server_list); + server_list = NULL; + } + } + I_unlock_mutex(ms_QueryId_mutex); + + if (server_list) + { + I_lock_mutex(&m_menu_mutex); + { + if (m_waiting_mode == M_WAITING_SERVERS) + m_waiting_mode = M_NOT_WAITING; + } + I_unlock_mutex(m_menu_mutex); + + I_lock_mutex(&ms_ServerList_mutex); + { + ms_ServerList = server_list; + } + I_unlock_mutex(ms_ServerList_mutex); + } + } + + free(ctx); +} +#endif/*HAVE_THREADS*/ + +void CL_QueryServerList (msg_server_t *server_list) +{ + INT32 i; + + for (i = 0; server_list[i].header.buffer[0]; i++) + { + // Make sure MS version matches our own, to + // thwart nefarious servers who lie to the MS. + + /* lol bruh, that version COMES from the servers */ + //if (strcmp(version, server_list[i].version) == 0) + { + INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); + 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); + } + } +} + void CL_UpdateServerList(boolean internetsearch, INT32 room) { +#ifdef HAVE_THREADS + struct Fetch_servers_ctx *ctx; +#endif + SL_ClearServerList(0); if (!netgame && I_NetOpenSocket) @@ -1820,53 +1904,32 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) if (internetsearch) { - const msg_server_t *server_list; - INT32 i = -1; - server_list = GetShortServersList(room); +#ifdef HAVE_THREADS + ctx = malloc(sizeof *ctx); + + /* This called from M_Refresh so I don't use a mutex */ + m_waiting_mode = M_WAITING_SERVERS; + + I_lock_mutex(&ms_QueryId_mutex); + { + ctx->id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + ctx->room = room; + + I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx); +#else + msg_server_t *server_list; + + server_list = GetShortServersList(room, 0); + if (server_list) { - char version[8] = ""; -#if VERSION > 0 || SUBVERSION > 0 - snprintf(version, sizeof (version), "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); -#else - strcpy(version, GetRevisionString()); + CL_QueryServerList(server_list); + free(server_list); + } #endif - version[sizeof (version) - 1] = '\0'; - - for (i = 0; server_list[i].header.buffer[0]; i++) - { - // Make sure MS version matches our own, to - // thwart nefarious servers who lie to the MS. - - /* lol bruh, that version COMES from the servers */ - //if (strcmp(version, server_list[i].version) == 0) - { - INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); - 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); - } - } - } - - //no server list?(-1) or no servers?(0) - if (!i) - { - ; /// TODO: display error or warning? - } } } @@ -5054,7 +5117,13 @@ void NetUpdate(void) if (nowtime > resptime) { resptime = nowtime; +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Ticker(); +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif CON_Ticker(); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 463240a2a..5324d8f46 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -18,6 +18,7 @@ #include "d_net.h" #include "tables.h" #include "d_player.h" +#include "mserv.h" /* The 'packet version' is used to distinguish packet formats. @@ -541,6 +542,7 @@ void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(void); void CL_Reset(void); void CL_ClearPlayer(INT32 playernum); +void CL_QueryServerList(msg_server_t *list); void CL_UpdateServerList(boolean internetsearch, INT32 room); // Is there a game running boolean Playing(void); diff --git a/src/d_main.c b/src/d_main.c index 07a7ecf91..cd4b68b78 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -46,6 +46,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "hu_stuff.h" #include "i_sound.h" #include "i_system.h" +#include "i_threads.h" #include "i_video.h" #include "m_argv.h" #include "m_menu.h" @@ -174,6 +175,8 @@ void D_ProcessEvents(void) { event_t *ev; + boolean eaten; + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { ev = &events[eventtail]; @@ -189,7 +192,17 @@ void D_ProcessEvents(void) } // Menu input - if (M_Responder(ev)) +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + { + eaten = M_Responder(ev); + } +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + + if (eaten) continue; // menu ate the event // console input @@ -510,7 +523,13 @@ static void D_Display(void) // vid size change is now finished if it was on... vid.recalc = 0; +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of everything +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif // focus lost moved to M_Drawer CON_Drawer(); diff --git a/src/f_finale.c b/src/f_finale.c index 825f646b0..b7b9a8c6d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -25,6 +25,7 @@ #include "w_wad.h" #include "z_zone.h" #include "i_system.h" +#include "i_threads.h" #include "m_menu.h" #include "dehacked.h" #include "g_input.h" @@ -959,7 +960,13 @@ void F_IntroDrawer(void) I_OsPolling(); I_UpdateNoBlit(); +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of wipes +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 if (moviemode) // make sure we save frames for the white hold too diff --git a/src/f_wipe.c b/src/f_wipe.c index 08d7ed991..ef16ca5fc 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -25,6 +25,7 @@ #include "z_zone.h" #include "i_system.h" +#include "i_threads.h" #include "m_menu.h" #include "console.h" #include "d_main.h" @@ -589,7 +590,15 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) I_UpdateNoBlit(); if (drawMenu) + { +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_Drawer(); // menu is drawn even on top of wipes +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + } I_FinishUpdate(); // page flip or blit buffer diff --git a/src/hms123311.c b/src/hms123311.c index a1a35f2b9..29af48e4c 100644 --- a/src/hms123311.c +++ b/src/hms123311.c @@ -19,6 +19,7 @@ Documentation available here. #include "doomdef.h" #include "d_clisrv.h" #include "command.h" +#include "m_menu.h" #include "mserv.h" #include "i_tcp.h"/* for current_port */ #include "z_zone.h" @@ -193,11 +194,13 @@ HMS_end (struct HMS_buffer *buffer) } int -HMS_fetch_rooms (int joining) +HMS_fetch_rooms (int joining, int query_id) { struct HMS_buffer *hms; int ok; + int doing_shit; + char *id; char *title; char *room_motd; @@ -209,6 +212,8 @@ HMS_fetch_rooms (int joining) int i; + (void)query_id; + hms = HMS_connect("rooms"); if (! hms) @@ -216,6 +221,8 @@ HMS_fetch_rooms (int joining) if (HMS_do(hms)) { + doing_shit = 1; + p = hms->buffer; for (i = 0; i < NUM_LIST_ROOMS && ( end = strstr(p, "\n\n\n") );) @@ -236,6 +243,18 @@ HMS_fetch_rooms (int joining) */ if (joining || id_no != 0) { +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + if (query_id != ms_QueryId) + doing_shit = 0; + } + I_unlock_mutex(ms_QueryId_mutex); + + if (! doing_shit) + break; +#endif + room_list[i].header.buffer[0] = 1; room_list[i].id = id_no; @@ -251,9 +270,31 @@ HMS_fetch_rooms (int joining) break; } - room_list[i].header.buffer[0] = 0; + if (doing_shit) + room_list[i].header.buffer[0] = 0; ok = 1; + + if (doing_shit) + { +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + { + for (i = 0; room_list[i].header.buffer[0]; i++) + { + if(*room_list[i].name != '\0') + { + MP_RoomMenu[i+1].text = room_list[i].name; + roomIds[i] = room_list[i].id; + MP_RoomMenu[i+1].status = IT_STRING|IT_CALL; + } + } + } +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + } } else ok = 0; @@ -385,10 +426,12 @@ HMS_list_servers (void) } msg_server_t * -HMS_fetch_servers (msg_server_t *list, int room_number) +HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) { struct HMS_buffer *hms; + int doing_shit; + char local_version[9]; char *room; @@ -404,6 +447,8 @@ HMS_fetch_servers (msg_server_t *list, int room_number) int i; + (void)query_id; + if (room_number > 0) { hms = HMS_connect("rooms/%d/servers", room_number); @@ -416,6 +461,8 @@ HMS_fetch_servers (msg_server_t *list, int room_number) if (HMS_do(hms)) { + doing_shit = 1; + snprintf(local_version, sizeof local_version, "%d.%d.%d", VERSION/100, @@ -448,6 +495,18 @@ HMS_fetch_servers (msg_server_t *list, int room_number) if (address && port && title && version) { +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + if (query_id != ms_QueryId) + doing_shit = 0; + } + I_unlock_mutex(ms_QueryId_mutex); + + if (! doing_shit) + break; +#endif + if (strcmp(version, local_version) == 0) { strlcpy(list[i].ip, address, sizeof list[i].ip); @@ -474,11 +533,15 @@ HMS_fetch_servers (msg_server_t *list, int room_number) } } + if (! doing_shit) + break; + p = ( section_end + 2 ); } while (section_end) ; - list[i].header.buffer[0] = 0; + if (doing_shit) + list[i].header.buffer[0] = 0; } else list = NULL; diff --git a/src/m_menu.c b/src/m_menu.c index c8d36300f..aa36d3d6d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -32,6 +32,7 @@ #include "sounds.h" #include "s_sound.h" #include "i_system.h" +#include "i_threads.h" // Addfile #include "filesrch.h" @@ -121,6 +122,12 @@ typedef enum NUM_QUITMESSAGES } text_enum; +#ifdef HAVE_THREADS +I_mutex m_menu_mutex; +#endif + +M_waiting_mode_t m_waiting_mode = M_NOT_WAITING; + const char *quitmsg[NUM_QUITMESSAGES]; // Stuff for customizing the player select screen Tails 09-22-2003 @@ -996,7 +1003,7 @@ enum FIRSTSERVERLINE }; -static menuitem_t MP_RoomMenu[] = +menuitem_t MP_RoomMenu[] = { {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, {IT_DISABLED, NULL, "", M_ChooseRoom, 18}, @@ -3769,6 +3776,30 @@ void M_SetupNextMenu(menu_t *menudef) { INT16 i; +#ifdef HAVE_THREADS + if (currentMenu == &MP_RoomDef || currentMenu == &MP_ConnectDef) + { + I_lock_mutex(&ms_QueryId_mutex); + { + ms_QueryId++; + } + I_unlock_mutex(ms_QueryId_mutex); + } + + if (currentMenu == &MP_ConnectDef) + { + I_lock_mutex(&ms_ServerList_mutex); + { + if (ms_ServerList) + { + free(ms_ServerList); + ms_ServerList = NULL; + } + } + I_unlock_mutex(ms_ServerList_mutex); + } +#endif/*HAVE_THREADS*/ + if (currentMenu->quitroutine) { // If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH @@ -3832,6 +3863,19 @@ void M_Ticker(void) if (currentMenu == &OP_ScreenshotOptionsDef) M_SetupScreenshotMenu(); + +#ifdef HAVE_THREADS + I_lock_mutex(&ms_ServerList_mutex); + { + if (ms_ServerList) + { + CL_QueryServerList(ms_ServerList); + free(ms_ServerList); + ms_ServerList = NULL; + } + } + I_unlock_mutex(ms_ServerList_mutex); +#endif } // @@ -10407,22 +10451,65 @@ static INT32 menuRoomIndex = 0; static void M_DrawRoomMenu(void) { + static int frame = -12; + int dot_frame; + char text[4]; + const char *rmotd; + const char *waiting_message; + + int dots; + + if (m_waiting_mode) + { + dot_frame = frame / 4; + dots = dot_frame + 3; + + strcpy(text, " "); + + if (dots > 0) + { + if (dot_frame < 0) + dot_frame = 0; + + strncpy(&text[dot_frame], "...", min(dots, 3 - dot_frame)); + } + + if (++frame == 12) + frame = -12; + + currentMenu->menuitems[0].text = text; + } // use generic drawer for cursor, items and title M_DrawGenericMenu(); V_DrawString(currentMenu->x - 16, currentMenu->y, V_YELLOWMAP, M_GetText("Select a room")); - M_DrawTextBox(144, 24, 20, 20); + if (m_waiting_mode == M_NOT_WAITING) + { + M_DrawTextBox(144, 24, 20, 20); - if (itemOn == 0) - rmotd = M_GetText("Don't connect to the Master Server."); - else - rmotd = room_list[itemOn-1].motd; + if (itemOn == 0) + rmotd = M_GetText("Don't connect to the Master Server."); + else + rmotd = room_list[itemOn-1].motd; - rmotd = V_WordWrap(0, 20*8, 0, rmotd); - V_DrawString(144+8, 32, V_ALLOWLOWERCASE|V_RETURN8, rmotd); + rmotd = V_WordWrap(0, 20*8, 0, rmotd); + V_DrawString(144+8, 32, V_ALLOWLOWERCASE|V_RETURN8, rmotd); + } + + if (m_waiting_mode) + { + // Display a little "please wait" message. + M_DrawTextBox(52, BASEVIDHEIGHT/2-10, 25, 3); + if (m_waiting_mode == M_WAITING_VERSION) + waiting_message = "Checking for updates..."; + else + waiting_message = "Fetching room info..."; + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, waiting_message); + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2)+12, 0, "Please wait."); + } } static void M_DrawConnectMenu(void) @@ -10490,6 +10577,14 @@ static void M_DrawConnectMenu(void) localservercount = serverlistcount; M_DrawGenericMenu(); + + if (m_waiting_mode) + { + // 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."); + } } static boolean M_CancelConnect(void) @@ -10579,10 +10674,10 @@ void M_SortServerList(void) #ifndef NONET #ifdef UPDATE_ALERT -static boolean M_CheckMODVersion(void) +static boolean M_CheckMODVersion(int id) { char updatestring[500]; - const char *updatecheck = GetMODVersion(); + const char *updatecheck = GetMODVersion(id); if(updatecheck) { sprintf(updatestring, UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck); @@ -10591,7 +10686,62 @@ static boolean M_CheckMODVersion(void) } else return true; } -#endif + +#ifdef HAVE_THREADS +static void +Check_new_version_thread (int *id) +{ + int hosting; + int ok; + + ok = 0; + + if (M_CheckMODVersion(*id)) + { + I_lock_mutex(&ms_QueryId_mutex); + { + ok = ( *id == ms_QueryId ); + } + I_unlock_mutex(ms_QueryId_mutex); + + if (ok) + { + I_lock_mutex(&m_menu_mutex); + { + m_waiting_mode = M_WAITING_ROOMS; + hosting = ( currentMenu->prevMenu == &MP_ServerDef ); + } + I_unlock_mutex(m_menu_mutex); + + GetRoomsList(hosting, *id); + } + } + else + { + I_lock_mutex(&ms_QueryId_mutex); + { + ok = ( *id == ms_QueryId ); + } + I_unlock_mutex(ms_QueryId_mutex); + } + + if (ok) + { + I_lock_mutex(&m_menu_mutex); + { + if (m_waiting_mode) + { + m_waiting_mode = M_NOT_WAITING; + MP_RoomMenu[0].text = ""; + } + } + I_unlock_mutex(m_menu_mutex); + } + + free(id); +} +#endif/*HAVE_THREADS*/ +#endif/*UPDATE_ALERT*/ static void M_ConnectMenu(INT32 choice) { @@ -10627,11 +10777,14 @@ static void M_ConnectMenuModChecks(INT32 choice) M_ConnectMenu(-1); } -static UINT32 roomIds[NUM_LIST_ROOMS]; +UINT32 roomIds[NUM_LIST_ROOMS]; static void M_RoomMenu(INT32 choice) { INT32 i; +#ifdef HAVE_THREADS + int *id; +#endif (void)choice; @@ -10644,34 +10797,47 @@ static void M_RoomMenu(INT32 choice) if (rendermode == render_soft) I_FinishUpdate(); // page flip or blit buffer - if (GetRoomsList(currentMenu == &MP_ServerDef) < 0) - return; - -#ifdef UPDATE_ALERT - if (!M_CheckMODVersion()) - return; -#endif - for (i = 1; i < NUM_LIST_ROOMS+1; ++i) MP_RoomMenu[i].status = IT_DISABLED; memset(roomIds, 0, sizeof(roomIds)); - for (i = 0; room_list[i].header.buffer[0]; i++) - { - if(*room_list[i].name != '\0') - { - MP_RoomMenu[i+1].text = room_list[i].name; - roomIds[i] = room_list[i].id; - MP_RoomMenu[i+1].status = IT_STRING|IT_CALL; - } - } - MP_RoomDef.prevMenu = currentMenu; M_SetupNextMenu(&MP_RoomDef); + +#ifdef UPDATE_ALERT +#ifdef HAVE_THREADS + m_waiting_mode = M_WAITING_VERSION; + MP_RoomMenu[0].text = ""; + + id = malloc(sizeof *id); + + I_lock_mutex(&ms_QueryId_mutex); + { + *id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + I_spawn_thread("check-new-version", + (I_thread_fn)Check_new_version_thread, id); +#else/*HAVE_THREADS*/ + if (M_CheckMODVersion(0)) + { + GetRoomsList(currentMenu->prevMenu == &MP_ServerDef, 0); + } +#endif/*HAVE_THREADS*/ +#endif/*UPDATE_ALERT*/ } static void M_ChooseRoom(INT32 choice) { +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + ms_QueryId++; + } + I_unlock_mutex(ms_QueryId_mutex); +#endif + if (choice == 0) ms_RoomId = -1; else diff --git a/src/m_menu.h b/src/m_menu.h index 565b98945..b01910d8b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -18,8 +18,10 @@ #include "doomstat.h" // for NUMGAMETYPES #include "d_event.h" #include "command.h" -#include "r_skins.h" // for SKINNAMESIZE #include "f_finale.h" // for ttmode_enum +#include "i_threads.h" +#include "mserv.h" +#include "r_things.h" // for SKINNAMESIZE // // MENUS @@ -223,6 +225,18 @@ typedef enum } menumessagetype_t; void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); +typedef enum +{ + M_NOT_WAITING, + + M_WAITING_VERSION, + M_WAITING_ROOMS, + M_WAITING_SERVERS, +} +M_waiting_mode_t; + +extern M_waiting_mode_t m_waiting_mode; + // Called by linux_x/i_video_xshm.c void M_QuitResponse(INT32 ch); @@ -313,6 +327,9 @@ typedef struct menuitem_s UINT8 alphaKey; } menuitem_t; +extern menuitem_t MP_RoomMenu[]; +extern UINT32 roomIds[NUM_LIST_ROOMS]; + typedef struct menu_s { UINT32 menuid; // ID to encode menu type and hierarchy @@ -332,6 +349,10 @@ void M_ClearMenus(boolean callexitmenufunc); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); +#ifdef HAVE_THREADS +extern I_mutex m_menu_mutex; +#endif + extern menu_t *currentMenu; extern menu_t MainDef; diff --git a/src/mserv.c b/src/mserv.c index 92a6399f3..4404d9ffa 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -18,6 +18,7 @@ #include "doomstat.h" #include "doomdef.h" #include "command.h" +#include "i_threads.h" #include "mserv.h" #include "m_menu.h" #include "z_zone.h" @@ -46,6 +47,14 @@ consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SA char *ms_API; INT16 ms_RoomId = -1; +#ifdef HAVE_THREADS +int ms_QueryId; +I_mutex ms_QueryId_mutex; + +msg_server_t *ms_ServerList; +I_mutex ms_ServerList_mutex; +#endif + static enum { MSCS_NONE, MSCS_WAITING, MSCS_REGISTERED, MSCS_FAILED } con_state = MSCS_NONE; UINT16 current_port = 0; @@ -72,26 +81,36 @@ void AddMServCommands(void) static void WarnGUI (void) { +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n\nCheck the console for details.\n"), NULL, MM_NOTHING); +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif } #define NUM_LIST_SERVER MAXSERVERLIST -const msg_server_t *GetShortServersList(INT32 room) +msg_server_t *GetShortServersList(INT32 room, int id) { - static msg_server_t server_list[NUM_LIST_SERVER+1]; // +1 for easy test + msg_server_t *server_list; - if (HMS_fetch_servers(server_list, room)) + // +1 for easy test + server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list); + + if (HMS_fetch_servers(server_list, room, id)) return server_list; else { + free(server_list); WarnGUI(); return NULL; } } -INT32 GetRoomsList(boolean hosting) +INT32 GetRoomsList(boolean hosting, int id) { - if (HMS_fetch_rooms( ! hosting )) + if (HMS_fetch_rooms( ! hosting, id)) return 1; else { @@ -101,17 +120,32 @@ INT32 GetRoomsList(boolean hosting) } #ifdef UPDATE_ALERT -const char *GetMODVersion(void) +char *GetMODVersion(int id) { - static char buffer[16]; + char *buffer; int c; - c = HMS_compare_mod_version(buffer, sizeof buffer); + (void)id; + + buffer = malloc(16); + + c = HMS_compare_mod_version(buffer, 16); + +#ifdef HAVE_THREADS + I_lock_mutex(&ms_QueryId_mutex); + { + if (id != ms_QueryId) + c = -1; + } + I_unlock_mutex(ms_QueryId_mutex); +#endif if (c > 0) return buffer; else { + free(buffer); + if (! c) WarnGUI(); diff --git a/src/mserv.h b/src/mserv.h index b59b7b2b6..bce6f04ef 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -14,6 +14,8 @@ #ifndef _MSERV_H_ #define _MSERV_H_ +#include "i_threads.h" + #define HMS123311 // don't mess with nights, man // lowered from 32 due to menu changes @@ -75,15 +77,23 @@ extern char *ms_API; // anything else is whatever room the MS assigns to that number (online mode) extern INT16 ms_RoomId; +#ifdef HAVE_THREADS +extern int ms_QueryId; +extern I_mutex ms_QueryId_mutex; + +extern msg_server_t *ms_ServerList; +extern I_mutex ms_ServerList_mutex; +#endif + void RegisterServer(void); void UnregisterServer(void); void MasterClient_Ticker(void); -const msg_server_t *GetShortServersList(INT32 room); -INT32 GetRoomsList(boolean hosting); +msg_server_t *GetShortServersList(INT32 room, int id); +INT32 GetRoomsList(boolean hosting, int id); #ifdef UPDATE_ALERT -const char *GetMODVersion(void); +char *GetMODVersion(int id); void GetMODVersion_Console(void); #endif extern msg_rooms_t room_list[NUM_LIST_ROOMS+1]; @@ -92,12 +102,12 @@ void AddMServCommands(void); /* HTTP */ int HMS_in_use (void); -int HMS_fetch_rooms (int joining); +int HMS_fetch_rooms (int joining, int id); int HMS_register (void); void HMS_unlist (void); int HMS_update (void); void HMS_list_servers (void); -msg_server_t * HMS_fetch_servers (msg_server_t *list, int room); +msg_server_t * HMS_fetch_servers (msg_server_t *list, int room, int id); int HMS_compare_mod_version (char *buffer, size_t size_of_buffer); #endif