//-----------------------------------------------------------------------------
// Remove entry from dictionary, Returns TRUE if removed.
//-----------------------------------------------------------------------------
bool RemoveFileFromResourceList( const char *pFilename, CUtlRBTree< CUtlString, int > *pTree )
{
	char szOutName[MAX_PATH];
	char *pOutName;
	V_strncpy( szOutName, pFilename, sizeof( szOutName ) );
	V_FixSlashes( szOutName );
	V_RemoveDotSlashes( szOutName );
	V_strlower( szOutName );
	pOutName = szOutName;

	// strip any prefixed game name
	for ( int i = 0; g_GameNames[i] != NULL; i++ )
	{
		size_t len = strlen( g_GameNames[i] );
		if ( !V_strnicmp( pOutName, g_GameNames[i], len ) && pOutName[len] == '\\' )
		{
			// skip past game name and slash
			pOutName += len+1;
			break;
		}
	}

	if ( pTree->Find( pOutName ) != pTree->InvalidIndex() )
	{
		pTree->Remove( pOutName );
		return true;
	}

	return false;
}
Exemple #2
0
//-----------------------------------------------------------------------------
// Fixes up a file name, removing dot slashes, fixing slashes, converting to lowercase, etc.
//-----------------------------------------------------------------------------
void V_FixupPathName( char *pOut, size_t nOutLen, const char *pPath )
{
	V_strncpy( pOut, pPath, nOutLen );
	V_FixSlashes( pOut );
	V_RemoveDotSlashes( pOut );
	V_FixDoubleSlashes( pOut );
	V_strlower( pOut );
}
static bool IsValidFileForTransfer_d( const char *filepath )
{
	if( filepath == nullptr )
	{
		DebugWarning( "[ServerSecure] Invalid file to download (string pointer was NULL)\n" );
		return false;
	}

	size_t len = std::strlen( filepath );
	if( len == 0 )
	{
		DebugWarning( "[ServerSecure] Invalid file to download (path length was 0)\n" );
		return false;
	}

	if( validation_mode == ValidationModeLua )
	{
		if( !PushHookRun( lua_interface ) )
			return false;

		lua_interface->PushString( hook_name );
		lua_interface->PushString( filepath );

		bool valid = true;
		if( lua_interface->PCall( 2, 1, -4 ) != 0 )
			lua_interface->Msg( "\n[ERROR] %s\n\n", lua_interface->GetString( -1 ) );
		else if( lua_interface->IsType( -1, GarrysMod::Lua::Type::BOOL ) )
			valid = lua_interface->GetBool( -1 );

		lua_interface->Pop( 2 );

		return valid;
	}

	std::string nicefile( filepath, len );
	if( !V_RemoveDotSlashes( &nicefile[0] ) )
		return BlockDownload( filepath );

	len = std::strlen( nicefile.c_str( ) );
	nicefile.resize( len );
	filepath = nicefile.c_str( );

	DebugWarning( "[ServerSecure] Checking file \"%s\"\n", filepath );

	if( !IsValidFileForTransfer( filepath ) )
		return BlockDownload( filepath );

	int32_t index = downloads->FindStringIndex( filepath );
	if( index != INVALID_STRING_INDEX )
		return true;

	if( len == 22 && std::strncmp( filepath, downloads_dir, 10 ) == 0 && std::strncmp( filepath + len - 4, ".dat", 4 ) == 0 )
		return true;

	return BlockDownload( filepath );
}
static void FileSystem_AddLoadedSearchPath( 
	CFSSearchPathsInit &initInfo, 
	const char *pPathID, 
	bool *bFirstGamePath, 
	const char *pBaseDir, 
	const char *pLocation,
	bool bLowViolence )
{
	char fullLocationPath[MAX_PATH];
	Q_MakeAbsolutePath( fullLocationPath, sizeof( fullLocationPath ), pLocation, pBaseDir );

	// Now resolve any ./'s.
	V_FixSlashes( fullLocationPath );
	if ( !V_RemoveDotSlashes( fullLocationPath ) )
		Error( "FileSystem_AddLoadedSearchPath - Can't resolve pathname for '%s'", fullLocationPath );
	
	// Add language, mod, and gamebin search paths automatically.
	if ( Q_stricmp( pPathID, "game" ) == 0 )
	{
		// add the low violence path
		if ( bLowViolence )
		{
			char szPath[MAX_PATH];
			Q_snprintf( szPath, sizeof(szPath), "%s_lv", fullLocationPath );
			initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
		}
		
		// add the language path
		if ( initInfo.m_pLanguage )
		{
			AddLanguageGameDir( initInfo.m_pFileSystem, fullLocationPath, initInfo.m_pLanguage );
		}

		if ( CommandLine()->FindParm( "-tempcontent" ) != 0 )
		{
			char szPath[MAX_PATH];
			Q_snprintf( szPath, sizeof(szPath), "%s_tempcontent", fullLocationPath );
			initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
		}

		// mark the first "game" dir as the "MOD" dir
		if ( *bFirstGamePath )
		{
			*bFirstGamePath = false;
			initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, "MOD", PATH_ADD_TO_TAIL );
			Q_strncpy( initInfo.m_ModPath, fullLocationPath, sizeof( initInfo.m_ModPath ) );
		}
	
		// add the game bin
		AddGameBinDir( initInfo.m_pFileSystem, fullLocationPath );
	}

	initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, pPathID, PATH_ADD_TO_TAIL );
}
FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo )
{
	if ( !initInfo.m_pFileSystem || !initInfo.m_pDirectoryName )
		return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_LoadSearchPaths: Invalid parameters specified." );

	KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths;
	FSReturnCode_t retVal = LoadGameInfoFile( initInfo.m_pDirectoryName, pMainFile, pFileSystemInfo, pSearchPaths );
	if ( retVal != FS_OK )
		return retVal;
	
	// All paths except those marked with |gameinfo_path| are relative to the base dir.
	char baseDir[MAX_PATH];
	if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) )
		return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." );

	// The MOD directory is always the one that contains gameinfo.txt
	Q_strncpy( initInfo.m_ModPath, initInfo.m_pDirectoryName, sizeof( initInfo.m_ModPath ) );

	#define GAMEINFOPATH_TOKEN		"|gameinfo_path|"
	#define BASESOURCEPATHS_TOKEN	"|all_source_engine_paths|"

	const char *pszExtraSearchPath = CommandLine()->ParmValue( "-insert_search_path" );
	if ( pszExtraSearchPath )
	{
		CUtlStringList vecPaths;
		V_SplitString( pszExtraSearchPath, ",", vecPaths );
		FOR_EACH_VEC( vecPaths, idxExtraPath )
		{
			char szAbsSearchPath[MAX_PATH];
			Q_StripPrecedingAndTrailingWhitespace( vecPaths[ idxExtraPath ] );
			V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), vecPaths[ idxExtraPath ], baseDir );
			V_FixSlashes( szAbsSearchPath );
			if ( !V_RemoveDotSlashes( szAbsSearchPath ) )
				Error( "Bad -insert_search_path - Can't resolve pathname for '%s'", szAbsSearchPath );
			V_StripTrailingSlash( szAbsSearchPath );
			FileSystem_AddLoadedSearchPath( initInfo, "GAME", szAbsSearchPath, false );
			FileSystem_AddLoadedSearchPath( initInfo, "MOD", szAbsSearchPath, false );
		}
	}
Exemple #6
0
void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir )
{
	if ( V_IsAbsolutePath( pPath ) )
	{
		// pPath is not relative.. just copy it.
		V_strncpy( pOut, pPath, outLen );
	}
	else
	{
		// Make sure the starting directory is absolute..
		if ( pStartingDir && V_IsAbsolutePath( pStartingDir ) )
		{
			V_strncpy( pOut, pStartingDir, outLen );
		}
		else
		{
			if ( !_getcwd( pOut, outLen ) )
				Error( "V_MakeAbsolutePath: _getcwd failed." );

			if ( pStartingDir )
			{
				V_AppendSlash( pOut, outLen );
				V_strncat( pOut, pStartingDir, outLen, COPY_ALL_CHARACTERS );
			}
		}

		// Concatenate the paths.
		V_AppendSlash( pOut, outLen );
		V_strncat( pOut, pPath, outLen, COPY_ALL_CHARACTERS );
	}

	if ( !V_RemoveDotSlashes( pOut ) )
		Error( "V_MakeAbsolutePath: tried to \"..\" past the root." );

	V_FixSlashes( pOut );
}
static void FileSystem_AddLoadedSearchPath( 
	CFSSearchPathsInit &initInfo, 
	const char *pPathID, 
	bool *bFirstGamePath, 
	const char *pBaseDir, 
	const char *pLocation,
	bool bLowViolence )
{
	char fullLocationPath[MAX_PATH];
	Q_MakeAbsolutePath( fullLocationPath, sizeof( fullLocationPath ), pLocation, pBaseDir );

	// Now resolve any ./'s.
	V_FixSlashes( fullLocationPath );
	if ( !V_RemoveDotSlashes( fullLocationPath ) )
		Error( "FileSystem_AddLoadedSearchPath - Can't resolve pathname for '%s'", fullLocationPath );

	// Add language, mod, and gamebin search paths automatically.
	if ( Q_stricmp( pPathID, "game" ) == 0 )
	{
		bool bDoAllPaths = true;
#if defined( _X360 ) && defined( LEFT4DEAD )
		// hl2 is a vestigal mistake due to shaders, xbox needs to prevent any search path bloat
		if ( V_stristr( fullLocationPath, "\\hl2" ) )
		{
			bDoAllPaths = false;
		}
#endif

		// add the language path, needs to be topmost, generally only contains audio
		// and the language localized movies (there are 2 version one normal, one LV)
		// this trumps the LV english movie as desired for the language
		if ( initInfo.m_pLanguage && bDoAllPaths )
		{
			AddLanguageGameDir( initInfo.m_pFileSystem, fullLocationPath, initInfo.m_pLanguage );
		}

		// next add the low violence path
		if ( bLowViolence && bDoAllPaths )
		{
			char szPath[MAX_PATH];
			Q_snprintf( szPath, sizeof(szPath), "%s_lv", fullLocationPath );
			initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
		}
		
		if ( CommandLine()->FindParm( "-tempcontent" ) != 0 && bDoAllPaths )
		{
			char szPath[MAX_PATH];
			Q_snprintf( szPath, sizeof(szPath), "%s_tempcontent", fullLocationPath );
			initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL );
		}

		// mark the first "game" dir as the "MOD" dir
		if ( *bFirstGamePath )
		{
			*bFirstGamePath = false;
			initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, "MOD", PATH_ADD_TO_TAIL );
			Q_strncpy( initInfo.m_ModPath, fullLocationPath, sizeof( initInfo.m_ModPath ) );
		}
	
		if ( bDoAllPaths )
		{
			// add the game bin
			AddGameBinDir( initInfo.m_pFileSystem, fullLocationPath );
		}
	}

	initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, pPathID, PATH_ADD_TO_TAIL );
}
//-----------------------------------------------------------------------------
// Generate a tree containing files from a reslist.  Returns TRUE if successful.
//-----------------------------------------------------------------------------
bool LoadReslist( const char *pReslistName, CUtlRBTree< CUtlString, int > *pTree )
{
	CUtlBuffer buffer;
	if ( !scriptlib->ReadFileToBuffer( pReslistName, buffer, true ) )
	{
		return false;
	}

	char szBasename[MAX_PATH];
	V_FileBase( pReslistName, szBasename, sizeof( szBasename ) );

	characterset_t breakSet;
	CharacterSetBuild( &breakSet, "" );

	// parse reslist
	char szToken[MAX_PATH];
	char szBspName[MAX_PATH];
	szBspName[0] = '\0';
	for ( ;; )
	{
		int nTokenSize = buffer.ParseToken( &breakSet, szToken, sizeof( szToken ) );
		if ( nTokenSize <= 0 )
		{
			break;
		}

		// reslists are pc built, filenames can be sloppy
		V_strlower( szToken );
		V_FixSlashes( szToken );
		V_RemoveDotSlashes( szToken );

		// can safely cull filetypes that are ignored by queued loader at runtime
		bool bKeep = false;
		const char *pExt = V_GetFileExtension( szToken );
		if ( !pExt )
		{
			// unknown
			continue;
		}
		else if ( !V_stricmp( pExt, "vmt" ) || 
				!V_stricmp( pExt, "vhv" ) || 
				!V_stricmp( pExt, "mdl" ) || 
				!V_stricmp( pExt, "raw" ) || 
				!V_stricmp( pExt, "wav" ) )
		{
			bKeep = true;
		}
		else if ( !V_stricmp( pExt, "mp3" ) )
		{
			// change to .wav
			V_SetExtension( szToken, ".wav", sizeof( szToken ) );
			bKeep = true;
		}
		else if ( !V_stricmp( pExt, "bsp" ) )
		{
			// reslists erroneously have multiple bsps
			if ( !V_stristr( szToken, szBasename ) )
			{
				// wrong one, cull it
				continue;
			}
			else
			{
				// right one, save it
				strcpy( szBspName, szToken );
				bKeep = true;
			}
		}

		if ( bKeep )
		{
			FindOrAddFileToResourceList( szToken, pTree );
		}
	}

	if ( !szBspName[0] )
	{
		// reslist is not bsp derived, nothing more to do
		return true;
	}

	CUtlVector< CUtlString > bspList;
	bool bOK = GetDependants_BSP( szBspName, &bspList );
	if ( !bOK )
	{
		return false;
	}
	
	// add all the bsp dependants to the resource list
	for ( int i=0; i<bspList.Count(); i++ )
	{
		FindOrAddFileToResourceList( bspList[i].String(), pTree );
	}

	// iterate all the models in the resource list, get all their dependents
	CUtlVector< CUtlString > modelList;
	for ( int i = pTree->FirstInorder(); i != pTree->InvalidIndex(); i = pTree->NextInorder( i ) )
	{
		const char *pExt = V_GetFileExtension( pTree->Element( i ).String() );
		if ( !pExt || V_stricmp( pExt, "mdl" ) )
		{
			continue;
		}

		if ( !GetDependants_MDL( pTree->Element( i ).String(), &modelList ) )
		{
			return false;
		}
	}

	// add all the model dependents to the resource list
	for ( int i=0; i<modelList.Count(); i++ )
	{
		FindOrAddFileToResourceList( modelList[i].String(), pTree );
	}

	// check for optional commentary, include wav dependencies
	char szCommentaryName[MAX_PATH];
	V_ComposeFileName( g_szGamePath, szBspName, szCommentaryName, sizeof( szCommentaryName ) );
	V_StripExtension( szCommentaryName, szCommentaryName, sizeof( szCommentaryName ) );
	V_strncat( szCommentaryName, "_commentary.txt", sizeof( szCommentaryName ) );
	CUtlBuffer commentaryBuffer;
	if ( ReadFileToBuffer( szCommentaryName, commentaryBuffer, true, true ) )
	{
		// any single token may be quite large to due to text
		char szCommentaryToken[8192];
		for ( ;; )
		{
			int nTokenSize = commentaryBuffer.ParseToken( &breakSet, szCommentaryToken, sizeof( szCommentaryToken ) );
			if ( nTokenSize < 0 )
			{
				break;
			}
			if ( nTokenSize > 0 && !V_stricmp( szCommentaryToken, "commentaryfile" ) )
			{
				// get the commentary file
				nTokenSize = commentaryBuffer.ParseToken( &breakSet, szCommentaryToken, sizeof( szCommentaryToken ) );
				if ( nTokenSize > 0 )
				{
					// skip past sound chars
					char *pName = szCommentaryToken;
					while ( *pName && IsSoundChar( *pName ) )
					{
						pName++;
					}
					char szWavFile[MAX_PATH];
					V_snprintf( szWavFile, sizeof( szWavFile ), "sound/%s", pName );
					FindOrAddFileToResourceList( szWavFile, pTree );
				}
			}
		}
	}

	// check for optional blacklist
	char szBlacklist[MAX_PATH];
	V_ComposeFileName( g_szGamePath, "reslistfixes_xbox.xsc", szBlacklist, sizeof( szBlacklist ) );
	CUtlBuffer blacklistBuffer;
	if ( ReadFileToBuffer( szBlacklist, blacklistBuffer, true, true ) )
	{
		for ( ;; )
		{
			int nTokenSize = blacklistBuffer.ParseToken( &breakSet, szToken, sizeof( szToken ) );
			if ( nTokenSize <= 0 )
			{
				break;
			}

			bool bAdd;
			if ( !V_stricmp( szToken, "-" ) )
			{
				bAdd = false;
			}
			else if ( !V_stricmp( szToken, "+" ) )
			{
				bAdd = true;
			}
			else
			{
				// bad syntax, skip line
				Msg( "Bad Syntax, expecting '+' or '-' as first token in reslist fixup file '%s'.\n", szBlacklist );
				continue;
			}

			// get entry
			nTokenSize = blacklistBuffer.ParseToken( &breakSet, szToken, sizeof( szToken ) );
			if ( nTokenSize <= 0 )
			{
				break;
			}

			if ( bAdd )	
			{
				FindOrAddFileToResourceList( szToken, pTree );
			}
			else
			{
				RemoveFileFromResourceList( szToken, pTree );
			}
		}
	}

	return true;
}