Пример #1
0
void Sys_FS_FindClose( void )
{
	assert( findbase );

	if( fdir )
	{
		closedir( fdir );
		fdir = NULL;
	}

	fdfd = -1;
	fdots = 0;

	Mem_TempFree( findbase );
	findbase = NULL;
	findbase_size = 0;
	findpattern = NULL;

	if( findpath )
	{
		Mem_TempFree( findpath );
		findpath = NULL;
		findpath_size = 0;
	}
}
Пример #2
0
// free the result from mm_parseResponse2
void MM_FreeResponse( char **argv )
{
	if( argv )
	{
		if( argv[0] )
			Mem_TempFree( argv[0] );
		Mem_TempFree( argv );
	}
}
Пример #3
0
/*
* R_Bloom_InitTextures
*/
static void R_Bloom_InitTextures( void )
{
	qbyte *data;
	int size;

	if( glConfig.ext.texture_non_power_of_two )
	{
		screen_texture_width = glState.width;
		screen_texture_height = glState.height;
	}
	else
	{
		// find closer power of 2 to screen size 
		for (screen_texture_width = 1;screen_texture_width < glState.width;screen_texture_width <<= 1);
		for (screen_texture_height = 1;screen_texture_height < glState.height;screen_texture_height <<= 1);
	}

	// disable blooms if we can't handle a texture of that size
	if( screen_texture_width > glConfig.maxTextureSize || screen_texture_height > glConfig.maxTextureSize )
	{
		screen_texture_width = screen_texture_height = 0;
		Cvar_ForceSet( "r_bloom", "0" );
		Com_Printf( S_COLOR_YELLOW "WARNING: 'R_InitBloomScreenTexture' too high resolution for light bloom, effect disabled\n" );
		return;
	}

	// init the screen texture
	size = screen_texture_width * screen_texture_height * 4;
	data = Mem_TempMalloc( size );
	memset( data, 255, size );
	r_bloomscreentexture = R_LoadPic( "***r_bloomscreentexture***", &data, screen_texture_width, screen_texture_height, IT_CLAMP|IT_NOMIPMAP|IT_NOCOMPRESS|IT_NOPICMIP, 3 );
	Mem_TempFree( data );

	// validate bloom size and init the bloom effect texture
	R_Bloom_InitEffectTexture();

	// if screensize is more than 2x the bloom effect texture, set up for stepped downsampling
	r_bloomdownsamplingtexture = NULL;
	r_screendownsamplingtexture_size = 0;

	if( (glState.width > (BLOOM_SIZE * 2) || glState.height > (BLOOM_SIZE * 2)) && !r_bloom_fast_sample->integer )
	{
		r_screendownsamplingtexture_size = (int)( BLOOM_SIZE * 2 );
		data = Mem_TempMalloc( r_screendownsamplingtexture_size * r_screendownsamplingtexture_size * 4 );
		memset( data, 0, r_screendownsamplingtexture_size * r_screendownsamplingtexture_size * 4 );
		r_bloomdownsamplingtexture = R_LoadPic( "***r_bloomdownsamplingtexture***", &data, r_screendownsamplingtexture_size, r_screendownsamplingtexture_size, IT_CLAMP|IT_NOMIPMAP|IT_NOCOMPRESS|IT_NOPICMIP, 3 );
		Mem_TempFree( data );
	}

	// init the screen backup texture
	if( r_screendownsamplingtexture_size )
		R_Bloom_InitBackUpTexture( r_screendownsamplingtexture_size, r_screendownsamplingtexture_size );
	else
		R_Bloom_InitBackUpTexture( BLOOM_SIZE, BLOOM_SIZE );
}
Пример #4
0
/*
* Con_Dump_f
*
* Save the console contents out to a file
*/
static void Con_Dump_f( void )
{
    int file;
    size_t buffer_size;
    char *buffer;
    size_t name_size;
    char *name;
    const char *newline = "\r\n";

    if( !con_initialized )
        return;

    if( Cmd_Argc() != 2 )
    {
        Com_Printf( "usage: condump <filename>\n" );
        return;
    }

    name_size = sizeof( char ) * ( strlen( Cmd_Argv( 1 ) ) + strlen( ".txt" ) + 1 );
    name = Mem_TempMalloc( name_size );

    Q_strncpyz( name, Cmd_Argv( 1 ), name_size );
    COM_DefaultExtension( name, ".txt", name_size );
    COM_SanitizeFilePath( name );

    if( !COM_ValidateRelativeFilename( name ) )
    {
        Com_Printf( "Invalid filename.\n" );
        Mem_TempFree( name );
        return;
    }

    if( FS_FOpenFile( name, &file, FS_WRITE ) == -1 )
    {
        Com_Printf( "Couldn't open: %s\n", name );
        Mem_TempFree( name );
        return;
    }

    buffer_size = Con_BufferText( NULL, newline ) + 1;
    buffer = Mem_TempMalloc( buffer_size );

    Con_BufferText( buffer, newline );

    FS_Write( buffer, buffer_size - 1, file );

    FS_FCloseFile( file );

    Mem_TempFree( buffer );

    Com_Printf( "Dumped console text: %s\n", name );
    Mem_TempFree( name );
}
Пример #5
0
/*
* R_Bloom_InitEffectTexture
*/
static void R_Bloom_InitEffectTexture( void )
{
	qbyte *data;
	int		limit;

	if( r_bloom_sample_size->integer < 32 )
		Cvar_ForceSet( "r_bloom_sample_size", "32" );

	// make sure bloom size doesn't have stupid values
	limit = min( r_bloom_sample_size->integer, min( screen_texture_width, screen_texture_height ) );

	if( glConfig.ext.texture_non_power_of_two )
		BLOOM_SIZE = limit;
	else	// make sure bloom size is a power of 2
		for( BLOOM_SIZE = 32; (BLOOM_SIZE<<1) <= limit; BLOOM_SIZE <<= 1 );

	if( BLOOM_SIZE != r_bloom_sample_size->integer )
		Cvar_ForceSet( "r_bloom_sample_size", va( "%i", BLOOM_SIZE ) );

	data = Mem_TempMalloc( BLOOM_SIZE * BLOOM_SIZE * 4 );
	memset( data, 0, BLOOM_SIZE * BLOOM_SIZE * 4 );

	r_bloomeffecttexture = R_LoadPic( "***r_bloomeffecttexture***", &data, BLOOM_SIZE, BLOOM_SIZE, IT_CLAMP|IT_NOMIPMAP|IT_NOCOMPRESS|IT_NOPICMIP, 3 );

	Mem_TempFree( data );
}
Пример #6
0
/*
* Com_LoadScriptLibrary
*/
static void *Com_LoadScriptLibrary( const char *basename, void *parms )
{
	size_t file_size;
	char *file;
	void *( *GetAngelwrapAPI )(void *);
	dllfunc_t funcs[2];

	if( script_library )
		Com_Error( ERR_FATAL, "Com_LoadScriptLibrary without Com_UnloadScriptLibrary" );

	file_size = strlen( LIB_DIRECTORY "/" ) + strlen( basename ) + 1 + strlen( ARCH ) + strlen( LIB_SUFFIX ) + 1;
	file = Mem_TempMalloc( file_size );
	Q_snprintfz( file, file_size, LIB_DIRECTORY "/%s_" ARCH LIB_SUFFIX, basename );

	funcs[0].name = "GetAngelwrapAPI";
	funcs[0].funcPointer = ( void ** )&GetAngelwrapAPI;
	funcs[1].name = NULL;
	script_library = Com_LoadLibrary( file, funcs );

	Mem_TempFree( file );

	if( script_library )
		return GetAngelwrapAPI( parms );
	return NULL;
}
Пример #7
0
/*
* ML_Update
*/
bool ML_Update( void )
{
	int i, len, total, newpaks;
	size_t size;
	char *map, *maps, *filename;

	newpaks = FS_Rescan();
	if( !newpaks )
		return false;

	total = FS_GetFileListExt( "maps", ".bsp", NULL, &size, 0, 0 );
	if( size )
	{
		maps = ( char* )Mem_TempMalloc( size );
		FS_GetFileList( "maps", ".bsp", maps, size, 0, 0 );
		for( i = 0, len = 0; i < total; i++ )
		{
			map = maps + len;
			len += strlen( map ) + 1;

			filename = ( char * )COM_FileBase( map );
			COM_StripExtension( filename );

			// don't check for existance of each file itself, as we've just got the fresh list
			if( !ML_FilenameExistsExt( filename, true ) )
				ML_AddMap( filename, MLIST_UNKNOWN_MAPNAME );
		}
		Mem_TempFree( maps );
	}

	return true;
}
Пример #8
0
// callback for scandir
int evdev_filter( const struct dirent *de )
{
	char *filename;
	int fd;

	// check that we have character file
	if( de->d_type != DT_CHR )
		return 0;

	filename = Mem_TempMalloc( strlen( EVDEV_DIR ) + strlen( de->d_name ) + 1 );
	strcpy( filename, EVDEV_DIR );
	strcat( filename, de->d_name );

	// open the file and see if we have a mouse
	fd = open( filename, O_RDONLY );
	Mem_TempFree( filename );
	if( fd != -1 )
	{
		if( evdev_ismouse( fd ) )
		{
			close( fd );
			return 1;
		}

		close( fd );
	}

	return 0;
}
Пример #9
0
/*
* CL_ReadServerCache
*/
void CL_ReadServerCache( void )
{
	int filelen, filehandle;
	qbyte *buf = NULL;
	char *ptr, *token;
	netadr_t adr;
	char adrString[64];
	qboolean favorite = qfalse;

	filelen = FS_FOpenFile( SERVERSFILE, &filehandle, FS_READ );
	if( !filehandle || filelen < 1 )
	{
		FS_FCloseFile( filehandle );
	}
	else
	{
		buf = Mem_TempMalloc( filelen + 1 );
		filelen = FS_Read( buf, filelen, filehandle );
		FS_FCloseFile( filehandle );
	}

	if( !buf )
		return;

	ptr = ( char * )buf;
	while( ptr )
	{
		token = COM_ParseExt( &ptr, qtrue );
		if( !token[0] )
			break;

		if( !Q_stricmp( token, "master" ) )
		{
			favorite = qfalse;
			continue;
		}

		if( !Q_stricmp( token, "favorites" ) )
		{
			favorite = qtrue;
			continue;
		}

		if( NET_StringToAddress( token, &adr ) )
		{
			Q_strncpyz( adrString, token, sizeof( adrString ) );
			token = COM_ParseExt( &ptr, qfalse );
			if( !token[0] )
				continue;

			if( favorite )
				CL_AddServerToList( &favoritesList, adrString, (unsigned int)atoi( token ) );
			else
				CL_AddServerToList( &masterList, adrString, (unsigned int)atoi( token ) );
		}
	}

	Mem_TempFree( buf );
}
Пример #10
0
/*
* TV_GenericConnect_f
*/
static void TV_GenericConnect_f( socket_type_t socket )
{
	netadr_t serveraddress;
	char *servername, *password, *name;
	upstream_t *upstream;
	unsigned int delay;

	if( Cmd_Argc() < 2 )
	{
		Com_Printf( "Usage: %s <server> [password] [name] [delay]\n", Cmd_Argv( 0 ) );
		return;
	}

	if( !NET_StringToAddress( Cmd_Argv( 1 ), &serveraddress ) )
	{
		Com_Printf( "Bad server address: %s\n", Cmd_Argv( 1 ) );
		return;
	}

	servername = TempCopyString( Cmd_Argv( 1 ) );
	password = ( Cmd_Argc() >= 3 ? TempCopyString( Cmd_Argv( 2 ) ) : NULL );
	name = ( Cmd_Argc() >= 4 ? Cmd_Argv( 3 ) : "" );
	delay = ( Cmd_Argc() >= 5 ? (unsigned)atoi( Cmd_Argv( 4 ) )*1000 : RELAY_GLOBAL_DELAY );

	if( TV_UpstreamForText( servername, &upstream ) )
	{
		if( upstream->state >= CA_CONNECTED && upstream->relay.delay == delay
			&& upstream->socket && upstream->socket->type == socket )
		{
			Com_Printf( "Already connected to %s\n", servername );
			goto exit;
		}

		TV_Upstream_Shutdown( upstream, "Disconnected by adminstrator" );
		upstream = NULL;
	}

	upstream = TV_Upstream_New( servername, name, delay );
	assert( upstream );
	TV_Upstream_Connect( upstream, servername, password, socket, &serveraddress );

exit:
	Mem_TempFree( servername );
	if( password )
		Mem_TempFree( password );
}
Пример #11
0
/*
* TV_Upstream_StartDemo
*/
void TV_Upstream_StartDemo( upstream_t *upstream, const char *demoname, qboolean randomize )
{
	char *name, *filepath;
	int tempdemofilehandle, tempdemofilelen;

	name = filepath = NULL;
	tempdemofilehandle = 0;
	tempdemofilelen = -1;

	TV_Upstream_NextDemo( demoname, upstream->demo.filename, randomize, &name, &filepath );

	if( filepath )
	{
		if( COM_ValidateRelativeFilename( filepath ) )
			tempdemofilelen = FS_FOpenFile( filepath, &tempdemofilehandle, FS_READ|SNAP_DEMO_GZ );
	}

	TV_Upstream_StopDemo( upstream );

	if( name )
		Com_Printf( "Starting demo from %s\n", filepath );

	upstream->demo.playing = qtrue;
	upstream->demo.filename = name ? TV_Upstream_CopyString( upstream, name ) : NULL;
	upstream->demo.filehandle = tempdemofilehandle;
	upstream->demo.filelen = tempdemofilelen;
	upstream->demo.random = randomize;
	upstream->state = CA_HANDSHAKE;
	upstream->reliable = qfalse;

	upstream->servername = TV_Upstream_CopyString( upstream, demoname );	// can be demo filename/pattern or demolist filename
	upstream->rejected = qfalse;
	upstream->lastPacketReceivedTime = tvs.realtime;	// reset the timeout limit
	upstream->multiview = qfalse;
	upstream->precacheDone = qfalse;

	if( name )
		Mem_TempFree( name );
	if( filepath )
		Mem_TempFree( filepath );
}
Пример #12
0
/*
* CL_SoundModule_StartLocalSound
*/
void CL_SoundModule_StartLocalSound( const char *name )
{
	assert( name );

	if( se )
	{
		char *finalname;

		finalname = CL_SetSoundExtension( name );
		se->StartLocalSound( finalname );
		Mem_TempFree( finalname );
	}
}
Пример #13
0
/*
* CL_SoundModule_Load
* 
* Helper function to try loading sound module with certain name
*/
static bool CL_SoundModule_Load( const char *name, sound_import_t *import, bool verbose )
{
	int apiversion;
	size_t file_size;
	char *file;
	void *( *GetSoundAPI )(void *);
	dllfunc_t funcs[2];

	if( verbose )
		Com_Printf( "Loading sound module: %s\n", name );

	file_size = strlen( LIB_DIRECTORY "/" LIB_PREFIX "snd_" ) + strlen( name ) + 1 + strlen( ARCH ) + strlen( LIB_SUFFIX ) + 1;
	file = Mem_TempMalloc( file_size );
	Q_snprintfz( file, file_size, LIB_DIRECTORY "/" LIB_PREFIX "snd_%s_" ARCH LIB_SUFFIX, name );

	funcs[0].name = "GetSoundAPI";
	funcs[0].funcPointer = ( void ** )&GetSoundAPI;
	funcs[1].name = NULL;
	sound_library = Com_LoadLibrary( file, funcs );

	Mem_TempFree( file );

	if( !sound_library )
	{
		Com_Printf( "Loading %s failed\n", name );
		return false;
	}

	s_loaded = true;

	se = ( sound_export_t * )GetSoundAPI( import );
	apiversion = se->API();
	if( apiversion != SOUND_API_VERSION )
	{
		CL_SoundModule_Shutdown( verbose );
		Com_Printf( "Wrong module version for %s: %i, not %i\n", name, apiversion, SOUND_API_VERSION );
		return false;
	}

	if( !se->Init( VID_GetWindowHandle(), MAX_EDICTS, verbose ) )
	{
		CL_SoundModule_Shutdown( verbose );
		Com_Printf( "Initialization of %s failed\n", name );
		return false;
	}

	if( verbose )
		Com_Printf( "Initialization of %s succesful\n", name );

	return true;
}
Пример #14
0
/*
* SV_ReloadPureList
*/
static void SV_ReloadPureList( void ) {
	char **paks;
	int i, numpaks;

	Com_FreePureList( &svs.purelist );

	// game modules
	if( sv_pure_forcemodulepk3->string[0] ) {
		if( Q_strnicmp( COM_FileBase( sv_pure_forcemodulepk3->string ), "modules", strlen( "modules" ) ) ||
			!FS_IsPakValid( sv_pure_forcemodulepk3->string, NULL ) ) {
			Com_Printf( "Warning: Invalid value for sv_pure_forcemodulepk3, disabling\n" );
			Cvar_ForceSet( "sv_pure_forcemodulepk3", "" );
		} else {
			SV_AddPurePak( sv_pure_forcemodulepk3->string );
		}
	}

	if( !sv_pure_forcemodulepk3->string[0] ) {
		char *libname;
		int libname_size;

		libname_size = strlen( LIB_PREFIX ) + 5 + strlen( ARCH ) + strlen( LIB_SUFFIX ) + 1;
		libname = Mem_TempMalloc( libname_size );
		Q_snprintfz( libname, libname_size, LIB_PREFIX "game_" ARCH LIB_SUFFIX );

		if( !FS_PakNameForFile( libname ) ) {
			if( sv_pure->integer ) {
				Com_Printf( "Warning: Game module not in pk3, disabling pure mode\n" );
				Com_Printf( "sv_pure_forcemodulepk3 can be used to force the pure system to use a different module\n" );
				Cvar_ForceSet( "sv_pure", "0" );
			}
		} else {
			SV_AddPureFile( libname );
		}

		Mem_TempFree( libname );
		libname = NULL;
	}

	// *pure.(pk3|pak)
	paks = NULL;
	numpaks = FS_GetExplicitPurePakList( &paks );
	if( numpaks ) {
		for( i = 0; i < numpaks; i++ ) {
			SV_AddPurePak( paks[i] );
			Mem_ZoneFree( paks[i] );
		}
		Mem_ZoneFree( paks );
	}
}
Пример #15
0
/*
* CL_SoundModule_StartBackgroundTrack
*/
void CL_SoundModule_StartBackgroundTrack( const char *intro, const char *loop )
{
	assert( intro );

	if( se )
	{
		char *finalintro, *finalloop;

		finalintro = CL_SetSoundExtension( intro );
		if( loop )
		{
			finalloop = CL_SetSoundExtension( loop );
		}
		else
		{
			finalloop = NULL;
		}
		se->StartBackgroundTrack( finalintro, finalloop );
		Mem_TempFree( finalintro );
		if( finalloop )
			Mem_TempFree( finalloop );
	}
}
Пример #16
0
/*
* R_Bloom_InitBackUpTexture
*/
static void R_Bloom_InitBackUpTexture( int width, int height )
{
	qbyte *data;

	data = Mem_TempMalloc( width * height * 4 );
	memset( data, 0, width * height * 4 );

	r_screenbackuptexture_width = width;
	r_screenbackuptexture_height = height;

	r_bloombackuptexture = R_LoadPic( "***r_bloombackuptexture***", &data, width, height, IT_CLAMP|IT_NOMIPMAP|IT_NOCOMPRESS|IT_NOPICMIP, 3 );

	Mem_TempFree( data );
}
Пример #17
0
/*
* Sys_FS_FindNext
*/
const char *Sys_FS_FindNext( unsigned musthave, unsigned canhave )
{
	struct dirent64 *d;

	assert( fdir );
	assert( findbase && findpattern );

	if( !fdir )
		return NULL;

	while( ( d = readdir64( fdir ) ) != NULL )
	{
		if( !CompareAttributes( d, findbase, musthave, canhave ) )
			continue;

		if( fdots > 0 )
		{
			// . and .. never match
			const char *base = COM_FileBase( d->d_name );
			if( !strcmp( base, "." ) || !strcmp( base, ".." ) )
			{
				fdots--;
				continue;
			}
		}

		if( !*findpattern || Com_GlobMatch( findpattern, d->d_name, 0 ) )
		{
			const char *dname = d->d_name;
			size_t dname_len = strlen( dname );
			size_t size = sizeof( char ) * ( findbase_size + dname_len + 1 + 1 );
			if( findpath_size < size )
			{
				if( findpath )
					Mem_TempFree( findpath );
				findpath_size = size * 2; // extra size to reduce reallocs
				findpath = Mem_TempMalloc( findpath_size );
			}

			Q_snprintfz( findpath, findpath_size, "%s/%s%s", findbase, dname,
				dname[dname_len-1] != '/' && FS_DirentIsDir( d, findbase ) ? "/" : "" );
			if( CompareAttributesForPath( d, findpath, musthave, canhave ) )
				return findpath;
		}
	}

	return NULL;
}
Пример #18
0
static int wswcurl_debug_callback( CURL *curl, curl_infotype infotype, char *buf, size_t buf_size, void *userp ) {
	char *temp;

	if( infotype != CURLINFO_TEXT ) {
		return 0;
	}

	temp = Mem_TempMalloc( buf_size + 1 );
	memcpy( temp, buf, buf_size );

	Com_Printf( "%s\n", temp );

	Mem_TempFree( temp );

	return 0;
}
Пример #19
0
int evdev_scandevices( void )
{
	struct dirent **de;	// list of pointers
	char *filename;
	char deviceName[256];
	int n;

	if( m_evdev_fds )
	{
		free( m_evdev_fds );
		m_evdev_fds = 0;
	}
	m_evdev_num = 0;

	n = scandir( EVDEV_DIR, &de, evdev_filter, NULL );
	if( n > 0 )
	{
		m_evdev_fds = calloc( n, sizeof( *m_evdev_fds ) );
		m_evdev_num = n;

		while( n-- )
		{
			filename = Mem_TempMalloc( strlen( EVDEV_DIR ) + strlen( de[n]->d_name ) + 1 );
			strcpy( filename, EVDEV_DIR );
			strcat( filename, de[n]->d_name );

			m_evdev_fds[n] = open( filename, O_RDONLY | O_NONBLOCK );

			// some nice information about the device
			if( ioctl( m_evdev_fds[n], EVIOCGNAME(sizeof(deviceName)-1), deviceName) < 0 )
				deviceName[0] = '\0';

			Com_Printf( "Evdev: Found %s (%s)\n", deviceName, filename );

			Mem_TempFree( filename );
			free( de[n] );
		}

		free( de );
	}

	return m_evdev_num;
}
Пример #20
0
/*
* CL_SoundModule_RegisterSound
*/
struct sfx_s *CL_SoundModule_RegisterSound( const char *name )
{
	assert( name );

	if( se )
	{
		struct sfx_s *retval;
		char *finalname;

		finalname = CL_SetSoundExtension( name );
		retval = se->RegisterSound( finalname );
		Mem_TempFree( finalname );

		return retval;
	}
	else
	{
		return NULL;
	}
}
Пример #21
0
/*
* TV_Demo_f
*/
static void TV_Demo_f( void )
{
	char *servername, *name, *mode;
	upstream_t *upstream;
	unsigned int delay;
	qboolean randomize = qtrue;

	if( Cmd_Argc() < 2 )
	{
		Com_Printf( "Usage: %s <pattern|playlist> [name] [ordered|random] [delay]\n", Cmd_Argv( 0 ) );
		return;
	}

	servername = TempCopyString( Cmd_Argv( 1 ) );
	name = ( Cmd_Argc() >= 3 ? Cmd_Argv( 2 ) : "" );
	mode = ( Cmd_Argc() >= 4 ? Cmd_Argv( 3 ) : "" );
	delay = ( Cmd_Argc() >= 5 ? (unsigned)atoi( Cmd_Argv( 4 ) )*1000 : RELAY_MIN_DELAY );
	if( !Q_stricmp( mode, "ordered" ) )
		randomize = qfalse;

	if( TV_UpstreamForText( servername, &upstream ) )
	{
		if( upstream->state >= CA_CONNECTED && upstream->relay.delay == delay )
		{
			Com_Printf( "Already connected to %s\n", servername );
			goto exit;
		}

		TV_Upstream_Shutdown( upstream, "Disconnected by adminstrator" );
		upstream = NULL;
	}

	upstream = TV_Upstream_New( servername, name, delay );
	assert( upstream );
	TV_Upstream_StartDemo( upstream, servername, randomize );

exit:
	Mem_TempFree( servername );
}
Пример #22
0
/*
* TV_Upstream_IsAutoRecordable
*/
qboolean TV_Upstream_IsAutoRecordable( upstream_t *upstream )
{
	char *s, *t;
	static const char *seps = ";";
	qboolean match = qfalse;
	upstream_t *tupstream;

	assert( upstream );

	if( upstream->demo.playing )
		return qfalse;
	if( !Q_stricmp( tv_autorecord->string, "*" ) )
		return qtrue;

	// search for the given upstream in record list (semicolon separated)
	s = TempCopyString( tv_autorecord->string );

	t = strtok( s, seps );
	while( t != NULL )
	{
		qboolean res = TV_UpstreamForText( t, &tupstream );
		if( res && (tupstream == upstream) )
		{
			match = qtrue;
			break; // found a match
		}

		t = strtok( NULL, seps );
	}

	Mem_TempFree( s );
	if( match )
		return qtrue;

	return qfalse;
}
Пример #23
0
/*
* CM_LoadMap
* Loads in the map and all submodels
* 
*  for spawning a server with no map at all, call like this:
*  CM_LoadMap( "", qfalse, &checksum );	// no real map
*/
cmodel_t *CM_LoadMap( cmodel_state_t *cms, const char *name, qboolean clientload, unsigned *checksum )
{
	int length;
	unsigned *buf;
	char *header;
	const modelFormatDescr_t *descr;
	bspFormatDesc_t *bspFormat = NULL;

	assert( cms );
	assert( name && strlen( name ) < MAX_CONFIGSTRING_CHARS );
	assert( checksum );

	cms->map_clientload = clientload;

	if( !strcmp( cms->map_name, name ) && ( clientload || !Cvar_Value( "flushmap" ) ) )
	{
		*checksum = cms->checksum;

		if( !clientload )
		{
			memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) );
			CM_FloodAreaConnections( cms );
		}

		return cms->map_cmodels; // still have the right version
	}

	CM_Clear( cms );

	if( !name || !name[0] )
	{
		cms->numleafs = 1;
		cms->numcmodels = 2;
		*checksum = 0;
		return cms->map_cmodels;    // cinematic servers won't have anything at all
	}

	//
	// load the file
	//
	length = FS_LoadFile( name, ( void ** )&buf, NULL, 0 );
	if( !buf )
		Com_Error( ERR_DROP, "Couldn't load %s", name );

	cms->checksum = Com_MD5Digest32( ( const qbyte * )buf, length );
	*checksum = cms->checksum;

	// call the apropriate loader
	descr = Q_FindFormatDescriptor( cm_supportedformats, ( const qbyte * )buf, (const bspFormatDesc_t **)&bspFormat );
	if( !descr )
		Com_Error( ERR_DROP, "CM_LoadMap: unknown fileid for %s", name );

	if( !bspFormat )
		Com_Error( ERR_DROP, "CM_LoadMap: %s: unknown bsp format" );

	// copy header into temp variable to be saveed in a cvar
	header = Mem_TempMalloc( descr->headerLen + 1 );
	memcpy( header, buf, descr->headerLen );
	header[descr->headerLen] = '\0';

	// store map format description in cvars
	Cvar_ForceSet( "cm_mapHeader", header );
	Cvar_ForceSet( "cm_mapVersion", va( "%i", LittleLong( *((int *)((qbyte *)buf + descr->headerLen)) ) ) );

	Mem_TempFree( header );

	descr->loader( cms, NULL, buf, bspFormat );

	CM_InitBoxHull( cms );
	CM_InitOctagonHull( cms );

	if( cms->numareas )
	{
		cms->map_areas = Mem_Alloc( cms->mempool, cms->numareas * sizeof( *cms->map_areas ) );
		cms->map_areaportals = Mem_Alloc( cms->mempool, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) );

		memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) );
		CM_FloodAreaConnections( cms );
	}

	memset( cms->nullrow, 255, MAX_CM_LEAFS / 8 );

	Q_strncpyz( cms->map_name, name, sizeof( cms->map_name ) );

	return cms->map_cmodels;
}
Пример #24
0
/*
* ML_InitFromCache
* Fills map list array from cache, much faster
*/
static void ML_InitFromCache( void )
{
	int count, i, total, len;
	size_t size = 0;
	char *buffer, *chr, *current, *curend;
	char *temp, *maps, *map;
	mapdir_t *dir, *curmap, *prev;

	if( ml_initialized )
		return;

	total = FS_GetFileListExt( "maps", ".bsp", NULL, &size, 0, 0 );
	if( !total )
		return;

	// load maps from directory reading into a list
	maps = temp = ( char* )Mem_TempMalloc( size + sizeof( mapdir_t ) * total );
	temp += size;
	FS_GetFileList( "maps", ".bsp", maps, size, 0, 0 );
	len = 0;
	prev = NULL;
	dir = NULL;
	for( i = 0; i < total; i++ )
	{
		map = maps + len;
		len += strlen( map ) + 1;

		curmap = ( mapdir_t * )temp;
		temp += sizeof( mapdir_t );

		COM_StripExtension( map );

		if( !i )
			dir = curmap;
		else
		{
			prev->next = curmap;
			curmap->prev = prev;
		}

		curmap->filename = map;
		prev = curmap;
	}

	FS_LoadCacheFile( MLIST_CACHE, (void **)&buffer, NULL, 0 );
	if( !buffer )
	{
		Mem_TempFree( maps );
		return;
	}

	current = curend = buffer;
	count = 0;

	for( chr = buffer; *chr; chr++ )
	{
		// current character is a delimiter
		if( *chr == '\n' )
		{
			if( *(chr-1) == '\r' )
				*(chr-1) = '\0';	// clear the CR too
			*chr = '\0';			// clear the LF

			// if we have got both params
			if( !( ++count & 1 ) )
			{
				// check if its in the maps directory
				for( curmap = dir; curmap; curmap = curmap->next )
				{
					if( !Q_stricmp( curmap->filename, current ) )
					{
						if( curmap->prev )
							curmap->prev->next = curmap->next;
						else
							dir = curmap->next;

						if( curmap->next )
							curmap->next->prev = curmap->prev;
						break;
					}
				}

				// if we found it in the maps directory
				if( curmap )
				{
					COM_SanitizeFilePath( current );

					// well, if we've got a map with an unknown fullname, load it from map
					if( !strcmp( curend + 1, MLIST_UNKNOWN_MAPNAME ) )
						ML_AddMap( current, NULL );
					else
						ML_AddMap( current, curend + 1 );
				}
				current = chr + 1;
			}
			else
				curend = chr;
		}
	}

	// we've now loaded the mapcache, but there may be files which
	// have been added to maps directory, and the mapcache isnt aware
	// these will be left over in our directory list
	for( curmap = dir; curmap; curmap = curmap->next )
		ML_AddMap( curmap->filename, NULL );

	Mem_TempFree( maps );
	FS_FreeFile( buffer );
}
Пример #25
0
/*
* TV_Upstream_NextDemo
*/
void TV_Upstream_NextDemo( const char *demoname, const char *curdemo, qboolean randomize, char **name, char **filepath )
{
	int i, j, total;
	size_t bufsize, len, dir_size;
	char *file, *buf, **match, *dir;
	const char *extension, *pattern, *p;

	*name = *filepath = NULL;

	assert( demoname );
	assert( *demoname );

	buf = NULL;
	bufsize = 0;
	total = 0;

	// check if user specified a demo pattern (e.g. "tutorials/*.wd10") or a demolist filename
	extension = COM_FileExtension( demoname );
	if( extension && !Q_stricmp( extension, APP_DEMO_EXTENSION_STR ) )
		pattern = demoname;
	else
		pattern = "";

	dir_size = strlen( "demos" ) + strlen( pattern ) + 1;
	dir = Mem_TempMalloc( dir_size );
	strcpy( dir, "demos" );

	if( *pattern )
	{
		// find first character that looks like a wildcard
		const char *last_slash = NULL;

		p = pattern;
		do
		{
			if( *p == '/' )
				last_slash = p;
			else if( *p == '?' || *p == '*' || *p == '[' )
				break;
		} while( *++p );

		// append the path part of wildcard to dir and shift the pattern
		if( last_slash )
		{
			Q_strncatz( dir, "/", dir_size );
			Q_strncatz( dir, pattern, strlen( dir ) + (last_slash - pattern) + 1 );
			pattern = last_slash + 1;
		}

		bufsize = 0;
		total = FS_GetFileListExt( dir, APP_DEMO_EXTENSION_STR, NULL, &bufsize, 0, 0 );
		if( !total )
			bufsize = 0;

		if( bufsize )
		{
			buf = Mem_TempMalloc( bufsize );
			FS_GetFileList( dir, APP_DEMO_EXTENSION_STR, buf, bufsize, 0, 0 );
		}
	}
	else
	{
		// load demolist file and pick next available demo
		int filehandle = 0, filelen = -1;

		// load list from file
		filelen = FS_FOpenFile( demoname, &filehandle, FS_READ );
		if( filehandle && filelen > 0 )
		{
			bufsize = (size_t)(filelen + 1);
			buf = Mem_TempMalloc( bufsize );
			FS_Read( buf, filelen, filehandle );
			FS_FCloseFile( filehandle );
		}

		// parse the list stripping CRLF characters
		if( buf )
		{
			p = strtok( buf, "\r\n" );
			if( p )
			{
				char *newbuf;
				size_t newbufsize;

				newbufsize = 0;
				newbuf = Mem_TempMalloc( bufsize );
				while( p != NULL )
				{
					total++;

					Q_strncpyz( newbuf + newbufsize, p, bufsize - newbufsize );
					newbufsize += strlen( p ) + 1;
					p = strtok( NULL, "\r\n" );
				}

				Mem_TempFree( buf );
				buf = newbuf;
			}
		}
	}

	if( buf )
	{
		int next;

		// get the list of demo files
		match = Mem_TempMalloc( total * sizeof( char * ) );
		total = 0;

		next = (randomize ? -1 : 0);
		for( len = 0; buf[len]; )
		{
			file = buf + len;
			len += strlen( file ) + 1;

			if( *pattern )
			{
				if( !Com_GlobMatch( pattern, file, qfalse ) )
					continue;
			}

			// avoid replays
			if( curdemo && !Q_stricmp( file, curdemo ) )
			{
				// if ordered, schedule the next map
				if( !randomize )
					next = total;
				continue;
			}

			match[total++] = file;
		}

		// pick a new random demo if possible or otherwise try the old one
		if( total )
		{
			if( next < 0 )
				next = rand() % total;

			// walk the list until we find an existing file
			// in case of pattern match, the check is not necessary though
			for( i = 0; i < total; i++ )
			{
				j = (i + next) % total;
				if( !*pattern )
				{
					extension = COM_FileExtension( match[j] );
					if( FS_FOpenFile( va( "demos/%s%s", match[j], 
							(extension ? "" : APP_DEMO_EXTENSION_STR) ), NULL, FS_READ ) == -1 )
						continue;
				}

				*name = TempCopyString( match[j] );
				break;
			}
		}

		// fallback to current demo
		if( !*name && curdemo )
			*name = TempCopyString( curdemo );

		Mem_TempFree( match );

		// append the dir to filename, sigh..
		if( *name )
		{
			size_t filepath_size;

			filepath_size = strlen( dir ) + strlen( "/" ) + strlen( *name ) + strlen( APP_DEMO_EXTENSION_STR ) + 1;
			*filepath = Mem_TempMalloc( filepath_size );
			strcpy( *filepath, dir );
			strcat( *filepath, "/" );
			strcat( *filepath, *name );
			COM_DefaultExtension( *filepath, APP_DEMO_EXTENSION_STR, filepath_size );
		}

		Mem_TempFree( buf );
	}

	Mem_TempFree( dir );
}
Пример #26
0
/*
* Com_Printf
* 
* Both client and server can use this, and it will output
* to the apropriate place.
*/
void Com_Printf( const char *format, ... )
{
	va_list	argptr;
	char msg[MAX_PRINTMSG];

	time_t timestamp;
	char timestamp_str[MAX_PRINTMSG];
	struct tm *timestampptr;
	timestamp = time( NULL );
	timestampptr = gmtime( &timestamp );
	strftime( timestamp_str, MAX_PRINTMSG, "%Y-%m-%dT%H:%M:%SZ ", timestampptr );

	va_start( argptr, format );
	Q_vsnprintfz( msg, sizeof( msg ), format, argptr );
	va_end( argptr );

	if( rd_target )
	{
		if( (int)( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) )
		{
			rd_flush( rd_target, rd_buffer, rd_extra );
			*rd_buffer = 0;
		}
		strcat( rd_buffer, msg );
		return;
	}

	QMutex_Lock( com_print_mutex );

	Con_Print( msg );

	// also echo to debugging console
	Sys_ConsoleOutput( msg );

	// logconsole
	if( logconsole && logconsole->modified )
	{
		logconsole->modified = qfalse;

		if( log_file )
		{
			FS_FCloseFile( log_file );
			log_file = 0;
		}

		if( logconsole->string && logconsole->string[0] )
		{
			size_t name_size;
			char *name;

			name_size = strlen( logconsole->string ) + strlen( ".log" ) + 1;
			name = ( char* )Mem_TempMalloc( name_size );
			Q_strncpyz( name, logconsole->string, name_size );
			COM_DefaultExtension( name, ".log", name_size );

			if( FS_FOpenFile( name, &log_file, ( logconsole_append && logconsole_append->integer ? FS_APPEND : FS_WRITE ) ) == -1 )
			{
				log_file = 0;
				Com_Printf( "Couldn't open: %s\n", name );
			}

			Mem_TempFree( name );
		}
	}

	if( log_file )
	{
		if( logconsole_timestamp && logconsole_timestamp->integer )
			FS_Printf( log_file, "%s", timestamp_str );
		FS_Printf( log_file, "%s", msg );
		if( logconsole_flush && logconsole_flush->integer )
			FS_Flush( log_file ); // force it to save every time
	}

	QMutex_Unlock( com_print_mutex );
}
Пример #27
0
/*
* SV_BeginDownload_f
* Responds to reliable download packet with reliable initdownload packet
*/
static void SV_BeginDownload_f( client_t *client )
{
	const char *requestname;
	const char *uploadname;
	size_t alloc_size;
	unsigned checksum;
	char *url;
	const char *errormsg = NULL;
	qboolean allow, requestpak;
	qboolean local_http = SV_Web_Running() && sv_uploads_http->integer != 0;

	requestpak = ( atoi( Cmd_Argv( 1 ) ) == 1 );
	requestname = Cmd_Argv( 2 );

	if( !requestname[0] || !COM_ValidateRelativeFilename( requestname ) )
	{
		SV_DenyDownload( client, "Invalid filename" );
		return;
	}

	if( !SV_FilenameForDownloadRequest( requestname, requestpak, &uploadname, &errormsg ) ) {
		assert( errormsg != NULL );
		SV_DenyDownload( client, errormsg );
		return;
	}

	if( FS_CheckPakExtension( uploadname ) )
	{
		allow = qfalse;

		// allow downloading paks from the pure list, if not spawned
		if( client->state < CS_SPAWNED )
		{
			purelist_t *purefile;

			purefile = svs.purelist;
			while( purefile )
			{
				if( !strcmp( uploadname, purefile->filename ) )
				{
					allow = qtrue;
					break;
				}
				purefile = purefile->next;
			}
		}

		// game module has a change to allow extra downloads
		if( !allow && !SV_GameAllowDownload( client, requestname, uploadname ) )
		{
			SV_DenyDownload( client, "Downloading of this file is not allowed" );
			return;
		}
	}
	else
	{
		if( !SV_GameAllowDownload( client, requestname, uploadname ) )
		{
			SV_DenyDownload( client, "Downloading of this file is not allowed" );
			return;
		}
	}

	// we will just overwrite old download, if any
	if( client->download.name )
	{
		if( client->download.data )
		{
			FS_FreeBaseFile( client->download.data );
			client->download.data = NULL;
		}

		Mem_ZoneFree( client->download.name );
		client->download.name = NULL;

		client->download.size = 0;
		client->download.timeout = 0;
	}

	client->download.size = FS_LoadBaseFile( uploadname, NULL, NULL, 0 );
	if( client->download.size == -1 )
	{
		Com_Printf( "Error getting size of %s for uploading\n", uploadname );
		client->download.size = 0;
		SV_DenyDownload( client, "Error getting file size" );
		return;
	}

	checksum = FS_ChecksumBaseFile( uploadname );
	client->download.timeout = svs.realtime + 1000 * 60 * 60; // this is web download timeout

	alloc_size = sizeof( char ) * ( strlen( uploadname ) + 1 );
	client->download.name = Mem_ZoneMalloc( alloc_size );
	Q_strncpyz( client->download.name, uploadname, alloc_size );

	Com_Printf( "Offering %s to %s\n", client->download.name, client->name );

	if( FS_CheckPakExtension( uploadname ) && ( local_http || sv_uploads_baseurl->string[0] != 0 ) )
	{
		// .pk3 and .pak download from the web
		if( local_http )
		{
			url = TempCopyString( va( "files/%s", uploadname ) );
		}
		else
		{
			alloc_size = sizeof( char ) * ( strlen( sv_uploads_baseurl->string ) + 1 );
			url = Mem_TempMalloc( alloc_size );
			Q_snprintfz( url, alloc_size, "%s/", sv_uploads_baseurl->string );
		}
	}
	else if( SV_IsDemoDownloadRequest( requestname ) && ( local_http || sv_uploads_demos_baseurl->string[0] != 0 ) )
	{
		// demo file download from the web
		if( local_http )
		{
			url = TempCopyString( va( "files/%s", uploadname ) );
		}
		else
		{
			alloc_size = sizeof( char ) * ( strlen( sv_uploads_demos_baseurl->string ) + 1 );
			url = Mem_TempMalloc( alloc_size );
			Q_snprintfz( url, alloc_size, "%s/", sv_uploads_demos_baseurl->string );
		}
	}
	else
	{
		url = NULL;
	}

	// start the download
	SV_InitClientMessage( client, &tmpMessage, NULL, 0 );
	SV_SendServerCommand( client, "initdownload \"%s\" %i %u %i \"%s\"", client->download.name,
		client->download.size, checksum, local_http ? 1 : 0, ( url ? url : "" ) );
	SV_AddReliableCommandsToMessage( client, &tmpMessage );
	SV_SendMessageToClient( client, &tmpMessage );

	if( url )
	{
		Mem_TempFree( url );
		url = NULL;
	}
}
Пример #28
0
/*
* SV_WebDownload
*/
static qboolean SV_WebDownload( const char *baseUrl, const char *filepath, qboolean overwrite, qboolean silent )
{
	qboolean success;
	int alloc_size;
	char *temppath, *writepath, *url;

	if( developer->integer )
		silent = qfalse;

	if( !baseUrl || !baseUrl[0] || !filepath )
		return qfalse;

	if( !strrchr( baseUrl, '/' ) )
	{
		if( !silent )
			Com_Printf( "SV_WebDownload: Invalid URL\n" );
		return qfalse;
	}

	if( filepath[0] == '/' ) // filepath should never begin with a slash
		filepath++;

	if( !COM_ValidateRelativeFilename( filepath ) )
	{
		if( !silent )
			Com_Printf( "SV_WebDownload: Invalid filename\n" );
		return qfalse;
	}

	if( !COM_FileExtension( filepath ) )
	{
		if( !silent )
			Com_Printf( "SV_WebDownload: no file extension\n" );
		return qfalse;
	}

	// full url (baseurl + path)
	alloc_size = strlen( baseUrl ) + 1 + strlen( filepath ) + 1;
	url = Mem_TempMalloc( alloc_size );
	if( baseUrl[ strlen( baseUrl ) - 1 ] == '/' ) // url includes last slash
		Q_snprintfz( url, alloc_size, "%s%s", baseUrl, filepath );
	else
		Q_snprintfz( url, alloc_size, "%s/%s", baseUrl, filepath );

	// add .tmp (relative + .tmp)
	alloc_size = strlen( filepath ) + strlen( ".tmp" ) + 1;
	temppath = Mem_TempMalloc( alloc_size );
	Q_snprintfz( temppath, alloc_size, "%s.tmp", filepath );

	// full write path for curl
	alloc_size = strlen( FS_WriteDirectory() ) + 1 + strlen( temppath ) + 1;
	writepath = Mem_TempMalloc( alloc_size );
	Q_snprintfz( writepath, alloc_size, "%s/%s", FS_WriteDirectory(), temppath );

	webDownloadPercentPrint = 0;
	webDownloadPercentStarted = qfalse;

	success = Web_Get( url, NULL, writepath, qtrue, 60 * 30, 60, SV_WebDownloadProgress, qfalse );

	if( webDownloadPercentStarted )
		Com_Printf( "\n" );

	if( !success )
	{
		if( !silent )
			Com_Printf( "Failed to download remote file.\n" );
		goto failed;
	}

	// rename the downloaded file
	if( !FS_MoveBaseFile( temppath, filepath ) )
	{
		if( !overwrite )
		{
			if( !silent )
				Com_Printf( "Failed to rename temporary file.\n" );
			goto failed;
		}

		// check if it failed because there already exists a file with the same name
		// and in this case remove this file
		if( FS_FOpenBaseFile( filepath, NULL, FS_READ ) != -1 )
		{
			char *backfile;

			alloc_size = strlen( filepath ) + strlen( ".bak" ) + 1;
			backfile = Mem_TempMalloc( alloc_size );
			Q_snprintfz( backfile, alloc_size, "%s.bak", filepath );

			// if there is already a .bak file, destroy it
			if( FS_FOpenBaseFile( backfile, NULL, FS_READ ) != -1 )
				FS_RemoveBaseFile( backfile );

			// move the current file into .bak file
			if( !FS_MoveBaseFile( filepath, backfile ) )
			{
				Mem_TempFree( backfile );
				if( !silent )
					Com_Printf( "Failed to backup destination file.\n" );
				goto failed;
			}

			// now try renaming the downloaded file again
			if( !FS_MoveBaseFile( temppath, filepath ) )
			{
				// didn't work, so restore the backup file
				if( FS_MoveBaseFile( backfile, filepath ) )
				{
					if( !silent )
						Com_Printf( "Failed to rename temporary file, restoring from backup.\n" );
				}
				else
				{
					if( !silent )
						Com_Printf( "Failed to rename temporary file and restore from backup.\n" );
				}

				Mem_TempFree( backfile );
				goto failed;
			}

			Mem_TempFree( backfile );
		}
	}

	Mem_TempFree( temppath );
	Mem_TempFree( writepath );
	Mem_TempFree( url );

	return qtrue;

failed:
	if( !silent )
		Com_Printf( "Removing temporary file: %s\n", writepath );
	FS_RemoveAbsoluteFile( writepath );
	Mem_TempFree( temppath );
	Mem_TempFree( writepath );
	Mem_TempFree( url );

	return qfalse;
}
Пример #29
0
/*
* SV_AutoUpdateFromWeb
*/
void SV_AutoUpdateFromWeb( qboolean checkOnly )
{
	static const char *autoUpdateBaseUrl = APP_UPDATE_URL APP_SERVER_UPDATE_DIRECTORY;
	char checksumString1[32], checksumString2[32];
	unsigned int checksum;
	qboolean success;
	int length, filenum;
	qbyte *data;
	const char *token, *ptr;
	char path[MAX_QPATH];
	int downloadCount = 0, downloadFailed = 0;
	char newVersionTag[MAX_QPATH];
	qboolean newVersion = qfalse;

	if( !dedicated->integer )
		return;

	assert( svs.mapcmd[0] );

	if( !checkOnly )
		SV_UpdateActivity();

	Com_Printf( "\n" );
	Com_Printf( "========== Starting Auto Update ===========\n" );

	Com_Printf( "Checking for updates\n" );

	// download the update file list
	success = SV_WebDownload( autoUpdateBaseUrl, APP_SERVER_UPDATE_FILE, qtrue, qtrue );

	// set as last updated today
	if( !checkOnly )
		Cvar_ForceSet( "sv_lastAutoUpdate", va( "%i", (int)Com_DaysSince1900() ) );

	if( !success ) // no update to do
		goto done;

	// read the file list
	if( ( length = FS_FOpenBaseFile( APP_SERVER_UPDATE_FILE, &filenum, FS_READ ) ) == -1 )
	{
		Com_Printf( "WARNING: Couldn't find %s\n", path );
		goto done;
	}

	if( !length )
	{
		FS_FCloseFile( filenum );
		goto done;
	}

	data = Mem_TempMalloc( length + 1 );
	FS_Read( data, length, filenum );
	FS_FCloseFile( filenum );
	FS_RemoveBaseFile( APP_SERVER_UPDATE_FILE );

	ptr = (const char *)data;

	// first token is always the current release version
	token = COM_ParseExt( &ptr, qtrue );
	if( !token[0] )
		goto cancel;

	// compare versions
	Q_strncpyz( newVersionTag, token, sizeof( newVersionTag ) );
	if( atof( newVersionTag ) > atof( va( "%4.3f", APP_VERSION ) ) )
		newVersion = qtrue;

	while( ptr )
	{
		// we got what should be a checksum
		token = COM_ParseExt( &ptr, qtrue );
		if( !token[0] )
			goto cancel;

		// copy checksum reported by server
		Q_strncpyz( checksumString1, token, sizeof( checksumString1 ) );

		// get filename
		token = COM_ParseExt( &ptr, qtrue );
		if( !token[0] )
			goto cancel;

		// filename should never begin with a slash
		if( token[0] == '/' )
			token++;

		Q_strncpyz( path, token, sizeof( path ) );

		// we got what should be a file path
		if( !COM_ValidateRelativeFilename( path ) )
		{
			Com_Printf( "WARNING: Invalid filename %s\n", path );
			continue;
		}

		checksum = FS_ChecksumBaseFile( path );
		Q_snprintfz( checksumString2, sizeof( checksumString2 ), "%u", checksum );

		// if same checksum no need to update
		if( !strcmp( checksumString1, checksumString2 ) )
			continue;

		// if it's a pack file and the file exists it can't be replaced, so skip
		if( FS_CheckPakExtension( path ) && checksum )
		{
			Com_Printf( "WARNING: Purity check failed for: %s\n", path );
			Com_Printf( "WARNING: This file has been locally modified. It is highly \n" );
			Com_Printf( "WARNING: recommended to restore the original file.\n" );
			Com_Printf( "WARNING: Reinstalling \""APPLICATION"\" might be convenient.\n" );
			continue;	
		}

		if( checkOnly )
		{
			Com_Printf( "File update available : %s\n", path );
			continue;
		}
		
		if( developer->integer )
			Com_Printf( "Downloading update of %s (checksum %s local checksum %s)\n", path, checksumString1, checksumString2 );
		else
			Com_Printf( "Updating %s\n", path );

		if( !SV_WebDownload( autoUpdateBaseUrl, path, qtrue, qtrue ) )
		{
			Com_Printf( "Failed to update %s\n", path );
			downloadFailed++;
		}

		downloadCount++;
	}

cancel:
	Mem_TempFree( data );
done:
	if( newVersion )
	{
		if( downloadCount )
		{
			if( downloadFailed )
				Com_Printf( "This version of "APPLICATION" was updated incompletely\n" );
			else
				Com_Printf( "This version of "APPLICATION" was updated successfully\n\n" );
		}

		Com_Printf( "****** Version %s of "APPLICATION" is available. ******\n", newVersionTag );
		Com_Printf( "****** Please download the new version at "APP_URL" ******\n" );
	}
	else if( downloadCount )
	{
		if( downloadFailed )
			Com_Printf( APPLICATION" was updated incompletely\n" );
		else
			Com_Printf( APPLICATION" was updated successfully\n" );
	}
	else if( !checkOnly )
	{
		if( downloadFailed )
			Com_Printf( "At least one file failed to update\n" );
		else
			Com_Printf( APPLICATION" is up to date\n" );
	}

	Com_Printf( "========== Auto Update Finished ===========\n" );
	Com_Printf( "\n" );

	// update the map list, which also does a filesystem rescan
	ML_Update();

	// if there are any new filesystem entries, restart
	if( FS_GetNotifications() & FS_NOTIFT_NEWPAKS )
	{
		if( sv.state != ss_dead )
		{
			// restart the current map, SV_Map also rescans the filesystem
			Com_Printf( "The server will now restart...\n\n" );

			// start the default map if current map isn't available
			Cbuf_ExecuteText( EXEC_APPEND, va( "map %s\n", svs.mapcmd[0] ? svs.mapcmd : sv_defaultmap->string ) );
		}
	}
}
Пример #30
0
/*
* TV_Upstream_StartDemoRecord
*/
void TV_Upstream_StartDemoRecord( upstream_t *upstream, const char *demoname, qboolean silent )
{
	char *servername, *temp;
	size_t name_size;

	assert( upstream );
	assert( demoname );

	if( upstream->demo.playing )
	{
		if( !silent )
			Com_Printf( "You can't record from another demo.\n" );
		return;
	}

	if( upstream->demo.recording )
	{
		if( !silent )
			Com_Printf( "Already recording.\n" );
		return;
	}

	// strip the port number from servername
	servername = TempCopyString( upstream->servername );
	temp = strstr( servername, ":" );
	if( temp ) *temp = '\0';

	// store the name
	name_size = sizeof( char ) * ( strlen( "demos/tvserver" ) + 1 + strlen( servername ) + 1 + strlen( demoname ) + strlen( APP_DEMO_EXTENSION_STR ) + 1 );
	upstream->demo.filename = Mem_ZoneMalloc( name_size );

	Q_snprintfz( upstream->demo.filename, name_size, "demos/tvserver/%s/%s", servername, demoname );
	COM_SanitizeFilePath( upstream->demo.filename );
	COM_DefaultExtension( upstream->demo.filename, APP_DEMO_EXTENSION_STR, name_size );

	Mem_TempFree( servername );

	if( !COM_ValidateRelativeFilename( upstream->demo.filename ) )
	{
		if( !silent )
			Com_Printf( "Invalid filename.\n" );
		Mem_ZoneFree( upstream->demo.filename );
		return;
	}

	// temp name
	name_size = sizeof( char ) * ( strlen( upstream->demo.filename ) + strlen( ".rec" ) + 1 );
	upstream->demo.tempname = Mem_ZoneMalloc( name_size );
	Q_snprintfz( upstream->demo.tempname, name_size, "%s.rec", upstream->demo.filename );

	// open the demo file
	if( FS_FOpenFile( upstream->demo.tempname, &upstream->demo.filehandle, FS_WRITE|SNAP_DEMO_GZ ) == -1 )
	{
		Com_Printf( "Error: Couldn't create the demo file.\n" );

		Mem_ZoneFree( upstream->demo.tempname );
		upstream->demo.tempname = NULL;
		Mem_ZoneFree( upstream->demo.filename );
		upstream->demo.filename = NULL;
		return;
	}

	if( !silent )
		Com_Printf( "Recording demo: %s\n", upstream->demo.filename );

	upstream->demo.recording = qtrue;
	upstream->demo.localtime = 0;
	upstream->demo.basetime = upstream->demo.duration = 0;

	// don't start saving messages until a non-delta compressed message is received
	TV_Upstream_AddReliableCommand( upstream, "nodelta" ); // request non delta compressed frame from server
	upstream->demo.waiting = qtrue;

	// the rest of the demo file will be individual frames
}