Skip to content

Commit

Permalink
Introducing HPM Support for custom battle confs
Browse files Browse the repository at this point in the history
Special Thanks to Mhalicot.

Signed-off-by: shennetsind <ind@henn.et>
  • Loading branch information
shennetsind committed Dec 16, 2013
1 parent f6daed3 commit 0e25c60
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 3 deletions.
65 changes: 64 additions & 1 deletion src/common/HPM.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand All @@ -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");
Expand Down Expand Up @@ -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 */
Expand All @@ -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;

Expand All @@ -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;
}
11 changes: 11 additions & 0 deletions src/common/HPM.h
Expand Up @@ -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 {
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/common/HPMi.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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 ;/ */
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/map/battle.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand Down
13 changes: 12 additions & 1 deletion src/plugins/sample.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 0e25c60

Please sign in to comment.