diff options
-rw-r--r-- | src/char/Makefile.in | 2 | ||||
-rw-r--r-- | src/common/HPM.c | 40 | ||||
-rw-r--r-- | src/common/HPM.h | 9 | ||||
-rw-r--r-- | src/common/HPMi.h | 22 | ||||
-rw-r--r-- | src/common/Makefile.in | 3 | ||||
-rw-r--r-- | src/login/Makefile.in | 2 | ||||
-rw-r--r-- | src/map/Makefile.in | 2 | ||||
-rw-r--r-- | src/plugins/HPMHooking.c | 3 | ||||
-rw-r--r-- | src/plugins/HPMHooking.h | 55 | ||||
-rw-r--r-- | src/plugins/Makefile.in | 2 | ||||
-rw-r--r-- | src/plugins/sample.c | 1 |
11 files changed, 100 insertions, 41 deletions
diff --git a/src/char/Makefile.in b/src/char/Makefile.in index 456f7e9d2..fe40621fb 100644 --- a/src/char/Makefile.in +++ b/src/char/Makefile.in @@ -23,7 +23,7 @@ CONFIG_D = ../config CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) COMMON_D = ../common -COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) +COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) ../plugins/HPMHooking.h SYSINFO_INC = $(COMMON_D)/sysinfo.inc COMMON_INCLUDE = -I.. diff --git a/src/common/HPM.c b/src/common/HPM.c index d3d050d27..02b675704 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -38,6 +38,7 @@ #include "common/timer.h" #include "common/utils.h" #include "common/nullpo.h" +#include "plugins/HPMHooking.h" #include <stdio.h> #include <stdlib.h> @@ -51,6 +52,7 @@ struct malloc_interface iMalloc_HPM; struct malloc_interface *HPMiMalloc; struct HPM_interface HPM_s; struct HPM_interface *HPM; +struct HPMHooking_core_interface HPMHooking_core_s; /** * (char*) data name -> (unsigned int) HPMDataCheck[] index @@ -341,13 +343,13 @@ void hplugins_removeFromHPData(enum HPluginDataTypes type, uint32 pluginID, stru /* TODO: add ability for tracking using pID for the upcoming runtime load/unload support. */ bool HPM_AddHook(enum HPluginHookType type, const char *target, void *hook, unsigned int pID) { - if (!HPM->hooking) { + if (!HPM->hooking->enabled) { ShowError("HPM:AddHook Fail! '%s' tried to hook to '%s' but HPMHooking is disabled!\n",HPM->pid2name(pID),target); return false; } /* search if target is a known hook point within 'common' */ /* if not check if a sub-hooking list is available (from the server) and run it by */ - if (HPM->addhook_sub && HPM->addhook_sub(type,target,hook,pID)) + if (HPM->hooking->addhook_sub != NULL && HPM->hooking->addhook_sub(type,target,hook,pID)) return true; ShowError("HPM:AddHook: unknown Hooking Point '%s'!\n",target); @@ -358,12 +360,12 @@ bool HPM_AddHook(enum HPluginHookType type, const char *target, void *hook, unsi void HPM_HookStop(const char *func, unsigned int pID) { /* track? */ - HPM->force_return = true; + HPM->hooking->force_return = true; } -bool HPM_HookStopped (void) +bool HPM_HookStopped(void) { - return HPM->force_return; + return HPM->hooking->force_return; } /** @@ -567,16 +569,20 @@ struct hplugin *hplugin_load(const char* filename) { plugin->hpi->addToHPData = hplugins_addToHPData; plugin->hpi->getFromHPData = hplugins_getFromHPData; plugin->hpi->removeFromHPData = hplugins_removeFromHPData; - plugin->hpi->AddHook = HPM_AddHook; - plugin->hpi->HookStop = HPM_HookStop; - plugin->hpi->HookStopped = HPM_HookStopped; plugin->hpi->addArg = hpm_add_arg; plugin->hpi->addConf = hplugins_addconf; + if ((plugin->hpi->hooking = plugin_import(plugin->dll, "HPMHooking_s", struct HPMHooking_interface *)) != NULL) { + plugin->hpi->hooking->AddHook = HPM_AddHook; + plugin->hpi->hooking->HookStop = HPM_HookStop; + plugin->hpi->hooking->HookStopped = HPM_HookStopped; + } /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); - ShowStatus("HPM: Loaded plugin '"CL_WHITE"%s"CL_RESET"' (%s).\n", plugin->info->name, plugin->info->version); + ShowStatus("HPM: Loaded plugin '"CL_WHITE"%s"CL_RESET"' (%s)%s.\n", + plugin->info->name, plugin->info->version, + plugin->hpi->hooking != NULL ? " built with HPMHooking support" : ""); return plugin; } @@ -660,12 +666,13 @@ void hplugins_config_read(void) { bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); if ((func = plugin_import(plugin->dll, "Hooked",const char * (*)(bool *))) != NULL && (addhook_sub = plugin_import(plugin->dll, "HPM_Plugin_AddHook",bool (*)(enum HPluginHookType, const char *, void *, unsigned int))) != NULL) { - const char *failed = func(&HPM->force_return); + const char *failed = func(&HPM->hooking->force_return); if (failed) { ShowError("HPM: failed to retrieve '%s' for '"CL_WHITE"%s"CL_RESET"'!\n", failed, plugin_name); } else { - HPM->hooking = true; - HPM->addhook_sub = addhook_sub; + HPM->hooking->enabled = true; + HPM->hooking->addhook_sub = addhook_sub; + HPM->hooking->Hooked = func; // The purpose of this is type-checking 'func' at compile time. } } } @@ -1046,11 +1053,10 @@ void hpm_final(void) void hpm_defaults(void) { HPM = &HPM_s; + HPM->hooking = &HPMHooking_core_s; memset(&HPM->filenames, 0, sizeof(HPM->filenames)); VECTOR_INIT(HPM->cmdline_load_plugins); - HPM->force_return = false; - HPM->hooking = false; /* */ HPM->init = hpm_init; HPM->final = hpm_final; @@ -1067,7 +1073,6 @@ void hpm_defaults(void) HPM->pid2name = hplugins_id2name; HPM->parse_packets = hplugins_parse_packets; HPM->load_sub = NULL; - HPM->addhook_sub = NULL; HPM->parseConf = hplugins_parse_conf; HPM->getBattleConf = hplugins_get_battle_conf; HPM->DataCheck = HPM_DataCheck; @@ -1078,4 +1083,9 @@ void hpm_defaults(void) HPM->data_store_create = hplugin_data_store_create; HPM->data_store_validate = hplugin_data_store_validate; HPM->data_store_validate_sub = NULL; + + HPM->hooking->enabled = false; + HPM->hooking->force_return = false; + HPM->hooking->addhook_sub = NULL; + HPM->hooking->Hooked = NULL; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 109549aad..0b1275fde 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -65,6 +65,8 @@ #endif // WIN32 +struct HPMHooking_core_interface; + struct hplugin { DLL dll; unsigned int idx; @@ -126,9 +128,6 @@ struct HPM_interface { /* vars */ unsigned int version[2]; bool off; - bool hooking; - /* hooking */ - bool force_return; /* data */ VECTOR_DECL(struct hplugin *) plugins; VECTOR_DECL(struct hpm_symbol *) symbols; @@ -159,7 +158,6 @@ struct HPM_interface { char *(*pid2name) (unsigned int pid); unsigned char (*parse_packets) (int fd, int packet_id, enum HPluginPacketHookingPoints point); void (*load_sub) (struct hplugin *plugin); - bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); /* for custom config parsing */ bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point); bool (*getBattleConf) (const char* w1, int *value); @@ -173,6 +171,9 @@ struct HPM_interface { bool (*data_store_validate) (enum HPluginDataTypes type, struct hplugin_data_store **storeptr, bool initialize); /* for server-specific HPData e.g. map_session_data */ bool (*data_store_validate_sub) (enum HPluginDataTypes type, struct hplugin_data_store **storeptr, bool initialize); + + /* hooking */ + struct HPMHooking_core_interface *hooking; }; CMDLINEARG(loadplugin); diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 72640b382..e16eb1d75 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -25,6 +25,7 @@ #include "common/core.h" #include "common/showmsg.h" +struct HPMHooking_interface; struct Sql; // common/sql.h struct script_state; struct AtCommandInfo; @@ -32,7 +33,7 @@ struct socket_data; struct map_session_data; struct hplugin_data_store; -#define HPM_VERSION "1.1" +#define HPM_VERSION "1.2" #define HPM_ADDCONF_LENGTH 40 struct hplugin_info { @@ -71,11 +72,6 @@ enum HPluginPacketHookingPoints { hpPHP_MAX, }; -enum HPluginHookType { - HOOK_TYPE_PRE, - HOOK_TYPE_POST, -}; - /** * Data types for plugin custom data. */ @@ -107,13 +103,6 @@ enum HPluginConfType { 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 ;/ */ -/* will not run the original function after pre-hook processing is complete (other hooks will run) */ -#define hookStop() (HPMi->HookStop(__func__,HPMi->pid)) -#define hookStopped() (HPMi->HookStopped()) - #define addArg(name, param,func,help) (HPMi->addArg(HPMi->pid,(name),(param),(cmdline_arg_ ## func),(help))) /* HPData handy redirects */ /* session[] */ @@ -231,10 +220,6 @@ struct HPMi_interface { void (*removeFromHPData) (enum HPluginDataTypes type, uint32 pluginID, struct hplugin_data_store *store, uint32 classid); /* packet */ bool (*addPacket) (unsigned short cmd, unsigned short length, void (*receive)(int fd), unsigned int point, unsigned int pluginID); - /* Hooking */ - 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, CmdlineExecFunc func, const char *help); /* battle-config recv param */ @@ -243,6 +228,9 @@ struct HPMi_interface { void (*addPCGPermission) (unsigned int pluginID, char *name, unsigned int *mask); struct Sql *sql_handle; + + /* Hooking */ + struct HPMHooking_interface *hooking; }; #ifdef HERCULES_CORE #define HPM_SYMBOL(n, s) (HPM->share((s), (n)), true) diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 4580f70b8..6e7ffa088 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -50,7 +50,8 @@ COMMON_C += console.c core.c memmgr.c socket.c COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \ grfio.h hercules.h HPM.h HPMi.h memmgr.h mapindex.h md5calc.h \ mmo.h mutex.h nullpo.h random.h showmsg.h socket.h spinlock.h \ - sql.h strlib.h sysinfo.h thread.h timer.h utils.h winapi.h + sql.h strlib.h sysinfo.h thread.h timer.h utils.h winapi.h \ + ../plugins/HPMHooking.h COMMON_PH = COMMON_SQL_OBJ = obj_sql/sql.o diff --git a/src/login/Makefile.in b/src/login/Makefile.in index 274a82fc8..c74ed1e10 100644 --- a/src/login/Makefile.in +++ b/src/login/Makefile.in @@ -23,7 +23,7 @@ CONFIG_D = ../config CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) COMMON_D = ../common -COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) +COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) ../plugins/HPMHooking.h SYSINFO_INC = $(COMMON_D)/sysinfo.inc COMMON_INCLUDE = -I.. diff --git a/src/map/Makefile.in b/src/map/Makefile.in index ff582d2f9..3c6a3f806 100644 --- a/src/map/Makefile.in +++ b/src/map/Makefile.in @@ -23,7 +23,7 @@ CONFIG_D = ../config CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) COMMON_D = ../common -COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) +COMMON_H = $(filter-out %.p.h, $(wildcard $(COMMON_D)/*.h)) ../plugins/HPMHooking.h SYSINFO_INC = $(COMMON_D)/sysinfo.inc COMMON_INCLUDE = -I.. diff --git a/src/plugins/HPMHooking.c b/src/plugins/HPMHooking.c index 6530035b9..4fb7911c2 100644 --- a/src/plugins/HPMHooking.c +++ b/src/plugins/HPMHooking.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "HPMHooking.h" + #include "common/hercules.h" #include "common/db.h" #include "common/memmgr.h" diff --git a/src/plugins/HPMHooking.h b/src/plugins/HPMHooking.h new file mode 100644 index 000000000..b2d95dd8d --- /dev/null +++ b/src/plugins/HPMHooking.h @@ -0,0 +1,55 @@ +/** + * This file is part of Hercules. + * http://herc.ws - http://github.com/HerculesWS/Hercules + * + * Copyright (C) 2016 Hercules Dev Team + * + * Hercules is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef PLUGINS_HPMHOOKING_H +#define PLUGINS_HPMHOOKING_H + +#include "common/hercules.h" + +enum HPluginHookType { + HOOK_TYPE_PRE, + HOOK_TYPE_POST, +}; + +struct HPMHooking_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); +}; + +#ifdef HERCULES_CORE +struct HPMHooking_core_interface { + bool enabled; + bool force_return; + bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); + const char *(*Hooked)(bool *fr); +}; +#else // ! HERCULES_CORE +HPExport struct HPMHooking_interface HPMHooking_s; + +#define addHookPre(tname,hook) (HPMi->hooking->AddHook(HOOK_TYPE_PRE,(tname),(hook),HPMi->pid)) +#define addHookPost(tname,hook) (HPMi->hooking->AddHook(HOOK_TYPE_POST,(tname),(hook),HPMi->pid)) +/* need better names ;/ */ +/* will not run the original function after pre-hook processing is complete (other hooks will run) */ +#define hookStop() (HPMi->hooking->HookStop(__func__,HPMi->pid)) +#define hookStopped() (HPMi->hooking->HookStopped()) + +#endif // ! HERCULES_CORE + +#endif // PLUGINS_HPMHOOKING_H diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index c3baa2f30..42d6d821c 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -47,7 +47,7 @@ PLUGINS = sample db2sql HPMHooking_char HPMHooking_login HPMHooking_map $(MYPLUG COMMON_D = ../common # Includes private headers (plugins might need them) -COMMON_H = $(wildcard $(COMMON_D)/*.h) +COMMON_H = $(wildcard $(COMMON_D)/*.h) ../plugins/HPMHooking.h COMMON_INCLUDE = -I.. THIRDPARTY_INCLUDE = -I../../3rdparty diff --git a/src/plugins/sample.c b/src/plugins/sample.c index 8fba2f4df..d6036dd70 100644 --- a/src/plugins/sample.c +++ b/src/plugins/sample.c @@ -29,6 +29,7 @@ #include "map/pc.h" #include "map/script.h" +#include "plugins/HPMHooking.h" #include "common/HPMDataCheck.h" /* should always be the last Hercules file included! (if you don't make it last, it'll intentionally break compile time) */ #include <stdio.h> |