From 7a276976948fa39e2d329de3b622c34dd0c572ad Mon Sep 17 00:00:00 2001
From: Haru <haru@dotalux.com>
Date: Sat, 20 Aug 2016 18:44:02 +0200
Subject: Re-added HPM support for configuration settings

Plugin settings should be relative to the the libconfig file root. For
example, a configuration setting of type HPCT_CHAR will be relative to
the root of conf/char/char-server.conf. In order to add a configuration
entry inside the char_configuration block, the full configuration path
(slash-delimited) should be passed to addCharConf(), as in the
following example:

`addCharConf("char_configuration/my_setting", my_parser_function);`

Signed-off-by: Haru <haru@dotalux.com>
---
 src/char/char.c   |  6 ++++--
 src/common/HPM.c  | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/common/HPM.h  |  3 ++-
 src/login/login.c |  3 ++-
 src/map/battle.c  |  2 +-
 src/map/log.c     |  3 ++-
 src/map/map.c     |  3 ++-
 src/map/script.c  |  3 ++-
 8 files changed, 73 insertions(+), 11 deletions(-)

(limited to 'src')

diff --git a/src/char/char.c b/src/char/char.c
index 6f79a55e3..712d7efb2 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -5399,7 +5399,8 @@ bool char_sql_config_read(const char *filename, bool imported)
 		}
 	}
 
-	// TODO HPM->parseConf(w1, w2, HPCT_CHAR_INTER);
+	if (!HPM->parse_conf(&config, filename, HPCT_CHAR_INTER, imported))
+		retval = false;
 
 	libconfig->destroy(&config);
 	return retval;
@@ -5553,7 +5554,8 @@ bool char_config_read(const char *filename, bool imported)
 	if (!pincode->config_read(filename, &config, imported))
 		retval = false;
 
-	// TODO HPM->parseConf(w1, w2, HPCT_CHAR);
+	if (!HPM->parse_conf(&config, filename, HPCT_CHAR, imported))
+		retval = false;
 
 	ShowInfo("Done reading %s.\n", filename);
 
diff --git a/src/common/HPM.c b/src/common/HPM.c
index a134a4822..dbe121940 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -826,7 +826,7 @@ char* HPM_astrdup(const char *p, const char *file, int line, const char *func) {
  * @retval true if a registered plugin was found to handle the entry.
  * @retval false if no registered plugins could be found.
  */
-bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType point)
+bool hplugins_parse_conf_entry(const char *w1, const char *w2, enum HPluginConfType point)
 {
 	int i;
 	ARR_FIND(0, VECTOR_LENGTH(HPM->config_listeners[point]), i, strcmpi(w1, VECTOR_INDEX(HPM->config_listeners[point], i).key) == 0);
@@ -860,13 +860,67 @@ bool hplugins_get_battle_conf(const char *w1, int *value)
 }
 
 /**
- * Parses battle config entries registered by plugins.
+ * Parses configuration entries registered by plugins.
  *
  * @param config   The configuration file to parse.
  * @param filename Path to configuration file.
+ * @param point    The type of configuration file.
  * @param imported Whether the current config is imported from another file.
  * @retval false in case of error.
  */
+bool hplugins_parse_conf(const struct config_t *config, const char *filename, enum HPluginConfType point, bool imported)
+{
+	const struct config_setting_t *setting = NULL;
+	int i, val, type;
+	char buf[1024];
+	bool retval = true;
+
+	nullpo_retr(false, config);
+
+	for (i = 0; i < VECTOR_LENGTH(HPM->config_listeners[point]); i++) {
+		const struct HPConfListenStorage *entry = &VECTOR_INDEX(HPM->config_listeners[point], i);
+		const char *config_name = entry->key;
+		const char *str = buf;
+		if ((setting = libconfig->lookup(config, config_name)) == NULL) {
+			if (!imported && entry->required) {
+				ShowWarning("Missing configuration '%s' in file %s!\n", config_name, filename);
+				retval = false;
+			}
+			continue;
+		}
+
+		switch ((type = config_setting_type(setting))) {
+		case CONFIG_TYPE_INT:
+			val = libconfig->setting_get_int(setting);
+			sprintf(buf, "%d", val); // FIXME: Remove this when support to int's as value is added
+			str = buf;
+			break;
+		case CONFIG_TYPE_BOOL:
+			val = libconfig->setting_get_bool(setting);
+			sprintf(buf, "%d", val); // FIXME: Remove this when support to int's as value is added
+			str = buf;
+			break;
+		case CONFIG_TYPE_STRING:
+			str = libconfig->setting_get_string(setting);
+			break;
+		default: // Unsupported type
+			ShowWarning("Setting %s has unsupported type %d, ignoring...\n", config_name, type);
+			retval = false;
+			continue;
+		}
+		entry->parse_func(config_name, str);
+	}
+	return retval;
+}
+
+/**
+ * parses battle config entries registered by plugins.
+ *
+ * @param config   the configuration file to parse.
+ * @param filename path to configuration file.
+ * @param imported whether the current config is imported from another file.
+ * @retval false in case of error.
+ */
 bool hplugins_parse_battle_conf(const struct config_t *config, const char *filename, bool imported)
 {
 	const struct config_setting_t *setting = NULL;
@@ -1120,7 +1174,8 @@ void hpm_defaults(void)
 	HPM->pid2name = hplugins_id2name;
 	HPM->parse_packets = hplugins_parse_packets;
 	HPM->load_sub = NULL;
-	HPM->parseConf = hplugins_parse_conf;
+	HPM->parse_conf_entry = hplugins_parse_conf_entry;
+	HPM->parse_conf = hplugins_parse_conf;
 	HPM->parse_battle_conf = hplugins_parse_battle_conf;
 	HPM->getBattleConf = hplugins_get_battle_conf;
 	HPM->DataCheck = HPM_DataCheck;
diff --git a/src/common/HPM.h b/src/common/HPM.h
index 43f610a6a..e55397022 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -163,7 +163,8 @@ struct HPM_interface {
 	unsigned char (*parse_packets) (int fd, int packet_id, enum HPluginPacketHookingPoints point);
 	void (*load_sub) (struct hplugin *plugin);
 	/* for custom config parsing */
-	bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point);
+	bool (*parse_conf) (const struct config_t *config, const char *filename, enum HPluginConfType point, bool imported);
+	bool (*parse_conf_entry) (const char *w1, const char *w2, enum HPluginConfType point);
 	bool (*getBattleConf) (const char* w1, int *value);
 	/* validates plugin data */
 	bool (*DataCheck) (struct s_HPMDataCheck *src, unsigned int size, int version, char *name);
diff --git a/src/login/login.c b/src/login/login.c
index 19293d61b..ae584206f 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1847,7 +1847,8 @@ bool login_config_read(const char *filename, bool imported)
 	if (!loginlog_config_read("conf/common/inter-server.conf", imported)) // Only inter-server
 		retval = false;
 
-	// TODO HPM->parseConf(w1, w2, HPCT_LOGIN);
+	if (!HPM->parse_conf(&config, filename, HPCT_LOGIN, imported))
+		retval = false;
 
 	ShowInfo("Finished reading %s.\n", filename);
 
diff --git a/src/map/battle.c b/src/map/battle.c
index c564b81cd..01072702d 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7438,7 +7438,7 @@ bool battle_set_value(const char *param, const char *value)
 
 	ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(param, battle_data[i].str) == 0);
 	if (i == ARRAYLENGTH(battle_data)) {
-		if (HPM->parseConf(param, value, HPCT_BATTLE)) /* if plugin-owned, succeed */
+		if (HPM->parse_conf_entry(param, value, HPCT_BATTLE)) /* if plugin-owned, succeed */
 			return true;
 		return false; // not found
 	}
diff --git a/src/map/log.c b/src/map/log.c
index 6131f9cf4..902d428a7 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -685,7 +685,8 @@ bool log_config_read(const char *filename, bool imported)
 	if (!log_config_read_filter(filename, &config, imported))
 		retval = false;
 
-	// TODO HPM->parseConf(w1, w2, HPCT_LOG);
+	if (!HPM->parse_conf(&config, filename, HPCT_LOG, imported))
+		retval = false;
 
 	target = logs->config.sql_logs ? "table" : "file";
 
diff --git a/src/map/map.c b/src/map/map.c
index 40bcd9263..58d2a0803 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -4255,7 +4255,8 @@ bool inter_config_read(const char *filename, bool imported)
 	if (!map->inter_config_read_connection(filename, &config, imported))
 		retval = false;
 
-	// TODO HPM->parseConf(w1, w2, HPCT_MAP_INTER);
+	if (!HPM->parse_conf(&config, filename, HPCT_MAP_INTER, imported))
+		retval = false;
 
 	// import should overwrite any previous configuration, so it should be called last
 	if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
diff --git a/src/map/script.c b/src/map/script.c
index 09cefa500..df6a8d159 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -4556,7 +4556,8 @@ bool script_config_read(const char *filename, bool imported)
 	libconfig->setting_lookup_int(setting, "input_min_value", &script->config.input_min_value);
 	libconfig->setting_lookup_int(setting, "input_max_value", &script->config.input_max_value);
 
-	// TODO HPM->parseConf(w1, w2, HPCT_SCRIPT));
+	if (!HPM->parse_conf(&config, filename, HPCT_SCRIPT, imported))
+		retval = false;
 
 	// import should overwrite any previous configuration, so it should be called last
 	if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
-- 
cgit v1.2.3-70-g09d2