Exemple #1
0
/*
* Cvar_FixCheatVars
* 
* All cheat variables with be reset to default unless cheats are allowed
*/
void Cvar_FixCheatVars( void )
{
	struct trie_dump_s *dump;
	unsigned int i;
	cvar_flag_t flags = CVAR_CHEAT;

	if( Cvar_CheatsAllowed() )
		return;

	assert( cvar_trie );
	Trie_DumpIf( cvar_trie, "", TRIE_DUMP_VALUES, Cvar_HasFlags, &flags, &dump );
	for( i = 0; i < dump->size; ++i )
	{
		cvar_t *const var = (cvar_t *) dump->key_value_vector[i].value;
		Mem_ZoneFree( var->string );
		var->string = ZoneCopyString( var->dvalue );
		var->value = atof( var->string );
		var->integer = Q_rint( var->value );
	}
	Trie_FreeDump( dump );
}
Exemple #2
0
/*
* Key_SetBinding
*/
void Key_SetBinding( int keynum, const char *binding )
{
	if( keynum == -1 )
		return;

	// free old bindings
	if( keybindings[keynum] )
	{
		if( !Q_stricmp( keybindings[keynum], "toggleconsole" ) )
			consolebinded--;

		Mem_ZoneFree( keybindings[keynum] );
		keybindings[keynum] = NULL;
	}

	if( !binding )
		return;

	// allocate memory for new binding
	keybindings[keynum] = ZoneCopyString( binding );

	if( !Q_stricmp( keybindings[keynum], "toggleconsole" ) )
		consolebinded++;
}
Exemple #3
0
/*
* CL_ParseServerData
*/
static void CL_ParseServerData( msg_t *msg )
{
	const char *str, *gamedir;
	int i, sv_bitflags, numpure;
	int http_portnum;

	Com_DPrintf( "Serverdata packet received.\n" );

	// wipe the client_state_t struct

	CL_ClearState();
	CL_SetClientState( CA_CONNECTED );

	// parse protocol version number
	i = MSG_ReadLong( msg );

	if( i != APP_PROTOCOL_VERSION )
		Com_Error( ERR_DROP, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION );

	cl.servercount = MSG_ReadLong( msg );
	cl.snapFrameTime = (unsigned int)MSG_ReadShort( msg );

	// set extrapolation time to half snapshot time
	Cvar_ForceSet( "cl_extrapolationTime", va( "%i", (unsigned int)( cl.snapFrameTime * 0.5 ) ) );
	cl_extrapolationTime->modified = qfalse;

	// base game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty base game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid base game directory: %s", str );
	if( strcmp( FS_BaseGameDirectory(), str ) )
	{
		Com_Error( ERR_DROP, "Server has different base game directory (%s) than the client (%s)", str,
			FS_BaseGameDirectory() );
	}

	// game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid game directory: %s", str );
	gamedir = FS_GameDirectory();
	if( strcmp( str, gamedir ) )
	{
		// shutdown the cgame module first in case it is running for whatever reason
		// (happens on wswtv in lobby), otherwise precaches that are going to follow
		// will probably f**k up (like models trying to load before the world model)
		CL_GameModule_Shutdown();

		if( !FS_SetGameDirectory( str, qtrue ) )
			Com_Error( ERR_DROP, "Failed to load game directory set by server: %s", str );
		ML_Restart( qtrue );
	}

	// parse player entity number
	cl.playernum = MSG_ReadShort( msg );

	// get the full level name
	Q_strncpyz( cl.servermessage, MSG_ReadString( msg ), sizeof( cl.servermessage ) );

	sv_bitflags = MSG_ReadByte( msg );

	if( cls.demo.playing )
	{
		cls.reliable = ( sv_bitflags & SV_BITFLAGS_RELIABLE );
	}
	else
	{
		if( cls.reliable != ( ( sv_bitflags & SV_BITFLAGS_RELIABLE ) != 0 ) )
			Com_Error( ERR_DROP, "Server and client disagree about connection reliability" );
	}

	// builting HTTP server port
	if( cls.httpbaseurl ) {
		Mem_Free( cls.httpbaseurl );
		cls.httpbaseurl = NULL;
	}

	if( ( sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) {
		if( ( sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) {
			// read base upstream url
			cls.httpbaseurl = ZoneCopyString( MSG_ReadString( msg ) );
		}
		else {
			http_portnum = MSG_ReadShort( msg ) & 0xffff;
			cls.httpaddress = cls.serveraddress;
			if( cls.httpaddress.type == NA_IP6 ) {
				cls.httpaddress.address.ipv6.port = BigShort( http_portnum );
			} else {
				cls.httpaddress.address.ipv4.port = BigShort( http_portnum );
			}
			if( http_portnum ) {
				if( cls.httpaddress.type == NA_LOOPBACK ) {
					cls.httpbaseurl = ZoneCopyString( va( "http://localhost:%hu/", http_portnum ) );
				}
				else {
					cls.httpbaseurl = ZoneCopyString( va( "http://%s/", NET_AddressToString( &cls.httpaddress ) ) );
				}
			}
		}
	}

	// pure list

	// clean old, if necessary
	Com_FreePureList( &cls.purelist );

	// add new
	numpure = MSG_ReadShort( msg );
	while( numpure > 0 )
	{
		const char *pakname = MSG_ReadString( msg );
		const unsigned checksum = MSG_ReadLong( msg );

		Com_AddPakToPureList( &cls.purelist, pakname, checksum, NULL );

		numpure--;
	}

	//assert( numpure == 0 );

	// get the configstrings request
	CL_AddReliableCommand( va( "configstrings %i 0", cl.servercount ) );

	cls.sv_pure = ( sv_bitflags & SV_BITFLAGS_PURE ) != 0;
	cls.sv_tv = ( sv_bitflags & SV_BITFLAGS_TVSERVER ) != 0;

#ifdef PURE_CHEAT
	cls.sv_pure = qfalse;
#endif

	// separate the printfs so the server message can have a color
	Com_Printf( S_COLOR_WHITE "\n" "=====================================\n" );
	Com_Printf( S_COLOR_WHITE "%s\n\n", cl.servermessage );
}
Exemple #4
0
/*
* CL_InitDownload_f
* 
* Hanldles server's initdownload message, starts web or server download if possible
*/
 static void CL_InitDownload_f( void )
{
	const char *filename;
	const char *url;
	int size, alloc_size;
	unsigned checksum;
	qboolean allow_localhttpdownload;
	download_list_t	*dl;
	// ignore download commands coming from demo files
	if( cls.demo.playing )		
		return;

	// read the data
	filename = Cmd_Argv( 1 );
	size = atoi( Cmd_Argv( 2 ) );
	checksum = strtoul( Cmd_Argv( 3 ), NULL, 10 );
	allow_localhttpdownload = ( atoi( Cmd_Argv( 4 ) ) != 0 ) && cls.httpbaseurl != NULL;
	url = Cmd_Argv( 5 );

	if( !cls.download.requestname )
	{
		Com_Printf( "Got init download message without request\n" );
		return;
	}

	if( cls.download.filenum || cls.download.web )
	{
		Com_Printf( "Got init download message while already downloading\n" );
		return;
	}

	if( size == -1 )
	{
		// means that download was refused
		Com_Printf( "Server refused download request: %s\n", url ); // if it's refused, url field holds the reason
		CL_DownloadDone();
		return;
	}

	if( size <= 0 )
	{
		Com_Printf( "Server gave invalid size, not downloading\n" );
		CL_DownloadDone();
		return;
	}

	if( checksum == 0 )
	{
		Com_Printf( "Server didn't provide checksum, not downloading\n" );
		CL_DownloadDone();
		return;
	}

	if( !COM_ValidateRelativeFilename( filename ) )
	{
		Com_Printf( "Not downloading, invalid filename: %s\n", filename );
		CL_DownloadDone();
		return;
	}

	if( FS_CheckPakExtension( filename ) && !cls.download.requestpak )
	{
		Com_Printf( "Got a pak file when requesting normal one, not downloading\n" );
		CL_DownloadDone();
		return;
	}

	if( !FS_CheckPakExtension( filename ) && cls.download.requestpak )
	{
		Com_Printf( "Got a non pak file when requesting pak, not downloading\n" );
		CL_DownloadDone();
		return;
	}

	if( !strchr( filename, '/' ) )
	{
		Com_Printf( "Refusing to download file with no gamedir: %s\n", filename );
		CL_DownloadDone();
		return;
	}

	// check that it is in game or basegame dir
	if( strlen( filename ) < strlen( FS_GameDirectory() )+1 ||
		strncmp( filename, FS_GameDirectory(), strlen( FS_GameDirectory() ) ) ||
		filename[strlen( FS_GameDirectory() )] != '/' )
	{
		if( strlen( filename ) < strlen( FS_BaseGameDirectory() )+1 ||
			strncmp( filename, FS_BaseGameDirectory(), strlen( FS_BaseGameDirectory() ) ) ||
			filename[strlen( FS_BaseGameDirectory() )] != '/' )
		{
			Com_Printf( "Can't download, invalid game directory: %s\n", filename );
			CL_DownloadDone();
			return;
		}
	}

	if( FS_CheckPakExtension( filename ) )
	{
		if( strchr( strchr( filename, '/' ) + 1, '/' ) )
		{
			Com_Printf( "Refusing to download pack file to subdirectory: %s\n", filename );
			CL_DownloadDone();
			return;
		}

		if( !Q_strnicmp( COM_FileBase( filename ), "modules", strlen( "modules" ) ) )
		{
			if( !CL_CanDownloadModules() )
			{
				CL_DownloadDone();
				return;
			}
		}

		if( FS_FOpenBaseFile( filename, NULL, FS_READ ) != -1 )
		{
			Com_Printf( "Can't download, file already exists: %s\n", filename );
			CL_DownloadDone();
			return;
		}
	}
	else
	{
		if( strcmp( cls.download.requestname, strchr( filename, '/' ) + 1 ) )
		{
			Com_Printf( "Can't download, got different file than requested: %s\n", filename );
			CL_DownloadDone();
			return;
		}
	}

	if( cls.download.requestnext )
	{
		dl = cls.download.list;
		while( dl != NULL )
		{
			if( !Q_stricmp( dl->filename, filename ) )
			{
				Com_Printf( "Skipping, already tried downloading: %s\n", filename );
				CL_DownloadDone();
				return;
			}
			dl = dl->next;
		}
	}

	cls.download.name = ZoneCopyString( filename );

	alloc_size = strlen( filename ) + strlen( ".tmp" ) + 1;
	cls.download.tempname = Mem_ZoneMalloc( alloc_size );
	Q_snprintfz( cls.download.tempname, alloc_size, "%s.tmp", filename );

	cls.download.web = qfalse;
	cls.download.cancelled = qfalse;
	cls.download.disconnect = qfalse;
	cls.download.size = size;
	cls.download.checksum = checksum;
	cls.download.percent = 0;
	cls.download.timeout = 0;
	cls.download.retries = 0;
	cls.download.timestart = Sys_Milliseconds();
	cls.download.offset = 0;
	cls.download.baseoffset = 0;
	cls.download.pending_reconnect = qfalse;

	Cvar_ForceSet( "cl_download_name", COM_FileBase( cls.download.name ) );
	Cvar_ForceSet( "cl_download_percent", "0" );

	if( cls.download.requestnext )
	{
		dl = Mem_ZoneMalloc( sizeof( download_list_t ) );
		dl->filename = ZoneCopyString( cls.download.name );
		dl->next = cls.download.list;
		cls.download.list = dl;
	}

	if( cl_downloads_from_web->integer && allow_localhttpdownload && url && url[0] != 0 ) {
		cls.download.web = qtrue;
		Com_Printf( "Web download: %s from %s%s\n", cls.download.tempname, cls.httpbaseurl, url );
	}
	else if( cl_downloads_from_web->integer && url && url[0] != 0 ) {
		cls.download.web = qtrue;
		Com_Printf( "Web download: %s from %s\n", cls.download.tempname, url );
	}
	else {
		Com_Printf( "Server download: %s\n", cls.download.tempname );
	}

	cls.download.baseoffset = cls.download.offset = FS_FOpenBaseFile( cls.download.tempname, &cls.download.filenum, FS_APPEND );
	if( !cls.download.filenum )
	{
		Com_Printf( "Can't download, couldn't open %s for writing\n", cls.download.tempname );

		Mem_ZoneFree( cls.download.name );
		cls.download.name = NULL;
		Mem_ZoneFree( cls.download.tempname );
		cls.download.tempname = NULL;

		cls.download.filenum = 0;
		cls.download.offset = 0;
		cls.download.size = 0;
		CL_DownloadDone();
		return;
	}

	if( cls.download.web ) {
		char *referer, *fullurl;
		const char *headers[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };

		alloc_size = strlen( APP_URI_SCHEME ) + strlen( NET_AddressToString( &cls.serveraddress ) ) + 1;
		referer = Mem_ZoneMalloc( alloc_size );
		Q_snprintfz( referer, alloc_size, APP_URI_SCHEME "%s", NET_AddressToString( &cls.serveraddress ) );
		Q_strlwr( referer );

		if( allow_localhttpdownload ) {
			alloc_size = strlen( cls.httpbaseurl ) + 1 + strlen( url ) + 1;
			fullurl = Mem_ZoneMalloc( alloc_size );
			Q_snprintfz( fullurl, alloc_size, "%s/%s", cls.httpbaseurl, url );
		}
		else {
			size_t url_len = strlen( url );
			alloc_size = url_len + 1 + strlen( filename ) * 3 + 1;
			fullurl = Mem_ZoneMalloc( alloc_size );
			Q_snprintfz( fullurl, alloc_size, "%s/", url );
			Q_urlencode_unsafechars( filename, fullurl + url_len + 1, alloc_size - url_len - 1 );
		}

		headers[0] = "Referer";
		headers[1] = referer;

		CL_AddSessionHttpRequestHeaders( fullurl, &headers[2] );

		CL_AsyncStreamRequest( fullurl, headers, cl_downloads_from_web_timeout->integer / 100, cls.download.offset, 
			CL_WebDownloadReadCb, CL_WebDownloadDoneCb, NULL, NULL, qfalse );

		Mem_ZoneFree( fullurl );
		Mem_ZoneFree( referer );
		return;
	}

	// have to use Sys_Milliseconds because cls.realtime might be old from Web_Get
	cls.download.timeout = Sys_Milliseconds() + 3000;
	cls.download.retries = 0;

	CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, cls.download.offset ) );
}
Exemple #5
0
/*
* Cvar_Get
* Creates the variable if it doesn't exist.
* If the variable already exists, the value will not be set
* The flags will be or'ed and default value overwritten in if the variable exists.
*/
cvar_t *Cvar_Get( const char *var_name, const char *var_value, cvar_flag_t flags )
{
	cvar_t *var;

	if( !var_name || !var_name[0] )
		return NULL;

	if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) || Cvar_FlagIsSet( flags, CVAR_SERVERINFO ) )
	{
		if( !Cvar_InfoValidate( var_name, qtrue ) )
		{
			Com_Printf( "invalid info cvar name\n" );
			return NULL;
		}
	}

	assert( cvar_trie );
	Trie_Find( cvar_trie, var_name, TRIE_EXACT_MATCH, (void **)&var );

	if( var )
	{
		assert( var_value );
		if( !var->dvalue || strcmp( var->dvalue, var_value ) )
		{
			if( var->dvalue )
				Mem_ZoneFree( var->dvalue ); // free the old default value string
			var->dvalue = ZoneCopyString( (char *) var_value );
		}
#ifdef PUBLIC_BUILD
		if( Cvar_FlagIsSet( flags, CVAR_READONLY ) || Cvar_FlagIsSet( flags, CVAR_DEVELOPER ) )
		{
#else
		if( Cvar_FlagIsSet( flags, CVAR_READONLY ) )
		{
#endif
			if( !var->string || strcmp( var->string, var_value ) )
			{
				if( var->string )
					Mem_ZoneFree( var->string );
				var->string = ZoneCopyString( (char *) var_value );
				var->value = atof( var->string );
				var->integer = Q_rint( var->value );
			}
			var->flags = flags;
		}

		if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) && !Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) )
			userinfo_modified = qtrue; // transmit at next oportunity

		Cvar_FlagSet( &var->flags, flags );
		return var;
	}

	if( !var_value )
		return NULL;

	if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) || Cvar_FlagIsSet( flags, CVAR_SERVERINFO ) )
	{
		if( !Cvar_InfoValidate( var_value, qfalse ) )
		{
			Com_Printf( "invalid info cvar value\n" );
			return NULL;
		}
	}

	var = Mem_ZoneMalloc( (int)( sizeof( *var ) + strlen( var_name ) + 1 ) );
	var->name = (char *)( (qbyte *)var + sizeof( *var ) );
	strcpy( var->name, var_name );
	var->dvalue = ZoneCopyString( (char *) var_value );
	var->string = ZoneCopyString( (char *) var_value );
	Cvar_SetModified( var );
	var->value = atof( var->string );
	var->integer = Q_rint( var->value );
	var->flags = flags;

	Trie_Insert( cvar_trie, var_name, var );

	return var;
}

/*
* Cvar_Set2
*/
static cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
{
	cvar_t *var = Cvar_Find( var_name );

	if( !var )
	{
		// create it
		return Cvar_Get( var_name, value, 0 );
	}

	if( Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) || Cvar_FlagIsSet( var->flags, CVAR_SERVERINFO ) )
	{
		if( !Cvar_InfoValidate( value, qfalse ) )
		{
			Com_Printf( "invalid info cvar value\n" );
			return var;
		}
	}

	if( !force )
	{
#ifdef PUBLIC_BUILD
		if( Cvar_FlagIsSet( var->flags, CVAR_NOSET ) || Cvar_FlagIsSet( var->flags, CVAR_READONLY ) || Cvar_FlagIsSet( var->flags, CVAR_DEVELOPER ) )
		{
#else
		if( Cvar_FlagIsSet( var->flags, CVAR_NOSET ) || Cvar_FlagIsSet( var->flags, CVAR_READONLY ) )
		{
#endif
			Com_Printf( "%s is write protected.\n", var_name );
			return var;
		}

		if( Cvar_FlagIsSet( var->flags, CVAR_CHEAT ) && strcmp( value, var->dvalue ) )
		{
			if( !Cvar_CheatsAllowed() )
			{
				Com_Printf( "%s is cheat protected.\n", var_name );
				return var;
			}
		}

		if( Cvar_FlagIsSet( var->flags, CVAR_LATCH ) || Cvar_FlagIsSet( var->flags, CVAR_LATCH_VIDEO ) ||
			Cvar_FlagIsSet( var->flags, CVAR_LATCH_SOUND ) )
		{
			if( var->latched_string )
			{
				if( !strcmp( value, var->latched_string ) )
					return var;
				Mem_ZoneFree( var->latched_string );
			}
			else
			{
				if( !strcmp( value, var->string ) )
					return var;
			}

			if( Com_ServerState() )
			{
				Com_Printf( "%s will be changed upon restarting.\n", var->name );
				var->latched_string = ZoneCopyString( (char *) value );
			}
			else
			{
				if( Cvar_FlagIsSet( var->flags, CVAR_LATCH_VIDEO ) )
				{
					Com_Printf( "%s will be changed upon restarting video.\n", var->name );
					var->latched_string = ZoneCopyString( (char *) value );
				}
				else if( Cvar_FlagIsSet( var->flags, CVAR_LATCH_SOUND ) )
				{
					Com_Printf( "%s will be changed upon restarting sound.\n", var->name );
					var->latched_string = ZoneCopyString( (char *) value );
				}
				else
				{
					if( !strcmp( var->name, "fs_game" ) )
					{
						FS_SetGameDirectory( value, qfalse );
						return var;
					}
					Mem_ZoneFree( var->string ); // free the old value string
					var->string = ZoneCopyString( value );
					var->value = atof( var->string );
					var->integer = Q_rint( var->value );
					Cvar_SetModified( var );
				}
			}
			return var;
		}
	}
	else
	{
		if( var->latched_string )
		{
			Mem_ZoneFree( var->latched_string );
			var->latched_string = NULL;
		}
	}

	if( !strcmp( value, var->string ) )
		return var; // not changed

	Cvar_SetModified( var );

	if( Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) )
		userinfo_modified = qtrue; // transmit at next oportunity

	Mem_ZoneFree( var->string ); // free the old value string

	var->string = ZoneCopyString( (char *) value );
	var->value = atof( var->string );
	var->integer = Q_rint( var->value );

	return var;
}

/*
* Cvar_ForceSet
* Set the variable even if NOSET or LATCH
*/
cvar_t *Cvar_ForceSet( const char *var_name, const char *value )
{
	return Cvar_Set2( var_name, value, qtrue );
}

/*
* Cvar_Set
* Create the variable if it doesn't exist
*/
cvar_t *Cvar_Set( const char *var_name, const char *value )
{
	return Cvar_Set2( var_name, value, qfalse );
}

/*
* Cvar_FullSet
*/
cvar_t *Cvar_FullSet( const char *var_name, const char *value, cvar_flag_t flags, qboolean overwrite_flags )
{
	cvar_t *var;

	var = Cvar_Find( var_name );
	if( !var )
		return Cvar_Get( var_name, value, flags );

	if( overwrite_flags )
	{
		var->flags = flags;
	}
	else
	{
		Cvar_FlagSet( &var->flags, flags );
	}

	// if we overwrite the flags, we will also force the value
	return Cvar_Set2( var_name, value, overwrite_flags );
}