1774 lines · 37.6 KB · C
RawDownload
// cl_main.c  -- client main loop #include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" cvar_t	*adr0;cvar_t	*adr1;cvar_t	*adr2;cvar_t	*adr3;cvar_t	*adr4;cvar_t	*adr5;cvar_t	*adr6;cvar_t	*adr7;cvar_t	*adr8; cvar_t	*cl_stereo_separation;cvar_t	*cl_stereo; cvar_t	*rcon_client_password;cvar_t	*rcon_address; cvar_t	*cl_noskins;cvar_t	*cl_autoskins;cvar_t	*cl_footsteps;cvar_t	*cl_timeout;cvar_t	*cl_predict;//cvar_t	*cl_minfps;cvar_t	*cl_maxfps;cvar_t	*cl_gun; cvar_t	*cl_add_particles;cvar_t	*cl_add_lights;cvar_t	*cl_add_entities;cvar_t	*cl_add_blend; cvar_t	*cl_shownet;cvar_t	*cl_showmiss;cvar_t	*cl_showclamp; cvar_t	*cl_paused;cvar_t	*cl_timedemo; cvar_t	*cl_lightlevel; //// userinfo//cvar_t	*info_password;cvar_t	*info_spectator;cvar_t	*name;cvar_t	*skin;cvar_t	*rate;cvar_t	*fov;cvar_t	*msg;cvar_t	*hand;cvar_t	*gender;cvar_t	*gender_auto; cvar_t	*cl_vwep; client_static_t	cls;client_state_t	cl; centity_t		cl_entities[MAX_EDICTS]; entity_state_t	cl_parse_entities[MAX_PARSE_ENTITIES]; 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; //====================================================================== voidCL_SetGameInput(k){	switch(cls.key_dest = k){	case key_game:		IN_Grabm(1);		if(Cvar_VariableValue("maxclients") == 1 && Com_ServerState())			Cvar_Set("paused", "0");		break;	default:		IN_Grabm(0);		if(Cvar_VariableValue("maxclients") == 1 && Com_ServerState())			Cvar_Set("paused", "1");		break;	}}  /*====================CL_WriteDemoMessage Dumps the current net message, prefixed by the length====================*/void CL_WriteDemoMessage (void){	int		len, swlen; 	// the first eight bytes are just packet sequencing stuff	len = net_message.cursize-8;	swlen = LittleLong(len);	fwrite (&swlen, 4, 1, cls.demofile);	fwrite (net_message.data+8,	len, 1, cls.demofile);}  /*====================CL_Stop_f stop recording a demo====================*/void CL_Stop_f (void){	int		len; 	if (!cls.demorecording)	{		Com_Printf ("Not recording a demo.\n");		return;	} // finish up	len = -1;	fwrite (&len, 4, 1, cls.demofile);	fclose (cls.demofile);	cls.demofile = NULL;	cls.demorecording = false;	Com_Printf ("Stopped demo.\n");} /*====================CL_Record_f record <demoname> Begins recording a demo from the current position====================*/void CL_Record_f (void){	char	name[MAX_OSPATH];	char	buf_data[MAX_MSGLEN];	sizebuf_t	buf;	int		i;	int		len;	entity_state_t	*ent;	entity_state_t	nullstate; 	if (Cmd_Argc() != 2)	{		Com_Printf ("record <demoname>\n");		return;	} 	if (cls.demorecording)	{		Com_Printf ("Already recording.\n");		return;	} 	if (cls.state != ca_active)	{		Com_Printf ("You must be in a level to record.\n");		return;	} 	//	// open the demo file	//	Com_sprintf (name, sizeof(name), "%s/demos/%s.dm2", FS_Gamedir(), Cmd_Argv(1)); 	Com_Printf ("recording to %s.\n", name);	FS_CreatePath (name);	cls.demofile = fopen (name, "wb");	if (!cls.demofile)	{		Com_Printf ("ERROR: couldn't open.\n");		return;	}	cls.demorecording = true; 	// don't start saving messages until a non-delta compressed message is received	cls.demowaiting = true; 	//	// write out messages to hold the startup information	//	SZ_Init (&buf, (uchar *)buf_data, sizeof(buf_data)); 	// send the serverdata	MSG_WriteByte (&buf, svc_serverdata);	MSG_WriteLong (&buf, PROTOCOL_VERSION);	MSG_WriteLong (&buf, 0x10000 + cl.servercount);	MSG_WriteByte (&buf, 1);	// demos are always attract loops	MSG_WriteString (&buf, cl.gamedir);	MSG_WriteShort (&buf, cl.playernum); 	MSG_WriteString (&buf, cl.configstrings[CS_NAME]); 	// configstrings	for (i=0 ; i<MAX_CONFIGSTRINGS ; i++)	{		if (cl.configstrings[i][0])		{			if (buf.cursize + strlen (cl.configstrings[i]) + 32 > buf.maxsize)			{	// write it out				len = LittleLong (buf.cursize);				fwrite (&len, 4, 1, cls.demofile);				fwrite (buf.data, buf.cursize, 1, cls.demofile);				buf.cursize = 0;			} 			MSG_WriteByte (&buf, svc_configstring);			MSG_WriteShort (&buf, i);			MSG_WriteString (&buf, cl.configstrings[i]);		} 	} 	// baselines	memset (&nullstate, 0, sizeof(nullstate));	for (i=0; i<MAX_EDICTS ; i++)	{		ent = &cl_entities[i].baseline;		if (!ent->modelindex)			continue; 		if (buf.cursize + 64 > buf.maxsize)		{	// write it out			len = LittleLong (buf.cursize);			fwrite (&len, 4, 1, cls.demofile);			fwrite (buf.data, buf.cursize, 1, cls.demofile);			buf.cursize = 0;		} 		MSG_WriteByte (&buf, svc_spawnbaseline);				MSG_WriteDeltaEntity (&nullstate, &cl_entities[i].baseline, &buf, true, true);	} 	MSG_WriteByte (&buf, svc_stufftext);	MSG_WriteString (&buf, "precache\n"); 	// write it to the demo file 	len = LittleLong (buf.cursize);	fwrite (&len, 4, 1, cls.demofile);	fwrite (buf.data, buf.cursize, 1, cls.demofile); 	// the rest of the demo file will be individual frames} /* adds the current command line as a clc_stringcmd to the client message. * things like godmode, noclip, etc, are commands directed to the server, so * when they are typed in at the console, they will need to be forwarded. */void Cmd_ForwardToServer (void){	char *cmd; 	cmd = Cmd_Argv(0);	if(cls.state <= ca_connected || *cmd == '-' || *cmd == '+'){		Com_Printf("Unknown command \"%s\"\n", cmd);		return;	} 	MSG_WriteByte(&cls.netchan.message, clc_stringcmd);	SZ_Print(&cls.netchan.message, cmd);	if(Cmd_Argc() > 1){		SZ_Print(&cls.netchan.message, " ");		SZ_Print(&cls.netchan.message, Cmd_Args());	}} voidCL_Setenv_f(void){	int i, l = 0, argc;	char name[1024], val[1024], *env; 	argc = Cmd_Argc(); 	if(argc > 2){		strncpy(name, Cmd_Argv(1), sizeof name);		for(i = 2; i < argc; i++){			strncpy(val+l, Cmd_Argv(i), sizeof(name) - l - 2);			val[sizeof(val)-2] = 0;			strcat(val, " ");			l = strlen(val);		}		putenv(name, val);	}else if(argc == 2){		env = getenv(Cmd_Argv(1));		if(env){			Com_Printf("%s=%s\n", Cmd_Argv(1), env);			free(env);		}else			Com_Printf("%s undefined\n", Cmd_Argv(1), env);	}} voidCL_ForwardToServer_f(void){	if(cls.state != ca_connected && cls.state != ca_active){		Com_Printf("Can't \"%s\", not connected\n", Cmd_Argv(0));		return;	}	/* don't forward the first argument */	if(Cmd_Argc() > 1){		MSG_WriteByte(&cls.netchan.message, clc_stringcmd);		SZ_Print(&cls.netchan.message, Cmd_Args());	}}  /*==================CL_Pause_f==================*/void CL_Pause_f (void){	// never pause in multiplayer	if (Cvar_VariableValue ("maxclients") > 1 || !Com_ServerState ())	{		Cvar_SetValue ("paused", 0);		return;	} 	Cvar_SetValue ("paused", !cl_paused->value);} /*==================CL_Quit_f==================*/void CL_Quit_f (void){	CL_Disconnect ();	Com_Quit ();} /*================CL_Drop Called after an ERR_DROP was thrown================*/void CL_Drop (void){	if (cls.state == ca_uninitialized)		return;	if (cls.state == ca_disconnected)		return; 	CL_Disconnect (); 	// drop loading plaque unless this is the initial game start	if (cls.disable_servercount != -1)		SCR_EndLoadingPlaque ();	// get rid of loading plaque}  /*=======================CL_SendConnectPacket We have gotten a challenge from the server, so try andconnect.======================*/void CL_SendConnectPacket (void){	netadr_t	adr;	int		port; 	if (!NET_StringToAdr (cls.servername, &adr))	{		Com_Printf ("Bad server address\n");		cls.connect_time = 0;		return;	}	if (adr.port == 0)		adr.port = BigShort (PORT_SERVER); 	port = Cvar_VariableValue ("qport");	userinfo_modified = false; 	Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",		PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() );} /*=================CL_CheckForResend Resend a connect message if the last one has timed out=================*/void CL_CheckForResend (void){	netadr_t	adr; 	// if the local server is running and we aren't	// then connect	if (cls.state == ca_disconnected && Com_ServerState() )	{		cls.state = ca_connecting;		strncpy (cls.servername, "localhost", sizeof(cls.servername)-1);		// we don't need a challenge on the localhost		CL_SendConnectPacket ();		return;//		cls.connect_time = -99999;	// CL_CheckForResend() will fire immediately	} 	// resend if we haven't gotten a reply yet	if (cls.state != ca_connecting)		return; 	if (cls.realtime - cls.connect_time < 3000)		return; 	if (!NET_StringToAdr (cls.servername, &adr))	{		Com_Printf ("Bad server address\n");		cls.state = ca_disconnected;		return;	}	if (adr.port == 0)		adr.port = BigShort (PORT_SERVER); 	cls.connect_time = cls.realtime;	// for retransmit requests 	Com_Printf ("Connecting to %s...\n", cls.servername); 	Netchan_OutOfBandPrint (NS_CLIENT, adr, "getchallenge\n");}  /*================CL_Connect_f ================*/void CL_Connect_f (void){	char	*server; 	if (Cmd_Argc() != 2)	{		Com_Printf ("usage: connect <server>\n");		return;		}		if (Com_ServerState ())	{	// if running a local server, kill it and reissue		SV_Shutdown (va("Server quit\n", msg), false);	}	else	{		CL_Disconnect ();	} 	server = Cmd_Argv (1); 	NET_Config (true);		// allow remote 	CL_Disconnect (); 	cls.state = ca_connecting;	strncpy (cls.servername, server, sizeof(cls.servername)-1);	cls.connect_time = -99999;	// CL_CheckForResend() will fire immediately}  /*=====================CL_Rcon_f   Send the rest of the command line over as  an unconnected command.=====================*/void CL_Rcon_f (void){	char	message[1024];

Lines 1–500 of 1774.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t