Newer
Older
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file mserv.c
/// \brief Commands used to communicate with the master server
#if !defined (UNDER_CE)
#include <time.h>
#endif
#include "doomstat.h"
#include "doomdef.h"
#include "command.h"
#include "i_threads.h"
static int MSId;
static int MSRegisteredId = -1;
static boolean MSRegistered;
static boolean MSInProgress;
static boolean MSUpdateAgain;
static time_t MSLastPing;
#ifdef HAVE_THREADS
static I_mutex MSMutex;
static I_cond MSCond;
# define Lock_state() I_lock_mutex (&MSMutex)
# define Unlock_state() I_unlock_mutex (MSMutex)
#else/*HAVE_THREADS*/
# define Lock_state()
# define Unlock_state()
#endif/*HAVE_THREADS*/
static void Update_parameters (void);
#ifndef NONET
static void Command_Listserv_f(void);
#endif
static void MasterServer_OnChange(void);
static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
{2, "MIN"},
{60, "MAX"},
{0}
};
consvar_t cv_masterserver = {"masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_servername = {"servername", "SRB2Kart server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Update_parameters, 0, NULL, NULL, 0, 0, NULL};
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};
#ifdef HAVE_THREADS
int ms_QueryId;
I_mutex ms_QueryId_mutex;
msg_server_t *ms_ServerList;
I_mutex ms_ServerList_mutex;
#endif
UINT16 current_port = 0;
// Room list is an external variable now.
// Avoiding having to get info ten thousand times...
msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test
/** Adds variables and commands relating to the master server.
*
* \sa cv_masterserver, cv_servername,
* Command_Listserv_f
*/
void AddMServCommands(void)
{
#ifndef NONET
CV_RegisterVar(&cv_masterserver);
CV_RegisterVar(&cv_masterserver_update_rate);
CV_RegisterVar(&cv_masterserver_debug);
CV_RegisterVar(&cv_servername);
COM_AddCommand("listserv", Command_Listserv_f);
#endif
}
#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
msg_server_t *GetShortServersList(INT32 room, int id)
msg_server_t *server_list;
// +1 for easy test
server_list = malloc(( NUM_LIST_SERVER + 1 ) * sizeof *server_list);
if (HMS_fetch_servers(server_list, room, id))
INT32 GetRoomsList(boolean hosting, int id)
if (HMS_fetch_rooms( ! hosting, id))
char *GetMODVersion(int id)
(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
Monster Iestyn
committed
{
Monster Iestyn
committed
Monster Iestyn
committed
}
}
// Console only version of the above (used before game init)
void GetMODVersion_Console(void)
{
if (HMS_compare_mod_version(buffer, sizeof buffer) > 0)
I_Error(UPDATE_ALERT_STRING_CONSOLE, VERSIONSTRING, buffer);
}
#endif
#ifndef NONET
/** Gets a list of game servers. Called from console.
*/
static void Command_Listserv_f(void)
{
CONS_Printf(M_GetText("Retrieving server list...\n"));
static void
Finish_registration (void)
CONS_Printf("Registering this server on the master server...\n");
registered = HMS_register();
Lock_state();
MSRegistered = registered;
MSRegisteredId = MSId;
time(&MSLastPing);
if (registered)
CONS_Printf("Master server registration successful.\n");
static void
Finish_update (void)
int registered;
int done;
Lock_state();
registered = MSRegistered;
MSUpdateAgain = false;/* this will happen anyway */
}
Unlock_state();
if (registered)
{
if (HMS_update())
{
Lock_state();
{
time(&MSLastPing);
MSRegistered = true;
}
Unlock_state();
CONS_Printf("Updated master server listing.\n");
}
else
Finish_registration();
Finish_registration();
Lock_state();
done = ! MSUpdateAgain;
if (done)
MSInProgress = false;
Unlock_state();
if (! done)
Finish_update();
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
static void
Finish_unlist (void)
{
int registered;
Lock_state();
{
registered = MSRegistered;
}
Unlock_state();
if (registered)
{
CONS_Printf("Removing this server from the master server...\n");
if (HMS_unlist())
CONS_Printf("Server deregistration request successfully sent.\n");
Lock_state();
{
MSRegistered = false;
}
Unlock_state();
#ifdef HAVE_THREADS
I_wake_all_cond(&MSCond);
#endif
}
Lock_state();
{
if (MSId == MSRegisteredId)
MSId++;
}
Unlock_state();
}
#ifdef HAVE_THREADS
static int *
Server_id (void)
int *id;
id = malloc(sizeof *id);
Lock_state();
Unlock_state();
return id;
static int *
New_server_id (void)
{
int *id;
id = malloc(sizeof *id);
Lock_state();
{
*id = ++MSId;
I_wake_all_cond(&MSCond);
}
Unlock_state();
return id;
}
static void
Register_server_thread (int *id)
int same;
Lock_state();
/* wait for previous unlist to finish */
while (*id == MSId && MSRegistered)
I_hold_cond(&MSCond, MSMutex);
same = ( *id == MSId );/* it could have been a while */
Unlock_state();
if (same)/* it could have been a while */
Finish_registration();
static void
Update_server_thread (int *id)
int same;
Lock_state();
{
same = ( *id == MSRegisteredId );
}
Unlock_state();
if (same)
Finish_update();
free(id);
static void
Unlist_server_thread (int *id)
{
int same;
Lock_state();
{
same = ( *id == MSRegisteredId );
}
Unlock_state();
if (same)
Finish_unlist();
free(id);
}
static void
Change_masterserver_thread (char *api)
{
Lock_state();
{
while (MSRegistered)
I_hold_cond(&MSCond, MSMutex);
}
Unlock_state();
HMS_set_api(api);
}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
#endif/*HAVE_THREADS*/
void RegisterServer(void)
{
#ifdef HAVE_THREADS
I_spawn_thread(
"register-server",
(I_thread_fn)Register_server_thread,
New_server_id()
);
#else
Finish_registration();
#endif
}
static void UpdateServer(void)
{
#ifdef HAVE_THREADS
I_spawn_thread(
"update-server",
(I_thread_fn)Update_server_thread,
Server_id()
);
#else
Finish_update();
#endif
}
void UnregisterServer(void)
{
#ifdef HAVE_THREADS
I_spawn_thread(
"unlist-server",
(I_thread_fn)Unlist_server_thread,
Server_id()
);
#else
Finish_unlist();
#endif
}
static boolean
Online (void)
{
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
}
static inline void SendPingToMasterServer(void)
{
int ready;
time_t now;
if (Online())
{
time(&now);
Lock_state();
{
ready = (
MSRegisteredId == MSId &&
! MSInProgress &&
now >= ( MSLastPing + cv_masterserver_update_rate.value )
);
if (ready)
MSInProgress = true;
}
Unlock_state();
if (ready)
UpdateServer();
}
}
static void
Update_parameters (void)
{
int registered;
int delayed;
if (Online())
{
Lock_state();
{
delayed = MSInProgress;
if (delayed)/* do another update after the current one */
MSUpdateAgain = true;
else
registered = MSRegistered;
}
Unlock_state();
if (! delayed && registered)
UpdateServer();
}
}
void MasterClient_Ticker(void)
#ifdef HAVE_THREADS
I_spawn_thread(
"change-masterserver",
(I_thread_fn)Change_masterserver_thread,
strdup(api)
);
#else
HMS_set_api(strdup(api));
#endif
}
static void MasterServer_OnChange(void)
{
UnregisterServer();