mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +00:00
Merge remote-tracking branch 'remotes/james/awful-mix-fucked' into awful-mix
This commit is contained in:
commit
af0a93ea53
11 changed files with 115 additions and 649 deletions
|
@ -1304,8 +1304,7 @@ found:
|
|||
|
||||
var->string = var->zstring = Z_StrDup(valstr);
|
||||
|
||||
if (var->flags & CV_PASSWORD); // Don't change value for password field
|
||||
else if (override)
|
||||
if (override)
|
||||
var->value = overrideval;
|
||||
else if (var->flags & CV_FLOAT)
|
||||
{
|
||||
|
|
|
@ -98,8 +98,7 @@ typedef enum
|
|||
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
|
||||
// used on menus
|
||||
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
|
||||
CV_PASSWORD = 4096 // Password field
|
||||
CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on.
|
||||
} cvflags_t;
|
||||
|
||||
typedef struct CV_PossibleValue_s
|
||||
|
|
426
src/d_clisrv.c
426
src/d_clisrv.c
|
@ -23,7 +23,6 @@
|
|||
#include "d_net.h"
|
||||
#include "d_netfil.h" // fileneedednum
|
||||
#include "d_main.h"
|
||||
#include "d_event.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.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)
|
||||
{
|
||||
INT32 i = rsp->playernum, j;
|
||||
//mobj_t *savedmo = players[i].mo;
|
||||
mobj_t *savedmo = players[i].mo;
|
||||
|
||||
// Do not send anything visual related.
|
||||
// Only send data that we need to know for physics.
|
||||
|
@ -768,17 +767,11 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
return;
|
||||
|
||||
//...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.
|
||||
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;
|
||||
}
|
||||
|
||||
//server thinks player has a body.
|
||||
//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;
|
||||
}
|
||||
|
||||
resynch_inprogress[node] = false; // Let's see if there's REALLY anyone left to sync.....
|
||||
netbuffer->packettype = PT_RESYNCHING;
|
||||
for (i = 0, j = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
|
@ -1039,24 +1031,10 @@ static void SV_SendResynch(INT32 node)
|
|||
if (!(resynch_status[node] & 1<<i))
|
||||
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
|
||||
if (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;
|
||||
}
|
||||
|
||||
|
@ -1070,15 +1048,6 @@ static void SV_SendResynch(INT32 node)
|
|||
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)
|
||||
{
|
||||
XBOXSTATIC UINT8 buf[2];
|
||||
|
@ -1133,32 +1102,22 @@ typedef enum
|
|||
CL_CONNECTED,
|
||||
CL_ABORTED,
|
||||
CL_ASKFULLFILELIST,
|
||||
CL_ASKDOWNLOADFILES,
|
||||
CL_WAITDOWNLOADFILESRESPONSE,
|
||||
#ifdef HAVE_CURL
|
||||
CL_PREPAREHTTPFILES,
|
||||
CL_DOWNLOADHTTPFILES,
|
||||
#endif
|
||||
CL_CHALLENGE
|
||||
} cl_mode_t;
|
||||
|
||||
static void GetPackets(void);
|
||||
|
||||
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
|
||||
char http_source[MAX_MIRROR_LENGTH];
|
||||
#endif
|
||||
|
||||
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
|
||||
|
||||
// Player name send/load
|
||||
|
||||
static void CV_SavePlayerNames(UINT8 **p)
|
||||
|
@ -1194,7 +1153,6 @@ static void CV_LoadPlayerNames(UINT8 **p)
|
|||
}
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
static UINT32 SL_SearchServer(INT32 node);
|
||||
|
||||
//
|
||||
// CL_DrawConnectionStatus
|
||||
|
@ -1223,42 +1181,11 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
// 15 pal entries total.
|
||||
const char *cltext;
|
||||
|
||||
if (cl_mode != CL_CHALLENGE)
|
||||
for (i = 0; i < 16; ++i)
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
|
||||
for (i = 0; i < 16; ++i)
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
|
||||
|
||||
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
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
if (lastfilenum != -1)
|
||||
|
@ -1281,12 +1208,11 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
case CL_WAITJOINRESPONSE:
|
||||
cltext = M_GetText("Requesting to join...");
|
||||
break;
|
||||
case CL_ASKDOWNLOADFILES:
|
||||
case CL_WAITDOWNLOADFILESRESPONSE:
|
||||
#ifdef HAVE_CURL
|
||||
case CL_PREPAREHTTPFILES:
|
||||
#endif
|
||||
cltext = M_GetText("Waiting to download files...");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cltext = M_GetText("Connecting to server...");
|
||||
break;
|
||||
|
@ -1376,9 +1302,6 @@ static boolean CL_SendJoin(void)
|
|||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
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));
|
||||
}
|
||||
|
@ -1410,10 +1333,10 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
|
||||
netbuffer->u.serverinfo.kartvars = (UINT8) (
|
||||
(cv_kartspeed.value & SV_SPEEDMASK) |
|
||||
(dedicated ? SV_DEDICATED : 0) |
|
||||
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
|
||||
(dedicated ? SV_DEDICATED : 0)
|
||||
);
|
||||
|
||||
|
||||
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
|
@ -1479,18 +1402,15 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
if (! D_IsJoinPasswordOn())
|
||||
{
|
||||
mirror_length = strlen(httpurl);
|
||||
if (mirror_length > MAX_MIRROR_LENGTH)
|
||||
mirror_length = MAX_MIRROR_LENGTH;
|
||||
mirror_length = strlen(httpurl);
|
||||
if (mirror_length > MAX_MIRROR_LENGTH)
|
||||
mirror_length = MAX_MIRROR_LENGTH;
|
||||
|
||||
if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0)
|
||||
// If there's an encoding error, send nothing, we accept that the above may be truncated
|
||||
strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length);
|
||||
if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0)
|
||||
// If there's an encoding error, send nothing, we accept that the above may be truncated
|
||||
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
|
||||
|
||||
p = PutFileNeeded(0);
|
||||
|
@ -2015,7 +1935,39 @@ static boolean CL_FinishedFileList(void)
|
|||
else if (i == 1)
|
||||
cl_mode = CL_ASKJOIN;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2062,6 +2014,16 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
|||
|
||||
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);
|
||||
if (serverlist[i].info.kartvars & SV_LOTSOFADDONS)
|
||||
{
|
||||
|
@ -2140,6 +2102,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
|
||||
#ifdef HAVE_CURL
|
||||
case CL_PREPAREHTTPFILES:
|
||||
if (http_source[0])
|
||||
{
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
||||
|
@ -2169,8 +2132,11 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
if (curl_failedwebdownload && !curl_transfers)
|
||||
{
|
||||
CONS_Printf("One or more files failed to download, falling back to internal downloader\n");
|
||||
cl_mode = CL_ASKDOWNLOADFILES;
|
||||
break;
|
||||
if (CL_SendRequestFile())
|
||||
{
|
||||
cl_mode = CL_DOWNLOADFILES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!curl_transfers)
|
||||
|
@ -2194,7 +2160,6 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
/* FALLTHRU */
|
||||
|
||||
case CL_ASKJOIN:
|
||||
cl_needsdownload = false;
|
||||
CL_LoadServerFiles();
|
||||
#ifdef JOININGAME
|
||||
// prepare structures to save the file
|
||||
|
@ -2203,23 +2168,9 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
CL_PrepareDownloadSaveGame(tmpsave);
|
||||
#endif
|
||||
if (CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
cl_mode = CL_WAITJOINRESPONSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CL_ASKDOWNLOADFILES:
|
||||
cl_needsdownload = true;
|
||||
|
||||
if (CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
cl_mode = CL_WAITDOWNLOADFILESRESPONSE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#ifdef JOININGAME
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
case CL_CHALLENGE:
|
||||
(*asksent) = I_GetTime() - NEWTICRATE; // Send password immediately upon entering
|
||||
break;
|
||||
|
||||
case CL_WAITJOINRESPONSE:
|
||||
case CL_WAITDOWNLOADFILESRESPONSE:
|
||||
if (*asksent + NEWTICRATE < I_GetTime() && CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CL_CONNECTED:
|
||||
default:
|
||||
break;
|
||||
|
@ -2263,15 +2202,21 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
// Call it only once by tic
|
||||
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
|
||||
//if (key == 's' && server)
|
||||
// doomcom->numnodes = (INT16)pnumnodes;
|
||||
//SV_FileSendTicker();
|
||||
INT32 key;
|
||||
|
||||
I_OsPolling();
|
||||
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();
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
|
@ -2295,73 +2240,6 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
|
|||
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
|
||||
*
|
||||
* \param viams ???
|
||||
|
@ -2382,7 +2260,6 @@ static void CL_ConnectToServer(boolean viams)
|
|||
#endif
|
||||
|
||||
cl_mode = CL_SEARCHING;
|
||||
cl_challengenum = 0;
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
lastfilenum = -1;
|
||||
|
@ -2407,8 +2284,6 @@ static void CL_ConnectToServer(boolean viams)
|
|||
if (gamestate == GS_VOTING)
|
||||
Y_EndVote();
|
||||
|
||||
resynch_local_inprogress = false; // Just in case this was never cleared...
|
||||
|
||||
DEBFILE(va("waiting %d nodes\n", doomcom->numnodes));
|
||||
G_SetGamestate(GS_WAITINGPLAYERS);
|
||||
wipegamestate = GS_WAITINGPLAYERS;
|
||||
|
@ -2439,8 +2314,6 @@ static void CL_ConnectToServer(boolean viams)
|
|||
SL_ClearServerList(servernode);
|
||||
#endif
|
||||
|
||||
cl_challengeattempted = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// If the connection was aborted for some reason, leave
|
||||
|
@ -3386,9 +3259,6 @@ void D_ClientServerInit(void)
|
|||
gametic = 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
|
||||
SV_StopServer();
|
||||
SV_ResetServer();
|
||||
|
@ -3512,7 +3382,6 @@ void D_QuitNetGame(void)
|
|||
HSendPacket(servernode, true, 0, 0);
|
||||
}
|
||||
|
||||
resynch_local_inprogress = false; // No more resyncing!
|
||||
D_CloseConnection();
|
||||
ClearAdminPlayers();
|
||||
|
||||
|
@ -3871,35 +3740,6 @@ static void HandleConnect(SINT8 node)
|
|||
boolean newnode = false;
|
||||
#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
|
||||
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
|
||||
if (!nodeingame[node])
|
||||
|
@ -4099,52 +3939,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
Net_CloseConnection(node);
|
||||
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
|
||||
if (server && serverrunning)
|
||||
{ // But wait I thought I'm the server?
|
||||
|
@ -4173,63 +3967,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
}
|
||||
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
|
||||
{
|
||||
INT32 j;
|
||||
|
@ -4245,9 +3982,6 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||
break;
|
||||
|
||||
if (cl_challengeattempted == 1) // Successful password noise.
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
|
||||
if (client)
|
||||
{
|
||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
#ifndef __D_CLISRV__
|
||||
#define __D_CLISRV__
|
||||
|
||||
#include "d_event.h"
|
||||
#include "d_ticcmd.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
The 'packet version' is used to distinguish packet formats.
|
||||
This version is independent of VERSION and SUBVERSION. Different
|
||||
|
@ -86,9 +83,6 @@ typedef enum
|
|||
PT_CLIENT4MIS,
|
||||
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
|
||||
// allows HSendPacket(*, true, *, *) to return false.
|
||||
// In addition, this packet can't occupy all the available slots.
|
||||
|
@ -361,22 +355,13 @@ typedef struct
|
|||
char application[MAXAPPLICATION];
|
||||
UINT8 version; // Different versions don't work
|
||||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers;
|
||||
UINT8 needsdownload;
|
||||
UINT8 challengenum; // Non-zero if trying to join with a password attempt
|
||||
UINT8 challengeanswer[MD5_LEN]; // Join challenge
|
||||
UINT8 localplayers; // number of splitscreen players
|
||||
UINT8 mode;
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 challengenum; // Number to send back in join attempt
|
||||
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 SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||
#define SV_DEDICATED 0x40 // server is dedicated
|
||||
#define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
|
@ -462,11 +447,6 @@ typedef struct
|
|||
UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||
} ATTRPACK filesneededconfig_pak;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char http_source[MAX_MIRROR_LENGTH];/* first byte 0? no die! */
|
||||
} ATTRPACK fileconfig;
|
||||
|
||||
//
|
||||
// Network packet data
|
||||
//
|
||||
|
@ -492,7 +472,6 @@ typedef struct
|
|||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
||||
filetx_pak filetxpak; // 139 bytes
|
||||
clientconfig_pak clientcfg; // 153 bytes
|
||||
joinchallenge_pak joinchallenge; // 17 bytes
|
||||
serverinfo_pak serverinfo; // 1024 bytes
|
||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||
askinfo_pak askinfo; // 61 bytes
|
||||
|
@ -501,7 +480,6 @@ typedef struct
|
|||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
||||
fileconfig filecfg;
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
@ -599,7 +577,6 @@ void CL_Reset(void);
|
|||
void CL_ClearPlayer(INT32 playernum);
|
||||
void CL_RemovePlayer(INT32 playernum, INT32 reason);
|
||||
void CL_UpdateServerList(boolean internetsearch, INT32 room);
|
||||
boolean CL_Responder(event_t *ev);
|
||||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
|
|
|
@ -231,9 +231,6 @@ void D_ProcessEvents(void)
|
|||
if (M_ScreenshotResponder(ev))
|
||||
continue; // ate the event
|
||||
|
||||
if (CL_Responder(ev))
|
||||
continue;
|
||||
|
||||
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
|
||||
{
|
||||
if (cht_Responder(ev))
|
||||
|
|
95
src/d_net.c
95
src/d_net.c
|
@ -339,7 +339,6 @@ static boolean Processackpak(void)
|
|||
{
|
||||
UINT8 ack = netbuffer->ack;
|
||||
getackpacket++;
|
||||
|
||||
if (cmpack(ack, node->firstacktosend) <= 0)
|
||||
{
|
||||
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,
|
||||
// Then search for a "hole" in the queue
|
||||
UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1);
|
||||
|
||||
if (!nextfirstack)
|
||||
nextfirstack = 1;
|
||||
|
||||
|
@ -781,8 +779,6 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
{
|
||||
"NOTHING",
|
||||
"SERVERCFG",
|
||||
|
||||
|
||||
"CLIENTCMD",
|
||||
"CLIENTMIS",
|
||||
"CLIENT2CMD",
|
||||
|
@ -803,33 +799,20 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"RESYNCHEND",
|
||||
"RESYNCHGET",
|
||||
|
||||
|
||||
|
||||
|
||||
"CLIENT3CMD",
|
||||
"CLIENT3MIS",
|
||||
"CLIENT4CMD",
|
||||
"CLIENT4MIS",
|
||||
"BASICKEEPALIVE",
|
||||
|
||||
"JOINCHALLENGE",
|
||||
"DOWNLOADFILESOKAY",
|
||||
|
||||
"FILEFRAGMENT",
|
||||
|
||||
"TEXTCMD",
|
||||
"TEXTCMD2",
|
||||
"TEXTCMD3",
|
||||
"TEXTCMD4",
|
||||
|
||||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
"RESYNCHING",
|
||||
|
||||
|
||||
"TELLFILESNEEDED",
|
||||
"MOREFILESNEEDED",
|
||||
|
||||
"PING"
|
||||
};
|
||||
|
||||
|
@ -847,7 +830,7 @@ static void DebugPrintpacket(const char *header)
|
|||
break;
|
||||
case PT_CLIENTJOIN:
|
||||
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
|
||||
netbuffer->u.clientcfg.needsdownload);
|
||||
netbuffer->u.clientcfg.mode);
|
||||
break;
|
||||
case PT_SERVERTICS:
|
||||
{
|
||||
|
@ -1084,10 +1067,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
|||
netbuffer->checksum = NetbufferChecksum();
|
||||
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
|
||||
// Simulate internet :)
|
||||
//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 nodejustjoined;
|
||||
//boolean nodejustjoined;
|
||||
|
||||
// Get a packet from self
|
||||
if (rebound_tail != rebound_head)
|
||||
|
@ -1151,56 +1130,11 @@ boolean HGetPacket(void)
|
|||
|
||||
while(true)
|
||||
{
|
||||
nodejustjoined = I_NetGet();
|
||||
//I_NetGet();
|
||||
//nodejustjoined = I_NetGet();
|
||||
I_NetGet();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
|
||||
getbytes += packetheaderlength + doomcom->datalength; // For stat
|
||||
|
||||
|
@ -1215,8 +1149,8 @@ boolean HGetPacket(void)
|
|||
if (netbuffer->checksum != NetbufferChecksum())
|
||||
{
|
||||
DEBFILE("Bad packet checksum\n");
|
||||
Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
|
||||
//Net_CloseConnection(doomcom->remotenode);
|
||||
//Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode);
|
||||
Net_CloseConnection(doomcom->remotenode);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1225,6 +1159,21 @@ boolean HGetPacket(void)
|
|||
DebugPrintpacket("GET");
|
||||
#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
|
||||
if (!Processackpak())
|
||||
continue; // discarded (duplicated)
|
||||
|
|
128
src/d_netcmd.c
128
src/d_netcmd.c
|
@ -172,7 +172,6 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
|
|||
static void Got_Removal(UINT8 **cp, INT32 playernum);
|
||||
static void Command_Verify_f(void);
|
||||
static void Command_RemoveAdmin_f(void);
|
||||
static void Command_ChangeJoinPassword_f(void);
|
||||
static void Command_MotD_f(void);
|
||||
static void Got_MotD_f(UINT8 **cp, INT32 playernum);
|
||||
|
||||
|
@ -554,8 +553,6 @@ void D_RegisterServerCommands(void)
|
|||
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
|
||||
|
||||
// Remote Administration
|
||||
CV_RegisterVar(&cv_dummyjoinpassword);
|
||||
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
|
||||
COM_AddCommand("password", Command_Changepassword_f);
|
||||
RegisterNetXCmd(XD_LOGIN, Got_Login);
|
||||
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"));
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
size_t i, j;
|
||||
|
|
|
@ -246,14 +246,6 @@ void RemoveAdminPlayer(INT32 playernum);
|
|||
void ItemFinder_OnChange(void);
|
||||
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
|
||||
UINT8 CanChangeSkin(INT32 playernum);
|
||||
|
||||
|
|
15
src/i_tcp.c
15
src/i_tcp.c
|
@ -508,8 +508,6 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void SOCK_FreeNodenum(INT32 numnode);
|
||||
|
||||
// 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.
|
||||
/** \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?
|
||||
for (j = 1; j < MAXNETNODES; j++)
|
||||
if (!(nodeingame[j] || SV_SendingFile(j)))
|
||||
SOCK_FreeNodenum(j); // At least free this PROPERLY
|
||||
nodeconnected[j] = false;
|
||||
}
|
||||
|
||||
static SINT8 getfreenode(void)
|
||||
|
@ -626,13 +624,6 @@ static boolean SOCK_Get(void)
|
|||
}
|
||||
// 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
|
||||
j = getfreenode();
|
||||
if (j > 0)
|
||||
|
@ -659,11 +650,7 @@ static boolean SOCK_Get(void)
|
|||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBFILE("New node detected: No more free slots\n");
|
||||
doomcom->remotenode = -1; // no packet
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
49
src/m_menu.c
49
src/m_menu.c
|
@ -981,10 +981,9 @@ static menuitem_t MP_MainMenu[] =
|
|||
|
||||
static menuitem_t MP_ServerMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0},
|
||||
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10},
|
||||
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20},
|
||||
{IT_STRING|IT_CVAR|IT_CV_PASSWORD, NULL, "Password", &cv_dummyjoinpassword, 44},
|
||||
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10},
|
||||
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20},
|
||||
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
|
||||
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
|
||||
|
@ -2426,9 +2425,6 @@ static void M_NextOpt(void)
|
|||
{
|
||||
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
|
||||
{
|
||||
if (itemOn + 1 > currentMenu->numitems - 1)
|
||||
|
@ -2442,9 +2438,6 @@ static void M_PrevOpt(void)
|
|||
{
|
||||
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
|
||||
{
|
||||
if (!itemOn)
|
||||
|
@ -2729,10 +2722,8 @@ boolean M_Responder(event_t *ev)
|
|||
// BP: one of the more big hack i have never made
|
||||
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)
|
||||
ch = shiftxform[ch];
|
||||
|
@ -3821,8 +3812,6 @@ static void M_DrawGenericMenu(void)
|
|||
case IT_CVAR:
|
||||
{
|
||||
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
|
||||
char asterisks[MAXSTRINGLENGTH+1];
|
||||
size_t sl;
|
||||
switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
|
||||
{
|
||||
case IT_CV_SLIDER:
|
||||
|
@ -3830,27 +3819,6 @@ static void M_DrawGenericMenu(void)
|
|||
case IT_CV_NOPRINT: // color use this
|
||||
case IT_CV_INVISSLIDER: // monitor toggles use this
|
||||
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:
|
||||
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
|
||||
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);
|
||||
|
||||
// display game speed for race gametypes
|
||||
if (serverlist[slindex].info.gametype == GT_RACE)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -8694,11 +8660,6 @@ static void M_StartServer(INT32 choice)
|
|||
// Still need to reset devmode
|
||||
cv_debug = 0;
|
||||
|
||||
if (strlen(cv_dummyjoinpassword.string) > 0)
|
||||
D_SetJoinPassword(cv_dummyjoinpassword.string);
|
||||
else
|
||||
joinpasswordset = false;
|
||||
|
||||
if (demo.playback)
|
||||
G_StopDemo();
|
||||
if (metalrecording)
|
||||
|
|
|
@ -113,7 +113,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
|||
#define IT_CV_NOPRINT 1536
|
||||
#define IT_CV_NOMOD 2048
|
||||
#define IT_CV_INVISSLIDER 2560
|
||||
#define IT_CV_PASSWORD 3072
|
||||
|
||||
//call/submenu specific
|
||||
// There used to be a lot more here but ...
|
||||
|
|
Loading…
Reference in a new issue