Example #1
0
/*
* SV_Download_f
* Download command issued from server
*/
static void SV_Download_f( void )
{
	qboolean success;
	char *s;
	char url[MAX_STRING_CHARS], filepath[MAX_QPATH], writepath[MAX_QPATH];

	if( Cmd_Argc() != 2 )
	{
		Com_Printf( "Usage: %s <url>\n", Cmd_Argv( 0 ) );
		Com_Printf( "Downloads .pk3 or .pak from URL to gamedir and adds it to the server\n" );
		Com_Printf( "Note, server will not function properly while downloading\n" );
		return;
	}

	s = Cmd_Argv( 1 );
	if( !Com_GlobMatch( "*://*", s, qfalse ) )
		Q_strncpyz( url, "http://", sizeof( url ) );
	else
		url[0] = 0;
	Q_strncatz( url, s, sizeof( url ) );

	s = strrchr( url, '/' );
	if( !s )
	{
		Com_Printf( "%s: invalid URL\n", Cmd_Argv( 0 ) );
		return;
	}

	Q_strncpyz( filepath, va( "%s/%s", FS_GameDirectory(), s + 1 ), sizeof( filepath ) );
	Q_strncpyz( writepath, va( "%s.tmp", filepath ), sizeof( writepath ) );

	if( !FS_CheckPakExtension( writepath ) )
	{
		Com_Printf( "Missing or invalid archive extension. Only download of pack files is supported\n" );
		return;
	}

	Com_Printf( "download url: %s\n", url );

	webDownloadPercentPrint = 0;

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

	if( !success )
	{
		Com_Printf( "Server web download failed\n" );
		return;
	}

	if( !FS_MoveBaseFile( writepath, filepath ) )
	{
		Com_Printf( "Couldn't rename the downloaded file. Download failed\n" );
		return;
	}

	Com_Printf( "Download successful\n" );

	// update the map list, which also does a filesystem rescan
	ML_Update();
}
Example #2
0
static int Dynvar_Console( void *dynvar, void *pattern )
{
	const dynvar_t *const var = ( (dynvar_t *) dynvar );
	assert( var );
	return var->console &&
	       ( !pattern || Com_GlobMatch( (const char *) pattern, var->name, qfalse ) );
}
Example #3
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;
}
Example #4
0
static int ML_PatternMatchesMap( void *map, void *pattern )
{
	assert( map );
	return !pattern || Com_GlobMatch( (const char *) pattern, ( (mapinfo_t *) map )->filename, false );
}
Example #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 );
}
Example #6
0
static int Cvar_PatternMatches( void *cvar, void *pattern )
{
	return !pattern || Com_GlobMatch( (const char *) pattern, ( (cvar_t *) cvar )->name, qfalse );
}
Example #7
0
/*
* TV_Upstream_ParseConfigstringCommand_f
*/
static void TV_Upstream_HandleConfigstring( upstream_t *upstream, int index, const char *val )
{
	char hostname[MAX_CONFIGSTRING_CHARS];
	msg_t msg;
	qbyte msgbuf[MAX_MSGLEN];

	if( !val || !val[0] )
		return;

	if( index < 0 || index >= MAX_CONFIGSTRINGS )
		TV_Upstream_Error( upstream, "configstring > MAX_CONFIGSTRINGS" );

	Q_strncpyz( upstream->configstrings[index], val, sizeof( upstream->configstrings[index] ) );

	if( index == CS_AUTORECORDSTATE )
	{
		// don't do a thing until we receive a "precache" command
		if( upstream->precacheDone )
			TV_Upstream_AutoRecordAction( upstream, upstream->configstrings[CS_AUTORECORDSTATE] );
		return;
	}

	if( index != CS_HOSTNAME )
		return;

	if( !upstream->demo.playing )
	{
		TV_Upstream_SetName( upstream, val );
		return;
	}

	// demos often come with generic hostnames, attempt to workaround that
	if( !Q_stricmp( val, APPLICATION " server" ) )
	{
		char *temp;
		size_t temp_size;
		const char *filebase;

		filebase = COM_FileBase( upstream->demo.filename );
		temp_size = strlen( filebase ) + strlen( APP_DEMO_EXTENSION_STR ) + 1;
		temp = Mem_TempMalloc( temp_size );
		Q_strncpyz( temp, filebase, temp_size );
		COM_ReplaceExtension( temp, APP_DEMO_EXTENSION_STR, temp_size );

		if( Com_GlobMatch( "*_auto[0-9][0-9][0-9][0-9]" APP_DEMO_EXTENSION_STR, temp, qfalse )
			|| Com_GlobMatch( "*_mvd" APP_DEMO_EXTENSION_STR, temp, qfalse ) )
			temp[strrchr( temp, '_' ) - temp] = '\0';
		else
			COM_StripExtension( temp );

		Q_strncpyz( hostname, va( S_COLOR_ORANGE "R: " S_COLOR_WHITE "%s", temp ), sizeof( hostname ) );

		Mem_TempFree( temp );
	}
	else
	{
		Q_strncpyz( hostname, va( S_COLOR_ORANGE "R: " S_COLOR_WHITE "%s", val ), sizeof( hostname ) );
	}

	TV_Upstream_SetName( upstream, hostname );

	// override CS_HOSTNAME in next packet
	MSG_Init( &msg, msgbuf, sizeof( msgbuf ) );
	MSG_WriteByte( &msg, svc_servercs );
	MSG_WriteString( &msg, va( "cs %i \"%s\"", CS_HOSTNAME, hostname ) );
	TV_Upstream_SavePacket( upstream, &msg, 0 );
}
Example #8
0
/*
* SV_Init
* 
* Only called at plat.exe startup, not for each game
*/
void SV_Init( void )
{
	cvar_t *sv_pps;
	cvar_t *sv_fps;

	assert( !sv_initialized );

	memset( &svc, 0, sizeof( svc ) );

	SV_InitOperatorCommands();

	sv_mempool = Mem_AllocPool( NULL, "Server" );

	Cvar_Get( "sv_cheats", "0", CVAR_SERVERINFO | CVAR_LATCH );
	Cvar_Get( "protocol", va( "%i", APP_PROTOCOL_VERSION ), CVAR_SERVERINFO | CVAR_NOSET );

	sv_ip =			    Cvar_Get( "sv_ip", "", CVAR_ARCHIVE | CVAR_LATCH );
	sv_port =		    Cvar_Get( "sv_port", va( "%i", PORT_SERVER ), CVAR_ARCHIVE | CVAR_LATCH );
	sv_ip6 =			Cvar_Get( "sv_ip6", "::", CVAR_ARCHIVE | CVAR_LATCH );
	sv_port6 =		    Cvar_Get( "sv_port6", va( "%i", PORT_SERVER ), CVAR_ARCHIVE | CVAR_LATCH );
#ifdef TCP_SUPPORT
	sv_tcp =		    Cvar_Get( "sv_tcp", "1", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH );
#endif

	rcon_password =		    Cvar_Get( "rcon_password", "", 0 );
	sv_hostname =		    Cvar_Get( "sv_hostname", APPLICATION " server", CVAR_SERVERINFO | CVAR_ARCHIVE );
	sv_timeout =		    Cvar_Get( "sv_timeout", "125", 0 );
	sv_zombietime =		    Cvar_Get( "sv_zombietime", "2", 0 );
	sv_enforcetime =	    Cvar_Get( "sv_enforcetime", "1", 0 );
	sv_showclamp =		    Cvar_Get( "sv_showclamp", "0", 0 );
	sv_showRcon =		    Cvar_Get( "sv_showRcon", "1", 0 );
	sv_showChallenge =	    Cvar_Get( "sv_showChallenge", "0", 0 );
	sv_showInfoQueries =	Cvar_Get( "sv_showInfoQueries", "0", 0 );
	sv_highchars =			Cvar_Get( "sv_highchars", "1", 0 );

	sv_uploads_baseurl =	    Cvar_Get( "sv_uploads_baseurl", "", CVAR_ARCHIVE );
	sv_uploads_demos_baseurl =	Cvar_Get( "sv_uploads_demos_baseurl", "", CVAR_ARCHIVE );
	if( dedicated->integer )
	{
		sv_uploads =		    Cvar_Get( "sv_uploads", "1", CVAR_READONLY );
		sv_uploads_from_server = Cvar_Get( "sv_uploads_from_server", "1", CVAR_READONLY );
		sv_autoUpdate = Cvar_Get( "sv_autoUpdate", "1", CVAR_ARCHIVE );

		sv_pure =		Cvar_Get( "sv_pure", "1", CVAR_ARCHIVE | CVAR_LATCH | CVAR_SERVERINFO );

#ifdef PUBLIC_BUILD
		sv_public =		Cvar_Get( "sv_public", "1", CVAR_ARCHIVE | CVAR_LATCH );
#else
		sv_public =		Cvar_Get( "sv_public", "0", CVAR_ARCHIVE | CVAR_LATCH );
#endif
	}
	else
	{
		sv_uploads =		    Cvar_Get( "sv_uploads", "1", CVAR_ARCHIVE );
		sv_uploads_from_server = Cvar_Get( "sv_uploads_from_server", "1", CVAR_ARCHIVE );
		sv_autoUpdate = Cvar_Get( "sv_autoUpdate", "0", CVAR_READONLY );

		sv_pure =		Cvar_Get( "sv_pure", "0", CVAR_ARCHIVE | CVAR_LATCH | CVAR_SERVERINFO );
		sv_public =		Cvar_Get( "sv_public", "0", CVAR_ARCHIVE );
	}

	sv_iplimit = Cvar_Get( "sv_iplimit", "3", CVAR_ARCHIVE );

	sv_lastAutoUpdate = Cvar_Get( "sv_lastAutoUpdate", "0", CVAR_READONLY|CVAR_ARCHIVE );
	sv_pure_forcemodulepk3 =    Cvar_Get( "sv_pure_forcemodulepk3", "", CVAR_LATCH );

	sv_defaultmap =		    Cvar_Get( "sv_defaultmap", "wdm1", CVAR_ARCHIVE );
	sv_write_defaultmap =	Cvar_Get( "sv_write_defaultmap", "0", CVAR_ARCHIVE );
	sv_reconnectlimit =	    Cvar_Get( "sv_reconnectlimit", "3", CVAR_ARCHIVE );
	sv_maxclients =		    Cvar_Get( "sv_maxclients", "8", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_LATCH );
	sv_maxmvclients =	    Cvar_Get( "sv_maxmvclients", "4", CVAR_ARCHIVE | CVAR_SERVERINFO );

	Cvar_Get( "sv_modmanifest", "", CVAR_READONLY );
	Cvar_ForceSet( "sv_modmanifest", "" );

	// fix invalid sv_maxclients values
	if( sv_maxclients->integer < 1 )
		Cvar_FullSet( "sv_maxclients", "1", CVAR_ARCHIVE|CVAR_SERVERINFO|CVAR_LATCH, qtrue );
	else if( sv_maxclients->integer > MAX_CLIENTS )
		Cvar_FullSet( "sv_maxclients", va( "%i", MAX_CLIENTS ), CVAR_ARCHIVE|CVAR_SERVERINFO|CVAR_LATCH, qtrue );

	sv_demodir = Cvar_Get( "sv_demodir", "", CVAR_NOSET );
	if( sv_demodir->string[0] && Com_GlobMatch( "*[^0-9a-zA-Z_@]*", sv_demodir->string, qfalse ) )
	{
		Com_Printf( "Invalid demo prefix string: %s\n", sv_demodir->string );
		Cvar_ForceSet( "sv_demodir", "" );
	}

	// wsw : jal : cap client's exceding server rules
	sv_maxrate =		    Cvar_Get( "sv_maxrate", "0", CVAR_DEVELOPER );
	sv_compresspackets =	    Cvar_Get( "sv_compresspackets", "1", CVAR_DEVELOPER );
	sv_skilllevel =		    Cvar_Get( "sv_skilllevel", "1", CVAR_SERVERINFO|CVAR_ARCHIVE|CVAR_LATCH );

	if( sv_skilllevel->integer > 2 )
		Cvar_ForceSet( "sv_skilllevel", "2" );
	if( sv_skilllevel->integer < 0 )
		Cvar_ForceSet( "sv_skilllevel", "0" );

	sv_masterservers =	    Cvar_Get( "masterservers", DEFAULT_MASTER_SERVERS_IPS, CVAR_LATCH );

	sv_debug_serverCmd =	    Cvar_Get( "sv_debug_serverCmd", "0", CVAR_ARCHIVE );

	sv_MOTD = Cvar_Get( "sv_MOTD", "0", CVAR_ARCHIVE );
	sv_MOTDFile = Cvar_Get( "sv_MOTDFile", "", CVAR_ARCHIVE );
	sv_MOTDString = Cvar_Get( "sv_MOTDString", "", CVAR_ARCHIVE );
	SV_MOTD_Update();

	// this is a message holder for shared use
	MSG_Init( &tmpMessage, tmpMessageData, sizeof( tmpMessageData ) );

	// init server updates ratio
	if( dedicated->integer )
		sv_pps = Cvar_Get( "sv_pps", "20", CVAR_SERVERINFO|CVAR_NOSET );
	else
		sv_pps = Cvar_Get( "sv_pps", "20", CVAR_SERVERINFO );
	svc.snapFrameTime = (int)( 1000 / sv_pps->value );
	if( svc.snapFrameTime > 200 )
	{                           // too slow, also, netcode uses a byte
		Cvar_ForceSet( "sv_pps", "5" );
		svc.snapFrameTime = 200;
	}
	else if( svc.snapFrameTime < 10 )
	{                                 // abusive
		Cvar_ForceSet( "sv_pps", "100" );
		svc.snapFrameTime = 10;
	}

	sv_fps = Cvar_Get( "sv_fps", "62", CVAR_NOSET );
	svc.gameFrameTime = (int)( 1000 / sv_fps->value );
	if( svc.gameFrameTime > svc.snapFrameTime )
	{                                         // gamecode can never be slower than snaps
		svc.gameFrameTime = svc.snapFrameTime;
		Cvar_ForceSet( "sv_fps", sv_pps->dvalue );
	}

	Com_Printf( "Game running at %i fps. Server transmit at %i pps\n", sv_fps->integer, sv_pps->integer );

	//init the master servers list
	SV_InitMaster();

	SV_MM_Init();

	ML_Init();

	sv_initialized = qtrue;
}