diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/itemdb.c | 187 | ||||
-rw-r--r-- | src/map/itemdb.h | 4 |
2 files changed, 76 insertions, 115 deletions
diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 204d0ead5..3aae2c90c 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1531,138 +1531,99 @@ static void itemdb_read_chains(void) ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename); } -/** - * @return: amount of retrieved entries. - **/ -static int itemdb_combo_split_atoi(char *str, int *val) +static bool itemdb_read_combodb_libconfig(void) { - int i; - - nullpo_ret(val); + struct config_t combo_conf; + char filepath[256]; + safesnprintf(filepath, sizeof(filepath), "%s/%s/%s", map->db_path, DBPATH, "item_combo_db.conf"); - for (i=0; i<MAX_ITEMS_PER_COMBO; i++) { - if (!str) break; + if (libconfig->load_file(&combo_conf, filepath) == CONFIG_FALSE) { + ShowError("itemdb_read_combodb_libconfig: can't read %s\n", filepath); + return false; + } - val[i] = atoi(str); - str = strchr(str,':'); - if (str) - *str++=0; + struct config_setting_t *combo_db = NULL; + if ((combo_db = libconfig->setting_get_member(combo_conf.root, "combo_db")) == NULL) { + ShowError("itemdb_read_combodb_libconfig: can't read %s\n", filepath); + return false; } - if( i == 0 ) //No data found. - return 0; + int i = 0; + int count = 0; + struct config_setting_t *it = NULL; - return i; + while ((it = libconfig->setting_get_elem(combo_db, i++)) != NULL) { + if (itemdb->read_combodb_libconfig_sub(it, i - 1, filepath)) + ++count; + } + + libconfig->destroy(&combo_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath); + return true; } -/** - * <combo{:combo{:combo:{..}}}>,<{ script }> - **/ -static void itemdb_read_combos(void) + +static bool itemdb_read_combodb_libconfig_sub(struct config_setting_t *it, int idx, const char *source) { - uint32 lines = 0, count = 0; - char line[1024]; - char filepath[256]; - FILE* fp; + nullpo_retr(false, it); + nullpo_retr(false, source); - safesnprintf(filepath, 256, "%s/%s", map->db_path, DBPATH"item_combo_db.txt"); + struct config_setting_t *t = NULL; - if ((fp = fopen(filepath, "r")) == NULL) { - ShowError("itemdb_read_combos: File not found \"%s\".\n", filepath); - return; + if ((t = libconfig->setting_get_member(it, "Items")) == NULL) { + ShowWarning("itemdb_read_combodb_libconfig_sub: invalid item list for combo (%d), in (%s), skipping..\n", idx, source); + return false; } - // process rows one by one - while(fgets(line, sizeof(line), fp)) { - char *str[2], *p; - - lines++; - - if (line[0] == '/' && line[1] == '/') - continue; - - memset(str, 0, sizeof(str)); + if (!config_setting_is_array(t)) { + ShowWarning("itemdb_read_combodb_libconfig_sub: the combo (%d) item list must be an array, in (%s), skipping..\n", idx, source); + return false; + } - p = line; - p = trim(p); - if (*p == '\0') - continue;// empty line + int len = libconfig->setting_length(t); + if (len > MAX_ITEMS_PER_COMBO) { + ShowWarning("itemdb_read_combodb_libconfig_sub: the size of combo (%d) item list is too big (%d, max = %d), in (%s), skipping..\n", idx, len, MAX_ITEMS_PER_COMBO, source); + return false; + } - if (!strchr(p,',')) { - /* is there even a single column? */ - ShowError("itemdb_read_combos: Insufficient columns in line %u of \"%s\", skipping.\n", lines, filepath); - continue; - } + struct item_combo *combo = NULL; + RECREATE(itemdb->combos, struct item_combo *, ++itemdb->combo_count); + CREATE(combo, struct item_combo, 1); - str[0] = p; - p = strchr(p,','); - *p = '\0'; - p++; + combo->id = itemdb->combo_count - 1; + combo->count = len; - str[1] = p; - p = strchr(p,','); - p++; + for (int i = 0; i < len; i++) { + struct item_data *item = NULL; + const char *name = libconfig->setting_get_string_elem(t, i); - if (str[1][0] != '{') { - ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %u of \"%s\", skipping.\n", lines, filepath); - continue; + if ((item = itemdb->name2id(name)) == NULL) { + ShowWarning("itemdb_read_combodb_libconfig_sub: unknown item '%s', in (%s), skipping..\n", name, source); + --itemdb->combo_count; + aFree(combo); + return false; } + combo->nameid[i] = item->nameid; + } - /* no ending key anywhere (missing \}\) */ - if ( str[1][strlen(str[1])-1] != '}' ) { - ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %u of \"%s\", skipping.\n", lines, filepath); - continue; - } else { - int items[MAX_ITEMS_PER_COMBO]; - int v = 0, retcount = 0; - struct item_combo *combo = NULL; - - if((retcount = itemdb->combo_split_atoi(str[0], items)) < 2) { - ShowError("itemdb_read_combos: line %u of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, filepath); - continue; - } - - /* validate */ - for(v = 0; v < retcount; v++) { - if( !itemdb->exists(items[v]) ) { - ShowError("itemdb_read_combos: line %u of \"%s\" contains unknown item ID %d, skipping.\n", lines, filepath, items[v]); - break; - } - } - /* failed at some item */ - if( v < retcount ) - continue; - - RECREATE(itemdb->combos, struct item_combo*, ++itemdb->combo_count); - - CREATE(combo, struct item_combo, 1); - - combo->count = retcount; - combo->script = script->parse(str[1], filepath, lines, 0, NULL); - combo->id = itemdb->combo_count - 1; - /* populate ->nameid field */ - for( v = 0; v < retcount; v++ ) { - combo->nameid[v] = items[v]; - } - - itemdb->combos[itemdb->combo_count - 1] = combo; + const char *str = NULL; + if (libconfig->setting_lookup_string(it, "Script", &str) == CONFIG_TRUE) { + combo->script = *str ? script->parse(str, source, -idx, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + } else { + ShowWarning("itemdb_read_combodb_libconfig_sub: invalid script for combo (%d) in (%s), skipping..\n", idx, source); + --itemdb->combo_count; + aFree(combo); + return false; + } - /* populate the items to refer to this combo */ - for( v = 0; v < retcount; v++ ) { - struct item_data * it; - int index; + itemdb->combos[combo->id] = combo; - it = itemdb->exists(items[v]); - index = it->combos_count; - RECREATE(it->combos, struct item_combo*, ++it->combos_count); - it->combos[index] = combo; - } - } - count++; + /* populate the items to refer to this combo */ + for (int i = 0; i < len; i++) { + struct item_data *item = itemdb->exists(combo->nameid[i]); + RECREATE(item->combos, struct item_combo *, ++item->combos_count); + item->combos[item->combos_count - 1] = combo; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%"PRIu32""CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, DBPATH"item_combo_db.txt"); - - return; + return true; } /*====================================== @@ -2492,7 +2453,7 @@ static void itemdb_read(bool minimal) itemdb->name_constants(); - itemdb->read_combos(); + itemdb->read_combodb_libconfig(); itemdb->read_groups(); itemdb->read_chains(); itemdb->read_packages(); @@ -2840,8 +2801,8 @@ void itemdb_defaults(void) itemdb->isrestricted = itemdb_isrestricted; itemdb->isidentified = itemdb_isidentified; itemdb->isidentified2 = itemdb_isidentified2; - itemdb->combo_split_atoi = itemdb_combo_split_atoi; - itemdb->read_combos = itemdb_read_combos; + itemdb->read_combodb_libconfig = itemdb_read_combodb_libconfig; + itemdb->read_combodb_libconfig_sub = itemdb_read_combodb_libconfig_sub; itemdb->gendercheck = itemdb_gendercheck; itemdb->validate_entry = itemdb_validate_entry; itemdb->readdb_options_additional_fields = itemdb_readdb_options_additional_fields; diff --git a/src/map/itemdb.h b/src/map/itemdb.h index d1e5973e8..16a348797 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -668,8 +668,8 @@ struct itemdb_interface { int (*isrestricted) (struct item *item, int gmlv, int gmlv2, int(*func)(struct item_data *, int, int)); int (*isidentified) (int nameid); int (*isidentified2) (struct item_data *data); - int (*combo_split_atoi) (char *str, int *val); - void (*read_combos) (void); + bool (*read_combodb_libconfig) (void); + bool (*read_combodb_libconfig_sub) (struct config_setting_t *it, int idx, const char *source); int (*gendercheck) (struct item_data *id); int (*validate_entry) (struct item_data *entry, int n, const char *source); void (*readdb_options_additional_fields) (struct itemdb_option *ito, struct config_setting_t *t, const char *source); |