diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 110 | ||||
-rw-r--r-- | src/common/HPM.h | 8 | ||||
-rw-r--r-- | src/common/HPMi.h | 23 | ||||
-rw-r--r-- | src/common/Makefile.in | 17 | ||||
-rw-r--r-- | src/common/db.c | 18 | ||||
-rw-r--r-- | src/common/db.h | 13 | ||||
-rw-r--r-- | src/common/mmo.h | 52 | ||||
-rw-r--r-- | src/common/timer.h | 3 |
8 files changed, 188 insertions, 56 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 9895ae95d..8be9298f9 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -40,7 +40,7 @@ void hplugin_export_symbol(void *var, char *name) { HPM->symbols[HPM->symbol_count - 1]->ptr = var; } -void *hplugin_import_symbol(char *name) { +void *hplugin_import_symbol(char *name, unsigned int pID) { unsigned int i; for( i = 0; i < HPM->symbol_count; i++ ) { @@ -48,7 +48,7 @@ void *hplugin_import_symbol(char *name) { return HPM->symbols[i]->ptr; } - ShowError("HPM:get_symbol: '"CL_WHITE"%s"CL_RESET"' not found!\n",name); + ShowError("HPM:get_symbol:%s: '"CL_WHITE"%s"CL_RESET"' not found!\n",HPM->pid2name(pID),name); return NULL; } @@ -59,7 +59,7 @@ bool hplugin_iscompatible(char* version) { return false; sscanf(version, "%u.%u", &req_major, &req_minor); - + return ( req_major == HPM->version[0] && req_minor <= HPM->version[1] ) ? true : false; } @@ -108,7 +108,7 @@ bool hplugin_populate(struct hplugin *plugin, const char *filename) { return true; } -void hplugin_load(const char* filename) { +struct hplugin *hplugin_load(const char* filename) { struct hplugin *plugin; struct hplugin_info *info; struct HPMi_interface **HPMi; @@ -118,7 +118,7 @@ void hplugin_load(const char* filename) { if( HPM->exists(filename) ) { ShowWarning("HPM:plugin_load: attempting to load duplicate '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); - return; + return NULL; } plugin = HPM->create(); @@ -126,30 +126,33 @@ void hplugin_load(const char* filename) { if( !( plugin->dll = plugin_open(filename) ) ){ ShowWarning("HPM:plugin_load: failed to load '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } if( !( info = plugin_import(plugin->dll, "pinfo",struct hplugin_info*) ) ) { ShowDebug("HPM:plugin_load: failed to retrieve 'plugin_info' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } if( !(info->type & SERVER_TYPE) ) { HPM->unload(plugin); - return; + return NULL; } if( !HPM->iscompatible(info->req_version) ) { ShowWarning("HPM:plugin_load: '"CL_WHITE"%s"CL_RESET"' incompatible version '%s' -> '%s', skipping...\n", filename, info->req_version, HPM_VERSION); HPM->unload(plugin); - return; + return NULL; } - + + plugin->info = info; + plugin->filename = aStrdup(filename); + if( !( import_symbol_ref = plugin_import(plugin->dll, "import_symbol",void **) ) ) { ShowWarning("HPM:plugin_load: failed to retrieve 'import_symbol' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } *import_symbol_ref = HPM->import_symbol; @@ -157,21 +160,21 @@ void hplugin_load(const char* filename) { if( !( sql_handle = plugin_import(plugin->dll, "mysql_handle",Sql **) ) ) { ShowWarning("HPM:plugin_load: failed to retrieve 'mysql_handle' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } - *sql_handle = HPM->import_symbol("sql_handle"); + *sql_handle = HPM->import_symbol("sql_handle",plugin->idx); if( !( HPMi = plugin_import(plugin->dll, "HPMi",struct HPMi_interface **) ) ) { ShowWarning("HPM:plugin_load: failed to retrieve 'HPMi' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } if( !( *HPMi = plugin_import(plugin->dll, "HPMi_s",struct HPMi_interface *) ) ) { ShowWarning("HPM:plugin_load: failed to retrieve 'HPMi_s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); - return; + return NULL; } plugin->hpi = *HPMi; @@ -184,30 +187,34 @@ void hplugin_load(const char* filename) { if( ( plugin->hpi->event[HPET_READY] = plugin_import(plugin->dll, "server_online",void (*)(void)) ) ) anyEvent = true; + if( ( plugin->hpi->event[HPET_POST_FINAL] = plugin_import(plugin->dll, "server_post_final",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); - return; + return NULL; } if( !HPM->populate(plugin,filename) ) - return; + return NULL; + /* id */ plugin->hpi->pid = plugin->idx; /* core */ - plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand"); - plugin->hpi->addPacket = HPM->import_symbol("addPacket"); - plugin->hpi->addToSession = HPM->import_symbol("addToSession"); - plugin->hpi->getFromSession = HPM->import_symbol("getFromSession"); - plugin->hpi->removeFromSession = HPM->import_symbol("removeFromSession"); + 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); /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); - - plugin->info = info; - plugin->filename = aStrdup(filename); - - return; + + return plugin; } void hplugin_unload(struct hplugin* plugin) { @@ -253,8 +260,26 @@ void hplugins_config_read(void) { int length = config_setting_length(plist), i; char filename[60]; for(i = 0; i < length; i++) { - snprintf(filename, 60, "plugins/%s%s", config_setting_get_string_elem(plist,i), DLL_EXT); - HPM->load(filename); + if( !strcmpi(config_setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first + struct hplugin *plugin; + snprintf(filename, 60, "plugins/%s%s", config_setting_get_string_elem(plist,i), 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) ) { + HPM->hooking = true; + HPM->addhook_sub = addhook_sub; + } + } + } + } + } + for(i = 0; i < length; i++) { + if( strcmpi(config_setting_get_string_elem(plist,i),"HPMHooking") ) {//now all others + snprintf(filename, 60, "plugins/%s%s", config_setting_get_string_elem(plist,i), DLL_EXT); + HPM->load(filename); + } } config_destroy(&plugins_conf); } @@ -436,6 +461,25 @@ void* HPM_realloc(void *p, size_t size, const char *file, int line, const char * char* HPM_astrdup(const char *p, const char *file, int line, const char *func) { return iMalloc->astrdup(p,HPM_file2ptr(file),line,func); } +/* 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 ) { + 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) ) + return true; + return false; +} +void HPM_HookStop (const char *func, unsigned int pID) { + /* track? */ + HPM->force_return = true; +} +bool HPM_HookStopped (void) { + return HPM->force_return; +} void hplugins_share_defaults(void) { /* console */ @@ -447,6 +491,9 @@ void hplugins_share_defaults(void) { HPM->share(hplugins_addToSession,"addToSession"); HPM->share(hplugins_getFromSession,"getFromSession"); HPM->share(hplugins_removeFromSession,"removeFromSession"); + HPM->share(HPM_AddHook,"AddHook"); + HPM->share(HPM_HookStop,"HookStop"); + HPM->share(HPM_HookStopped,"HookStopped"); /* core */ HPM->share(&runflag,"runflag"); HPM->share(arg_v,"arg_v"); @@ -489,7 +536,7 @@ void hpm_init(void) { HPMiMalloc->realloc = HPM_realloc; HPMiMalloc->astrdup = HPM_astrdup; - sscanf(HPM_VERSION, "%d.%d", &HPM->version[0], &HPM->version[1]); + sscanf(HPM_VERSION, "%u.%u", &HPM->version[0], &HPM->version[1]); if( HPM->version[0] == 0 && HPM->version[1] == 0 ) { ShowError("HPM:init:failed to retrieve HPM version!!\n"); @@ -554,6 +601,8 @@ void hpm_defaults(void) { HPM->fnames = NULL; HPM->fnamec = 0; + HPM->force_return = false; + HPM->hooking = false; HPM->init = hpm_init; HPM->final = hpm_final; @@ -573,4 +622,5 @@ void hpm_defaults(void) { HPM->pid2name = hplugins_id2name; HPM->parse_packets = hplugins_parse_packets; HPM->load_sub = NULL; + HPM->addhook_sub = NULL; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 614498fd3..395555948 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -79,6 +79,9 @@ struct HPM_interface { /* vars */ unsigned int version[2]; bool off; + bool hooking; + /* hooking */ + bool force_return; /* data */ struct hplugin **plugins; unsigned int plugin_count; @@ -94,12 +97,12 @@ struct HPM_interface { void (*init) (void); void (*final) (void); struct hplugin * (*create) (void); - void (*load) (const char* filename); + struct hplugin * (*load) (const char* filename); void (*unload) (struct hplugin* plugin); bool (*exists) (const char *filename); bool (*iscompatible) (char* version); void (*event) (enum hp_event_types type); - void *(*import_symbol) (char *); + void *(*import_symbol) (char *name, unsigned int pID); void (*share) (void *, char *); void (*symbol_defaults) (void); void (*config_read) (void); @@ -108,6 +111,7 @@ struct HPM_interface { char *(*pid2name) (unsigned int pid); 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); } HPM_s; struct HPM_interface *HPM; diff --git a/src/common/HPMi.h b/src/common/HPMi.h index c8bce8ee8..9c2a6184e 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -35,7 +35,7 @@ struct map_session_data; /* after */ #include "../common/showmsg.h" -#define HPM_VERSION "0.2" +#define HPM_VERSION "1.0" struct hplugin_info { char* name; @@ -44,10 +44,10 @@ struct hplugin_info { char* req_version; }; -HPExport void *(*import_symbol) (char *name); +HPExport void *(*import_symbol) (char *name, unsigned int pID); HPExport Sql *mysql_handle; -#define GET_SYMBOL(n) import_symbol(n) +#define GET_SYMBOL(n) import_symbol(n,HPMi->pid) #define SERVER_TYPE_ALL SERVER_TYPE_LOGIN|SERVER_TYPE_CHAR|SERVER_TYPE_MAP @@ -55,6 +55,7 @@ enum hp_event_types { HPET_INIT,/* server starts */ HPET_FINAL,/* server is shutting down */ HPET_READY,/* server is ready (online) */ + HPET_POST_FINAL,/* server is done shutting down */ HPET_MAX, }; @@ -70,6 +71,18 @@ enum HPluginPacketHookingPoints { hpPHP_MAX, }; +enum HPluginHookType { + HOOK_TYPE_PRE, + HOOK_TYPE_POST, +}; + +#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() + /* Hercules Plugin Mananger Include Interface */ HPExport struct HPMi_interface { /* */ @@ -89,6 +102,10 @@ HPExport struct HPMi_interface { void (*removeFromSession) (struct socket_data *sess, unsigned int id, unsigned int type); /* 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); } HPMi_s; #ifndef _HPM_H_ HPExport struct HPMi_interface *HPMi; diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 78f9cd0d1..53b7a472e 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -40,22 +40,25 @@ CC = @CC@ export CC ##################################################################### -.PHONY: all sql common common_sql common_mini clean help +.PHONY: all sql common common_sql common_mini clean buildclean help all: sql sql: $(SQL_DEPENDS) -clean: - @echo " CLEAN common" +buildclean: + @echo " CLEAN common (build temp files)" @rm -rf *.o obj_all obj_sql +clean: buildclean + @echo " CLEAN common" + help: @echo "possible targets are 'sql' 'all' 'clean' 'help'" - @echo "'sql' - builds object files used in sql servers" - @echo "'all' - builds all above targets" - @echo "'clean' - cleans builds and objects" - @echo "'help' - outputs this message" + @echo "'sql' - builds object files used in sql servers" + @echo "'all' - builds all above targets" + @echo "'clean', 'buildclean' - cleans builds and objects" + @echo "'help' - outputs this message" ##################################################################### diff --git a/src/common/db.c b/src/common/db.c index bd2bea424..b3a58e0a4 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -2730,20 +2730,26 @@ void linkdb_insert( struct linkdb_node** head, void *key, void* data) node->data = data; } -void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... ) -{ +void linkdb_vforeach( struct linkdb_node** head, LinkDBFunc func, va_list ap) { struct linkdb_node *node; if( head == NULL ) return; node = *head; while ( node ) { - va_list args; - va_start(args, func); - func( node->key, node->data, args ); - va_end(args); + va_list argscopy; + va_copy(argscopy, ap); + func(node->key, node->data, argscopy); + va_end(argscopy); node = node->next; } } +void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ...) { + va_list ap; + va_start(ap, func); + linkdb_vforeach(head, func, ap); + va_end(ap); +} + void* linkdb_search( struct linkdb_node** head, void *key) { int n = 0; diff --git a/src/common/db.h b/src/common/db.h index aa4bfb054..dffd2356d 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -882,12 +882,13 @@ struct linkdb_node { typedef void (*LinkDBFunc)(void* key, void* data, va_list args); -void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // 重複を考慮しない -void linkdb_replace( struct linkdb_node** head, void *key, void* data); // 重複を考慮する -void* linkdb_search ( struct linkdb_node** head, void *key); -void* linkdb_erase ( struct linkdb_node** head, void *key); -void linkdb_final ( struct linkdb_node** head ); -void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... ); +void linkdb_insert (struct linkdb_node** head, void *key, void* data); // 重複を考慮しない +void linkdb_replace (struct linkdb_node** head, void *key, void* data); // 重複を考慮する +void* linkdb_search (struct linkdb_node** head, void *key); +void* linkdb_erase (struct linkdb_node** head, void *key); +void linkdb_final (struct linkdb_node** head); +void linkdb_vforeach(struct linkdb_node** head, LinkDBFunc func, va_list ap); +void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...); diff --git a/src/common/mmo.h b/src/common/mmo.h index b51d0ec4a..205cf8425 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -772,16 +772,68 @@ enum { JOB_KAGEROU = 4211, JOB_OBORO, + JOB_REBELLION = 4215, JOB_MAX, }; +//Total number of classes (for data storage) +#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC) + enum { SEX_FEMALE = 0, SEX_MALE, SEX_SERVER }; +enum weapon_type { + W_FIST, //Bare hands + W_DAGGER, //1 + W_1HSWORD, //2 + W_2HSWORD, //3 + W_1HSPEAR, //4 + W_2HSPEAR, //5 + W_1HAXE, //6 + W_2HAXE, //7 + W_MACE, //8 + W_2HMACE, //9 (unused) + W_STAFF, //10 + W_BOW, //11 + W_KNUCKLE, //12 + W_MUSICAL, //13 + W_WHIP, //14 + W_BOOK, //15 + W_KATAR, //16 + W_REVOLVER, //17 + W_RIFLE, //18 + W_GATLING, //19 + W_SHOTGUN, //20 + W_GRENADE, //21 + W_HUUMA, //22 + W_2HSTAFF, //23 + MAX_WEAPON_TYPE, + // dual-wield constants + W_DOUBLE_DD, // 2 daggers + W_DOUBLE_SS, // 2 swords + W_DOUBLE_AA, // 2 axes + W_DOUBLE_DS, // dagger + sword + W_DOUBLE_DA, // dagger + axe + W_DOUBLE_SA, // sword + axe +}; + +enum ammo_type { + A_ARROW = 1, + A_DAGGER, //2 + A_BULLET, //3 + A_SHELL, //4 + A_GRENADE, //5 + A_SHURIKEN, //6 + A_KUNAI, //7 + A_CANNONBALL, //8 + A_THROWWEAPON //9 +}; + + // sanity checks... #if MAX_ZENY > INT_MAX #error MAX_ZENY is too big diff --git a/src/common/timer.h b/src/common/timer.h index 3146a2e66..600f9fd02 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -23,9 +23,8 @@ typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data); struct TimerData { unsigned int tick; TimerFunc func; - int type; + unsigned char type; int interval; - int heap_pos; // general-purpose storage int id; |