]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/vfspk3/vfs.cpp
more compile fail
[xonotic/netradiant.git] / plugins / vfspk3 / vfs.cpp
index 688374830ea7727ab8adf9eca47a8ac72ffa6bbb..bea0adb44079912412f58a091de3567d92a753e9 100644 (file)
@@ -60,9 +60,10 @@ ArchiveModules& FileSystemQ3API_getArchiveModules();
 #include "stream/stringstream.h"
 #include "os/path.h"
 #include "moduleobservers.h"
+#include "filematch.h"
 
 
-#define VFS_MAXDIRS 8
+#define VFS_MAXDIRS 64
 
 #if defined(WIN32)
 #define PATH_MAX 260
@@ -91,6 +92,8 @@ typedef std::list<archive_entry_t> archives_t;
 static archives_t g_archives;
 static char    g_strDirs[VFS_MAXDIRS][PATH_MAX+1];
 static int     g_numDirs;
+static char    g_strForbiddenDirs[VFS_MAXDIRS][PATH_MAX+1];
+static int     g_numForbiddenDirs = 0;
 static bool    g_bUsePak = true;
 
 ModuleObservers g_observers;
@@ -297,7 +300,34 @@ typedef std::set<CopiedString, PakLess> Archives;
 // reads all pak files from a dir
 void InitDirectory(const char* directory, ArchiveModules& archiveModules)
 {
-  if (g_numDirs == (VFS_MAXDIRS-1))
+  int j;
+
+  g_numForbiddenDirs = 0;
+  StringTokeniser st(GlobalRadiant().getGameDescriptionKeyValue("forbidden_paths"), " ");
+  for(j = 0; j < VFS_MAXDIRS; ++j)
+  {
+    const char *t = st.getToken();
+    if(string_empty(t))
+      break;
+    strncpy(g_strForbiddenDirs[g_numForbiddenDirs], t, PATH_MAX);
+    g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = '\0';
+    ++g_numForbiddenDirs;
+  }
+
+  for(j = 0; j < g_numForbiddenDirs; ++j)
+  {
+    const char *p = strrchr(directory, '/');
+    p = (p ? (p+1) : directory);
+    if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
+      break;
+  }
+  if(j < g_numForbiddenDirs)
+  {
+    printf("Directory %s matched by forbidden dirs, removed\n", directory);
+    return;
+  }
+
+  if (g_numDirs == VFS_MAXDIRS)
     return;
 
   strncpy(g_strDirs[g_numDirs], directory, PATH_MAX);
@@ -352,7 +382,33 @@ void InitDirectory(const char* directory, ArchiveModules& archiveModules)
         if(name == 0)
           break;
 
+       for(j = 0; j < g_numForbiddenDirs; ++j)
+         if(!string_compare_nocase_upper(name, g_strForbiddenDirs[j]))
+           break;
+       if(j < g_numForbiddenDirs)
+         continue;
+
         const char *ext = strrchr (name, '.');
+
+       if(ext && !string_compare_nocase_upper(ext, ".pk3dir"))
+       {
+         if (g_numDirs == VFS_MAXDIRS)
+           continue;
+         snprintf(g_strDirs[g_numDirs], PATH_MAX, "%s%s/", path, name);
+         g_strDirs[g_numDirs][PATH_MAX] = '\0';
+         FixDOSName (g_strDirs[g_numDirs]);
+         AddSlash (g_strDirs[g_numDirs]);
+         g_numDirs++;
+
+         {
+           archive_entry_t entry;
+           entry.name = g_strDirs[g_numDirs-1];
+           entry.archive = OpenArchive(g_strDirs[g_numDirs-1]);
+           entry.is_pakfile = false;
+           g_archives.push_back(entry);
+         }
+       }
+
         if ((ext == 0) || *(++ext) == '\0' || GetArchiveTable(archiveModules, ext) == 0)
           continue;
 
@@ -407,6 +463,7 @@ void Shutdown()
   g_archives.clear();
 
   g_numDirs = 0;
+  g_numForbiddenDirs = 0;
 }
 
 #define VFS_SEARCH_PAK 0x1
@@ -532,15 +589,15 @@ const char* FindFile(const char* relative)
 
 const char* FindPath(const char* absolute)
 {
+  const char *best = "";
   for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
   {
-    if(path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str())))
-    {
-      return (*i).name.c_str();
-    }
+       if(string_length((*i).name.c_str()) > string_length(best))
+      if(path_equal_n(absolute, (*i).name.c_str(), string_length((*i).name.c_str())))
+        best = (*i).name.c_str();
   }
 
-  return "";
+  return best;
 }
 
 
@@ -641,29 +698,33 @@ public:
     g_observers.detach(observer);
   }
 
-  Archive* getArchive(const char* archiveName)
+  Archive* getArchive(const char* archiveName, bool pakonly)
   {
     for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
     {
-      if((*i).is_pakfile)
-      {
-        if(path_equal((*i).name.c_str(), archiveName))
-        {
-          return (*i).archive;
-        }
-      }
+      if(pakonly && !(*i).is_pakfile)
+        continue;
+
+      if(path_equal((*i).name.c_str(), archiveName))
+        return (*i).archive;
     }
     return 0;
   }
-  void forEachArchive(const ArchiveNameCallback& callback)
+  void forEachArchive(const ArchiveNameCallback& callback, bool pakonly, bool reverse)
   {
+    if (reverse)
+      g_archives.reverse();
+
     for(archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i)
     {
-      if((*i).is_pakfile)
-      {
-        callback((*i).name.c_str());
-      }
+      if(pakonly && !(*i).is_pakfile)
+        continue;
+
+      callback((*i).name.c_str());
     }
+
+    if (reverse)
+      g_archives.reverse();
   }
 };