X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=plugins%2Fvfspk3%2Fvfs.cpp;h=1cd50a31bd9cf7ed852e6a9f2a7477d0c4ee38da;hb=650279d27dcea9bf35dc01eb17531e8c661aa3fa;hp=a76fafbaabe211c3ae04262538c9847327c56195;hpb=07d0b8aa640d00454991ea04c61b4e460de03ea3;p=xonotic%2Fnetradiant.git diff --git a/plugins/vfspk3/vfs.cpp b/plugins/vfspk3/vfs.cpp index a76fafba..1cd50a31 100644 --- a/plugins/vfspk3/vfs.cpp +++ b/plugins/vfspk3/vfs.cpp @@ -42,6 +42,7 @@ // #include "vfs.h" +#include "globaldefs.h" #include #include @@ -59,11 +60,12 @@ ArchiveModules& FileSystemQ3API_getArchiveModules(); #include "os/path.h" #include "moduleobservers.h" #include "filematch.h" +#include "dpkdeps.h" -#define VFS_MAXDIRS 64 +const int VFS_MAXDIRS = 64; -#if defined( WIN32 ) +#if GDEF_OS_WINDOWS #define PATH_MAX 260 #endif @@ -322,60 +324,6 @@ void AddDpkPak( const char* name, const char* fullpath, bool is_pakfile ){ g_pakfile_paths.insert( PakfilePathsKV( name, pakfile_path ) ); } -// Comparaison function for version numbers -// Implementation is based on dpkg's version comparison code (verrevcmp() and order()) -// http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=blob;f=lib/dpkg/version.c;hb=74946af470550a3295e00cf57eca1747215b9311 -static int char_weight(char c){ - if (std::isdigit(c)) - return 0; - else if (std::isalpha(c)) - return c; - else if (c == '~') - return -1; - else if (c) - return c + 256; - else - return 0; -} - -static int VersionCmp(const char* a, const char* b){ - while (*a || *b) { - int firstDiff = 0; - - while ((*a && !std::isdigit(*a)) || (*b && !std::isdigit(*b))) { - int ac = char_weight(*a); - int bc = char_weight(*b); - - if (ac != bc) - return ac - bc; - - a++; - b++; - } - - while (*a == '0') - a++; - while (*b == '0') - b++; - - while (std::isdigit(*a) && std::isdigit(*b)) { - if (firstDiff == 0) - firstDiff = *a - *b; - a++; - b++; - } - - if (std::isdigit(*a)) - return 1; - if (std::isdigit(*b)) - return -1; - if (firstDiff) - return firstDiff; - } - - return false; -} - // takes name without ext, returns without ext static const char* GetLatestDpkPakVersion( const char* name ){ const char* maxversion = 0; @@ -389,7 +337,7 @@ static const char* GetLatestDpkPakVersion( const char* name ){ pakname = i->first.c_str(); if ( strncmp( pakname, name, namelen ) != 0 || pakname[namelen] != '_' ) continue; pakversion = pakname + (namelen + 1); - if ( maxversion == 0 || VersionCmp( pakversion, maxversion ) > 0 ){ + if ( maxversion == 0 || DpkPakVersionCmp( pakversion, maxversion ) > 0 ){ maxversion = pakversion; result = pakname; } @@ -430,62 +378,64 @@ 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 + StringOutputStream baseDirectory( 256 ); + const char* basegame = GlobalRadiant().getRequiredGameDescriptionKeyValue( "basegame" ); + baseDirectory << GlobalRadiant().getGameToolsPath() << basegame << '/'; + 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(); CopiedString line; - const char* c; - const char* p_name; - const char* p_name_end; - const char* p_version; - const char* p_version_end; + char *p_name; + char *p_version; while ( line = istream.readLine(), string_length( line.c_str() ) ) { - c = line.c_str(); - while ( std::isspace( *c ) && *c != '\0' ) ++c; - p_name = c; - while ( !std::isspace( *c ) && *c != '\0' ) ++c; - p_name_end = c; - while ( std::isspace( *c ) && *c != '\0' ) ++c; - p_version = c; - while ( !std::isspace( *c ) && *c != '\0' ) ++c; - p_version_end = c; - - if ( p_name_end - p_name == 0 ) continue; - if ( p_version_end - p_version == 0 ) { - const char* p_pakname; - CopiedString name_final = CopiedString( StringRange( p_name, p_name_end ) ); - p_pakname = GetLatestDpkPakVersion( name_final.c_str() ); - if ( p_pakname != NULL ) { - LoadDpkPakWithDeps( p_pakname ); - } + if ( !DpkReadDepsLine( line.c_str(), &p_name, &p_version ) ) continue; + if ( !p_version ) { + const char* p_latest = GetLatestDpkPakVersion( p_name ); + if ( p_latest ) LoadDpkPakWithDeps( p_latest ); } else { - int len = ( p_name_end - p_name ) + ( p_version_end - p_version ) + 1; + int len = string_length( p_name ) + string_length( p_version ) + 1; char* p_pakname = string_new( len ); - strncpy( p_pakname, p_name, p_name_end - p_name ); - p_pakname[ p_name_end - p_name ] = '\0'; - strcat( p_pakname, "_" ); - strncat( p_pakname, p_version, p_version_end - p_version ); + sprintf( p_pakname, "%s_%s", p_name, p_version ); LoadDpkPakWithDeps( p_pakname ); string_release( p_pakname, len ); } + string_release( p_name, string_length( p_name ) ); + if ( p_version ) string_release( p_version, string_length( p_version ) ); } } @@ -717,8 +667,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; @@ -734,8 +684,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; } @@ -848,6 +798,12 @@ void initDirectory( const char *path ){ InitDirectory( path, FileSystemQ3API_getArchiveModules() ); } void initialise(){ + load(); + globalOutputStream() << "filesystem initialised\n"; + g_observers.realise(); +} + +void load(){ ArchiveModules& archiveModules = FileSystemQ3API_getArchiveModules(); bool is_dpk_vfs = GetArchiveTable( archiveModules, "dpk" ); @@ -855,10 +811,8 @@ void initialise(){ 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() ) ){ @@ -873,10 +827,19 @@ void initialise(){ g_pakfile_paths.clear(); g_loaded_dpk_paks.clear(); } +} - globalOutputStream() << "filesystem initialised\n"; - g_observers.realise(); +void clear() { + // like shutdown() but does not unrealise (keep map etc.) + Shutdown(); +} + +void refresh(){ + // like initialise() but does not realise (keep map etc.) + load(); + globalOutputStream() << "filesystem refreshed\n"; } + void shutdown(){ g_observers.unrealise(); globalOutputStream() << "filesystem shutdown\n";