Merge remote-tracking branch 'remotes/james/awful-mix-fucked' into awful-mix

This commit is contained in:
Wolfy 2020-04-30 04:40:11 -05:00
commit af0a93ea53
11 changed files with 115 additions and 649 deletions

View file

@ -1304,8 +1304,7 @@ found:
var->string = var->zstring = Z_StrDup(valstr); var->string = var->zstring = Z_StrDup(valstr);
if (var->flags & CV_PASSWORD); // Don't change value for password field if (override)
else if (override)
var->value = overrideval; var->value = overrideval;
else if (var->flags & CV_FLOAT) else if (var->flags & CV_FLOAT)
{ {

View file

@ -98,8 +98,7 @@ typedef enum
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it // can only be set when we have the pointer to it
// used on menus // used on menus
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on.
CV_PASSWORD = 4096 // Password field
} cvflags_t; } cvflags_t;
typedef struct CV_PossibleValue_s typedef struct CV_PossibleValue_s

View file

@ -23,7 +23,6 @@
#include "d_net.h" #include "d_net.h"
#include "d_netfil.h" // fileneedednum #include "d_netfil.h" // fileneedednum
#include "d_main.h" #include "d_main.h"
#include "d_event.h"
#include "g_game.h" #include "g_game.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "keys.h" #include "keys.h"
@ -675,7 +674,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
static void resynch_read_player(resynch_pak *rsp) static void resynch_read_player(resynch_pak *rsp)
{ {
INT32 i = rsp->playernum, j; INT32 i = rsp->playernum, j;
//mobj_t *savedmo = players[i].mo; mobj_t *savedmo = players[i].mo;
// Do not send anything visual related. // Do not send anything visual related.
// Only send data that we need to know for physics. // Only send data that we need to know for physics.
@ -768,17 +767,11 @@ static void resynch_read_player(resynch_pak *rsp)
return; return;
//...but keep old mo even if it is corrupt or null! //...but keep old mo even if it is corrupt or null!
//players[i].mo = savedmo; players[i].mo = savedmo;
//Transfer important mo information if they have a valid mo. //Transfer important mo information if they have a valid mo.
if (!rsp->hasmo) if (!rsp->hasmo)
{
// Get rid of their object if they aren't supposed to have one.....??
if (players[i].mo)
P_RemoveMobj(players[i].mo);
return; return;
}
//server thinks player has a body. //server thinks player has a body.
//Give them a new body that can be then manipulated by the server's info. //Give them a new body that can be then manipulated by the server's info.
@ -1031,7 +1024,6 @@ static void SV_SendResynch(INT32 node)
return; return;
} }
resynch_inprogress[node] = false; // Let's see if there's REALLY anyone left to sync.....
netbuffer->packettype = PT_RESYNCHING; netbuffer->packettype = PT_RESYNCHING;
for (i = 0, j = 0; i < MAXPLAYERS; ++i) for (i = 0, j = 0; i < MAXPLAYERS; ++i)
{ {
@ -1039,24 +1031,10 @@ static void SV_SendResynch(INT32 node)
if (!(resynch_status[node] & 1<<i)) if (!(resynch_status[node] & 1<<i))
continue; continue;
if (!playeringame[i])
continue; // Player doesn't exist any more, so no need to resync them!
resynch_inprogress[node] = true;
// waiting for a reply or just waiting in general // waiting for a reply or just waiting in general
if (resynch_sent[node][i]) if (resynch_sent[node][i])
{ {
--resynch_sent[node][i]; --resynch_sent[node][i];
if (resynch_sent[node][i] > TICRATE)
{
CONS_Alert(CONS_ERROR, "Node %d (%s) somehow had a stupidly-long resync delay?! (%d tics to resync player %d)\n",
node, player_names[nodetoplayer[node]], resynch_sent[node][i], i
);
resynch_sent[node][i] = TICRATE;
}
continue; continue;
} }
@ -1070,15 +1048,6 @@ static void SV_SendResynch(INT32 node)
break; break;
} }
if (!resynch_inprogress[node])
{
CONS_Alert(CONS_ERROR, "Node %d (%s) somehow had resync status for nonexistent players?! (%08x)\n",
node, player_names[nodetoplayer[node]], resynch_status[node] = 0x00
);
resynch_status[node] = 0x00;
resynch_inprogress[node] = true; // So they get the PT_RESYNCHEND...
}
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250) if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
{ {
XBOXSTATIC UINT8 buf[2]; XBOXSTATIC UINT8 buf[2];
@ -1133,32 +1102,22 @@ typedef enum
CL_CONNECTED, CL_CONNECTED,
CL_ABORTED, CL_ABORTED,
CL_ASKFULLFILELIST, CL_ASKFULLFILELIST,
CL_ASKDOWNLOADFILES,
CL_WAITDOWNLOADFILESRESPONSE,
#ifdef HAVE_CURL #ifdef HAVE_CURL
CL_PREPAREHTTPFILES, CL_PREPAREHTTPFILES,
CL_DOWNLOADHTTPFILES, CL_DOWNLOADHTTPFILES,
#endif #endif
CL_CHALLENGE
} cl_mode_t; } cl_mode_t;
static void GetPackets(void); static void GetPackets(void);
static cl_mode_t cl_mode = CL_SEARCHING; static cl_mode_t cl_mode = CL_SEARCHING;
static boolean cl_needsdownload = false;
static UINT16 cl_lastcheckedfilecount = 0;
static UINT8 cl_challengenum = 0;
static UINT8 cl_challengequestion[MD5_LEN+1];
static char cl_challengepassword[65];
static UINT8 cl_challengeanswer[MD5_LEN+1];
static UINT8 cl_challengeattempted = 0;
static char cl_challengeaddress[64];
#ifdef HAVE_CURL #ifdef HAVE_CURL
char http_source[MAX_MIRROR_LENGTH]; char http_source[MAX_MIRROR_LENGTH];
#endif #endif
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
// Player name send/load // Player name send/load
static void CV_SavePlayerNames(UINT8 **p) static void CV_SavePlayerNames(UINT8 **p)
@ -1194,7 +1153,6 @@ static void CV_LoadPlayerNames(UINT8 **p)
} }
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
static UINT32 SL_SearchServer(INT32 node);
// //
// CL_DrawConnectionStatus // CL_DrawConnectionStatus
@ -1223,42 +1181,11 @@ static inline void CL_DrawConnectionStatus(void)
// 15 pal entries total. // 15 pal entries total.
const char *cltext; const char *cltext;
if (cl_mode != CL_CHALLENGE)
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15)); V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
switch (cl_mode) switch (cl_mode)
{ {
case CL_CHALLENGE:
{
char asterisks[33];
size_t sl = min(32, strlen(cl_challengepassword));
UINT32 serverid;
memset(asterisks, '*', sl);
memset(asterisks+sl, 0, 33-sl);
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_MONOSPACE|V_ALLOWLOWERCASE, asterisks);
V_DrawFixedPatch((BASEVIDWIDTH/2) << FRACBITS, (BASEVIDHEIGHT/2) << FRACBITS, FRACUNIT, 0, W_CachePatchName("BSRVLOCK", PU_CACHE), NULL);
serverid = SL_SearchServer(servernode);
if (serverid == UINT32_MAX)
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 1);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server is password protected."));
}
else
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server,"));
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+8, V_ALLOWLOWERCASE, serverlist[serverid].info.servername);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+16, V_REDMAP, M_GetText("is password protected."));
}
cltext = M_GetText(cl_challengeattempted ? "Incorrect password. Please try again." : "Please enter the server password.");
}
break;
#ifdef JOININGAME #ifdef JOININGAME
case CL_DOWNLOADSAVEGAME: case CL_DOWNLOADSAVEGAME:
if (lastfilenum != -1) if (lastfilenum != -1)
@ -1281,12 +1208,11 @@ static inline void CL_DrawConnectionStatus(void)
case CL_WAITJOINRESPONSE: case CL_WAITJOINRESPONSE:
cltext = M_GetText("Requesting to join..."); cltext = M_GetText("Requesting to join...");
break; break;
case CL_ASKDOWNLOADFILES:
case CL_WAITDOWNLOADFILESRESPONSE:
#ifdef HAVE_CURL #ifdef HAVE_CURL
case CL_PREPAREHTTPFILES: case CL_PREPAREHTTPFILES:
#endif
cltext = M_GetText("Waiting to download files..."); cltext = M_GetText("Waiting to download files...");
break;
#endif
default: default:
cltext = M_GetText("Connecting to server..."); cltext = M_GetText("Connecting to server...");
break; break;
@ -1376,9 +1302,6 @@ static boolean CL_SendJoin(void)
netbuffer->u.clientcfg.subversion = SUBVERSION; netbuffer->u.clientcfg.subversion = SUBVERSION;
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
sizeof netbuffer->u.clientcfg.application); sizeof netbuffer->u.clientcfg.application);
netbuffer->u.clientcfg.needsdownload = cl_needsdownload;
netbuffer->u.clientcfg.challengenum = cl_challengenum;
memcpy(netbuffer->u.clientcfg.challengeanswer, cl_challengeanswer, MD5_LEN);
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
} }
@ -1410,10 +1333,10 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.kartvars = (UINT8) ( netbuffer->u.serverinfo.kartvars = (UINT8) (
(cv_kartspeed.value & SV_SPEEDMASK) | (cv_kartspeed.value & SV_SPEEDMASK) |
(dedicated ? SV_DEDICATED : 0) | (dedicated ? SV_DEDICATED : 0)
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
); );
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
MAXSERVERNAME); MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
@ -1479,8 +1402,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum
#ifdef HAVE_CURL #ifdef HAVE_CURL
if (! D_IsJoinPasswordOn())
{
mirror_length = strlen(httpurl); mirror_length = strlen(httpurl);
if (mirror_length > MAX_MIRROR_LENGTH) if (mirror_length > MAX_MIRROR_LENGTH)
mirror_length = MAX_MIRROR_LENGTH; mirror_length = MAX_MIRROR_LENGTH;
@ -1490,7 +1411,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length); strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length);
netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0'; netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0';
}
#endif #endif
p = PutFileNeeded(0); p = PutFileNeeded(0);
@ -2015,7 +1935,39 @@ static boolean CL_FinishedFileList(void)
else if (i == 1) else if (i == 1)
cl_mode = CL_ASKJOIN; cl_mode = CL_ASKJOIN;
else else
cl_mode = CL_ASKDOWNLOADFILES; {
// must download something
// can we, though?
#ifdef HAVE_CURL
if (http_source[0] == '\0' || curl_failedwebdownload)
#endif
{
if (!CL_CheckDownloadable()) // nope!
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You cannot connect to this server\n"
"because you cannot download the files\n"
"that you are missing from the server.\n\n"
"See the console or log file for\n"
"more details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return false;
}
if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES;
}
#ifdef HAVE_CURL
else
{
cl_mode = CL_PREPAREHTTPFILES;
}
#endif
}
return true; return true;
} }
@ -2062,6 +2014,16 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
if (client) if (client)
{ {
#ifdef HAVE_CURL
if (serverlist[i].info.httpsource[0])
strncpy(http_source, serverlist[i].info.httpsource, MAX_MIRROR_LENGTH);
else
http_source[0] = '\0';
#else
if (serverlist[i].info.httpsource[0])
CONS_Printf("We received a http url from the server, however it will not be used as this build lacks curl support (%s)\n", serverlist[i].info.httpsource);
#endif
D_ParseFileneeded(serverlist[i].info.fileneedednum, serverlist[i].info.fileneeded, 0); D_ParseFileneeded(serverlist[i].info.fileneedednum, serverlist[i].info.fileneeded, 0);
if (serverlist[i].info.kartvars & SV_LOTSOFADDONS) if (serverlist[i].info.kartvars & SV_LOTSOFADDONS)
{ {
@ -2140,6 +2102,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
#ifdef HAVE_CURL #ifdef HAVE_CURL
case CL_PREPAREHTTPFILES: case CL_PREPAREHTTPFILES:
if (http_source[0])
{ {
for (i = 0; i < fileneedednum; i++) for (i = 0; i < fileneedednum; i++)
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
@ -2169,9 +2132,12 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
if (curl_failedwebdownload && !curl_transfers) if (curl_failedwebdownload && !curl_transfers)
{ {
CONS_Printf("One or more files failed to download, falling back to internal downloader\n"); CONS_Printf("One or more files failed to download, falling back to internal downloader\n");
cl_mode = CL_ASKDOWNLOADFILES; if (CL_SendRequestFile())
{
cl_mode = CL_DOWNLOADFILES;
break; break;
} }
}
if (!curl_transfers) if (!curl_transfers)
cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now
@ -2194,7 +2160,6 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
/* FALLTHRU */ /* FALLTHRU */
case CL_ASKJOIN: case CL_ASKJOIN:
cl_needsdownload = false;
CL_LoadServerFiles(); CL_LoadServerFiles();
#ifdef JOININGAME #ifdef JOININGAME
// prepare structures to save the file // prepare structures to save the file
@ -2203,23 +2168,9 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
CL_PrepareDownloadSaveGame(tmpsave); CL_PrepareDownloadSaveGame(tmpsave);
#endif #endif
if (CL_SendJoin()) if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITJOINRESPONSE; cl_mode = CL_WAITJOINRESPONSE;
}
break; break;
case CL_ASKDOWNLOADFILES:
cl_needsdownload = true;
if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITDOWNLOADFILESRESPONSE;
}
break;
#ifdef JOININGAME #ifdef JOININGAME
case CL_DOWNLOADSAVEGAME: case CL_DOWNLOADSAVEGAME:
// At this state, the first (and only) needed file is the gamestate // At this state, the first (and only) needed file is the gamestate
@ -2233,19 +2184,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
break; break;
#endif #endif
case CL_CHALLENGE:
(*asksent) = I_GetTime() - NEWTICRATE; // Send password immediately upon entering
break;
case CL_WAITJOINRESPONSE: case CL_WAITJOINRESPONSE:
case CL_WAITDOWNLOADFILESRESPONSE:
if (*asksent + NEWTICRATE < I_GetTime() && CL_SendJoin())
{
*asksent = I_GetTime();
}
break;
case CL_CONNECTED: case CL_CONNECTED:
default: default:
break; break;
@ -2263,15 +2202,21 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
// Call it only once by tic // Call it only once by tic
if (*oldtic != I_GetTime()) if (*oldtic != I_GetTime())
{ {
I_OsPolling();
D_ProcessEvents();
if (gamestate != GS_WAITINGPLAYERS)
return false;
// why are these here? this is for servers, we're a client INT32 key;
//if (key == 's' && server)
// doomcom->numnodes = (INT16)pnumnodes; I_OsPolling();
//SV_FileSendTicker(); key = I_GetKey();
// Only ESC and non-keyboard keys abort connection
if (key == KEY_ESCAPE || key >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
D_QuitNetGame();
CL_Reset();
D_StartTitle();
return false;
}
*oldtic = I_GetTime(); *oldtic = I_GetTime();
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
@ -2295,73 +2240,6 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
return true; return true;
} }
boolean CL_Responder(event_t *ev)
{
size_t len;
INT32 ch;
if (!(client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED))
return false; // Don't do anything outside of the connection screen
if (ev->type != ev_keydown)
return false;
ch = (INT32)ev->data1;
// Only ESC and non-keyboard keys abort connection
if (ch == KEY_ESCAPE || ch >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
//M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
return true;
}
if (cl_mode != CL_CHALLENGE)
return false;
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course
{
len = strlen(cl_challengepassword);
if (len < 64)
{
cl_challengepassword[len+1] = 0;
cl_challengepassword[len] = CON_ShiftChar(ch);
}
cl_challengeattempted = 0;
}
else if (ch == KEY_BACKSPACE)
{
len = strlen(cl_challengepassword);
if (len > 0)
cl_challengepassword[len-1] = 0;
cl_challengeattempted = 0;
}
else if (ch == KEY_ENTER)
{
netgame = true;
multiplayer = true;
#ifndef NONET
SL_ClearServerList(servernode);
if (I_NetMakeNodewPort)
servernode = I_NetMakeNode(cl_challengeaddress);
#endif
cl_mode = CL_SEARCHING;
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
cl_challengeattempted = 1;
}
return true;
}
/** Use adaptive send using net_bandwidth and stat.sendbytes /** Use adaptive send using net_bandwidth and stat.sendbytes
* *
* \param viams ??? * \param viams ???
@ -2382,7 +2260,6 @@ static void CL_ConnectToServer(boolean viams)
#endif #endif
cl_mode = CL_SEARCHING; cl_mode = CL_SEARCHING;
cl_challengenum = 0;
#ifdef CLIENT_LOADINGSCREEN #ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1; lastfilenum = -1;
@ -2407,8 +2284,6 @@ static void CL_ConnectToServer(boolean viams)
if (gamestate == GS_VOTING) if (gamestate == GS_VOTING)
Y_EndVote(); Y_EndVote();
resynch_local_inprogress = false; // Just in case this was never cleared...
DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); DEBFILE(va("waiting %d nodes\n", doomcom->numnodes));
G_SetGamestate(GS_WAITINGPLAYERS); G_SetGamestate(GS_WAITINGPLAYERS);
wipegamestate = GS_WAITINGPLAYERS; wipegamestate = GS_WAITINGPLAYERS;
@ -2439,8 +2314,6 @@ static void CL_ConnectToServer(boolean viams)
SL_ClearServerList(servernode); SL_ClearServerList(servernode);
#endif #endif
cl_challengeattempted = 0;
do do
{ {
// If the connection was aborted for some reason, leave // If the connection was aborted for some reason, leave
@ -3386,9 +3259,6 @@ void D_ClientServerInit(void)
gametic = 0; gametic = 0;
localgametic = 0; localgametic = 0;
memset(cl_challengequestion, 0x00, MD5_LEN+1);
memset(cl_challengeanswer, 0x00, MD5_LEN+1);
// do not send anything before the real begin // do not send anything before the real begin
SV_StopServer(); SV_StopServer();
SV_ResetServer(); SV_ResetServer();
@ -3512,7 +3382,6 @@ void D_QuitNetGame(void)
HSendPacket(servernode, true, 0, 0); HSendPacket(servernode, true, 0, 0);
} }
resynch_local_inprogress = false; // No more resyncing!
D_CloseConnection(); D_CloseConnection();
ClearAdminPlayers(); ClearAdminPlayers();
@ -3871,35 +3740,6 @@ static void HandleConnect(SINT8 node)
boolean newnode = false; boolean newnode = false;
#endif #endif
if (node != servernode && !nodeingame[node] && D_IsJoinPasswordOn())
{
// Ensure node sent the correct password challenge
boolean passed = false;
if (netbuffer->u.clientcfg.challengenum && D_VerifyJoinPasswordChallenge(netbuffer->u.clientcfg.challengenum, netbuffer->u.clientcfg.challengeanswer))
passed = true;
if (!passed)
{
D_MakeJoinPasswordChallenge(&netbuffer->u.joinchallenge.challengenum, netbuffer->u.joinchallenge.question);
netbuffer->packettype = PT_JOINCHALLENGE;
HSendPacket(node, false, 0, sizeof(joinchallenge_pak));
Net_CloseConnection(node);
return;
}
}
if (netbuffer->u.clientcfg.needsdownload)
{
netbuffer->packettype = PT_DOWNLOADFILESOKAY;
strncpy(netbuffer->u.filecfg.http_source, cv_httpsource.string,
MAX_MIRROR_LENGTH);
HSendPacket(node, true, 0, sizeof netbuffer->u.filecfg);
return;
}
// client authorised to join // client authorised to join
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
if (!nodeingame[node]) if (!nodeingame[node])
@ -4099,52 +3939,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
break; break;
case PT_JOINCHALLENGE:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
if (cl_mode == CL_WAITJOINRESPONSE || cl_mode == CL_WAITDOWNLOADFILESRESPONSE)
{
cl_challengenum = netbuffer->u.joinchallenge.challengenum;
memcpy(cl_challengequestion, netbuffer->u.joinchallenge.question, 16);
if (I_GetNodeAddress)
strcpy(cl_challengeaddress, I_GetNodeAddress(node));
Net_CloseConnection(node); // Don't need to stay connected while challenging
cl_mode = CL_CHALLENGE;
switch (cl_challengeattempted)
{
case 2:
// We already sent a correct password, so throw it back up again.
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
#ifndef NONET
if (I_NetMakeNodewPort)
servernode = I_NetMakeNode(cl_challengeaddress);
#endif
if (cl_needsdownload)
cl_mode = CL_ASKDOWNLOADFILES;
else
cl_mode = CL_ASKJOIN;
break;
case 1:
// We entered the wrong password!
S_StartSound(NULL, sfx_s26d);
break;
default:
// First entry to the password screen.
S_StartSound(NULL, sfx_s224);
break;
}
}
break;
case PT_SERVERREFUSE: // Negative response of client join request case PT_SERVERREFUSE: // Negative response of client join request
if (server && serverrunning) if (server && serverrunning)
{ // But wait I thought I'm the server? { // But wait I thought I'm the server?
@ -4173,63 +3967,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
} }
break; break;
case PT_DOWNLOADFILESOKAY:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
if (netbuffer->u.filecfg.http_source[0] != '\0')
{
netbuffer->u.filecfg.http_source[MAX_MIRROR_LENGTH-1] = '\0';
#ifdef HAVE_CURL
if (! curl_failedwebdownload)
{
strncpy(http_source, netbuffer->u.filecfg.http_source,
sizeof http_source);
cl_mode = CL_PREPAREHTTPFILES;
}
#else
CONS_Printf("We received a http url from the server, however it will not be used as this build lacks curl support (%s)\n", netbuffer->u.filecfg.http_source);
#endif
}
if (cl_mode == CL_WAITDOWNLOADFILESRESPONSE)
{
if (CL_CheckDownloadable())
{
CONS_Printf("trying to download\n");
if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES;
}
else
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You cannot connect to this server\n"
"because you cannot download the files\n"
"that you are missing from the server.\n\n"
"See the console or log file for\n"
"more details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
break;
}
}
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
cl_challengeattempted = 2;
break;
case PT_SERVERCFG: // Positive response of client join request case PT_SERVERCFG: // Positive response of client join request
{ {
INT32 j; INT32 j;
@ -4245,9 +3982,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (cl_mode != CL_WAITJOINRESPONSE) if (cl_mode != CL_WAITJOINRESPONSE)
break; break;
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
if (client) if (client)
{ {
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);

View file

@ -13,14 +13,11 @@
#ifndef __D_CLISRV__ #ifndef __D_CLISRV__
#define __D_CLISRV__ #define __D_CLISRV__
#include "d_event.h"
#include "d_ticcmd.h" #include "d_ticcmd.h"
#include "d_netcmd.h" #include "d_netcmd.h"
#include "tables.h" #include "tables.h"
#include "d_player.h" #include "d_player.h"
#include "md5.h"
/* /*
The 'packet version' is used to distinguish packet formats. The 'packet version' is used to distinguish packet formats.
This version is independent of VERSION and SUBVERSION. Different This version is independent of VERSION and SUBVERSION. Different
@ -86,9 +83,6 @@ typedef enum
PT_CLIENT4MIS, PT_CLIENT4MIS,
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
PT_JOINCHALLENGE, // You must give a password to joinnnnn
PT_DOWNLOADFILESOKAY, // You can download files from the server....
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
// allows HSendPacket(*, true, *, *) to return false. // allows HSendPacket(*, true, *, *) to return false.
// In addition, this packet can't occupy all the available slots. // In addition, this packet can't occupy all the available slots.
@ -361,22 +355,13 @@ typedef struct
char application[MAXAPPLICATION]; char application[MAXAPPLICATION];
UINT8 version; // Different versions don't work UINT8 version; // Different versions don't work
UINT8 subversion; // Contains build version UINT8 subversion; // Contains build version
UINT8 localplayers; UINT8 localplayers; // number of splitscreen players
UINT8 needsdownload; UINT8 mode;
UINT8 challengenum; // Non-zero if trying to join with a password attempt
UINT8 challengeanswer[MD5_LEN]; // Join challenge
} ATTRPACK clientconfig_pak; } ATTRPACK clientconfig_pak;
typedef struct #define SV_SPEEDMASK 0x03 // used to send kartspeed
{ #define SV_DEDICATED 0x40 // server is dedicated
UINT8 challengenum; // Number to send back in join attempt #define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
UINT8 question[MD5_LEN]; // Challenge data to be manipulated and answered with
} ATTRPACK joinchallenge_pak;
#define SV_SPEEDMASK 0x03
#define SV_LOTSOFADDONS 0x20
#define SV_DEDICATED 0x40
#define SV_PASSWORD 0x80
#define MAXSERVERNAME 32 #define MAXSERVERNAME 32
#define MAXFILENEEDED 915 #define MAXFILENEEDED 915
@ -462,11 +447,6 @@ typedef struct
UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
} ATTRPACK filesneededconfig_pak; } ATTRPACK filesneededconfig_pak;
typedef struct
{
char http_source[MAX_MIRROR_LENGTH];/* first byte 0? no die! */
} ATTRPACK fileconfig;
// //
// Network packet data // Network packet data
// //
@ -492,7 +472,6 @@ typedef struct
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes filetx_pak filetxpak; // 139 bytes
clientconfig_pak clientcfg; // 153 bytes clientconfig_pak clientcfg; // 153 bytes
joinchallenge_pak joinchallenge; // 17 bytes
serverinfo_pak serverinfo; // 1024 bytes serverinfo_pak serverinfo; // 1024 bytes
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes askinfo_pak askinfo; // 61 bytes
@ -501,7 +480,6 @@ typedef struct
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
INT32 filesneedednum; // 4 bytes INT32 filesneedednum; // 4 bytes
filesneededconfig_pak filesneededcfg; // ??? bytes filesneededconfig_pak filesneededcfg; // ??? bytes
fileconfig filecfg;
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
} u; // This is needed to pack diff packet types data together } u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t; } ATTRPACK doomdata_t;
@ -599,7 +577,6 @@ void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum); void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason); void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_UpdateServerList(boolean internetsearch, INT32 room); void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running // Is there a game running
boolean Playing(void); boolean Playing(void);

View file

@ -231,9 +231,6 @@ void D_ProcessEvents(void)
if (M_ScreenshotResponder(ev)) if (M_ScreenshotResponder(ev))
continue; // ate the event continue; // ate the event
if (CL_Responder(ev))
continue;
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN) if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{ {
if (cht_Responder(ev)) if (cht_Responder(ev))

View file

@ -339,7 +339,6 @@ static boolean Processackpak(void)
{ {
UINT8 ack = netbuffer->ack; UINT8 ack = netbuffer->ack;
getackpacket++; getackpacket++;
if (cmpack(ack, node->firstacktosend) <= 0) if (cmpack(ack, node->firstacktosend) <= 0)
{ {
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
@ -362,7 +361,6 @@ static boolean Processackpak(void)
// Is a good packet so increment the acknowledge number, // Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue // Then search for a "hole" in the queue
UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1);
if (!nextfirstack) if (!nextfirstack)
nextfirstack = 1; nextfirstack = 1;
@ -781,8 +779,6 @@ static const char *packettypename[NUMPACKETTYPE] =
{ {
"NOTHING", "NOTHING",
"SERVERCFG", "SERVERCFG",
"CLIENTCMD", "CLIENTCMD",
"CLIENTMIS", "CLIENTMIS",
"CLIENT2CMD", "CLIENT2CMD",
@ -803,33 +799,20 @@ static const char *packettypename[NUMPACKETTYPE] =
"RESYNCHEND", "RESYNCHEND",
"RESYNCHGET", "RESYNCHGET",
"CLIENT3CMD", "CLIENT3CMD",
"CLIENT3MIS", "CLIENT3MIS",
"CLIENT4CMD", "CLIENT4CMD",
"CLIENT4MIS", "CLIENT4MIS",
"BASICKEEPALIVE", "BASICKEEPALIVE",
"JOINCHALLENGE",
"DOWNLOADFILESOKAY",
"FILEFRAGMENT", "FILEFRAGMENT",
"TEXTCMD", "TEXTCMD",
"TEXTCMD2", "TEXTCMD2",
"TEXTCMD3", "TEXTCMD3",
"TEXTCMD4", "TEXTCMD4",
"CLIENTJOIN", "CLIENTJOIN",
"NODETIMEOUT", "NODETIMEOUT",
"RESYNCHING", "RESYNCHING",
"TELLFILESNEEDED",
"MOREFILESNEEDED",
"PING" "PING"
}; };
@ -847,7 +830,7 @@ static void DebugPrintpacket(const char *header)
break; break;
case PT_CLIENTJOIN: case PT_CLIENTJOIN:
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers, fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
netbuffer->u.clientcfg.needsdownload); netbuffer->u.clientcfg.mode);
break; break;
case PT_SERVERTICS: case PT_SERVERTICS:
{ {
@ -1084,10 +1067,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
netbuffer->checksum = NetbufferChecksum(); netbuffer->checksum = NetbufferChecksum();
sendbytes += packetheaderlength + doomcom->datalength; // For stat sendbytes += packetheaderlength + doomcom->datalength; // For stat
// Joinpasswords close nodes, this may try to send to a waiting-to-close node, so cancel closing?
if (netbuffer->packettype == PT_CLIENTJOIN)
nodes[node].flags &= ~NF_CLOSE;
#ifdef PACKETDROP #ifdef PACKETDROP
// Simulate internet :) // Simulate internet :)
//if (rand() >= (INT32)(RAND_MAX * (PACKETLOSSRATE / 100.f))) //if (rand() >= (INT32)(RAND_MAX * (PACKETLOSSRATE / 100.f)))
@ -1124,7 +1103,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
// //
boolean HGetPacket(void) boolean HGetPacket(void)
{ {
boolean nodejustjoined; //boolean nodejustjoined;
// Get a packet from self // Get a packet from self
if (rebound_tail != rebound_head) if (rebound_tail != rebound_head)
@ -1151,56 +1130,11 @@ boolean HGetPacket(void)
while(true) while(true)
{ {
nodejustjoined = I_NetGet(); //nodejustjoined = I_NetGet();
//I_NetGet(); I_NetGet();
if (doomcom->remotenode == -1) // No packet received if (doomcom->remotenode == -1) // No packet received
{
if (nodejustjoined) // _This_ means we did receive a packet, but either from a node we couldn't allocate or a gone player ackreting...
continue;
else
return false; return false;
}
if (nodejustjoined)
{
// If a new node sends an unexpected packet, just ignore it
if (server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN
|| netbuffer->packettype == PT_TELLFILESNEEDED
|| netbuffer->packettype == PT_CLIENTCMD))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}
// UGLY PROBABLY-BAD HACK: If we get PT_CLIENTJOIN, assume this is an in-order packet?
if (netbuffer->packettype == PT_CLIENTJOIN)
nodes[doomcom->remotenode].firstacktosend = (UINT8)((netbuffer->ack-1+MAXACKTOSEND) % MAXACKTOSEND);
if (netbuffer->ack > 1 && !(server && netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE("New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n");
CONS_Alert(CONS_NOTICE, "New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n");
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}
// Reinitialize vars for the new node just in case there's anything left over from other players.....
InitNode(&nodes[doomcom->remotenode]);
SV_AbortSendFiles(doomcom->remotenode);
}
// Joinpasswords close nodes, this may receive from a waiting-to-close node, so cancel closing?
if (netbuffer->packettype == PT_CLIENTJOIN)
nodes[doomcom->remotenode].flags &= ~NF_CLOSE;
getbytes += packetheaderlength + doomcom->datalength; // For stat getbytes += packetheaderlength + doomcom->datalength; // For stat
@ -1215,8 +1149,8 @@ boolean HGetPacket(void)
if (netbuffer->checksum != NetbufferChecksum()) if (netbuffer->checksum != NetbufferChecksum())
{ {
DEBFILE("Bad packet checksum\n"); DEBFILE("Bad packet checksum\n");
Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode); //Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
//Net_CloseConnection(doomcom->remotenode); Net_CloseConnection(doomcom->remotenode);
continue; continue;
} }
@ -1225,6 +1159,21 @@ boolean HGetPacket(void)
DebugPrintpacket("GET"); DebugPrintpacket("GET");
#endif #endif
/*// If a new node sends an unexpected packet, just ignore it
if (nodejustjoined && server
&& !(netbuffer->packettype == PT_ASKINFO
|| netbuffer->packettype == PT_SERVERINFO
|| netbuffer->packettype == PT_PLAYERINFO
|| netbuffer->packettype == PT_REQUESTFILE
|| netbuffer->packettype == PT_ASKINFOVIAMS
|| netbuffer->packettype == PT_CLIENTJOIN))
{
DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]));
//CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]);
Net_CloseConnection(doomcom->remotenode | FORCECLOSE);
continue;
}*/
// Proceed the ack and ackreturn field // Proceed the ack and ackreturn field
if (!Processackpak()) if (!Processackpak())
continue; // discarded (duplicated) continue; // discarded (duplicated)

View file

@ -172,7 +172,6 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void); static void Command_Verify_f(void);
static void Command_RemoveAdmin_f(void); static void Command_RemoveAdmin_f(void);
static void Command_ChangeJoinPassword_f(void);
static void Command_MotD_f(void); static void Command_MotD_f(void);
static void Got_MotD_f(UINT8 **cp, INT32 playernum); static void Got_MotD_f(UINT8 **cp, INT32 playernum);
@ -554,8 +553,6 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
// Remote Administration // Remote Administration
CV_RegisterVar(&cv_dummyjoinpassword);
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
COM_AddCommand("password", Command_Changepassword_f); COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login); RegisterNetXCmd(XD_LOGIN, Got_Login);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -3972,131 +3969,6 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("You are no longer a server administrator.\n")); CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
} }
// Join password stuff
consvar_t cv_dummyjoinpassword = {"dummyjoinpassword", "", CV_HIDEN|CV_NOSHOWHELP|CV_PASSWORD, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#define NUMJOINCHALLENGES 32
static UINT8 joinpassmd5[MD5_LEN+1];
boolean joinpasswordset = false;
static UINT8 joinpasschallenges[NUMJOINCHALLENGES][MD5_LEN];
static tic_t joinpasschallengeson[NUMJOINCHALLENGES];
boolean D_IsJoinPasswordOn(void)
{
return joinpasswordset;
}
static inline void GetChallengeAnswer(UINT8 *question, UINT8 *passwordmd5, UINT8 *answer)
{
D_MD5PasswordPass(question, MD5_LEN, (char *) passwordmd5, answer);
}
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer)
{
static UINT8 passwordmd5[MD5_LEN+1];
memset(passwordmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &passwordmd5);
GetChallengeAnswer(question, passwordmd5, answer);
}
void D_SetJoinPassword(const char *pw)
{
memset(joinpassmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &joinpassmd5);
joinpasswordset = true;
}
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer)
{
boolean passed = false;
num %= NUMJOINCHALLENGES;
//@TODO use a constant-time memcmp....
if (joinpasschallengeson[num] > 0 && memcmp(answer, joinpasschallenges[num], MD5_LEN) == 0)
passed = true;
// Wipe and reset the challenge so that it can't be tried against again, as a small measure against brute-force attacks.
memset(joinpasschallenges[num], 0x00, MD5_LEN);
joinpasschallengeson[num] = 0;
return passed;
}
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question)
{
size_t i;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
(*num) = M_RandomKey(NUMJOINCHALLENGES);
if (joinpasschallengeson[(*num)] == 0)
break;
}
if (joinpasschallengeson[(*num)] > 0)
{
// Ugh, all challenges are (probably) taken. Let's find the oldest one and overwrite it.
tic_t oldesttic = INT32_MAX;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
if (joinpasschallengeson[i] < oldesttic)
{
(*num) = i;
oldesttic = joinpasschallengeson[i];
}
}
}
joinpasschallengeson[(*num)] = I_GetTime();
memset(question, 0x00, MD5_LEN);
for (i = 0; i < MD5_LEN; i++)
question[i] = M_RandomByte();
// Store the answer in memory. What was the question again?
GetChallengeAnswer(question, joinpassmd5, joinpasschallenges[(*num)]);
// This ensures that num is always non-zero and will be valid when used for the answer
if ((*num) == 0)
(*num) = NUMJOINCHALLENGES;
}
// Remote Administration
static void Command_ChangeJoinPassword_f(void)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
if (client) // cannot change remotely
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("joinpassword <password>: set a password to join the server\nUse -remove to disable the password.\n"));
return;
}
if (strcmp(COM_Argv(1), "-remove") == 0)
{
joinpasswordset = false;
CONS_Printf(M_GetText("Join password removed.\n"));
}
else
{
D_SetJoinPassword(COM_Argv(1));
CONS_Printf(M_GetText("Join password set.\n"));
}
#endif
}
static void Command_MotD_f(void) static void Command_MotD_f(void)
{ {
size_t i, j; size_t i, j;

View file

@ -246,14 +246,6 @@ void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);
extern consvar_t cv_dummyjoinpassword;
extern boolean joinpasswordset;
boolean D_IsJoinPasswordOn(void);
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer);
void D_SetJoinPassword(const char *pw);
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer);
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question);
// used for the player setup menu // used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum); UINT8 CanChangeSkin(INT32 playernum);

View file

@ -508,8 +508,6 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
return false; return false;
} }
static void SOCK_FreeNodenum(INT32 numnode);
// This is a hack. For some reason, nodes aren't being freed properly. // This is a hack. For some reason, nodes aren't being freed properly.
// This goes through and cleans up what nodes were supposed to be freed. // This goes through and cleans up what nodes were supposed to be freed.
/** \warning This function causes the file downloading to stop if someone joins. /** \warning This function causes the file downloading to stop if someone joins.
@ -526,7 +524,7 @@ static void cleanupnodes(void)
// Why can't I start at zero? // Why can't I start at zero?
for (j = 1; j < MAXNETNODES; j++) for (j = 1; j < MAXNETNODES; j++)
if (!(nodeingame[j] || SV_SendingFile(j))) if (!(nodeingame[j] || SV_SendingFile(j)))
SOCK_FreeNodenum(j); // At least free this PROPERLY nodeconnected[j] = false;
} }
static SINT8 getfreenode(void) static SINT8 getfreenode(void)
@ -626,13 +624,6 @@ static boolean SOCK_Get(void)
} }
// not found // not found
if (netbuffer->packettype == PT_NOTHING)
{
DEBFILE(va("Ackret received from disconnected address:%s, ignoring...\n", SOCK_AddrToStr(&fromaddress)));
doomcom->remotenode = -1; // no packet
return true;
}
// find a free slot // find a free slot
j = getfreenode(); j = getfreenode();
if (j > 0) if (j > 0)
@ -659,11 +650,7 @@ static boolean SOCK_Get(void)
return true; return true;
} }
else else
{
DEBFILE("New node detected: No more free slots\n"); DEBFILE("New node detected: No more free slots\n");
doomcom->remotenode = -1; // no packet
return true;
}
} }
} }

View file

@ -981,10 +981,9 @@ static menuitem_t MP_MainMenu[] =
static menuitem_t MP_ServerMenu[] = static menuitem_t MP_ServerMenu[] =
{ {
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0}, {IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10},
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30},
{IT_STRING|IT_CVAR|IT_CV_PASSWORD, NULL, "Password", &cv_dummyjoinpassword, 44},
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68}, {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
@ -2426,9 +2425,6 @@ static void M_NextOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (itemOn + 1 > currentMenu->numitems - 1) if (itemOn + 1 > currentMenu->numitems - 1)
@ -2442,9 +2438,6 @@ static void M_PrevOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (!itemOn) if (!itemOn)
@ -2729,10 +2722,8 @@ boolean M_Responder(event_t *ev)
// BP: one of the more big hack i have never made // BP: one of the more big hack i have never made
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
{ {
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING || (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD) if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{ {
if (ch == KEY_TAB && (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value ^= 1;
if (shiftdown && ch >= 32 && ch <= 127) if (shiftdown && ch >= 32 && ch <= 127)
ch = shiftxform[ch]; ch = shiftxform[ch];
@ -3821,8 +3812,6 @@ static void M_DrawGenericMenu(void)
case IT_CVAR: case IT_CVAR:
{ {
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
char asterisks[MAXSTRINGLENGTH+1];
size_t sl;
switch (currentMenu->menuitems[i].status & IT_CVARTYPE) switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
{ {
case IT_CV_SLIDER: case IT_CV_SLIDER:
@ -3830,27 +3819,6 @@ static void M_DrawGenericMenu(void)
case IT_CV_NOPRINT: // color use this case IT_CV_NOPRINT: // color use this
case IT_CV_INVISSLIDER: // monitor toggles use this case IT_CV_INVISSLIDER: // monitor toggles use this
break; break;
case IT_CV_PASSWORD:
if (i == itemOn)
{
V_DrawRightAlignedThinString(x + MAXSTRINGLENGTH*8 + 10, y, V_ALLOWLOWERCASE, va(M_GetText("Tab: %s password"), cv->value ? "hide" : "show"));
}
if (!cv->value || i != itemOn)
{
sl = strlen(cv->string);
memset(asterisks, '*', sl);
memset(asterisks + sl, 0, MAXSTRINGLENGTH+1-sl);
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, asterisks);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(asterisks, 0), y + 12,
'_' | 0x80, false);
y += 16;
break;
}
/* fallthru */
case IT_CV_STRING: case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
@ -8434,6 +8402,7 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt);
// display game speed for race gametypes
if (serverlist[slindex].info.gametype == GT_RACE) if (serverlist[slindex].info.gametype == GT_RACE)
{ {
spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue; spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue;
@ -8441,9 +8410,6 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd));
} }
if (serverlist[slindex].info.kartvars & SV_PASSWORD)
V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL);
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
} }
@ -8694,11 +8660,6 @@ static void M_StartServer(INT32 choice)
// Still need to reset devmode // Still need to reset devmode
cv_debug = 0; cv_debug = 0;
if (strlen(cv_dummyjoinpassword.string) > 0)
D_SetJoinPassword(cv_dummyjoinpassword.string);
else
joinpasswordset = false;
if (demo.playback) if (demo.playback)
G_StopDemo(); G_StopDemo();
if (metalrecording) if (metalrecording)

View file

@ -113,7 +113,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_CV_NOPRINT 1536 #define IT_CV_NOPRINT 1536
#define IT_CV_NOMOD 2048 #define IT_CV_NOMOD 2048
#define IT_CV_INVISSLIDER 2560 #define IT_CV_INVISSLIDER 2560
#define IT_CV_PASSWORD 3072
//call/submenu specific //call/submenu specific
// There used to be a lot more here but ... // There used to be a lot more here but ...