📄 cl_main.pas
字号:
// remote command from gui front end
if (strcmp(c, 'cmd') = 0) then
begin
if (not NET_IsLocalAddress(net_from)) then
begin
Com_Printf('Command packet from remote host. Ignored.'#10);
exit;
end;
Sys_AppActivate();
s := MSG_ReadString(net_message);
Cbuf_AddText(s);
Cbuf_AddText(#10);
exit;
end;
// print command from somewhere
if (strcmp(c, 'print') = 0) then
begin
s := MSG_ReadString(net_message);
Com_Printf('%s', [s]);
exit;
end;
// ping from somewhere
if (strcmp(c, 'ping') = 0) then
begin
Netchan_OutOfBandPrint(NS_CLIENT, net_from, 'ack', []);
exit;
end;
// challenge from the server we are connecting to
if (strcmp(c, 'challenge') = 0) then
begin
cls.challenge := StrToInt(Cmd_Argv(1));
CL_SendConnectPacket();
exit;
end;
// echo request from server
if (strcmp(c, 'echo') = 0) then
begin
Netchan_OutOfBandPrint(NS_CLIENT, net_from, '%s', [Cmd_Argv(1)]);
exit;
end;
Com_Printf('Unknown command.'#10);
end;
{*
=================
CL_DumpPackets
A vain attempt to help bad TCP stacks that cause problems
when they overflow
=================
*}
procedure CL_DumpPackets;
begin
{$IFDEF WIN32}
while (NET_GetPacket(NS_CLIENT, net_from, net_message)) do
{$ELSE}
while (NET_GetPacket(NS_CLIENT, @net_from, @net_message)) do
{$ENDIF}
begin
Com_Printf('dumping a packet'#10);
end;
end;
{*
=================
CL_ReadPackets
=================
*}
procedure CL_ReadPackets;
begin
{$IFDEF WIN32}
while (NET_GetPacket(NS_CLIENT, net_from, net_message)) do
{$ELSE}
while (NET_GetPacket(NS_CLIENT, @net_from, @net_message)) do
{$ENDIF}
begin
// Com_Printf ("packet"#10);
//
// remote command packet
//
if (PInteger(net_message.data)^ = -1) then
begin
CL_ConnectionlessPacket();
continue;
end;
if (cls.state = ca_disconnected) or (cls.state = ca_connecting) then
continue; // dump it if not connected
if (net_message.cursize < 8) then
begin
Com_Printf('%s: Runt packet'#10, [NET_AdrToString(net_from)]);
continue;
end;
//
// packet from server
//
if (not NET_CompareAdr(net_from, cls.netchan.remote_address)) then
begin
Com_DPrintf('%s:sequenced packet without connection'#10
, [NET_AdrToString(net_from)]);
continue;
end;
if (not Netchan_Process(cls.netchan, net_message)) then
continue; // wasn't accepted for some reason
CL_ParseServerMessage();
end;
//
// check timeout
//
if (cls.state >= ca_connected) and
(cls.realtime - cls.netchan.last_received > cl_timeout.value * 1000) then
begin
Inc(cl.timeoutcount);
if (cl.timeoutcount > 5) then
begin // timeoutcount saves debugger
Com_Printf(#10'Server connection timed out.'#10);
CL_Disconnect();
exit;
end;
end
else
cl.timeoutcount := 0;
end;
//=============================================================================
{*
==============
CL_FixUpGender_f
==============
*}
procedure CL_FixUpGender;
var
p: pchar;
sk: array[0..80 - 1] of char;
begin
if (gender_auto.value <> 0) then
begin
if (gender.modified) then
begin
// was set directly, don't override the user
gender.modified := false;
exit;
end;
strncpy(sk, skin.string_, sizeof(sk) - 1);
p := strchr(sk, Byte('/'));
if (p <> nil) then
p^ := #0;
if (Q_stricmp(sk, 'male') = 0) or (Q_stricmp(sk, 'cyborg') = 0) then
Cvar_Set('gender', 'male')
else if (Q_stricmp(sk, 'female') = 0) or (Q_stricmp(sk, 'crackhor') = 0) then
Cvar_Set('gender', 'female')
else
Cvar_Set('gender', 'none');
gender.modified := false;
end;
end;
{*
==============
CL_Userinfo_f
==============
*}
procedure CL_Userinfo_f; cdecl;
begin
Com_Printf('User info settings:'#10);
Info_Print(Cvar_Userinfo_());
end;
{*
=================
CL_Snd_Restart_f
Restart the sound subsystem so it can pick up
new parameters and flush all sounds
=================
*}
procedure CL_Snd_Restart_f; cdecl;
begin
S_Shutdown();
S_Init();
CL_RegisterSounds();
end;
var
precache_check, // for autodownload of precache items
precache_spawncount,
precache_tex,
precache_model_skin: integer;
precache_model: PByte; // used for skin checking in alias models
const
PLAYER_MULT = 5;
// ENV_CNT is map load, ENV_CNT+1 is first env map
ENV_CNT = (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT);
TEXTURE_CNT = (ENV_CNT + 13);
var
env_suf: array[0..5] of pchar = ('rt', 'bk', 'lf', 'ft', 'up', 'dn');
procedure CL_RequestNextDownload;
var
map_checksum: Cardinal; // for detecting cheater maps
fn: array[0..MAX_OSPATH - 1] of char;
pheader: dmdl_p;
i, n: integer;
model, skin: array[0..MAX_QPATH - 1] of char;
p: pchar;
begin
if (cls.state <> ca_connected) then
exit;
if (allow_download.value = 0) and (precache_check < ENV_CNT) then
precache_check := ENV_CNT;
//ZOID
if (precache_check = CS_MODELS) then
begin // confirm map
precache_check := CS_MODELS + 2; // 0 isn't used
if (allow_download_maps.value <> 0) then
if (not CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS + 1])) then
exit; // started a download
end;
if (precache_check >= CS_MODELS) and (precache_check < CS_MODELS + MAX_MODELS) then
begin
if (allow_download_models.value <> 0) then
begin
while (precache_check < CS_MODELS + MAX_MODELS) and
(cl.configstrings[precache_check][0] <> #0) do
begin
if (cl.configstrings[precache_check][0] = '*') or
(cl.configstrings[precache_check][0] = '#') then
begin
Inc(precache_check);
continue;
end;
if (precache_model_skin = 0) then
begin
if (not CL_CheckOrDownloadFile(cl.configstrings[precache_check])) then
begin
precache_model_skin := 1;
exit; // started a download
end;
precache_model_skin := 1;
end;
// checking for skins in the model
if (precache_model = nil) then
begin
FS_LoadFile(cl.configstrings[precache_check], @precache_model);
if (precache_model = nil) then
begin
precache_model_skin := 0;
Inc(precache_check);
continue; // couldn't load it
end;
if (LittleLong(PCardinal(precache_model)^) <> IDALIASHEADER) then
begin
// not an alias model
FS_FreeFile(precache_model);
precache_model := nil;
precache_model_skin := 0;
Inc(precache_check);
continue;
end;
pheader := dmdl_p(precache_model);
if (LittleLong(pheader.version) <> ALIAS_VERSION) then
begin
Inc(precache_check);
precache_model_skin := 0;
continue; // couldn't load it
end;
end;
pheader := dmdl_p(precache_model);
while (precache_model_skin - 1 < LittleLong(pheader.num_skins)) do
begin
if (not CL_CheckOrDownloadFile(Pointer(Cardinal(precache_model) +
LittleLong(pheader.ofs_skins) +
(precache_model_skin - 1) * MAX_SKINNAME))) then
begin
Inc(precache_model_skin);
exit; // started a download
end;
Inc(precache_model_skin);
end;
if (precache_model <> nil) then
begin
FS_FreeFile(precache_model);
precache_model := nil;
end;
precache_model_skin := 0;
Inc(precache_check);
end;
end;
precache_check := CS_SOUNDS;
end;
if (precache_check >= CS_SOUNDS) and (precache_check < CS_SOUNDS + MAX_SOUNDS) then
begin
if (allow_download_sounds.value <> 0) then
begin
if (precache_check = CS_SOUNDS) then
Inc(precache_check); // zero is blank
while (precache_check < CS_SOUNDS + MAX_SOUNDS) and
(cl.configstrings[precache_check][0] <> #0) do
begin
if (cl.configstrings[precache_check][0] = '*') then
begin
Inc(precache_check);
continue;
end;
Com_sprintf(fn, sizeof(fn), 'sound/%s', [cl.configstrings[precache_check]]);
Inc(precache_check);
if (not CL_CheckOrDownloadFile(fn)) then
exit; // started a download
end;
end;
precache_check := CS_IMAGES;
end;
if (precache_check >= CS_IMAGES) and (precache_check < CS_IMAGES + MAX_IMAGES) then
begin
if (precache_check = CS_IMAGES) then
Inc(precache_check); // zero is blank
while (precache_check < CS_IMAGES + MAX_IMAGES) and
(cl.configstrings[precache_check][0] <> #0) do
begin
Com_sprintf(fn, sizeof(fn), 'pics/%s.pcx', [cl.configstrings[precache_check]]);
Inc(precache_check);
if (not CL_CheckOrDownloadFile(fn)) then
exit; // started a download
end;
precache_check := CS_PLAYERSKINS;
end;
// skins are special, since a player has three things to download:
// model, weapon model and skin
// so precache_check is now *3
if (precache_check >= CS_PLAYERSKINS) and (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) then
begin
if (allow_download_players.value <> 0) then
begin
while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) do
begin
i := (precache_check - CS_PLAYERSKINS) div PLAYER_MULT;
n := (precache_check - CS_PLAYERSKINS) mod PLAYER_MULT;
if (cl.configstrings[CS_PLAYERSKINS + i][0] = #0) then
begin
precache_check := CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
continue;
end;
p := strchr(cl.configstrings[CS_PLAYERSKINS + i], Byte('\'));
if (p <> nil) then
Inc(p)
else
p := cl.configstrings[CS_PLAYERSKINS + i];
strcpy(model, p);
p := strchr(model, Byte('/'));
if (p = nil) then
p := strchr(model, Byte('\'));
if (p <> nil) then
begin
p^ := #0;
inc(p);
strcpy(skin, p);
end
else
skin[0] := #0;
if (n = 0) then
begin // model
Com_sprintf(fn, sizeof(fn), 'players/%s/tris.md2', [model]);
if (not CL_CheckOrDownloadFile(fn)) then
begin
precache_check := CS_PLAYERSKINS + i * PLAYER_MULT + 1;
exit; // started a download
end;
Inc(n);
{*FALL THROUGH*}
end;
if (n = 1) then
begin // weapon model
Com_sprintf(fn, sizeof(fn), 'players/%s/weapon.md2', [model]);
if (not CL_CheckOrDownloadFile(fn)) then
begin
precache_check := CS_PLAYERSKINS + i * PLAYER_MULT + 2;
exit; // started a download
end;
Inc(n);
{*FALL THROUGH*}
end;
if (n = 2) then
begin // weapon skin
Com_sprintf(fn, sizeof(fn), 'players/%s/weapon.pcx', [model]);
if (not CL_CheckOrDownloadFile(fn)) then
begin
precache_check := CS_PLAYERSKINS + i * PLAYER_MULT + 3;
exit; // started a download
end;
Inc(n);
{*FALL THROUGH*}
end;
if (n = 3) then
begin // skin
Com_sprintf(fn, sizeof(fn), 'players/%s/%s.pcx', [model, skin]);
if (not CL_CheckOrDownloadFile(fn)) then
begin
precache_check := CS_PLAYERSKINS + i * PLAYER_MULT + 4;
exit; // started a download
end;
Inc(n);
{*FALL THROUGH*}
end;
if (N = 4) then
begin // skin_i
Com_sprintf(fn, sizeof(fn), 'players/%s/%s_i.pcx', [model, skin]);
if (not CL_CheckOrDownloadFile(fn)) then
begin
precache_check := CS_PLAYERSKINS + i * PLAYER_MULT + 5;
exit; // started a download
end;
// move on to next model
precache_check := CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
end;
end;
end;
// precache phase completed
precache_check := ENV_CNT;
end;
if (precache_check = ENV_CNT) then
begin
precache_check := ENV_CNT + 1;
CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, map_checksum);
// Note : map_checksum has been typecasted to Integer in the conversion - by burnin
if (Integer(map_checksum) <> StrToInt(cl.configstrings[CS_MAPCHECKSUM])) then
begin
Com_Error(ERR_DROP, 'Local map version differs from server: %d != ''%s'''#10,
[map_checksum, cl.configstrings[CS_MAPCHECKSUM]]);
exit;
end;
end;
if (precache_check > ENV_CNT) and (precache_check < TEXTURE_CNT) then
begin
if (allow_download.value <> 0) and (allow_download_maps.value <> 0) then
begin
while (precache_check < TEXTURE_CNT) do
begin
n := precache_check - ENV_CNT - 1;
Inc(precache_check);
if ((n and 1) <> 0) then
Com_sprintf(fn, sizeof(fn), 'env/%s%s.pcx',
[cl.configstrings[CS_SKY], env_suf[n div 2]])
else
Com_sprintf(fn, sizeof(fn), 'env/%s%s.tga',
[cl.configstrings[CS_SKY], env_suf[n div 2]]);
if (not CL_CheckOrDownloadFile(fn)) then
exit; // started a download
end;
end;
precache_check := TEXTURE_CNT;
end;
if (precache_check = TEXTURE_CNT) then
begin
precache_check := TEXTURE_CNT + 1;
precache_tex := 0;
end;
// confirm existance of textures, download any that don't exist
if (precache_check = TEXTURE_CNT + 1) then
begin
if (allow_download.value <> 0) and (allow_download_maps.value <> 0) then
begin
while (precache_tex < numtexinfo) do
begin
Com_sprintf(fn, sizeof(fn), 'textures/%s.wal', [map_surfaces[precache_tex].rname]);
Inc(precache_tex);
if (not CL_CheckOrDownloadFile(fn)) then
exit; // started a download
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -