summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <hemagx2@gmail.com>2015-12-12 21:44:27 +0200
committerHaru <haru@dotalux.com>2015-12-13 03:55:41 +0100
commitf102c913b2aa093ef40c7846e25850ebb1106d71 (patch)
tree8965bde6164baa50121171c7291ea438e11d8503
parentbb214d4651c9c9aa9599f50cb5de52059176a87f (diff)
downloadhercules-f102c913b2aa093ef40c7846e25850ebb1106d71.tar.gz
hercules-f102c913b2aa093ef40c7846e25850ebb1106d71.tar.bz2
hercules-f102c913b2aa093ef40c7846e25850ebb1106d71.tar.xz
hercules-f102c913b2aa093ef40c7846e25850ebb1106d71.zip
- Fixed #723 now it's possible to retrieve Battle Config Settings from plugins into scripts
- Fixed Possible Crash when null parse function pointer passed to HPMi->addConf - Now it's possible to use same parse function for all config entries - Now Battle Config entries must have a return function
-rw-r--r--src/common/HPM.c40
-rw-r--r--src/common/HPM.h4
-rw-r--r--src/common/HPMi.h16
-rw-r--r--src/map/battle.c20
-rw-r--r--src/map/battle.h4
-rw-r--r--src/map/script.c14
-rw-r--r--src/plugins/sample.c31
7 files changed, 104 insertions, 25 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c
index 7d9a0b104..e5c3c47ba 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -389,11 +389,21 @@ bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, CmdlineExecF
* @retval true if the listener was added successfully.
* @retval false in case of error.
*/
-bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val))
+bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key))
{
struct HPConfListenStorage *conf;
int i;
+ if (parse_func == NULL) {
+ ShowError("HPM->addConf:%s: missing setter function for config '%s'\n",HPM->pid2name(pluginID),name);
+ return false;
+ }
+
+ if (type == HPCT_BATTLE && return_func == NULL) {
+ ShowError("HPM->addConf:%s: missing getter function for config '%s'\n",HPM->pid2name(pluginID),name);
+ return false;
+ }
+
if (type >= HPCT_MAX) {
ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name);
return false;
@@ -412,7 +422,8 @@ bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *na
conf->pluginID = pluginID;
safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH);
- conf->func = func;
+ conf->parse_func = parse_func;
+ conf->return_func = return_func;
return true;
}
@@ -798,7 +809,29 @@ bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType po
if (i == VECTOR_LENGTH(HPM->config_listeners[point]))
return false;
- VECTOR_INDEX(HPM->config_listeners[point], i).func(w2);
+ VECTOR_INDEX(HPM->config_listeners[point], i).parse_func(w1, w2);
+ return true;
+}
+
+/**
+ * Get a battle configuration entry through the registered plugins.
+ *
+ * @param[in] w1 The configuration entry name.
+ * @param[out] value Where the config result will be saved
+ * @retval true in case of data found
+ * @retval false in case of no data found
+ */
+bool hplugins_get_battle_conf(const char *w1, int *value)
+{
+ int i;
+
+ nullpo_retr(false, value);
+
+ ARR_FIND(0, VECTOR_LENGTH(HPM->config_listeners[HPCT_BATTLE]), i, strcmpi(w1, VECTOR_INDEX(HPM->config_listeners[HPCT_BATTLE], i).key) == 0);
+ if (i == VECTOR_LENGTH(HPM->config_listeners[HPCT_BATTLE]))
+ return false;
+
+ *value = VECTOR_INDEX(HPM->config_listeners[HPCT_BATTLE], i).return_func(w1);
return true;
}
@@ -1020,6 +1053,7 @@ void hpm_defaults(void)
HPM->load_sub = NULL;
HPM->addhook_sub = NULL;
HPM->parseConf = hplugins_parse_conf;
+ HPM->getBattleConf = hplugins_get_battle_conf;
HPM->DataCheck = HPM_DataCheck;
HPM->datacheck_init = HPM_datacheck_init;
HPM->datacheck_final = HPM_datacheck_final;
diff --git a/src/common/HPM.h b/src/common/HPM.h
index 5420e5300..bcf831d0e 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -101,7 +101,8 @@ struct HPMFileNameCache {
struct HPConfListenStorage {
unsigned int pluginID;
char key[HPM_ADDCONF_LENGTH];
- void (*func) (const char *val);
+ void (*parse_func) (const char *key, const char *val);
+ int (*return_func) (const char *key);
};
/* Hercules Plugin Manager Interface */
@@ -145,6 +146,7 @@ struct HPM_interface {
bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID);
/* for custom config parsing */
bool (*parseConf) (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);
void (*datacheck_init) (const struct s_HPMDataCheck *src, unsigned int length, int version);
diff --git a/src/common/HPMi.h b/src/common/HPMi.h
index 9a61dd256..5b62f80d9 100644
--- a/src/common/HPMi.h
+++ b/src/common/HPMi.h
@@ -183,19 +183,19 @@ enum HPluginConfType {
/* HPMi->addPacket */
#define addPacket(cmd,len,receive,point) HPMi->addPacket(cmd,len,receive,point,HPMi->pid)
/* HPMi->addBattleConf */
-#define addBattleConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_BATTLE,bcname,funcname)
+#define addBattleConf(bcname,funcname,returnfunc) HPMi->addConf(HPMi->pid,HPCT_BATTLE,bcname,funcname,returnfunc)
/* HPMi->addLogin */
-#define addLoginConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOGIN,bcname,funcname)
+#define addLoginConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOGIN,bcname,funcname,NULL)
/* HPMi->addChar */
-#define addCharConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR,bcname,funcname)
+#define addCharConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR,bcname,funcname,NULL)
/* HPMi->addCharInter */
-#define addCharInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR_INTER,bcname,funcname)
+#define addCharInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR_INTER,bcname,funcname,NULL)
/* HPMi->addMapInter */
-#define addMapInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_MAP_INTER,bcname,funcname)
+#define addMapInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_MAP_INTER,bcname,funcname,NULL)
/* HPMi->addLog */
-#define addLogConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOG,bcname,funcname)
+#define addLogConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOG,bcname,funcname,NULL)
/* HPMi->addScript */
-#define addScriptConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_SCRIPT,bcname,funcname)
+#define addScriptConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_SCRIPT,bcname,funcname,NULL)
/* HPMi->addPCGPermission */
#define addGroupPermission(pcgname,maskptr) HPMi->addPCGPermission(HPMi->pid,pcgname,&maskptr)
@@ -222,7 +222,7 @@ struct HPMi_interface {
/* program --arg/-a */
bool (*addArg) (unsigned int pluginID, char *name, bool has_param, CmdlineExecFunc func, const char *help);
/* battle-config recv param */
- bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val));
+ bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key));
/* pc group permission */
void (*addPCGPermission) (unsigned int pluginID, char *name, unsigned int *mask);
diff --git a/src/map/battle.c b/src/map/battle.c
index 7fbbcd0d5..1725d8c65 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7329,15 +7329,23 @@ int battle_set_value(const char* w1, const char* w2)
return 1;
}
-int battle_get_value(const char* w1)
+bool battle_get_value(const char *w1, int *value)
{
int i;
- nullpo_retr(1, w1);
+
+ nullpo_retr(false, w1);
+ nullpo_retr(false, value);
+
ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0);
- if (i == ARRAYLENGTH(battle_data))
- return 0; // not found
- else
- return *battle_data[i].val;
+ if (i == ARRAYLENGTH(battle_data)) {
+ if (HPM->getBattleConf(w1,value))
+ return true;
+ } else {
+ *value = *battle_data[i].val;
+ return true;
+ }
+
+ return false;
}
void battle_set_defaults(void) {
diff --git a/src/map/battle.h b/src/map/battle.h
index 68a427e72..595ed32bb 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -630,8 +630,8 @@ struct battle_interface {
/* - battle_config */
int (*config_read) (const char *cfgName);
void (*config_set_defaults) (void);
- int (*config_set_value) (const char* w1, const char* w2);
- int (*config_get_value) (const char* w1);
+ int (*config_set_value) (const char *w1, const char *w2);
+ bool (*config_get_value) (const char *w1, int *value);
void (*config_adjust) (void);
/* ----------------------------------------- */
/* picks a random enemy within the specified range */
diff --git a/src/map/script.c b/src/map/script.c
index cfc7ed052..cc9552d60 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -14620,8 +14620,20 @@ BUILDIN(setbattleflag)
BUILDIN(getbattleflag)
{
const char *flag;
+ int value;
+
flag = script_getstr(st,2);
- script_pushint(st,battle->config_get_value(flag));
+
+ if (battle->config_get_value(flag, &value)) {
+ script_pushint(st,value);
+ return true;
+ } else {
+ script_pushint(st,0);
+ ShowWarning("buildin_getbattleflag: non-exist battle config requested %s \n", flag);
+ script->reportsrc(st);
+ return false;
+ }
+
return true;
}
diff --git a/src/plugins/sample.c b/src/plugins/sample.c
index d7e5523d6..d1a00a70d 100644
--- a/src/plugins/sample.c
+++ b/src/plugins/sample.c
@@ -40,6 +40,8 @@ struct sample_data_struct {
unsigned int someNumber;
};
+int my_setting;
+
/* sample packet implementation */
/* cmd 0xf3 - it is a client-server existent id, for clif_parse_GlobalMessage */
/* in this sample we do nothing and simply redirect */
@@ -111,10 +113,31 @@ int my_pc_dropitem_post(int retVal, struct map_session_data *sd,int *n,int *amou
}
return 1;
}
-void parse_my_setting(const char *val) {
- ShowDebug("Received 'my_setting:%s'\n",val);
+/*
+* Key is the setting name in our example it's 'my_setting' while val is the value of it.
+* this way you can manage more than one setting in one function instead of define multiable ones
+*/
+
+void parse_my_setting(const char *key, const char *val) {
+ ShowDebug("Received '%s:%s'\n",key,val);
/* do anything with the var e.g. config_switch(val) */
+ /* for our example we will save it in global variable */
+
+ /* please note, battle settings can be only returned as int for scripts and other usage */
+ if (strcmpi(key,"my_setting") == 0)
+ my_setting = atoi(val);
+}
+
+/* Battle Config Settings need to have return function in-case scripts need to read it */
+int return_my_setting(const char *key)
+{
+ /* first we check the key to know what setting we need to return with strcmpi then return it */
+ if (strcmpi(key, "my_setting") == 0)
+ return my_setting;
+
+ return 0;
}
+
/* run when server starts */
HPExport void plugin_init (void) {
ShowInfo("Server type is ");
@@ -171,8 +194,8 @@ HPExport void plugin_init (void) {
HPExport void server_preinit (void) {
/* makes map server listen to mysetting:value in any "battleconf" file (including imported or custom ones) */
/* value is not limited to numbers, its passed to our plugins handler (parse_my_setting) as const char *,
- * and thus can be manipulated at will */
- addBattleConf("my_setting",parse_my_setting);
+ * however for battle config to be returned to our script engine we need it to be number (int) so keep use it as int only */
+ addBattleConf("my_setting",parse_my_setting,return_my_setting);
}
/* run when server is ready (online) */
HPExport void server_online (void) {