mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-14 00:10:46 +00:00
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");
|
cvar_t dpcompat_set = SCVAR("dpcompat_set", "0");
|
||||||
int Cmd_ExecLevel;
|
int Cmd_ExecLevel;
|
||||||
qboolean cmd_didwait;
|
qboolean cmd_didwait;
|
||||||
|
qboolean cmd_blockwait;
|
||||||
|
|
||||||
void Cmd_ForwardToServer (void);
|
void Cmd_ForwardToServer (void);
|
||||||
|
|
||||||
|
@ -161,6 +162,9 @@ bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"
|
||||||
*/
|
*/
|
||||||
void Cmd_Wait_f (void)
|
void Cmd_Wait_f (void)
|
||||||
{
|
{
|
||||||
|
if (cmd_blockwait)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#ifndef CLIENTONLY
|
||||||
if (cmd_didwait && sv.state)
|
if (cmd_didwait && sv.state)
|
||||||
Con_DPrintf("waits without server frames\n");
|
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.
|
// Normally called once per frame, but may be explicitly invoked.
|
||||||
// Do not call inside a command function!
|
// Do not call inside a command function!
|
||||||
|
|
||||||
|
extern qboolean cmd_blockwait;
|
||||||
void Cbuf_ExecuteLevel(int level);
|
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.
|
//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.
|
//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 {
|
typedef enum {
|
||||||
LOG_CONSOLE,
|
LOG_CONSOLE,
|
||||||
LOG_PLAYER,
|
LOG_PLAYER,
|
||||||
|
LOG_RCON,
|
||||||
LOG_TYPES
|
LOG_TYPES
|
||||||
} logtype_t;
|
} logtype_t;
|
||||||
void Log_Dir_Callback (struct cvar_s *var, char *oldvalue);
|
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)
|
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 !(search->flags & SPF_COPYPROTECTED);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3944,6 +3944,10 @@ void FS_ChangeGame_f(void)
|
||||||
int i;
|
int i;
|
||||||
char *arg = Cmd_Argv(1);
|
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)
|
if (!*arg)
|
||||||
{
|
{
|
||||||
Con_Printf("Valid games are:\n");
|
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)
|
if (0)
|
||||||
{ //treat *ALL* tests against the actual geometry instead of using any brushes.
|
{ //treat *ALL* tests against the actual geometry instead of using any brushes.
|
||||||
//also ignores the bsp etc. not fast. testing only.
|
//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++)
|
for (i = 0; i < mod->numsurfaces; i++)
|
||||||
{
|
{
|
||||||
CM_ClipBoxToMesh(trace_mins, trace_maxs, trace_start, trace_end, &trace_trace, mod->surfaces[i].mesh);
|
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
|
else
|
||||||
if (0)
|
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++)
|
for (i = 0; i < mod->numleafs; i++)
|
||||||
CM_TraceToLeaf(&mod->leafs[i]);
|
CM_TraceToLeaf(&mod->leafs[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,12 @@ void Log_Name_Callback (struct cvar_s *var, char *oldvalue);
|
||||||
// cvars
|
// cvars
|
||||||
#define CONLOGGROUP "Console logging"
|
#define CONLOGGROUP "Console logging"
|
||||||
cvar_t log_enable[LOG_TYPES] = { CVARF("log_enable", "0", CVAR_NOTFROMSERVER),
|
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),
|
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_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_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);
|
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:
|
case LOG_PLAYER:
|
||||||
f = "players";
|
f = "players";
|
||||||
break;
|
break;
|
||||||
|
case LOG_RCON:
|
||||||
|
f = "rcon";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,11 @@
|
||||||
#define FTE_WORDSIZE 64
|
#define FTE_WORDSIZE 64
|
||||||
#define quintptr_t unsigned qintptr_t
|
#define quintptr_t unsigned qintptr_t
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
typedef __int32 qintptr_t; //add __w64 if you need msvc to shut up about unsafe type conversions
|
#ifndef _MSC_VER
|
||||||
typedef unsigned __int32 quintptr_t;
|
#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 qintptr_t __int32
|
||||||
// #define quintptr_t unsigned qintptr_t
|
// #define quintptr_t unsigned qintptr_t
|
||||||
#define FTE_WORDSIZE 32
|
#define FTE_WORDSIZE 32
|
||||||
|
|
|
@ -8837,6 +8837,14 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\client\in_generic.c"
|
RelativePath="..\client\in_generic.c"
|
||||||
>
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release Dedicated Server|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug Dedicated Server|Win32"
|
Name="Debug Dedicated Server|Win32"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
|
@ -11183,6 +11191,14 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\client\pr_clcmd.c"
|
RelativePath="..\client\pr_clcmd.c"
|
||||||
>
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release Dedicated Server|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug Dedicated Server|Win32"
|
Name="Debug Dedicated Server|Win32"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
|
@ -16807,6 +16823,7 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Release Dedicated Server|Win32"
|
Name="Release Dedicated Server|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
|
@ -21320,7 +21337,6 @@
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Release Dedicated Server|Win32"
|
Name="Release Dedicated Server|Win32"
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
|
|
|
@ -457,11 +457,11 @@ typedef struct client_s
|
||||||
|
|
||||||
char downloadfn[MAX_QPATH];
|
char downloadfn[MAX_QPATH];
|
||||||
vfsfile_t *download; // file being downloaded
|
vfsfile_t *download; // file being downloaded
|
||||||
unsigned int downloadsize; // total bytes
|
qofs_t downloadsize; // total bytes
|
||||||
unsigned int downloadcount; // bytes sent
|
qofs_t downloadcount; // bytes sent
|
||||||
|
|
||||||
int downloadacked; //DP-specific
|
qofs_t downloadacked; //DP-specific
|
||||||
int downloadstarted; //DP-specific
|
qofs_t downloadstarted; //DP-specific
|
||||||
|
|
||||||
int spec_track; // entnum of player tracking
|
int spec_track; // entnum of player tracking
|
||||||
|
|
||||||
|
@ -1161,7 +1161,7 @@ void SVM_Think(int port);
|
||||||
//
|
//
|
||||||
// svonly.c
|
// 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_BeginRedirect (redirect_t rd, int lang);
|
||||||
void SV_EndRedirect (void);
|
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_wads = CVAR("allow_download_wads", "1");
|
||||||
cvar_t allow_download_configs = CVAR("allow_download_configs", "0");
|
cvar_t allow_download_configs = CVAR("allow_download_configs", "0");
|
||||||
cvar_t allow_download_copyrighted = CVAR("allow_download_copyrighted", "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_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");
|
cvar_t sv_public = CVAR("sv_public", "0");
|
||||||
|
@ -3697,6 +3698,7 @@ void SVC_RemoteCommand (void)
|
||||||
|
|
||||||
if (!Rcon_Validate ())
|
if (!Rcon_Validate ())
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
#ifdef SVRANKING
|
#ifdef SVRANKING
|
||||||
if (cmd_allowaccess.value) //try and find a username, match the numeric password
|
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"
|
Con_TPrintf ("Rcon from %s:\n%s\n"
|
||||||
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4);
|
, 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;
|
remaining[0] = 0;
|
||||||
|
|
||||||
|
@ -3753,22 +3755,32 @@ void SVC_RemoteCommand (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
, NET_AdrToString (adr, sizeof(adr), &net_from), net_message.data+4);
|
||||||
|
|
||||||
SV_BeginRedirect (RD_PACKET, svs.language);
|
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
|
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);
|
, 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;
|
remaining[0] = 0;
|
||||||
|
|
||||||
|
@ -3778,16 +3790,19 @@ void SVC_RemoteCommand (void)
|
||||||
{
|
{
|
||||||
Con_TPrintf("Rcon was too long\n");
|
Con_TPrintf("Rcon was too long\n");
|
||||||
SV_EndRedirect ();
|
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");
|
, NET_AdrToString (adr, sizeof(adr), &net_from), "Was too long - possible buffer overflow attempt");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcat (remaining, Cmd_Argv(i) );
|
Q_strncatz(remaining, Cmd_Argv(i), sizeof(remaining));
|
||||||
strcat (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 ();
|
SV_EndRedirect ();
|
||||||
|
@ -5278,6 +5293,7 @@ void SV_InitLocal (void)
|
||||||
Cvar_Register (&allow_download_wads, cvargroup_serverpermissions);
|
Cvar_Register (&allow_download_wads, cvargroup_serverpermissions);
|
||||||
Cvar_Register (&allow_download_root, cvargroup_serverpermissions);
|
Cvar_Register (&allow_download_root, cvargroup_serverpermissions);
|
||||||
Cvar_Register (&allow_download_copyrighted, cvargroup_serverpermissions);
|
Cvar_Register (&allow_download_copyrighted, cvargroup_serverpermissions);
|
||||||
|
Cvar_Register (&allow_download_other, cvargroup_serverpermissions);
|
||||||
Cvar_Register (&secure, cvargroup_serverpermissions);
|
Cvar_Register (&secure, cvargroup_serverpermissions);
|
||||||
|
|
||||||
Cvar_Register (&sv_highchars, cvargroup_servercontrol);
|
Cvar_Register (&sv_highchars, cvargroup_servercontrol);
|
||||||
|
|
|
@ -62,8 +62,12 @@ void SV_FlushRedirect (void)
|
||||||
|
|
||||||
Log_String(LOG_CONSOLE, va("{\n%s}\n", outputbuf));
|
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[0] = 0xff;
|
||||||
send[1] = 0xff;
|
send[1] = 0xff;
|
||||||
send[2] = 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
|
#define CHUNKSIZE 1024
|
||||||
char buffer[CHUNKSIZE];
|
char buffer[CHUNKSIZE];
|
||||||
|
@ -2015,16 +2015,20 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
||||||
sizebuf_t *msg, msg_oob;
|
sizebuf_t *msg, msg_oob;
|
||||||
int i;
|
int i;
|
||||||
int error = false;
|
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;
|
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);
|
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;
|
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;
|
error = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2032,12 +2036,15 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
||||||
host_client->downloadcount = chunknum*CHUNKSIZE;
|
host_client->downloadcount = chunknum*CHUNKSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (!error && chunks > 0)
|
||||||
|
{
|
||||||
if ((host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) || (host_client->datagram.cursize + CHUNKSIZE+5 > 1400))
|
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.
|
//would overflow the packet, or result in (ethernet) fragmentation and high packet loss.
|
||||||
msg = &msg_oob;
|
msg = &msg_oob;
|
||||||
|
|
||||||
if (!ezfilenum)
|
if (!ezfilenum) //can't oob it
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (host_client->waschoked)
|
if (host_client->waschoked)
|
||||||
|
@ -2047,9 +2054,6 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
|
||||||
i = 0;
|
|
||||||
else
|
|
||||||
i = VFS_READ (host_client->download, buffer, CHUNKSIZE);
|
i = VFS_READ (host_client->download, buffer, CHUNKSIZE);
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
|
@ -2080,11 +2084,16 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
|
||||||
{
|
{
|
||||||
Netchan_OutOfBand(NS_SERVER, &host_client->netchan.remote_address, msg_oob.cursize, msg_oob.data);
|
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));
|
Netchan_Block(&host_client->netchan, msg_oob.cursize, SV_RateForClient(host_client));
|
||||||
|
host_client->netchan.bytesout += msg_oob.cursize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i < 0)
|
else if (i < 0)
|
||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
|
chunks--;
|
||||||
|
chunknum++;
|
||||||
|
}
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
VFS_CLOSE (host_client->download);
|
VFS_CLOSE (host_client->download);
|
||||||
|
@ -2122,9 +2131,9 @@ void SV_NextDownload_f (void)
|
||||||
if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)
|
if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)
|
||||||
{
|
{
|
||||||
if (Cmd_Argc() < 2)
|
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
|
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;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2596,6 +2605,7 @@ qboolean SV_AllowDownload (const char *name)
|
||||||
extern cvar_t allow_download_root;
|
extern cvar_t allow_download_root;
|
||||||
extern cvar_t allow_download_configs;
|
extern cvar_t allow_download_configs;
|
||||||
extern cvar_t allow_download_copyrighted;
|
extern cvar_t allow_download_copyrighted;
|
||||||
|
extern cvar_t allow_download_other;
|
||||||
char cleanname[MAX_QPATH];
|
char cleanname[MAX_QPATH];
|
||||||
int i=0;
|
int i=0;
|
||||||
if (strlen(name) >= MAX_QPATH)
|
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.
|
if (strchr(name, '\\')) //no windows paths - grow up lame windows users.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!Q_strcasecmp("log", COM_FileExtension(name)))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!strncmp(name, "package/", 8))
|
if (!strncmp(name, "package/", 8))
|
||||||
{
|
{
|
||||||
if (!strcmp("pk4", COM_FileExtension(name)) || !strcmp("pk3", COM_FileExtension(name)) || !strcmp("pak", COM_FileExtension(name)))
|
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
|
//root of gamedir
|
||||||
if (!strchr(name, '/') && !allow_download_root.value)
|
if (!strchr(name, '/') && !allow_download_root.value)
|
||||||
{
|
{
|
||||||
if (strcmp(name, "csprogs.dat")) //we always allow csprogs.dat to be downloaded (if downloads are permitted).
|
if (!strcmp(name, "csprogs.dat")) //we always allow csprogs.dat to be downloaded (if downloads are permitted).
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//any other subdirs are allowed
|
//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)
|
static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
|
||||||
|
@ -3036,8 +3050,15 @@ void SV_BeginDownload_f(void)
|
||||||
host_client->download = tmp;
|
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, -1);
|
||||||
|
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_Long (host_client, host_client->downloadsize);
|
||||||
ClientReliableWrite_String (host_client, host_client->downloadfn);
|
ClientReliableWrite_String (host_client, host_client->downloadfn);
|
||||||
}
|
}
|
||||||
|
@ -5333,8 +5354,11 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC)
|
||||||
return;
|
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"
|
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);
|
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");
|
, NET_AdrToString (adr, sizeof(adr), &net_from), "Was too long - possible buffer overflow attempt");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcat (remaining, Cmd_Argv(i) );
|
Q_strncatz(remaining, Cmd_Argv(i), sizeof(remaining));
|
||||||
strcat (remaining, " ");
|
Q_strncatz(remaining, " ", sizeof(remaining));
|
||||||
}
|
}
|
||||||
|
|
||||||
Cmd_ExecuteString (remaining, stats.trustlevel);
|
Cmd_ExecuteString (remaining, stats.trustlevel);
|
||||||
|
|
Loading…
Reference in a new issue