Exemplo n.º 1
0
/*
* CL_SetSoundExtension
*/
static char *CL_SetSoundExtension( const char *name )
{
	unsigned int i;
	char *finalname;
	size_t finalname_size, maxlen;
	const char *extension;

	assert( name );

	if( COM_FileExtension( name ) )
		return TempCopyString( name );

	maxlen = 0;
	for( i = 0; i < NUM_SOUND_EXTENSIONS; i++ )
	{
		if( strlen( SOUND_EXTENSIONS[i] ) > maxlen )
			maxlen = strlen( SOUND_EXTENSIONS[i] );
	}

	finalname_size = strlen( name ) + maxlen + 1;
	finalname = Mem_TempMalloc( finalname_size );
	Q_strncpyz( finalname, name, finalname_size );

	extension = FS_FirstExtension( finalname, SOUND_EXTENSIONS, NUM_SOUND_EXTENSIONS );
	if( extension )
		Q_strncatz( finalname, extension, finalname_size );
	// if not found, we just pass it without the extension

	return finalname;
}
Exemplo n.º 2
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 );
}
Exemplo n.º 3
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 );
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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 );
}
Exemplo n.º 6
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
}
Exemplo n.º 7
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;
	}
}