From 5b983fc43b2f632a51ddbeef360e2462ad3ca055 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 11 Feb 2016 16:35:08 +0100 Subject: Ported npc config to libconfig Ported to modern Hercules and cleaned up from Panikon's commits: ca009582cb22340951aa3e86c044ec1dca05df36, 6d6adf9bab2ba6f4274395018b8def566b880197 Signed-off-by: Haru --- src/map/map.c | 117 ++++++++++++++++++++++++++++++++++++++++------------------ src/map/map.h | 2 +- 2 files changed, 83 insertions(+), 36 deletions(-) (limited to 'src/map') diff --git a/src/map/map.c b/src/map/map.c index 37885cd0b..a6e19d88f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -4113,44 +4113,91 @@ bool map_config_read(const char *filename, bool imported) return retval; } -void map_reloadnpc_sub(char *cfgName) { - char line[1024], w1[1024], w2[1024]; - FILE *fp; - - nullpo_retv(cfgName); - fp = fopen(cfgName,"r"); - if (fp == NULL) { - ShowError("Map configuration file not found at: %s\n", cfgName); - return; +/** + * Reads 'npc_global_list'/'npc_removed_list' and adds or removes NPC sources + * from map-server. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool map_read_npclist(const char *filename, bool imported) +{ + struct config_t config; + struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; + + struct DBMap *deleted_npcs; + + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + deleted_npcs = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY, MAP_NAME_LENGTH); + + // Remove maps + if ((setting = libconfig->lookup(&config, "npc_removed_list")) != NULL) { + int i, del_count = libconfig->setting_length(setting); + for (i = 0; i < del_count; i++) { + const char *scriptname; + + if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0') + continue; + + strdb_put(deleted_npcs, scriptname, NULL); + + if (imported) // Map list is empty on the first run, only do this for imported files. + npc->delsrcfile(scriptname); + } } - while (fgets(line, sizeof(line), fp)) { - char* ptr; + if ((setting = libconfig->lookup(&config, "npc_global_list")) != NULL) { + int i, count = libconfig->setting_length(setting); + if (count <= 0) { + if (!imported) { + ShowWarning("map_read_npclist: no NPCs found in %s!\n", filename); + retval = false; + } + } + for (i = 0; i < count; i++) { + const char *scriptname; - if (line[0] == '/' && line[1] == '/') - continue; - if ((ptr = strstr(line, "//")) != NULL) - *ptr = '\n'; //Strip comments - if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2) - continue; + if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0') + continue; - //Strip trailing spaces - ptr = w2 + strlen(w2); - while (--ptr >= w2 && *ptr == ' '); - ptr++; - *ptr = '\0'; - - if (strcmpi(w1, "npc") == 0) - npc->addsrcfile(w2); - else if (strcmpi(w1, "import") == 0) - map->reloadnpc_sub(w2); - else if (strcmpi(w1, "delnpc") == 0) - npc->delsrcfile(w2); - else - ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName); + if (strdb_exists(deleted_npcs, scriptname)) + continue; + + npc->addsrcfile(scriptname); + } + } else { + ShowError("map_read_npclist: npc_global_list was not found in %s!\n", filename); + retval = false; } - fclose(fp); + db_destroy(deleted_npcs); + + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + const char *base_npclist = NULL; +#ifdef RENEWAL + base_npclist = "npc/re/scripts_main.conf"; +#else + base_npclist = "npc/pre-re/scripts_main.conf"; +#endif + if (strcmp(import, filename) == 0 || strcmp(import, base_npclist) == 0) { + ShowWarning("map_read_npclist: Loop detected! Skipping 'import'...\n"); + } else { + if (!map->read_npclist(import, true)) + retval = false; + } + } + + libconfig->destroy(&config); + return retval; } /** @@ -4164,9 +4211,9 @@ void map_reloadnpc(bool clear) { npc->addsrcfile("clear"); // this will clear the current script list #ifdef RENEWAL - map->reloadnpc_sub("npc/re/scripts_main.conf"); + map->read_npclist("npc/re/scripts_main.conf", false); #else - map->reloadnpc_sub("npc/pre-re/scripts_main.conf"); + map->read_npclist("npc/pre-re/scripts_main.conf", false); #endif // Append extra scripts @@ -6754,7 +6801,7 @@ void map_defaults(void) { map->readgat = map_readgat; map->readallmaps = map_readallmaps; map->config_read = map_config_read; - map->reloadnpc_sub = map_reloadnpc_sub; + map->read_npclist = map_read_npclist; map->inter_config_read = inter_config_read; map->inter_config_read_database_names = inter_config_read_database_names; map->inter_config_read_connection = inter_config_read_connection; diff --git a/src/map/map.h b/src/map/map.h index 6514ef0af..723691971 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1188,7 +1188,7 @@ END_ZEROED_BLOCK; int (*readgat) (struct map_data *m); int (*readallmaps) (void); bool (*config_read) (const char *filename, bool imported); - void (*reloadnpc_sub) (char *cfgName); + bool (*read_npclist) (const char *filename, bool imported); bool (*inter_config_read) (const char *filename, bool imported); bool (*inter_config_read_database_names) (const char *filename, const struct config_t *config, bool imported); bool (*inter_config_read_connection) (const char *filename, const struct config_t *config, bool imported); -- cgit v1.2.3-60-g2f50