public Stream OpenFileRead(string relativePath, bool allowCopyFiles, out Pack foundInPack, string gameDirectory, FileSearch searchFlags, bool checkOnly, out bool found, out DateTime lastModified) { lastModified = DateTime.MinValue; if(_searchPaths.Count == 0) { idConsole.FatalError("Filesystem call made without initialization"); } if((relativePath == null) || (relativePath == string.Empty)) { idConsole.FatalError("open file read: null 'relativePath' parameter passed"); } found = false; foundInPack = null; // qpaths are not supposed to have a leading slash. relativePath = relativePath.TrimEnd('/'); // make absolutely sure that it can't back up the path. // the searchpaths do guarantee that something will always // be prepended, so we don't need to worry about "c:" or "//limbo". if((relativePath.Contains("..") == true) || (relativePath.Contains("::") == true)) { return null; } // // search through the path, one element at a time // foreach(SearchPath searchPath in _searchPaths) { if((searchPath.Directory != null) && ((searchFlags & FileSearch.SearchDirectories) == FileSearch.SearchDirectories)) { // check a file in the directory tree. // if we are running restricted, the only files we // will allow to come from the directory are .cfg files. if((idE.CvarSystem.GetBool("fs_restrict") == true) /* TODO: serverPaks.Num()*/) { if(FileAllowedFromDirectory(relativePath) == false) { continue; } } idDirectory dir = searchPath.Directory; if((gameDirectory != null) && (gameDirectory != string.Empty)) { if(dir.GameDirectory != gameDirectory) { continue; } } string netPath = CreatePath(dir.Path, dir.GameDirectory, relativePath); Stream file = null; if(File.Exists(netPath) == true) { try { file = File.OpenRead(netPath); lastModified = File.GetLastWriteTime(netPath); } catch(Exception x) { idConsole.DeveloperWriteLine("OpenFileRead Exception: {0}", x.ToString()); continue; } } if(file == null) { continue; } if(idE.CvarSystem.GetInteger("fs_debug") > 0) { idConsole.WriteLine("open file read: {0} (found in '{1}/{2}')", relativePath, dir.Path, dir.GameDirectory); } if((_loadedFileFromDir == false) && (FileAllowedFromDirectory(relativePath) == false)) { // TODO /*if(restartChecksums.Num()) { common->FatalError("'%s' loaded from directory: Failed to restart with pure mode restrictions for server connect", relativePath); }*/ idConsole.DeveloperWriteLine("filesystem: switching to pure mode will require a restart. '{0}' loaded from directory.", relativePath); _loadedFileFromDir = true; } // TODO: if fs_copyfiles is set /*if(allowCopyFiles && fs_copyfiles.GetInteger()) { idStr copypath; idStr name; copypath = BuildOSPath(fs_savepath.GetString(), dir->gamedir, relativePath); netpath.ExtractFileName(name); copypath.StripFilename(); copypath += PATHSEPERATOR_STR; copypath += name; bool isFromCDPath = !dir->path.Cmp(fs_cdpath.GetString()); bool isFromSavePath = !dir->path.Cmp(fs_savepath.GetString()); bool isFromBasePath = !dir->path.Cmp(fs_basepath.GetString()); switch(fs_copyfiles.GetInteger()) { case 1: // copy from cd path only if(isFromCDPath) { CopyFile(netpath, copypath); } break; case 2: // from cd path + timestamps if(isFromCDPath) { CopyFile(netpath, copypath); } else if(isFromSavePath || isFromBasePath) { idStr sourcepath; sourcepath = BuildOSPath(fs_cdpath.GetString(), dir->gamedir, relativePath); FILE* f1 = OpenOSFile(sourcepath, "r"); if(f1) { ID_TIME_T t1 = Sys_FileTimeStamp(f1); fclose(f1); FILE* f2 = OpenOSFile(copypath, "r"); if(f2) { ID_TIME_T t2 = Sys_FileTimeStamp(f2); fclose(f2); if(t1 > t2) { CopyFile(sourcepath, copypath); } } } } break; case 3: if(isFromCDPath || isFromBasePath) { CopyFile(netpath, copypath); } break; case 4: if(isFromCDPath && !isFromBasePath) { CopyFile(netpath, copypath); } break; } }*/ if(file != null) { found = true; } return file; } /*else if(search->pack && (searchFlags & FSFLAG_SEARCH_PAKS)) { if(!search->pack->hashTable[hash]) { continue; } // disregard if it doesn't match one of the allowed pure pak files if(serverPaks.Num()) { GetPackStatus(search->pack); if(search->pack->pureStatus != PURE_NEVER && !serverPaks.Find(search->pack)) { continue; // not on the pure server pak list } } // look through all the pak file elements pak = search->pack; if(searchFlags & FSFLAG_BINARY_ONLY) { // make sure this pak is tagged as a binary file if(pak->binary == BINARY_UNKNOWN) { int confHash; fileInPack_t* pakFile; confHash = HashFileName(BINARY_CONFIG); pak->binary = BINARY_NO; for(pakFile = search->pack->hashTable[confHash]; pakFile; pakFile = pakFile->next) { if(!FilenameCompare(pakFile->name, BINARY_CONFIG)) { pak->binary = BINARY_YES; break; } } } if(pak->binary == BINARY_NO) { continue; // not a binary pak, skip } } for(pakFile = pak->hashTable[hash]; pakFile; pakFile = pakFile->next) { // case and separator insensitive comparisons if(!FilenameCompare(pakFile->name, relativePath)) { idFile_InZip* file = ReadFileFromZip(pak, pakFile, relativePath); if(foundInPak) { *foundInPak = pak; } if(!pak->referenced && !(searchFlags & FSFLAG_PURE_NOREF)) { // mark this pak referenced if(fs_debug.GetInteger()) { common->Printf("idFileSystem::OpenFileRead: %s -> adding %s to referenced paks\n", relativePath, pak->pakFilename.c_str()); } pak->referenced = true; } if(fs_debug.GetInteger()) { common->Printf("idFileSystem::OpenFileRead: %s (found in '%s')\n", relativePath, pak->pakFilename.c_str()); } return file; } } } }*/ // TODO /*if ( searchFlags & FSFLAG_SEARCH_ADDONS ) { for ( search = addonPaks; search; search = search->next ) { assert( search->pack ); fileInPack_t *pakFile; pak = search->pack; for ( pakFile = pak->hashTable[hash]; pakFile; pakFile = pakFile->next ) { if ( !FilenameCompare( pakFile->name, relativePath ) ) { idFile_InZip *file = ReadFileFromZip( pak, pakFile, relativePath ); if ( foundInPak ) { *foundInPak = pak; } // we don't toggle pure on paks found in addons - they can't be used without a reloadEngine anyway if ( fs_debug.GetInteger( ) ) { common->Printf( "idFileSystem::OpenFileRead: %s (found in addon pk4 '%s')\n", relativePath, search->pack->pakFilename.c_str() ); } return file; } } }*/ } if(idE.CvarSystem.GetInteger("fs_debug") > 0) { idConsole.WriteLine("Can't find {0}", relativePath); } return null; }
public Stream OpenFileRead(string relativePath, bool allowCopyFiles, out Pack foundInPack, FileSearch searchFlags) { return OpenFileRead(relativePath, allowCopyFiles, out foundInPack, null, searchFlags); }
public Stream OpenFileRead(string relativePath, bool allowCopyFiles, out Pack foundInPack, string gameDirectory, FileSearch searchFlags) { bool found; DateTime lastModified; return OpenFileRead(relativePath, allowCopyFiles, out foundInPack, null, searchFlags, false, out found, out lastModified); }
private Pack LoadZipFile(string zip) { ZipFile zipFile = new ZipFile(zip); Pack pack = new Pack(); pack.FileName = zip; pack.Zip = zipFile; pack.FileCount = (int) zipFile.Count; // TODO: check if this is an addon pak /*pack->addon = false; confHash = HashFileName( ADDON_CONFIG ); for ( pakFile = pack->hashTable[confHash]; pakFile; pakFile = pakFile->next ) { if ( !FilenameCompare( pakFile->name, ADDON_CONFIG ) ) { pack->addon = true; idFile_InZip *file = ReadFileFromZip( pack, pakFile, ADDON_CONFIG ); // may be just an empty file if you don't bother about the mapDef if ( file && file->Length() ) { char *buf; buf = new char[ file->Length() + 1 ]; file->Read( (void *)buf, file->Length() ); buf[ file->Length() ] = '\0'; pack->addon_info = ParseAddonDef( buf, file->Length() ); delete[] buf; } if ( file ) { CloseFile( file ); } break; } }*/ return pack; }