mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'mserv-servitude' into 'master'
MServ Servitude See merge request KartKrew/Kart!1438
This commit is contained in:
commit
aa5446cf40
16 changed files with 602 additions and 165 deletions
|
|
@ -502,6 +502,7 @@ consvar_t cv_kicktime = Server("kicktime", "20").values(CV_Unsigned);
|
|||
|
||||
void MasterServer_OnChange(void);
|
||||
consvar_t cv_masterserver = Server("masterserver", "https://ms.kartkrew.org/ms/api").onchange(MasterServer_OnChange);
|
||||
consvar_t cv_masterserver_nagattempts = Server("masterserver_nagattempts", "5").values(CV_Unsigned);
|
||||
|
||||
void MasterServer_Debug_OnChange (void);
|
||||
consvar_t cv_masterserver_debug = Server("masterserver_debug", "Off").on_off().onchange(MasterServer_Debug_OnChange);
|
||||
|
|
@ -540,13 +541,14 @@ consvar_t cv_server_contact = Server("server_contact", "").onchange_noinit(Updat
|
|||
consvar_t cv_servername = Server("servername", "Ring Racers server").onchange_noinit(Update_parameters);
|
||||
|
||||
void M_SortServerList(void);
|
||||
consvar_t cv_serversort = Server("serversort", "Ping").dont_save().onchange(M_SortServerList).values({
|
||||
{0,"Ping"},
|
||||
{1,"AVG. Power Level"},
|
||||
{2,"Most Players"},
|
||||
{3,"Least Players"},
|
||||
{4,"Max Player Slots"},
|
||||
{5,"Gametype"},
|
||||
consvar_t cv_serversort = Server("serversort", "Recommended").dont_save().onchange(M_SortServerList).values({
|
||||
{-1, "Recommended"},
|
||||
{ 0, "Ping"},
|
||||
{ 1, "AVG. Power Level"},
|
||||
{ 2, "Most Players"},
|
||||
{ 3, "Least Players"},
|
||||
{ 4, "Max Player Slots"},
|
||||
{ 5, "Gametype"},
|
||||
});
|
||||
|
||||
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
|
||||
|
|
|
|||
|
|
@ -1550,6 +1550,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)
|
||||
{
|
||||
|
|
@ -1562,6 +1566,8 @@ static void SL_ClearServerList(INT32 connectedserver)
|
|||
serverlist[i].node = 0;
|
||||
}
|
||||
serverlistcount = 0;
|
||||
|
||||
memset(resendserverlistnode, 0, sizeof resendserverlistnode);
|
||||
}
|
||||
|
||||
static UINT32 SL_SearchServer(INT32 node)
|
||||
|
|
@ -1574,32 +1580,37 @@ static UINT32 SL_SearchServer(INT32 node)
|
|||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
|
||||
static boolean 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)
|
||||
{
|
||||
// not found add it
|
||||
if (serverlistcount >= MAXSERVERLIST)
|
||||
return; // list full
|
||||
return false; // list full
|
||||
|
||||
if (info->_255 != 255)
|
||||
return;/* old packet format */
|
||||
return false;/* old packet format */
|
||||
|
||||
if (info->packetversion != PACKETVERSION)
|
||||
return;/* old new packet format */
|
||||
return false;/* old new packet format */
|
||||
|
||||
if (info->version != VERSION)
|
||||
return; // Not same version.
|
||||
return false; // Not same version.
|
||||
|
||||
if (info->subversion != SUBVERSION)
|
||||
return; // Close, but no cigar.
|
||||
return false; // Close, but no cigar.
|
||||
|
||||
if (strcmp(info->application, SRB2APPLICATION))
|
||||
return;/* that's a different mod */
|
||||
return false;/* that's a different mod */
|
||||
|
||||
if (info->modifiedgame != (mpmenu.room == 1))
|
||||
return false;/* CORE vs MODDED! */
|
||||
|
||||
i = serverlistcount++;
|
||||
}
|
||||
|
|
@ -1609,6 +1620,8 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
|
|||
|
||||
// resort server list
|
||||
M_SortServerList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CL_QueryServerList (msg_server_t *server_list)
|
||||
|
|
@ -1617,6 +1630,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
|
||||
|
|
@ -1629,19 +1644,43 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4187,6 +4226,11 @@ boolean SV_SpawnServer(void)
|
|||
I_NetOpenSocket();
|
||||
}
|
||||
|
||||
if (cv_advertise.value)
|
||||
{
|
||||
RegisterServer();
|
||||
}
|
||||
|
||||
ourIP = 0;
|
||||
STUN_bind(GotOurIP);
|
||||
}
|
||||
|
|
@ -4609,7 +4653,9 @@ static void HandleServerInfo(SINT8 node)
|
|||
memcpy(servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
|
||||
CopyCaretColors(netbuffer->u.serverinfo.servername, servername, MAXSERVERNAME);
|
||||
|
||||
SL_InsertServer(&netbuffer->u.serverinfo, node);
|
||||
// If we have cause to reject it, it's not worth observing.
|
||||
if (SL_InsertServer(&netbuffer->u.serverinfo, node) == false)
|
||||
serverlistultimatecount--;
|
||||
}
|
||||
|
||||
static void PT_WillResendGamestate(void)
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ struct serverelem_t
|
|||
};
|
||||
|
||||
extern serverelem_t serverlist[MAXSERVERLIST];
|
||||
extern UINT32 serverlistcount;
|
||||
extern UINT32 serverlistcount, serverlistultimatecount;
|
||||
extern INT32 mapchangepending;
|
||||
|
||||
// Points inside doomcom
|
||||
|
|
@ -595,6 +595,7 @@ void CL_ClearPlayer(INT32 playernum);
|
|||
void CL_RemovePlayer(INT32 playernum, kickreason_t reason);
|
||||
void CL_QueryServerList(msg_server_t *list);
|
||||
void CL_UpdateServerList(void);
|
||||
void CL_TimeoutServerList(void);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
|
|||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
|
||||
if (drawMenu)
|
||||
if (drawMenu && rendermode != render_none)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&k_menu_mutex);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
/*
|
||||
Documentation available here.
|
||||
|
||||
<https://ms.kartkrew.org/tools/api/2/>
|
||||
<https://ms.kartkrew.org/tools/api/2.2/>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
|
|
@ -441,7 +441,12 @@ HMS_fetch_servers (msg_server_t *list, int query_id)
|
|||
break;
|
||||
#endif
|
||||
|
||||
//#define MSERVTESTALONE
|
||||
#ifdef MSERVTESTALONE
|
||||
strcpy(list[i].ip, "127.0.0.1"); // MS test without needing a second person to host
|
||||
#else
|
||||
strlcpy(list[i].ip, address, sizeof list[i].ip);
|
||||
#endif
|
||||
strlcpy(list[i].port, port, sizeof list[i].port);
|
||||
|
||||
if (contact)
|
||||
|
|
@ -511,6 +516,40 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
|
|||
return ok;
|
||||
}
|
||||
|
||||
const char *
|
||||
HMS_fetch_rules (char *buffer, size_t buffer_size)
|
||||
{
|
||||
struct HMS_buffer *hms;
|
||||
|
||||
hms = HMS_connect("rules");
|
||||
|
||||
if (! hms)
|
||||
return NULL;
|
||||
|
||||
boolean ok = HMS_do(hms);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
char *p = strstr(hms->buffer, "\n\n");
|
||||
|
||||
if (p)
|
||||
{
|
||||
p[1] = '\0';
|
||||
|
||||
strlcpy(buffer, hms->buffer, buffer_size);
|
||||
}
|
||||
else
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
HMS_end(hms);
|
||||
|
||||
if (!ok)
|
||||
return NULL;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *
|
||||
Strip_trailing_slashes (char *api)
|
||||
{
|
||||
|
|
|
|||
11
src/k_menu.h
11
src/k_menu.h
|
|
@ -29,8 +29,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SERVERLISTDEBUG
|
||||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
#define IT_TYPE 14 // (2+4+8)
|
||||
|
|
@ -831,7 +829,6 @@ extern struct mpmenu_s {
|
|||
// See M_OptSelectTick, it'll make more sense there. Sorry if this is a bit of a mess!
|
||||
|
||||
UINT8 room;
|
||||
boolean roomforced;
|
||||
tic_t ticker;
|
||||
|
||||
UINT8 servernum;
|
||||
|
|
@ -842,6 +839,9 @@ extern struct mpmenu_s {
|
|||
|
||||
} mpmenu;
|
||||
|
||||
void M_PleaseWait(void);
|
||||
void M_PopupMasterServerRules(void);
|
||||
|
||||
// Time Attack
|
||||
void M_PrepareTimeAttack(INT32 choice);
|
||||
void M_StartTimeAttack(INT32 choice);
|
||||
|
|
@ -895,11 +895,6 @@ void Fetch_servers_thread (int *id);
|
|||
void M_RefreshServers(INT32 choice);
|
||||
void M_ServersMenu(INT32 choice);
|
||||
|
||||
// for debugging purposes...
|
||||
#ifdef SERVERLISTDEBUG
|
||||
void M_ServerListFillDebug(void);
|
||||
#endif
|
||||
|
||||
// Options menu:
|
||||
|
||||
// mode descriptions for video mode menu
|
||||
|
|
|
|||
101
src/k_menudraw.c
101
src/k_menudraw.c
|
|
@ -3086,6 +3086,23 @@ void M_DrawTimeAttack(void)
|
|||
|
||||
// NOTE: This is pretty rigid and only intended for use with the multiplayer options menu which has *3* choices.
|
||||
|
||||
static void M_DrawMasterServerReminder(void)
|
||||
{
|
||||
// Did you change the Server Browser address? Have a little reminder.
|
||||
|
||||
INT32 mservflags = 0;
|
||||
if (CV_IsSetToDefault(&cv_masterserver))
|
||||
mservflags = highlightflags;
|
||||
else
|
||||
mservflags = warningflags;
|
||||
|
||||
INT32 y = BASEVIDHEIGHT - 24;
|
||||
|
||||
V_DrawFadeFill(0, y-1, BASEVIDWIDTH, 10+1, 0, 31, 5);
|
||||
V_DrawCenteredThinString(BASEVIDWIDTH/2, y,
|
||||
mservflags, va("List via \"%s\"", cv_masterserver.string));
|
||||
}
|
||||
|
||||
static void M_MPOptDrawer(menu_t *m, INT16 extend[3][3])
|
||||
{
|
||||
// This is a copypaste of the generic gamemode menu code with a few changes.
|
||||
|
|
@ -3149,6 +3166,7 @@ void M_DrawMPOptSelect(void)
|
|||
M_DrawEggaChannel();
|
||||
M_DrawMenuTooltips();
|
||||
M_MPOptDrawer(&PLAY_MP_OptSelectDef, mpmenu.modewinextend);
|
||||
M_DrawMasterServerReminder();
|
||||
}
|
||||
|
||||
// Multiplayer mode option select: HOST GAME!
|
||||
|
|
@ -3400,14 +3418,79 @@ void M_DrawMPRoomSelect(void)
|
|||
|
||||
// Draw buttons:
|
||||
|
||||
if (!mpmenu.roomforced || mpmenu.room == 0)
|
||||
V_DrawFixedPatch(160<<FRACBITS, 100<<FRACBITS, FRACUNIT, mpmenu.room ? (5<<V_ALPHASHIFT) : 0, butt1[(mpmenu.room) ? 1 : 0], NULL);
|
||||
V_DrawFixedPatch(160<<FRACBITS, 90<<FRACBITS, FRACUNIT, mpmenu.room ? (5<<V_ALPHASHIFT) : 0, butt1[(mpmenu.room) ? 1 : 0], NULL);
|
||||
|
||||
if (!mpmenu.roomforced || mpmenu.room == 1)
|
||||
V_DrawFixedPatch(160<<FRACBITS, 100<<FRACBITS, FRACUNIT, (!mpmenu.room) ? (5<<V_ALPHASHIFT) : 0, butt2[(!mpmenu.room) ? 1 : 0], NULL);
|
||||
V_DrawFixedPatch(160<<FRACBITS, 90<<FRACBITS, FRACUNIT, (!mpmenu.room) ? (5<<V_ALPHASHIFT) : 0, butt2[(!mpmenu.room) ? 1 : 0], NULL);
|
||||
|
||||
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL);
|
||||
V_DrawCenteredThinString(BASEVIDWIDTH/2, 12, 0, "Select today's type of play!");
|
||||
|
||||
M_DrawMasterServerReminder();
|
||||
}
|
||||
|
||||
// SERVER BROWSER
|
||||
static void M_DrawServerCountAndHorizontalBar(void)
|
||||
{
|
||||
const char *text;
|
||||
INT32 y = currentMenu->y+STRINGHEIGHT;
|
||||
|
||||
const char throbber[4] = {'-', '\\', '|', '/'};
|
||||
UINT8 throbindex = (mpmenu.ticker/4) % 4;
|
||||
|
||||
switch (M_GetWaitingMode())
|
||||
{
|
||||
case M_WAITING_VERSION:
|
||||
text = "Checking for updates...";
|
||||
break;
|
||||
|
||||
case M_WAITING_SERVERS:
|
||||
text = "Loading server list...";
|
||||
break;
|
||||
|
||||
default:
|
||||
if (serverlistultimatecount > serverlistcount)
|
||||
{
|
||||
text = va("%d/%d server%s found...",
|
||||
serverlistcount,
|
||||
serverlistultimatecount,
|
||||
serverlistultimatecount == 1 ? "" : "s"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throbindex = UINT8_MAX; // No throbber!
|
||||
text = va("%d server%s found",
|
||||
serverlistcount,
|
||||
serverlistcount == 1 ? "" : "s"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (throbindex == UINT8_MAX)
|
||||
{
|
||||
V_DrawRightAlignedString(
|
||||
BASEVIDWIDTH - currentMenu->x,
|
||||
y,
|
||||
highlightflags,
|
||||
text
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawRightAlignedString(
|
||||
BASEVIDWIDTH - currentMenu->x - 12, y,
|
||||
highlightflags,
|
||||
text
|
||||
);
|
||||
|
||||
V_DrawCenteredString( // Only clean way to center the throbber without exposing character width
|
||||
BASEVIDWIDTH - currentMenu->x - 4, y,
|
||||
highlightflags,
|
||||
va("%c", throbber[throbindex])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void M_DrawMPServerBrowser(void)
|
||||
{
|
||||
patch_t *text1 = W_CachePatchName("MENUBGT1", PU_CACHE);
|
||||
|
|
@ -3503,11 +3586,19 @@ void M_DrawMPServerBrowser(void)
|
|||
V_DrawFill(0, 53, 320, 1, 31);
|
||||
V_DrawFill(0, 55, 320, 1, 31);
|
||||
|
||||
V_DrawCenteredGamemodeString(160, 2, 0, 0, "Server Browser");
|
||||
const char *headertext;
|
||||
if (M_SecretUnlocked(SECRET_ADDONS, true))
|
||||
headertext = va("%s Servers", mpmenu.room ? "Modded" : "Core");
|
||||
else
|
||||
headertext = "Server Browser";
|
||||
V_DrawCenteredGamemodeString(160, 2, 0, 0, headertext);
|
||||
|
||||
// normal menu options
|
||||
M_DrawGenericMenu();
|
||||
|
||||
// And finally, the overlay bar!
|
||||
M_DrawServerCountAndHorizontalBar();
|
||||
M_DrawMasterServerReminder();
|
||||
}
|
||||
|
||||
// OPTIONS MENU
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "../k_menu.h"
|
||||
#include "../m_cond.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../mserv.h" // cv_masterserver
|
||||
|
||||
#if defined (TESTERS)
|
||||
#define IT_STRING_CALL_NOTESTERS IT_DISABLED
|
||||
|
|
@ -11,13 +12,74 @@
|
|||
#define IT_STRING_CALL_NOTESTERS (IT_STRING | IT_CALL)
|
||||
#endif // TESTERS
|
||||
|
||||
static boolean firstDismissedNagThisBoot = true;
|
||||
|
||||
static void M_HandleMasterServerResetChoice(INT32 ch)
|
||||
{
|
||||
if (ch == MA_YES)
|
||||
{
|
||||
CV_Set(&cv_masterserver, cv_masterserver.defaultvalue);
|
||||
CV_Set(&cv_masterserver_nagattempts, cv_masterserver_nagattempts.defaultvalue);
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstDismissedNagThisBoot)
|
||||
{
|
||||
if (cv_masterserver_nagattempts.value > 0)
|
||||
{
|
||||
CV_SetValue(&cv_masterserver_nagattempts, cv_masterserver_nagattempts.value - 1);
|
||||
}
|
||||
firstDismissedNagThisBoot = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M_PreMPHostInitChoice(INT32 ch)
|
||||
{
|
||||
M_HandleMasterServerResetChoice(ch);
|
||||
M_MPHostInit(0);
|
||||
}
|
||||
|
||||
static void M_PreMPHostInit(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (!CV_IsSetToDefault(&cv_masterserver) && cv_masterserver_nagattempts.value > 0)
|
||||
{
|
||||
M_StartMessage("Server Browser Alert", M_GetText("Hey! You've changed the game's\naddress for the Server Browser.\n\nYou won't be able to host games on\nthe official Server Browser.\n\nUnless you're from the future, this\nprobably isn't what you want.\n"), &M_PreMPHostInitChoice, MM_YESNO, "Fix and continue", "I changed the URL intentionally");
|
||||
return;
|
||||
}
|
||||
|
||||
M_MPHostInit(0);
|
||||
}
|
||||
|
||||
static void M_PreMPRoomSelectInitChoice(INT32 ch)
|
||||
{
|
||||
M_HandleMasterServerResetChoice(ch);
|
||||
M_MPRoomSelectInit(0);
|
||||
}
|
||||
|
||||
static void M_PreMPRoomSelectInit(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (!CV_IsSetToDefault(&cv_masterserver) && cv_masterserver_nagattempts.value > 0)
|
||||
{
|
||||
M_StartMessage("Server Browser Alert", M_GetText("Hey! You've changed the game's\naddress for the Server Browser.\n\nYou won't be able to see games from\nthe official Server Browser.\n\nUnless you're from the future, this\nprobably isn't what you want.\n"), &M_PreMPRoomSelectInitChoice, MM_YESNO, "Fix and continue", "I changed the URL intentionally");
|
||||
return;
|
||||
}
|
||||
|
||||
M_MPRoomSelectInit(0);
|
||||
}
|
||||
|
||||
menuitem_t PLAY_MP_OptSelect[] =
|
||||
{
|
||||
{IT_STRING_CALL_NOTESTERS, "Host Game", "Start your own online game!",
|
||||
NULL, {.routine = M_MPHostInit}, 0, 0},
|
||||
NULL, {.routine = M_PreMPHostInit}, 0, 0},
|
||||
|
||||
{IT_STRING_CALL_NOTESTERS, "Server Browser", "Search for game servers to play in.",
|
||||
NULL, {.routine = M_MPRoomSelectInit}, 0, 0},
|
||||
NULL, {.routine = M_PreMPRoomSelectInit}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Join by IP", "Join an online game by its IP address.",
|
||||
NULL, {.routine = M_MPJoinIPInit}, 0, 0},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../k_menu.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../mserv.h"
|
||||
|
||||
// MULTIPLAYER HOST SCREEN -- see mhost_e
|
||||
menuitem_t PLAY_MP_Host[] =
|
||||
|
|
@ -43,13 +45,41 @@ menu_t PLAY_MP_HostDef = {
|
|||
NULL
|
||||
};
|
||||
|
||||
void M_PopupMasterServerRules(void)
|
||||
{
|
||||
#ifdef MASTERSERVER
|
||||
if (cv_advertise.value && (serverrunning || currentMenu == &PLAY_MP_HostDef))
|
||||
{
|
||||
char *rules = GetMasterServerRules();
|
||||
|
||||
if (rules != NULL)
|
||||
{
|
||||
M_StartMessage("Server List Rules", rules, NULL, MM_NOTHING, NULL, NULL);
|
||||
Z_Free(rules);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void M_MPHostInit(INT32 choice)
|
||||
{
|
||||
|
||||
(void)choice;
|
||||
mpmenu.modewinextend[0][0] = 1;
|
||||
M_SetupNextMenu(&PLAY_MP_HostDef, true);
|
||||
itemOn = mhost_go;
|
||||
|
||||
Get_rules();
|
||||
// There's one downside to doing it this way:
|
||||
// if you turn advertise on via the console,
|
||||
// then access this menu for the first time,
|
||||
// no rules will pop up because they haven't
|
||||
// arrived yet.
|
||||
M_PopupMasterServerRules();
|
||||
// HOWEVER, this menu popup isn't for people
|
||||
// who know how to use the Developer Console.
|
||||
// People who CAN do that should already know
|
||||
// what kind of service they're connecting to.
|
||||
// (it'll still appear in the logs later, too!)
|
||||
}
|
||||
|
||||
void M_HandleHostMenuGametype(INT32 choice)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../i_system.h" // I_OsPolling
|
||||
#include "../i_video.h" // I_UpdateNoBlit
|
||||
#include "../m_misc.h" // NUMLOGIP
|
||||
#include "../f_finale.h" // g_wipeskiprender
|
||||
|
||||
menuitem_t PLAY_MP_JoinIP[] =
|
||||
{
|
||||
|
|
@ -56,6 +57,21 @@ void M_MPJoinIPInit(INT32 choice)
|
|||
M_SetupNextMenu(&PLAY_MP_JoinIPDef, true);
|
||||
}
|
||||
|
||||
void M_PleaseWait(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
g_wipeskiprender = true;
|
||||
|
||||
M_DrawTextBox(56, BASEVIDHEIGHT/2-12, 24, 2);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "PLEASE WAIT...");
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
if (rendermode == render_soft)
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
}
|
||||
|
||||
// Attempts to join a given IP from the menu.
|
||||
void M_JoinIP(const char *ipa)
|
||||
{
|
||||
|
|
@ -67,13 +83,7 @@ void M_JoinIP(const char *ipa)
|
|||
|
||||
COM_BufAddText(va("connect \"%s\"\n", ipa));
|
||||
|
||||
// A little "please wait" message.
|
||||
M_DrawTextBox(56, BASEVIDHEIGHT/2-12, 24, 2);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Connecting to server...");
|
||||
I_OsPolling();
|
||||
I_UpdateNoBlit();
|
||||
if (rendermode == render_soft)
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
M_PleaseWait();
|
||||
}
|
||||
|
||||
boolean M_JoinIPInputs(INT32 ch)
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ void M_MPRoomSelect(INT32 choice)
|
|||
M_ServersMenu(0);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
else if (mpmenu.roomforced == false
|
||||
&& menucmd[pid].dpad_lr != 0)
|
||||
else if (menucmd[pid].dpad_lr != 0)
|
||||
{
|
||||
mpmenu.room ^= 1;
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
|
|
@ -59,12 +58,28 @@ void M_MPRoomSelectTick(void)
|
|||
void M_MPRoomSelectInit(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
if (modifiedgame)
|
||||
{
|
||||
M_StartMessage("Server Browser & Add-Ons", M_GetText("You have add-ons loaded.\nYou won't be able to join netgames!\n\nTo play online, restart the game\nand don't load any addons.\n\n\"Dr. Robotnik's Ring Racers\" will\nautomatically add everything\nyou need when you join.\n"), NULL, MM_NOTHING, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// The following behaviour is affected by modifiedgame despite the above restriction.
|
||||
// It's a sanity check were that to be removed, wheither by us or by a modified client.
|
||||
// "wheither"? That typo rules, I'm keeping that ~toast 280823
|
||||
|
||||
mpmenu.room = (modifiedgame == true) ? 1 : 0;
|
||||
mpmenu.roomforced = ((modifiedgame == true) || (!M_SecretUnlocked(SECRET_ADDONS, true)));
|
||||
mpmenu.ticker = 0;
|
||||
mpmenu.servernum = 0;
|
||||
mpmenu.scrolln = 0;
|
||||
mpmenu.slide = 0;
|
||||
|
||||
if ((modifiedgame == true) || (M_SecretUnlocked(SECRET_ADDONS, true) == false))
|
||||
{
|
||||
M_ServersMenu(0);
|
||||
return;
|
||||
}
|
||||
|
||||
M_SetupNextMenu(&PLAY_MP_RoomSelectDef, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
|
||||
#include "../k_menu.h"
|
||||
#include "../v_video.h"
|
||||
#include "../i_system.h" // I_OsPolling
|
||||
#include "../i_video.h" // I_UpdateNoBlit
|
||||
#include "../s_sound.h"
|
||||
|
||||
//#define SERVERLISTDEBUG
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
#include "../m_random.h"
|
||||
|
||||
void M_ServerListFillDebug(void);
|
||||
#endif
|
||||
|
||||
menuitem_t PLAY_MP_ServerBrowser[] =
|
||||
|
|
@ -16,8 +19,8 @@ menuitem_t PLAY_MP_ServerBrowser[] =
|
|||
{IT_STRING | IT_CVAR, "SORT BY", NULL, // tooltip MUST be null.
|
||||
NULL, {.cvar = &cv_serversort}, 0, 0},
|
||||
|
||||
{IT_STRING, "REFRESH", NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
{IT_STRING | IT_CALL, "REFRESH", NULL,
|
||||
NULL, {.routine = &M_RefreshServers}, 0, 0},
|
||||
|
||||
{IT_NOTHING, NULL, NULL, NULL, {NULL}, 0, 0},
|
||||
};
|
||||
|
|
@ -42,28 +45,6 @@ menu_t PLAY_MP_ServerBrowserDef = {
|
|||
// for server fetch threads...
|
||||
M_waiting_mode_t m_waiting_mode = M_NOT_WAITING;
|
||||
|
||||
// depending on mpmenu.room, either allows only unmodded servers or modded ones. Remove others from the list.
|
||||
// we do this by iterating backwards.
|
||||
static void M_CleanServerList(void)
|
||||
{
|
||||
UINT8 i = serverlistcount;
|
||||
|
||||
while (i)
|
||||
{
|
||||
|
||||
if (serverlist[i].info.modifiedgame != mpmenu.room)
|
||||
{
|
||||
// move everything after this index 1 slot down...
|
||||
if (i != serverlistcount)
|
||||
memcpy(&serverlist[i], &serverlist[i+1], sizeof(serverelem_t)*(serverlistcount-i));
|
||||
|
||||
serverlistcount--;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
M_SetWaitingMode (int mode)
|
||||
{
|
||||
|
|
@ -180,31 +161,19 @@ void M_RefreshServers(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
|
||||
CL_UpdateServerList();
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
M_ServerListFillDebug();
|
||||
#else /*SERVERLISTDEBUG*/
|
||||
#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*/
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
M_ServerListFillDebug();
|
||||
#endif
|
||||
M_CleanServerList();
|
||||
M_SortServerList();
|
||||
|
||||
#endif /*SERVERLISTDEBUG*/
|
||||
}
|
||||
|
||||
#ifdef UPDATE_ALERT
|
||||
|
|
@ -253,13 +222,21 @@ void M_ServersMenu(INT32 choice)
|
|||
// modified game check: no longer handled
|
||||
// we don't request a restart unless the filelist differs
|
||||
|
||||
CL_UpdateServerList();
|
||||
|
||||
mpmenu.ticker = 0;
|
||||
mpmenu.servernum = 0;
|
||||
mpmenu.scrolln = 0;
|
||||
mpmenu.slide = 0;
|
||||
|
||||
PLAY_MP_ServerBrowserDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&PLAY_MP_ServerBrowserDef, false);
|
||||
itemOn = 0;
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
M_ServerListFillDebug();
|
||||
#else /*SERVERLISTDEBUG*/
|
||||
|
||||
#if defined (MASTERSERVER) && defined (HAVE_THREADS)
|
||||
I_lock_mutex(&ms_QueryId_mutex);
|
||||
{
|
||||
|
|
@ -289,12 +266,7 @@ void M_ServersMenu(INT32 choice)
|
|||
M_RefreshServers(0);
|
||||
#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
M_ServerListFillDebug();
|
||||
#endif
|
||||
|
||||
M_CleanServerList();
|
||||
M_SortServerList();
|
||||
#endif /*SERVERLISTDEBUG*/
|
||||
}
|
||||
|
||||
#ifdef SERVERLISTDEBUG
|
||||
|
|
@ -304,29 +276,31 @@ void M_ServerListFillDebug(void)
|
|||
{
|
||||
UINT8 i = 0;
|
||||
|
||||
serverlistcount = 10;
|
||||
serverlistcount = 40;
|
||||
memset(serverlist, 0, sizeof(serverlist)); // zero out the array for convenience...
|
||||
|
||||
for (i = 0; i < serverlistcount; i++)
|
||||
{
|
||||
// We don't really care about the server node for this, let's just fill in the info so that we have a visual...
|
||||
serverlist[i].info.numberofplayer = min(i, 8);
|
||||
serverlist[i].info.maxplayer = 8;
|
||||
serverlist[i].info.maxplayer = M_RandomRange(8, 16);
|
||||
UINT8 val = i % 16;
|
||||
serverlist[i].info.numberofplayer = min(val, serverlist[i].info.maxplayer);
|
||||
|
||||
serverlist[i].info.avgpwrlv = P_RandomRange(PR_UNDEFINED, 500, 1500);
|
||||
serverlist[i].info.time = P_RandomRange(PR_UNDEFINED, 1, 8); // ping
|
||||
serverlist[i].info.avgpwrlv = M_RandomRange(500, 1500);
|
||||
serverlist[i].info.time = M_RandomRange(1, 8); // ping
|
||||
|
||||
strcpy(serverlist[i].info.servername, va("Serv %d", i+1));
|
||||
|
||||
strcpy(serverlist[i].info.gametypename, i & 1 ? "Race" : "Battle");
|
||||
|
||||
P_RandomRange(PR_UNDEFINED, 0, 5); // change results...
|
||||
serverlist[i].info.kartvars = P_RandomRange(PR_UNDEFINED, 0, 3) & SV_SPEEDMASK;
|
||||
serverlist[i].info.kartvars = M_RandomRange(0, 3) & SV_SPEEDMASK;
|
||||
|
||||
serverlist[i].info.modifiedgame = P_RandomRange(PR_UNDEFINED, 0, 1);
|
||||
serverlist[i].info.modifiedgame = M_RandomRange(0, 1);
|
||||
|
||||
CONS_Printf("Serv %d | %d...\n", i, serverlist[i].info.modifiedgame);
|
||||
}
|
||||
|
||||
M_SortServerList();
|
||||
}
|
||||
|
||||
#endif // SERVERLISTDEBUG
|
||||
|
|
@ -339,7 +313,7 @@ static int ServerListEntryComparator_##key(const void *entry1, const void *entry
|
|||
const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2; \
|
||||
if (sa->info.key != sb->info.key) \
|
||||
return sa->info.key - sb->info.key; \
|
||||
return strcmp(sa->info.servername, sb->info.servername); \
|
||||
return sa->info.time - sb->info.time; \
|
||||
}
|
||||
|
||||
// This does descending instead of ascending.
|
||||
|
|
@ -349,15 +323,22 @@ static int ServerListEntryComparator_##key##_reverse(const void *entry1, const v
|
|||
const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2; \
|
||||
if (sb->info.key != sa->info.key) \
|
||||
return sb->info.key - sa->info.key; \
|
||||
return strcmp(sb->info.servername, sa->info.servername); \
|
||||
return sa->info.time - sb->info.time; \
|
||||
}
|
||||
|
||||
SERVER_LIST_ENTRY_COMPARATOR(time)
|
||||
//SERVER_LIST_ENTRY_COMPARATOR(time) -- done seperately due to the usual tiebreaker being time
|
||||
SERVER_LIST_ENTRY_COMPARATOR(numberofplayer)
|
||||
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(numberofplayer)
|
||||
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(maxplayer)
|
||||
SERVER_LIST_ENTRY_COMPARATOR(avgpwrlv)
|
||||
|
||||
static int ServerListEntryComparator_time(const void *entry1, const void *entry2)
|
||||
{
|
||||
const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2;
|
||||
if (sa->info.time != sb->info.time)
|
||||
return sa->info.time - sb->info.time;
|
||||
return strcmp(sa->info.servername, sb->info.servername);
|
||||
}
|
||||
|
||||
static int ServerListEntryComparator_gametypename(const void *entry1, const void *entry2)
|
||||
{
|
||||
|
|
@ -365,13 +346,51 @@ static int ServerListEntryComparator_gametypename(const void *entry1, const void
|
|||
int c;
|
||||
if (( c = strcasecmp(sa->info.gametypename, sb->info.gametypename) ))
|
||||
return c;
|
||||
return strcmp(sa->info.servername, sb->info.servername); \
|
||||
return sa->info.time - sb->info.time;
|
||||
}
|
||||
|
||||
static int ServerListEntryComparator_recommended(const void *entry1, const void *entry2)
|
||||
{
|
||||
const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2;
|
||||
|
||||
INT32 saseedval = sa->info.numberofplayer;
|
||||
INT32 sbseedval = sb->info.numberofplayer;
|
||||
|
||||
// Tyron wrote the following on 25072022:
|
||||
// "sort should be two parts
|
||||
// top part of the list is "all non-empty servers sorted by reverse playercount", with servers above a certain reported ping marked as bad connection or whatever
|
||||
// bottom part of the list is all empty servers sorted by ping"
|
||||
// toast is implementing on 27082023, over a year later, because
|
||||
// "fixing server join flow" is saner to do near the end
|
||||
|
||||
{
|
||||
const UINT8 SERVER_EMPTY = 1;
|
||||
|
||||
// The intent with this nudge is to show you
|
||||
// good games you could get a memorable Duel in,
|
||||
// with the possibility to really katamari into
|
||||
// something more substantial.
|
||||
// By comparison, empty games are not nearly as
|
||||
// fun to get going, so let's lower their SEO.
|
||||
if (!saseedval)
|
||||
saseedval = MAXPLAYERS + SERVER_EMPTY;
|
||||
if (!sbseedval)
|
||||
sbseedval = MAXPLAYERS + SERVER_EMPTY;
|
||||
}
|
||||
|
||||
if (saseedval != sbseedval)
|
||||
return saseedval - sbseedval;
|
||||
|
||||
return sa->info.time - sb->info.time;
|
||||
}
|
||||
|
||||
void M_SortServerList(void)
|
||||
{
|
||||
switch(cv_serversort.value)
|
||||
{
|
||||
case -1:
|
||||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_recommended);
|
||||
break;
|
||||
case 0: // Ping.
|
||||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_time);
|
||||
break;
|
||||
|
|
@ -397,89 +416,115 @@ void M_SortServerList(void)
|
|||
// Server browser inputs & ticker
|
||||
void M_MPServerBrowserTick(void)
|
||||
{
|
||||
mpmenu.ticker++;
|
||||
mpmenu.slide /= 2;
|
||||
|
||||
#if defined (MASTERSERVER) && defined (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
|
||||
|
||||
CL_TimeoutServerList();
|
||||
}
|
||||
|
||||
// Input handler for server browser.
|
||||
boolean M_ServerBrowserInputs(INT32 ch)
|
||||
{
|
||||
UINT8 pid = 0;
|
||||
UINT8 maxscroll = serverlistcount-(SERVERSPERPAGE/2);
|
||||
INT16 maxscroll = serverlistcount - (SERVERSPERPAGE/2) - 2; // Why? Because
|
||||
if (maxscroll < 0)
|
||||
maxscroll = 0;
|
||||
|
||||
const INT16 serverbrowserOn = (currentMenu->numitems - 1);
|
||||
|
||||
(void) ch;
|
||||
|
||||
if (!itemOn && menucmd[pid].dpad_ud < 0)
|
||||
{
|
||||
M_PrevOpt(); // go to itemOn 2
|
||||
if (serverlistcount)
|
||||
{
|
||||
UINT8 prevscroll = mpmenu.scrolln;
|
||||
// Return the MS listing to the bottom.
|
||||
INT32 prevscroll = mpmenu.scrolln;
|
||||
|
||||
mpmenu.servernum = serverlistcount;
|
||||
mpmenu.servernum = serverlistcount-1;
|
||||
mpmenu.scrolln = maxscroll;
|
||||
mpmenu.slide = SERVERSPACE * (prevscroll - mpmenu.scrolln);
|
||||
mpmenu.slide = SERVERSPACE * (prevscroll - (INT32)mpmenu.scrolln);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemOn = 1; // Sike! If there are no servers, go to refresh instead.
|
||||
M_PrevOpt(); // Double apply
|
||||
}
|
||||
|
||||
return true; // overwrite behaviour.
|
||||
}
|
||||
else if (itemOn == 2) // server browser itself...
|
||||
else if (itemOn == (serverbrowserOn - 1) && menucmd[pid].dpad_ud > 0 && !serverlistcount)
|
||||
{
|
||||
// we have to manually do that here.
|
||||
if (M_MenuBackPressed(pid))
|
||||
M_NextOpt(); // Double apply
|
||||
}
|
||||
else if (itemOn == serverbrowserOn) // server browser itself...
|
||||
{
|
||||
#ifndef SERVERLISTDEBUG
|
||||
if (M_MenuConfirmPressed(pid))
|
||||
{
|
||||
M_GoBack(0);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
COM_BufAddText(va("connect node %d\n", serverlist[mpmenu.servernum].node));
|
||||
|
||||
M_PleaseWait();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (menucmd[pid].dpad_ud > 0) // down
|
||||
if (menucmd[pid].dpad_ud > 0) // down
|
||||
{
|
||||
if (mpmenu.servernum >= serverlistcount-1)
|
||||
{
|
||||
UINT8 prevscroll = mpmenu.scrolln;
|
||||
mpmenu.servernum = 0;
|
||||
mpmenu.scrolln = 0;
|
||||
mpmenu.slide = SERVERSPACE * (prevscroll - mpmenu.scrolln);
|
||||
|
||||
M_NextOpt(); // Go back to the top of the real menu.
|
||||
}
|
||||
else
|
||||
if ((UINT32)(mpmenu.servernum+1) < serverlistcount)
|
||||
{
|
||||
// Listing scroll down
|
||||
mpmenu.servernum++;
|
||||
if (mpmenu.scrolln < maxscroll && mpmenu.servernum > SERVERSPERPAGE/2)
|
||||
{
|
||||
mpmenu.scrolln++;
|
||||
mpmenu.slide += SERVERSPACE;
|
||||
}
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return the MS listing to the top.
|
||||
INT32 prevscroll = mpmenu.scrolln;
|
||||
|
||||
mpmenu.servernum = 0;
|
||||
mpmenu.scrolln = 0;
|
||||
mpmenu.slide = SERVERSPACE * (prevscroll - (INT32)mpmenu.scrolln);
|
||||
}
|
||||
else if (menucmd[pid].dpad_ud < 0)
|
||||
{
|
||||
|
||||
if (!mpmenu.servernum)
|
||||
if (mpmenu.servernum)
|
||||
{
|
||||
M_PrevOpt();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mpmenu.servernum <= serverlistcount-(SERVERSPERPAGE/2) && mpmenu.scrolln)
|
||||
// Listing scroll up
|
||||
if (mpmenu.servernum <= (INT16)maxscroll && mpmenu.scrolln)
|
||||
{
|
||||
mpmenu.scrolln--;
|
||||
mpmenu.slide -= SERVERSPACE;
|
||||
}
|
||||
|
||||
mpmenu.servernum--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true; // Overwrite behaviour.
|
||||
}
|
||||
return false; // use normal behaviour.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,19 +31,20 @@ static inline size_t M_StringHeight(const char *string)
|
|||
void M_StartMessage(const char *header, const char *string, void (*routine)(INT32), menumessagetype_t itemtype, const char *confirmstr, const char *defaultstr)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
static char *message = NULL;
|
||||
Z_Free(message);
|
||||
DEBFILE(string);
|
||||
|
||||
message = V_ScaledWordWrap(
|
||||
BASEVIDWIDTH << FRACBITS,
|
||||
char *message = V_ScaledWordWrap(
|
||||
(BASEVIDWIDTH - 8) << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0,
|
||||
HU_FONT,
|
||||
string
|
||||
);
|
||||
|
||||
strncpy(menumessage.message, string, MAXMENUMESSAGE);
|
||||
strncpy(menumessage.message, message, MAXMENUMESSAGE);
|
||||
|
||||
Z_Free(message);
|
||||
|
||||
menumessage.header = header;
|
||||
menumessage.flags = itemtype;
|
||||
menumessage.routine = routine;
|
||||
|
|
@ -84,7 +85,7 @@ void M_StartMessage(const char *header, const char *string, void (*routine)(INT3
|
|||
// oogh my god this was replaced in 2023
|
||||
|
||||
menumessage.x = (8 * MAXSTRINGLENGTH) - 1;
|
||||
menumessage.y = M_StringHeight(message);
|
||||
menumessage.y = M_StringHeight(menumessage.message);
|
||||
|
||||
M_SetMenuDelay(pid); // Set menu delay to avoid setting off any of the handlers.
|
||||
}
|
||||
|
|
|
|||
98
src/mserv.c
98
src/mserv.c
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "doomstat.h"
|
||||
#include "doomdef.h"
|
||||
#include "console.h" // con_startup
|
||||
#include "command.h"
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
|
|
@ -40,6 +41,8 @@ static boolean MSUpdateAgain;
|
|||
|
||||
static time_t MSLastPing;
|
||||
|
||||
static char *MSRules;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static I_mutex MSMutex;
|
||||
static I_cond MSCond;
|
||||
|
|
@ -157,6 +160,43 @@ static void Command_Listserv_f(void)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean firstmsrules = false;
|
||||
|
||||
static void
|
||||
Get_masterserver_rules (boolean checkfirst)
|
||||
{
|
||||
char rules[256];
|
||||
|
||||
if (checkfirst)
|
||||
{
|
||||
boolean MSRulesExist;
|
||||
|
||||
Lock_state();
|
||||
MSRulesExist = (MSRules != NULL);
|
||||
Unlock_state();
|
||||
|
||||
if (MSRulesExist)
|
||||
return;
|
||||
}
|
||||
|
||||
if (HMS_fetch_rules(rules, sizeof rules))
|
||||
{
|
||||
Lock_state();
|
||||
Z_Free(MSRules);
|
||||
MSRules = Z_StrDup(rules);
|
||||
|
||||
if (MSRegistered == true)
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
firstmsrules = true;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Finish_registration (void)
|
||||
{
|
||||
|
|
@ -175,6 +215,17 @@ Finish_registration (void)
|
|||
}
|
||||
Unlock_state();
|
||||
|
||||
char *rules = GetMasterServerRules();
|
||||
if (rules == NULL)
|
||||
{
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
if (registered)
|
||||
CONS_Printf("Master server registration successful.\n");
|
||||
}
|
||||
|
|
@ -257,6 +308,15 @@ Finish_unlist (void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Finish_masterserver_change (char *api)
|
||||
{
|
||||
HMS_set_api(api);
|
||||
|
||||
if (!con_startup)
|
||||
Get_masterserver_rules(false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static int *
|
||||
Server_id (void)
|
||||
|
|
@ -350,7 +410,14 @@ Change_masterserver_thread (char *api)
|
|||
}
|
||||
Unlock_state();
|
||||
|
||||
HMS_set_api(api);
|
||||
Finish_masterserver_change(api);
|
||||
}
|
||||
|
||||
static void
|
||||
Get_masterserver_rules_thread (void)
|
||||
{
|
||||
// THIS FUNC has its own lock check in it
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
|
|
@ -397,6 +464,17 @@ void UnregisterServer(void)
|
|||
#endif/*MASTERSERVER*/
|
||||
}
|
||||
|
||||
char *GetMasterServerRules(void)
|
||||
{
|
||||
char *rules;
|
||||
|
||||
Lock_state();
|
||||
rules = MSRules ? Z_StrDup(MSRules) : NULL;
|
||||
Unlock_state();
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
static boolean
|
||||
Online (void)
|
||||
{
|
||||
|
|
@ -447,7 +525,21 @@ Set_api (const char *api)
|
|||
strdup(api)
|
||||
);
|
||||
#else
|
||||
HMS_set_api(strdup(api));
|
||||
Finish_masterserver_change(strdup(api));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Get_rules (void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"get-masterserver-rules",
|
||||
(I_thread_fn)Get_masterserver_rules_thread,
|
||||
NULL
|
||||
);
|
||||
#else
|
||||
Get_masterserver_rules(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -521,6 +613,8 @@ void Advertise_OnChange(void)
|
|||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
|
||||
M_PopupMasterServerRules();
|
||||
}
|
||||
|
||||
#ifdef DEVELOP
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ struct msg_ban_t
|
|||
// ================================ GLOBALS ===============================
|
||||
|
||||
extern consvar_t cv_masterserver, cv_servername;
|
||||
extern consvar_t cv_masterserver_nagattempts;
|
||||
extern consvar_t cv_server_contact;
|
||||
extern consvar_t cv_masterserver_update_rate;
|
||||
extern consvar_t cv_masterserver_timeout;
|
||||
|
|
@ -77,6 +78,8 @@ extern I_mutex ms_ServerList_mutex;
|
|||
void RegisterServer(void);
|
||||
void UnregisterServer(void);
|
||||
|
||||
void Get_rules(void);
|
||||
|
||||
void MasterClient_Ticker(void);
|
||||
|
||||
msg_server_t *GetShortServersList(int id);
|
||||
|
|
@ -84,6 +87,8 @@ msg_server_t *GetShortServersList(int id);
|
|||
char *GetMODVersion(int id);
|
||||
#endif
|
||||
|
||||
char *GetMasterServerRules(void);
|
||||
|
||||
void AddMServCommands(void);
|
||||
|
||||
/* HTTP */
|
||||
|
|
@ -94,6 +99,7 @@ int HMS_update (void);
|
|||
void HMS_list_servers (void);
|
||||
msg_server_t * HMS_fetch_servers (msg_server_t *list, int id);
|
||||
int HMS_compare_mod_version (char *buffer, size_t size_of_buffer);
|
||||
const char * HMS_fetch_rules (char *buffer, size_t size_of_buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#define SRB2VERSION "2.0"/* this must be the first line, for cmake !! */
|
||||
#define SRB2VERSION "1.0"/* this must be the first line, for cmake !! */
|
||||
|
||||
// The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/showgroups.php ).
|
||||
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue