⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_main.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
		end;
		Netchan_Setup (NS_CLIENT, @cls.netchan, net_from, cls.quakePort);
		MSG_WriteChar (cls.netchan.message, Byte(clc_stringcmd));
		MSG_WriteString (cls.netchan.message, 'new');
		cls.state := ca_connected;
		exit;
  end;

	// server responding to a status broadcast
	if (strcmp(c, 'info') = 0) then begin
		CL_ParseStatusMessage ();
		exit;
	end;

	// 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
	while (NET_GetPacket (NS_CLIENT, net_from, net_message)) do begin
		Com_Printf ('dumping a packet'#10);
	end;
end;

(*
=================
CL_ReadPackets
=================
*)
procedure CL_ReadPackets;
begin
	while (NET_GetPacket (NS_CLIENT, net_from, net_message)) do 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;

        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;
		end;
		precache_check := TEXTURE_CNT+999;
	end;

//ZOID
	CL_RegisterSounds ();
	CL_PrepRefresh ();

	MSG_WriteByte (cls.netchan.message, Byte(clc_stringcmd));
	MSG_WriteString (cls.netchan.message, va('begin %d'#10, [precache_spawncount]) );
end;

(*
=================
CL_Precache_f

The server will send this command right
before allowing the client into the server
=================
*)
procedure CL_Precache_f; cdecl;
var
  map_checksum: Cardinal; // for detecting cheater maps

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -