summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2014-11-03 08:15:05 -0200
committershennetsind <ind@henn.et>2014-11-03 08:15:05 -0200
commitbee4c9d36f4a27e39cc76dc5d6c5f876ed44a678 (patch)
tree79f9aec5171e8aed2d701bf67167f260e05f41db /src/common
parent239d480487e24294975f35ed55f210837ad1088e (diff)
parentce3f4bfbe016ea69c855146667ba9bd9e0e2e221 (diff)
downloadhercules-bee4c9d36f4a27e39cc76dc5d6c5f876ed44a678.tar.gz
hercules-bee4c9d36f4a27e39cc76dc5d6c5f876ed44a678.tar.bz2
hercules-bee4c9d36f4a27e39cc76dc5d6c5f876ed44a678.tar.xz
hercules-bee4c9d36f4a27e39cc76dc5d6c5f876ed44a678.zip
Merge branch 'master' of github.com:HerculesWS/Hercules
Signed-off-by: shennetsind <ind@henn.et> Conflicts: src/map/battle.c
Diffstat (limited to 'src/common')
-rw-r--r--src/common/HPM.c115
-rw-r--r--src/common/HPM.h4
-rw-r--r--src/common/HPMDataCheck.h73
-rw-r--r--src/common/HPMi.h1
4 files changed, 137 insertions, 56 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c
index f39954175..7a875d1c4 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -31,6 +31,13 @@
struct malloc_interface iMalloc_HPM;
struct malloc_interface *HPMiMalloc;
+/**
+ * (char*) data name -> (unsigned int) HPMDataCheck[] index
+ **/
+DBMap *datacheck_db;
+int datacheck_version;
+const struct s_HPMDataCheck *datacheck_data;
+
void hplugin_trigger_event(enum hp_event_types type) {
unsigned int i;
for( i = 0; i < HPM->plugin_count; i++ ) {
@@ -122,6 +129,7 @@ struct hplugin *hplugin_load(const char* filename) {
bool anyEvent = false;
void **import_symbol_ref;
Sql **sql_handle;
+ int *HPMDataCheckVer;
unsigned int *HPMDataCheckLen;
struct s_HPMDataCheck *HPMDataCheck;
@@ -217,13 +225,20 @@ struct hplugin *hplugin_load(const char* filename) {
return NULL;
}
+ if( !( HPMDataCheckVer = plugin_import(plugin->dll, "HPMDataCheckVer", int *) ) ) {
+ ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheckVer' for '"CL_WHITE"%s"CL_RESET"', most likely an outdated plugin, skipping...\n", filename);
+ HPM->unload(plugin);
+ return NULL;
+ }
+
if( !( HPMDataCheck = plugin_import(plugin->dll, "HPMDataCheck", struct s_HPMDataCheck *) ) ) {
ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheck' for '"CL_WHITE"%s"CL_RESET"', most likely not including HPMDataCheck.h, skipping...\n", filename);
HPM->unload(plugin);
return NULL;
}
- if( HPM->DataCheck && !HPM->DataCheck(HPMDataCheck,*HPMDataCheckLen,plugin->info->name) ) {
+ // TODO: Remove the HPM->DataCheck != NULL check once login and char support is complete
+ if (HPM->DataCheck != NULL && !HPM->DataCheck(HPMDataCheck,*HPMDataCheckLen,*HPMDataCheckVer,plugin->info->name)) {
ShowWarning("HPM:plugin_load: '"CL_WHITE"%s"CL_RESET"' failed DataCheck, out of sync from the core (recompile plugin), skipping...\n", filename);
HPM->unload(plugin);
return NULL;
@@ -282,12 +297,6 @@ void hplugins_config_read(const char * const *extra_plugins, int extra_plugins_c
FILE *fp;
int i;
-// uncomment once login/char support is wrapped up
-// if( !HPM->DataCheck ) {
-// ShowError("HPM:config_read: HPM->DataCheck not set! Failure\n");
-// return;
-// }
-
/* 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";
@@ -309,27 +318,40 @@ void hplugins_config_read(const char * const *extra_plugins, int extra_plugins_c
if (plist != NULL) {
int length = libconfig->setting_length(plist);
char filename[60];
- for(i = 0; i < length; i++) {
- if( !strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first
+ char hooking_plugin_name[32];
+ const char *plugin_name_suffix = "";
+ if (SERVER_TYPE == SERVER_TYPE_LOGIN)
+ plugin_name_suffix = "_login";
+ else if (SERVER_TYPE == SERVER_TYPE_CHAR)
+ plugin_name_suffix = "_char";
+ else if (SERVER_TYPE == SERVER_TYPE_MAP)
+ plugin_name_suffix = "_map";
+ snprintf(hooking_plugin_name, sizeof(hooking_plugin_name), "HPMHooking%s", plugin_name_suffix);
+
+ for (i = 0; i < length; i++) {
+ const char *plugin_name = libconfig->setting_get_string_elem(plist,i);
+ if (strcmpi(plugin_name, "HPMHooking") == 0 || strcmpi(plugin_name, hooking_plugin_name) == 0) { //must load it first
struct hplugin *plugin;
- snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
- if( ( plugin = HPM->load(filename) ) ) {
+ snprintf(filename, 60, "plugins/%s%s", hooking_plugin_name, DLL_EXT);
+ if ((plugin = HPM->load(filename))) {
bool (*func)(bool *fr);
bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID);
- if( ( func = plugin_import(plugin->dll, "Hooked",bool (*)(bool *)) ) && ( addhook_sub = plugin_import(plugin->dll, "HPM_Plugin_AddHook",bool (*)(enum HPluginHookType, const char *, void *, unsigned int)) ) ) {
- if( func(&HPM->force_return) ) {
+ if ((func = plugin_import(plugin->dll, "Hooked",bool (*)(bool *)))
+ && (addhook_sub = plugin_import(plugin->dll, "HPM_Plugin_AddHook",bool (*)(enum HPluginHookType, const char *, void *, unsigned int)))) {
+ if (func(&HPM->force_return)) {
HPM->hooking = true;
HPM->addhook_sub = addhook_sub;
}
}
}
+ break;
}
}
- for(i = 0; i < length; i++) {
- if( strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//now all others
- snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
- HPM->load(filename);
- }
+ for (i = 0; i < length; i++) {
+ if (strncmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking", 10) == 0) // Already loaded, skip
+ continue;
+ snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT);
+ HPM->load(filename);
}
libconfig->destroy(&plugins_conf);
}
@@ -688,6 +710,56 @@ bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType po
return false;
}
+/**
+ * Called by HPM->DataCheck on a plugins incoming data, ensures data structs in use are matching!
+ **/
+bool HPM_DataCheck(struct s_HPMDataCheck *src, unsigned int size, int version, char *name) {
+ unsigned int i, j;
+
+ if (version != datacheck_version) {
+ ShowError("HPMDataCheck:%s: DataCheck API version mismatch %d != %d\n", name, datacheck_version, version);
+ return false;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (!(src[i].type|SERVER_TYPE))
+ continue;
+
+ if (!strdb_exists(datacheck_db, src[i].name)) {
+ ShowError("HPMDataCheck:%s: '%s' was not found\n",name,src[i].name);
+ return false;
+ } else {
+ j = strdb_uiget(datacheck_db, src[i].name);/* not double lookup; exists sets cache to found data */
+ if (src[i].size != datacheck_data[j].size) {
+ ShowWarning("HPMDataCheck:%s: '%s' size mismatch %u != %u\n",name,src[i].name,src[i].size,datacheck_data[j].size);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void HPM_datacheck_init(const struct s_HPMDataCheck *src, unsigned int length, int version) {
+ unsigned int i;
+
+ datacheck_version = version;
+ datacheck_data = src;
+
+ /**
+ * Populates datacheck_db for easy lookup later on
+ **/
+ datacheck_db = strdb_alloc(DB_OPT_BASE,0);
+
+ for(i = 0; i < length; i++) {
+ strdb_uiput(datacheck_db, src[i].name, i);
+ }
+}
+
+void HPM_datacheck_final(void) {
+ db_destroy(datacheck_db);
+}
+
void hplugins_share_defaults(void) {
/* console */
#ifdef CONSOLE_INPUT
@@ -729,6 +801,9 @@ void hplugins_share_defaults(void) {
void hpm_init(void) {
unsigned int i;
+ datacheck_db = NULL;
+ datacheck_data = NULL;
+ datacheck_version = 0;
HPM->symbols = NULL;
HPM->plugins = NULL;
@@ -866,5 +941,7 @@ void hpm_defaults(void) {
HPM->grabHPData = hplugins_grabHPData;
HPM->grabHPDataSub = NULL;
HPM->parseConf = hplugins_parse_conf;
- HPM->DataCheck = NULL;
+ 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 fe8d45066..a4ea504e6 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -151,7 +151,9 @@ struct HPM_interface {
/* for custom config parsing */
bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point);
/* validates plugin data */
- bool (*DataCheck) (struct s_HPMDataCheck *src, unsigned int size, char *name);
+ 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);
+ void (*datacheck_final) (void);
} HPM_s;
struct HPM_interface *HPM;
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 79ec36472..9f4316617 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -9,134 +9,135 @@
HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#ifdef COMMON_CONF_H
- { "libconfig_interface", sizeof(struct libconfig_interface) },
+ { "libconfig_interface", sizeof(struct libconfig_interface), SERVER_TYPE_ALL },
#else
#define COMMON_CONF_H
#endif // COMMON_CONF_H
#ifdef COMMON_DB_H
- { "DBData", sizeof(struct DBData) },
- { "DBIterator", sizeof(struct DBIterator) },
- { "DBMap", sizeof(struct DBMap) },
+ { "DBData", sizeof(struct DBData), SERVER_TYPE_ALL },
+ { "DBIterator", sizeof(struct DBIterator), SERVER_TYPE_ALL },
+ { "DBMap", sizeof(struct DBMap), SERVER_TYPE_ALL },
#else
#define COMMON_DB_H
#endif // COMMON_DB_H
#ifdef COMMON_DES_H
- { "BIT64", sizeof(struct BIT64) },
+ { "BIT64", sizeof(struct BIT64), SERVER_TYPE_ALL },
#else
#define COMMON_DES_H
#endif // COMMON_DES_H
#ifdef COMMON_ERS_H
- { "eri", sizeof(struct eri) },
+ { "eri", sizeof(struct eri), SERVER_TYPE_ALL },
#else
#define COMMON_ERS_H
#endif // COMMON_ERS_H
#ifdef COMMON_MAPINDEX_H
- { "mapindex_interface", sizeof(struct mapindex_interface) },
+ { "mapindex_interface", sizeof(struct mapindex_interface), SERVER_TYPE_ALL },
#else
#define COMMON_MAPINDEX_H
#endif // COMMON_MAPINDEX_H
#ifdef COMMON_MMO_H
- { "quest", sizeof(struct quest) },
+ { "quest", sizeof(struct quest), SERVER_TYPE_ALL },
#else
#define COMMON_MMO_H
#endif // COMMON_MMO_H
#ifdef COMMON_SOCKET_H
- { "socket_interface", sizeof(struct socket_interface) },
+ { "socket_interface", sizeof(struct socket_interface), SERVER_TYPE_ALL },
#else
#define COMMON_SOCKET_H
#endif // COMMON_SOCKET_H
#ifdef COMMON_STRLIB_H
- { "StringBuf", sizeof(struct StringBuf) },
- { "s_svstate", sizeof(struct s_svstate) },
+ { "StringBuf", sizeof(struct StringBuf), SERVER_TYPE_ALL },
+ { "s_svstate", sizeof(struct s_svstate), SERVER_TYPE_ALL },
#else
#define COMMON_STRLIB_H
#endif // COMMON_STRLIB_H
#ifdef COMMON_SYSINFO_H
- { "sysinfo_interface", sizeof(struct sysinfo_interface) },
+ { "sysinfo_interface", sizeof(struct sysinfo_interface), SERVER_TYPE_ALL },
#else
#define COMMON_SYSINFO_H
#endif // COMMON_SYSINFO_H
#ifdef MAP_ATCOMMAND_H
- { "AliasInfo", sizeof(struct AliasInfo) },
- { "atcommand_interface", sizeof(struct atcommand_interface) },
+ { "AliasInfo", sizeof(struct AliasInfo), SERVER_TYPE_MAP },
+ { "atcommand_interface", sizeof(struct atcommand_interface), SERVER_TYPE_MAP },
#else
#define MAP_ATCOMMAND_H
#endif // MAP_ATCOMMAND_H
#ifdef MAP_BATTLE_H
- { "Damage", sizeof(struct Damage) },
- { "battle_interface", sizeof(struct battle_interface) },
+ { "Damage", sizeof(struct Damage), SERVER_TYPE_MAP },
+ { "battle_interface", sizeof(struct battle_interface), SERVER_TYPE_MAP },
#else
#define MAP_BATTLE_H
#endif // MAP_BATTLE_H
#ifdef MAP_BUYINGSTORE_H
- { "buyingstore_interface", sizeof(struct buyingstore_interface) },
- { "s_buyingstore_item", sizeof(struct s_buyingstore_item) },
+ { "buyingstore_interface", sizeof(struct buyingstore_interface), SERVER_TYPE_MAP },
+ { "s_buyingstore_item", sizeof(struct s_buyingstore_item), SERVER_TYPE_MAP },
#else
#define MAP_BUYINGSTORE_H
#endif // MAP_BUYINGSTORE_H
#ifdef MAP_CHRIF_H
- { "auth_node", sizeof(struct auth_node) },
+ { "auth_node", sizeof(struct auth_node), SERVER_TYPE_MAP },
#else
#define MAP_CHRIF_H
#endif // MAP_CHRIF_H
#ifdef MAP_CLIF_H
- { "clif_interface", sizeof(struct clif_interface) },
+ { "clif_interface", sizeof(struct clif_interface), SERVER_TYPE_MAP },
#else
#define MAP_CLIF_H
#endif // MAP_CLIF_H
#ifdef MAP_ELEMENTAL_H
- { "elemental_skill", sizeof(struct elemental_skill) },
+ { "elemental_skill", sizeof(struct elemental_skill), SERVER_TYPE_MAP },
#else
#define MAP_ELEMENTAL_H
#endif // MAP_ELEMENTAL_H
#ifdef MAP_GUILD_H
- { "eventlist", sizeof(struct eventlist) },
- { "guardian_data", sizeof(struct guardian_data) },
+ { "eventlist", sizeof(struct eventlist), SERVER_TYPE_MAP },
+ { "guardian_data", sizeof(struct guardian_data), SERVER_TYPE_MAP },
#else
#define MAP_GUILD_H
#endif // MAP_GUILD_H
#ifdef MAP_MAPREG_H
- { "mapreg_save", sizeof(struct mapreg_save) },
+ { "mapreg_save", sizeof(struct mapreg_save), SERVER_TYPE_MAP },
#else
#define MAP_MAPREG_H
#endif // MAP_MAPREG_H
#ifdef MAP_MAP_H
- { "map_data_other_server", sizeof(struct map_data_other_server) },
+ { "map_data_other_server", sizeof(struct map_data_other_server), SERVER_TYPE_MAP },
#else
#define MAP_MAP_H
#endif // MAP_MAP_H
#ifdef MAP_PACKETS_STRUCT_H
- { "EQUIPSLOTINFO", sizeof(struct EQUIPSLOTINFO) },
+ { "EQUIPSLOTINFO", sizeof(struct EQUIPSLOTINFO), SERVER_TYPE_MAP },
#else
#define MAP_PACKETS_STRUCT_H
#endif // MAP_PACKETS_STRUCT_H
#ifdef MAP_PC_H
- { "autotrade_vending", sizeof(struct autotrade_vending) },
- { "item_cd", sizeof(struct item_cd) },
+ { "autotrade_vending", sizeof(struct autotrade_vending), SERVER_TYPE_MAP },
+ { "item_cd", sizeof(struct item_cd), SERVER_TYPE_MAP },
#else
#define MAP_PC_H
#endif // MAP_PC_H
#ifdef MAP_SCRIPT_H
- { "Script_Config", sizeof(struct Script_Config) },
- { "reg_db", sizeof(struct reg_db) },
- { "script_interface", sizeof(struct script_interface) },
+ { "Script_Config", sizeof(struct Script_Config), SERVER_TYPE_MAP },
+ { "reg_db", sizeof(struct reg_db), SERVER_TYPE_MAP },
+ { "script_interface", sizeof(struct script_interface), SERVER_TYPE_MAP },
#else
#define MAP_SCRIPT_H
#endif // MAP_SCRIPT_H
#ifdef MAP_SEARCHSTORE_H
- { "searchstore_interface", sizeof(struct searchstore_interface) },
+ { "searchstore_interface", sizeof(struct searchstore_interface), SERVER_TYPE_MAP },
#else
#define MAP_SEARCHSTORE_H
#endif // MAP_SEARCHSTORE_H
#ifdef MAP_SKILL_H
- { "skill_cd", sizeof(struct skill_cd) },
- { "skill_condition", sizeof(struct skill_condition) },
- { "skill_interface", sizeof(struct skill_interface) },
- { "skill_unit_save", sizeof(struct skill_unit_save) },
+ { "skill_cd", sizeof(struct skill_cd), SERVER_TYPE_MAP },
+ { "skill_condition", sizeof(struct skill_condition), SERVER_TYPE_MAP },
+ { "skill_interface", sizeof(struct skill_interface), SERVER_TYPE_MAP },
+ { "skill_unit_save", sizeof(struct skill_unit_save), SERVER_TYPE_MAP },
#else
#define MAP_SKILL_H
#endif // MAP_SKILL_H
};
HPExport unsigned int HPMDataCheckLen = ARRAYLENGTH(HPMDataCheck);
+HPExport int HPMDataCheckVer = 1;
#endif /* HPM_DATA_CHECK_H */
diff --git a/src/common/HPMi.h b/src/common/HPMi.h
index 478cfbdd9..485586f6f 100644
--- a/src/common/HPMi.h
+++ b/src/common/HPMi.h
@@ -36,6 +36,7 @@ struct hplugin_info {
struct s_HPMDataCheck {
char *name;
unsigned int size;
+ int type;
};
HPExport void *(*import_symbol) (char *name, unsigned int pID);