//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // 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 ); } }
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; }