summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/HPM.c110
-rw-r--r--src/common/HPM.h8
-rw-r--r--src/common/HPMi.h23
-rw-r--r--src/common/Makefile.in17
-rw-r--r--src/common/db.c18
-rw-r--r--src/common/db.h13
-rw-r--r--src/common/mmo.h52
-rw-r--r--src/common/timer.h3
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;