From: Holger Schemel Date: Thu, 10 Jan 2019 23:07:45 +0000 (+0100) Subject: added extracting level and artwork sets from zip files dropped into window X-Git-Tag: 4.1.2.0~54 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=f11d2545f41637e871283f7624dccc8243d05138;p=rocksndiamonds.git added extracting level and artwork sets from zip files dropped into window --- diff --git a/src/events.c b/src/events.c index f8a888ad..90f6615a 100644 --- a/src/events.c +++ b/src/events.c @@ -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) diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 1ae27900..eec6cb5a 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -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); diff --git a/src/libgame/setup.h b/src/libgame/setup.h index 64f51d13..40e2a964 100644 --- a/src/libgame/setup.h +++ b/src/libgame/setup.h @@ -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); diff --git a/src/libgame/system.h b/src/libgame/system.h index 0e67600c..ffb8f185 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -711,6 +711,7 @@ #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 "" @@ -732,6 +733,16 @@ 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 ? \