added extracting level and artwork sets from zip files dropped into window
authorHolger Schemel <info@artsoft.org>
Thu, 10 Jan 2019 23:07:45 +0000 (00:07 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 12 Jan 2019 20:09:43 +0000 (21:09 +0100)
src/events.c
src/libgame/setup.c
src/libgame/setup.h
src/libgame/system.h

index f8a888ade1161aafedc37b655bd711f8a5d9858b..90f6615a20f61ee0647a61f58f03b0b586d17791 100644 (file)
@@ -1529,6 +1529,21 @@ void HandleClientMessageEvent(ClientMessageEvent *event)
 static void HandleDropFileEventExt(char *filename)
 {
   Error(ERR_DEBUG, "DROP FILE EVENT: '%s'", filename);
+
+  // check and extract dropped zip files into correct user data directory
+  if (strSuffixLower(filename, ".zip"))
+  {
+    int tree_type = GetZipFileTreeType(filename);
+    char *directory = TREE_USERDIR(tree_type);
+
+    if (directory == NULL)
+    {
+      Error(ERR_WARN, "zip file '%s' has invalid content!", filename);
+
+      return;
+    }
+
+    ExtractZipFileIntoDirectory(filename, directory, tree_type);
 }
 
 static void HandleDropTextEventExt(char *text)
index 1ae27900c05b0e6e183268632491e9e0f7788c17..eec6cb5a6ca1f6b5d187037bc32dcf35ebc172e5 100644 (file)
@@ -340,7 +340,7 @@ static char *getClassicArtworkDir(int type)
          getDefaultMusicDir(MUS_CLASSIC_SUBDIR) : "");
 }
 
-static char *getUserGraphicsDir(void)
+char *getUserGraphicsDir(void)
 {
   static char *usergraphics_dir = NULL;
 
@@ -350,7 +350,7 @@ static char *getUserGraphicsDir(void)
   return usergraphics_dir;
 }
 
-static char *getUserSoundsDir(void)
+char *getUserSoundsDir(void)
 {
   static char *usersounds_dir = NULL;
 
@@ -360,7 +360,7 @@ static char *getUserSoundsDir(void)
   return usersounds_dir;
 }
 
-static char *getUserMusicDir(void)
+char *getUserMusicDir(void)
 {
   static char *usermusic_dir = NULL;
 
@@ -2982,6 +2982,73 @@ static void setArtworkInfoCacheEntry(TreeInfo *artwork_info,
 // functions for loading level info and custom artwork info
 // ----------------------------------------------------------------------------
 
+int GetZipFileTreeType(char *zip_filename)
+{
+  static char *top_dir_path = NULL;
+  static char *top_dir_conf_filename[NUM_BASE_TREE_TYPES] = { NULL };
+  static char *conf_basename[NUM_BASE_TREE_TYPES] =
+  {
+    GRAPHICSINFO_FILENAME,
+    SOUNDSINFO_FILENAME,
+    MUSICINFO_FILENAME,
+    LEVELINFO_FILENAME
+  };
+  int j;
+
+  checked_free(top_dir_path);
+  top_dir_path = NULL;
+
+  for (j = 0; j < NUM_BASE_TREE_TYPES; j++)
+  {
+    checked_free(top_dir_conf_filename[j]);
+    top_dir_conf_filename[j] = NULL;
+  }
+
+  char **zip_entries = zip_list(zip_filename);
+
+  // check if zip file successfully opened
+  if (zip_entries == NULL || zip_entries[0] == NULL)
+    return TREE_TYPE_UNDEFINED;
+
+  // first zip file entry is expected to be top level directory
+  char *top_dir = zip_entries[0];
+
+  // check if valid top level directory found in zip file
+  if (!strSuffix(top_dir, "/"))
+    return TREE_TYPE_UNDEFINED;
+
+  // get filenames of valid configuration files in top level directory
+  for (j = 0; j < NUM_BASE_TREE_TYPES; j++)
+    top_dir_conf_filename[j] = getStringCat2(top_dir, conf_basename[j]);
+
+  int tree_type = TREE_TYPE_UNDEFINED;
+  int e = 0;
+
+  while (zip_entries[e] != NULL)
+  {
+    // check if every zip file entry is below top level directory
+    if (!strPrefix(zip_entries[e], top_dir))
+      return TREE_TYPE_UNDEFINED;
+
+    // check if this zip file entry is a valid configuration filename
+    for (j = 0; j < NUM_BASE_TREE_TYPES; j++)
+    {
+      if (strEqual(zip_entries[e], top_dir_conf_filename[j]))
+      {
+       // only exactly one valid configuration file allowed
+       if (tree_type != TREE_TYPE_UNDEFINED)
+         return TREE_TYPE_UNDEFINED;
+
+       tree_type = j;
+      }
+    }
+
+    e++;
+  }
+
+  return tree_type;
+}
+
 static boolean CheckZipFileForDirectory(char *zip_filename, char *directory,
                                        int tree_type)
 {
@@ -3051,8 +3118,8 @@ static boolean CheckZipFileForDirectory(char *zip_filename, char *directory,
   return TRUE;
 }
 
-static boolean ExtractZipFileIntoDirectory(char *zip_filename, char *directory,
-                                          int tree_type)
+boolean ExtractZipFileIntoDirectory(char *zip_filename, char *directory,
+                                   int tree_type)
 {
   boolean zip_file_valid = CheckZipFileForDirectory(zip_filename, directory,
                                                    tree_type);
index 64f51d1304e512f67833db278b958417555ac9a7..40e2a9641b33b06b2b96701d205d8a3abf76eca0 100644 (file)
@@ -226,6 +226,9 @@ typedef struct hashtable     SetupFileHash;
                         ARTWORKCLASS_UNDEFINED)
 
 
+char *getUserGraphicsDir(void);
+char *getUserSoundsDir(void);
+char *getUserMusicDir(void);
 char *setLevelArtworkDir(TreeInfo *);
 char *getProgramMainDataPath(char *, char *);
 char *getProgramConfigFilename(char *);
@@ -314,6 +317,9 @@ char *getSetupLine(struct TokenInfo *, char *, int);
 
 unsigned int get_hash_from_key(void *);
 
+int GetZipFileTreeType(char *);
+boolean ExtractZipFileIntoDirectory(char *, char *, int);
+
 boolean AdjustGraphicsForEMC(void);
 
 void LoadLevelInfo(void);
index 0e67600c6b478fa589f5c80ff850790aa7d66a97..ffb8f185c41ff7bca179531e9c95b6fc3706c64e 100644 (file)
 #define TREE_TYPE_LEVEL_DIR    3
 #define TREE_TYPE_LEVEL_NR     4
 
+#define NUM_BASE_TREE_TYPES    4
 #define NUM_TREE_TYPES         5
 
 #define INFOTEXT_UNDEFINED     ""
                                 INFOTEXT_MUSIC_DIR :                   \
                                 INFOTEXT_UNDEFINED)
 
+#define TREE_USERDIR(t)                ((t) == TREE_TYPE_LEVEL_DIR ?           \
+                                getUserLevelDir(NULL) :                \
+                                (t) == TREE_TYPE_GRAPHICS_DIR ?        \
+                                getUserGraphicsDir() :                 \
+                                (t) == TREE_TYPE_SOUNDS_DIR ?          \
+                                getUserSoundsDir() :                   \
+                                (t) == TREE_TYPE_MUSIC_DIR ?           \
+                                getUserMusicDir() :                    \
+                                NULL)
+
 // values for artwork handling
 #define LEVELDIR_ARTWORK_SET_PTR(leveldir, type)                       \
                                ((type) == ARTWORK_TYPE_GRAPHICS ?      \