Esempio n. 1
0
/*
* CL_WriteServerCache
*/
void CL_WriteServerCache( void )
{
	serverlist_t *server;
	int filehandle;
	char str[256];
	netadr_t adr;

	if( FS_FOpenFile( SERVERSFILE, &filehandle, FS_WRITE ) == -1 )
	{
		Com_Printf( "CL_WriteServerList: Couldn't create the cache file\n" );
		return;
	}

	Q_snprintfz( str, sizeof( str ), "// servers cache file generated by %s. Do not modify\n", APPLICATION );
	FS_Print( filehandle, str );

	FS_Print( filehandle, "master\n" );
	server = masterList;
	while( server )
	{
		if( server->lastValidPing + 7 > Com_DaysSince1900() )
		{
			if( NET_StringToAddress( server->address, &adr ) )
			{
				Q_snprintfz( str, sizeof( str ), "%s %i\n", server->address, (int)server->lastValidPing );
				FS_Print( filehandle, str );
			}
		}

		server = server->pnext;
	}

	FS_Print( filehandle, "favorites\n" );
	server = favoritesList;
	while( server )
	{
		if( server->lastValidPing + 7 > Com_DaysSince1900() )
		{
			if( NET_StringToAddress( server->address, &adr ) )
			{
				Q_snprintfz( str, sizeof( str ), "%s %i\n", server->address, (int)server->lastValidPing );
				FS_Print( filehandle, str );
			}
		}

		server = server->pnext;
	}

	FS_FCloseFile( filehandle );
}
Esempio n. 2
0
/*
* CL_ParseStatusMessage
* Handle a reply from a ping
*/
void CL_ParseStatusMessage( const socket_t *socket, const netadr_t *address, msg_t *msg )
{
	char *s = MSG_ReadString( msg );
	serverlist_t *pingserver;
	char adrString[64];

	Com_DPrintf( "%s\n", s );

	Q_strncpyz( adrString, NET_AddressToString( address ), sizeof( adrString ) );

	// ping response
	pingserver = CL_ServerFindInList( masterList, adrString );
	if( !pingserver )
		pingserver = CL_ServerFindInList( favoritesList, adrString );

	if( pingserver && pingserver->pingTimeStamp ) // valid ping
	{
		unsigned int ping = Sys_Milliseconds() - pingserver->pingTimeStamp;
		CL_UIModule_AddToServerList( adrString, va( "\\\\ping\\\\%i%s", ping, s ) );
		pingserver->pingTimeStamp = 0;
		pingserver->lastValidPing = Com_DaysSince1900();
		return;
	}

	// assume LAN response
	if( NET_IsLANAddress( address ) && ( localQueryTimeStamp + LAN_SERVER_PINGING_TIMEOUT > Sys_Milliseconds() ) ) {
		unsigned int ping = Sys_Milliseconds() - localQueryTimeStamp;
		CL_UIModule_AddToServerList( adrString, va( "\\\\ping\\\\%i%s", ping, s ) );
		return;
	}

	// add the server info, but ignore the ping, cause it's not valid
	CL_UIModule_AddToServerList( adrString, s );
}
Esempio n. 3
0
/*
* SV_AutoUpdateFromWeb
*/
void SV_AutoUpdateFromWeb( bool checkOnly )
{
	if( checkOnly ) {
		Com_Autoupdate_Run( true, NULL );
		return;
	}

	Cvar_ForceSet( "sv_lastAutoUpdate", va( "%i", (int)Com_DaysSince1900() ) );
	Com_Autoupdate_Run( false, &SV_AutoUpdateComplete_f );
}
Esempio n. 4
0
/*
* SV_CheckAutoUpdate
*/
static void SV_CheckAutoUpdate( void )
{
	unsigned int days;

	if( !sv_pure->integer && sv_autoUpdate->integer )
	{
		Com_Printf( "WARNING: Autoupdate is not available for unpure servers.\n" );
		Cvar_ForceSet( "sv_autoUpdate", "0" );
	}

	if( !sv_autoUpdate->integer || !dedicated->integer )
		return;

	// do not if there has been any activity in the last 2 hours
	if( ( svc.last_activity + 1800000 ) > Sys_Milliseconds() )
		return;

	days = (unsigned int)sv_lastAutoUpdate->integer;

	// daily check
	if( days < Com_DaysSince1900() )
		SV_AutoUpdateFromWeb( qfalse );
}
Esempio n. 5
0
/*
* CL_AddServerToList
*/
static qboolean CL_AddServerToList( serverlist_t **serversList, char *adr, unsigned int days )
{
	serverlist_t *newserv;
	netadr_t nadr;

	if( !adr || !strlen( adr ) )
		return qfalse;

	if( !NET_StringToAddress( adr, &nadr ) )
		return qfalse;

	newserv = CL_ServerFindInList( *serversList, adr );
	if( newserv ) {
		// ignore excessive updates for about a second or so, which may happen
		// when we're querying multiple master servers at once
		if( !newserv->masterServerUpdateSeq ||
			newserv->lastUpdatedByMasterServer + 1000 < Sys_Milliseconds() ) {
			newserv->lastUpdatedByMasterServer = Sys_Milliseconds();
			newserv->masterServerUpdateSeq = masterServerUpdateSeq;
		}
		return qfalse;
	}

	newserv = (serverlist_t *)Mem_ZoneMalloc( sizeof( serverlist_t ) );
	Q_strncpyz( newserv->address, adr, sizeof( newserv->address ) );
	newserv->pingTimeStamp = 0;
	if( days == 0 )
		newserv->lastValidPing = Com_DaysSince1900();
	else
		newserv->lastValidPing = days;
	newserv->lastUpdatedByMasterServer = Sys_Milliseconds();
	newserv->masterServerUpdateSeq = masterServerUpdateSeq;
	newserv->pnext = *serversList;
	*serversList = newserv;

	return qtrue;
}
Esempio n. 6
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 ) );
		}
	}
}