📄 sv_user.c
字号:
|| !strstr (name, "/") )
{ // don't allow anything with .. path
MSG_WriteByte (&sv_client->netchan.message, svc_download);
MSG_WriteShort (&sv_client->netchan.message, -1);
MSG_WriteByte (&sv_client->netchan.message, 0);
return;
}
if (sv_client->download)
FS_FreeFile (sv_client->download);
sv_client->downloadsize = FS_LoadFile (name, (void **)&sv_client->download);
sv_client->downloadcount = offset;
if (offset > sv_client->downloadsize)
sv_client->downloadcount = sv_client->downloadsize;
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);
return;
}
SV_NextDownload_f ();
Com_DPrintf ("Downloading %s to %s\n", name, sv_client->name);
}
//============================================================================
/*
=================
SV_Disconnect_f
The client is going to disconnect, so remove the connection immediately
=================
*/
void SV_Disconnect_f (void)
{
// SV_EndRedirect ();
SV_DropClient (sv_client);
}
/*
==================
SV_ShowServerinfo_f
Dumps the serverinfo info string
==================
*/
void SV_ShowServerinfo_f (void)
{
Info_Print (Cvar_Serverinfo());
}
void SV_Nextserver (void)
{
char *v;
//ZOID, ss_pic can be nextserver'd in coop mode
if (sv.state == ss_game || (sv.state == ss_pic && !Cvar_VariableValue("coop")))
return; // can't nextserver while playing a normal game
svs.spawncount++; // make sure another doesn't sneak in
v = Cvar_VariableString ("nextserver");
if (!v[0])
Cbuf_AddText ("killserver\n");
else
{
Cbuf_AddText (v);
Cbuf_AddText ("\n");
}
Cvar_Set ("nextserver","");
}
/*
==================
SV_Nextserver_f
A cinematic has completed or been aborted by a client, so move
to the next server,
==================
*/
void SV_Nextserver_f (void)
{
if ( atoi(Cmd_Argv(1)) != svs.spawncount ) {
Com_DPrintf ("Nextserver() from wrong level, from %s\n", sv_client->name);
return; // leftover from last server
}
Com_DPrintf ("Nextserver() from %s\n", sv_client->name);
SV_Nextserver ();
}
typedef struct
{
char *name;
void (*func) (void);
} ucmd_t;
ucmd_t ucmds[] =
{
// auto issued
{"new", SV_New_f},
{"configstrings", SV_Configstrings_f},
{"baselines", SV_Baselines_f},
{"begin", SV_Begin_f},
{"nextserver", SV_Nextserver_f},
{"disconnect", SV_Disconnect_f},
// issued by hand at client consoles
{"info", SV_ShowServerinfo_f},
{"download", SV_BeginDownload_f},
{"nextdl", SV_NextDownload_f},
{NULL, NULL}
};
/*
==================
SV_ExecuteUserCommand
==================
*/
void SV_ExecuteUserCommand (char *s)
{
ucmd_t *u;
Cmd_TokenizeString (s, true);
sv_player = sv_client->edict;
// SV_BeginRedirect (RD_CLIENT);
for (u=ucmds ; u->name ; u++)
if (!strcmp (Cmd_Argv(0), u->name) )
{
u->func ();
break;
}
if (!u->name && sv.state == ss_game)
ge->ClientCommand (sv_player);
// SV_EndRedirect ();
}
/*
===========================================================================
USER CMD EXECUTION
===========================================================================
*/
void SV_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
/*
===================
SV_ExecuteClientMessage
The current net_message is parsed for the given client
===================
*/
void SV_ExecuteClientMessage (client_t *cl)
{
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;
int lastframe;
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)
{
Com_Printf ("SV_ReadClientMessage: badread\n");
SV_DropClient (cl);
return;
}
c = MSG_ReadByte (&net_message);
if (c == -1)
break;
switch (c)
{
default:
Com_Printf ("SV_ReadClientMessage: unknown command char\n");
SV_DropClient (cl);
return;
case clc_nop:
break;
case clc_userinfo:
strncpy (cl->userinfo, MSG_ReadString (&net_message), sizeof(cl->userinfo)-1);
SV_UserinfoChanged (cl);
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);
lastframe = MSG_ReadLong (&net_message);
if (lastframe != cl->lastframe) {
cl->lastframe = lastframe;
if (cl->lastframe > 0) {
cl->frame_latency[cl->lastframe&(LATENCY_COUNTS-1)] =
svs.realtime - cl->frames[cl->lastframe & UPDATE_MASK].senttime;
}
}
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_BlockSequenceCRCByte (
net_message.data + checksumIndex + 1,
net_message.readcount - checksumIndex - 1,
cl->netchan.incoming_sequence);
if (calculatedChecksum != checksum)
{
Com_DPrintf ("Failed command checksum for %s (%d != %d)/%d\n",
cl->name, calculatedChecksum, checksum,
cl->netchan.incoming_sequence);
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)
{
SV_ClientThink (cl, &cl->lastcmd);
net_drop--;
}
if (net_drop > 1)
SV_ClientThink (cl, &oldest);
if (net_drop > 0)
SV_ClientThink (cl, &oldcmd);
}
SV_ClientThink (cl, &newcmd);
}
cl->lastcmd = newcmd;
break;
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;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -