X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=2eca885ac16b27fb5ced808c25871f15239dd250;hb=34df5c161045d8dddfd1c24d7fb1cfa29e0a9746;hp=1ae27900c05b0e6e183268632491e9e0f7788c17;hpb=c3e0f340f3ba490911b5e1dce7d9902b01afc207;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 1ae27900..2eca885a 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,28 +3118,37 @@ static boolean CheckZipFileForDirectory(char *zip_filename, char *directory, return TRUE; } -static boolean ExtractZipFileIntoDirectory(char *zip_filename, char *directory, - int tree_type) +char *ExtractZipFileIntoDirectory(char *zip_filename, char *directory, + int tree_type) { boolean zip_file_valid = CheckZipFileForDirectory(zip_filename, directory, tree_type); - Error(ERR_DEBUG, "zip file '%s': %s", zip_filename, - (zip_file_valid ? "EXTRACT" : "REJECT")); - if (!zip_file_valid) - return FALSE; + { + Error(ERR_WARN, "zip file '%s' rejected!", zip_filename); + + return NULL; + } char **zip_entries = zip_extract(zip_filename, directory); - boolean zip_file_extracted = (zip_entries != NULL); + if (zip_entries == NULL) + { + Error(ERR_WARN, "zip file '%s' could not be extracted!", zip_filename); - if (zip_file_extracted) - Error(ERR_DEBUG, "zip file successfully extracted!"); - else - Error(ERR_DEBUG, "zip file could not be extracted!"); + return NULL; + } - return zip_file_extracted; + Error(ERR_INFO, "zip file '%s' successfully extracted!", zip_filename); + + // first zip file entry contains top level directory + char *top_dir = zip_entries[0]; + + // remove trailing directory separator from top level directory + top_dir[strlen(top_dir) - 1] = '\0'; + + return top_dir; } static void ProcessZipFilesInDirectory(char *directory, int tree_type) @@ -3104,10 +3180,9 @@ static void ProcessZipFilesInDirectory(char *directory, int tree_type) if (!fileExists(zip_filename_extracted) && !fileExists(zip_filename_rejected)) { - boolean zip_file_extracted = ExtractZipFileIntoDirectory(zip_filename, - directory, - tree_type); - char *marker_filename = (zip_file_extracted ? zip_filename_extracted : + char *top_dir = ExtractZipFileIntoDirectory(zip_filename, directory, + tree_type); + char *marker_filename = (top_dir != NULL ? zip_filename_extracted : zip_filename_rejected); FILE *marker_file; @@ -3828,6 +3903,47 @@ void AddUserLevelSetToLevelInfo(char *level_subdir_new) Error(ERR_EXIT, "internal level set structure corrupted -- aborting"); } +static boolean AddUserArtworkSetToArtworkInfoExt(char *artwork_subdir_new, + int type) +{ + // get artwork info tree node of first artwork set + TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type); + char *artwork_user_dir = USER_ARTWORK_DIRECTORY(type); + + int draw_deactivation_mask = GetDrawDeactivationMask(); + + // override draw deactivation mask (temporarily disable drawing) + SetDrawDeactivationMask(REDRAW_ALL); + + // load new artwork set config and add it next to first artwork set + LoadArtworkInfoFromArtworkConf(&artwork_first_node->next, NULL, + artwork_user_dir, artwork_subdir_new, type); + + // set draw deactivation mask to previous value + SetDrawDeactivationMask(draw_deactivation_mask); + + // get artwork info tree node of newly added artwork set + LevelDirTree *artwork_new = getTreeInfoFromIdentifier(artwork_first_node, + artwork_subdir_new); + if (artwork_new == NULL) // should not happen + return FALSE; + + // correct top link and parent node link of newly created tree node + artwork_new->node_top = artwork_first_node->node_top; + artwork_new->node_parent = artwork_first_node->node_parent; + + // sort artwork info tree to adjust position of newly added artwork set + sortTreeInfo(&artwork_first_node); + + return TRUE; +} + +void AddUserArtworkSetToArtworkInfo(char *artwork_subdir_new, int type) +{ + if (!AddUserArtworkSetToArtworkInfoExt(artwork_subdir_new, type)) + Error(ERR_EXIT, "internal artwork set structure corrupted -- aborting"); +} + char *getArtworkIdentifierForUserLevelSet(int type) { char *classic_artwork_set = getClassicArtworkSet(type);