From 0e25c604d9f84cbb0a9a737633a8b764c2a9d96f Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 16 Dec 2013 20:20:39 -0200 Subject: Introducing HPM Support for custom battle confs Special Thanks to Mhalicot. Signed-off-by: shennetsind --- src/common/HPM.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/common/HPM.h | 11 +++++++++ src/common/HPMi.h | 11 +++++++++ src/map/battle.c | 6 ++++- src/plugins/sample.c | 13 ++++++++++- 5 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/common/HPM.c b/src/common/HPM.c index 005bc2ddc..8e41e5838 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -215,6 +215,7 @@ struct hplugin *hplugin_load(const char* filename) { plugin->hpi->HookStop = HPM->import_symbol("HookStop",plugin->idx); plugin->hpi->HookStopped = HPM->import_symbol("HookStopped",plugin->idx); plugin->hpi->addArg = HPM->import_symbol("addArg",plugin->idx); + plugin->hpi->addConf = HPM->import_symbol("addConf",plugin->idx); /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); @@ -602,6 +603,48 @@ bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, void (*func) return true; } +bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)) { + struct HPConfListenStorage *conf; + unsigned int i; + + if( type >= HPCT_MAX ) { + ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name); + return false; + } + + for(i = 0; i < HPM->confsc[type]; i++) { + if( !strcmpi(name,HPM->confs[type][i].key) ) { + ShowError("HPM->addConf:%s: duplicate '%s', already in use by '%s'!",HPM->pid2name(pluginID),name,HPM->pid2name(HPM->confs[type][i].pluginID)); + return false; + } + } + + RECREATE(HPM->confs[type], struct HPConfListenStorage, ++HPM->confsc[type]); + conf = &HPM->confs[type][HPM->confsc[type] - 1]; + + conf->pluginID = pluginID; + safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH); + conf->func = func; + + return true; +} +bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType point) { + unsigned int i; + + /* exists? */ + for(i = 0; i < HPM->confsc[point]; i++) { + if( !strcmpi(w1,HPM->confs[point][i].key) ) + break; + } + + /* trigger and we're set! */ + if( i != HPM->confsc[point] ) { + HPM->confs[point][i].func(w2); + return true; + } + + return false; +} void hplugins_share_defaults(void) { /* console */ @@ -617,6 +660,7 @@ void hplugins_share_defaults(void) { HPM->share(HPM_HookStop,"HookStop"); HPM->share(HPM_HookStopped,"HookStopped"); HPM->share(hpm_add_arg,"addArg"); + HPM->share(hplugins_addconf,"addConf"); /* core */ HPM->share(&runflag,"runflag"); HPM->share(arg_v,"arg_v"); @@ -728,6 +772,11 @@ void hpm_final(void) { aFree(HPM->packets[i]); } + for( i = 0; i < HPCT_MAX; i++ ) { + if( HPM->confsc[i] ) + aFree(HPM->confs[i]); + } + HPM->arg_db->destroy(HPM->arg_db,HPM->arg_db_clear_sub); /* HPM->fnames is cleared after the memory manager goes down */ @@ -736,13 +785,26 @@ void hpm_final(void) { return; } void hpm_defaults(void) { + unsigned int i; HPM = &HPM_s; HPM->fnames = NULL; HPM->fnamec = 0; HPM->force_return = false; HPM->hooking = false; - + /* */ + HPM->fnames = NULL; + HPM->fnamec = 0; + for(i = 0; i < hpPHP_MAX; i++) { + HPM->packets[i] = NULL; + HPM->packetsc[i] = 0; + } + for(i = 0; i < HPCT_MAX; i++) { + HPM->confs[i] = NULL; + HPM->confsc[i] = 0; + } + HPM->arg_db = NULL; + /* */ HPM->init = hpm_init; HPM->final = hpm_final; @@ -767,4 +829,5 @@ void hpm_defaults(void) { HPM->arg_help = hpm_arg_help; HPM->grabHPData = hplugins_grabHPData; HPM->grabHPDataSub = NULL; + HPM->parseConf = hplugins_parse_conf; } diff --git a/src/common/HPM.h b/src/common/HPM.h index d5a5cbb6a..1f2ba4648 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -88,6 +88,12 @@ struct HPDataOperationStorage { void **HPDataSRCPtr; unsigned int *hdatac; }; +/* */ +struct HPConfListenStorage { + unsigned int pluginID; + char key[HPM_ADDCONF_LENGTH]; + void (*func) (const char *val); +}; /* Hercules Plugin Manager Interface */ struct HPM_interface { @@ -108,6 +114,9 @@ struct HPM_interface { /* plugin file ptr caching */ struct HPMFileNameCache *fnames; unsigned int fnamec; + /* config listen */ + struct HPConfListenStorage *confs[HPCT_MAX]; + unsigned int confsc[HPCT_MAX]; /* --command-line */ DBMap *arg_db; /* funcs */ @@ -135,6 +144,8 @@ struct HPM_interface { void (*grabHPData) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); /* for server-specific HPData e.g. map_session_data */ void (*grabHPDataSub) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); + /* for custom config parsing */ + bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point); } HPM_s; struct HPM_interface *HPM; diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 2cd1075c4..742132cde 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -36,6 +36,7 @@ struct map_session_data; #include "../common/showmsg.h" #define HPM_VERSION "1.0" +#define HPM_ADDCONF_LENGTH 40 struct hplugin_info { char* name; @@ -83,6 +84,12 @@ enum HPluginDataTypes { HPDT_NPCD, }; +/* used in macros and conf storage */ +enum HPluginConfType { + HPCT_BATTLE, /* battle-conf (map-server */ + HPCT_MAX, +}; + #define addHookPre(tname,hook) (HPMi->AddHook(HOOK_TYPE_PRE,(tname),(hook),HPMi->pid)) #define addHookPost(tname,hook) (HPMi->AddHook(HOOK_TYPE_POST,(tname),(hook),HPMi->pid)) /* need better names ;/ */ @@ -128,6 +135,8 @@ enum HPluginDataTypes { } /* 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) /* Hercules Plugin Mananger Include Interface */ HPExport struct HPMi_interface { @@ -150,6 +159,8 @@ HPExport struct HPMi_interface { bool (*HookStopped) (void); /* program --arg/-a */ bool (*addArg) (unsigned int pluginID, char *name, bool has_param,void (*func) (char *param),void (*help) (void)); + /* battle-config recv param */ + bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)); } HPMi_s; #ifndef _HPM_H_ HPExport struct HPMi_interface *HPMi; diff --git a/src/map/battle.c b/src/map/battle.c index 3b8064278..b8143213a 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -12,6 +12,7 @@ #include "../common/socket.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/HPM.h" #include "map.h" #include "path.h" @@ -6708,8 +6709,11 @@ int battle_set_value(const char* w1, const char* w2) int i; ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0); - if (i == ARRAYLENGTH(battle_data)) + if (i == ARRAYLENGTH(battle_data)) { + if( HPM->parseConf(w1,w2,HPCT_BATTLE) ) /* if plugin-owned, succeed */ + return 1; return 0; // not found + } if (val < battle_data[i].min || val > battle_data[i].max) { diff --git a/src/plugins/sample.c b/src/plugins/sample.c index 552194e43..b3e2b570f 100644 --- a/src/plugins/sample.c +++ b/src/plugins/sample.c @@ -109,6 +109,10 @@ 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); + /* do anything with the var e.g. config_switch(val) */ +} /* run when server starts */ HPExport void plugin_init (void) { char *server_type; @@ -168,7 +172,14 @@ HPExport void plugin_init (void) { /* if the original pc->dropitem was successful and the amount stored on my_pc_dropitem_storage is higher than 1, */ /* our posthook will display a message to the user about the cap */ /* - by checking whether it was successful (retVal value) it allows for the originals conditions to take place */ - addHookPost("pc->dropitem",my_pc_dropitem_post); + addHookPost("pc->dropitem",my_pc_dropitem_post); +} +/* triggered when server starts loading, before any server-specific data is set */ +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); } /* run when server is ready (online) */ HPExport void server_online (void) { -- cgit v1.2.3-60-g2f50