X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=plugins%2Fvfspk3%2Fvfs.cpp;h=703a956e15246afa5854a276fb5f692eef52f658;hp=bb3b5dbf4fc7c8cc237efdf54da6671272aa6872;hb=a333eaee1c5b8b20ec59411f4878f8fc5bdfa584;hpb=73e3cc2bedc68cd6bd6479ca25e34b1c5d423bc9 diff --git a/plugins/vfspk3/vfs.cpp b/plugins/vfspk3/vfs.cpp index bb3b5dbf..703a956e 100644 --- a/plugins/vfspk3/vfs.cpp +++ b/plugins/vfspk3/vfs.cpp @@ -42,6 +42,7 @@ // #include "vfs.h" +#include "globaldefs.h" #include #include @@ -62,9 +63,9 @@ ArchiveModules& FileSystemQ3API_getArchiveModules(); #include "dpkdeps.h" -#define VFS_MAXDIRS 64 +const int VFS_MAXDIRS = 64; -#if defined( WIN32 ) +#if GDEF_OS_WINDOWS #define PATH_MAX 260 #endif @@ -128,8 +129,8 @@ static void FixDOSName( char *src ){ } const _QERArchiveTable* GetArchiveTable( ArchiveModules& archiveModules, const char* ext ){ - StringOutputStream tmp( 16 ); - tmp << LowerCase( ext ); + std::string tmp = ext; + transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); return archiveModules.findModule( tmp.c_str() ); } @@ -143,7 +144,7 @@ static Archive* InitPakFile( ArchiveModules& archiveModules, const char *filenam entry.archive = table->m_pfnOpenArchive( filename ); entry.is_pakfile = true; g_archives.push_back( entry ); - globalOutputStream() << " pak file: " << filename << "\n"; + globalOutputStream() << "pak file: " << filename << "\n"; return entry.archive; } @@ -281,9 +282,10 @@ bool operator()( const CopiedString& self, const CopiedString& other ) const { typedef std::set Archives; -Archive* AddPk3Dir( const char* fullpath ){ +Archive* AddPakDir( const char* fullpath ){ if ( g_numDirs == VFS_MAXDIRS ) return 0; + globalOutputStream() << "pak directory: " << fullpath << "\n"; strncpy( g_strDirs[g_numDirs], fullpath, PATH_MAX ); g_strDirs[g_numDirs][PATH_MAX] = '\0'; g_numDirs++; @@ -299,16 +301,16 @@ Archive* AddPk3Dir( const char* fullpath ){ } } -// for Daemon DPK vfs +// for Daemon DPK VFS Archive* AddDpkDir( const char* fullpath ){ - return AddPk3Dir( fullpath ); + return AddPakDir( fullpath ); } struct pakfile_path_t { CopiedString fullpath; // full pak dir or pk3dir name - bool is_pakfile; // defines is it .pk3dir or .pk3 file + bool is_pakfile; // tells it is .pk3dir or .pk3 file }; typedef std::pair PakfilePathsKV; @@ -345,6 +347,9 @@ static const char* GetLatestDpkPakVersion( const char* name ){ } // release string after using +// Note: it also contains the version string, +// for …/src/map-castle_src.dpkdir/maps/castle.map +// it will return map-castle_src static char* GetCurrentMapDpkPakName(){ char* mapdir; char* mapname; @@ -354,21 +359,27 @@ static char* GetCurrentMapDpkPakName(){ mapname = string_clone( GlobalRadiant().getMapName() ); mapnamelen = string_length( mapname ); - mapdir = strrchr( mapname, '/' ); - if ( mapdir ) { - mapdir -= 12; - if ( strncmp( mapdir, ".dpkdir/maps/", 13 ) == 0 ) { - *mapdir = '\0'; - mapdir = strrchr( mapname, '/' ); - if ( mapdir ) mapdir++; - else mapdir = mapname; - result = string_clone( mapdir ); + char pattern[] = ".dpkdir/"; + char* end = strstr( mapname, ".dpkdir/" ); + if ( end ) + { + end[ 0 ] = '\0'; + + mapdir = strrchr( mapname, '/' ); + if ( mapdir ) + { + mapdir++; } + else + { + mapdir = mapname; + } + + result = string_clone( mapdir ); } string_release( mapname, mapnamelen ); return result; - } // prevent loading duplicates or circular references @@ -377,23 +388,43 @@ static Archives g_loaded_dpk_paks; // actual pak adding on initialise, deferred from InitDirectory // Daemon DPK filesystem doesn't need load all paks it finds static void LoadDpkPakWithDeps( const char* pakname ){ - const char* und = strrchr( pakname, '_' ); - if ( !und ) pakname = GetLatestDpkPakVersion( pakname ); - if ( !pakname || g_loaded_dpk_paks.find( pakname ) != g_loaded_dpk_paks.end() ) return; - - PakfilePaths::iterator i = g_pakfile_paths.find( pakname ); - if ( i == g_pakfile_paths.end() ) return; - Archive* arc; - if ( i->second.is_pakfile ){ - arc = InitPakFile( FileSystemQ3API_getArchiveModules(), i->second.fullpath.c_str() ); + ArchiveTextFile* depsFile; + + if (pakname == NULL) { + // load DEPS from game pack + std::string baseDirectory( GlobalRadiant().getGameToolsPath() ); + baseDirectory += GlobalRadiant().getRequiredGameDescriptionKeyValue( "basegame" ); + baseDirectory += '/'; + arc = AddDpkDir( baseDirectory.c_str() ); + depsFile = arc->openTextFile( "DEPS" ); } else { - arc = AddDpkDir( i->second.fullpath.c_str() ); + const char* und = strrchr( pakname, '_' ); + if ( !und ) { + pakname = GetLatestDpkPakVersion( pakname ); + } + if ( !pakname || g_loaded_dpk_paks.find( pakname ) != g_loaded_dpk_paks.end() ) { + return; + } + + PakfilePaths::iterator i = g_pakfile_paths.find( pakname ); + if ( i == g_pakfile_paths.end() ) { + return; + } + + if ( i->second.is_pakfile ){ + arc = InitPakFile( FileSystemQ3API_getArchiveModules(), i->second.fullpath.c_str() ); + } else { + arc = AddDpkDir( i->second.fullpath.c_str() ); + } + g_loaded_dpk_paks.insert( pakname ); + + depsFile = arc->openTextFile( "DEPS" ); } - g_loaded_dpk_paks.insert( pakname ); - ArchiveTextFile* depsFile = arc->openTextFile( "DEPS" ); - if ( !depsFile ) return; + if ( !depsFile ) { + return; + } { TextLinesInputStream istream = depsFile->getInputStream(); @@ -432,6 +463,7 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ g_numForbiddenDirs = 0; StringTokeniser st( GlobalRadiant().getGameDescriptionKeyValue( "forbidden_paths" ), " " ); + for ( j = 0; j < VFS_MAXDIRS; ++j ) { const char *t = st.getToken(); @@ -457,6 +489,7 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ } g_free( dbuf ); } + if ( j < g_numForbiddenDirs ) { printf( "Directory %s matched by forbidden dirs, removed\n", directory ); return; @@ -487,20 +520,22 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ GDir* dir = g_dir_open( path, 0, 0 ); - if ( dir != 0 ) { + if ( dir != NULL ) { globalOutputStream() << "vfs directory: " << path << "\n"; Archives archives; Archives archivesOverride; const char* ignore_prefix = ""; const char* override_prefix = ""; - bool is_pk3_vfs, is_pk4_vfs, is_dpk_vfs; + bool is_wad_vfs, is_pak_vfs, is_pk3_vfs, is_pk4_vfs, is_dpk_vfs; - is_pk3_vfs = GetArchiveTable( archiveModules, "pk3" ); - is_pk4_vfs = GetArchiveTable( archiveModules, "pk4" ); - is_dpk_vfs = GetArchiveTable( archiveModules, "dpk" ); + is_wad_vfs = !!GetArchiveTable( archiveModules, "wad" ); + is_pak_vfs = !!GetArchiveTable( archiveModules, "pak" ); + is_pk3_vfs = !!GetArchiveTable( archiveModules, "pk3" ); + is_pk4_vfs = !!GetArchiveTable( archiveModules, "pk4" ); + is_dpk_vfs = !!GetArchiveTable( archiveModules, "dpk" ); - if ( !is_dpk_vfs ) { + if ( is_dpk_vfs ) { // See if we are in "sp" or "mp" mapping mode const char* gamemode = gamemode_get(); @@ -514,10 +549,11 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ } } - for (;; ) + while ( true ) { const char* name = g_dir_read_name( dir ); - if ( name == 0 ) { + + if ( name == nullptr ) { break; } @@ -529,36 +565,36 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ break; } } + if ( j < g_numForbiddenDirs ) { continue; } const char *ext = strrchr( name, '.' ); - char tmppath[PATH_MAX]; + char tmppath[PATH_MAX + 1]; - if ( is_dpk_vfs ) { - if ( !!ext && !string_compare_nocase_upper( ext, ".dpkdir" ) ) { + if ( ext != nullptr ) { + if ( is_dpk_vfs && !string_compare_nocase_upper( ext, ".dpkdir" ) ) { snprintf( tmppath, PATH_MAX, "%s%s/", path, name ); tmppath[PATH_MAX] = '\0'; FixDOSName( tmppath ); AddSlash( tmppath ); AddDpkPak( CopiedString( StringRange( name, ext ) ).c_str(), tmppath, false ); } - } - if ( is_pk3_vfs || is_pk4_vfs ) { - if ( !!ext && ( !string_compare_nocase_upper( ext, ".pk3dir" ) - || !string_compare_nocase_upper( ext, ".pk4dir" ) ) ) { + else if ( ( is_wad_vfs && !string_compare_nocase_upper( ext, ".pakdir" ) ) + || ( is_pk3_vfs && !string_compare_nocase_upper( ext, ".pk3dir" ) ) + || ( is_pk4_vfs && !string_compare_nocase_upper( ext, ".pk4dir" ) ) ) { snprintf( tmppath, PATH_MAX, "%s%s/", path, name ); tmppath[PATH_MAX] = '\0'; FixDOSName( tmppath ); AddSlash( tmppath ); - AddPk3Dir( tmppath ); + AddPakDir( tmppath ); } } // GetArchiveTable() needs "pk3" if ext is ".pk3" - if ( ( ext == 0 ) || *( ext + 1 ) == '\0' || GetArchiveTable( archiveModules, ext + 1 ) == 0 ) { + if ( ( ext == nullptr ) || *( ext + 1 ) == '\0' || GetArchiveTable( archiveModules, ext + 1 ) == 0 ) { continue; } @@ -566,16 +602,18 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ if ( !string_empty( ignore_prefix ) && strncmp( name, ignore_prefix, strlen( ignore_prefix ) ) == 0 ) { continue; } + if ( !string_empty( override_prefix ) && strncmp( name, override_prefix, strlen( override_prefix ) ) == 0 ) { if ( !string_compare_nocase_upper( ext, ".dpk" ) ) { if ( is_dpk_vfs ) { archives.insert( name ); + continue; } } else { archivesOverride.insert( name ); + continue; } - continue; } archives.insert( name ); @@ -589,7 +627,8 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ for ( Archives::iterator i = archives.begin(); i != archives.end(); ++i ) { const char* name = i->c_str(); const char* ext = strrchr( name, '.' ); - if ( !string_compare_nocase_upper( ext, ".dpk" ) ) { + if ( !string_compare_nocase_upper( ext, ".dpk" ) ) + { CopiedString name_final = CopiedString( StringRange( name, ext ) ); fullpath = string_new_concat( path, name ); AddDpkPak( name_final.c_str(), fullpath, true ); @@ -597,24 +636,30 @@ void InitDirectory( const char* directory, ArchiveModules& archiveModules ){ } } } - if ( is_pk3_vfs || is_pk4_vfs ) { + else + { for ( Archives::iterator i = archivesOverride.begin(); i != archivesOverride.end(); ++i ) { const char* name = i->c_str(); const char* ext = strrchr( name, '.' ); - if ( !string_compare_nocase_upper( ext, ".pk3" ) - || !string_compare_nocase_upper( ext, ".pk4" ) ) { + if ( ( is_wad_vfs && !string_compare_nocase_upper( ext, ".wad" ) ) + || ( is_pak_vfs && !string_compare_nocase_upper( ext, ".pak" ) ) + || ( is_pk3_vfs && !string_compare_nocase_upper( ext, ".pk3" ) ) + || ( is_pk4_vfs && !string_compare_nocase_upper( ext, ".pk4" ) ) ) { fullpath = string_new_concat( path, i->c_str() ); InitPakFile( archiveModules, fullpath ); string_release( fullpath, string_length( fullpath ) ); } } + for ( Archives::iterator i = archives.begin(); i != archives.end(); ++i ) { const char* name = i->c_str(); const char* ext = strrchr( name, '.' ); - if ( !string_compare_nocase_upper( ext, ".pk3" ) - || !string_compare_nocase_upper( ext, ".pk4" ) ) { + if ( ( is_wad_vfs && !string_compare_nocase_upper( ext, ".wad" ) ) + || ( is_pak_vfs && !string_compare_nocase_upper( ext, ".pak" ) ) + || ( is_pk3_vfs && !string_compare_nocase_upper( ext, ".pk3" ) ) + || ( is_pk4_vfs && !string_compare_nocase_upper( ext, ".pk4" ) ) ) { fullpath = string_new_concat( path, i->c_str() ); InitPakFile( archiveModules, fullpath ); string_release( fullpath, string_length( fullpath ) ); @@ -646,8 +691,8 @@ void Shutdown(){ g_loaded_dpk_paks.clear(); } -#define VFS_SEARCH_PAK 0x1 -#define VFS_SEARCH_DIR 0x2 +const int VFS_SEARCH_PAK = 0x1; +const int VFS_SEARCH_DIR = 0x2; int GetFileCount( const char *filename, int flag ){ int count = 0; @@ -663,8 +708,8 @@ int GetFileCount( const char *filename, int flag ){ for ( archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i ) { - if ( ( *i ).is_pakfile && ( flag & VFS_SEARCH_PAK ) != 0 - || !( *i ).is_pakfile && ( flag & VFS_SEARCH_DIR ) != 0 ) { + if ( (( *i ).is_pakfile && ( flag & VFS_SEARCH_PAK ) != 0) + || (!( *i ).is_pakfile && ( flag & VFS_SEARCH_DIR ) != 0) ) { if ( ( *i ).archive->containsFile( fixed ) ) { ++count; } @@ -784,16 +829,14 @@ void initialise(){ void load(){ ArchiveModules& archiveModules = FileSystemQ3API_getArchiveModules(); - bool is_dpk_vfs = GetArchiveTable( archiveModules, "dpk" ); + bool is_dpk_vfs = !!GetArchiveTable( archiveModules, "dpk" ); if ( is_dpk_vfs ) { const char* pakname; g_loaded_dpk_paks.clear(); - pakname = GetLatestDpkPakVersion( "tex-common" ); - if (pakname != NULL) { - LoadDpkPakWithDeps( pakname ); - } + // Load DEPS from game pack + LoadDpkPakWithDeps( NULL ); // prevent VFS double start, for MapName="" and MapName="unnamed.map" if ( string_length( GlobalRadiant().getMapName() ) ){ @@ -900,6 +943,9 @@ Archive* getArchive( const char* archiveName, bool pakonly ){ if ( path_equal( ( *i ).name.c_str(), archiveName ) ) { return ( *i ).archive; } + else if ( path_equal( path_get_filename_start( ( *i ).name.c_str() ), archiveName ) ) { + return ( *i ).archive; + } } return 0; }