diff options
author | shennetsind <ind@henn.et> | 2013-11-09 17:06:32 -0200 |
---|---|---|
committer | shennetsind <ind@henn.et> | 2013-11-09 17:06:45 -0200 |
commit | 1be53db78a321436d0ebe6093595b769f10874b6 (patch) | |
tree | bb76bc0cfc48402e8f0b60b4abf667d73be3d7e1 | |
parent | 8ed38f98894fb04b4403b44dc0f36281cfd36326 (diff) | |
download | hercules-1be53db78a321436d0ebe6093595b769f10874b6.tar.gz hercules-1be53db78a321436d0ebe6093595b769f10874b6.tar.bz2 hercules-1be53db78a321436d0ebe6093595b769f10874b6.tar.xz hercules-1be53db78a321436d0ebe6093595b769f10874b6.zip |
HPM Support for plugin-implemented "--args" (options)
As a necessary measure for the upcoming bot that will keep .sql files in sync with their .txt counterparts.
Special Thanks to Haruna
Signed-off-by: shennetsind <ind@henn.et>
-rw-r--r-- | src/common/HPM.c | 90 | ||||
-rw-r--r-- | src/common/HPM.h | 13 | ||||
-rw-r--r-- | src/common/HPMi.h | 5 | ||||
-rw-r--r-- | src/common/core.c | 5 | ||||
-rw-r--r-- | src/login/login.c | 2 | ||||
-rw-r--r-- | src/map/map.c | 44 | ||||
-rw-r--r-- | src/map/map.h | 2 |
7 files changed, 130 insertions, 31 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index e7ab94687..5d08821e6 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -190,6 +190,9 @@ struct hplugin *hplugin_load(const char* filename) { if( ( plugin->hpi->event[HPET_POST_FINAL] = plugin_import(plugin->dll, "server_post_final",void (*)(void)) ) ) anyEvent = true; + if( ( plugin->hpi->event[HPET_PRE_INIT] = plugin_import(plugin->dll, "server_preinit",void (*)(void)) ) ) + anyEvent = true; + if( !anyEvent ) { ShowWarning("HPM:plugin_load: no events found for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); @@ -200,16 +203,17 @@ struct hplugin *hplugin_load(const char* filename) { return NULL; /* id */ - plugin->hpi->pid = plugin->idx; + plugin->hpi->pid = plugin->idx; /* core */ - plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand",plugin->idx); - plugin->hpi->addPacket = HPM->import_symbol("addPacket",plugin->idx); - plugin->hpi->addToSession = HPM->import_symbol("addToSession",plugin->idx); - plugin->hpi->getFromSession = HPM->import_symbol("getFromSession",plugin->idx); - plugin->hpi->removeFromSession = HPM->import_symbol("removeFromSession",plugin->idx); - plugin->hpi->AddHook = HPM->import_symbol("AddHook",plugin->idx); - plugin->hpi->HookStop = HPM->import_symbol("HookStop",plugin->idx); - plugin->hpi->HookStopped = HPM->import_symbol("HookStopped",plugin->idx); + plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand",plugin->idx); + plugin->hpi->addPacket = HPM->import_symbol("addPacket",plugin->idx); + plugin->hpi->addToSession = HPM->import_symbol("addToSession",plugin->idx); + plugin->hpi->getFromSession = HPM->import_symbol("getFromSession",plugin->idx); + plugin->hpi->removeFromSession = HPM->import_symbol("removeFromSession",plugin->idx); + plugin->hpi->AddHook = HPM->import_symbol("AddHook",plugin->idx); + 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); /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); @@ -247,6 +251,13 @@ void hplugins_config_read(void) { config_t plugins_conf; config_setting_t *plist = NULL; const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name + FILE *fp; + + /* yes its ugly, its temporary and will be gone as soon as the new inter-server.conf is set */ + if( (fp = fopen("conf/import/plugins.conf","r")) ) { + config_filename = "conf/import/plugins.conf"; + fclose(fp); + } if (conf_read_file(&plugins_conf, config_filename)) return; @@ -483,6 +494,51 @@ void HPM_HookStop (const char *func, unsigned int pID) { bool HPM_HookStopped (void) { return HPM->force_return; } +/* command-line args */ +bool hpm_parse_arg(const char *arg, int *index, char *argv[], bool param) { + struct HPMArgData *data; + + if( (data = strdb_get(HPM->arg_db,arg)) ) { + data->func((data->has_param && param)?argv[(*index)+1]:NULL); + if( data->has_param && param ) *index += 1; + return true; + } + + return false; +} +void hpm_arg_help(void) { + DBIterator *iter = db_iterator(HPM->arg_db); + struct HPMArgData *data = NULL; + + for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) ) { + if( data->help != NULL ) + data->help(); + else + ShowInfo(" %s (%s)\t\t<no description provided>\n",data->name,HPM->pid2name(data->pluginID)); + } + + dbi_destroy(iter); +} +bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, void (*func) (char *param),void (*help) (void)) { + struct HPMArgData *data = NULL; + + if( strdb_exists(HPM->arg_db, name) ) { + ShowError("HPM:add_arg:%s duplicate! (from %s)\n",name,HPM->pid2name(pluginID)); + return false; + } + + CREATE(data, struct HPMArgData, 1); + + data->pluginID = pluginID; + data->name = aStrdup(name); + data->func = func; + data->help = help; + data->has_param = has_param; + + strdb_put(HPM->arg_db, data->name, data); + + return true; +} void hplugins_share_defaults(void) { /* console */ @@ -497,6 +553,7 @@ void hplugins_share_defaults(void) { HPM->share(HPM_AddHook,"AddHook"); HPM->share(HPM_HookStop,"HookStop"); HPM->share(HPM_HookStopped,"HookStopped"); + HPM->share(hpm_add_arg,"addArg"); /* core */ HPM->share(&runflag,"runflag"); HPM->share(arg_v,"arg_v"); @@ -551,6 +608,8 @@ void hpm_init(void) { HPM->packetsc[i] = 0; } + HPM->arg_db = strdb_alloc(DB_OPT_RELEASE_DATA, 0); + HPM->symbol_defaults(); #ifdef CONSOLE_INPUT @@ -569,6 +628,14 @@ void hpm_memdown(void) { if( HPM->fnames ) free(HPM->fnames); + +} +int hpm_arg_db_clear_sub(DBKey key, DBData *data, va_list args) { + struct HPMArgData *a = DB->data2ptr(data); + + aFree(a->name); + + return 0; } void hpm_final(void) { unsigned int i; @@ -594,6 +661,8 @@ void hpm_final(void) { aFree(HPM->packets[i]); } + HPM->arg_db->destroy(HPM->arg_db,HPM->arg_db_clear_sub); + /* HPM->fnames is cleared after the memory manager goes down */ iMalloc->post_shutdown = hpm_memdown; @@ -626,4 +695,7 @@ void hpm_defaults(void) { HPM->parse_packets = hplugins_parse_packets; HPM->load_sub = NULL; HPM->addhook_sub = NULL; + HPM->arg_db_clear_sub = hpm_arg_db_clear_sub; + HPM->parse_arg = hpm_parse_arg; + HPM->arg_help = hpm_arg_help; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 395555948..e685b3068 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -74,6 +74,14 @@ struct HPMFileNameCache { char *name; }; +struct HPMArgData { + unsigned int pluginID; + char *name;/* e.g. "--my-arg","-v","--whatever" */ + void (*help) (void);/* to display when --help is used */ + void (*func) (char *param);/* NULL when no param is available */ + bool has_param;/* because of the weird "--arg<space>param" instead of the "--arg=param" */ +}; + /* Hercules Plugin Manager Interface */ struct HPM_interface { /* vars */ @@ -93,6 +101,8 @@ struct HPM_interface { /* plugin file ptr caching */ struct HPMFileNameCache *fnames; unsigned int fnamec; + /* --command-line */ + DBMap *arg_db; /* funcs */ void (*init) (void); void (*final) (void); @@ -112,6 +122,9 @@ struct HPM_interface { unsigned char (*parse_packets) (int fd, enum HPluginPacketHookingPoints point); void (*load_sub) (struct hplugin *plugin); bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); + bool (*parse_arg) (const char *arg, int* index, char *argv[], bool param); + void (*arg_help) (void); + int (*arg_db_clear_sub) (DBKey key, DBData *data, va_list args); } HPM_s; struct HPM_interface *HPM; diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 9c2a6184e..f071bf09e 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -56,6 +56,7 @@ enum hp_event_types { HPET_FINAL,/* server is shutting down */ HPET_READY,/* server is ready (online) */ HPET_POST_FINAL,/* server is done shutting down */ + HPET_PRE_INIT,/* server is about to start (used to e.g. add custom "--args" handling) */ HPET_MAX, }; @@ -83,6 +84,8 @@ enum HPluginHookType { #define hookStop() HPMi->HookStop(__func__,HPMi->pid) #define hookStopped() HPMi->HookStopped() +#define addArg(name,param,func,help) HPMi->addArg(HPMi->pid,name,param,func,help) + /* Hercules Plugin Mananger Include Interface */ HPExport struct HPMi_interface { /* */ @@ -106,6 +109,8 @@ HPExport struct HPMi_interface { bool (*AddHook) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); void (*HookStop) (const char *func, unsigned int pID); bool (*HookStopped) (void); + /* program --arg/-a */ + bool (*addArg) (unsigned int pluginID, char *name, bool has_param,void (*func) (char *param),void (*help) (void)); } HPMi_s; #ifndef _HPM_H_ HPExport struct HPMi_interface *HPMi; diff --git a/src/common/core.c b/src/common/core.c index f57cc4c79..a414a5d0b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -8,6 +8,7 @@ #include "../common/strlib.h" #include "core.h" #include "../common/console.h" +#include "../common/random.h" #ifndef MINICORE #include "../common/db.h" @@ -337,6 +338,10 @@ int main (int argc, char **argv) { timer->init(); + /* timer first */ + rnd_init(); + srand((unsigned int)timer->gettick()); + console->init(); HCache->init(); diff --git a/src/login/login.c b/src/login/login.c index f47f1519c..73e89d4ff 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -1777,8 +1777,6 @@ int do_init(int argc, char** argv) login_set_defaults(); login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME); login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME); - - rnd_init(); for( i = 0; i < ARRAYLENGTH(server); ++i ) chrif_server_init(i); diff --git a/src/map/map.c b/src/map/map.c index cd192b7d4..1d47d196e 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -5215,6 +5215,7 @@ void map_helpscreen(bool do_exit) ShowInfo(" --grf-path <file>\t\tAlternative GRF path configuration.\n"); ShowInfo(" --inter-config <file>\t\tAlternative inter-server configuration.\n"); ShowInfo(" --log-config <file>\t\tAlternative logging configuration.\n"); + HPM->arg_help();/* display help for commands implemented thru HPM */ if( do_exit ) exit(EXIT_SUCCESS); } @@ -5257,10 +5258,11 @@ void do_shutdown(void) } } -bool map_arg_next_value(const char* option, int i, int argc) +bool map_arg_next_value(const char* option, int i, int argc, bool must) { if( i >= argc-1 ) { - ShowWarning("Missing value for option '%s'.\n", option); + if( must ) + ShowWarning("Missing value for option '%s'.\n", option); return false; } @@ -5377,6 +5379,8 @@ void map_hp_symbols(void) { } void map_load_defaults(void) { + map_defaults(); + /* */ atcommand_defaults(); battle_defaults(); battleground_defaults(); @@ -5426,17 +5430,23 @@ int do_init(int argc, char *argv[]) #ifdef GCOLLECT GC_enable_incremental(); #endif + + map_load_defaults(); - map_defaults(); - - rnd_init(); - + HPM->load_sub = HPM_map_plugin_load_sub; + HPM->symbol_defaults_sub = map_hp_symbols; + HPM->config_read(); + + HPM->event(HPET_PRE_INIT); + for( i = 1; i < argc ; i++ ) { const char* arg = argv[i]; if( arg[0] != '-' && ( arg[0] != '/' || arg[1] == '-' ) ) {// -, -- and / ShowError("Unknown option '%s'.\n", argv[i]); exit(EXIT_FAILURE); + } else if ( HPM->parse_arg(arg,&i,argv,map->arg_next_value(arg, i, argc, false)) ) { + continue; /* HPM Triggered */ } else if( (++arg)[0] == '-' ) {// long option arg++; @@ -5445,35 +5455,35 @@ int do_init(int argc, char *argv[]) } else if( strcmp(arg, "version") == 0 ) { map->versionscreen(true); } else if( strcmp(arg, "map-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->MAP_CONF_NAME = argv[++i]; } else if( strcmp(arg, "battle-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->BATTLE_CONF_FILENAME = argv[++i]; } else if( strcmp(arg, "atcommand-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->ATCOMMAND_CONF_FILENAME = argv[++i]; } else if( strcmp(arg, "script-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->SCRIPT_CONF_NAME = argv[++i]; } else if( strcmp(arg, "msg-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->MSG_CONF_NAME = argv[++i]; } else if( strcmp(arg, "grf-path-file") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->GRF_PATH_FILENAME = argv[++i]; } else if( strcmp(arg, "inter-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->INTER_CONF_NAME = argv[++i]; } else if( strcmp(arg, "log-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->LOG_CONF_NAME = argv[++i]; } else if( strcmp(arg, "run-once") == 0 ) { // close the map-server as soon as its done.. for testing [Celest] runflag = CORE_ST_STOP; } else if( strcmp(arg, "script-check") == 0 ) { minimal = true; runflag = CORE_ST_STOP; - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) scriptcheck = argv[++i]; } else { ShowError("Unknown option '%s'.\n", argv[i]); @@ -5495,7 +5505,6 @@ int do_init(int argc, char *argv[]) } } - map_load_defaults(); if (!minimal) { map->config_read(map->MAP_CONF_NAME); CREATE(map->list,struct map_data,map->count); @@ -5580,9 +5589,6 @@ int do_init(int argc, char *argv[]) timer->add_func_list(map->removemobs_timer, "map_removemobs_timer"); timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000); - HPM->load_sub = HPM_map_plugin_load_sub; - HPM->symbol_defaults_sub = map_hp_symbols; - HPM->config_read(); HPM->event(HPET_INIT); } diff --git a/src/map/map.h b/src/map/map.h index 20e328c88..4b2671702 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1047,7 +1047,7 @@ struct map_interface { int (*abort_sub) (struct map_session_data *sd, va_list ap); void (*helpscreen) (bool do_exit); void (*versionscreen) (bool do_exit); - bool (*arg_next_value) (const char *option, int i, int argc); + bool (*arg_next_value) (const char *option, int i, int argc, bool must); void (*addblcell) (struct block_list *bl); void (*delblcell) (struct block_list *bl); int (*get_new_bonus_id) (void); |