summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-11-09 17:06:32 -0200
committershennetsind <ind@henn.et>2013-11-09 17:06:45 -0200
commit1be53db78a321436d0ebe6093595b769f10874b6 (patch)
treebb76bc0cfc48402e8f0b60b4abf667d73be3d7e1 /src
parent8ed38f98894fb04b4403b44dc0f36281cfd36326 (diff)
downloadhercules-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>
Diffstat (limited to 'src')
-rw-r--r--src/common/HPM.c90
-rw-r--r--src/common/HPM.h13
-rw-r--r--src/common/HPMi.h5
-rw-r--r--src/common/core.c5
-rw-r--r--src/login/login.c2
-rw-r--r--src/map/map.c44
-rw-r--r--src/map/map.h2
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);