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.
This commit is contained in:
James R 2020-04-26 19:46:35 -07:00
parent c472a9f50d
commit c96506dd3b
10 changed files with 492 additions and 92 deletions

View file

@ -1820,37 +1820,56 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
M_SortServerList();
}
void CL_UpdateServerList(boolean internetsearch, INT32 room)
#ifdef HAVE_THREADS
struct Fetch_servers_ctx
{
SL_ClearServerList(0);
int room;
int id;
};
if (!netgame && I_NetOpenSocket)
{
if (I_NetOpenSocket())
{
netgame = true;
multiplayer = true;
}
}
static void
Fetch_servers_thread (struct Fetch_servers_ctx *ctx)
{
msg_server_t *server_list;
// search for local servers
if (netgame)
SendAskInfo(BROADCASTADDR);
server_list = GetShortServersList(ctx->room, ctx->id);
if (internetsearch)
{
const msg_server_t *server_list;
INT32 i = -1;
server_list = GetShortServersList(room);
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());
#endif
version[sizeof (version) - 1] = '\0';
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++)
{
@ -1879,13 +1898,57 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
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)
{
if (I_NetOpenSocket())
{
netgame = true;
multiplayer = true;
}
}
//no server list?(-1) or no servers?(0)
if (!i)
// search for local servers
if (netgame)
SendAskInfo(BROADCASTADDR);
if (internetsearch)
{
; /// TODO: display error or warning?
#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)
{
CL_QueryServerList(server_list);
free(server_list);
}
#endif
}
}
@ -5528,7 +5591,13 @@ FILESTAMP
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();
}
SV_FileSendTicker();

View file

@ -18,6 +18,7 @@
#include "d_netcmd.h"
#include "tables.h"
#include "d_player.h"
#include "mserv.h"
#include "md5.h"
@ -568,6 +569,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running

View file

@ -50,6 +50,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"
@ -222,6 +223,8 @@ void D_ProcessEvents(void)
{
event_t *ev;
boolean eaten;
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
ev = &events[eventtail];
@ -249,7 +252,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
@ -541,7 +554,13 @@ static void D_Display(void)
if (gamestate != GS_TIMEATTACK)
CON_Drawer();
#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
//

View file

@ -24,6 +24,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"
@ -317,7 +318,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
}
}

View file

@ -22,6 +22,7 @@
#include "z_zone.h"
#include "i_system.h"
#include "i_threads.h"
#include "m_menu.h"
#include "console.h"
#include "d_main.h"
@ -377,7 +378,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

View file

@ -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;
}
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,10 +533,14 @@ HMS_fetch_servers (msg_server_t *list, int room_number)
}
}
if (! doing_shit)
break;
p = ( section_end + 2 );
}
while (section_end) ;
if (doing_shit)
list[i].header.buffer[0] = 0;
}
else

View file

@ -32,6 +32,7 @@
#include "sounds.h"
#include "s_sound.h"
#include "i_system.h"
#include "i_threads.h"
// Addfile
#include "filesrch.h"
@ -118,6 +119,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
@ -1043,7 +1050,7 @@ enum
FIRSTSERVERLINE
};
static menuitem_t MP_RoomMenu[] =
menuitem_t MP_RoomMenu[] =
{
{IT_STRING | IT_CALL, NULL, "<Offline Mode>", M_ChooseRoom, 9},
{IT_DISABLED, NULL, "", M_ChooseRoom, 18},
@ -3211,6 +3218,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
@ -3268,6 +3299,19 @@ void M_Ticker(void)
if (--vidm_testingmode == 0)
setmodeneeded = vidm_previousmode + 1;
}
#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
}
//
@ -8236,13 +8280,43 @@ 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, highlightflags, M_GetText("Select a room"));
if (m_waiting_mode == M_NOT_WAITING)
{
M_DrawTextBox(144, 24, 20, 20);
if (itemOn == 0)
@ -8252,6 +8326,19 @@ static void M_DrawRoomMenu(void)
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)
@ -8327,6 +8414,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)
@ -8408,10 +8503,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);
@ -8420,7 +8515,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 = "<Offline Mode>";
}
}
I_unlock_mutex(m_menu_mutex);
}
free(id);
}
#endif/*HAVE_THREADS*/
#endif/*UPDATE_ALERT*/
static void M_ConnectMenu(INT32 choice)
{
@ -8456,11 +8606,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;
@ -8473,34 +8626,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

View file

@ -17,6 +17,8 @@
#include "d_event.h"
#include "command.h"
#include "i_threads.h"
#include "mserv.h"
#include "r_things.h" // for SKINNAMESIZE
//
@ -66,6 +68,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);
@ -156,6 +170,9 @@ typedef struct menuitem_s
extern menuitem_t PlayerMenu[MAXSKINS];
extern menuitem_t MP_RoomMenu[];
extern UINT32 roomIds[NUM_LIST_ROOMS];
typedef struct menu_s
{
const char *menutitlepic;
@ -171,6 +188,10 @@ typedef struct menu_s
void M_SetupNextMenu(menu_t *menudef);
void M_ClearMenus(boolean callexitmenufunc);
#ifdef HAVE_THREADS
extern I_mutex m_menu_mutex;
#endif
extern menu_t *currentMenu;
extern menu_t MainDef;

View file

@ -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();

View file

@ -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