From f9ec2a634cd1ea720b693358c1efecdac6bc384c Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Tue, 28 Apr 2020 14:21:57 -0700
Subject: [PATCH] Fix switching the master server

---
 src/d_clisrv.h  |  1 +
 src/hms123311.c | 33 +++++++++++++++++++++++++++++++--
 src/mserv.c     | 45 +++++++++++++++++++++++++++++++--------------
 src/mserv.h     |  4 +---
 4 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index 5324d8f463..216f4903a9 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -502,6 +502,7 @@ typedef enum
 } kickreason_t;
 
 extern boolean server;
+extern boolean serverrunning;
 #define client (!server)
 extern boolean dedicated; // For dedicated server
 extern UINT16 software_MAXPACKETLENGTH;
diff --git a/src/hms123311.c b/src/hms123311.c
index 6730438a7a..6e749e3bf7 100644
--- a/src/hms123311.c
+++ b/src/hms123311.c
@@ -22,6 +22,7 @@ Documentation available here.
 #include "m_menu.h"
 #include "mserv.h"
 #include "i_tcp.h"/* for current_port */
+#include "i_threads.h"
 
 /* I just stop myself from making macros anymore. */
 #define Blame( ... ) \
@@ -34,6 +35,11 @@ consvar_t cv_masterserver_debug = {
 
 static int hms_started;
 
+static char *hms_api;
+#ifdef HAVE_THREADS
+static I_mutex hms_api_mutex;
+#endif
+
 static char *hms_server_token;
 
 struct HMS_buffer
@@ -101,13 +107,21 @@ HMS_connect (const char *format, ...)
 		return NULL;
 	}
 
-	seek = strlen(ms_API) + 1;/* + '/' */
+#ifdef HAVE_THREADS
+	I_lock_mutex(&hms_api_mutex);
+#endif
+
+	seek = strlen(hms_api) + 1;/* + '/' */
 
 	va_start (ap, format);
 	url = malloc(seek + vsnprintf(0, 0, format, ap) + 1);
 	va_end (ap);
 
-	sprintf(url, "%s/", ms_API);
+	sprintf(url, "%s/", hms_api);
+
+#ifdef HAVE_THREADS
+	I_unlock_mutex(hms_api_mutex);
+#endif
 
 	va_start (ap, format);
 	vsprintf(&url[seek], format, ap);
@@ -590,3 +604,18 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
 
 	return ok;
 }
+
+void
+HMS_set_api (char *api)
+{
+#ifdef HAVE_THREADS
+	I_lock_mutex(&hms_api_mutex);
+#endif
+	{
+		free(hms_api);
+		hms_api = api;
+	}
+#ifdef HAVE_THREADS
+	I_unlock_mutex(hms_api_mutex);
+#endif
+}
diff --git a/src/mserv.c b/src/mserv.c
index 273c9cfee3..265cb01fee 100644
--- a/src/mserv.c
+++ b/src/mserv.c
@@ -61,7 +61,6 @@ consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_N
 
 consvar_t cv_masterserver_update_rate = {"masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
 
-char *ms_API;
 INT16 ms_RoomId = -1;
 
 #ifdef HAVE_THREADS
@@ -377,6 +376,19 @@ Unlist_server_thread (int *id)
 
 	free(id);
 }
+
+static void
+Change_masterserver_thread (char *api)
+{
+	Lock_state();
+	{
+		while (MSRegistered)
+			I_hold_cond(&MSCond, MSMutex);
+	}
+	Unlock_state();
+
+	HMS_set_api(api);
+}
 #endif/*HAVE_THREADS*/
 
 void RegisterServer(void)
@@ -421,7 +433,7 @@ void UnregisterServer(void)
 static boolean
 Online (void)
 {
-	return ( server && ms_RoomId > 0 );
+	return ( serverrunning && ms_RoomId > 0 );
 }
 
 static inline void SendPingToMasterServer(void)
@@ -480,21 +492,26 @@ void MasterClient_Ticker(void)
 	SendPingToMasterServer();
 }
 
-static void MasterServer_OnChange(void)
+static void
+Set_api (const char *api)
 {
-	boolean auto_register;
-
-	//auto_register = ( con_state != MSCS_NONE );
-	auto_register = false;
+#ifdef HAVE_THREADS
+	I_spawn_thread(
+			"change-masterserver",
+			(I_thread_fn)Change_masterserver_thread,
+			strdup(api)
+	);
+#else
+	HMS_set_api(strdup(api));
+#endif
+}
 
-	if (ms_API)
-	{
-		UnregisterServer();
-		Z_Free(ms_API);
-	}
+static void MasterServer_OnChange(void)
+{
+	UnregisterServer();
 
-	ms_API = Z_StrDup(cv_masterserver.string);
+	Set_api(cv_masterserver.string);
 
-	if (auto_register)
+	if (Online())
 		RegisterServer();
 }
diff --git a/src/mserv.h b/src/mserv.h
index b36ad11c40..a02c08a192 100644
--- a/src/mserv.h
+++ b/src/mserv.h
@@ -70,8 +70,6 @@ extern consvar_t cv_masterserver, cv_servername;
 extern consvar_t cv_masterserver_update_rate;
 extern consvar_t cv_masterserver_debug;
 
-extern char *ms_API;
-
 // < 0 to not connect (usually -1) (offline mode)
 // == 0 to show all rooms, not a valid hosting room
 // anything else is whatever room the MS assigns to that number (online mode)
@@ -101,7 +99,7 @@ extern msg_rooms_t room_list[NUM_LIST_ROOMS+1];
 void AddMServCommands(void);
 
 /* HTTP */
-int  HMS_in_use (void);
+void HMS_set_api (char *api);
 int  HMS_fetch_rooms (int joining, int id);
 int  HMS_register (void);
 int  HMS_unlist (void);
-- 
GitLab