|
|
Quake II v3.17
--- g:\quake2\code\server\sv_user.c Mon Mar 02 15:21:11 1998
+++ sv_user.c Sun Mar 15 19:08:37 1998
@@ -42,6 +42,7 @@
int playernum;
edict_t *ent;
+
Com_DPrintf ("New() from %s\n", sv_client->name);
if (sv_client->state != cs_connected)
@@ -108,6 +109,8 @@
Com_DPrintf ("Configstrings() from %s\n", sv_client->name);
+
+
if (sv_client->state != cs_connected)
{
Com_Printf ("configstrings not valid -- already spawned\n");
@@ -165,6 +168,8 @@
Com_DPrintf ("Baselines() from %s\n", sv_client->name);
+
+
if (sv_client->state != cs_connected)
{
Com_Printf ("baselines not valid -- already spawned\n");
@@ -202,7 +207,7 @@
if (start == MAX_EDICTS)
{
MSG_WriteByte (&sv_client->netchan.message, svc_stufftext);
- MSG_WriteString (&sv_client->netchan.message, va("precache ; cmd begin %i\n",svs.spawncount) );
+ MSG_WriteString (&sv_client->netchan.message, va("precache %i\n", svs.spawncount) );
}
else
{
@@ -273,7 +278,6 @@
FS_FreeFile (sv_client->download);
sv_client->download = NULL;
-
}
/*
@@ -285,10 +289,35 @@
{
char *name;
extern cvar_t *allow_download;
+ extern cvar_t *allow_download_players;
+ extern cvar_t *allow_download_models;
+ extern cvar_t *allow_download_sounds;
+ extern cvar_t *allow_download_maps;
+ extern int file_from_pak; // ZOID did file come from pak?
+ int offset = 0;
name = Cmd_Argv(1);
+
+ if (Cmd_Argc() > 2)
+ offset = atoi(Cmd_Argv(2)); // downloaded offset
+
+ // hacked by zoid to allow more conrol over download
+ // first off, no .. or global allow check
if (strstr (name, "..") || !allow_download->value
- || strstr (name, "maps") ) // don't allow full map downloads
+ // leading dot is no good
+ || *name == '.'
+ // leading slash bad as well, must be in subdir
+ || *name == '/'
+ // next up, skin check
+ || (strncmp(name, "players/", 6) == 0 && !allow_download_players->value)
+ // now models
+ || (strncmp(name, "models/", 6) == 0 && !allow_download_models->value)
+ // now sounds
+ || (strncmp(name, "sound/", 6) == 0 && !allow_download_sounds->value)
+ // now maps (note special case for maps, must not be in pak)
+ || (strncmp(name, "maps/", 6) == 0 && !allow_download_maps->value)
+ // MUST be in a subdirectory
+ || !strstr (name, "/") )
{ // don't allow anything with .. path
MSG_WriteByte (&sv_client->netchan.message, svc_download);
MSG_WriteShort (&sv_client->netchan.message, -1);
@@ -296,15 +325,24 @@
return;
}
+
if (sv_client->download)
FS_FreeFile (sv_client->download);
sv_client->downloadsize = FS_LoadFile (name, (void **)&sv_client->download);
- sv_client->downloadcount = 0;
+ sv_client->downloadcount = offset;
- if (!sv_client->download)
+ if (!sv_client->download
+ // special check for maps, if it came from a pak file, don't allow
+ // download ZOID
+ || (strncmp(name, "maps/", 5) == 0 && file_from_pak))
{
Com_DPrintf ("Couldn't download %s to %s\n", name, sv_client->name);
+ if (sv_client->download) {
+ FS_FreeFile (sv_client->download);
+ sv_client->download = NULL;
+ }
+
MSG_WriteByte (&sv_client->netchan.message, svc_download);
MSG_WriteShort (&sv_client->netchan.message, -1);
MSG_WriteByte (&sv_client->netchan.message, 0);
@@ -316,6 +354,7 @@
}
+
//============================================================================
@@ -358,9 +397,12 @@
if (!v[0])
Cbuf_AddText ("killserver\n");
else
+
{
Cbuf_AddText (v);
+
Cbuf_AddText ("\n");
+
}
Cvar_Set ("nextserver","");
}
@@ -444,17 +486,29 @@
*/
+
void ClientThink (client_t *cl, usercmd_t *cmd)
+
{
+
cl->commandMsec -= cmd->msec;
+
if (cl->commandMsec < 0 && sv_enforcetime->value )
+
{
+
Com_DPrintf ("commandMsec underflow from %s\n", cl->name);
+
return;
+
}
+
ge->ClientThink (cl->edict, cmd);
+
}
+
+
#define MAX_STRINGCMDS 8
/*
===================
@@ -467,22 +521,32 @@
{
int c;
char *s;
+
usercmd_t nullcmd;
usercmd_t oldest, oldcmd, newcmd;
int net_drop;
int stringCmdCount;
+
int checksum, calculatedChecksum;
+
int checksumIndex;
+
qboolean move_issued;
+
sv_client = cl;
sv_player = sv_client->edict;
+
// only allow one move command
+
move_issued = false;
+
+
stringCmdCount = 0;
+
while (1)
{
if (net_message.readcount > net_message.cursize)
@@ -512,57 +576,96 @@
break;
case clc_move:
+
if (move_issued)
+
return; // someone is trying to cheat...
+
move_issued = true;
+
+
checksumIndex = net_message.readcount;
+
checksum = MSG_ReadByte (&net_message);
+
+
cl->lastframe = MSG_ReadLong (&net_message);
+
memset (&nullcmd, 0, sizeof(nullcmd));
MSG_ReadDeltaUsercmd (&net_message, &nullcmd, &oldest);
MSG_ReadDeltaUsercmd (&net_message, &oldest, &oldcmd);
MSG_ReadDeltaUsercmd (&net_message, &oldcmd, &newcmd);
if ( cl->state != cs_spawned )
+
{
+
cl->lastframe = -1;
break;
}
+
+
// if the checksum fails, ignore the rest of the packet
+
calculatedChecksum = COM_BlockSequenceCheckByte (
+
net_message.data + checksumIndex + 1,
+
net_message.readcount - checksumIndex - 1,
+
cl->netchan.incoming_sequence);
+
+
if (calculatedChecksum != checksum)
+
{
+
+ // hack for unreliable end condition
+ if ((cl->netchan.incoming_sequence %
+ (NUMVERTEXNORMALS * sizeof(vec3_t))) + 3 <
+ (NUMVERTEXNORMALS * sizeof(vec3_t))) {
Com_DPrintf ("Failed command checksum for %s\n", cl->name);
+
return;
+
+ }
}
+
+
if (!sv_paused->value)
+
{
net_drop = cl->netchan.dropped;
if (net_drop < 20)
{
+
//if (net_drop > 2)
+
// Com_Printf ("drop %i\n", net_drop);
while (net_drop > 2)
{
ClientThink (cl, &cl->lastcmd);
+
net_drop--;
}
if (net_drop > 1)
ClientThink (cl, &oldest);
+
if (net_drop > 0)
ClientThink (cl, &oldcmd);
+
}
ClientThink (cl, &newcmd);
+
}
+
+
cl->lastcmd = newcmd;
break;
@@ -570,13 +673,19 @@
case clc_stringcmd:
s = MSG_ReadString (&net_message);
+
+
// malicious users may try using too many string commands
+
if (++stringCmdCount < MAX_STRINGCMDS)
SV_ExecuteUserCommand (s);
+
if (cl->state == cs_zombie)
+
return; // disconnect command
break;
}
}
+
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.