tweaked download rules to match mvdsv, by adding an allow_download_other cvar.
added log_enable_rcon (and enabled it by default), for feature parity with mvdsv. invalid requests, valid requests, and redirected prints are all logged. tweaked server-side download code to not bug out with downloads larger than 2gb. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4697 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
1908310788
commit
b1e3060648
12 changed files with 163 additions and 77 deletions
|
@ -26,6 +26,7 @@ cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536");
|
|||
cvar_t dpcompat_set = SCVAR("dpcompat_set", "0");
|
||||
int Cmd_ExecLevel;
|
||||
qboolean cmd_didwait;
|
||||
qboolean cmd_blockwait;
|
||||
|
||||
void Cmd_ForwardToServer (void);
|
||||
|
||||
|
@ -161,6 +162,9 @@ bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"
|
|||
*/
|
||||
void Cmd_Wait_f (void)
|
||||
{
|
||||
if (cmd_blockwait)
|
||||
return;
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
if (cmd_didwait && sv.state)
|
||||
Con_DPrintf("waits without server frames\n");
|
||||
|
|
|
@ -55,6 +55,7 @@ void Cbuf_Execute (void);
|
|||
// Normally called once per frame, but may be explicitly invoked.
|
||||
// Do not call inside a command function!
|
||||
|
||||
extern qboolean cmd_blockwait;
|
||||
void Cbuf_ExecuteLevel(int level);
|
||||
//executes only a single cbuf level. can be used to restrict cbuf execution to some 'safe' set of commands, so there are no surprise 'map' commands.
|
||||
//will not magically make all commands safe to exec, but will prevent user commands slipping in too.
|
||||
|
|
|
@ -570,6 +570,7 @@ void PO_Close(struct po_s *po);
|
|||
typedef enum {
|
||||
LOG_CONSOLE,
|
||||
LOG_PLAYER,
|
||||
LOG_RCON,
|
||||
LOG_TYPES
|
||||
} logtype_t;
|
||||
void Log_Dir_Callback (struct cvar_s *var, char *oldvalue);
|
||||
|
|
|
@ -1051,7 +1051,7 @@ qboolean FS_GetPackageDownloadable(const char *package)
|
|||
|
||||
for (search = com_searchpaths ; search ; search = search->next)
|
||||
{
|
||||
if (!strcmp(package, search->purepath))
|
||||
if (!Q_strcasecmp(package, search->purepath))
|
||||
return !(search->flags & SPF_COPYPROTECTED);
|
||||
}
|
||||
return false;
|
||||
|
@ -3944,6 +3944,10 @@ void FS_ChangeGame_f(void)
|
|||
int i;
|
||||
char *arg = Cmd_Argv(1);
|
||||
|
||||
//don't execute this if we're executing rcon commands, as this can change game directories.
|
||||
if (cmd_blockwait)
|
||||
return;
|
||||
|
||||
if (!*arg)
|
||||
{
|
||||
Con_Printf("Valid games are:\n");
|
||||
|
|
|
@ -5691,6 +5691,10 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
if (0)
|
||||
{ //treat *ALL* tests against the actual geometry instead of using any brushes.
|
||||
//also ignores the bsp etc. not fast. testing only.
|
||||
|
||||
trace_ispoint = trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0
|
||||
&& trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0;
|
||||
|
||||
for (i = 0; i < mod->numsurfaces; i++)
|
||||
{
|
||||
CM_ClipBoxToMesh(trace_mins, trace_maxs, trace_start, trace_end, &trace_trace, mod->surfaces[i].mesh);
|
||||
|
@ -5699,6 +5703,9 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
|||
else
|
||||
if (0)
|
||||
{
|
||||
trace_ispoint = trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0
|
||||
&& trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0;
|
||||
|
||||
for (i = 0; i < mod->numleafs; i++)
|
||||
CM_TraceToLeaf(&mod->leafs[i]);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,12 @@ void Log_Name_Callback (struct cvar_s *var, char *oldvalue);
|
|||
// cvars
|
||||
#define CONLOGGROUP "Console logging"
|
||||
cvar_t log_enable[LOG_TYPES] = { CVARF("log_enable", "0", CVAR_NOTFROMSERVER),
|
||||
CVARF("log_enable_players", "0", CVAR_NOTFROMSERVER)};
|
||||
CVARF("log_enable_players", "0", CVAR_NOTFROMSERVER),
|
||||
CVARF("log_enable_rcon", "1", CVAR_NOTFROMSERVER)
|
||||
};
|
||||
cvar_t log_name[LOG_TYPES] = { CVARFC("log_name", "", CVAR_NOTFROMSERVER, Log_Name_Callback),
|
||||
CVARFC("log_name_players", "", CVAR_NOTFROMSERVER, Log_Name_Callback)};
|
||||
CVARFC("log_name_players", "", CVAR_NOTFROMSERVER, Log_Name_Callback),
|
||||
CVARFC("log_name_rcon", "", CVAR_NOTFROMSERVER, Log_Name_Callback)};
|
||||
cvar_t log_dir = CVARFC("log_dir", "", CVAR_NOTFROMSERVER, Log_Dir_Callback);
|
||||
cvar_t log_readable = CVARFD("log_readable", "7", CVAR_NOTFROMSERVER, "Bitfield describing what to convert/strip. If 0, exact byte representation will be used.\n&1: Dequakify text.\n&2: Strip special markup.\n&4: Strip ansi control codes.");
|
||||
cvar_t log_developer = CVARF("log_developer", "0", CVAR_NOTFROMSERVER);
|
||||
|
@ -88,6 +91,9 @@ void Log_String (logtype_t lognum, char *s)
|
|||
case LOG_PLAYER:
|
||||
f = "players";
|
||||
break;
|
||||
case LOG_RCON:
|
||||
f = "rcon";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
#define FTE_WORDSIZE 64
|
||||
#define quintptr_t unsigned qintptr_t
|
||||
#elif defined(_WIN32)
|
||||
typedef __int32 qintptr_t; //add __w64 if you need msvc to shut up about unsafe type conversions
|
||||
typedef unsigned __int32 quintptr_t;
|
||||
#ifndef _MSC_VER
|
||||
#define __w64
|
||||
#endif
|
||||
typedef __int32 __w64 qintptr_t; //add __w64 if you need msvc to shut up about unsafe type conversions
|
||||
typedef unsigned __int32 __w64 quintptr_t;
|
||||
// #define qintptr_t __int32
|
||||
// #define quintptr_t unsigned qintptr_t
|
||||
#define FTE_WORDSIZE 32
|
||||
|
|
|
@ -8837,6 +8837,14 @@
|
|||
<File
|
||||
RelativePath="..\client\in_generic.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
|
@ -11183,6 +11191,14 @@
|
|||
<File
|
||||
RelativePath="..\client\pr_clcmd.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
|
@ -16807,6 +16823,7 @@
|
|||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -21320,7 +21337,6 @@
|
|||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
|
|
@ -457,11 +457,11 @@ typedef struct client_s
|
|||
|
||||
char downloadfn[MAX_QPATH];
|
||||
vfsfile_t *download; // file being downloaded
|
||||
unsigned int downloadsize; // total bytes
|
||||
unsigned int downloadcount; // bytes sent
|
||||
qofs_t downloadsize; // total bytes
|
||||
qofs_t downloadcount; // bytes sent
|
||||
|
||||
int downloadacked; //DP-specific
|
||||
int downloadstarted; //DP-specific
|
||||
qofs_t downloadacked; //DP-specific
|
||||
qofs_t downloadstarted; //DP-specific
|
||||
|
||||
int spec_track; // entnum of player tracking
|
||||
|
||||
|
@ -1161,7 +1161,7 @@ void SVM_Think(int port);
|
|||
//
|
||||
// svonly.c
|
||||
//
|
||||
typedef enum {RD_NONE, RD_CLIENT, RD_PACKET, RD_OBLIVION, RD_MASTER} redirect_t; //oblivion is provided so people can read the output before the buffer is wiped.
|
||||
typedef enum {RD_NONE, RD_CLIENT, RD_PACKET, RD_PACKET_LOG, RD_OBLIVION, RD_MASTER} redirect_t; //oblivion is provided so people can read the output before the buffer is wiped.
|
||||
void SV_BeginRedirect (redirect_t rd, int lang);
|
||||
void SV_EndRedirect (void);
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If
|
|||
cvar_t allow_download_wads = CVAR("allow_download_wads", "1");
|
||||
cvar_t allow_download_configs = CVAR("allow_download_configs", "0");
|
||||
cvar_t allow_download_copyrighted = CVAR("allow_download_copyrighted", "0");
|
||||
cvar_t allow_download_other = CVAR("allow_download_other", "0");
|
||||
|
||||
cvar_t sv_serverip = CVARD("sv_serverip", "", "Set this cvar to the server's public ip address if the server is behind a firewall and cannot detect its own public address. Providing a port is required if the firewall/nat remaps it, but is otherwise optional.");
|
||||
cvar_t sv_public = CVAR("sv_public", "0");
|
||||
|
@ -3697,6 +3698,7 @@ void SVC_RemoteCommand (void)
|
|||
|
||||
if (!Rcon_Validate ())
|
||||
{
|
||||
/*
|
||||
#ifdef SVRANKING
|
||||
if (cmd_allowaccess.value) //try and find a username, match the numeric password
|
||||
{
|
||||
|
@ -3727,7 +3729,7 @@ void SVC_RemoteCommand (void)
|
|||
Con_TPrintf ("Rcon from %s:\n%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4);
|
||||
|
||||
SV_BeginRedirect (RD_PACKET, svs.language);
|
||||
SV_BeginRedirect (RD_PACKET_LOG, svs.language);
|
||||
|
||||
remaining[0] = 0;
|
||||
|
||||
|
@ -3753,22 +3755,32 @@ void SVC_RemoteCommand (void)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
Con_TPrintf ("Bad rcon from %s:\n%s\n"
|
||||
Log_String(LOG_RCON, va("Bad rcon from %s:\t%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4));
|
||||
|
||||
Con_TPrintf ("Bad rcon from %s:\t%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4);
|
||||
|
||||
SV_BeginRedirect (RD_PACKET, svs.language);
|
||||
|
||||
Con_TPrintf ("Bad rcon_password.\n");
|
||||
|
||||
Con_TPrintf ("Bad rcon_password. Passwords might be logged. Be careful.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//make sure stuff is flushed
|
||||
cmd_blockwait = true;
|
||||
Cbuf_ExecuteLevel(rcon_level.ival);
|
||||
cmd_blockwait = false;
|
||||
|
||||
Con_TPrintf ("Rcon from %s:\n%s\n"
|
||||
Log_String(LOG_RCON, va("\n\nRcon from %s:\t%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4));
|
||||
|
||||
Con_TPrintf ("Rcon from %s:\t%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4);
|
||||
|
||||
SV_BeginRedirect (RD_PACKET, svs.language);
|
||||
SV_BeginRedirect (RD_PACKET_LOG, svs.language);
|
||||
|
||||
remaining[0] = 0;
|
||||
|
||||
|
@ -3778,16 +3790,19 @@ void SVC_RemoteCommand (void)
|
|||
{
|
||||
Con_TPrintf("Rcon was too long\n");
|
||||
SV_EndRedirect ();
|
||||
Con_TPrintf ("Rcon from %s:\n%s\n"
|
||||
Con_TPrintf ("Rcon from %s:\t%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), "Was too long - possible buffer overflow attempt");
|
||||
return;
|
||||
}
|
||||
strcat (remaining, Cmd_Argv(i) );
|
||||
strcat (remaining, " ");
|
||||
Q_strncatz(remaining, Cmd_Argv(i), sizeof(remaining));
|
||||
Q_strncatz(remaining, " ", sizeof(remaining));
|
||||
}
|
||||
|
||||
Cmd_ExecuteString (remaining, rcon_level.ival);
|
||||
|
||||
//make sure the wait command can't be used to fuck up our logs.
|
||||
cmd_blockwait = true;
|
||||
Cbuf_AddText(remaining, rcon_level.ival);
|
||||
Cbuf_ExecuteLevel(rcon_level.ival);
|
||||
cmd_blockwait = false;
|
||||
}
|
||||
|
||||
SV_EndRedirect ();
|
||||
|
@ -5278,6 +5293,7 @@ void SV_InitLocal (void)
|
|||
Cvar_Register (&allow_download_wads, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_root, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_copyrighted, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_other, cvargroup_serverpermissions);
|
||||
Cvar_Register (&secure, cvargroup_serverpermissions);
|
||||
|
||||
Cvar_Register (&sv_highchars, cvargroup_servercontrol);
|
||||
|
|
|
@ -62,8 +62,12 @@ void SV_FlushRedirect (void)
|
|||
|
||||
Log_String(LOG_CONSOLE, va("{\n%s}\n", outputbuf));
|
||||
|
||||
if (sv_redirected == RD_PACKET)
|
||||
if (sv_redirected == RD_PACKET || sv_redirected == RD_PACKET_LOG)
|
||||
{
|
||||
//log it to the rcon log if its not just a status response
|
||||
if (sv_redirected == RD_PACKET_LOG)
|
||||
Log_String(LOG_RCON, outputbuf);
|
||||
|
||||
send[0] = 0xff;
|
||||
send[1] = 0xff;
|
||||
send[2] = 0xff;
|
||||
|
|
|
@ -2007,7 +2007,7 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
|
|||
}
|
||||
}
|
||||
|
||||
void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
||||
static void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum, int chunks)
|
||||
{
|
||||
#define CHUNKSIZE 1024
|
||||
char buffer[CHUNKSIZE];
|
||||
|
@ -2015,16 +2015,20 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
|||
sizebuf_t *msg, msg_oob;
|
||||
int i;
|
||||
int error = false;
|
||||
//can't support this yet. at least forcing to 1 avoids too bad infinite loops. this can be a nasty dos attack on a server. if (chunks < 1)
|
||||
chunks = 1;
|
||||
|
||||
msg = &host_client->datagram;
|
||||
|
||||
if (chunknum*CHUNKSIZE > host_client->downloadsize)
|
||||
if (chunknum == -1)
|
||||
error = 2; //silent, don't report it
|
||||
else if (chunknum*CHUNKSIZE > host_client->downloadsize)
|
||||
{
|
||||
SV_ClientTPrintf (host_client, PRINT_HIGH, "Warning: Invalid file chunk requested %u to %u of %u.\n", chunknum*CHUNKSIZE, (chunknum+1)*CHUNKSIZE, host_client->downloadsize);
|
||||
error = 2;
|
||||
}
|
||||
|
||||
if (!error && VFS_SEEK (host_client->download, chunknum*CHUNKSIZE) == false)
|
||||
if (!error && VFS_SEEK (host_client->download, (qofs_t)chunknum*CHUNKSIZE) == false)
|
||||
error = true;
|
||||
else
|
||||
{
|
||||
|
@ -2032,58 +2036,63 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
|||
host_client->downloadcount = chunknum*CHUNKSIZE;
|
||||
}
|
||||
|
||||
if ((host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) || (host_client->datagram.cursize + CHUNKSIZE+5 > 1400))
|
||||
|
||||
while (!error && chunks > 0)
|
||||
{
|
||||
//would overflow the packet, or result in (ethernet) fragmentation and high packet loss.
|
||||
msg = &msg_oob;
|
||||
if ((host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) || (host_client->datagram.cursize + CHUNKSIZE+5 > 1400))
|
||||
{
|
||||
//would overflow the packet, or result in (ethernet) fragmentation and high packet loss.
|
||||
msg = &msg_oob;
|
||||
|
||||
if (!ezfilenum)
|
||||
return;
|
||||
if (!ezfilenum) //can't oob it
|
||||
return;
|
||||
|
||||
if (host_client->waschoked)
|
||||
return; //don't let chunked downloads flood out the standard packets.
|
||||
if (host_client->waschoked)
|
||||
return; //don't let chunked downloads flood out the standard packets.
|
||||
|
||||
if (!Netchan_CanPacket(&host_client->netchan, SV_RateForClient(host_client)))
|
||||
return;
|
||||
}
|
||||
if (!Netchan_CanPacket(&host_client->netchan, SV_RateForClient(host_client)))
|
||||
return;
|
||||
}
|
||||
|
||||
if (error)
|
||||
i = 0;
|
||||
else
|
||||
i = VFS_READ (host_client->download, buffer, CHUNKSIZE);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
if (msg == &msg_oob)
|
||||
if (i > 0)
|
||||
{
|
||||
msg = &msg_oob;
|
||||
msg->cursize = 0;
|
||||
msg->maxsize = sizeof(oobdata);
|
||||
msg->currentbit = 0;
|
||||
msg->packing = SZ_RAWBYTES;
|
||||
msg->allowoverflow = 0;
|
||||
msg->overflowed = 0;
|
||||
msg->data = oobdata;
|
||||
MSG_WriteByte(msg, A2C_PRINT);
|
||||
SZ_Write(msg, "\\chunk", 6);
|
||||
MSG_WriteLong(msg, ezfilenum); //echoing the file num is used so the packets don't go out of sync.
|
||||
if (msg == &msg_oob)
|
||||
{
|
||||
msg = &msg_oob;
|
||||
msg->cursize = 0;
|
||||
msg->maxsize = sizeof(oobdata);
|
||||
msg->currentbit = 0;
|
||||
msg->packing = SZ_RAWBYTES;
|
||||
msg->allowoverflow = 0;
|
||||
msg->overflowed = 0;
|
||||
msg->data = oobdata;
|
||||
MSG_WriteByte(msg, A2C_PRINT);
|
||||
SZ_Write(msg, "\\chunk", 6);
|
||||
MSG_WriteLong(msg, ezfilenum); //echoing the file num is used so the packets don't go out of sync.
|
||||
}
|
||||
|
||||
if (i != CHUNKSIZE)
|
||||
memset(buffer+i, 0, CHUNKSIZE-i);
|
||||
|
||||
MSG_WriteByte(msg, svc_download);
|
||||
MSG_WriteLong(msg, chunknum);
|
||||
SZ_Write(msg, buffer, CHUNKSIZE);
|
||||
|
||||
if (msg == &msg_oob)
|
||||
{
|
||||
Netchan_OutOfBand(NS_SERVER, &host_client->netchan.remote_address, msg_oob.cursize, msg_oob.data);
|
||||
Netchan_Block(&host_client->netchan, msg_oob.cursize, SV_RateForClient(host_client));
|
||||
host_client->netchan.bytesout += msg_oob.cursize;
|
||||
}
|
||||
}
|
||||
else if (i < 0)
|
||||
error = true;
|
||||
|
||||
if (i != CHUNKSIZE)
|
||||
memset(buffer+i, 0, CHUNKSIZE-i);
|
||||
|
||||
MSG_WriteByte(msg, svc_download);
|
||||
MSG_WriteLong(msg, chunknum);
|
||||
SZ_Write(msg, buffer, CHUNKSIZE);
|
||||
|
||||
if (msg == &msg_oob)
|
||||
{
|
||||
Netchan_OutOfBand(NS_SERVER, &host_client->netchan.remote_address, msg_oob.cursize, msg_oob.data);
|
||||
Netchan_Block(&host_client->netchan, msg_oob.cursize, SV_RateForClient(host_client));
|
||||
}
|
||||
chunks--;
|
||||
chunknum++;
|
||||
}
|
||||
else if (i < 0)
|
||||
error = true;
|
||||
|
||||
if (error)
|
||||
{
|
||||
|
@ -2122,9 +2131,9 @@ void SV_NextDownload_f (void)
|
|||
if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)
|
||||
{
|
||||
if (Cmd_Argc() < 2)
|
||||
SV_NextChunkedDownload(atoi(Cmd_Argv(1)), atoi(Cmd_Argv(2)), atoi(Cmd_Argv(3)));
|
||||
SV_NextChunkedDownload(atoi(Cmd_Argv(1)), atoi(Cmd_Argv(2)), atoi(Cmd_Argv(3)), atoi(Cmd_Argv(4)));
|
||||
else
|
||||
SV_NextChunkedDownload(atoi(Cmd_Argv(1)), atoi(Cmd_Argv(2)), atoi(Cmd_Argv(3)));
|
||||
SV_NextChunkedDownload(atoi(Cmd_Argv(1)), atoi(Cmd_Argv(2)), atoi(Cmd_Argv(3)), atoi(Cmd_Argv(4)));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -2596,6 +2605,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
extern cvar_t allow_download_root;
|
||||
extern cvar_t allow_download_configs;
|
||||
extern cvar_t allow_download_copyrighted;
|
||||
extern cvar_t allow_download_other;
|
||||
char cleanname[MAX_QPATH];
|
||||
int i=0;
|
||||
if (strlen(name) >= MAX_QPATH)
|
||||
|
@ -2620,6 +2630,9 @@ qboolean SV_AllowDownload (const char *name)
|
|||
if (strchr(name, '\\')) //no windows paths - grow up lame windows users.
|
||||
return false;
|
||||
|
||||
if (!Q_strcasecmp("log", COM_FileExtension(name)))
|
||||
return false;
|
||||
|
||||
if (!strncmp(name, "package/", 8))
|
||||
{
|
||||
if (!strcmp("pk4", COM_FileExtension(name)) || !strcmp("pk3", COM_FileExtension(name)) || !strcmp("pak", COM_FileExtension(name)))
|
||||
|
@ -2677,12 +2690,13 @@ qboolean SV_AllowDownload (const char *name)
|
|||
//root of gamedir
|
||||
if (!strchr(name, '/') && !allow_download_root.value)
|
||||
{
|
||||
if (strcmp(name, "csprogs.dat")) //we always allow csprogs.dat to be downloaded (if downloads are permitted).
|
||||
return false;
|
||||
if (!strcmp(name, "csprogs.dat")) //we always allow csprogs.dat to be downloaded (if downloads are permitted).
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//any other subdirs are allowed
|
||||
return true;
|
||||
return !!allow_download_other.value;;
|
||||
}
|
||||
|
||||
static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
|
||||
|
@ -3036,9 +3050,16 @@ void SV_BeginDownload_f(void)
|
|||
host_client->download = tmp;
|
||||
}
|
||||
|
||||
ClientReliableWrite_Begin (host_client, svc_download, 10+strlen(host_client->downloadfn));
|
||||
ClientReliableWrite_Begin (host_client, svc_download, 18+strlen(host_client->downloadfn));
|
||||
ClientReliableWrite_Long (host_client, -1);
|
||||
ClientReliableWrite_Long (host_client, host_client->downloadsize);
|
||||
if (host_client->downloadsize >= 0x7fffffff)
|
||||
{ //avoid unsigned values.
|
||||
ClientReliableWrite_Long (host_client, 0x80000000); //signal that its 64bit
|
||||
ClientReliableWrite_Long (host_client, qofs_Low(host_client->downloadsize));
|
||||
ClientReliableWrite_Long (host_client, qofs_High(host_client->downloadsize));
|
||||
}
|
||||
else
|
||||
ClientReliableWrite_Long (host_client, host_client->downloadsize);
|
||||
ClientReliableWrite_String (host_client, host_client->downloadfn);
|
||||
}
|
||||
else
|
||||
|
@ -5333,8 +5354,11 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
|
|||
return;
|
||||
}
|
||||
|
||||
Log_String(LOG_RCON, va("cmd from %s - %s:\n%s\n"
|
||||
, NET_AdrToString (adr, sizeof(adr), &net_from), host_client->name, s));
|
||||
|
||||
Con_TPrintf ("cmd from %s:\n%s\n"
|
||||
, host_client->name, net_message.data+4);
|
||||
, host_client->name, s);
|
||||
|
||||
SV_BeginRedirect (RD_CLIENT, host_client->language);
|
||||
|
||||
|
@ -5351,8 +5375,8 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
|
|||
, NET_AdrToString (adr, sizeof(adr), &net_from), "Was too long - possible buffer overflow attempt");
|
||||
return;
|
||||
}
|
||||
strcat (remaining, Cmd_Argv(i) );
|
||||
strcat (remaining, " ");
|
||||
Q_strncatz(remaining, Cmd_Argv(i), sizeof(remaining));
|
||||
Q_strncatz(remaining, " ", sizeof(remaining));
|
||||
}
|
||||
|
||||
Cmd_ExecuteString (remaining, stats.trustlevel);
|
||||
|
|
Loading…
Reference in a new issue