move->sequence = MSG_ReadLong ();
move->time = MSG_ReadFloat ();
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
- move->receivetime = sv.time;
+ move->receivetime = (float)sv.time;
// calculate average ping time
host_client->ping = move->receivetime - move->time;
{
double frametime = bound(0, move->time - oldmovetime, 0.1);
double oldframetime = prog->globals.server->frametime;
+ double oldframetime2 = sv.frametime;
//if (move->time - oldmovetime >= 0.1001)
// Con_DPrintf("client move exceeds 100ms! (time %f -> time %f)\n", oldmovetime, move->time);
+ // the server and qc frametime values must be changed temporarily
+ sv.frametime = frametime;
prog->globals.server->frametime = frametime;
SV_Physics_ClientEntity(host_client->edict);
+ sv.frametime = oldframetime2;
prog->globals.server->frametime = oldframetime;
host_client->clmovement_skipphysicsframes = sv_clmovement_waitforinput.integer;
}
===================
*/
extern void SV_SendServerinfo(client_t *client);
+extern sizebuf_t vm_tempstringsbuf;
void SV_ReadClientMessage(void)
{
- int cmd, num;
+ int cmd, num, start;
char *s;
//MSG_BeginReading ();
Cmd_ExecuteString (s, src_client);
else if (SV_ParseClientCommandQC)
{
- PRVM_G_INT(OFS_PARM0) = PRVM_SetEngineString(s);
+ int restorevm_tempstringsbuf_cursize;
+ restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+ PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(s);
prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
PRVM_ExecuteProgram ((func_t)(SV_ParseClientCommandQC - prog->functions), "QC function SV_ParseClientCommand is missing");
+ vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
}
- else if (strncasecmp(s, "status", 6) == 0
- || strncasecmp(s, "name", 4) == 0
- || strncasecmp(s, "say", 3) == 0
- || strncasecmp(s, "say_team", 8) == 0
- || strncasecmp(s, "tell", 4) == 0
- || strncasecmp(s, "color", 5) == 0
- || strncasecmp(s, "kill", 4) == 0
- || strncasecmp(s, "pause", 5) == 0
- || strncasecmp(s, "kick", 4) == 0
- || strncasecmp(s, "ping", 4) == 0
- || strncasecmp(s, "ban", 3) == 0
- || strncasecmp(s, "pmodel", 6) == 0
- || strncasecmp(s, "rate", 4) == 0
- || strncasecmp(s, "playermodel", 11) == 0
- || strncasecmp(s, "playerskin", 10) == 0
- || (gamemode == GAME_NEHAHRA && (strncasecmp(s, "max", 3) == 0 || strncasecmp(s, "monster", 7) == 0 || strncasecmp(s, "scrag", 5) == 0 || strncasecmp(s, "gimme", 5) == 0 || strncasecmp(s, "wraith", 6) == 0))
- || (gamemode != GAME_NEHAHRA && (strncasecmp(s, "god", 3) == 0 || strncasecmp(s, "notarget", 8) == 0 || strncasecmp(s, "fly", 3) == 0 || strncasecmp(s, "give", 4) == 0 || strncasecmp(s, "noclip", 6) == 0)))
- Cmd_ExecuteString (s, src_client);
else
- Con_Printf("%s tried to %s\n", host_client->name, s);
+ Cmd_ExecuteString (s, src_client);
break;
case clc_disconnect:
SV_DropClient (false);
break;
+ case clc_ackdownloaddata:
+ start = MSG_ReadLong();
+ num = MSG_ReadShort();
+ if (host_client->download_file && host_client->download_started)
+ {
+ if (host_client->download_expectedposition == start)
+ {
+ int size = (int)FS_FileSize(host_client->download_file);
+ // a data block was successfully received by the client,
+ // update the expected position on the next data block
+ host_client->download_expectedposition = start + num;
+ // if this was the last data block of the file, it's done
+ if (host_client->download_expectedposition >= FS_FileSize(host_client->download_file))
+ {
+ // tell the client that the download finished
+ // we need to calculate the crc now
+ //
+ // note: at this point the OS probably has the file
+ // entirely in memory, so this is a faster operation
+ // now than it was when the download started.
+ //
+ // it is also preferable to do this at the end of the
+ // download rather than the start because it reduces
+ // potential for Denial Of Service attacks against the
+ // server.
+ int crc;
+ unsigned char *temp;
+ FS_Seek(host_client->download_file, 0, SEEK_SET);
+ temp = Mem_Alloc(tempmempool, size);
+ FS_Read(host_client->download_file, temp, size);
+ crc = CRC_Block(temp, size);
+ Mem_Free(temp);
+ // calculated crc, send the file info to the client
+ // (so that it can verify the data)
+ Host_ClientCommands(va("\ncl_downloadfinished %i %i %s\n", size, crc, host_client->download_name));
+ Con_DPrintf("Download of %s by %s has finished\n", host_client->download_name, host_client->name);
+ FS_Close(host_client->download_file);
+ host_client->download_file = NULL;
+ host_client->download_name[0] = 0;
+ host_client->download_expectedposition = 0;
+ host_client->download_started = false;
+ }
+ }
+ else
+ {
+ // a data block was lost, reset to the expected position
+ // and resume sending from there
+ FS_Seek(host_client->download_file, host_client->download_expectedposition, SEEK_SET);
+ }
+ }
+ break;
+
case clc_ackframe:
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
num = MSG_ReadLong();