From 3b89a135dcde9779bd0537cd136a7c34cfadbe3f Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sun, 17 Mar 2013 01:12:33 -0300 Subject: Re-Introducing Console Input It's back. It's efficient. It's awesome. http://hercules.ws/board/topic/272-re-introducing-console-input/ Signed-off-by: shennetsind --- src/common/console.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 src/common/console.c (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c new file mode 100644 index 000000000..ee4570b2a --- /dev/null +++ b/src/common/console.c @@ -0,0 +1,186 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams + +#include "../common/showmsg.h" +#include "../common/console.h" +#include "../config/core.h" +#include "core.h" + +#ifndef MINICORE + #include "../common/atomic.h" + #include "../common/spinlock.h" + #include "../common/thread.h" + #include "../common/mutex.h" + #include "../common/timer.h" + #include "../common/strlib.h" +#endif + +#include +#include +#ifndef _WIN32 + #include +#else + #include "../common/winapi.h" // Console close event handling +#endif + +#ifdef CONSOLE_INPUT + #ifdef _WIN32 + #include /* _kbhit() */ + #endif +#endif + +/*====================================== + * CORE : Display title + *--------------------------------------*/ +void display_title(void) { + const char* svn = get_svn_revision(); + const char* git = get_git_hash(); + + ShowMessage("\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" Hercules Development Team presents "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" _ _ _ "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" | | | | | | "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" | |_| | ___ _ __ ___ _ _| | ___ ___ "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" | _ |/ _ \\ '__/ __| | | | |/ _ \\/ __|"CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" | | | | __/ | | (__| |_| | | __/\\__ \\"CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" \\_| |_/\\___|_| \\___|\\__,_|_|\\___||___/"CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" http://hercules.ws/board/ "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_BG_RED" "CL_BT_WHITE" "CL_BG_RED""CL_CLL""CL_NORMAL"\n"); + + if( git[0] != HERC_UNKNOWN_VER ) + ShowInfo("Git Hash: '"CL_WHITE"%s"CL_RESET"'\n", git); + else if( svn[0] != HERC_UNKNOWN_VER ) + ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'\n", svn); +} +#ifdef CONSOLE_INPUT +#ifdef _WIN32 +int console_parse_key_pressed(void) { + return _kbhit(); +} +#else /* _WIN32 */ +int console_parse_key_pressed(void) { + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + + return FD_ISSET(STDIN_FILENO, &fds); +} +#endif /* _WIN32 */ + +void console_parse(char* line) { + int c, i = 0, len = MAX_CONSOLE_INPUT - 1;/* we leave room for the \0 :P */ + + while( (c = fgetc(stdin)) != EOF ) { + if( --len == 0 ) + break; + if( (line[i++] = c) == '\n') { + line[i-1] = '\0';/* clear, we skip the new line */ + break;/* new line~! we leave it for the next cycle */ + } + } + + line[i++] = '\0'; +} +void *cThread_main(void *x) { + + while( console->ptstate ) {/* loopx */ + if( console->key_pressed() ) { + char input[MAX_CONSOLE_INPUT]; + + console->parse(input); + if( input[0] != '\0' ) {/* did we get something? */ + EnterSpinLock(&console->ptlock); + + if( cinput.count == CONSOLE_PARSE_SIZE ) { + LeaveSpinLock(&console->ptlock); + continue;/* drop */ + } + + safestrncpy(cinput.queue[cinput.count++],input,MAX_CONSOLE_INPUT); + LeaveSpinLock(&console->ptlock); + } + } + ramutex_lock( console->ptmutex ); + racond_wait( console->ptcond, console->ptmutex, -1 ); + ramutex_unlock( console->ptmutex ); + } + + return NULL; +} +int console_parse_timer(int tid, unsigned int tick, int id, intptr_t data) { + int i; + EnterSpinLock(&console->ptlock); + for(i = 0; i < cinput.count; i++) { + parse_console(cinput.queue[i]); + } + cinput.count = 0; + LeaveSpinLock(&console->ptlock); + racond_signal(console->ptcond); + return 0; +} +void console_parse_final(void) { + InterlockedDecrement(&console->ptstate); + racond_signal(console->ptcond); + + /* wait for thread to close */ + rathread_wait(console->pthread, NULL); + + racond_destroy(console->ptcond); + ramutex_destroy(console->ptmutex); + +} +void console_parse_init(void) { + cinput.count = 0; + + console->ptstate = 1; + + InitializeSpinLock(&console->ptlock); + + console->ptmutex = ramutex_create(); + console->ptcond = racond_create(); + + if( (console->pthread = rathread_create(console->pthread_main, NULL)) == NULL ){ + ShowFatalError("console_parse_init: failed to spawn console_parse thread.\n"); + exit(EXIT_FAILURE); + } + + add_timer_func_list(console->parse_timer, "console_parse_timer"); + add_timer_interval(gettick() + 1000, console->parse_timer, 0, 0, 500);/* start listening in 1s; re-try every 0.5s */ + +} +#endif /* CONSOLE_INPUT */ + +void console_init (void) { + console->display_title(); +#ifdef CONSOLE_INPUT + console->parse_init(); +#endif +} +void console_final(void) { +#ifdef CONSOLE_INPUT + console->parse_final(); +#endif +} +void console_defaults(void) { + console = &console_s; + console->init = console_init; + console->final = console_final; + console->display_title = display_title; +#ifdef CONSOLE_INPUT + console->parse_init = console_parse_init; + console->parse_final = console_parse_final; + console->parse_timer = console_parse_timer; + console->pthread_main = cThread_main; + console->parse = console_parse; + console->key_pressed = console_parse_key_pressed; +#endif +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 81809c70483a1046f64d25ef4ad88c850ff6a0a2 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sun, 17 Mar 2013 18:44:17 -0300 Subject: Fixed mysterious msvc LNK2005 error. Also fixed title being displayed twice. Signed-off-by: shennetsind --- src/common/console.c | 7 ++++--- src/common/console.h | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index ee4570b2a..08ab6bcd4 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -3,9 +3,9 @@ // Portions Copyright (c) Athena Dev Teams #include "../common/showmsg.h" -#include "../common/console.h" +#include "../common/core.h" #include "../config/core.h" -#include "core.h" +#include "console.h" #ifndef MINICORE #include "../common/atomic.h" @@ -30,6 +30,8 @@ #endif #endif +struct console_interface console_s; + /*====================================== * CORE : Display title *--------------------------------------*/ @@ -160,7 +162,6 @@ void console_parse_init(void) { #endif /* CONSOLE_INPUT */ void console_init (void) { - console->display_title(); #ifdef CONSOLE_INPUT console->parse_init(); #endif diff --git a/src/common/console.h b/src/common/console.h index d0b9e8bb1..7f1490084 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -4,7 +4,6 @@ #ifndef _CONSOLE_H_ #define _CONSOLE_H_ -#include "../common/atomic.h" #include "../common/thread.h" #include "../common/mutex.h" #include "../common/spinlock.h" @@ -39,7 +38,7 @@ struct console_interface { void (*parse) (char* line); int (*key_pressed) (void); #endif -} console_s; +}; struct console_interface *console; -- cgit v1.2.3-70-g09d2 From 64dca8681c90dca15009fb82e54154d3faf3b1d6 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Thu, 25 Apr 2013 10:32:26 -0300 Subject: Fixed Bug #7189 http://hercules.ws/board/tracker/issue-7189-warning-while-recompiling-using-centos5/ Signed-off-by: shennetsind --- src/char/pincode.c | 2 +- src/char/pincode.h | 2 +- src/common/console.c | 2 +- src/login/account_sql.c | 2 +- src/map/pc.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/common/console.c') diff --git a/src/char/pincode.c b/src/char/pincode.c index 4135c0c1c..2603df2d8 100644 --- a/src/char/pincode.c +++ b/src/char/pincode.c @@ -198,4 +198,4 @@ void pincode_defaults(void) { pincode->check = pincode_check; pincode->config_read = pincode_config_read; -} \ No newline at end of file +} diff --git a/src/char/pincode.h b/src/char/pincode.h index 94e0b4f5b..358f21ff7 100644 --- a/src/char/pincode.h +++ b/src/char/pincode.h @@ -39,4 +39,4 @@ struct pincode_interface *pincode; void pincode_defaults(void); -#endif /* _PINCODE_H_ */ \ No newline at end of file +#endif /* _PINCODE_H_ */ diff --git a/src/common/console.c b/src/common/console.c index 08ab6bcd4..67897ee81 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -184,4 +184,4 @@ void console_defaults(void) { console->parse = console_parse; console->key_pressed = console_parse_key_pressed; #endif -} \ No newline at end of file +} diff --git a/src/login/account_sql.c b/src/login/account_sql.c index 9fbe50727..1d77f1975 100644 --- a/src/login/account_sql.c +++ b/src/login/account_sql.c @@ -688,4 +688,4 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo void account_db_sql_up(AccountDB* self) { AccountDB_SQL* db = (AccountDB_SQL*)self; Sql_HerculesUpdateCheck(db->accounts); -} \ No newline at end of file +} diff --git a/src/map/pc.c b/src/map/pc.c index 2ac5d6919..671cea6c4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4593,7 +4593,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil struct status_data *sd_status, *md_status; struct mob_data *md; struct item tmp_item; - struct item_data *data; + struct item_data *data = NULL; if(!sd || !bl || bl->type!=BL_MOB) return 0; -- cgit v1.2.3-70-g09d2 From a2c45a8db6d724b98ab41fe9e75e1f7ea7523d5d Mon Sep 17 00:00:00 2001 From: shennetsind Date: Thu, 2 May 2013 17:14:01 -0300 Subject: Introducing Hercules Plugin Mananger http://hercules.ws/board/topic/549-introducing-hercules-plugin-manager/ Signed-off-by: shennetsind --- Hercules-9.sln | 6 + Makefile.in | 17 + conf/plugins.conf | 15 + configure | 241 ++++++ configure.in | 106 ++- plugins/empty.txt | 1 + src/CMakeLists.txt | 1 + src/char/char.c | 25 +- src/common/CMakeLists.txt | 3 + src/common/HPM.c | 348 ++++++++ src/common/HPM.h | 83 ++ src/common/HPMi.h | 67 ++ src/common/Makefile.in | 2 +- src/common/console.c | 223 ++++- src/common/console.h | 24 + src/common/core.c | 16 +- src/common/core.h | 17 +- src/common/db.c | 20 +- src/common/ers.c | 9 +- src/common/netbuffer.c | 8 +- src/common/showmsg.c | 17 +- src/common/showmsg.h | 32 +- src/login/login.c | 57 +- src/map/atcommand.c | 90 +- src/map/atcommand.h | 12 +- src/map/clif.c | 42 +- src/map/map.c | 199 ++--- src/map/npc_chat.c | 12 +- src/map/pc_groups.c | 11 +- src/map/script.c | 1484 +++++++++++++++----------------- src/map/script.h | 129 ++- src/plugins/CMakeLists.txt | 36 + src/plugins/Makefile.in | 28 + src/plugins/sample.c | 74 ++ vcproj-10/char-server.vcxproj | 3 + vcproj-10/char-server.vcxproj.filters | 9 + vcproj-10/login-server.vcxproj | 3 + vcproj-10/login-server.vcxproj.filters | 9 + vcproj-10/map-server.vcxproj | 3 + vcproj-10/map-server.vcxproj.filters | 9 + vcproj-12/char-server.vcxproj | 3 + vcproj-12/char-server.vcxproj.filters | 9 + vcproj-12/login-server.vcxproj | 3 + vcproj-12/login-server.vcxproj.filters | 9 + vcproj-12/map-server.vcxproj | 3 + vcproj-12/map-server.vcxproj.filters | 9 + vcproj-9/char-server.vcproj | 12 + vcproj-9/login-server.vcproj | 12 + vcproj-9/map-server.vcproj | 12 + vcproj-9/plugin-sample.vcproj | 187 ++++ 50 files changed, 2664 insertions(+), 1086 deletions(-) create mode 100644 conf/plugins.conf create mode 100644 plugins/empty.txt create mode 100644 src/common/HPM.c create mode 100644 src/common/HPM.h create mode 100644 src/common/HPMi.h create mode 100644 src/plugins/CMakeLists.txt create mode 100644 src/plugins/Makefile.in create mode 100644 src/plugins/sample.c create mode 100644 vcproj-9/plugin-sample.vcproj (limited to 'src/common/console.c') diff --git a/Hercules-9.sln b/Hercules-9.sln index 7159e3f7f..66f4522b2 100644 --- a/Hercules-9.sln +++ b/Hercules-9.sln @@ -8,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map-server", "vcproj-9\map- EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mapcache", "vcproj-9\mapcache.vcproj", "{D356871D-58E1-450B-967A-E7E9646175AF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin-sample", "vcproj-9\plugin-sample.vcproj", "{D356871D-58E1-450B-967A-E7E9646175AF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -30,6 +32,10 @@ Global {D356871D-58E1-450B-967A-E7E9646175AF}.Debug|Win32.Build.0 = Debug|Win32 {D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.ActiveCfg = Release|Win32 {D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.Build.0 = Release|Win32 + {D356871D-58E1-450B-967A-E6E9646175AF}.Debug|Win32.ActiveCfg = Debug|Win32 + {D356871D-58E1-450B-967A-E6E9646175AF}.Debug|Win32.Build.0 = Debug|Win32 + {D356871D-58E1-450B-967A-E6E9646175AF}.Release|Win32.ActiveCfg = Release|Win32 + {D356871D-58E1-450B-967A-E6E9646175AF}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Makefile.in b/Makefile.in index 251a874d1..769892f1a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,6 +18,14 @@ else MAP_SQL_DEPENDS=needs_mysql endif +WITH_PLUGINS=@WITH_PLUGINS@ +ifeq ($(WITH_PLUGINS),yes) + ALL_DEPENDS+=plugins + PLUGIN_DEPENDS=common_sql +else + PLUGIN_DEPENDS=no_plugins +endif + ##################################################################### .PHONY: sql \ @@ -27,6 +35,7 @@ endif char_sql \ map_sql \ tools \ + plugins \ import \ test \ clean help @@ -59,6 +68,9 @@ tools: test: @$(MAKE) -C src/test +plugins: $(PLUGIN_DEPENDS) + @$(MAKE) -C src/plugins + import: # 1) create conf/import folder # 2) add missing files @@ -75,6 +87,7 @@ clean: @$(MAKE) -C src/login $@ @$(MAKE) -C src/char $@ @$(MAKE) -C src/map $@ + @$(MAKE) -C src/plugins $@ @$(MAKE) -C src/tool $@ @$(MAKE) -C src/test $@ @@ -102,6 +115,10 @@ needs_mysql: @echo "MySQL not found or disabled by the configure script" @exit 1 +no_plugins: + @echo "Plugins disabled by the configure script" + @exit 1 + ##################################################################### # TODO diff --git a/conf/plugins.conf b/conf/plugins.conf new file mode 100644 index 000000000..5233c4ed4 --- /dev/null +++ b/conf/plugins.conf @@ -0,0 +1,15 @@ +//==================================================== +//= _ _ _ +//= | | | | | | +//= | |_| | ___ _ __ ___ _ _| | ___ ___ +//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __| +//= | | | | __/ | | (__| |_| | | __/\__ \ +//= \_| |_/\___|_| \___|\__,_|_|\___||___/ +//= +//= http://hercules.ws/board/ +//==================================================== +// == http://hercules.ws/board/topic/549-introducing-hercules-plugin-manager/ +plugins_list:[ + //"sample" + //"other" +] \ No newline at end of file diff --git a/configure b/configure index 3c0eaaf41..62680923e 100755 --- a/configure +++ b/configure @@ -604,6 +604,8 @@ MYSQL_CFLAGS MYSQL_VERSION HAVE_MYSQL MYSQL_CONFIG_HOME +WITH_PLUGINS +SOFLAGS AR SET_MAKE EGREP @@ -2127,6 +2129,8 @@ ac_config_files="$ac_config_files 3rdparty/mt19937ar/Makefile 3rdparty/libconfig ac_config_files="$ac_config_files src/char/Makefile src/login/Makefile" +ac_config_files="$ac_config_files src/plugins/Makefile" + ac_config_files="$ac_config_files src/map/Makefile src/tool/Makefile" ac_config_files="$ac_config_files src/test/Makefile" @@ -4425,6 +4429,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="$CFLAGS -pipe -ffast-math -Wall -Wno-sign-compare" CPPFLAGS="$CPPFLAGS -I../common" +# flags used for compiling shared objects +SOFLAGS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 @@ -4947,6 +4953,240 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$OLD_CFLAGS" +# +# option for shared objects +# +echo "$as_me:$LINENO: checking how to make shared objects" >&5 +echo $ECHO_N "checking how to make shared objects... $ECHO_C" >&6 +OLD_CFLAGS="$CFLAGS" +compiler_shared_objects="" +if test "$compiler_supports_pic" = "yes" ; then + my_shared_test_flags="$CFLAGS -fPIC" +fi +# default +CFLAGS="$my_shared_test_flags -shared" +cat >conftest.$ac_ext <<_ACEOF + + int bar = 0; + + int foo(void) + { + return bar; + } + +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + compiler_shared_objects="-shared" + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +# BeOS specific +CFLAGS="$my_shared_test_flags -nostart" +cat >conftest.$ac_ext <<_ACEOF + + int bar = 0; + + int foo(void) + { + return bar; + } + +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + compiler_shared_objects="-nostart" + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +my_shared_test_flags="" +CFLAGS="$OLD_CFLAGS" +if test "$compiler_supports_shared_objects" = "no" ; then + echo "$as_me:$LINENO: result: not supported" >&5 +echo "${ECHO_T}not supported" >&6 + { echo "$as_me:$LINENO: compiler is unable to generate shared objects, disabled plugins (optional)" >&5 +echo "$as_me: compiler is unable to generate shared objects, disabled plugins (optional)" >&6;} + WITH_PLUGINS="no" +else + echo "$as_me:$LINENO: result: $compiler_shared_objects" >&5 +echo "${ECHO_T}$compiler_shared_objects" >&6 + SOFLAGS="$SOFLAGS $compiler_shared_objects" + +# +# shared objects need position independent code; some platforms emit +# it always, others need -fPIC +# +echo "$as_me:$LINENO: checking whether $CC needs -fPIC for shared objects" >&5 +echo $ECHO_N "checking whether $CC needs -fPIC for shared objects... $ECHO_C" >&6 +OLD_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $SOFLAGS" +WITH_PLUGINS="yes" +cat >conftest.$ac_ext <<_ACEOF + + int bar = 0; + + int foo(void) + { + return bar; + } + +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + CFLAGS="$OLD_CFLAGS" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + if test "$compiler_supports_pic" = "yes" ; then + # Verify if -shared really fails due to lack of -fPIC or something else + CFLAGS="$CFLAGS -fPIC" + cat >conftest.$ac_ext <<_ACEOF + + int bar = 0; + + int foo(void) + { + return bar; + } + +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + CFLAGS="$OLD_CFLAGS -fPIC" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + echo "$as_me:$LINENO: result: no, but fails for another reason" >&5 +echo "${ECHO_T}no, but fails for another reason" >&6 + { { echo "$as_me:$LINENO: error: compiler is unable to compile shared objects for an unhandled reason, please report this with attached config.log... stopping" >&5 +echo "$as_me: error: compiler is unable to compile shared objects for an unhandled reason, please report this with attached config.log... stopping" >&2;} + { (exit 1); exit 1; }; } + + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + else + # Disable compilation of plugins (optional), so 'make all' does not fail + echo "$as_me:$LINENO: result: yes, but unsupported" >&5 +echo "${ECHO_T}yes, but unsupported" >&6 + { echo "$as_me:$LINENO: compiler is unable to generate position independent code, disabled plugins (optional)" >&5 +echo "$as_me: compiler is unable to generate position independent code, disabled plugins (optional)" >&6;} + WITH_PLUGINS="no" + fi + + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi # # -O2 implies -fstrict-aliasing, but the code is not safe for that @@ -6754,6 +6994,7 @@ do "src/char/Makefile") CONFIG_FILES="$CONFIG_FILES src/char/Makefile" ;; "src/login/Makefile") CONFIG_FILES="$CONFIG_FILES src/login/Makefile" ;; "src/map/Makefile") CONFIG_FILES="$CONFIG_FILES src/map/Makefile" ;; + "src/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/plugins/Makefile" ;; "src/tool/Makefile") CONFIG_FILES="$CONFIG_FILES src/tool/Makefile" ;; "src/test/Makefile") CONFIG_FILES="$CONFIG_FILES src/test/Makefile" ;; diff --git a/configure.in b/configure.in index 5444be663..f52fcf00b 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([src/common/cbasetypes.h]) AC_CONFIG_FILES([Makefile src/common/Makefile]) AC_CONFIG_FILES([3rdparty/mt19937ar/Makefile 3rdparty/libconfig/Makefile]) AC_CONFIG_FILES([src/char/Makefile src/login/Makefile]) -AC_CONFIG_FILES([src/map/Makefile src/tool/Makefile]) +AC_CONFIG_FILES([src/map/Makefile src/plugins/Makefile src/tool/Makefile]) AC_CONFIG_FILES([src/test/Makefile]) AC_GNU_SOURCE @@ -521,6 +521,110 @@ AC_COMPILE_IFELSE( ) CFLAGS="$OLD_CFLAGS" +# +# option for shared objects +# +AC_MSG_CHECKING([how to make shared objects]) +OLD_CFLAGS="$CFLAGS" +compiler_shared_objects="" +if test "$compiler_supports_pic" = "yes" ; then + my_shared_test_flags="$CFLAGS -fPIC" +fi +# default +CFLAGS="$my_shared_test_flags -shared" +AC_LINK_IFELSE( + [[ + int bar = 0; + + int foo(void) + { + return bar; + } + ]], + [ + compiler_shared_objects="-shared" + ] +) +# BeOS specific +CFLAGS="$my_shared_test_flags -nostart" +AC_LINK_IFELSE( + [[ + int bar = 0; + + int foo(void) + { + return bar; + } + ]], + [ + compiler_shared_objects="-nostart" + ] +) +my_shared_test_flags="" +CFLAGS="$OLD_CFLAGS" +if test "$compiler_supports_shared_objects" = "no" ; then + AC_MSG_RESULT([not supported]) + AC_MSG_NOTICE([compiler is unable to generate shared objects, disabled plugins (optional)]) + WITH_PLUGINS="no" +else + AC_MSG_RESULT([$compiler_shared_objects]) + SOFLAGS="$SOFLAGS $compiler_shared_objects" + +# +# shared objects need position independent code; some platforms emit +# it always, others need -fPIC +# +AC_MSG_CHECKING([whether $CC needs -fPIC for shared objects]) +OLD_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $SOFLAGS" +WITH_PLUGINS="yes" +AC_LINK_IFELSE( + [[ + int bar = 0; + + int foo(void) + { + return bar; + } + ]], + [ + AC_MSG_RESULT([no]) + CFLAGS="$OLD_CFLAGS" + ], + [ + if test "$compiler_supports_pic" = "yes" ; then + # Verify if -shared really fails due to lack of -fPIC or something else + CFLAGS="$CFLAGS -fPIC" + AC_LINK_IFELSE( + [[ + int bar = 0; + + int foo(void) + { + return bar; + } + ]], + [ + AC_MSG_RESULT([yes]) + CFLAGS="$OLD_CFLAGS -fPIC" + ], + [ + AC_MSG_RESULT([no, but fails for another reason]) + AC_MSG_ERROR([compiler is unable to compile shared objects for an unhandled reason, please report this with attached config.log... stopping]) + ] + ) + else + # Disable compilation of plugins (optional), so 'make all' does not fail + AC_MSG_RESULT([yes, but unsupported]) + AC_MSG_NOTICE([compiler is unable to generate position independent code, disabled plugins (optional)]) + WITH_PLUGINS="no" + fi + ] +) + +fi +AC_SUBST([WITH_PLUGINS]) + # # -O2 implies -fstrict-aliasing, but the code is not safe for that diff --git a/plugins/empty.txt b/plugins/empty.txt new file mode 100644 index 000000000..e6b990d30 --- /dev/null +++ b/plugins/empty.txt @@ -0,0 +1 @@ +Oi. nothing to see here! unless you compile a plugin :P \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94ccf4183..100958358 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,3 +17,4 @@ add_subdirectory( login ) add_subdirectory( char ) add_subdirectory( map ) add_subdirectory( tool ) +add_subdirectory( plugins ) \ No newline at end of file diff --git a/src/char/char.c b/src/char/char.c index d5064eee2..f674cc0c7 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -4349,26 +4349,6 @@ int parse_char(int fd) return 0; } -// Console Command Parser [Wizputer] -int parse_console(const char* command) -{ - ShowNotice("Console command: %s\n", command); - - if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 ) - runflag = 0; - else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 ) - ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n"); - else if( strcmpi("help", command) == 0 ) - { - ShowInfo("To shutdown the server:\n"); - ShowInfo(" 'shutdown|exit|quit|end'\n"); - ShowInfo("To know if server is alive:\n"); - ShowInfo(" 'alive|status'\n"); - } - - return 0; -} - int mapif_sendall(unsigned char *buf, unsigned int len) { int i, c; @@ -4904,9 +4884,8 @@ void do_abort(void) { } -void set_server_type(void) -{ - SERVER_TYPE = ATHENA_SERVER_CHAR; +void set_server_type(void) { + SERVER_TYPE = SERVER_TYPE_CHAR; } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 508154c00..dbc30734c 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -68,6 +68,8 @@ set( COMMON_BASE_HEADERS "${COMMON_SOURCE_DIR}/des.h" "${COMMON_SOURCE_DIR}/ers.h" "${COMMON_SOURCE_DIR}/grfio.h" + "${COMMON_SOURCE_DIR}/HPM.h" + "${COMMON_SOURCE_DIR}/HPMi.h" "${COMMON_SOURCE_DIR}/malloc.h" "${COMMON_SOURCE_DIR}/mapindex.h" "${COMMON_SOURCE_DIR}/md5calc.h" @@ -94,6 +96,7 @@ set( COMMON_BASE_SOURCES "${COMMON_SOURCE_DIR}/des.c" "${COMMON_SOURCE_DIR}/ers.c" "${COMMON_SOURCE_DIR}/grfio.c" + "${COMMON_SOURCE_DIR}/HPM.c" "${COMMON_SOURCE_DIR}/malloc.c" "${COMMON_SOURCE_DIR}/mapindex.c" "${COMMON_SOURCE_DIR}/md5calc.c" diff --git a/src/common/HPM.c b/src/common/HPM.c new file mode 100644 index 000000000..ec5ba888e --- /dev/null +++ b/src/common/HPM.c @@ -0,0 +1,348 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file + +#include "../common/cbasetypes.h" +#include "../common/mmo.h" +#include "../common/core.h" +#include "../common/malloc.h" +#include "../common/showmsg.h" +#include "../common/socket.h" +#include "../common/timer.h" +#include "../common/conf.h" +#include "../common/utils.h" +#include "../common/console.h" +#include "HPM.h" + +#include +#include +#include +#ifndef WIN32 +#include +#endif + +void hplugin_trigger_event(enum hp_event_types type) { + unsigned int i; + for( i = 0; i < HPM->plugin_count; i++ ) { + if( HPM->plugins[i]->hpi->event[type] != NULL ) + (HPM->plugins[i]->hpi->event[type])(); + } +} + +void hplugin_export_symbol(void *var, char *name) { + RECREATE(HPM->symbols, struct hpm_symbol *, ++HPM->symbol_count); + CREATE(HPM->symbols[HPM->symbol_count - 1] ,struct hpm_symbol, 1); + HPM->symbols[HPM->symbol_count - 1]->name = name; + HPM->symbols[HPM->symbol_count - 1]->ptr = var; +} + +void *hplugin_import_symbol(char *name) { + unsigned int i; + + for( i = 0; i < HPM->symbol_count; i++ ) { + if( strcmp(HPM->symbols[i]->name,name) == 0 ) + return HPM->symbols[i]->ptr; + } + + ShowError("HPM:get_symbol: '"CL_WHITE"%s"CL_RESET"' not found!\n",name); + return NULL; +} + +bool hplugin_iscompatible(char* version) { + unsigned int req_major = 0, req_minor = 0; + + if( version == NULL ) + return false; + + sscanf(version, "%d.%d", &req_major, &req_minor); + + return ( req_major == HPM->version[0] && req_minor <= HPM->version[1] ) ? true : false; +} + +bool hplugin_exists(const char *filename) { + unsigned int i; + for(i = 0; i < HPM->plugin_count; i++) { + if( strcmpi(HPM->plugins[i]->filename,filename) == 0 ) + return true; + } + return false; +} +struct hplugin *hplugin_create(void) { + RECREATE(HPM->plugins, struct hplugin *, ++HPM->plugin_count); + CREATE(HPM->plugins[HPM->plugin_count - 1], struct hplugin, 1); + HPM->plugins[HPM->plugin_count - 1]->idx = HPM->plugin_count - 1; + HPM->plugins[HPM->plugin_count - 1]->filename = NULL; + return HPM->plugins[HPM->plugin_count - 1]; +} +bool hplugin_showmsg_populate(struct hplugin *plugin, const char *filename) { + void **ShowSub; + const char* ShowSubNames[9] = { + "ShowMessage", + "ShowStatus", + "ShowSQL", + "ShowInfo", + "ShowNotice", + "ShowWarning", + "ShowDebug", + "ShowError", + "ShowFatalError", + }; + void* ShowSubRef[9] = { + ShowMessage, + ShowStatus, + ShowSQL, + ShowInfo, + ShowNotice, + ShowWarning, + ShowDebug, + ShowError, + ShowFatalError, + }; + int i; + for(i = 0; i < 9; i++) { + if( !( ShowSub = plugin_import(plugin->dll, ShowSubNames[i],void **) ) ) { + ShowWarning("HPM:plugin_load: failed to retrieve '%s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", ShowSubNames[i], filename); + HPM->unload(plugin); + return false; + } + *ShowSub = ShowSubRef[i]; + } + return true; +} +void hplugin_load(const char* filename) { + struct hplugin *plugin; + struct hplugin_info *info; + struct HPMi_interface **HPMi; + bool anyEvent = false; + void **import_symbol_ref; + + if( HPM->exists(filename) ) { + ShowWarning("HPM:plugin_load: attempting to load duplicate '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); + return; + } + + plugin = HPM->create(); + + 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; + } + + 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; + } + + if( !(info->type & SERVER_TYPE) ) { + HPM->unload(plugin); + return; + } + + 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; + } + + 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; + } + + *import_symbol_ref = HPM->import_symbol; + + 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; + } + + 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; + } + plugin->hpi = *HPMi; + + if( ( plugin->hpi->event[HPET_INIT] = plugin_import(plugin->dll, "plugin_init",void (*)(void)) ) ) + anyEvent = true; + + if( ( plugin->hpi->event[HPET_FINAL] = plugin_import(plugin->dll, "plugin_final",void (*)(void)) ) ) + anyEvent = true; + + if( ( plugin->hpi->event[HPET_READY] = plugin_import(plugin->dll, "server_online",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; + } + + if( !HPM->showmsg_pop(plugin,filename) ) + return; + + if( SERVER_TYPE == SERVER_TYPE_MAP ) { + plugin->hpi->addCommand = HPM->import_symbol("addCommand"); + plugin->hpi->addScript = HPM->import_symbol("addScript"); + plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand"); + } + + plugin->info = info; + plugin->filename = aStrdup(filename); + + return; +} + +void hplugin_unload(struct hplugin* plugin) { + unsigned int i = plugin->idx, cursor = 0; + + if( plugin->filename ) + aFree(plugin->filename); + if( plugin->dll ) + plugin_close(plugin->dll); + + aFree(plugin); + if( !HPM->off ) { + HPM->plugins[i] = NULL; + for(i = 0; i < HPM->plugin_count; i++) { + if( HPM->plugins[i] == NULL ) + continue; + if( cursor != i ) + HPM->plugins[cursor] = HPM->plugins[i]; + cursor++; + } + if( !(HPM->plugin_count = cursor) ) { + aFree(HPM->plugins); + HPM->plugins = NULL; + } + } +} + +void hplugins_config_read(void) { + config_t plugins_conf; + config_setting_t *plist = NULL; + const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name + + if (conf_read_file(&plugins_conf, config_filename)) + return; + + if( HPM->symbol_defaults_sub ) + HPM->symbol_defaults_sub(); + + plist = config_lookup(&plugins_conf, "plugins_list"); + + if (plist != NULL) { + 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); + } + config_destroy(&plugins_conf); + } + + if( HPM->plugin_count ) + ShowStatus("HPM: There are '"CL_WHITE"%d"CL_RESET"' plugins loaded, type '"CL_WHITE"plugins"CL_RESET"' to list them\n", HPM->plugin_count); +} +void hplugins_share_defaults(void) { + /* console */ + HPM->share(console->addCommand,"addCPCommand"); + /* core */ + HPM->share(&runflag,"runflag"); + HPM->share(arg_v,"arg_v"); + HPM->share(&arg_c,"arg_c"); + HPM->share(SERVER_NAME,"SERVER_NAME"); + HPM->share(&SERVER_TYPE,"SERVER_TYPE"); + HPM->share((void*)get_svn_revision,"get_svn_revision"); + HPM->share((void*)get_git_hash,"get_git_hash"); + /* socket */ + HPM->share(RFIFOSKIP,"RFIFOSKIP"); + HPM->share(WFIFOSET,"WFIFOSET"); + HPM->share(do_close,"do_close"); + HPM->share(make_connection,"make_connection"); + HPM->share(session,"session"); + HPM->share(&fd_max,"fd_max"); + HPM->share(addr_,"addr"); + /* timer */ + HPM->share(gettick,"gettick"); + HPM->share(add_timer,"add_timer"); + HPM->share(add_timer_interval,"add_timer_interval"); + HPM->share(add_timer_func_list,"add_timer_func_list"); + HPM->share(delete_timer,"delete_timer"); + HPM->share(get_uptime,"get_uptime"); +} +CPCMD(plugins) { + if( HPM->plugin_count == 0 ) { + ShowInfo("HPC: there are no plugins loaded\n"); + } else { + unsigned int i; + + ShowInfo("HPC: There are '"CL_WHITE"%d"CL_RESET"' plugins loaded\n",HPM->plugin_count); + + for(i = 0; i < HPM->plugin_count; i++) { + ShowInfo("HPC: - '"CL_WHITE"%s"CL_RESET"' (%s)\n",HPM->plugins[i]->info->name,HPM->plugins[i]->filename); + } + } +} +void hpm_init(void) { + HPM->symbols = NULL; + HPM->plugins = NULL; + HPM->plugin_count = HPM->symbol_count = 0; + HPM->off = false; + + sscanf(HPM_VERSION, "%d.%d", &HPM->version[0], &HPM->version[1]); + + if( HPM->version[0] == 0 && HPM->version[1] == 0 ) { + ShowError("HPM:init:failed to retrieve HPM version!!\n"); + return; + } + HPM->symbol_defaults(); + + console->addCommand("plugins",CPCMD_A(plugins)); + + return; +} + +void hpm_final(void) { + unsigned int i; + + HPM->off = true; + + for( i = 0; i < HPM->plugin_count; i++ ) { + HPM->unload(HPM->plugins[i]); + } + + if( HPM->plugins ) + aFree(HPM->plugins); + + for( i = 0; i < HPM->symbol_count; i++ ) { + aFree(HPM->symbols[i]); + } + + if( HPM->symbols ) + aFree(HPM->symbols); + + return; +} +void hpm_defaults(void) { + HPM = &HPM_s; + + HPM->init = hpm_init; + HPM->final = hpm_final; + + HPM->create = hplugin_create; + HPM->load = hplugin_load; + HPM->unload = hplugin_unload; + HPM->event = hplugin_trigger_event; + HPM->exists = hplugin_exists; + HPM->iscompatible = hplugin_iscompatible; + HPM->import_symbol = hplugin_import_symbol; + HPM->share = hplugin_export_symbol; + HPM->symbol_defaults = hplugins_share_defaults; + HPM->config_read = hplugins_config_read; + HPM->showmsg_pop = hplugin_showmsg_populate; + HPM->symbol_defaults_sub = NULL; +} \ No newline at end of file diff --git a/src/common/HPM.h b/src/common/HPM.h new file mode 100644 index 000000000..ac2c4050f --- /dev/null +++ b/src/common/HPM.h @@ -0,0 +1,83 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file + +#ifndef _HPM_H_ +#define _HPM_H_ + +#include "../common/cbasetypes.h" +#include "../common/HPMi.h" + +#ifdef WIN32 + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #define plugin_open(x) LoadLibraryA(x) + #define plugin_import(x,y,z) (z)GetProcAddress(x,y) + #define plugin_close(x) FreeLibrary(x) + + #define DLL_EXT ".dll" + #define DLL HINSTANCE +#else + #include + #define plugin_open(x) dlopen(x,RTLD_NOW) + #define plugin_import(x,y,z) (z)dlsym(x,y) + #define plugin_close(x) dlclose(x) + + #ifdef CYGWIN + #define DLL_EXT ".dll" + #else + #define DLL_EXT ".so" + #endif + + #define DLL void * + + #include // size_t + +#endif + +struct hplugin { + DLL dll; + unsigned int idx; + char *filename; + struct hplugin_info *info; + struct HPMi_interface *hpi; +}; + +struct hpm_symbol { + char *name; + void *ptr; +}; + +/* Hercules Plugin Manager Interface */ +struct HPM_interface { + /* vars */ + unsigned int version[2]; + bool off; + /* data */ + struct hplugin **plugins; + unsigned int plugin_count; + struct hpm_symbol **symbols; + unsigned int symbol_count; + /* funcs */ + void (*init) (void); + void (*final) (void); + struct hplugin * (*create) (void); + void (*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 (*share) (void *, char *); + void (*symbol_defaults) (void); + void (*config_read) (void); + bool (*showmsg_pop) (struct hplugin *plugin,const char *filename); + void (*symbol_defaults_sub) (void); +} HPM_s; + +struct HPM_interface *HPM; + +void hpm_defaults(void); + +#endif /* _HPM_H_ */ \ No newline at end of file diff --git a/src/common/HPMi.h b/src/common/HPMi.h new file mode 100644 index 000000000..517d9125d --- /dev/null +++ b/src/common/HPMi.h @@ -0,0 +1,67 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file + +#ifndef _HPMi_H_ +#define _HPMi_H_ + +#include "../common/cbasetypes.h" +#include "../common/core.h" +#include "../common/console.h" + +struct script_state; +struct AtCommandInfo; + +#ifdef WIN32 + #define HPExport __declspec(dllexport) +#else + #define HPExport +#endif + +#ifndef _SHOWMSG_H_ + HPExport void (*ShowMessage) (const char *, ...); + HPExport void (*ShowStatus) (const char *, ...); + HPExport void (*ShowSQL) (const char *, ...); + HPExport void (*ShowInfo) (const char *, ...); + HPExport void (*ShowNotice) (const char *, ...); + HPExport void (*ShowWarning) (const char *, ...); + HPExport void (*ShowDebug) (const char *, ...); + HPExport void (*ShowError) (const char *, ...); + HPExport void (*ShowFatalError) (const char *, ...); +#endif + +/* after */ +#include "../common/showmsg.h" + +#define HPM_VERSION "0.1" + +struct hplugin_info { + char* name; + enum server_types type; + char* version; + char* req_version; +}; + +HPExport void *(*import_symbol) (char *name); +#define GET_SYMBOL(n) import_symbol(n) + +#define SERVER_TYPE_ALL SERVER_TYPE_LOGIN|SERVER_TYPE_CHAR|SERVER_TYPE_MAP + +enum hp_event_types { + HPET_INIT,/* server starts */ + HPET_FINAL,/* server is shutting down */ + HPET_READY,/* server is ready (online) */ + HPET_MAX, +}; + +/* Hercules Plugin Mananger Include Interface */ +struct HPMi_interface { + void (*event[HPET_MAX]) (void); + bool (*addCommand) (char *name, bool (*func)(const int fd, struct map_session_data* sd, const char* command, const char* message,struct AtCommandInfo *info)); + bool (*addScript) (char *name, char *args, bool (*func)(struct script_state *st)); + void (*addCPCommand) (char *name, CParseFunc func); +} HPMi_s; +#ifndef _HPM_H_ + struct HPMi_interface *HPMi; +#endif + +#endif /* _HPMi_H_ */ \ No newline at end of file diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 26cae3e51..279f82e5f 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -1,5 +1,5 @@ -COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o \ +COMMON_OBJ = obj_all/core.o obj_all/socket.o obj_all/timer.o obj_all/db.o obj_all/HPM.o \ obj_all/nullpo.o obj_all/malloc.o obj_all/showmsg.o obj_all/strlib.o obj_all/utils.o \ obj_all/grfio.o obj_all/mapindex.o obj_all/ers.o obj_all/md5calc.o \ obj_all/minicore.o obj_all/minisocket.o obj_all/minimalloc.o obj_all/random.o obj_all/des.o \ diff --git a/src/common/console.c b/src/common/console.c index 67897ee81..db914db98 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -8,6 +8,8 @@ #include "console.h" #ifndef MINICORE + #include "../common/ers.h" + #include "../common/malloc.h" #include "../common/atomic.h" #include "../common/spinlock.h" #include "../common/thread.h" @@ -77,7 +79,212 @@ int console_parse_key_pressed(void) { return FD_ISSET(STDIN_FILENO, &fds); } #endif /* _WIN32 */ +CPCMD(exit) { + runflag = 0; +} +CPCMD(ers_report) { + ers_report(); +} +CPCMD(help) { + unsigned int i = 0; + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( console->cmd_list[i]->next_count ) { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",console->cmd_list[i]->cmd); + console->parse_list_subs(console->cmd_list[i],2); + } else { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"'\n",console->cmd_list[i]->cmd); + } + } +} +/* [Ind/Hercules] */ +CPCMD(malloc_usage) { + unsigned int val = (unsigned int)malloc_usage(); + ShowInfo("malloc_usage: %.2f MB\n",(double)(val)/1024); +} +#define CP_DEF_C(x) { #x , NULL , NULL, NULL } +#define CP_DEF_C2(x,y) { #x , NULL , #y, NULL } +#define CP_DEF_S(x,y) { #x , console_parse_ ## x , #y, NULL } +#define CP_DEF(x) { #x , console_parse_ ## x , NULL, NULL } +void console_load_defaults(void) { + struct { + char *name; + CParseFunc func; + char *connect; + struct CParseEntry *self; + } default_list[] = { + CP_DEF(help), + CP_DEF_C(server), + CP_DEF_S(ers_report,server), + CP_DEF_S(malloc_usage,server), + CP_DEF_S(exit,server), + }; + unsigned int i, len = ARRAYLENGTH(default_list); + struct CParseEntry *cmd; + + RECREATE(console->cmds,struct CParseEntry *, len); + + for(i = 0; i < len; i++) { + CREATE(cmd, struct CParseEntry, 1); + + safestrncpy(cmd->cmd, default_list[i].name, CP_CMD_LENGTH); + + if( default_list[i].func ) + cmd->u.func = default_list[i].func; + else + cmd->u.next = NULL; + + cmd->next_count = 0; + + console->cmd_count++; + console->cmds[i] = cmd; + default_list[i].self = cmd; + if( !default_list[i].connect ) { + RECREATE(console->cmd_list,struct CParseEntry *, ++console->cmd_list_count); + console->cmd_list[console->cmd_list_count - 1] = cmd; + } + } + + for(i = 0; i < len; i++) { + unsigned int k; + if( !default_list[i].connect ) + continue; + for(k = 0; k < console->cmd_count; k++) { + if( strcmpi(default_list[i].connect,console->cmds[k]->cmd) == 0 ) { + cmd = default_list[i].self; + RECREATE(console->cmds[k]->u.next, struct CParseEntry *, ++console->cmds[k]->next_count); + console->cmds[k]->u.next[console->cmds[k]->next_count - 1] = cmd; + break; + } + } + } +} +void console_parse_create(char *name, CParseFunc func) { + unsigned int i; + char *tok; + char sublist[CP_CMD_LENGTH * 5]; + struct CParseEntry *cmd; + + safestrncpy(sublist, name, CP_CMD_LENGTH * 5); + tok = strtok(sublist,":"); + + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( strcmpi(tok,console->cmd_list[i]->cmd) == 0 ) + break; + } + if( i == console->cmd_list_count ) { + RECREATE(console->cmds,struct CParseEntry *, ++console->cmd_count); + CREATE(cmd, struct CParseEntry, 1); + safestrncpy(cmd->cmd, tok, CP_CMD_LENGTH); + cmd->next_count = 0; + console->cmds[console->cmd_count - 1] = cmd; + RECREATE(console->cmd_list,struct CParseEntry *, ++console->cmd_list_count); + console->cmd_list[console->cmd_list_count - 1] = cmd; + i = console->cmd_list_count - 1; + } + + cmd = console->cmd_list[i]; + while( ( tok = strtok(NULL, ":") ) != NULL ) { + + for(i = 0; i < cmd->next_count; i++) { + if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) + break; + } + + if ( i == cmd->next_count ) { + RECREATE(console->cmds,struct CParseEntry *, ++console->cmd_count); + CREATE(console->cmds[console->cmd_count-1], struct CParseEntry, 1); + safestrncpy(console->cmds[console->cmd_count-1]->cmd, tok, CP_CMD_LENGTH); + console->cmds[console->cmd_count-1]->next_count = 0; + RECREATE(cmd->u.next, struct CParseEntry *, ++cmd->next_count); + cmd->u.next[cmd->next_count - 1] = console->cmds[console->cmd_count-1]; + cmd = console->cmds[console->cmd_count-1]; + continue; + } + + } + cmd->u.func = func; +} +void console_parse_list_subs(struct CParseEntry *cmd, unsigned char depth) { + unsigned int i; + char msg[CP_CMD_LENGTH * 2]; + for( i = 0; i < cmd->next_count; i++ ) { + if( cmd->u.next[i]->next_count ) { + memset(msg, '-', depth); + snprintf(msg + depth,CP_CMD_LENGTH * 2, " '"CL_WHITE"%s"CL_RESET"'",cmd->u.next[i]->cmd); + ShowInfo("%s subs\n",msg); + console->parse_list_subs(cmd->u.next[i],depth + 1); + } else { + memset(msg, '-', depth); + snprintf(msg + depth,CP_CMD_LENGTH * 2, " %s",cmd->u.next[i]->cmd); + ShowInfo("%s\n",msg); + } + } +} +void console_parse_sub(char *line) { + struct CParseEntry *cmd; + char bline[200]; + char *tok; + char sublist[CP_CMD_LENGTH * 5]; + unsigned int i, len = 0; + memcpy(bline, line, 200); + tok = strtok(line, " "); + for ( i = 0; i < console->cmd_list_count; i++ ) { + if( strcmpi(tok,console->cmd_list[i]->cmd) == 0 ) + break; + } + + if( i == console->cmd_list_count ) { + ShowError("'"CL_WHITE"%s"CL_RESET"' is not a known command, type '"CL_WHITE"help"CL_RESET"' to list all commands\n",line); + return; + } + + cmd = console->cmd_list[i]; + + len += snprintf(sublist,CP_CMD_LENGTH * 5,"%s", cmd->cmd) + 1; + + if( cmd->next_count == 0 && console->cmd_list[i]->u.func ) { + char *r = NULL; + if( (tok = strtok(NULL, " ")) ) { + r = bline; + r += len + 1; + } + cmd->u.func(r); + } else { + while( ( tok = strtok(NULL, " ") ) != NULL ) { + for( i = 0; i < cmd->next_count; i++ ) { + if( strcmpi(cmd->u.next[i]->cmd,tok) == 0 ) + break; + } + if( i == cmd->next_count ) { + if( strcmpi("help",tok) == 0 ) { + if( cmd->next_count ) { + ShowInfo("- '"CL_WHITE"%s"CL_RESET"' subs\n",sublist); + console->parse_list_subs(cmd,2); + } else { + ShowError("'"CL_WHITE"%s"CL_RESET"' doesn't possess any subcommands\n",sublist); + } + return; + } + ShowError("'"CL_WHITE"%s"CL_RESET"' is not a known subcommand of '"CL_WHITE"%s"CL_RESET"'\n",tok,cmd->cmd); + ShowError("type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); + return; + } + if( cmd->u.next[i]->next_count == 0 && cmd->u.next[i]->u.func ) { + char *r = NULL; + if( (tok = strtok(NULL, " ")) ) { + r = bline; + r += len + strlen(cmd->u.next[i]->cmd) + 1; + } + cmd->u.next[i]->u.func(r); + return; + } else + cmd = cmd->u.next[i]; + len += snprintf(sublist + len,CP_CMD_LENGTH * 5,":%s", cmd->cmd); + } + ShowError("it is only a category, type '"CL_WHITE"%s help"CL_RESET"' to list its subcommands\n",sublist); + } +} void console_parse(char* line) { int c, i = 0, len = MAX_CONSOLE_INPUT - 1;/* we leave room for the \0 :P */ @@ -122,7 +329,7 @@ int console_parse_timer(int tid, unsigned int tick, int id, intptr_t data) { int i; EnterSpinLock(&console->ptlock); for(i = 0; i < cinput.count; i++) { - parse_console(cinput.queue[i]); + console->parse_sub(cinput.queue[i]); } cinput.count = 0; LeaveSpinLock(&console->ptlock); @@ -163,12 +370,22 @@ void console_parse_init(void) { void console_init (void) { #ifdef CONSOLE_INPUT + console->cmd_count = console->cmd_list_count = 0; + console->load_defaults(); console->parse_init(); #endif } void console_final(void) { #ifdef CONSOLE_INPUT + int i; console->parse_final(); + for( i = 0; i < console->cmd_count; i++ ) { + if( console->cmds[i]->next_count ) + aFree(console->cmds[i]->u.next); + aFree(console->cmds[i]); + } + aFree(console->cmds); + aFree(console->cmd_list); #endif } void console_defaults(void) { @@ -182,6 +399,10 @@ void console_defaults(void) { console->parse_timer = console_parse_timer; console->pthread_main = cThread_main; console->parse = console_parse; + console->parse_sub = console_parse_sub; console->key_pressed = console_parse_key_pressed; + console->load_defaults = console_load_defaults; + console->parse_list_subs = console_parse_list_subs; + console->addCommand = console_parse_create; #endif } diff --git a/src/common/console.h b/src/common/console.h index 7f1490084..ebce013f7 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -14,6 +14,21 @@ * why is there a limit, why not make it dynamic? - I'm playing it safe, I'd rather not play with memory management between threads **/ #define CONSOLE_PARSE_SIZE 10 + +typedef void (*CParseFunc)(char *line); +#define CPCMD(x) void console_parse_ ##x (char *line) +#define CPCMD_A(x) console_parse_ ##x + +#define CP_CMD_LENGTH 20 +struct CParseEntry { + char cmd[CP_CMD_LENGTH]; + union { + CParseFunc func; + struct CParseEntry **next; + } u; + unsigned short next_count; +}; + struct { char queue[CONSOLE_PARSE_SIZE][MAX_CONSOLE_INPUT]; unsigned short count; @@ -31,12 +46,21 @@ struct console_interface { ramutex ptmutex;/* parse thread mutex */ racond ptcond;/* parse thread cond */ /* */ + struct CParseEntry **cmd_list; + struct CParseEntry **cmds; + unsigned int cmd_count; + unsigned int cmd_list_count; + /* */ void (*parse_init) (void); void (*parse_final) (void); int (*parse_timer) (int tid, unsigned int tick, int id, intptr_t data); void *(*pthread_main) (void *x); void (*parse) (char* line); + void (*parse_sub) (char* line); int (*key_pressed) (void); + void (*load_defaults) (void); + void (*parse_list_subs) (struct CParseEntry *cmd, unsigned char depth); + void (*addCommand) (char *name, CParseFunc func); #endif }; diff --git a/src/common/core.c b/src/common/core.c index da4e4ccf9..9fd9747aa 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -17,6 +17,7 @@ #include "../common/sql.h" #include "../config/core.h" #include "../common/strlib.h" + #include "../common/HPM.h" #endif #include @@ -37,7 +38,6 @@ int arg_c = 0; char **arg_v = NULL; char *SERVER_NAME = NULL; -char SERVER_TYPE = ATHENA_SERVER_NONE; #ifndef MINICORE // minimalist Core // Added by Gabuzomeu @@ -295,6 +295,9 @@ int main (int argc, char **argv) arg_c = argc; arg_v = argv; } +#ifndef MINICORE + hpm_defaults(); +#endif console_defaults(); malloc_init();// needed for Show* in display_title() [FlavioJS] @@ -320,13 +323,16 @@ int main (int argc, char **argv) #endif timer_init(); - + console->init(); + +#ifndef MINICORE + HPM->init(); +#endif socket_init(); do_init(argc,argv); - {// Main runtime cycle int next; while (runflag != CORE_ST_STOP) { @@ -338,7 +344,9 @@ int main (int argc, char **argv) console->final(); do_final(); - +#ifndef MINICORE + HPM->final(); +#endif timer_final(); socket_final(); db_final(); diff --git a/src/common/core.h b/src/common/core.h index 21da18938..8fdcdcfc3 100644 --- a/src/common/core.h +++ b/src/common/core.h @@ -23,17 +23,15 @@ extern char **arg_v; extern int runflag; extern char *SERVER_NAME; -enum { - ATHENA_SERVER_NONE = 0, // not defined - ATHENA_SERVER_LOGIN = 1, // login server - ATHENA_SERVER_CHAR = 2, // char server - ATHENA_SERVER_INTER = 4, // inter server - ATHENA_SERVER_MAP = 8, // map server +enum server_types { + SERVER_TYPE_UNKNOWN = 0x0, + SERVER_TYPE_LOGIN = 0x1, + SERVER_TYPE_CHAR = 0x2, + SERVER_TYPE_MAP = 0x4, }; -extern char SERVER_TYPE; +enum server_types SERVER_TYPE; -extern int parse_console(const char* buf); const char *get_svn_revision(void); const char *get_git_hash (void); extern int do_init(int,char**); @@ -42,8 +40,7 @@ extern void do_abort(void); extern void do_final(void); /// The main loop continues until runflag is CORE_ST_STOP -enum E_CORE_ST -{ +enum E_CORE_ST { CORE_ST_STOP = 0, CORE_ST_RUN, CORE_ST_LAST diff --git a/src/common/db.c b/src/common/db.c index 204c6d2ea..7ac9b2dc7 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -47,6 +47,7 @@ * - create a db that organizes itself by splaying * * HISTORY: + * 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] * 2012/03/09 - Added enum for data types (int, uint, void*) * 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. * 2007/11/09 - Added an iterator to the database. @@ -319,6 +320,10 @@ static struct db_stats { #define DB_COUNTSTAT(token) #endif /* !defined(DB_ENABLE_STATS) */ +/* [Ind/Hercules] */ +struct eri *db_iterator_ers; +struct eri *db_alloc_ers; + /*****************************************************************************\ * (2) Section of private functions used by the database system. * * db_rotate_left - Rotate a tree node to the left. * @@ -1366,7 +1371,7 @@ void dbit_obj_destroy(DBIterator* self) // unlock the database db_free_unlock(it->db); // free iterator - aFree(self); + ers_free(db_iterator_ers,self); } /** @@ -1384,7 +1389,7 @@ static DBIterator* db_obj_iterator(DBMap* self) DBIterator_impl* it; DB_COUNTSTAT(db_iterator); - CREATE(it, struct DBIterator_impl, 1); + it = ers_alloc(db_iterator_ers, struct DBIterator_impl); /* Interface of the iterator **/ it->vtable.first = dbit_obj_first; it->vtable.last = dbit_obj_last; @@ -2127,7 +2132,7 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) db->free_max = 0; ers_destroy(db->nodes); db_free_unlock(db); - aFree(db); + ers_free(db_alloc_ers, db); return sum; } @@ -2409,7 +2414,7 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; } #endif /* DB_ENABLE_STATS */ - CREATE(db, struct DBMap_impl, 1); + db = ers_alloc(db_alloc_ers, struct DBMap_impl); options = db_fix_options(type, options); /* Interface of the database */ @@ -2602,8 +2607,9 @@ void* db_data2ptr(DBData *data) * @public * @see #db_final(void) */ -void db_init(void) -{ +void db_init(void) { + db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_NONE); + db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_NONE); DB_COUNTSTAT(db_init); } @@ -2696,6 +2702,8 @@ void db_final(void) stats.db_data2ui, stats.db_data2ptr, stats.db_init, stats.db_final); #endif /* DB_ENABLE_STATS */ + ers_destroy(db_iterator_ers); + ers_destroy(db_alloc_ers); } // Link DB System - jAthena diff --git a/src/common/ers.c b/src/common/ers.c index 3b354166e..13e54b393 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -1,7 +1,7 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams /*****************************************************************************\ - * Copyright (c) Athena Dev Teams - Licensed under GNU GPL * - * For more information, see LICENCE in the main folder * - * * *

Entry Reusage System

* * * * There are several root entry managers, each with a different entry size. * @@ -48,8 +48,7 @@ #ifndef DISABLE_ERS -#define ERS_ROOT_SIZE 256 -#define ERS_BLOCK_ENTRIES 4096 +#define ERS_BLOCK_ENTRIES 2048 struct ers_list { diff --git a/src/common/netbuffer.c b/src/common/netbuffer.c index 57742d612..60a299aa9 100644 --- a/src/common/netbuffer.c +++ b/src/common/netbuffer.c @@ -52,10 +52,10 @@ void netbuffer_init(){ // Set localsection name according to running serverype. switch(SERVER_TYPE){ - case ATHENA_SERVER_LOGIN: strcpy(localsection, "login-netbuffer"); break; - case ATHENA_SERVER_CHAR: strcpy(localsection, "char-netbuffer"); break; - case ATHENA_SERVER_INTER: strcpy(localsection, "inter-netbuffer"); break; - case ATHENA_SERVER_MAP: strcpy(localsection, "map-netbuffer"); break; + case SERVER_TYPE_LOGIN: strcpy(localsection, "login-netbuffer"); break; + case SERVER_TYPE_CHAR: strcpy(localsection, "char-netbuffer"); break; + //case ATHENA_SERVER_INTER: strcpy(localsection, "inter-netbuffer"); break; + case SERVER_TYPE_MAP: strcpy(localsection, "map-netbuffer"); break; default: strcpy(localsection, "unsupported_type"); break; } diff --git a/src/common/showmsg.c b/src/common/showmsg.c index 609ae3c50..50fa972f0 100644 --- a/src/common/showmsg.c +++ b/src/common/showmsg.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/strlib.h" // StringBuf @@ -687,22 +688,12 @@ int _vShowMessage(enum msg_type flag, const char *string, va_list ap) ShowError("Empty string passed to _vShowMessage().\n"); return 1; } - /** - * For the buildbot, these result in a EXIT_FAILURE from core.c when done reading the params. - **/ -#if defined(BUILDBOT) - if( flag == MSG_WARNING || - flag == MSG_ERROR || - flag == MSG_SQL ) { - buildbotflag = 1; - } -#endif if( ( flag == MSG_WARNING && console_msg_log&1 ) || ( ( flag == MSG_ERROR || flag == MSG_SQL ) && console_msg_log&2 ) || ( flag == MSG_DEBUG && console_msg_log&4 ) ) {//[Ind] FILE *log = NULL; - if( (log = fopen(SERVER_TYPE == ATHENA_SERVER_MAP ? "./log/map-msg_log.log" : "./log/unknown.log","a+")) ) { + if( (log = fopen(SERVER_TYPE == SERVER_TYPE_MAP ? "./log/map-msg_log.log" : "./log/unknown.log","a+")) ) { char timestring[255]; time_t curtime; time(&curtime); diff --git a/src/common/showmsg.h b/src/common/showmsg.h index 0d6cb5c9f..a88985770 100644 --- a/src/common/showmsg.h +++ b/src/common/showmsg.h @@ -1,11 +1,13 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _SHOWMSG_H_ #define _SHOWMSG_H_ -#include "libconfig.h" - +#ifndef _HPMi_H_ + #include "libconfig.h" +#endif // for help with the console colors look here: // http://www.edoceo.com/liberum/?doc=printf-with-color // some code explanation (used here): @@ -85,15 +87,17 @@ enum msg_type { }; extern void ClearScreen(void); -extern void ShowMessage(const char *, ...); -extern void ShowStatus(const char *, ...); -extern void ShowSQL(const char *, ...); -extern void ShowInfo(const char *, ...); -extern void ShowNotice(const char *, ...); -extern void ShowWarning(const char *, ...); -extern void ShowDebug(const char *, ...); -extern void ShowError(const char *, ...); -extern void ShowFatalError(const char *, ...); -extern void ShowConfigWarning(config_setting_t *config, const char *string, ...); +#ifndef _HPMi_H_ + extern void ShowMessage(const char *, ...); + extern void ShowStatus(const char *, ...); + extern void ShowSQL(const char *, ...); + extern void ShowInfo(const char *, ...); + extern void ShowNotice(const char *, ...); + extern void ShowWarning(const char *, ...); + extern void ShowDebug(const char *, ...); + extern void ShowError(const char *, ...); + extern void ShowFatalError(const char *, ...); + extern void ShowConfigWarning(config_setting_t *config, const char *string, ...); +#endif #endif /* _SHOWMSG_H_ */ diff --git a/src/login/login.c b/src/login/login.c index 2b96eefec..09dd938db 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -360,58 +360,6 @@ int login_lan_config_read(const char *lancfgName) return 0; } -//----------------------- -// Console Command Parser [Wizputer] -//----------------------- -int parse_console(const char* command) -{ - ShowNotice("Console command: %s\n", command); - - if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 || strcmpi("end", command) == 0 ) - runflag = 0; - else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 ) - ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n"); - else if( strcmpi("help", command) == 0 ) - { - ShowInfo("To shutdown the server:\n"); - ShowInfo(" 'shutdown|exit|quit|end'\n"); - ShowInfo("To know if server is alive:\n"); - ShowInfo(" 'alive|status'\n"); - ShowInfo("To create a new account:\n"); - ShowInfo(" 'create'\n"); - } - else - {// commands with parameters - char cmd[128], params[256]; - - if( sscanf(command, "%127s %255[^\r\n]", cmd, params) < 2 ) - { - return 0; - } - - if( strcmpi(cmd, "create") == 0 ) - { - char username[NAME_LENGTH], password[NAME_LENGTH], sex; - - if( sscanf(params, "%23s %23s %c", username, password, &sex) < 3 || strnlen(username, sizeof(username)) < 4 || strnlen(password, sizeof(password)) < 1 ) - { - ShowWarning("Console: Invalid parameters for '%s'. Usage: %s \n", cmd, cmd); - return 0; - } - - if( mmo_auth_new(username, password, TOUPPER(sex), "0.0.0.0") != -1 ) - { - ShowError("Console: Account creation failed.\n"); - return 0; - } - ShowStatus("Console: Account '%s' created successfully.\n", username); - } - } - - return 0; -} - - //-------------------------------- // Packet parsing for char-servers //-------------------------------- @@ -1836,9 +1784,8 @@ void do_abort(void) { } -void set_server_type(void) -{ - SERVER_TYPE = ATHENA_SERVER_LOGIN; +void set_server_type(void) { + SERVER_TYPE = SERVER_TYPE_LOGIN; } diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 85332905e..5b82666fb 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -51,12 +51,7 @@ #include #include - -#define ACMD(x) static bool atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info) - static char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) -static DBMap* atcommand_db = NULL; //name -> AtCommandInfo -static DBMap* atcommand_alias_db = NULL; //alias -> AtCommandInfo static char atcmd_output[CHAT_SIZE_MAX]; static char atcmd_player_name[NAME_LENGTH]; @@ -1436,7 +1431,7 @@ ACMD(help) { StringBuf_Init(&buf); StringBuf_AppendStr(&buf, msg_txt(990)); // Available aliases: command_info = get_atcommandinfo_byname(command_name); - iter = db_iterator(atcommand_alias_db); + iter = db_iterator(atcommand->alias_db); for (alias_info = dbi_first(iter); dbi_exists(iter); alias_info = dbi_next(iter)) { if (alias_info->command == command_info) { StringBuf_Printf(&buf, " %s", alias_info->alias); @@ -8433,7 +8428,7 @@ static void atcommand_commands_sub(struct map_session_data* sd, const int fd, At char line_buff[CHATBOX_SIZE]; char* cur = line_buff; AtCommandInfo* cmd; - DBIterator *iter = db_iterator(atcommand_db); + DBIterator *iter = db_iterator(atcommand->db); int count = 0; memset(line_buff,' ',CHATBOX_SIZE); @@ -9699,7 +9694,7 @@ void atcommand_basecommands(void) { }; AtCommandInfo* cmd; int i; - + for( i = 0; i < ARRAYLENGTH(atcommand_base); i++ ) { if(atcommand->exists(atcommand_base[i].command)) { // Should not happen if atcommand_base[] array is OK ShowDebug("atcommand_basecommands: duplicate ACMD_DEF for '%s'.\n", atcommand_base[i].command); @@ -9709,7 +9704,7 @@ void atcommand_basecommands(void) { safestrncpy(cmd->command, atcommand_base[i].command, sizeof(cmd->command)); cmd->func = atcommand_base[i].func; cmd->help = NULL;/* start as null dear */ - strdb_put(atcommand_db, cmd->command, cmd); + strdb_put(atcommand->db, cmd->command, cmd); } return; } @@ -9718,20 +9713,20 @@ void atcommand_basecommands(void) { * Command lookup functions *------------------------------------------*/ AtCommandInfo* atcommand_exists(const char* name) { - return strdb_get(atcommand_db, name); + return strdb_get(atcommand->db, name); } -static AtCommandInfo* get_atcommandinfo_byname(const char *name) -{ - if (strdb_exists(atcommand_db, name)) - return (AtCommandInfo*)strdb_get(atcommand_db, name); +static AtCommandInfo* get_atcommandinfo_byname(const char *name) { + AtCommandInfo *cmd; + if ((cmd = strdb_get(atcommand->db, name))) + return cmd; return NULL; } static const char* atcommand_checkalias(const char *aliasname) { AliasInfo *alias_info = NULL; - if ((alias_info = (AliasInfo*)strdb_get(atcommand_alias_db, aliasname)) != NULL) + if ((alias_info = (AliasInfo*)strdb_get(atcommand->alias_db, aliasname)) != NULL) return alias_info->command->command; return aliasname; } @@ -9752,8 +9747,8 @@ static void atcommand_get_suggestions(struct map_session_data* sd, const char *n if (!battle_config.atcommand_suggestions_enabled) return; - atcommand_iter = db_iterator(atcommand_db); - alias_iter = db_iterator(atcommand_alias_db); + atcommand_iter = db_iterator(atcommand->db); + alias_iter = db_iterator(atcommand->alias_db); // Build the matches for (command_info = dbi_first(atcommand_iter); dbi_exists(atcommand_iter); command_info = dbi_next(atcommand_iter)) { @@ -10050,14 +10045,14 @@ static void atcommand_config_read(const char* config_filename) { const char *alias = config_setting_get_string_elem(command, j); if (alias != NULL) { AliasInfo *alias_info; - if (strdb_exists(atcommand_alias_db, alias)) { + if (strdb_exists(atcommand->alias_db, alias)) { ShowConfigWarning(command, "atcommand_config_read: alias %s already exists", alias); continue; } CREATE(alias_info, AliasInfo, 1); alias_info->command = commandinfo; safestrncpy(alias_info->alias, alias, sizeof(alias_info->alias)); - strdb_put(atcommand_alias_db, alias, alias_info); + strdb_put(atcommand->alias_db, alias, alias_info); ++num_aliases; } } @@ -10116,8 +10111,8 @@ static void atcommand_config_read(const char* config_filename) { config_destroy(&atcommand_config); return; } -void atcommand_db_load_groups(int* group_ids) { - DBIterator *iter = db_iterator(atcommand_db); +void atcommand_db_load_groups(void) { + DBIterator *iter = db_iterator(atcommand->db); AtCommandInfo* cmd; int i; @@ -10125,11 +10120,11 @@ void atcommand_db_load_groups(int* group_ids) { cmd->at_groups = aMalloc( pc_group_max * sizeof(char) ); cmd->char_groups = aMalloc( pc_group_max * sizeof(char) ); for(i = 0; i < pc_group_max; i++) { - if( pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_ATCOMMAND ) ) + if( pc_group_can_use_command(atcommand->group_ids[i], cmd->command, COMMAND_ATCOMMAND ) ) cmd->at_groups[i] = 1; else cmd->at_groups[i] = 0; - if( pc_group_can_use_command(group_ids[i], cmd->command, COMMAND_CHARCOMMAND ) ) + if( pc_group_can_use_command(atcommand->group_ids[i], cmd->command, COMMAND_CHARCOMMAND ) ) cmd->char_groups[i] = 1; else cmd->char_groups[i] = 0; @@ -10166,11 +10161,35 @@ bool atcommand_can_use2(struct map_session_data *sd, const char *command, AtComm return false; } - +bool atcommand_hp_add(char *name, AtCommandFunc func) { + AtCommandInfo* cmd; + + if( runflag == MAPSERVER_ST_RUNNING ) { + ShowDebug("atcommand_hp_add: Commands can't be added after server is ready, skipping '%s'...\n",name); + return false; + } + + if( !atcommand->db ) + atcommand->db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); + + if( atcommand->exists(name) ) { + ShowDebug("atcommand_hp_add: duplicate command '%s', skipping...\n", name); + return false; + } + + CREATE(cmd, AtCommandInfo, 1); + + safestrncpy(cmd->command, name, sizeof(cmd->command)); + cmd->func = func; + cmd->help = NULL;/* start as null dear */ + + strdb_put(atcommand->db, cmd->command, cmd); + return true; +} void atcommand_db_clear(void) { - if (atcommand_db != NULL) { - DBIterator *iter = db_iterator(atcommand_db); + if (atcommand->db != NULL) { + DBIterator *iter = db_iterator(atcommand->db); AtCommandInfo* cmd; for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) { @@ -10182,16 +10201,18 @@ void atcommand_db_clear(void) { dbi_destroy(iter); - db_destroy(atcommand_db); + db_destroy(atcommand->db); } - if (atcommand_alias_db != NULL) - db_destroy(atcommand_alias_db); + if (atcommand->alias_db != NULL) + db_destroy(atcommand->alias_db); } void atcommand_doload(void) { - atcommand_db_clear(); - atcommand_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); - atcommand_alias_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); + if( runflag >= MAPSERVER_ST_RUNNING ) + atcommand_db_clear(); + if( !atcommand->db ) + atcommand->db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); + atcommand->alias_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); atcommand_basecommands(); //fills initial atcommand_db with known commands atcommand_config_read(ATCOMMAND_CONF_FILENAME); } @@ -10206,17 +10227,22 @@ void do_init_atcommand(void) { void do_final_atcommand(void) { atcommand_db_clear(); + if( atcommand->group_ids ) + aFree(atcommand->group_ids); } void atcommand_defaults(void) { atcommand = &atcommand_s; + atcommand->db = NULL; + atcommand->init = do_init_atcommand; atcommand->final = do_final_atcommand; atcommand->parse = is_atcommand; atcommand->can_use = atcommand_can_use; atcommand->can_use2 = atcommand_can_use2; + atcommand->create = atcommand_hp_add; atcommand->load_groups = atcommand_db_load_groups; atcommand->exists = atcommand_exists; atcommand->msg_read = msg_config_read; diff --git a/src/map/atcommand.h b/src/map/atcommand.h index cea59a416..f09b1f2b8 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -5,6 +5,8 @@ #ifndef _ATCOMMAND_H_ #define _ATCOMMAND_H_ +#include "../common/db.h" + /** * Declarations **/ @@ -66,14 +68,19 @@ struct atcommand_interface { /* atcommand binding */ struct atcmd_binding_data** binding; int binding_count; + unsigned int *group_ids; + /* other vars */ + DBMap* db; //name -> AtCommandInfo + DBMap* alias_db; //alias -> AtCommandInfo /* */ void (*init) (void); void (*final) (void); /* */ bool (*parse) (const int fd, struct map_session_data* sd, const char* message, int type); + bool (*create) (char *name, AtCommandFunc func); bool (*can_use) (struct map_session_data *sd, const char *command); bool (*can_use2) (struct map_session_data *sd, const char *command, AtCommandType type); - void (*load_groups) (int* group_ids); + void (*load_groups) (void); AtCommandInfo* (*exists) (const char* name); int (*msg_read) (const char* cfgName); void (*final_msg) (void); @@ -85,5 +92,8 @@ struct atcommand_interface *atcommand; const char* msg_txt(int msg_number); void atcommand_defaults(void); +/* stay here */ +#define ACMD(x) static bool atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info) +#define ACMD_A(x) atcommand_ ## x #endif /* _ATCOMMAND_H_ */ diff --git a/src/map/clif.c b/src/map/clif.c index 10c1a0d47..160de3adc 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5640,38 +5640,27 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val p.val2 = val2; p.val3 = val3; #endif - + ShowDebug("Sending type %d; aid %d; state %d; total %d; left %d; v1 %d; v2 %d; v3 %d;\n",p.index,p.AID,p.state,p.Total,p.Left,p.val1,p.val2,p.val3); clif->send(&p,sizeof(p), bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA); } /// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT). /// 008e .W .?B -void clif_displaymessage(const int fd, const char* mes) -{ +void clif_displaymessage(const int fd, const char* mes) { nullpo_retv(mes); - //Scrapped, as these are shared by disconnected players =X [Skotlex] - if (fd == 0) - ; - else { - char *message, *line; - - message = aStrdup(mes); - line = strtok(message, "\n"); - while(line != NULL) { - // Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client) - int len = strnlen(line, 255); - - if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line. - WFIFOHEAD(fd, 5 + len); - WFIFOW(fd,0) = 0x8e; - WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate - safestrncpy((char *)WFIFOP(fd,4), line, len + 1); - WFIFOSET(fd, 5 + len); - } - line = strtok(NULL, "\n"); + if( fd == -2 ) { + ShowInfo("HCP: %s\n",mes); + } else if ( fd > 0 ) { + int len; + + if ( ( len = strnlen(mes, 255) ) > 0 ) { // don't send a void message (it's not displaying on the client chat). @help can send void line. + WFIFOHEAD(fd, 5 + len); + WFIFOW(fd,0) = 0x8e; + WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate + safestrncpy((char *)WFIFOP(fd,4), mes, len + 1); + WFIFOSET(fd, 5 + len); } - aFree(message); } } @@ -16873,9 +16862,10 @@ int clif_parse(int fd) { set_eof(fd); return 0; } - // determine real packet length packet_len = packet_db[cmd].len; + if(sd) + ShowWarning("clif_parse: Received packet 0x%04x with packet_len = %d (%d).\n", cmd, packet_len,RFIFOREST(fd)); if (packet_len == -1) { // variable-length packet if (RFIFOREST(fd) < 4) return 0; @@ -16892,7 +16882,7 @@ int clif_parse(int fd) { } if ((int)RFIFOREST(fd) < packet_len) return 0; // not enough data received to form the packet - + if( packet_db[cmd].func == clif->pDebug ) packet_db[cmd].func(fd, sd); else if( packet_db[cmd].func != NULL ) { diff --git a/src/map/map.c b/src/map/map.c index 1bbad1d40..ed4eba209 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -15,6 +15,8 @@ #include "../common/strlib.h" #include "../common/utils.h" #include "../common/conf.h" +#include "../common/console.h" +#include "../common/HPM.h" #include "map.h" #include "path.h" @@ -160,6 +162,9 @@ char wisp_server_name[NAME_LENGTH] = "Server"; // can be modified in char-server int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex] int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89] +/* [Ind/Hercules] */ +struct eri *map_iterator_ers; + /*========================================== * server player count (of all mapservers) *------------------------------------------*/ @@ -2040,7 +2045,7 @@ struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types) { struct s_mapiterator* mapit; - CREATE(mapit, struct s_mapiterator, 1); + mapit = ers_alloc(map_iterator_ers, struct s_mapiterator); mapit->flags = flags; mapit->types = types; if( types == BL_PC ) mapit->dbi = db_iterator(pc_db); @@ -2057,7 +2062,7 @@ void mapit_free(struct s_mapiterator* mapit) nullpo_retv(mapit); dbi_destroy(mapit->dbi); - aFree(mapit); + ers_free(map_iterator_ers, mapit); } /// Returns the first block_list that matches the description. @@ -3263,80 +3268,6 @@ int map_readallmaps (void) static int map_ip_set = 0; static int char_ip_set = 0; -/*========================================== - * Console Command Parser [Wizputer] - *------------------------------------------*/ -int parse_console(const char* buf) -{ - char type[64]; - char command[64]; - char map[64]; - int16 x = 0; - int16 y = 0; - int16 m; - int n; - struct map_session_data sd; - - memset(&sd, 0, sizeof(struct map_session_data)); - strcpy(sd.status.name, "console"); - - if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%63s %hd %hd[^\n]", type, command, map, &x, &y) ) < 5 ) - { - if( ( n = sscanf(buf, "%63[^:]:%63[^\n]", type, command) ) < 2 ) - { - n = sscanf(buf, "%63[^\n]", type); - } - } - - if( n == 5 ) - { - m = map_mapname2mapid(map); - if( m < 0 ) - { - ShowWarning("Console: Unknown map.\n"); - return 0; - } - sd.bl.m = m; - map_search_freecell(&sd.bl, m, &sd.bl.x, &sd.bl.y, -1, -1, 0); - if( x > 0 ) - sd.bl.x = x; - if( y > 0 ) - sd.bl.y = y; - } - else - { - map[0] = '\0'; - if( n < 2 ) - command[0] = '\0'; - if( n < 1 ) - type[0] = '\0'; - } - - ShowNotice("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y); - - if( n == 5 && strcmpi("admin",type) == 0 ) { - if( !atcommand->parse(sd.fd, &sd, command, 0) ) - ShowInfo("Console: not atcommand\n"); - } else if( n == 2 && strcmpi("server", type) == 0 ) { - if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 ) { - runflag = 0; - } - } else if( strcmpi("ers_report", type) == 0 ) - ers_report(); - else if( strcmpi("help", type) == 0 ) { - ShowInfo("To use GM commands:\n"); - ShowInfo(" admin:: \n"); - ShowInfo("You can use any GM command that doesn't require the GM.\n"); - ShowInfo("No using @item or @warp however you can use @charwarp\n"); - ShowInfo("The is for commands that need coords of the GM\n"); - ShowInfo("IE: @spawn\n"); - ShowInfo("To shutdown the server:\n"); - ShowInfo(" server:shutdown\n"); - } - - return 0; -} - /*========================================== * Read map server configuration files (conf/map_server.conf...) *------------------------------------------*/ @@ -4999,6 +4930,7 @@ void do_final(void) ShowStatus("Terminating...\n"); hChSys.closing = true; + HPM->event(HPET_FINAL); //Ladies and babies first. iter = mapit_getallusers(); @@ -5027,7 +4959,7 @@ void do_final(void) ircbot->final();/* before clif. */ clif->final(); do_final_npc(); - do_final_script(); + script->final(); do_final_instance(); do_final_itemdb(); do_final_storage(); @@ -5062,6 +4994,7 @@ void do_final(void) regen_db->destroy(regen_db, NULL); map_sql_close(); + ers_destroy(map_iterator_ers); ShowStatus("Finished.\n"); } @@ -5123,22 +5056,19 @@ static void map_helpscreen(bool do_exit) /*====================================================== * Map-Server Version Screen [MC Cameri] *------------------------------------------------------*/ -static void map_versionscreen(bool do_exit) -{ - ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision()); - ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n"); - ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n"); +static void map_versionscreen(bool do_exit) { + const char *svn = get_svn_revision(); + const char *git = get_git_hash(); + ShowInfo(CL_WHITE"Hercules version: %s" CL_RESET"\n", git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); + ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://hercules.ws/\n"); + ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#Hercules\n"); ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n"); if( do_exit ) exit(EXIT_SUCCESS); } -/*====================================================== - * Map-Server Init and Command-line Arguments [Valaris] - *------------------------------------------------------*/ -void set_server_type(void) -{ - SERVER_TYPE = ATHENA_SERVER_MAP; +void set_server_type(void) { + SERVER_TYPE = SERVER_TYPE_MAP; } @@ -5163,14 +5093,80 @@ void do_shutdown(void) static bool map_arg_next_value(const char* option, int i, int argc) { - if( i >= argc-1 ) - { + if( i >= argc-1 ) { ShowWarning("Missing value for option '%s'.\n", option); return false; } return true; } +struct map_session_data cpsd; +CPCMD(gm_position) { + int x = 0, y = 0, m = 0; + char map_name[25]; + + if( line == NULL || sscanf(line, "%d %d %24s",&x,&y,map_name) < 3 ) { + ShowError("gm:info invalid syntax. use '"CL_WHITE"gm:info xCord yCord map_name"CL_RESET"'\n"); + return; + } + + if ( (m = map_mapname2mapid(map_name) <= 0 ) ) { + ShowError("gm:info '"CL_WHITE"%s"CL_RESET"' is not a known map\n",map_name); + return; + } + + if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) { + ShowError("gm:info '"CL_WHITE"%d %d"CL_RESET"' is out of '"CL_WHITE"%s"CL_RESET"' map bounds!\n",x,y,map_name); + return; + } + + ShowInfo("HCP: updated console's game position to '"CL_WHITE"%d %d %s"CL_RESET"'\n",x,y,map_name); + cpsd.bl.x = x; + cpsd.bl.y = y; + cpsd.bl.m = m; +} +CPCMD(gm_use) { + + if( line == NULL ) { + ShowError("gm:use invalid syntax. use '"CL_WHITE"gm:use @command "CL_RESET"'\n"); + return; + } + cpsd.fd = -2; + if( !atcommand->parse(cpsd.fd, &cpsd, line, 0) ) + ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' failed\n",line); + else + ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' was used\n",line); + cpsd.fd = 0; + +} +/* Hercules Console Parser */ +void map_cp_defaults(void) { + /* default HCP data */ + memset(&cpsd, 0, sizeof(struct map_session_data)); + strcpy(cpsd.status.name, "Hercules Console"); + cpsd.bl.x = 150; + cpsd.bl.y = 150; + cpsd.bl.m = map_mapname2mapid("prontera"); + + console->addCommand("gm:info",CPCMD_A(gm_position)); + console->addCommand("gm:use",CPCMD_A(gm_use)); +} +/* Hercules Plugin Mananger */ +void map_hp_symbols(void) { + /* full interfaces */ + HPM->share(atcommand,"atcommand"); + HPM->share(buyingstore,"buyingstore"); + HPM->share(clif,"clif"); + HPM->share(ircbot,"ircbot"); + HPM->share(logs,"logs"); + HPM->share(script,"script"); + HPM->share(searchstore,"searchstore"); + HPM->share(skill,"skill"); + HPM->share(vending,"vending"); + /* specific */ + HPM->share(atcommand->create,"addCommand"); + HPM->share(script->addScript,"addScript"); +} void load_defaults(void) { atcommand_defaults(); battle_defaults(); @@ -5178,6 +5174,7 @@ void load_defaults(void) { clif_defaults(); ircbot_defaults(); log_defaults(); + script_defaults(); searchstore_defaults(); skill_defaults(); vending_defaults(); @@ -5332,6 +5329,7 @@ int do_init(int argc, char *argv[]) iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH); + map_iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_NONE); map_sql_init(); if (logs->config.sql_logs) @@ -5347,14 +5345,18 @@ int do_init(int argc, char *argv[]) add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer"); add_timer_func_list(map_removemobs_timer, "map_removemobs_timer"); add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000); - + + HPM->symbol_defaults_sub = map_hp_symbols; + HPM->config_read(); + HPM->event(HPET_INIT); + atcommand->init(); battle->init(); do_init_instance(); do_init_chrif(); clif->init(); ircbot->init(); - do_init_script(); + script->init(); do_init_itemdb(); skill->init(); read_map_zone_db();/* read after item and skill initalization */ @@ -5384,15 +5386,14 @@ int do_init(int argc, char *argv[]) ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port); - if( runflag != CORE_ST_STOP ) - { + if( runflag != CORE_ST_STOP ) { shutdown_callback = do_shutdown; runflag = MAPSERVER_ST_RUNNING; } -#if defined(BUILDBOT) - if( buildbotflag ) - exit(EXIT_FAILURE); -#endif - + + map_cp_defaults(); + + HPM->event(HPET_READY); + return 0; } diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c index 64d0fe5e9..81373bbb6 100644 --- a/src/map/npc_chat.c +++ b/src/map/npc_chat.c @@ -408,9 +408,9 @@ int npc_chat_sub(struct block_list* bl, va_list ap) int buildin_defpattern(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); - const char* pattern = conv_str(st,& (st->stack->stack_data[st->start+3])); - const char* label = conv_str(st,& (st->stack->stack_data[st->start+4])); + int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); + const char* pattern = script->conv_str(st,& (st->stack->stack_data[st->start+3])); + const char* label = script->conv_str(st,& (st->stack->stack_data[st->start+4])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); npc_chat_def_pattern(nd, setid, pattern, label); @@ -420,7 +420,7 @@ int buildin_defpattern(struct script_state* st) int buildin_activatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); activate_pcreset(nd, setid); @@ -430,7 +430,7 @@ int buildin_activatepset(struct script_state* st) int buildin_deactivatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); deactivate_pcreset(nd, setid); @@ -440,7 +440,7 @@ int buildin_deactivatepset(struct script_state* st) int buildin_deletepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int setid = script->conv_num(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); delete_pcreset(nd, setid); diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c index 2fd143b53..42a068693 100644 --- a/src/map/pc_groups.c +++ b/src/map/pc_groups.c @@ -14,7 +14,6 @@ #include "pc_groups.h" #include "pc.h" // e_pc_permission - typedef struct GroupSettings GroupSettings; // Cached config settings/pointers for quick lookup @@ -278,16 +277,18 @@ static void read_config(void) { if( ( pc_group_max = group_count ) ) { DBIterator *iter = db_iterator(pc_group_db); GroupSettings *group_settings = NULL; - int* group_ids = aMalloc( pc_group_max * sizeof(int) ); + unsigned int* group_ids = aMalloc( pc_group_max * sizeof(unsigned int) ); int i = 0; for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { group_ids[i++] = group_settings->id; } - atcommand->load_groups(group_ids); - - aFree(group_ids); + if( atcommand->group_ids ) + aFree(atcommand->group_ids); + atcommand->group_ids = group_ids; + atcommand->load_groups(); + dbi_destroy(iter); } diff --git a/src/map/script.c b/src/map/script.c index fbe3a31df..3b1533f74 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -63,103 +63,6 @@ #include #include - -/////////////////////////////////////////////////////////////////////////////// -//## TODO possible enhancements: [FlavioJS] -// - 'callfunc' supporting labels in the current npc "::LabelName" -// - 'callfunc' supporting labels in other npcs "NpcName::LabelName" -// - 'function FuncName;' function declarations reverting to global functions -// if local label isn't found -// - join callfunc and callsub's functionality -// - remove dynamic allocation in add_word() -// - remove GETVALUE / SETVALUE -// - clean up the set_reg / set_val / setd_sub mess -// - detect invalid label references at parse-time - -// -// struct script_state* st; -// - -/// Returns the script_data at the target index -#define script_getdata(st,i) ( &((st)->stack->stack_data[(st)->start + (i)]) ) -/// Returns if the stack contains data at the target index -#define script_hasdata(st,i) ( (st)->end > (st)->start + (i) ) -/// Returns the index of the last data in the stack -#define script_lastdata(st) ( (st)->end - (st)->start - 1 ) -/// Pushes an int into the stack -#define script_pushint(st,val) push_val((st)->stack, C_INT, (val)) -/// Pushes a string into the stack (script engine frees it automatically) -#define script_pushstr(st,val) push_str((st)->stack, C_STR, (val)) -/// Pushes a copy of a string into the stack -#define script_pushstrcopy(st,val) push_str((st)->stack, C_STR, aStrdup(val)) -/// Pushes a constant string into the stack (must never change or be freed) -#define script_pushconststr(st,val) push_str((st)->stack, C_CONSTSTR, (val)) -/// Pushes a nil into the stack -#define script_pushnil(st) push_val((st)->stack, C_NOP, 0) -/// Pushes a copy of the data in the target index -#define script_pushcopy(st,i) push_copy((st)->stack, (st)->start + (i)) - -#define script_isstring(st,i) data_isstring(script_getdata(st,i)) -#define script_isint(st,i) data_isint(script_getdata(st,i)) - -#define script_getnum(st,val) conv_num(st, script_getdata(st,val)) -#define script_getstr(st,val) conv_str(st, script_getdata(st,val)) -#define script_getref(st,val) ( script_getdata(st,val)->ref ) - -// Note: "top" functions/defines use indexes relative to the top of the stack -// -1 is the index of the data at the top - -/// Returns the script_data at the target index relative to the top of the stack -#define script_getdatatop(st,i) ( &((st)->stack->stack_data[(st)->stack->sp + (i)]) ) -/// Pushes a copy of the data in the target index relative to the top of the stack -#define script_pushcopytop(st,i) push_copy((st)->stack, (st)->stack->sp + (i)) -/// Removes the range of values [start,end[ relative to the top of the stack -#define script_removetop(st,start,end) ( pop_stack((st), ((st)->stack->sp + (start)), (st)->stack->sp + (end)) ) - -// -// struct script_data* data; -// - -/// Returns if the script data is a string -#define data_isstring(data) ( (data)->type == C_STR || (data)->type == C_CONSTSTR ) -/// Returns if the script data is an int -#define data_isint(data) ( (data)->type == C_INT ) -/// Returns if the script data is a reference -#define data_isreference(data) ( (data)->type == C_NAME ) -/// Returns if the script data is a label -#define data_islabel(data) ( (data)->type == C_POS ) -/// Returns if the script data is an internal script function label -#define data_isfunclabel(data) ( (data)->type == C_USERFUNC_POS ) - -/// Returns if this is a reference to a constant -#define reference_toconstant(data) ( str_data[reference_getid(data)].type == C_INT ) -/// Returns if this a reference to a param -#define reference_toparam(data) ( str_data[reference_getid(data)].type == C_PARAM ) -/// Returns if this a reference to a variable -//##TODO confirm it's C_NAME [FlavioJS] -#define reference_tovariable(data) ( str_data[reference_getid(data)].type == C_NAME ) -/// Returns the unique id of the reference (id and index) -#define reference_getuid(data) ( (data)->u.num ) -/// Returns the id of the reference -#define reference_getid(data) ( (int32)(reference_getuid(data) & 0x00ffffff) ) -/// Returns the array index of the reference -#define reference_getindex(data) ( (int32)(((uint32)(reference_getuid(data) & 0xff000000)) >> 24) ) -/// Returns the name of the reference -#define reference_getname(data) ( str_buf + str_data[reference_getid(data)].str ) -/// Returns the linked list of uid-value pairs of the reference (can be NULL) -#define reference_getref(data) ( (data)->ref ) -/// Returns the value of the constant -#define reference_getconstant(data) ( str_data[reference_getid(data)].val ) -/// Returns the type of param -#define reference_getparamtype(data) ( str_data[reference_getid(data)].val ) - -/// Composes the uid of a reference from the id and the index -#define reference_uid(id,idx) ( (int32)((((uint32)(id)) & 0x00ffffff) | (((uint32)(idx)) << 24)) ) - -#define not_server_variable(prefix) ( (prefix) != '$' && (prefix) != '.' && (prefix) != '\'') -#define not_array_variable(prefix) ( (prefix) != '$' && (prefix) != '@' && (prefix) != '.' && (prefix) != '\'' ) -#define is_string_variable(name) ( (name)[strlen(name) - 1] == '$' ) - #define FETCH(n, t) \ if( script_hasdata(st,n) ) \ (t)=script_getnum(st,n); @@ -298,14 +201,6 @@ int potion_target=0; c_op get_com(unsigned char *script,int *pos); int get_num(unsigned char *script,int *pos); -typedef struct script_function { - bool (*func)(struct script_state *st); - const char *name; - const char *arg; -} script_function; - -extern script_function BUILDIN[]; - static struct linkdb_node* sleep_db;// int oid -> struct script_state* /*========================================== @@ -472,20 +367,19 @@ static void script_reportsrc(struct script_state *st) if( bl == NULL ) return; - switch( bl->type ) - { - case BL_NPC: - if( bl->m >= 0 ) - ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, map[bl->m].name, bl->x, bl->y); - else - ShowDebug("Source (NPC): %s (invisible/not on a map)\n", ((struct npc_data *)bl)->name); - break; - default: - if( bl->m >= 0 ) - ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), map[bl->m].name, bl->x, bl->y); - else - ShowDebug("Source (Non-NPC type %d): name %s (invisible/not on a map)\n", bl->type, status_get_name(bl)); - break; + switch( bl->type ) { + case BL_NPC: + if( bl->m >= 0 ) + ShowDebug("Source (NPC): %s at %s (%d,%d)\n", ((struct npc_data *)bl)->name, map[bl->m].name, bl->x, bl->y); + else + ShowDebug("Source (NPC): %s (invisible/not on a map)\n", ((struct npc_data *)bl)->name); + break; + default: + if( bl->m >= 0 ) + ShowDebug("Source (Non-NPC type %d): name %s at %s (%d,%d)\n", bl->type, status_get_name(bl), map[bl->m].name, bl->x, bl->y); + else + ShowDebug("Source (Non-NPC type %d): name %s (invisible/not on a map)\n", bl->type, status_get_name(bl)); + break; } } @@ -494,54 +388,43 @@ static void script_reportdata(struct script_data* data) { if( data == NULL ) return; - switch( data->type ) - { - case C_NOP:// no value - ShowDebug("Data: nothing (nil)\n"); - break; - case C_INT:// number - ShowDebug("Data: number value=%d\n", data->u.num); - break; - case C_STR: - case C_CONSTSTR:// string - if( data->u.str ) - { - ShowDebug("Data: string value=\"%s\"\n", data->u.str); - } - else - { - ShowDebug("Data: string value=NULL\n"); - } - break; - case C_NAME:// reference - if( reference_tovariable(data) ) - {// variable - const char* name = reference_getname(data); - if( not_array_variable(*name) ) - ShowDebug("Data: variable name='%s'\n", name); - else - ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data)); - } - else if( reference_toconstant(data) ) - {// constant - ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data)); - } - else if( reference_toparam(data) ) - {// param - ShowDebug("Data: param name='%s' type=%d\n", reference_getname(data), reference_getparamtype(data)); - } - else - {// ??? - ShowDebug("Data: reference name='%s' type=%s\n", reference_getname(data), script_op2name(data->type)); - ShowDebug("Please report this!!! - str_data.type=%s\n", script_op2name(str_data[reference_getid(data)].type)); - } - break; - case C_POS:// label - ShowDebug("Data: label pos=%d\n", data->u.num); - break; - default: - ShowDebug("Data: %s\n", script_op2name(data->type)); - break; + switch( data->type ) { + case C_NOP:// no value + ShowDebug("Data: nothing (nil)\n"); + break; + case C_INT:// number + ShowDebug("Data: number value=%d\n", data->u.num); + break; + case C_STR: + case C_CONSTSTR:// string + if( data->u.str ) { + ShowDebug("Data: string value=\"%s\"\n", data->u.str); + } else { + ShowDebug("Data: string value=NULL\n"); + } + break; + case C_NAME:// reference + if( reference_tovariable(data) ) {// variable + const char* name = reference_getname(data); + if( not_array_variable(*name) ) + ShowDebug("Data: variable name='%s'\n", name); + else + ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data)); + } else if( reference_toconstant(data) ) {// constant + ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data)); + } else if( reference_toparam(data) ) {// param + ShowDebug("Data: param name='%s' type=%d\n", reference_getname(data), reference_getparamtype(data)); + } else {// ??? + ShowDebug("Data: reference name='%s' type=%s\n", reference_getname(data), script_op2name(data->type)); + ShowDebug("Please report this!!! - str_data.type=%s\n", script_op2name(str_data[reference_getid(data)].type)); + } + break; + case C_POS:// label + ShowDebug("Data: label pos=%d\n", data->u.num); + break; + default: + ShowDebug("Data: %s\n", script_op2name(data->type)); + break; } } @@ -773,33 +656,33 @@ static void add_scriptl(int l) int backpatch = str_data[l].backpatch; switch(str_data[l].type){ - case C_POS: - case C_USERFUNC_POS: - add_scriptc(C_POS); - add_scriptb(str_data[l].label); - add_scriptb(str_data[l].label>>8); - add_scriptb(str_data[l].label>>16); - break; - case C_NOP: - case C_USERFUNC: - // Embedded data backpatch there is a possibility of label - add_scriptc(C_NAME); - str_data[l].backpatch = script_pos; - add_scriptb(backpatch); - add_scriptb(backpatch>>8); - add_scriptb(backpatch>>16); - break; - case C_INT: - add_scripti(abs(str_data[l].val)); - if( str_data[l].val < 0 ) //Notice that this is negative, from jA (Rayce) - add_scriptc(C_NEG); - break; - default: // assume C_NAME - add_scriptc(C_NAME); - add_scriptb(l); - add_scriptb(l>>8); - add_scriptb(l>>16); - break; + case C_POS: + case C_USERFUNC_POS: + add_scriptc(C_POS); + add_scriptb(str_data[l].label); + add_scriptb(str_data[l].label>>8); + add_scriptb(str_data[l].label>>16); + break; + case C_NOP: + case C_USERFUNC: + // Embedded data backpatch there is a possibility of label + add_scriptc(C_NAME); + str_data[l].backpatch = script_pos; + add_scriptb(backpatch); + add_scriptb(backpatch>>8); + add_scriptb(backpatch>>16); + break; + case C_INT: + add_scripti(abs(str_data[l].val)); + if( str_data[l].val < 0 ) //Notice that this is negative, from jA (Rayce) + add_scriptc(C_NEG); + break; + default: // assume C_NAME + add_scriptc(C_NAME); + add_scriptb(l); + add_scriptb(l>>8); + add_scriptb(l>>16); + break; } } @@ -927,8 +810,8 @@ int add_word(const char* p) static const char* parse_callfunc(const char* p, int require_paren, int is_custom) { - const char* p2; - const char* arg=NULL; + const char *p2; + char *arg = NULL; int func; func = add_word(p); @@ -936,13 +819,13 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) // buildin function add_scriptl(func); add_scriptc(C_ARG); - arg = BUILDIN[str_data[func].val].arg; + arg = script->buildin[str_data[func].val]; } else if( str_data[func].type == C_USERFUNC || str_data[func].type == C_USERFUNC_POS ){ // script defined function add_scriptl(buildin_callsub_ref); add_scriptc(C_ARG); add_scriptl(func); - arg = BUILDIN[str_data[buildin_callsub_ref].val].arg; + arg = script->buildin[str_data[buildin_callsub_ref].val]; if( *arg == 0 ) disp_error_message("parse_callfunc: callsub has no arguments, please review it's definition",p); if( *arg != '*' ) @@ -960,7 +843,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) add_scriptc(C_STR); while( *name ) add_scriptb(*name ++); add_scriptb(0); - arg = BUILDIN[str_data[buildin_callfunc_ref].val].arg; + arg = script->buildin[str_data[buildin_callfunc_ref].val]; if( *arg != '*' ) ++ arg; } #endif @@ -982,8 +865,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) {// syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN; */ - } else - {// + } else {// if( require_paren ){ if( *p != '(' ) disp_error_message("need '('",p); @@ -1009,7 +891,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) } --syntax.curly_count; } - if( *arg && *arg != '?' && *arg != '*' ) + if( arg && *arg && *arg != '?' && *arg != '*' ) disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script_config.warn_func_mismatch_paramnum); if( syntax.curly[syntax.curly_count].type != TYPE_ARGLIST ) disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p); @@ -2087,45 +1969,6 @@ const char* parse_syntax_close_sub(const char* p,int* flag) } } -/*========================================== - * Added built-in functions - *------------------------------------------*/ -static void add_BUILDIN(void) -{ - int i,n; - const char* p; - for( i = 0; BUILDIN[i].func; i++ ) - { - // arg must follow the pattern: (v|s|i|r|l)*\?*\*? - // 'v' - value (either string or int or reference) - // 's' - string - // 'i' - int - // 'r' - reference (of a variable) - // 'l' - label - // '?' - one optional parameter - // '*' - unknown number of optional parameters - p = BUILDIN[i].arg; - while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p; - while( *p == '?' ) ++p; - if( *p == '*' ) ++p; - if( *p != 0){ - ShowWarning("add_BUILDIN: ignoring function \"%s\" with invalid arg \"%s\".\n", BUILDIN[i].name, BUILDIN[i].arg); - } else if( *skip_word(BUILDIN[i].name) != 0 ){ - ShowWarning("add_BUILDIN: ignoring function with invalid name \"%s\" (must be a word).\n", BUILDIN[i].name); - } else { - n = add_str(BUILDIN[i].name); - str_data[n].type = C_FUNC; - str_data[n].val = i; - str_data[n].func = BUILDIN[i].func; - - if (!strcmp(BUILDIN[i].name, "set")) buildin_set_ref = n; - else if (!strcmp(BUILDIN[i].name, "callsub")) buildin_callsub_ref = n; - else if (!strcmp(BUILDIN[i].name, "callfunc")) buildin_callfunc_ref = n; - else if( !strcmp(BUILDIN[i].name, "getelementofarray") ) buildin_getelementofarray_ref = n; - } - } -} - /// Retrieves the value of a constant. bool script_get_constant(const char* name, int* value) { @@ -2254,7 +2097,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o const char *p,*tmpp; int i; struct script_code* code = NULL; - static int first=1; char end; bool unresolved_names = false; @@ -2262,11 +2104,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o return NULL;// empty script memset(&syntax,0,sizeof(syntax)); - if(first){ - add_BUILDIN(); - read_constdb(); - first=0; - } script_buf=(unsigned char *)aMalloc(SCRIPT_BLOCK_SIZE*sizeof(unsigned char)); script_pos=0; @@ -2754,8 +2591,7 @@ const char* conv_str(struct script_state* st, struct script_data* data) } /// Converts the data to an int -int conv_num(struct script_state* st, struct script_data* data) -{ +int conv_num(struct script_state* st, struct script_data* data) { char* p; long num; @@ -3215,11 +3051,11 @@ void op_2(struct script_state *st, int op) case C_ADD: if( data_isint(left) && data_isstring(right) ) {// convert int-string to string-string - conv_str(st, left); + script->conv_str(st, left); } else if( data_isstring(left) && data_isint(right) ) {// convert string-int to string-string - conv_str(st, right); + script->conv_str(st, right); } break; } @@ -3306,26 +3142,20 @@ static void script_check_buildin_argtype(struct script_state* st, int func) { char type; int idx, invalid = 0; - script_function* sf = &BUILDIN[str_data[func].val]; + char* sf = script->buildin[str_data[func].val]; - for( idx = 2; script_hasdata(st, idx); idx++ ) - { + for( idx = 2; script_hasdata(st, idx); idx++ ) { struct script_data* data = script_getdata(st, idx); - type = sf->arg[idx-2]; - - if( type == '?' || type == '*' ) - {// optional argument or unknown number of optional parameters ( no types are after this ) + type = sf[idx-2]; + + if( type == '?' || type == '*' ) {// optional argument or unknown number of optional parameters ( no types are after this ) break; - } - else if( type == 0 ) - {// more arguments than necessary ( should not happen, as it is checked before ) + } else if( type == 0 ) {// more arguments than necessary ( should not happen, as it is checked before ) ShowWarning("Found more arguments than necessary. unexpected arg type %s\n",script_op2name(data->type)); invalid++; break; - } - else - { + } else { const char* name = NULL; if( data_isreference(data) ) @@ -3333,8 +3163,7 @@ static void script_check_buildin_argtype(struct script_state* st, int func) name = reference_getname(data); } - switch( type ) - { + switch( type ) { case 'v': if( !data_isstring(data) && !data_isint(data) && !data_isreference(data) ) {// variant @@ -3379,8 +3208,7 @@ static void script_check_buildin_argtype(struct script_state* st, int func) } } - if(invalid) - { + if(invalid) { ShowDebug("Function: %s\n", get_str(func)); script_reportsrc(st); } @@ -3929,7 +3757,7 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 /*========================================== * Destructor *------------------------------------------*/ -int do_final_script() { +void do_final_script(void) { int i; #ifdef DEBUG_HASH if (battle_config.etc_log) @@ -4012,19 +3840,27 @@ int do_final_script() { if( atcommand->binding_count != 0 ) aFree(atcommand->binding); + + for( i = 0; i < script->buildin_count; i++) { + if( script->buildin[i] ) { + aFree(script->buildin[i]); + script->buildin[i] = NULL; + } + } + + aFree(script->buildin); - return 0; } /*========================================== * Initialization *------------------------------------------*/ -int do_init_script() { - userfunc_db=strdb_alloc(DB_OPT_DUP_KEY,0); - scriptlabel_db=strdb_alloc(DB_OPT_DUP_KEY,50); +void do_init_script(void) { + userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0); + scriptlabel_db = strdb_alloc(DB_OPT_DUP_KEY,50); autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0); - + script->parse_builtin(); + read_constdb(); mapreg_init(); - return 0; } int script_reload() { @@ -4061,7 +3897,6 @@ int script_reload() { #define BUILDIN_DEF(x,args) { buildin_ ## x , #x , args } #define BUILDIN_DEF2(x,x2,args) { buildin_ ## x , x2 , args } -#define BUILDIN(x) bool buildin_ ## x (struct script_state* st) ///////////////////////////////////////////////////////////////////// // NPC interaction @@ -5768,11 +5603,11 @@ BUILDIN(countitem) if( data_isstring(data) ) {// item name - id = itemdb_searchname(conv_str(st, data)); + id = itemdb_searchname(script->conv_str(st, data)); } else {// item id - id = itemdb_exists(conv_num(st, data)); + id = itemdb_exists(script->conv_num(st, data)); } if( id == NULL ) @@ -5815,11 +5650,11 @@ BUILDIN(countitem2) if( data_isstring(data) ) {// item name - id = itemdb_searchname(conv_str(st, data)); + id = itemdb_searchname(script->conv_str(st, data)); } else {// item id - id = itemdb_exists(conv_num(st, data)); + id = itemdb_exists(script->conv_num(st, data)); } if( id == NULL ) @@ -5882,9 +5717,9 @@ BUILDIN(checkweight) data = script_getdata(st,i); get_val(st, data); // convert into value in case of a variable if( data_isstring(data) ){// item name - id = itemdb_searchname(conv_str(st, data)); + id = itemdb_searchname(script->conv_str(st, data)); } else {// item id - id = itemdb_exists(conv_num(st, data)); + id = itemdb_exists(script->conv_num(st, data)); } if( id == NULL ) { ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was @@ -6055,14 +5890,14 @@ BUILDIN(getitem) get_val(st,data); if( data_isstring(data) ) {// "" - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); if( (item_data = itemdb_searchname(name)) == NULL ){ ShowError("buildin_getitem: Nonexistant item %s requested.\n", name); return false; //No item created. } nameid=item_data->nameid; } else if( data_isint(data) ) {// - nameid=conv_num(st,data); + nameid=script->conv_num(st,data); //Violet Box, Blue Box, etc - random item pick if( nameid < 0 ) { nameid = -nameid; @@ -6142,14 +5977,14 @@ BUILDIN(getitem2) data=script_getdata(st,2); get_val(st,data); if( data_isstring(data) ){ - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); if( item_data ) nameid=item_data->nameid; else nameid=UNKNOWN_ITEM_ID; }else - nameid=conv_num(st,data); + nameid=script->conv_num(st,data); amount=script_getnum(st,3); iden=script_getnum(st,4); @@ -6238,7 +6073,7 @@ BUILDIN(rentitem) if( data_isstring(data) ) { - const char *name = conv_str(st,data); + const char *name = script->conv_str(st,data); struct item_data *itd = itemdb_searchname(name); if( itd == NULL ) { @@ -6249,7 +6084,7 @@ BUILDIN(rentitem) } else if( data_isint(data) ) { - nameid = conv_num(st,data); + nameid = script->conv_num(st,data); if( nameid <= 0 || !itemdb_exists(nameid) ) { ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid); @@ -6300,7 +6135,7 @@ BUILDIN(getnameditem) data=script_getdata(st,2); get_val(st,data); if( data_isstring(data) ){ - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); if( item_data == NULL) { //Failed @@ -6309,7 +6144,7 @@ BUILDIN(getnameditem) } nameid = item_data->nameid; }else - nameid = conv_num(st,data); + nameid = script->conv_num(st,data); if(!itemdb_exists(nameid)/* || itemdb_isstackable(nameid)*/) { //Even though named stackable items "could" be risky, they are required for certain quests. @@ -6320,9 +6155,9 @@ BUILDIN(getnameditem) data=script_getdata(st,3); get_val(st,data); if( data_isstring(data) ) //Char Name - tsd=map_nick2sd(conv_str(st,data)); + tsd=map_nick2sd(script->conv_str(st,data)); else //Char Id was given - tsd=map_charid2sd(conv_num(st,data)); + tsd=map_charid2sd(script->conv_num(st,data)); if( tsd == NULL ) { //Failed @@ -6374,13 +6209,13 @@ BUILDIN(makeitem) data=script_getdata(st,2); get_val(st,data); if( data_isstring(data) ){ - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); if( (item_data = itemdb_searchname(name)) ) nameid=item_data->nameid; else nameid=UNKNOWN_ITEM_ID; } else { - nameid=conv_num(st,data); + nameid=script->conv_num(st,data); if( nameid <= 0 || !(item_data = itemdb_exists(nameid)) ){ ShowError("makeitem: Nonexistant item %d requested.\n", nameid); return false; //No item created. @@ -6587,7 +6422,7 @@ BUILDIN(delitem) get_val(st,data); if( data_isstring(data) ) { - const char* item_name = conv_str(st,data); + const char* item_name = script->conv_str(st,data); struct item_data* id = itemdb_searchname(item_name); if( id == NULL ) { @@ -6599,7 +6434,7 @@ BUILDIN(delitem) } else { - it.nameid = conv_num(st,data);// + it.nameid = script->conv_num(st,data);// if( !itemdb_exists( it.nameid ) ) { ShowError("script:delitem: unknown item \"%d\".\n", it.nameid); @@ -6656,7 +6491,7 @@ BUILDIN(delitem2) get_val(st,data); if( data_isstring(data) ) { - const char* item_name = conv_str(st,data); + const char* item_name = script->conv_str(st,data); struct item_data* id = itemdb_searchname(item_name); if( id == NULL ) { @@ -6668,7 +6503,7 @@ BUILDIN(delitem2) } else { - it.nameid = conv_num(st,data);// + it.nameid = script->conv_num(st,data);// if( !itemdb_exists( it.nameid ) ) { ShowError("script:delitem: unknown item \"%d\".\n", it.nameid); @@ -9004,11 +8839,11 @@ BUILDIN(initnpctimer) data = script_getdata(st,2); get_val(st,data); if( data_isstring(data) ) //NPC name - nd = npc_name2id(conv_str(st, data)); + nd = npc_name2id(script->conv_str(st, data)); else if( data_isint(data) ) //Flag { nd = (struct npc_data *)map_id2bl(st->oid); - flag = conv_num(st,data); + flag = script->conv_num(st,data); } else { @@ -9052,11 +8887,11 @@ BUILDIN(startnpctimer) data = script_getdata(st,2); get_val(st,data); if( data_isstring(data) ) //NPC name - nd = npc_name2id(conv_str(st, data)); + nd = npc_name2id(script->conv_str(st, data)); else if( data_isint(data) ) //Flag { nd = (struct npc_data *)map_id2bl(st->oid); - flag = conv_num(st,data); + flag = script->conv_num(st,data); } else { @@ -9098,11 +8933,11 @@ BUILDIN(stopnpctimer) data = script_getdata(st,2); get_val(st,data); if( data_isstring(data) ) //NPC name - nd = npc_name2id(conv_str(st, data)); + nd = npc_name2id(script->conv_str(st, data)); else if( data_isint(data) ) //Flag { nd = (struct npc_data *)map_id2bl(st->oid); - flag = conv_num(st,data); + flag = script->conv_num(st,data); } else { @@ -9332,14 +9167,14 @@ BUILDIN(itemeffect) { get_val( st, data ); if( data_isstring( data ) ){ - const char *name = conv_str( st, data ); + const char *name = script->conv_str( st, data ); if( ( item_data = itemdb_searchname( name ) ) == NULL ){ ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name ); return false; } } else if( data_isint( data ) ){ - int nameid = conv_num( st, data ); + int nameid = script->conv_num( st, data ); if( ( item_data = itemdb_exists( nameid ) ) == NULL ){ ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid ); @@ -9567,13 +9402,13 @@ BUILDIN(getareadropitem) data=script_getdata(st,7); get_val(st,data); if( data_isstring(data) ){ - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); item=UNKNOWN_ITEM_ID; if( item_data ) item=item_data->nameid; }else - item=conv_num(st,data); + item=script->conv_num(st,data); if( (m=map_mapname2mapid(str))< 0){ script_pushint(st,-1); @@ -11631,12 +11466,12 @@ BUILDIN(getitemname) get_val(st,data); if( data_isstring(data) ){ - const char *name=conv_str(st,data); + const char *name=script->conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); if( item_data ) item_id=item_data->nameid; }else - item_id=conv_num(st,data); + item_id=script->conv_num(st,data); i_data = itemdb_exists(item_id); if (i_data == NULL) @@ -14162,9 +13997,9 @@ BUILDIN(setnpcdisplay) get_val(st, data); if( data_isstring(data) ) - newname = conv_str(st,data); + newname = script->conv_str(st,data); else if( data_isint(data) ) - class_ = conv_num(st,data); + class_ = script->conv_num(st,data); else { ShowError("script:setnpcdisplay: expected a string or number\n"); @@ -14634,17 +14469,17 @@ BUILDIN(npcshopattach) BUILDIN(setitemscript) { int item_id,n=0; - const char *script; + const char *new_bonus_script; struct item_data *i_data; struct script_code **dstscript; item_id = script_getnum(st,2); - script = script_getstr(st,3); + new_bonus_script = script_getstr(st,3); if( script_hasdata(st,4) ) n=script_getnum(st,4); i_data = itemdb_exists(item_id); - if (!i_data || script==NULL || ( script[0] && script[0]!='{' )) { + if (!i_data || new_bonus_script==NULL || ( new_bonus_script[0] && new_bonus_script[0]!='{' )) { script_pushint(st,0); return true; } @@ -14662,7 +14497,7 @@ BUILDIN(setitemscript) if(*dstscript) script_free_code(*dstscript); - *dstscript = script[0] ? parse_script(script, "script_setitemscript", 0, 0) : NULL; + *dstscript = new_bonus_script[0] ? parse_script(new_bonus_script, "script_setitemscript", 0, 0) : NULL; script_pushint(st,1); return true; } @@ -15094,11 +14929,11 @@ BUILDIN(unitattack) get_val(st, data); if( data_isstring(data) ) { - TBL_PC* sd = map_nick2sd(conv_str(st, data)); + TBL_PC* sd = map_nick2sd(script->conv_str(st, data)); if( sd != NULL ) target_bl = &sd->bl; } else - target_bl = map_id2bl(conv_num(st, data)); + target_bl = map_id2bl(script->conv_num(st, data)); // request the attack if( target_bl == NULL ) { @@ -17158,466 +16993,565 @@ BUILDIN(npcskill) return true; } - // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT -BUILDIN(defpattern); -BUILDIN(activatepset); -BUILDIN(deactivatepset); -BUILDIN(deletepset); + BUILDIN(defpattern); + BUILDIN(activatepset); + BUILDIN(deactivatepset); + BUILDIN(deletepset); #endif -/// script command definitions -/// for an explanation on args, see add_BUILDIN -struct script_function BUILDIN[] = { - // NPC interaction - BUILDIN_DEF(mes,"s*"), - BUILDIN_DEF(next,""), - BUILDIN_DEF(close,""), - BUILDIN_DEF(close2,""), - BUILDIN_DEF(menu,"sl*"), - BUILDIN_DEF(select,"s*"), //for future jA script compatibility - BUILDIN_DEF(prompt,"s*"), - // - BUILDIN_DEF(goto,"l"), - BUILDIN_DEF(callsub,"l*"), - BUILDIN_DEF(callfunc,"s*"), - BUILDIN_DEF(return,"?"), - BUILDIN_DEF(getarg,"i?"), - BUILDIN_DEF(jobchange,"i?"), - BUILDIN_DEF(jobname,"i"), - BUILDIN_DEF(input,"r??"), - BUILDIN_DEF(warp,"sii"), - BUILDIN_DEF(areawarp,"siiiisii??"), - BUILDIN_DEF(warpchar,"siii"), // [LuzZza] - BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X] - BUILDIN_DEF(warpguild,"siii"), // [Fredzilla] - BUILDIN_DEF(setlook,"ii"), - BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it - BUILDIN_DEF(set,"rv"), - BUILDIN_DEF(setarray,"rv*"), - BUILDIN_DEF(cleararray,"rvi"), - BUILDIN_DEF(copyarray,"rri"), - BUILDIN_DEF(getarraysize,"r"), - BUILDIN_DEF(deletearray,"r?"), - BUILDIN_DEF(getelementofarray,"ri"), - BUILDIN_DEF(getitem,"vi?"), - BUILDIN_DEF(rentitem,"vi"), - BUILDIN_DEF(getitem2,"viiiiiiii?"), - BUILDIN_DEF(getnameditem,"vv"), - BUILDIN_DEF2(grouprandomitem,"groupranditem","i"), - BUILDIN_DEF(makeitem,"visii"), - BUILDIN_DEF(delitem,"vi?"), - BUILDIN_DEF(delitem2,"viiiiiiii?"), - BUILDIN_DEF2(enableitemuse,"enable_items",""), - BUILDIN_DEF2(disableitemuse,"disable_items",""), - BUILDIN_DEF(cutin,"si"), - BUILDIN_DEF(viewpoint,"iiiii"), - BUILDIN_DEF(heal,"ii"), - BUILDIN_DEF(itemheal,"ii"), - BUILDIN_DEF(percentheal,"ii"), - BUILDIN_DEF(rand,"i?"), - BUILDIN_DEF(countitem,"v"), - BUILDIN_DEF(countitem2,"viiiiiii"), - BUILDIN_DEF(checkweight,"vi*"), - BUILDIN_DEF(checkweight2,"rr"), - BUILDIN_DEF(readparam,"i?"), - BUILDIN_DEF(getcharid,"i?"), - BUILDIN_DEF(getnpcid,"i?"), - BUILDIN_DEF(getpartyname,"i"), - BUILDIN_DEF(getpartymember,"i?"), - BUILDIN_DEF(getpartyleader,"i?"), - BUILDIN_DEF(getguildname,"i"), - BUILDIN_DEF(getguildmaster,"i"), - BUILDIN_DEF(getguildmasterid,"i"), - BUILDIN_DEF(strcharinfo,"i"), - BUILDIN_DEF(strnpcinfo,"i"), - BUILDIN_DEF(getequipid,"i"), - BUILDIN_DEF(getequipname,"i"), - BUILDIN_DEF(getbrokenid,"i"), // [Valaris] - BUILDIN_DEF(repair,"i"), // [Valaris] - BUILDIN_DEF(repairall,""), - BUILDIN_DEF(getequipisequiped,"i"), - BUILDIN_DEF(getequipisenableref,"i"), - BUILDIN_DEF(getequipisidentify,"i"), - BUILDIN_DEF(getequiprefinerycnt,"i"), - BUILDIN_DEF(getequipweaponlv,"i"), - BUILDIN_DEF(getequippercentrefinery,"i"), - BUILDIN_DEF(successrefitem,"i"), - BUILDIN_DEF(failedrefitem,"i"), - BUILDIN_DEF(downrefitem,"i"), - BUILDIN_DEF(statusup,"i"), - BUILDIN_DEF(statusup2,"ii"), - BUILDIN_DEF(bonus,"iv"), - BUILDIN_DEF2(bonus,"bonus2","ivi"), - BUILDIN_DEF2(bonus,"bonus3","ivii"), - BUILDIN_DEF2(bonus,"bonus4","ivvii"), - BUILDIN_DEF2(bonus,"bonus5","ivviii"), - BUILDIN_DEF(autobonus,"sii??"), - BUILDIN_DEF(autobonus2,"sii??"), - BUILDIN_DEF(autobonus3,"siiv?"), - BUILDIN_DEF(skill,"vi?"), - BUILDIN_DEF(addtoskill,"vi?"), // [Valaris] - BUILDIN_DEF(guildskill,"vi"), - BUILDIN_DEF(getskilllv,"v"), - BUILDIN_DEF(getgdskilllv,"iv"), - BUILDIN_DEF(basicskillcheck,""), - BUILDIN_DEF(getgmlevel,""), - BUILDIN_DEF(getgroupid,""), - BUILDIN_DEF(end,""), - BUILDIN_DEF(checkoption,"i"), - BUILDIN_DEF(setoption,"i?"), - BUILDIN_DEF(setcart,"?"), - BUILDIN_DEF(checkcart,""), - BUILDIN_DEF(setfalcon,"?"), - BUILDIN_DEF(checkfalcon,""), - BUILDIN_DEF(setriding,"?"), - BUILDIN_DEF(checkriding,""), - BUILDIN_DEF(checkwug,""), - BUILDIN_DEF(checkmadogear,""), - BUILDIN_DEF(setmadogear,"?"), - BUILDIN_DEF2(savepoint,"save","sii"), - BUILDIN_DEF(savepoint,"sii"), - BUILDIN_DEF(gettimetick,"i"), - BUILDIN_DEF(gettime,"i"), - BUILDIN_DEF(gettimestr,"si"), - BUILDIN_DEF(openstorage,""), - BUILDIN_DEF(guildopenstorage,""), - BUILDIN_DEF(itemskill,"vi"), - BUILDIN_DEF(produce,"i"), - BUILDIN_DEF(cooking,"i"), - BUILDIN_DEF(monster,"siisii???"), - BUILDIN_DEF(getmobdrops,"i"), - BUILDIN_DEF(areamonster,"siiiisii???"), - BUILDIN_DEF(killmonster,"ss?"), - BUILDIN_DEF(killmonsterall,"s?"), - BUILDIN_DEF(clone,"siisi????"), - BUILDIN_DEF(doevent,"s"), - BUILDIN_DEF(donpcevent,"s"), - BUILDIN_DEF(cmdothernpc,"ss"), - BUILDIN_DEF(addtimer,"is"), - BUILDIN_DEF(deltimer,"s"), - BUILDIN_DEF(addtimercount,"si"), - BUILDIN_DEF(initnpctimer,"??"), - BUILDIN_DEF(stopnpctimer,"??"), - BUILDIN_DEF(startnpctimer,"??"), - BUILDIN_DEF(setnpctimer,"i?"), - BUILDIN_DEF(getnpctimer,"i?"), - BUILDIN_DEF(attachnpctimer,"?"), // attached the player id to the npc timer [Celest] - BUILDIN_DEF(detachnpctimer,"?"), // detached the player id from the npc timer [Celest] - BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex] - BUILDIN_DEF(announce,"si?????"), - BUILDIN_DEF(mapannounce,"ssi?????"), - BUILDIN_DEF(areaannounce,"siiiisi?????"), - BUILDIN_DEF(getusers,"i"), - BUILDIN_DEF(getmapguildusers,"si"), - BUILDIN_DEF(getmapusers,"s"), - BUILDIN_DEF(getareausers,"siiii"), - BUILDIN_DEF(getareadropitem,"siiiiv"), - BUILDIN_DEF(enablenpc,"s"), - BUILDIN_DEF(disablenpc,"s"), - BUILDIN_DEF(hideoffnpc,"s"), - BUILDIN_DEF(hideonnpc,"s"), - BUILDIN_DEF(sc_start,"iii?"), - BUILDIN_DEF(sc_start2,"iiii?"), - BUILDIN_DEF(sc_start4,"iiiiii?"), - BUILDIN_DEF(sc_end,"i?"), - BUILDIN_DEF(getstatus, "i?"), - BUILDIN_DEF(getscrate,"ii?"), - BUILDIN_DEF(debugmes,"s"), - BUILDIN_DEF2(catchpet,"pet","i"), - BUILDIN_DEF2(birthpet,"bpet",""), - BUILDIN_DEF(resetlvl,"i"), - BUILDIN_DEF(resetstatus,""), - BUILDIN_DEF(resetskill,""), - BUILDIN_DEF(skillpointcount,""), - BUILDIN_DEF(changebase,"i?"), - BUILDIN_DEF(changesex,""), - BUILDIN_DEF(waitingroom,"si?????"), - BUILDIN_DEF(delwaitingroom,"?"), - BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"), - BUILDIN_DEF(enablewaitingroomevent,"?"), - BUILDIN_DEF(disablewaitingroomevent,"?"), - BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT - BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT - BUILDIN_DEF(getwaitingroomstate,"i?"), - BUILDIN_DEF(warpwaitingpc,"sii?"), - BUILDIN_DEF(attachrid,"i"), - BUILDIN_DEF(detachrid,""), - BUILDIN_DEF(isloggedin,"i?"), - BUILDIN_DEF(setmapflagnosave,"ssii"), - BUILDIN_DEF(getmapflag,"si"), - BUILDIN_DEF(setmapflag,"si?"), - BUILDIN_DEF(removemapflag,"si?"), - BUILDIN_DEF(pvpon,"s"), - BUILDIN_DEF(pvpoff,"s"), - BUILDIN_DEF(gvgon,"s"), - BUILDIN_DEF(gvgoff,"s"), - BUILDIN_DEF(emotion,"i??"), - BUILDIN_DEF(maprespawnguildid,"sii"), - BUILDIN_DEF(agitstart,""), // - BUILDIN_DEF(agitend,""), - BUILDIN_DEF(agitcheck,""), // - BUILDIN_DEF(flagemblem,"i"), // Flag Emblem - BUILDIN_DEF(getcastlename,"s"), - BUILDIN_DEF(getcastledata,"si"), - BUILDIN_DEF(setcastledata,"sii"), - BUILDIN_DEF(requestguildinfo,"i?"), - BUILDIN_DEF(getequipcardcnt,"i"), - BUILDIN_DEF(successremovecards,"i"), - BUILDIN_DEF(failedremovecards,"ii"), - BUILDIN_DEF(marriage,"s"), - BUILDIN_DEF2(wedding_effect,"wedding",""), - BUILDIN_DEF(divorce,""), - BUILDIN_DEF(ispartneron,""), - BUILDIN_DEF(getpartnerid,""), - BUILDIN_DEF(getchildid,""), - BUILDIN_DEF(getmotherid,""), - BUILDIN_DEF(getfatherid,""), - BUILDIN_DEF(warppartner,"sii"), - BUILDIN_DEF(getitemname,"v"), - BUILDIN_DEF(getitemslots,"i"), - BUILDIN_DEF(makepet,"i"), - BUILDIN_DEF(getexp,"ii"), - BUILDIN_DEF(getinventorylist,""), - BUILDIN_DEF(getskilllist,""), - BUILDIN_DEF(clearitem,""), - BUILDIN_DEF(classchange,"ii"), - BUILDIN_DEF(misceffect,"i"), - BUILDIN_DEF(playBGM,"s"), - BUILDIN_DEF(playBGMall,"s?????"), - BUILDIN_DEF(soundeffect,"si"), - BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster] - BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris] - BUILDIN_DEF(guardian,"siisi??"), // summon guardians - BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris] - BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris] - BUILDIN_DEF(petrecovery,"ii"), // [Valaris] - BUILDIN_DEF(petloot,"i"), // [Valaris] - BUILDIN_DEF(petheal,"iiii"), // [Valaris] - BUILDIN_DEF(petskillattack,"viii"), // [Skotlex] - BUILDIN_DEF(petskillattack2,"viiii"), // [Valaris] - BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex] - BUILDIN_DEF(skilleffect,"vi"), // skill effect [Celest] - BUILDIN_DEF(npcskilleffect,"viii"), // npc skill effect [Valaris] - BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris] - BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris] - BUILDIN_DEF(nude,""), // nude command [Valaris] - BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT - BUILDIN_DEF(atcommand,"s"), // [MouseJstr] - BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr] - BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr] - BUILDIN_DEF(message,"ss"), // [MouseJstr] - BUILDIN_DEF(npctalk,"s"), // [Valaris] - BUILDIN_DEF(mobcount,"ss"), - BUILDIN_DEF(getlook,"i"), - BUILDIN_DEF(getsavepoint,"i"), - BUILDIN_DEF(npcspeed,"i"), // [Valaris] - BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] - BUILDIN_DEF(npcstop,""), // [Valaris] - BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] - BUILDIN_DEF(checkoption1,"i"), - BUILDIN_DEF(checkoption2,"i"), - BUILDIN_DEF(guildgetexp,"i"), - BUILDIN_DEF(guildchangegm,"is"), - BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus] - BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest] - BUILDIN_DEF(isnight,""), // check whether it is night time [Celest] - BUILDIN_DEF(isday,""), // check whether it is day time [Celest] - BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest] - BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest] - BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus] - BUILDIN_DEF(getrefine,""), // returns the refined number of the current item, or an item with index specified [celest] - BUILDIN_DEF(night,""), // sets the server to night time - BUILDIN_DEF(day,""), // sets the server to day time +bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st)) { + int n = add_str(name), i = 0; + + if( str_data[n].type == C_FUNC ) { + str_data[n].func = func; + i = str_data[n].val; + if( args ) { + int slen = strlen(args); + if( script->buildin[i] ) { + aFree(script->buildin[i]); + } + CREATE(script->buildin[i], char, slen + 1); + safestrncpy(script->buildin[i], args, slen + 1); + } else { + if( script->buildin[i] ) + aFree(script->buildin[i]); + script->buildin[i] = NULL; + } + + } else { + i = script->buildin_count; + str_data[n].type = C_FUNC; + str_data[n].val = i; + str_data[n].func = func; + + RECREATE(script->buildin, char *, ++script->buildin_count); + + /* we only store the arguments, its the only thing used out of this */ + if( args != NULL ) { + int slen = strlen(args); + CREATE(script->buildin[i], char, slen + 1); + safestrncpy(script->buildin[i], args, slen + 1); + } else + script->buildin[i] = NULL; + } + + return true; +} + +void script_parse_builtin(void) { + struct script_function BUILDIN[] = { + // NPC interaction + BUILDIN_DEF(mes,"s*"), + BUILDIN_DEF(next,""), + BUILDIN_DEF(close,""), + BUILDIN_DEF(close2,""), + BUILDIN_DEF(menu,"sl*"), + BUILDIN_DEF(select,"s*"), //for future jA script compatibility + BUILDIN_DEF(prompt,"s*"), + // + BUILDIN_DEF(goto,"l"), + BUILDIN_DEF(callsub,"l*"), + BUILDIN_DEF(callfunc,"s*"), + BUILDIN_DEF(return,"?"), + BUILDIN_DEF(getarg,"i?"), + BUILDIN_DEF(jobchange,"i?"), + BUILDIN_DEF(jobname,"i"), + BUILDIN_DEF(input,"r??"), + BUILDIN_DEF(warp,"sii"), + BUILDIN_DEF(areawarp,"siiiisii??"), + BUILDIN_DEF(warpchar,"siii"), // [LuzZza] + BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X] + BUILDIN_DEF(warpguild,"siii"), // [Fredzilla] + BUILDIN_DEF(setlook,"ii"), + BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it + BUILDIN_DEF(set,"rv"), + BUILDIN_DEF(setarray,"rv*"), + BUILDIN_DEF(cleararray,"rvi"), + BUILDIN_DEF(copyarray,"rri"), + BUILDIN_DEF(getarraysize,"r"), + BUILDIN_DEF(deletearray,"r?"), + BUILDIN_DEF(getelementofarray,"ri"), + BUILDIN_DEF(getitem,"vi?"), + BUILDIN_DEF(rentitem,"vi"), + BUILDIN_DEF(getitem2,"viiiiiiii?"), + BUILDIN_DEF(getnameditem,"vv"), + BUILDIN_DEF2(grouprandomitem,"groupranditem","i"), + BUILDIN_DEF(makeitem,"visii"), + BUILDIN_DEF(delitem,"vi?"), + BUILDIN_DEF(delitem2,"viiiiiiii?"), + BUILDIN_DEF2(enableitemuse,"enable_items",""), + BUILDIN_DEF2(disableitemuse,"disable_items",""), + BUILDIN_DEF(cutin,"si"), + BUILDIN_DEF(viewpoint,"iiiii"), + BUILDIN_DEF(heal,"ii"), + BUILDIN_DEF(itemheal,"ii"), + BUILDIN_DEF(percentheal,"ii"), + BUILDIN_DEF(rand,"i?"), + BUILDIN_DEF(countitem,"v"), + BUILDIN_DEF(countitem2,"viiiiiii"), + BUILDIN_DEF(checkweight,"vi*"), + BUILDIN_DEF(checkweight2,"rr"), + BUILDIN_DEF(readparam,"i?"), + BUILDIN_DEF(getcharid,"i?"), + BUILDIN_DEF(getnpcid,"i?"), + BUILDIN_DEF(getpartyname,"i"), + BUILDIN_DEF(getpartymember,"i?"), + BUILDIN_DEF(getpartyleader,"i?"), + BUILDIN_DEF(getguildname,"i"), + BUILDIN_DEF(getguildmaster,"i"), + BUILDIN_DEF(getguildmasterid,"i"), + BUILDIN_DEF(strcharinfo,"i"), + BUILDIN_DEF(strnpcinfo,"i"), + BUILDIN_DEF(getequipid,"i"), + BUILDIN_DEF(getequipname,"i"), + BUILDIN_DEF(getbrokenid,"i"), // [Valaris] + BUILDIN_DEF(repair,"i"), // [Valaris] + BUILDIN_DEF(repairall,""), + BUILDIN_DEF(getequipisequiped,"i"), + BUILDIN_DEF(getequipisenableref,"i"), + BUILDIN_DEF(getequipisidentify,"i"), + BUILDIN_DEF(getequiprefinerycnt,"i"), + BUILDIN_DEF(getequipweaponlv,"i"), + BUILDIN_DEF(getequippercentrefinery,"i"), + BUILDIN_DEF(successrefitem,"i"), + BUILDIN_DEF(failedrefitem,"i"), + BUILDIN_DEF(downrefitem,"i"), + BUILDIN_DEF(statusup,"i"), + BUILDIN_DEF(statusup2,"ii"), + BUILDIN_DEF(bonus,"iv"), + BUILDIN_DEF2(bonus,"bonus2","ivi"), + BUILDIN_DEF2(bonus,"bonus3","ivii"), + BUILDIN_DEF2(bonus,"bonus4","ivvii"), + BUILDIN_DEF2(bonus,"bonus5","ivviii"), + BUILDIN_DEF(autobonus,"sii??"), + BUILDIN_DEF(autobonus2,"sii??"), + BUILDIN_DEF(autobonus3,"siiv?"), + BUILDIN_DEF(skill,"vi?"), + BUILDIN_DEF(addtoskill,"vi?"), // [Valaris] + BUILDIN_DEF(guildskill,"vi"), + BUILDIN_DEF(getskilllv,"v"), + BUILDIN_DEF(getgdskilllv,"iv"), + BUILDIN_DEF(basicskillcheck,""), + BUILDIN_DEF(getgmlevel,""), + BUILDIN_DEF(getgroupid,""), + BUILDIN_DEF(end,""), + BUILDIN_DEF(checkoption,"i"), + BUILDIN_DEF(setoption,"i?"), + BUILDIN_DEF(setcart,"?"), + BUILDIN_DEF(checkcart,""), + BUILDIN_DEF(setfalcon,"?"), + BUILDIN_DEF(checkfalcon,""), + BUILDIN_DEF(setriding,"?"), + BUILDIN_DEF(checkriding,""), + BUILDIN_DEF(checkwug,""), + BUILDIN_DEF(checkmadogear,""), + BUILDIN_DEF(setmadogear,"?"), + BUILDIN_DEF2(savepoint,"save","sii"), + BUILDIN_DEF(savepoint,"sii"), + BUILDIN_DEF(gettimetick,"i"), + BUILDIN_DEF(gettime,"i"), + BUILDIN_DEF(gettimestr,"si"), + BUILDIN_DEF(openstorage,""), + BUILDIN_DEF(guildopenstorage,""), + BUILDIN_DEF(itemskill,"vi"), + BUILDIN_DEF(produce,"i"), + BUILDIN_DEF(cooking,"i"), + BUILDIN_DEF(monster,"siisii???"), + BUILDIN_DEF(getmobdrops,"i"), + BUILDIN_DEF(areamonster,"siiiisii???"), + BUILDIN_DEF(killmonster,"ss?"), + BUILDIN_DEF(killmonsterall,"s?"), + BUILDIN_DEF(clone,"siisi????"), + BUILDIN_DEF(doevent,"s"), + BUILDIN_DEF(donpcevent,"s"), + BUILDIN_DEF(cmdothernpc,"ss"), + BUILDIN_DEF(addtimer,"is"), + BUILDIN_DEF(deltimer,"s"), + BUILDIN_DEF(addtimercount,"si"), + BUILDIN_DEF(initnpctimer,"??"), + BUILDIN_DEF(stopnpctimer,"??"), + BUILDIN_DEF(startnpctimer,"??"), + BUILDIN_DEF(setnpctimer,"i?"), + BUILDIN_DEF(getnpctimer,"i?"), + BUILDIN_DEF(attachnpctimer,"?"), // attached the player id to the npc timer [Celest] + BUILDIN_DEF(detachnpctimer,"?"), // detached the player id from the npc timer [Celest] + BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex] + BUILDIN_DEF(announce,"si?????"), + BUILDIN_DEF(mapannounce,"ssi?????"), + BUILDIN_DEF(areaannounce,"siiiisi?????"), + BUILDIN_DEF(getusers,"i"), + BUILDIN_DEF(getmapguildusers,"si"), + BUILDIN_DEF(getmapusers,"s"), + BUILDIN_DEF(getareausers,"siiii"), + BUILDIN_DEF(getareadropitem,"siiiiv"), + BUILDIN_DEF(enablenpc,"s"), + BUILDIN_DEF(disablenpc,"s"), + BUILDIN_DEF(hideoffnpc,"s"), + BUILDIN_DEF(hideonnpc,"s"), + BUILDIN_DEF(sc_start,"iii?"), + BUILDIN_DEF(sc_start2,"iiii?"), + BUILDIN_DEF(sc_start4,"iiiiii?"), + BUILDIN_DEF(sc_end,"i?"), + BUILDIN_DEF(getstatus, "i?"), + BUILDIN_DEF(getscrate,"ii?"), + BUILDIN_DEF(debugmes,"s"), + BUILDIN_DEF2(catchpet,"pet","i"), + BUILDIN_DEF2(birthpet,"bpet",""), + BUILDIN_DEF(resetlvl,"i"), + BUILDIN_DEF(resetstatus,""), + BUILDIN_DEF(resetskill,""), + BUILDIN_DEF(skillpointcount,""), + BUILDIN_DEF(changebase,"i?"), + BUILDIN_DEF(changesex,""), + BUILDIN_DEF(waitingroom,"si?????"), + BUILDIN_DEF(delwaitingroom,"?"), + BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"), + BUILDIN_DEF(enablewaitingroomevent,"?"), + BUILDIN_DEF(disablewaitingroomevent,"?"), + BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT + BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT + BUILDIN_DEF(getwaitingroomstate,"i?"), + BUILDIN_DEF(warpwaitingpc,"sii?"), + BUILDIN_DEF(attachrid,"i"), + BUILDIN_DEF(detachrid,""), + BUILDIN_DEF(isloggedin,"i?"), + BUILDIN_DEF(setmapflagnosave,"ssii"), + BUILDIN_DEF(getmapflag,"si"), + BUILDIN_DEF(setmapflag,"si?"), + BUILDIN_DEF(removemapflag,"si?"), + BUILDIN_DEF(pvpon,"s"), + BUILDIN_DEF(pvpoff,"s"), + BUILDIN_DEF(gvgon,"s"), + BUILDIN_DEF(gvgoff,"s"), + BUILDIN_DEF(emotion,"i??"), + BUILDIN_DEF(maprespawnguildid,"sii"), + BUILDIN_DEF(agitstart,""), // + BUILDIN_DEF(agitend,""), + BUILDIN_DEF(agitcheck,""), // + BUILDIN_DEF(flagemblem,"i"), // Flag Emblem + BUILDIN_DEF(getcastlename,"s"), + BUILDIN_DEF(getcastledata,"si"), + BUILDIN_DEF(setcastledata,"sii"), + BUILDIN_DEF(requestguildinfo,"i?"), + BUILDIN_DEF(getequipcardcnt,"i"), + BUILDIN_DEF(successremovecards,"i"), + BUILDIN_DEF(failedremovecards,"ii"), + BUILDIN_DEF(marriage,"s"), + BUILDIN_DEF2(wedding_effect,"wedding",""), + BUILDIN_DEF(divorce,""), + BUILDIN_DEF(ispartneron,""), + BUILDIN_DEF(getpartnerid,""), + BUILDIN_DEF(getchildid,""), + BUILDIN_DEF(getmotherid,""), + BUILDIN_DEF(getfatherid,""), + BUILDIN_DEF(warppartner,"sii"), + BUILDIN_DEF(getitemname,"v"), + BUILDIN_DEF(getitemslots,"i"), + BUILDIN_DEF(makepet,"i"), + BUILDIN_DEF(getexp,"ii"), + BUILDIN_DEF(getinventorylist,""), + BUILDIN_DEF(getskilllist,""), + BUILDIN_DEF(clearitem,""), + BUILDIN_DEF(classchange,"ii"), + BUILDIN_DEF(misceffect,"i"), + BUILDIN_DEF(playBGM,"s"), + BUILDIN_DEF(playBGMall,"s?????"), + BUILDIN_DEF(soundeffect,"si"), + BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster] + BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris] + BUILDIN_DEF(guardian,"siisi??"), // summon guardians + BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris] + BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris] + BUILDIN_DEF(petrecovery,"ii"), // [Valaris] + BUILDIN_DEF(petloot,"i"), // [Valaris] + BUILDIN_DEF(petheal,"iiii"), // [Valaris] + BUILDIN_DEF(petskillattack,"viii"), // [Skotlex] + BUILDIN_DEF(petskillattack2,"viiii"), // [Valaris] + BUILDIN_DEF(petskillsupport,"viiii"), // [Skotlex] + BUILDIN_DEF(skilleffect,"vi"), // skill effect [Celest] + BUILDIN_DEF(npcskilleffect,"viii"), // npc skill effect [Valaris] + BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris] + BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris] + BUILDIN_DEF(nude,""), // nude command [Valaris] + BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT + BUILDIN_DEF(atcommand,"s"), // [MouseJstr] + BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr] + BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr] + BUILDIN_DEF(message,"ss"), // [MouseJstr] + BUILDIN_DEF(npctalk,"s"), // [Valaris] + BUILDIN_DEF(mobcount,"ss"), + BUILDIN_DEF(getlook,"i"), + BUILDIN_DEF(getsavepoint,"i"), + BUILDIN_DEF(npcspeed,"i"), // [Valaris] + BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] + BUILDIN_DEF(npcstop,""), // [Valaris] + BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] + BUILDIN_DEF(checkoption1,"i"), + BUILDIN_DEF(checkoption2,"i"), + BUILDIN_DEF(guildgetexp,"i"), + BUILDIN_DEF(guildchangegm,"is"), + BUILDIN_DEF(logmes,"s"), //this command actls as MES but rints info into LOG file either SQL/TXT [Lupus] + BUILDIN_DEF(summon,"si??"), // summons a slave monster [Celest] + BUILDIN_DEF(isnight,""), // check whether it is night time [Celest] + BUILDIN_DEF(isday,""), // check whether it is day time [Celest] + BUILDIN_DEF(isequipped,"i*"), // check whether another item/card has been equipped [Celest] + BUILDIN_DEF(isequippedcnt,"i*"), // check how many items/cards are being equipped [Celest] + BUILDIN_DEF(cardscnt,"i*"), // check how many items/cards are being equipped in the same arm [Lupus] + BUILDIN_DEF(getrefine,""), // returns the refined number of the current item, or an item with index specified [celest] + BUILDIN_DEF(night,""), // sets the server to night time + BUILDIN_DEF(day,""), // sets the server to day time #ifdef PCRE_SUPPORT - BUILDIN_DEF(defpattern,"iss"), // Define pattern to listen for [MouseJstr] - BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr] - BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr] - BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr] + BUILDIN_DEF(defpattern,"iss"), // Define pattern to listen for [MouseJstr] + BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr] + BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr] + BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr] #endif - BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus] - BUILDIN_DEF(getusersname,""), - BUILDIN_DEF(recovery,""), - BUILDIN_DEF(getpetinfo,"i"), - BUILDIN_DEF(gethominfo,"i"), - BUILDIN_DEF(getmercinfo,"i?"), - BUILDIN_DEF(checkequipedcard,"i"), - BUILDIN_DEF(jump_zero,"il"), //for future jA script compatibility - BUILDIN_DEF(globalmes,"s?"), //end jA addition - BUILDIN_DEF(unequip,"i"), // unequip command [Spectre] - BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris] - BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris] - BUILDIN_DEF(charat,"si"), - BUILDIN_DEF(setchar,"ssi"), - BUILDIN_DEF(insertchar,"ssi"), - BUILDIN_DEF(delchar,"si"), - BUILDIN_DEF(strtoupper,"s"), - BUILDIN_DEF(strtolower,"s"), - BUILDIN_DEF(charisupper, "si"), - BUILDIN_DEF(charislower, "si"), - BUILDIN_DEF(substr,"sii"), - BUILDIN_DEF(explode, "rss"), - BUILDIN_DEF(implode, "r?"), - BUILDIN_DEF(sprintf,"s*"), // [Mirei] - BUILDIN_DEF(sscanf,"ss*"), // [Mirei] - BUILDIN_DEF(strpos,"ss?"), - BUILDIN_DEF(replacestr,"sss??"), - BUILDIN_DEF(countstr,"ss?"), - BUILDIN_DEF(setnpcdisplay,"sv??"), - BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine. - BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info - BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info - BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item - // [zBuffer] List of mathematics commands ---> - BUILDIN_DEF(sqrt,"i"), - BUILDIN_DEF(pow,"ii"), - BUILDIN_DEF(distance,"iiii"), - // <--- [zBuffer] List of mathematics commands - BUILDIN_DEF(md5,"s"), - // [zBuffer] List of dynamic var commands ---> - BUILDIN_DEF(getd,"s"), - BUILDIN_DEF(setd,"sv"), - // <--- [zBuffer] List of dynamic var commands - BUILDIN_DEF(petstat,"i"), - BUILDIN_DEF(callshop,"s?"), // [Skotlex] - BUILDIN_DEF(npcshopitem,"sii*"), // [Lance] - BUILDIN_DEF(npcshopadditem,"sii*"), - BUILDIN_DEF(npcshopdelitem,"si*"), - BUILDIN_DEF(npcshopattach,"s?"), - BUILDIN_DEF(equip,"i"), - BUILDIN_DEF(autoequip,"ii"), - BUILDIN_DEF(setbattleflag,"si"), - BUILDIN_DEF(getbattleflag,"s"), - BUILDIN_DEF(setitemscript,"is?"), //Set NEW item bonus script. Lupus - BUILDIN_DEF(disguise,"i"), //disguise player. Lupus - BUILDIN_DEF(undisguise,""), //undisguise player. Lupus - BUILDIN_DEF(getmonsterinfo,"ii"), //Lupus - BUILDIN_DEF(axtoi,"s"), - BUILDIN_DEF(query_sql,"s*"), - BUILDIN_DEF(query_logsql,"s*"), - BUILDIN_DEF(escape_sql,"v"), - BUILDIN_DEF(atoi,"s"), - // [zBuffer] List of player cont commands ---> - BUILDIN_DEF(rid2name,"i"), - BUILDIN_DEF(pcfollow,"ii"), - BUILDIN_DEF(pcstopfollow,"i"), - BUILDIN_DEF(pcblockmove,"ii"), - // <--- [zBuffer] List of player cont commands - // [zBuffer] List of mob control commands ---> - BUILDIN_DEF(unitwalk,"ii?"), - BUILDIN_DEF(unitkill,"i"), - BUILDIN_DEF(unitwarp,"isii"), - BUILDIN_DEF(unitattack,"iv?"), - BUILDIN_DEF(unitstop,"i"), - BUILDIN_DEF(unittalk,"is"), - BUILDIN_DEF(unitemote,"ii"), - BUILDIN_DEF(unitskilluseid,"ivi?"), // originally by Qamera [Celest] - BUILDIN_DEF(unitskillusepos,"iviii"), // [Celest] -// <--- [zBuffer] List of mob control commands - BUILDIN_DEF(sleep,"i"), - BUILDIN_DEF(sleep2,"i"), - BUILDIN_DEF(awake,"s"), - BUILDIN_DEF(getvariableofnpc,"rs"), - BUILDIN_DEF(warpportal,"iisii"), - BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] - BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), - BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] - BUILDIN_DEF(eaclass,"?"), //[Skotlex] - BUILDIN_DEF(roclass,"i?"), //[Skotlex] - BUILDIN_DEF(checkvending,"?"), - BUILDIN_DEF(checkchatting,"?"), - BUILDIN_DEF(checkidle,"?"), - BUILDIN_DEF(openmail,""), - BUILDIN_DEF(openauction,""), - BUILDIN_DEF(checkcell,"siii"), - BUILDIN_DEF(setcell,"siiiiii"), - BUILDIN_DEF(setwall,"siiiiis"), - BUILDIN_DEF(delwall,"s"), - BUILDIN_DEF(searchitem,"rs"), - BUILDIN_DEF(mercenary_create,"ii"), - BUILDIN_DEF(mercenary_heal,"ii"), - BUILDIN_DEF(mercenary_sc_start,"iii"), - BUILDIN_DEF(mercenary_get_calls,"i"), - BUILDIN_DEF(mercenary_get_faith,"i"), - BUILDIN_DEF(mercenary_set_calls,"ii"), - BUILDIN_DEF(mercenary_set_faith,"ii"), - BUILDIN_DEF(readbook,"ii"), - BUILDIN_DEF(setfont,"i"), - BUILDIN_DEF(areamobuseskill,"siiiiviiiii"), - BUILDIN_DEF(progressbar,"si"), - BUILDIN_DEF(pushpc,"ii"), - BUILDIN_DEF(buyingstore,"i"), - BUILDIN_DEF(searchstores,"ii"), - BUILDIN_DEF(showdigit,"i?"), - // WoE SE - BUILDIN_DEF(agitstart2,""), - BUILDIN_DEF(agitend2,""), - BUILDIN_DEF(agitcheck2,""), - // BattleGround - BUILDIN_DEF(waitingroom2bg,"siiss?"), - BUILDIN_DEF(waitingroom2bg_single,"isiis"), - BUILDIN_DEF(bg_team_setxy,"iii"), - BUILDIN_DEF(bg_warp,"isii"), - BUILDIN_DEF(bg_monster,"isiisi?"), - BUILDIN_DEF(bg_monster_set_team,"ii"), - BUILDIN_DEF(bg_leave,""), - BUILDIN_DEF(bg_destroy,"i"), - BUILDIN_DEF(areapercentheal,"siiiiii"), - BUILDIN_DEF(bg_get_data,"ii"), - BUILDIN_DEF(bg_getareausers,"isiiii"), - BUILDIN_DEF(bg_updatescore,"sii"), - - // Instancing - BUILDIN_DEF(instance_create,"si"), - BUILDIN_DEF(instance_destroy,"?"), - BUILDIN_DEF(instance_attachmap,"si?"), - BUILDIN_DEF(instance_detachmap,"s?"), - BUILDIN_DEF(instance_attach,"i"), - BUILDIN_DEF(instance_id,"?"), - BUILDIN_DEF(instance_set_timeout,"ii?"), - BUILDIN_DEF(instance_init,"i"), - BUILDIN_DEF(instance_announce,"isi?????"), - BUILDIN_DEF(instance_npcname,"s?"), - BUILDIN_DEF(has_instance,"s?"), - BUILDIN_DEF(instance_warpall,"sii?"), - BUILDIN_DEF(instance_check_party,"i???"), - /** - * 3rd-related - **/ - BUILDIN_DEF(makerune,"i"), - BUILDIN_DEF(checkdragon,""),//[Ind] - BUILDIN_DEF(setdragon,"?"),//[Ind] - BUILDIN_DEF(ismounting,""),//[Ind] - BUILDIN_DEF(setmounting,""),//[Ind] - BUILDIN_DEF(checkre,"i"), - /** - * rAthena and beyond! - **/ - BUILDIN_DEF(getargcount,""), - BUILDIN_DEF(getcharip,"?"), - BUILDIN_DEF(is_function,"s"), - BUILDIN_DEF(get_revision,""), - BUILDIN_DEF(freeloop,"i"), - BUILDIN_DEF(getrandgroupitem,"ii"), - BUILDIN_DEF(cleanmap,"s"), - BUILDIN_DEF2(cleanmap,"cleanarea","siiii"), - BUILDIN_DEF(npcskill,"viii"), - BUILDIN_DEF(itemeffect,"v"), - BUILDIN_DEF(delequip,"i"), - /** - * @commands (script based) - **/ - BUILDIN_DEF(bindatcmd, "ss???"), - BUILDIN_DEF(unbindatcmd, "s"), - BUILDIN_DEF(useatcmd, "s"), - - //Quest Log System [Inkfish] - BUILDIN_DEF(setquest, "i"), - BUILDIN_DEF(erasequest, "i"), - BUILDIN_DEF(completequest, "i"), - BUILDIN_DEF(checkquest, "i?"), - BUILDIN_DEF(changequest, "ii"), - BUILDIN_DEF(showevent, "ii"), - {NULL,NULL,NULL}, -}; + BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus] + BUILDIN_DEF(getusersname,""), + BUILDIN_DEF(recovery,""), + BUILDIN_DEF(getpetinfo,"i"), + BUILDIN_DEF(gethominfo,"i"), + BUILDIN_DEF(getmercinfo,"i?"), + BUILDIN_DEF(checkequipedcard,"i"), + BUILDIN_DEF(jump_zero,"il"), //for future jA script compatibility + BUILDIN_DEF(globalmes,"s?"), //end jA addition + BUILDIN_DEF(unequip,"i"), // unequip command [Spectre] + BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris] + BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris] + BUILDIN_DEF(charat,"si"), + BUILDIN_DEF(setchar,"ssi"), + BUILDIN_DEF(insertchar,"ssi"), + BUILDIN_DEF(delchar,"si"), + BUILDIN_DEF(strtoupper,"s"), + BUILDIN_DEF(strtolower,"s"), + BUILDIN_DEF(charisupper, "si"), + BUILDIN_DEF(charislower, "si"), + BUILDIN_DEF(substr,"sii"), + BUILDIN_DEF(explode, "rss"), + BUILDIN_DEF(implode, "r?"), + BUILDIN_DEF(sprintf,"s*"), // [Mirei] + BUILDIN_DEF(sscanf,"ss*"), // [Mirei] + BUILDIN_DEF(strpos,"ss?"), + BUILDIN_DEF(replacestr,"sss??"), + BUILDIN_DEF(countstr,"ss?"), + BUILDIN_DEF(setnpcdisplay,"sv??"), + BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine. + BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info + BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info + BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item + // [zBuffer] List of mathematics commands ---> + BUILDIN_DEF(sqrt,"i"), + BUILDIN_DEF(pow,"ii"), + BUILDIN_DEF(distance,"iiii"), + // <--- [zBuffer] List of mathematics commands + BUILDIN_DEF(md5,"s"), + // [zBuffer] List of dynamic var commands ---> + BUILDIN_DEF(getd,"s"), + BUILDIN_DEF(setd,"sv"), + // <--- [zBuffer] List of dynamic var commands + BUILDIN_DEF(petstat,"i"), + BUILDIN_DEF(callshop,"s?"), // [Skotlex] + BUILDIN_DEF(npcshopitem,"sii*"), // [Lance] + BUILDIN_DEF(npcshopadditem,"sii*"), + BUILDIN_DEF(npcshopdelitem,"si*"), + BUILDIN_DEF(npcshopattach,"s?"), + BUILDIN_DEF(equip,"i"), + BUILDIN_DEF(autoequip,"ii"), + BUILDIN_DEF(setbattleflag,"si"), + BUILDIN_DEF(getbattleflag,"s"), + BUILDIN_DEF(setitemscript,"is?"), //Set NEW item bonus script. Lupus + BUILDIN_DEF(disguise,"i"), //disguise player. Lupus + BUILDIN_DEF(undisguise,""), //undisguise player. Lupus + BUILDIN_DEF(getmonsterinfo,"ii"), //Lupus + BUILDIN_DEF(axtoi,"s"), + BUILDIN_DEF(query_sql,"s*"), + BUILDIN_DEF(query_logsql,"s*"), + BUILDIN_DEF(escape_sql,"v"), + BUILDIN_DEF(atoi,"s"), + // [zBuffer] List of player cont commands ---> + BUILDIN_DEF(rid2name,"i"), + BUILDIN_DEF(pcfollow,"ii"), + BUILDIN_DEF(pcstopfollow,"i"), + BUILDIN_DEF(pcblockmove,"ii"), + // <--- [zBuffer] List of player cont commands + // [zBuffer] List of mob control commands ---> + BUILDIN_DEF(unitwalk,"ii?"), + BUILDIN_DEF(unitkill,"i"), + BUILDIN_DEF(unitwarp,"isii"), + BUILDIN_DEF(unitattack,"iv?"), + BUILDIN_DEF(unitstop,"i"), + BUILDIN_DEF(unittalk,"is"), + BUILDIN_DEF(unitemote,"ii"), + BUILDIN_DEF(unitskilluseid,"ivi?"), // originally by Qamera [Celest] + BUILDIN_DEF(unitskillusepos,"iviii"), // [Celest] + // <--- [zBuffer] List of mob control commands + BUILDIN_DEF(sleep,"i"), + BUILDIN_DEF(sleep2,"i"), + BUILDIN_DEF(awake,"s"), + BUILDIN_DEF(getvariableofnpc,"rs"), + BUILDIN_DEF(warpportal,"iisii"), + BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] + BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), + BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] + BUILDIN_DEF(eaclass,"?"), //[Skotlex] + BUILDIN_DEF(roclass,"i?"), //[Skotlex] + BUILDIN_DEF(checkvending,"?"), + BUILDIN_DEF(checkchatting,"?"), + BUILDIN_DEF(checkidle,"?"), + BUILDIN_DEF(openmail,""), + BUILDIN_DEF(openauction,""), + BUILDIN_DEF(checkcell,"siii"), + BUILDIN_DEF(setcell,"siiiiii"), + BUILDIN_DEF(setwall,"siiiiis"), + BUILDIN_DEF(delwall,"s"), + BUILDIN_DEF(searchitem,"rs"), + BUILDIN_DEF(mercenary_create,"ii"), + BUILDIN_DEF(mercenary_heal,"ii"), + BUILDIN_DEF(mercenary_sc_start,"iii"), + BUILDIN_DEF(mercenary_get_calls,"i"), + BUILDIN_DEF(mercenary_get_faith,"i"), + BUILDIN_DEF(mercenary_set_calls,"ii"), + BUILDIN_DEF(mercenary_set_faith,"ii"), + BUILDIN_DEF(readbook,"ii"), + BUILDIN_DEF(setfont,"i"), + BUILDIN_DEF(areamobuseskill,"siiiiviiiii"), + BUILDIN_DEF(progressbar,"si"), + BUILDIN_DEF(pushpc,"ii"), + BUILDIN_DEF(buyingstore,"i"), + BUILDIN_DEF(searchstores,"ii"), + BUILDIN_DEF(showdigit,"i?"), + // WoE SE + BUILDIN_DEF(agitstart2,""), + BUILDIN_DEF(agitend2,""), + BUILDIN_DEF(agitcheck2,""), + // BattleGround + BUILDIN_DEF(waitingroom2bg,"siiss?"), + BUILDIN_DEF(waitingroom2bg_single,"isiis"), + BUILDIN_DEF(bg_team_setxy,"iii"), + BUILDIN_DEF(bg_warp,"isii"), + BUILDIN_DEF(bg_monster,"isiisi?"), + BUILDIN_DEF(bg_monster_set_team,"ii"), + BUILDIN_DEF(bg_leave,""), + BUILDIN_DEF(bg_destroy,"i"), + BUILDIN_DEF(areapercentheal,"siiiiii"), + BUILDIN_DEF(bg_get_data,"ii"), + BUILDIN_DEF(bg_getareausers,"isiiii"), + BUILDIN_DEF(bg_updatescore,"sii"), + + // Instancing + BUILDIN_DEF(instance_create,"si"), + BUILDIN_DEF(instance_destroy,"?"), + BUILDIN_DEF(instance_attachmap,"si?"), + BUILDIN_DEF(instance_detachmap,"s?"), + BUILDIN_DEF(instance_attach,"i"), + BUILDIN_DEF(instance_id,"?"), + BUILDIN_DEF(instance_set_timeout,"ii?"), + BUILDIN_DEF(instance_init,"i"), + BUILDIN_DEF(instance_announce,"isi?????"), + BUILDIN_DEF(instance_npcname,"s?"), + BUILDIN_DEF(has_instance,"s?"), + BUILDIN_DEF(instance_warpall,"sii?"), + BUILDIN_DEF(instance_check_party,"i???"), + /** + * 3rd-related + **/ + BUILDIN_DEF(makerune,"i"), + BUILDIN_DEF(checkdragon,""),//[Ind] + BUILDIN_DEF(setdragon,"?"),//[Ind] + BUILDIN_DEF(ismounting,""),//[Ind] + BUILDIN_DEF(setmounting,""),//[Ind] + BUILDIN_DEF(checkre,"i"), + /** + * rAthena and beyond! + **/ + BUILDIN_DEF(getargcount,""), + BUILDIN_DEF(getcharip,"?"), + BUILDIN_DEF(is_function,"s"), + BUILDIN_DEF(get_revision,""), + BUILDIN_DEF(freeloop,"i"), + BUILDIN_DEF(getrandgroupitem,"ii"), + BUILDIN_DEF(cleanmap,"s"), + BUILDIN_DEF2(cleanmap,"cleanarea","siiii"), + BUILDIN_DEF(npcskill,"viii"), + BUILDIN_DEF(itemeffect,"v"), + BUILDIN_DEF(delequip,"i"), + /** + * @commands (script based) + **/ + BUILDIN_DEF(bindatcmd, "ss???"), + BUILDIN_DEF(unbindatcmd, "s"), + BUILDIN_DEF(useatcmd, "s"), + + //Quest Log System [Inkfish] + BUILDIN_DEF(setquest, "i"), + BUILDIN_DEF(erasequest, "i"), + BUILDIN_DEF(completequest, "i"), + BUILDIN_DEF(checkquest, "i?"), + BUILDIN_DEF(changequest, "ii"), + BUILDIN_DEF(showevent, "ii"), + }; + int i,n, len = ARRAYLENGTH(BUILDIN), start = script->buildin_count; + char* p; + RECREATE(script->buildin, char *, start + len); + for( i = 0; i < len; i++ ) { + // arg must follow the pattern: (v|s|i|r|l)*\?*\*? + // 'v' - value (either string or int or reference) + // 's' - string + // 'i' - int + // 'r' - reference (of a variable) + // 'l' - label + // '?' - one optional parameter + // '*' - unknown number of optional parameters + p = BUILDIN[i].arg; + while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p; + while( *p == '?' ) ++p; + if( *p == '*' ) ++p; + if( *p != 0 ){ + ShowWarning("script_parse_builtin: ignoring function \"%s\" with invalid arg \"%s\".\n", BUILDIN[i].name, BUILDIN[i].arg); + } else if( *skip_word(BUILDIN[i].name) != 0 ){ + ShowWarning("script_parse_builtin: ignoring function with invalid name \"%s\" (must be a word).\n", BUILDIN[i].name); + } else { + int slen = strlen(BUILDIN[i].arg), offset = start + i; + n = add_str(BUILDIN[i].name); + + if (!strcmp(BUILDIN[i].name, "set")) buildin_set_ref = n; + else if (!strcmp(BUILDIN[i].name, "callsub")) buildin_callsub_ref = n; + else if (!strcmp(BUILDIN[i].name, "callfunc")) buildin_callfunc_ref = n; + else if (!strcmp(BUILDIN[i].name, "getelementofarray") ) buildin_getelementofarray_ref = n; + + if( str_data[n].func && str_data[n].func != BUILDIN[i].func ) + continue;/* something replaced it, skip. */ + + str_data[n].type = C_FUNC; + str_data[n].val = offset; + str_data[n].func = BUILDIN[i].func; + + /* we only store the arguments, its the only thing used out of this */ + if( slen ) { + CREATE(script->buildin[offset], char, slen + 1); + safestrncpy(script->buildin[offset], BUILDIN[i].arg, slen + 1); + } else + script->buildin[offset] = NULL; + + script->buildin_count++; + + } + } +} + +void script_defaults(void) { + script = &script_s; + + script->buildin_count = 0; + script->buildin = NULL; + + script->init = do_init_script; + script->final = do_final_script; + + script->parse_builtin = script_parse_builtin; + script->addScript = script_hp_add; + script->conv_num = conv_num; + script->conv_str = conv_str; +} diff --git a/src/map/script.h b/src/map/script.h index 4a12a3f7f..a0d282bfe 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -159,8 +159,6 @@ void run_script_sub(struct script_code *rootscript,int pos,int rid,int oid, char void run_script(struct script_code*,int,int,int); int set_var(struct map_session_data *sd, char *name, void *val); -int conv_num(struct script_state *st,struct script_data *data); -const char* conv_str(struct script_state *st,struct script_data *data); int run_script_timer(int tid, unsigned int tick, int id, intptr_t data); void run_script_main(struct script_state *st); @@ -182,13 +180,134 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache); int script_config_read(char *cfgName); -int do_init_script(void); -int do_final_script(void); int add_str(const char* p); const char* get_str(int id); int script_reload(void); // @commands (script based) -void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref); +void setd_sub(struct script_state *st, struct map_session_data *sd, const char *varname, int elem, void *value, struct DBMap **ref); + +/////////////////////////////////////////////////////////////////////////////// +//## TODO possible enhancements: [FlavioJS] +// - 'callfunc' supporting labels in the current npc "::LabelName" +// - 'callfunc' supporting labels in other npcs "NpcName::LabelName" +// - 'function FuncName;' function declarations reverting to global functions +// if local label isn't found +// - join callfunc and callsub's functionality +// - remove dynamic allocation in add_word() +// - remove GETVALUE / SETVALUE +// - clean up the set_reg / set_val / setd_sub mess +// - detect invalid label references at parse-time + +// +// struct script_state* st; +// + +/// Returns the script_data at the target index +#define script_getdata(st,i) ( &((st)->stack->stack_data[(st)->start + (i)]) ) +/// Returns if the stack contains data at the target index +#define script_hasdata(st,i) ( (st)->end > (st)->start + (i) ) +/// Returns the index of the last data in the stack +#define script_lastdata(st) ( (st)->end - (st)->start - 1 ) +/// Pushes an int into the stack +#define script_pushint(st,val) push_val((st)->stack, C_INT, (val)) +/// Pushes a string into the stack (script engine frees it automatically) +#define script_pushstr(st,val) push_str((st)->stack, C_STR, (val)) +/// Pushes a copy of a string into the stack +#define script_pushstrcopy(st,val) push_str((st)->stack, C_STR, aStrdup(val)) +/// Pushes a constant string into the stack (must never change or be freed) +#define script_pushconststr(st,val) push_str((st)->stack, C_CONSTSTR, (val)) +/// Pushes a nil into the stack +#define script_pushnil(st) push_val((st)->stack, C_NOP, 0) +/// Pushes a copy of the data in the target index +#define script_pushcopy(st,i) push_copy((st)->stack, (st)->start + (i)) + +#define script_isstring(st,i) data_isstring(script_getdata(st,i)) +#define script_isint(st,i) data_isint(script_getdata(st,i)) + +#define script_getnum(st,val) script->conv_num(st, script_getdata(st,val)) +#define script_getstr(st,val) script->conv_str(st, script_getdata(st,val)) +#define script_getref(st,val) ( script_getdata(st,val)->ref ) + +// Note: "top" functions/defines use indexes relative to the top of the stack +// -1 is the index of the data at the top + +/// Returns the script_data at the target index relative to the top of the stack +#define script_getdatatop(st,i) ( &((st)->stack->stack_data[(st)->stack->sp + (i)]) ) +/// Pushes a copy of the data in the target index relative to the top of the stack +#define script_pushcopytop(st,i) push_copy((st)->stack, (st)->stack->sp + (i)) +/// Removes the range of values [start,end[ relative to the top of the stack +#define script_removetop(st,start,end) ( pop_stack((st), ((st)->stack->sp + (start)), (st)->stack->sp + (end)) ) + +// +// struct script_data* data; +// + +/// Returns if the script data is a string +#define data_isstring(data) ( (data)->type == C_STR || (data)->type == C_CONSTSTR ) +/// Returns if the script data is an int +#define data_isint(data) ( (data)->type == C_INT ) +/// Returns if the script data is a reference +#define data_isreference(data) ( (data)->type == C_NAME ) +/// Returns if the script data is a label +#define data_islabel(data) ( (data)->type == C_POS ) +/// Returns if the script data is an internal script function label +#define data_isfunclabel(data) ( (data)->type == C_USERFUNC_POS ) + +/// Returns if this is a reference to a constant +#define reference_toconstant(data) ( str_data[reference_getid(data)].type == C_INT ) +/// Returns if this a reference to a param +#define reference_toparam(data) ( str_data[reference_getid(data)].type == C_PARAM ) +/// Returns if this a reference to a variable +//##TODO confirm it's C_NAME [FlavioJS] +#define reference_tovariable(data) ( str_data[reference_getid(data)].type == C_NAME ) +/// Returns the unique id of the reference (id and index) +#define reference_getuid(data) ( (data)->u.num ) +/// Returns the id of the reference +#define reference_getid(data) ( (int32)(reference_getuid(data) & 0x00ffffff) ) +/// Returns the array index of the reference +#define reference_getindex(data) ( (int32)(((uint32)(reference_getuid(data) & 0xff000000)) >> 24) ) +/// Returns the name of the reference +#define reference_getname(data) ( str_buf + str_data[reference_getid(data)].str ) +/// Returns the linked list of uid-value pairs of the reference (can be NULL) +#define reference_getref(data) ( (data)->ref ) +/// Returns the value of the constant +#define reference_getconstant(data) ( str_data[reference_getid(data)].val ) +/// Returns the type of param +#define reference_getparamtype(data) ( str_data[reference_getid(data)].val ) + +/// Composes the uid of a reference from the id and the index +#define reference_uid(id,idx) ( (int32)((((uint32)(id)) & 0x00ffffff) | (((uint32)(idx)) << 24)) ) + +#define not_server_variable(prefix) ( (prefix) != '$' && (prefix) != '.' && (prefix) != '\'') +#define not_array_variable(prefix) ( (prefix) != '$' && (prefix) != '@' && (prefix) != '.' && (prefix) != '\'' ) +#define is_string_variable(name) ( (name)[strlen(name) - 1] == '$' ) + +#define BUILDIN(x) bool buildin_ ## x (struct script_state* st) +#define BUILDIN_A(x) buildin_ ## x + +struct script_function { + bool (*func)(struct script_state *st); + char *name; + char *arg; +}; +/* script.c interface (incomplete) */ +struct script_interface { + /* */ + char **buildin; + unsigned int buildin_count; + /* */ + void (*init) (void); + void (*final) (void); + /* */ + void (*parse_builtin) (void); + bool (*addScript) (char *name, char *args, bool (*func)(struct script_state *st)); + int (*conv_num) (struct script_state *st,struct script_data *data); + const char* (*conv_str) (struct script_state *st,struct script_data *data); +} script_s; + +struct script_interface *script; + +void script_defaults(void); #endif /* _SCRIPT_H_ */ diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt new file mode 100644 index 000000000..4e4851bc5 --- /dev/null +++ b/src/plugins/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# setup +# +get_property( CAN_BUILD_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS ) +if( NOT CAN_BUILD_SHARED_LIBS ) + return() +endif() + +# +# sample +# +option( BUILD_PLUGIN_sample "build sample plugin" OFF ) +if( BUILD_PLUGIN_sample ) +message( STATUS "Creating target sample" ) +set( SAMPLE_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/sample.c" + ) +set( LIBRARIES ${GLOBAL_LIBRARIES} ) +set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ) +set( DEFINITIONS ${GLOBAL_DEFINITIONS} ) +set( SOURCE_FILES ${SAMPLE_SOURCES} ) +source_group( sample FILES ${SAMPLE_SOURCES} ) +include_directories( ${INCLUDE_DIRS} ) +add_library( sample SHARED ${SOURCE_FILES} ) +target_link_libraries( sample ${LIBRARIES} ) +set_target_properties( sample PROPERTIES COMPILE_FLAGS "${DEFINITIONS}" ) +set_target_properties( sample PROPERTIES PREFIX "" ) +if( INSTALL_COMPONENT_RUNTIME ) + cpack_add_component( Runtime_sample DESCRIPTION "sample plugin" DISPLAY_NAME "sample" GROUP Runtime ) + install( TARGETS sample + DESTINATION "plugins" + COMPONENT Runtime_sample ) +endif( INSTALL_COMPONENT_RUNTIME ) +set( TARGET_LIST ${TARGET_LIST} sample CACHE INTERNAL "" ) +message( STATUS "Creating target sample - done" ) +endif( BUILD_PLUGIN_sample ) \ No newline at end of file diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in new file mode 100644 index 000000000..71b743dca --- /dev/null +++ b/src/plugins/Makefile.in @@ -0,0 +1,28 @@ + +COMMON_H = ../common/HPMi.h ../common/cbasetypes.h + +PLUGINS = sample + +@SET_MAKE@ + +##################################################################### +.PHONY : all $(PLUGINS) sample clean help + +all: $(PLUGINS) + +sample: sample@DLLEXT@ + +clean: + @echo " CLEAN plugins" + @rm -rf *.o + +help: + @echo "possible targets are $(PLUGINS:%='%') 'all' 'clean' 'help'" + @echo "'sample' - sample plugin" + @echo "'help' - outputs this message" + +##################################################################### + +%@DLLEXT@: %.c $(COMMON_H) + @echo " CC $<" + @@CC@ @DEFS@ @CFLAGS@ @CPPFLAGS@ @LDFLAGS@ @SOFLAGS@ -o ../../plugins/$@ $< \ No newline at end of file diff --git a/src/plugins/sample.c b/src/plugins/sample.c new file mode 100644 index 000000000..8e6b8fc86 --- /dev/null +++ b/src/plugins/sample.c @@ -0,0 +1,74 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Sample Hercules Plugin + +#include +#include +#include "../common/HPMi.h" +#include "../map/script.h" +#include "../map/pc.h" + +HPExport struct hplugin_info pinfo = { + "Sample", // Plugin name + SERVER_TYPE_MAP,// Which server types this plugin works with? + "0.1", // Plugin version + HPM_VERSION, // HPM Version (don't change, macro is automatically updated) +}; +ACMD(sample) {//@sample command - 5 params: const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info + printf("I'm being run! message -> '%s' by %s\n",message,sd->status.name); + return true; +} +BUILDIN(sample) {//script command 'sample(num);' - 1 param: struct script_state* st + int arg = script_getnum(st,2); + ShowInfo("I'm being run! arg -> '%d'\n",arg); + return true; +} +CPCMD(sample) {//console command 'sample' - 1 param: char *line + ShowInfo("I'm being run! arg -> '%s'\n",line?line:"NONE"); +} +struct script_interface *script;/* used by script commands */ +/* run when server starts */ +HPExport void plugin_init (void) { + char *server_type; + char *server_name; + + //get the symbols from the server + server_type = GET_SYMBOL("SERVER_TYPE"); + server_name = GET_SYMBOL("SERVER_NAME"); + + script = GET_SYMBOL("script"); + + if( !(script = GET_SYMBOL("script")) ) { + ShowError("Failed to load script interface var!\n"); + } + + ShowInfo ("Server type is "); + + switch (*server_type) { + case SERVER_TYPE_LOGIN: printf ("Login Server\n"); break; + case SERVER_TYPE_CHAR: printf ("Char Server\n"); break; + case SERVER_TYPE_MAP: printf ("Map Server\n"); break; + } + + ShowInfo ("I'm being run from the '%s' filename\n", server_name); + + if( HPMi->addCommand != NULL ) {//link our '@sample' command + HPMi->addCommand("sample",ACMD_A(sample)); + } + + if( HPMi->addScript != NULL ) {//link our 'sample' script command + HPMi->addScript("sample","i",BUILDIN_A(sample)); + } + + if( HPMi->addCPCommand != NULL ) {//link our 'sample' console command + HPMi->addCPCommand("this:is:a:sample",CPCMD_A(sample)); + } +} +/* run when server is ready (online) */ +HPExport void server_online (void) { + +} +/* run when server is shutting down */ +HPExport void plugin_final (void) { + ShowInfo ("%s says ~Bye world\n",pinfo.name); +} \ No newline at end of file diff --git a/vcproj-10/char-server.vcxproj b/vcproj-10/char-server.vcxproj index 9791cefb7..e07954292 100644 --- a/vcproj-10/char-server.vcxproj +++ b/vcproj-10/char-server.vcxproj @@ -142,6 +142,8 @@ + + @@ -183,6 +185,7 @@ + diff --git a/vcproj-10/char-server.vcxproj.filters b/vcproj-10/char-server.vcxproj.filters index 0c90c0ab8..13788df95 100644 --- a/vcproj-10/char-server.vcxproj.filters +++ b/vcproj-10/char-server.vcxproj.filters @@ -13,6 +13,9 @@ common + + common + common @@ -129,6 +132,12 @@ common + + common + + + common + common diff --git a/vcproj-10/login-server.vcxproj b/vcproj-10/login-server.vcxproj index 4e26c500f..20c780902 100644 --- a/vcproj-10/login-server.vcxproj +++ b/vcproj-10/login-server.vcxproj @@ -152,6 +152,8 @@ + + @@ -183,6 +185,7 @@ + diff --git a/vcproj-10/login-server.vcxproj.filters b/vcproj-10/login-server.vcxproj.filters index c5345b030..0ce4b8b6e 100644 --- a/vcproj-10/login-server.vcxproj.filters +++ b/vcproj-10/login-server.vcxproj.filters @@ -25,6 +25,9 @@ common + + common + common @@ -114,6 +117,12 @@ common + + common + + + common + common diff --git a/vcproj-10/map-server.vcxproj b/vcproj-10/map-server.vcxproj index 3810095fe..01f97ae0f 100644 --- a/vcproj-10/map-server.vcxproj +++ b/vcproj-10/map-server.vcxproj @@ -141,6 +141,8 @@ + + @@ -218,6 +220,7 @@ + diff --git a/vcproj-10/map-server.vcxproj.filters b/vcproj-10/map-server.vcxproj.filters index 325a62f67..2b04a4211 100644 --- a/vcproj-10/map-server.vcxproj.filters +++ b/vcproj-10/map-server.vcxproj.filters @@ -130,6 +130,9 @@ common + + common + common @@ -336,6 +339,12 @@ common + + common + + + common + common diff --git a/vcproj-12/char-server.vcxproj b/vcproj-12/char-server.vcxproj index d32222162..ab2974805 100644 --- a/vcproj-12/char-server.vcxproj +++ b/vcproj-12/char-server.vcxproj @@ -145,6 +145,8 @@ + + @@ -186,6 +188,7 @@ + diff --git a/vcproj-12/char-server.vcxproj.filters b/vcproj-12/char-server.vcxproj.filters index 0c90c0ab8..13788df95 100644 --- a/vcproj-12/char-server.vcxproj.filters +++ b/vcproj-12/char-server.vcxproj.filters @@ -13,6 +13,9 @@ common + + common + common @@ -129,6 +132,12 @@ common + + common + + + common + common diff --git a/vcproj-12/login-server.vcxproj b/vcproj-12/login-server.vcxproj index 65284dbd1..8500cc376 100644 --- a/vcproj-12/login-server.vcxproj +++ b/vcproj-12/login-server.vcxproj @@ -156,6 +156,8 @@ + + @@ -187,6 +189,7 @@ + diff --git a/vcproj-12/login-server.vcxproj.filters b/vcproj-12/login-server.vcxproj.filters index c5345b030..0ce4b8b6e 100644 --- a/vcproj-12/login-server.vcxproj.filters +++ b/vcproj-12/login-server.vcxproj.filters @@ -25,6 +25,9 @@ common + + common + common @@ -114,6 +117,12 @@ common + + common + + + common + common diff --git a/vcproj-12/map-server.vcxproj b/vcproj-12/map-server.vcxproj index ba61a956f..931f7d11d 100644 --- a/vcproj-12/map-server.vcxproj +++ b/vcproj-12/map-server.vcxproj @@ -146,6 +146,8 @@ + + @@ -222,6 +224,7 @@ + diff --git a/vcproj-12/map-server.vcxproj.filters b/vcproj-12/map-server.vcxproj.filters index 325a62f67..2b04a4211 100644 --- a/vcproj-12/map-server.vcxproj.filters +++ b/vcproj-12/map-server.vcxproj.filters @@ -130,6 +130,9 @@ common + + common + common @@ -336,6 +339,12 @@ common + + common + + + common + common diff --git a/vcproj-9/char-server.vcproj b/vcproj-9/char-server.vcproj index 4ae68cd36..f8d8e7abd 100644 --- a/vcproj-9/char-server.vcproj +++ b/vcproj-9/char-server.vcproj @@ -316,6 +316,18 @@ RelativePath="..\src\common\ers.h" > + + + + + + diff --git a/vcproj-9/login-server.vcproj b/vcproj-9/login-server.vcproj index 53c77309a..1031d2237 100644 --- a/vcproj-9/login-server.vcproj +++ b/vcproj-9/login-server.vcproj @@ -286,6 +286,18 @@ RelativePath="..\src\common\ers.h" > + + + + + + diff --git a/vcproj-9/map-server.vcproj b/vcproj-9/map-server.vcproj index 2b95e6b7f..fa62c43cf 100644 --- a/vcproj-9/map-server.vcproj +++ b/vcproj-9/map-server.vcproj @@ -331,6 +331,18 @@ RelativePath="..\src\common\grfio.h" > + + + + + + diff --git a/vcproj-9/plugin-sample.vcproj b/vcproj-9/plugin-sample.vcproj new file mode 100644 index 000000000..85f6d2108 --- /dev/null +++ b/vcproj-9/plugin-sample.vcproj @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6509af19cb4dbba9d8af7489301e58dc8c6ca9f7 Mon Sep 17 00:00:00 2001 From: Matheus Macabu Date: Thu, 2 May 2013 20:10:06 -0300 Subject: Follow-up to HPM. * Fixed small warning * Added support for Visual Studio 2010. Signed-off-by: Matheus Macabu --- .gitignore | 3 + Hercules-10.sln | 6 ++ src/common/console.c | 2 +- vcproj-10/char-server.vcxproj | 14 ++-- vcproj-10/char-server.vcxproj.filters | 14 ++-- vcproj-10/login-server.vcxproj | 6 +- vcproj-10/login-server.vcxproj.filters | 10 ++- vcproj-10/plugin-sample.vcxproj | 118 +++++++++++++++++++++++++++++++++ 8 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 vcproj-10/plugin-sample.vcxproj (limited to 'src/common/console.c') diff --git a/.gitignore b/.gitignore index 7d981021d..480ac1fa3 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ /vcproj-12/mapcache /vcproj-12/map-server_sql /vcproj-12/*.user +/vcproj-12/plugin-sample/ # /vcproj-10/ /vcproj-10/map-server @@ -97,6 +98,7 @@ /vcproj-10/mapcache /vcproj-10/map-server_sql /vcproj-10/*.user +/vcproj-10/plugin-sample/ # /vcproj-9/ /vcproj-9/*.user @@ -107,3 +109,4 @@ /vcproj-9/login-server_sql /vcproj-9/map-server_sql /vcproj-9/mapcache +/vcproj-9/plugin-sample/ diff --git a/Hercules-10.sln b/Hercules-10.sln index a740ee0b1..997df68af 100644 --- a/Hercules-10.sln +++ b/Hercules-10.sln @@ -8,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map-server", "vcproj-10\map EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mapcache", "vcproj-10\mapcache.vcxproj", "{D356871D-58E1-450B-967A-E7E9646175AF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin-sample", "vcproj-10\plugin-sample.vcxproj", "{E64C56D3-CDFB-483B-900B-A62D216B6D2F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -30,6 +32,10 @@ Global {D356871D-58E1-450B-967A-E7E9646175AF}.Debug|Win32.Build.0 = Debug|Win32 {D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.ActiveCfg = Release|Win32 {D356871D-58E1-450B-967A-E7E9646175AF}.Release|Win32.Build.0 = Release|Win32 + {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Debug|Win32.Build.0 = Debug|Win32 + {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Release|Win32.ActiveCfg = Release|Win32 + {E64C56D3-CDFB-483B-900B-A62D216B6D2F}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/common/console.c b/src/common/console.c index db914db98..c228ab790 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -377,7 +377,7 @@ void console_init (void) { } void console_final(void) { #ifdef CONSOLE_INPUT - int i; + unsigned int i; console->parse_final(); for( i = 0; i < console->cmd_count; i++ ) { if( console->cmds[i]->next_count ) diff --git a/vcproj-10/char-server.vcxproj b/vcproj-10/char-server.vcxproj index e07954292..46438b3aa 100644 --- a/vcproj-10/char-server.vcxproj +++ b/vcproj-10/char-server.vcxproj @@ -138,12 +138,13 @@ + - + - - + + @@ -171,7 +172,7 @@ - + @@ -181,8 +182,9 @@ + - + @@ -212,7 +214,7 @@ - + diff --git a/vcproj-10/char-server.vcxproj.filters b/vcproj-10/char-server.vcxproj.filters index 13788df95..3f3c2f6ac 100644 --- a/vcproj-10/char-server.vcxproj.filters +++ b/vcproj-10/char-server.vcxproj.filters @@ -4,7 +4,7 @@ common - + common @@ -82,7 +82,7 @@ char_sql - + char_sql @@ -115,6 +115,9 @@ common + + common + @@ -123,7 +126,7 @@ common - + common @@ -174,7 +177,7 @@ char_sql - + char_sql @@ -249,6 +252,9 @@ common + + common + diff --git a/vcproj-10/login-server.vcxproj b/vcproj-10/login-server.vcxproj index 20c780902..7cf90854d 100644 --- a/vcproj-10/login-server.vcxproj +++ b/vcproj-10/login-server.vcxproj @@ -138,6 +138,7 @@ + @@ -149,7 +150,7 @@ - + @@ -173,6 +174,7 @@ + @@ -182,7 +184,7 @@ - + diff --git a/vcproj-10/login-server.vcxproj.filters b/vcproj-10/login-server.vcxproj.filters index 0ce4b8b6e..46f4efbc4 100644 --- a/vcproj-10/login-server.vcxproj.filters +++ b/vcproj-10/login-server.vcxproj.filters @@ -16,7 +16,7 @@ common - + common @@ -88,6 +88,9 @@ common + + common + @@ -108,7 +111,7 @@ common - + common @@ -195,6 +198,9 @@ common + + common + diff --git a/vcproj-10/plugin-sample.vcxproj b/vcproj-10/plugin-sample.vcxproj new file mode 100644 index 000000000..4bb437cda --- /dev/null +++ b/vcproj-10/plugin-sample.vcxproj @@ -0,0 +1,118 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {E64C56D3-CDFB-483B-900B-A62D216B6D2F} + plugin-sample + Win32Proj + plugin-sample + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + ..\plugins\ + $(ProjectName)\$(Configuration)\ + false + ..\plugins\ + $(ProjectName)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + plugin-sample + plugin-sample + + + + /MP %(AdditionalOptions) + Disabled + ..\src\common;..\3rdparty\msinttypes\include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0417 + + + $(OutDir)$(TargetName).dll + + + true + $(IntDir)$(TargetName).pdb + false + $(IntDir)$(TargetName).lib + MachineX86 + + + + + /MP %(AdditionalOptions) + MaxSpeed + ..\src\common;..\3rdparty\msinttypes\include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreaded + Level3 + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0417 + + + $(OutDir)$(TargetName).dll + + + true + $(IntDir)$(TargetName).pdb + true + true + false + $(IntDir)$(TargetName).lib + MachineX86 + + + + + + + + + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3bfadf4d2329da54f2097e1f0fafba371347465f Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sat, 4 May 2013 20:36:29 -0300 Subject: Mapreg saving overhaul Server only saves variables that were changed, not all of them. Special Thanks to Yommy <3~! Signed-off-by: shennetsind --- src/common/console.c | 19 ++-- src/map/mapreg.h | 14 ++- src/map/mapreg_sql.c | 291 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 208 insertions(+), 116 deletions(-) (limited to 'src/common/console.c') diff --git a/src/common/console.c b/src/common/console.c index c228ab790..248dd7b45 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -337,15 +337,16 @@ int console_parse_timer(int tid, unsigned int tick, int id, intptr_t data) { return 0; } void console_parse_final(void) { - InterlockedDecrement(&console->ptstate); - racond_signal(console->ptcond); - - /* wait for thread to close */ - rathread_wait(console->pthread, NULL); - - racond_destroy(console->ptcond); - ramutex_destroy(console->ptmutex); - + if( console->ptstate ) { + InterlockedDecrement(&console->ptstate); + racond_signal(console->ptcond); + + /* wait for thread to close */ + rathread_wait(console->pthread, NULL); + + racond_destroy(console->ptcond); + ramutex_destroy(console->ptmutex); + } } void console_parse_init(void) { cinput.count = 0; diff --git a/src/map/mapreg.h b/src/map/mapreg.h index d5fadafc5..e83f9e053 100644 --- a/src/map/mapreg.h +++ b/src/map/mapreg.h @@ -1,9 +1,19 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _MAPREG_H_ #define _MAPREG_H_ +struct mapreg_save { + int uid; + union { + int i; + char *str; + } u; + bool save; +}; + void mapreg_reload(void); void mapreg_final(void); void mapreg_init(void); diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 7782f7f02..bac3cea13 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -1,8 +1,10 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/db.h" +#include "../common/ers.h" #include "../common/malloc.h" #include "../common/showmsg.h" #include "../common/sql.h" @@ -10,54 +12,69 @@ #include "../common/timer.h" #include "map.h" // mmysql_handle #include "script.h" +#include "mapreg.h" #include #include static DBMap* mapreg_db = NULL; // int var_id -> int value static DBMap* mapregstr_db = NULL; // int var_id -> char* value +static struct eri *mapreg_ers; //[Ind/Hercules] static char mapreg_table[32] = "mapreg"; -static bool mapreg_dirty = false; +static bool mapreg_i_dirty = false; +static bool mapreg_str_dirty = false; + #define MAPREG_AUTOSAVE_INTERVAL (300*1000) /// Looks up the value of an integer variable using its uid. -int mapreg_readreg(int uid) -{ - return idb_iget(mapreg_db, uid); +int mapreg_readreg(int uid) { + struct mapreg_save *m = idb_get(mapreg_db, uid); + return m?m->u.i:0; } /// Looks up the value of a string variable using its uid. -char* mapreg_readregstr(int uid) -{ - return idb_get(mapregstr_db, uid); +char* mapreg_readregstr(int uid) { + struct mapreg_save *m = idb_get(mapregstr_db, uid); + return m?m->u.str:NULL; } /// Modifies the value of an integer variable. -bool mapreg_setreg(int uid, int val) -{ +bool mapreg_setreg(int uid, int val) { + struct mapreg_save *m; int num = (uid & 0x00ffffff); int i = (uid & 0xff000000) >> 24; const char* name = get_str(num); - if( val != 0 ) - { - if( idb_iput(mapreg_db,uid,val) ) - mapreg_dirty = true; // already exists, delay write - else if(name[1] != '@') - {// write new variable to database - char tmp_str[32*2+1]; - Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32)); - if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val) ) - Sql_ShowDebug(mmysql_handle); + if( val != 0 ) { + if( (m = idb_get(mapreg_db,uid)) ) { + m->u.i = val; + if(name[1] != '@') { + m->save = true; + mapreg_i_dirty = true; + } + } else { + m = ers_alloc(mapreg_ers, struct mapreg_save); + + m->u.i = val; + m->uid = uid; + m->save = false; + + if(name[1] != '@') {// write new variable to database + char tmp_str[32*2+1]; + Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32)); + if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, tmp_str, i, val) ) + Sql_ShowDebug(mmysql_handle); + } + idb_put(mapreg_db, uid, m); + } + } else { // val == 0 + if( (m = idb_get(mapreg_db,uid)) ) { + ers_free(mapreg_ers, m); } - } - else // val == 0 - { idb_remove(mapreg_db,uid); - if( name[1] != '@' ) - {// Remove from database because it is unused. + if( name[1] != '@' ) {// Remove from database because it is unused. if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) ) Sql_ShowDebug(mmysql_handle); } @@ -67,32 +84,48 @@ bool mapreg_setreg(int uid, int val) } /// Modifies the value of a string variable. -bool mapreg_setregstr(int uid, const char* str) -{ +bool mapreg_setregstr(int uid, const char* str) { + struct mapreg_save *m; int num = (uid & 0x00ffffff); int i = (uid & 0xff000000) >> 24; const char* name = get_str(num); - if( str == NULL || *str == 0 ) - { + if( str == NULL || *str == 0 ) { if(name[1] != '@') { if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, name, i) ) Sql_ShowDebug(mmysql_handle); } + if( (m = idb_get(mapregstr_db,uid)) ) { + if( m->u.str != NULL ) + aFree(m->u.str); + ers_free(mapreg_ers, m); + } idb_remove(mapregstr_db,uid); - } - else - { - if (idb_put(mapregstr_db,uid, aStrdup(str))) - mapreg_dirty = true; - else if(name[1] != '@') { //put returned null, so we must insert. - // Someone is causing a database size infinite increase here without name[1] != '@' [Lance] - char tmp_str[32*2+1]; - char tmp_str2[255*2+1]; - Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32)); - Sql_EscapeStringLen(mmysql_handle, tmp_str2, str, strnlen(str, 255)); - if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, tmp_str, i, tmp_str2) ) - Sql_ShowDebug(mmysql_handle); + } else { + if( (m = idb_get(mapregstr_db,uid)) ) { + if( m->u.str != NULL ) + aFree(m->u.str); + m->u.str = aStrdup(str); + if(name[1] != '@') { + mapreg_str_dirty = true; + m->save = true; + } + } else { + m = ers_alloc(mapreg_ers, struct mapreg_save); + + m->uid = uid; + m->u.str = aStrdup(str); + m->save = false; + + if(name[1] != '@') { //put returned null, so we must insert. + char tmp_str[32*2+1]; + char tmp_str2[255*2+1]; + Sql_EscapeStringLen(mmysql_handle, tmp_str, name, strnlen(name, 32)); + Sql_EscapeStringLen(mmysql_handle, tmp_str2, str, strnlen(str, 255)); + if( SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, tmp_str, i, tmp_str2) ) + Sql_ShowDebug(mmysql_handle); + } + idb_put(mapregstr_db, uid, m); } } @@ -100,8 +133,7 @@ bool mapreg_setregstr(int uid, const char* str) } /// Loads permanent variables from database -static void script_load_mapreg(void) -{ +static void script_load_mapreg(void) { /* 0 1 2 +-------------------------+ @@ -126,97 +158,147 @@ static void script_load_mapreg(void) SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); - while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) - { + while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) { + struct mapreg_save *m = NULL; int s = add_str(varname); int i = index; - if( varname[length-1] == '$' ) - idb_put(mapregstr_db, (i<<24)|s, aStrdup(value)); - else - idb_iput(mapreg_db, (i<<24)|s, atoi(value)); + if( varname[length-1] == '$' ) { + if( idb_exists(mapregstr_db, (i<<24)|s) ) { + ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); + continue; + } + } else { + if( idb_exists(mapreg_db, (i<<24)|s) ) { + ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); + continue; + } + } + + m = ers_alloc(mapreg_ers, struct mapreg_save); + m->uid = (i<<24)|s; + m->save = false; + if( varname[length-1] == '$' ) { + m->u.str = aStrdup(value); + idb_put(mapregstr_db, m->uid, m); + } else { + m->u.i = atoi(value); + idb_put(mapreg_db, m->uid, m); + } } SqlStmt_Free(stmt); - mapreg_dirty = false; + mapreg_i_dirty = false; + mapreg_str_dirty = false; } /// Saves permanent variables to database -static void script_save_mapreg(void) -{ +static void script_save_mapreg(void) { DBIterator* iter; - DBData *data; - DBKey key; - - iter = db_iterator(mapreg_db); - for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) - { - int num = (key.i & 0x00ffffff); - int i = (key.i & 0xff000000) >> 24; - const char* name = get_str(num); - - if( name[1] == '@' ) - continue; - - if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, db_data2i(data), name, i) ) - Sql_ShowDebug(mmysql_handle); + struct mapreg_save *m = NULL; + + if( mapreg_i_dirty ) { + iter = db_iterator(mapreg_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + if( m->save ) { + int num = (m->uid & 0x00ffffff); + int i = (m->uid & 0xff000000) >> 24; + const char* name = get_str(num); + + if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg_table, m->u.i, name, i) ) + Sql_ShowDebug(mmysql_handle); + m->save = false; + } + } + dbi_destroy(iter); + mapreg_i_dirty = false; } - dbi_destroy(iter); - iter = db_iterator(mapregstr_db); - for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) - { - int num = (key.i & 0x00ffffff); - int i = (key.i & 0xff000000) >> 24; - const char* name = get_str(num); - char tmp_str2[2*255+1]; - - if( name[1] == '@' ) - continue; - - Sql_EscapeStringLen(mmysql_handle, tmp_str2, db_data2ptr(data), safestrnlen(db_data2ptr(data), 255)); - if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, tmp_str2, name, i) ) - Sql_ShowDebug(mmysql_handle); + if( mapreg_str_dirty ) { + iter = db_iterator(mapregstr_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + if( m->save ) { + int num = (m->uid & 0x00ffffff); + int i = (m->uid & 0xff000000) >> 24; + const char* name = get_str(num); + char tmp_str2[2*255+1]; + + Sql_EscapeStringLen(mmysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255)); + if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg_table, tmp_str2, name, i) ) + Sql_ShowDebug(mmysql_handle); + m->save = false; + } + } + dbi_destroy(iter); + mapreg_str_dirty = false; } - dbi_destroy(iter); - - mapreg_dirty = false; } -static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data) -{ - if( mapreg_dirty ) - script_save_mapreg(); - +static int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data) { + script_save_mapreg(); return 0; } -void mapreg_reload(void) -{ - if( mapreg_dirty ) - script_save_mapreg(); +void mapreg_reload(void) { + DBIterator* iter; + struct mapreg_save *m = NULL; + script_save_mapreg(); + + iter = db_iterator(mapreg_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + ers_free(mapreg_ers, m); + } + dbi_destroy(iter); + + iter = db_iterator(mapregstr_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + if( m->u.str != NULL ) { + aFree(m->u.str); + } + ers_free(mapreg_ers, m); + } + dbi_destroy(iter); + db_clear(mapreg_db); db_clear(mapregstr_db); script_load_mapreg(); } -void mapreg_final(void) -{ - if( mapreg_dirty ) - script_save_mapreg(); +void mapreg_final(void) { + DBIterator* iter; + struct mapreg_save *m = NULL; + + script_save_mapreg(); + iter = db_iterator(mapreg_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + ers_free(mapreg_ers, m); + } + dbi_destroy(iter); + + iter = db_iterator(mapregstr_db); + for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { + if( m->u.str != NULL ) { + aFree(m->u.str); + } + ers_free(mapreg_ers, m); + } + dbi_destroy(iter); + db_destroy(mapreg_db); db_destroy(mapregstr_db); + + ers_destroy(mapreg_ers); } -void mapreg_init(void) -{ +void mapreg_init(void) { mapreg_db = idb_alloc(DB_OPT_BASE); - mapregstr_db = idb_alloc(DB_OPT_RELEASE_DATA); + mapregstr_db = idb_alloc(DB_OPT_BASE); + mapreg_ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_NONE); script_load_mapreg(); @@ -224,8 +306,7 @@ void mapreg_init(void) add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, 0, 0, MAPREG_AUTOSAVE_INTERVAL); } -bool mapreg_config_read(const char* w1, const char* w2) -{ +bool mapreg_config_read(const char* w1, const char* w2) { if(!strcmpi(w1, "mapreg_db")) safestrncpy(mapreg_table, w2, sizeof(mapreg_table)); else -- cgit v1.2.3-70-g09d2 From 25e848f1a0f9317d63106cae048a1ef838411cb2 Mon Sep 17 00:00:00 2001 From: Susu Date: Fri, 17 May 2013 11:10:30 +0200 Subject: - Made DB and malloc lib HPM-friendly - Also fixed a bug preventing the plugins to be loeaded because HPMI and HPMI_s weren't HPExport --- src/char/char.c | 12 +- src/char/int_guild.c | 4 +- src/char/inter.c | 2 +- src/common/HPM.c | 4 +- src/common/HPMi.h | 4 +- src/common/console.c | 2 +- src/common/core.c | 10 +- src/common/db.c | 2001 ++++++++++++++++++++++++------------------------ src/common/db.h | 123 +-- src/common/malloc.c | 79 +- src/common/malloc.h | 72 +- src/login/login.c | 6 +- src/map/atcommand.c | 8 +- src/map/battleground.c | 2 +- src/map/chrif.c | 6 +- src/map/guild.c | 28 +- src/map/itemdb.c | 8 +- src/map/map.c | 14 +- src/map/npc.c | 14 +- src/map/script.c | 2 +- src/map/skill.c | 2 +- src/map/storage.c | 4 +- 22 files changed, 1228 insertions(+), 1179 deletions(-) (limited to 'src/common/console.c') diff --git a/src/char/char.c b/src/char/char.c index 6e0f5363e..00fc633df 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -187,7 +187,7 @@ static DBData create_online_char_data(DBKey key, va_list args) character->pincode_enable = -1; character->fd = -1; character->waiting_disconnect = INVALID_TIMER; - return db_ptr2data(character); + return DB->ptr2data(character); } void set_char_charselect(int account_id) @@ -321,7 +321,7 @@ void set_char_offline(int char_id, int account_id) */ static int char_db_setoffline(DBKey key, DBData *data, va_list ap) { - struct online_char_data* character = (struct online_char_data*)db_data2ptr(data); + struct online_char_data* character = (struct online_char_data*)DB->data2ptr(data); int server = va_arg(ap, int); if (server == -1) { character->char_id = -1; @@ -340,7 +340,7 @@ static int char_db_setoffline(DBKey key, DBData *data, va_list ap) */ static int char_db_kickoffline(DBKey key, DBData *data, va_list ap) { - struct online_char_data* character = (struct online_char_data*)db_data2ptr(data); + struct online_char_data* character = (struct online_char_data*)DB->data2ptr(data); int server_id = va_arg(ap, int); if (server_id > -1 && character->server != server_id) @@ -392,7 +392,7 @@ static DBData create_charstatus(DBKey key, va_list args) struct mmo_charstatus *cp; cp = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus)); cp->char_id = key.i; - return db_ptr2data(cp); + return DB->ptr2data(cp); } int inventory_to_sql(const struct item items[], int max, int id); @@ -4450,7 +4450,7 @@ int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data) */ static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap) { - struct online_char_data* character = db_data2ptr(data); + struct online_char_data* character = DB->data2ptr(data); int* i = va_arg(ap, int*); if(character->server > -1) @@ -4532,7 +4532,7 @@ static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_ */ static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) { - struct online_char_data *character= db_data2ptr(data); + struct online_char_data *character= DB->data2ptr(data); if (character->fd != -1) return 0; //Character still connected if (character->server == -2) //Unknown server.. set them offline diff --git a/src/char/int_guild.c b/src/char/int_guild.c index b666cadae..e1e012725 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -57,7 +57,7 @@ static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data) if( last_id == 0 ) //Save the first guild in the list. state = 1; - for( g = db_data2ptr(iter->first(iter, &key)); dbi_exists(iter); g = db_data2ptr(iter->next(iter, &key)) ) + for( g = DB->data2ptr(iter->first(iter, &key)); dbi_exists(iter); g = DB->data2ptr(iter->next(iter, &key)) ) { if( state == 0 && g->guild_id == last_id ) state++; //Save next guild in the list. @@ -739,7 +739,7 @@ int inter_guild_sql_init(void) */ static int guild_db_final(DBKey key, DBData *data, va_list ap) { - struct guild *g = db_data2ptr(data); + struct guild *g = DB->data2ptr(data); if (g->save_flag&GS_MASK) { inter_guild_tosql(g, g->save_flag&GS_MASK); return 1; diff --git a/src/char/inter.c b/src/char/inter.c index 83989271e..a1b075a14 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -935,7 +935,7 @@ int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) { unsigned long tick; - struct WisData *wd = db_data2ptr(data); + struct WisData *wd = DB->data2ptr(data); tick = va_arg(ap, unsigned long); if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX) diff --git a/src/common/HPM.c b/src/common/HPM.c index af06811a5..28ea8f413 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -264,6 +264,8 @@ void hplugins_share_defaults(void) { HPM->share(&SERVER_TYPE,"SERVER_TYPE"); HPM->share((void*)get_svn_revision,"get_svn_revision"); HPM->share((void*)get_git_hash,"get_git_hash"); + HPM->share(DB, "DB"); + HPM->share(malloclib, "malloclib"); /* socket */ HPM->share(RFIFOSKIP,"RFIFOSKIP"); HPM->share(WFIFOSET,"WFIFOSET"); @@ -284,7 +286,7 @@ void hplugins_share_defaults(void) { HPM->share(add_timer_interval,"add_timer_interval"); HPM->share(add_timer_func_list,"add_timer_func_list"); HPM->share(delete_timer,"delete_timer"); - HPM->share(get_uptime,"get_uptime"); + HPM->share(get_uptime,"get_uptime"); } CPCMD(plugins) { if( HPM->plugin_count == 0 ) { diff --git a/src/common/HPMi.h b/src/common/HPMi.h index a58eeed38..3cdb804e0 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -57,14 +57,14 @@ enum hp_event_types { }; /* Hercules Plugin Mananger Include Interface */ -struct HPMi_interface { +HPExport struct HPMi_interface { void (*event[HPET_MAX]) (void); bool (*addCommand) (char *name, bool (*func)(const int fd, struct map_session_data* sd, const char* command, const char* message,struct AtCommandInfo *info)); bool (*addScript) (char *name, char *args, bool (*func)(struct script_state *st)); void (*addCPCommand) (char *name, CParseFunc func); } HPMi_s; #ifndef _HPM_H_ - struct HPMi_interface *HPMi; + HPExport struct HPMi_interface *HPMi; #endif #endif /* _HPMi_H_ */ diff --git a/src/common/console.c b/src/common/console.c index 248dd7b45..ba93b8e09 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -98,7 +98,7 @@ CPCMD(help) { } /* [Ind/Hercules] */ CPCMD(malloc_usage) { - unsigned int val = (unsigned int)malloc_usage(); + unsigned int val = (unsigned int)malloclib->usage(); ShowInfo("malloc_usage: %.2f MB\n",(double)(val)/1024); } #define CP_DEF_C(x) { #x , NULL , NULL, NULL } diff --git a/src/common/core.c b/src/common/core.c index 984815bc2..0959e6fc9 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -284,9 +284,11 @@ void core_defaults(void) { #endif console_defaults(); strlib_defaults(); + malloc_defaults(); #ifndef MINICORE sql_defaults(); timer_defaults(); + db_defaults(); #endif } /*====================================== @@ -305,7 +307,7 @@ int main (int argc, char **argv) { } core_defaults(); - malloc_init();// needed for Show* in display_title() [FlavioJS] + malloclib->init();// needed for Show* in display_title() [FlavioJS] console->display_title(); @@ -320,7 +322,7 @@ int main (int argc, char **argv) { Sql_Init(); rathread_init(); mempool_init(); - db_init(); + DB->init(); signals_init(); #ifdef _WIN32 @@ -354,12 +356,12 @@ int main (int argc, char **argv) { #endif timer_final(); socket_final(); - db_final(); + DB->final(); mempool_final(); rathread_final(); #endif - malloc_final(); + malloclib->final(); return 0; } diff --git a/src/common/db.c b/src/common/db.c index 7ac9b2dc7..579697a99 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -1,70 +1,70 @@ /*****************************************************************************\ - * Copyright (c) Athena Dev Teams - Licensed under GNU GPL - * For more information, see LICENCE in the main folder - * - * This file is separated in five sections: - * (1) Private typedefs, enums, structures, defines and gblobal variables - * (2) Private functions - * (3) Protected functions used internally - * (4) Protected functions used in the interface of the database - * (5) Public functions - * - * The databases are structured as a hashtable of RED-BLACK trees. - * - * Properties of the RED-BLACK trees being used: - * 1. The value of any node is greater than the value of its left child and - * less than the value of its right child. - * 2. Every node is colored either RED or BLACK. - * 3. Every red node that is not a leaf has only black children. - * 4. Every path from the root to a leaf contains the same number of black - * nodes. - * 5. The root node is black. - * An n node in a RED-BLACK tree has the property that its - * height is O(lg(n)). - * Another important property is that after adding a node to a RED-BLACK - * tree, the tree can be readjusted in O(lg(n)) time. - * Similarly, after deleting a node from a RED-BLACK tree, the tree can be - * readjusted in O(lg(n)) time. - * {@link http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic18/} - * - * How to add new database types: - * 1. Add the identifier of the new database type to the enum DBType - * 2. If not already there, add the data type of the key to the union DBKey - * 3. If the key can be considered NULL, update the function db_is_key_null - * 4. If the key can be duplicated, update the functions db_dup_key and - * db_dup_key_free - * 5. Create a comparator and update the function db_default_cmp - * 6. Create a hasher and update the function db_default_hash - * 7. If the new database type requires or does not support some options, - * update the function db_fix_options - * - * TODO: - * - create test cases to test the database system thoroughly - * - finish this header describing the database system - * - create custom database allocator - * - make the system thread friendly - * - change the structure of the database to T-Trees - * - create a db that organizes itself by splaying - * - * HISTORY: - * 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] - * 2012/03/09 - Added enum for data types (int, uint, void*) - * 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. - * 2007/11/09 - Added an iterator to the database. - * 2006/12/21 - Added 1-node cache to the database. - * 2.1 (Athena build #???#) - Portability fix - * - Fixed the portability of casting to union and added the functions - * ensure and clear to the database. - * 2.0 (Athena build 4859) - Transition version - * - Almost everything recoded with a strategy similar to objects, - * database structure is maintained. - * 1.0 (up to Athena build 4706) - * - Previous database system. - * - * @version 2006/12/21 - * @author Athena Dev team - * @encoding US-ASCII - * @see #db.h +* Copyright (c) Athena Dev Teams - Licensed under GNU GPL +* For more information, see LICENCE in the main folder +* +* This file is separated in five sections: +* (1) Private typedefs, enums, structures, defines and gblobal variables +* (2) Private functions +* (3) Protected functions used internally +* (4) Protected functions used in the interface of the database +* (5) Public functions +* +* The databases are structured as a hashtable of RED-BLACK trees. +* +* Properties of the RED-BLACK trees being used: +* 1. The value of any node is greater than the value of its left child and +* less than the value of its right child. +* 2. Every node is colored either RED or BLACK. +* 3. Every red node that is not a leaf has only black children. +* 4. Every path from the root to a leaf contains the same number of black +* nodes. +* 5. The root node is black. +* An n node in a RED-BLACK tree has the property that its +* height is O(lg(n)). +* Another important property is that after adding a node to a RED-BLACK +* tree, the tree can be readjusted in O(lg(n)) time. +* Similarly, after deleting a node from a RED-BLACK tree, the tree can be +* readjusted in O(lg(n)) time. +* {@link http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic18/} +* +* How to add new database types: +* 1. Add the identifier of the new database type to the enum DBType +* 2. If not already there, add the data type of the key to the union DBKey +* 3. If the key can be considered NULL, update the function db_is_key_null +* 4. If the key can be duplicated, update the functions db_dup_key and +* db_dup_key_free +* 5. Create a comparator and update the function db_default_cmp +* 6. Create a hasher and update the function db_default_hash +* 7. If the new database type requires or does not support some options, +* update the function db_fix_options +* +* TODO: +* - create test cases to test the database system thoroughly +* - finish this header describing the database system +* - create custom database allocator +* - make the system thread friendly +* - change the structure of the database to T-Trees +* - create a db that organizes itself by splaying +* +* HISTORY: +* 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] +* 2012/03/09 - Added enum for data types (int, uint, void*) +* 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. +* 2007/11/09 - Added an iterator to the database. +* 2006/12/21 - Added 1-node cache to the database. +* 2.1 (Athena build #???#) - Portability fix +* - Fixed the portability of casting to union and added the functions +* ensure and clear to the database. +* 2.0 (Athena build 4859) - Transition version +* - Almost everything recoded with a strategy similar to objects, +* database structure is maintained. +* 1.0 (up to Athena build 4706) +* - Previous database system. +* +* @version 2006/12/21 +* @author Athena Dev team +* @encoding US-ASCII +* @see #db.h \*****************************************************************************/ #include #include @@ -77,58 +77,58 @@ #include "../common/strlib.h" /*****************************************************************************\ - * (1) Private typedefs, enums, structures, defines and global variables of * - * the database system. * - * DB_ENABLE_STATS - Define to enable database statistics. * - * HASH_SIZE - Define with the size of the hashtable. * - * DBNColor - Enumeration of colors of the nodes. * - * DBNode - Structure of a node in RED-BLACK trees. * - * struct db_free - Structure that holds a deleted node to be freed. * - * DBMap_impl - Struture of the database. * - * stats - Statistics about the database system. * +* (1) Private typedefs, enums, structures, defines and global variables of * +* the database system. * +* DB_ENABLE_STATS - Define to enable database statistics. * +* HASH_SIZE - Define with the size of the hashtable. * +* DBNColor - Enumeration of colors of the nodes. * +* DBNode - Structure of a node in RED-BLACK trees. * +* struct db_free - Structure that holds a deleted node to be freed. * +* DBMap_impl - Struture of the database. * +* stats - Statistics about the database system. * \*****************************************************************************/ /** - * If defined statistics about database nodes, database creating/destruction - * and function usage are keept and displayed when finalizing the database - * system. - * WARNING: This adds overhead to every database operation (not shure how much). - * @private - * @see #DBStats - * @see #stats - * @see #db_final(void) - */ +* If defined statistics about database nodes, database creating/destruction +* and function usage are keept and displayed when finalizing the database +* system. +* WARNING: This adds overhead to every database operation (not shure how much). +* @private +* @see #DBStats +* @see #stats +* @see #db_final(void) +*/ //#define DB_ENABLE_STATS /** - * Size of the hashtable in the database. - * @private - * @see DBMap_impl#ht - */ +* Size of the hashtable in the database. +* @private +* @see DBMap_impl#ht +*/ #define HASH_SIZE (256+27) /** - * The color of individual nodes. - * @private - * @see struct dbn - */ +* The color of individual nodes. +* @private +* @see struct dbn +*/ typedef enum node_color { RED, BLACK } node_color; /** - * A node in a RED-BLACK tree of the database. - * @param parent Parent node - * @param left Left child node - * @param right Right child node - * @param key Key of this database entry - * @param data Data of this database entry - * @param deleted If the node is deleted - * @param color Color of the node - * @private - * @see DBMap_impl#ht - */ +* A node in a RED-BLACK tree of the database. +* @param parent Parent node +* @param left Left child node +* @param right Right child node +* @param key Key of this database entry +* @param data Data of this database entry +* @param deleted If the node is deleted +* @param color Color of the node +* @private +* @see DBMap_impl#ht +*/ typedef struct dbn { // Tree structure struct dbn *parent; @@ -143,39 +143,39 @@ typedef struct dbn { } *DBNode; /** - * Structure that holds a deleted node. - * @param node Deleted node - * @param root Address to the root of the tree - * @private - * @see DBMap_impl#free_list - */ +* Structure that holds a deleted node. +* @param node Deleted node +* @param root Address to the root of the tree +* @private +* @see DBMap_impl#free_list +*/ struct db_free { DBNode node; DBNode *root; }; /** - * Complete database structure. - * @param vtable Interface of the database - * @param alloc_file File where the database was allocated - * @param alloc_line Line in the file where the database was allocated - * @param free_list Array of deleted nodes to be freed - * @param free_count Number of deleted nodes in free_list - * @param free_max Current maximum capacity of free_list - * @param free_lock Lock for freeing the nodes - * @param nodes Manager of reusable tree nodes - * @param cmp Comparator of the database - * @param hash Hasher of the database - * @param release Releaser of the database - * @param ht Hashtable of RED-BLACK trees - * @param type Type of the database - * @param options Options of the database - * @param item_count Number of items in the database - * @param maxlen Maximum length of strings in DB_STRING and DB_ISTRING databases - * @param global_lock Global lock of the database - * @private - * @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short) - */ +* Complete database structure. +* @param vtable Interface of the database +* @param alloc_file File where the database was allocated +* @param alloc_line Line in the file where the database was allocated +* @param free_list Array of deleted nodes to be freed +* @param free_count Number of deleted nodes in free_list +* @param free_max Current maximum capacity of free_list +* @param free_lock Lock for freeing the nodes +* @param nodes Manager of reusable tree nodes +* @param cmp Comparator of the database +* @param hash Hasher of the database +* @param release Releaser of the database +* @param ht Hashtable of RED-BLACK trees +* @param type Type of the database +* @param options Options of the database +* @param item_count Number of items in the database +* @param maxlen Maximum length of strings in DB_STRING and DB_ISTRING databases +* @param global_lock Global lock of the database +* @private +* @see #db_alloc(const char*,int,DBType,DBOptions,unsigned short) +*/ typedef struct DBMap_impl { // Database interface struct DBMap vtable; @@ -202,16 +202,16 @@ typedef struct DBMap_impl { } DBMap_impl; /** - * Complete iterator structure. - * @param vtable Interface of the iterator - * @param db Parent database - * @param ht_index Current index of the hashtable - * @param node Current node - * @private - * @see #DBIterator - * @see #DBMap_impl - * @see #DBNode - */ +* Complete iterator structure. +* @param vtable Interface of the iterator +* @param db Parent database +* @param ht_index Current index of the hashtable +* @param node Current node +* @private +* @see #DBIterator +* @see #DBMap_impl +* @see #DBNode +*/ typedef struct DBIterator_impl { // Iterator interface struct DBIterator vtable; @@ -222,11 +222,11 @@ typedef struct DBIterator_impl { #if defined(DB_ENABLE_STATS) /** - * Structure with what is counted when the database statistics are enabled. - * @private - * @see #DB_ENABLE_STATS - * @see #stats - */ +* Structure with what is counted when the database statistics are enabled. +* @private +* @see #DB_ENABLE_STATS +* @see #stats +*/ static struct db_stats { // Node alloc/free uint32 db_node_alloc; @@ -325,30 +325,30 @@ struct eri *db_iterator_ers; struct eri *db_alloc_ers; /*****************************************************************************\ - * (2) Section of private functions used by the database system. * - * db_rotate_left - Rotate a tree node to the left. * - * db_rotate_right - Rotate a tree node to the right. * - * db_rebalance - Rebalance the tree. * - * db_rebalance_erase - Rebalance the tree after a BLACK node was erased. * - * db_is_key_null - Returns not 0 if the key is considered NULL. * - * db_dup_key - Duplicate a key for internal use. * - * db_dup_key_free - Free the duplicated key. * - * db_free_add - Add a node to the free_list of a database. * - * db_free_remove - Remove a node from the free_list of a database. * - * db_free_lock - Increment the free_lock of a database. * - * db_free_unlock - Decrement the free_lock of a database. * - * If it was the last lock, frees the nodes in free_list. * - * NOTE: Keeps the database trees balanced. * +* (2) Section of private functions used by the database system. * +* db_rotate_left - Rotate a tree node to the left. * +* db_rotate_right - Rotate a tree node to the right. * +* db_rebalance - Rebalance the tree. * +* db_rebalance_erase - Rebalance the tree after a BLACK node was erased. * +* db_is_key_null - Returns not 0 if the key is considered NULL. * +* db_dup_key - Duplicate a key for internal use. * +* db_dup_key_free - Free the duplicated key. * +* db_free_add - Add a node to the free_list of a database. * +* db_free_remove - Remove a node from the free_list of a database. * +* db_free_lock - Increment the free_lock of a database. * +* db_free_unlock - Decrement the free_lock of a database. * +* If it was the last lock, frees the nodes in free_list. * +* NOTE: Keeps the database trees balanced. * \*****************************************************************************/ /** - * Rotate a node to the left. - * @param node Node to be rotated - * @param root Pointer to the root of the tree - * @private - * @see #db_rebalance(DBNode,DBNode *) - * @see #db_rebalance_erase(DBNode,DBNode *) - */ +* Rotate a node to the left. +* @param node Node to be rotated +* @param root Pointer to the root of the tree +* @private +* @see #db_rebalance(DBNode,DBNode *) +* @see #db_rebalance_erase(DBNode,DBNode *) +*/ static void db_rotate_left(DBNode node, DBNode *root) { DBNode y = node->right; @@ -373,13 +373,13 @@ static void db_rotate_left(DBNode node, DBNode *root) } /** - * Rotate a node to the right - * @param node Node to be rotated - * @param root Pointer to the root of the tree - * @private - * @see #db_rebalance(DBNode,DBNode *) - * @see #db_rebalance_erase(DBNode,DBNode *) - */ +* Rotate a node to the right +* @param node Node to be rotated +* @param root Pointer to the root of the tree +* @private +* @see #db_rebalance(DBNode,DBNode *) +* @see #db_rebalance_erase(DBNode,DBNode *) +*/ static void db_rotate_right(DBNode node, DBNode *root) { DBNode y = node->left; @@ -404,15 +404,15 @@ static void db_rotate_right(DBNode node, DBNode *root) } /** - * Rebalance the RED-BLACK tree. - * Called when the node and it's parent are both RED. - * @param node Node to be rebalanced - * @param root Pointer to the root of the tree - * @private - * @see #db_rotate_left(DBNode,DBNode *) - * @see #db_rotate_right(DBNode,DBNode *) - * @see #db_obj_put(DBMap*,DBKey,DBData) - */ +* Rebalance the RED-BLACK tree. +* Called when the node and it's parent are both RED. +* @param node Node to be rebalanced +* @param root Pointer to the root of the tree +* @private +* @see #db_rotate_left(DBNode,DBNode *) +* @see #db_rotate_right(DBNode,DBNode *) +* @see #db_obj_put(DBMap*,DBKey,DBData) +*/ static void db_rebalance(DBNode node, DBNode *root) { DBNode y; @@ -467,14 +467,14 @@ static void db_rebalance(DBNode node, DBNode *root) } /** - * Erase a node from the RED-BLACK tree, keeping the tree balanced. - * @param node Node to be erased from the tree - * @param root Root of the tree - * @private - * @see #db_rotate_left(DBNode,DBNode *) - * @see #db_rotate_right(DBNode,DBNode *) - * @see #db_free_unlock(DBMap_impl*) - */ +* Erase a node from the RED-BLACK tree, keeping the tree balanced. +* @param node Node to be erased from the tree +* @param root Root of the tree +* @private +* @see #db_rotate_left(DBNode,DBNode *) +* @see #db_rotate_right(DBNode,DBNode *) +* @see #db_free_unlock(DBMap_impl*) +*/ static void db_rebalance_erase(DBNode node, DBNode *root) { DBNode y = node; @@ -510,7 +510,7 @@ static void db_rebalance_erase(DBNode node, DBNode *root) // put the right of 'node' in 'y' y->right = node->right; node->right->parent = y; - // 'y' is a direct child of 'node' + // 'y' is a direct child of 'node' } else { x_parent = y; } @@ -558,9 +558,9 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } if ((w->left == NULL || w->left->color == BLACK) && (w->right == NULL || w->right->color == BLACK)) { - w->color = RED; - x = x_parent; - x_parent = x_parent->parent; + w->color = RED; + x = x_parent; + x_parent = x_parent->parent; } else { if (w->right == NULL || w->right->color == BLACK) { if (w->left) w->left->color = BLACK; @@ -584,9 +584,9 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } if ((w->right == NULL || w->right->color == BLACK) && (w->left == NULL || w->left->color == BLACK)) { - w->color = RED; - x = x_parent; - x_parent = x_parent->parent; + w->color = RED; + x = x_parent; + x_parent = x_parent->parent; } else { if (w->left == NULL || w->left->color == BLACK) { if (w->right) w->right->color = BLACK; @@ -607,39 +607,39 @@ static void db_rebalance_erase(DBNode node, DBNode *root) } /** - * Returns not 0 if the key is considered to be NULL. - * @param type Type of database - * @param key Key being tested - * @return not 0 if considered NULL, 0 otherwise - * @private - * @see #db_obj_get(DBMap*,DBKey) - * @see #db_obj_put(DBMap*,DBKey,DBData) - * @see #db_obj_remove(DBMap*,DBKey) - */ +* Returns not 0 if the key is considered to be NULL. +* @param type Type of database +* @param key Key being tested +* @return not 0 if considered NULL, 0 otherwise +* @private +* @see #db_obj_get(DBMap*,DBKey) +* @see #db_obj_put(DBMap*,DBKey,DBData) +* @see #db_obj_remove(DBMap*,DBKey) +*/ static int db_is_key_null(DBType type, DBKey key) { DB_COUNTSTAT(db_is_key_null); switch (type) { - case DB_STRING: - case DB_ISTRING: - return (key.str == NULL); + case DB_STRING: + case DB_ISTRING: + return (key.str == NULL); - default: // Not a pointer - return 0; + default: // Not a pointer + return 0; } } /** - * Duplicate the key used in the database. - * @param db Database the key is being used in - * @param key Key to be duplicated - * @param Duplicated key - * @private - * @see #db_free_add(DBMap_impl*,DBNode,DBNode *) - * @see #db_free_remove(DBMap_impl*,DBNode) - * @see #db_obj_put(DBMap*,DBKey,void *) - * @see #db_dup_key_free(DBMap_impl*,DBKey) - */ +* Duplicate the key used in the database. +* @param db Database the key is being used in +* @param key Key to be duplicated +* @param Duplicated key +* @private +* @see #db_free_add(DBMap_impl*,DBNode,DBNode *) +* @see #db_free_remove(DBMap_impl*,DBNode) +* @see #db_obj_put(DBMap*,DBKey,void *) +* @see #db_dup_key_free(DBMap_impl*,DBKey) +*/ static DBKey db_dup_key(DBMap_impl* db, DBKey key) { char *str; @@ -647,56 +647,56 @@ static DBKey db_dup_key(DBMap_impl* db, DBKey key) DB_COUNTSTAT(db_dup_key); switch (db->type) { - case DB_STRING: - case DB_ISTRING: - len = strnlen(key.str, db->maxlen); - str = (char*)aMalloc(len + 1); - memcpy(str, key.str, len); - str[len] = '\0'; - key.str = str; - return key; - - default: - return key; + case DB_STRING: + case DB_ISTRING: + len = strnlen(key.str, db->maxlen); + str = (char*)aMalloc(len + 1); + memcpy(str, key.str, len); + str[len] = '\0'; + key.str = str; + return key; + + default: + return key; } } /** - * Free a key duplicated by db_dup_key. - * @param db Database the key is being used in - * @param key Key to be freed - * @private - * @see #db_dup_key(DBMap_impl*,DBKey) - */ +* Free a key duplicated by db_dup_key. +* @param db Database the key is being used in +* @param key Key to be freed +* @private +* @see #db_dup_key(DBMap_impl*,DBKey) +*/ static void db_dup_key_free(DBMap_impl* db, DBKey key) { DB_COUNTSTAT(db_dup_key_free); switch (db->type) { - case DB_STRING: - case DB_ISTRING: - aFree((char*)key.str); - return; + case DB_STRING: + case DB_ISTRING: + aFree((char*)key.str); + return; - default: - return; + default: + return; } } /** - * Add a node to the free_list of the database. - * Marks the node as deleted. - * If the key isn't duplicated, the key is duplicated and released. - * @param db Target database - * @param root Root of the tree from the node - * @param node Target node - * @private - * @see #struct db_free - * @see DBMap_impl#free_list - * @see DBMap_impl#free_count - * @see DBMap_impl#free_max - * @see #db_obj_remove(DBMap*,DBKey) - * @see #db_free_remove(DBMap_impl*,DBNode) - */ +* Add a node to the free_list of the database. +* Marks the node as deleted. +* If the key isn't duplicated, the key is duplicated and released. +* @param db Target database +* @param root Root of the tree from the node +* @param node Target node +* @private +* @see #struct db_free +* @see DBMap_impl#free_list +* @see DBMap_impl#free_count +* @see DBMap_impl#free_max +* @see #db_obj_remove(DBMap*,DBKey) +* @see #db_free_remove(DBMap_impl*,DBNode) +*/ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) { DBKey old_key; @@ -704,8 +704,8 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) DB_COUNTSTAT(db_free_add); if (db->free_lock == (unsigned int)~0) { ShowFatalError("db_free_add: free_lock overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } if (!(db->options&DB_OPT_DUP_KEY)) { // Make sure we have a key until the node is freed @@ -718,8 +718,8 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) if (db->free_max <= db->free_count) { if (db->free_count == (unsigned int)~0) { ShowFatalError("db_free_add: free_count overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } db->free_max = (unsigned int)~0; @@ -734,18 +734,18 @@ static void db_free_add(DBMap_impl* db, DBNode node, DBNode *root) } /** - * Remove a node from the free_list of the database. - * Marks the node as not deleted. - * NOTE: Frees the duplicated key of the node. - * @param db Target database - * @param node Node being removed from free_list - * @private - * @see #struct db_free - * @see DBMap_impl#free_list - * @see DBMap_impl#free_count - * @see #db_obj_put(DBMap*,DBKey,DBData) - * @see #db_free_add(DBMap_impl*,DBNode*,DBNode) - */ +* Remove a node from the free_list of the database. +* Marks the node as not deleted. +* NOTE: Frees the duplicated key of the node. +* @param db Target database +* @param node Node being removed from free_list +* @private +* @see #struct db_free +* @see DBMap_impl#free_list +* @see DBMap_impl#free_count +* @see #db_obj_put(DBMap*,DBKey,DBData) +* @see #db_free_add(DBMap_impl*,DBNode*,DBNode) +*/ static void db_free_remove(DBMap_impl* db, DBNode node) { unsigned int i; @@ -769,35 +769,35 @@ static void db_free_remove(DBMap_impl* db, DBNode node) } /** - * Increment the free_lock of the database. - * @param db Target database - * @private - * @see DBMap_impl#free_lock - * @see #db_unlock(DBMap_impl*) - */ +* Increment the free_lock of the database. +* @param db Target database +* @private +* @see DBMap_impl#free_lock +* @see #db_unlock(DBMap_impl*) +*/ static void db_free_lock(DBMap_impl* db) { DB_COUNTSTAT(db_free_lock); if (db->free_lock == (unsigned int)~0) { ShowFatalError("db_free_lock: free_lock overflow\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); exit(EXIT_FAILURE); } db->free_lock++; } /** - * Decrement the free_lock of the database. - * If it was the last lock, frees the nodes of the database. - * Keeps the tree balanced. - * NOTE: Frees the duplicated keys of the nodes - * @param db Target database - * @private - * @see DBMap_impl#free_lock - * @see #db_free_dbn(DBNode) - * @see #db_lock(DBMap_impl*) - */ +* Decrement the free_lock of the database. +* If it was the last lock, frees the nodes of the database. +* Keeps the tree balanced. +* NOTE: Frees the duplicated keys of the nodes +* @param db Target database +* @private +* @see DBMap_impl#free_lock +* @see #db_free_dbn(DBNode) +* @see #db_lock(DBMap_impl*) +*/ static void db_free_unlock(DBMap_impl* db) { unsigned int i; @@ -805,8 +805,8 @@ static void db_free_unlock(DBMap_impl* db) DB_COUNTSTAT(db_free_unlock); if (db->free_lock == 0) { ShowWarning("db_free_unlock: free_lock was already 0\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); } else { db->free_lock--; } @@ -823,36 +823,36 @@ static void db_free_unlock(DBMap_impl* db) } /*****************************************************************************\ - * (3) Section of protected functions used internally. * - * NOTE: the protected functions used in the database interface are in the * - * next section. * - * db_int_cmp - Default comparator for DB_INT databases. * - * db_uint_cmp - Default comparator for DB_UINT databases. * - * db_string_cmp - Default comparator for DB_STRING databases. * - * db_istring_cmp - Default comparator for DB_ISTRING databases. * - * db_int_hash - Default hasher for DB_INT databases. * - * db_uint_hash - Default hasher for DB_UINT databases. * - * db_string_hash - Default hasher for DB_STRING databases. * - * db_istring_hash - Default hasher for DB_ISTRING databases. * - * db_release_nothing - Releaser that releases nothing. * - * db_release_key - Releaser that only releases the key. * - * db_release_data - Releaser that only releases the data. * - * db_release_both - Releaser that releases key and data. * +* (3) Section of protected functions used internally. * +* NOTE: the protected functions used in the database interface are in the * +* next section. * +* db_int_cmp - Default comparator for DB_INT databases. * +* db_uint_cmp - Default comparator for DB_UINT databases. * +* db_string_cmp - Default comparator for DB_STRING databases. * +* db_istring_cmp - Default comparator for DB_ISTRING databases. * +* db_int_hash - Default hasher for DB_INT databases. * +* db_uint_hash - Default hasher for DB_UINT databases. * +* db_string_hash - Default hasher for DB_STRING databases. * +* db_istring_hash - Default hasher for DB_ISTRING databases. * +* db_release_nothing - Releaser that releases nothing. * +* db_release_key - Releaser that only releases the key. * +* db_release_data - Releaser that only releases the data. * +* db_release_both - Releaser that releases key and data. * \*****************************************************************************/ /** - * Default comparator for DB_INT databases. - * Compares key1 to key2. - * Return 0 if equal, negative if lower and positive if higher. - * maxlen is ignored. - * @param key1 Key to be compared - * @param key2 Key being compared to - * @param maxlen Maximum length of the key to hash - * @return 0 if equal, negative if lower and positive if higher - * @see DBType#DB_INT - * @see #DBComparator - * @see #db_default_cmp(DBType) - */ +* Default comparator for DB_INT databases. +* Compares key1 to key2. +* Return 0 if equal, negative if lower and positive if higher. +* maxlen is ignored. +* @param key1 Key to be compared +* @param key2 Key being compared to +* @param maxlen Maximum length of the key to hash +* @return 0 if equal, negative if lower and positive if higher +* @see DBType#DB_INT +* @see #DBComparator +* @see #db_default_cmp(DBType) +*/ static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { (void)maxlen;//not used @@ -863,18 +863,18 @@ static int db_int_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** - * Default comparator for DB_UINT databases. - * Compares key1 to key2. - * Return 0 if equal, negative if lower and positive if higher. - * maxlen is ignored. - * @param key1 Key to be compared - * @param key2 Key being compared to - * @param maxlen Maximum length of the key to hash - * @return 0 if equal, negative if lower and positive if higher - * @see DBType#DB_UINT - * @see #DBComparator - * @see #db_default_cmp(DBType) - */ +* Default comparator for DB_UINT databases. +* Compares key1 to key2. +* Return 0 if equal, negative if lower and positive if higher. +* maxlen is ignored. +* @param key1 Key to be compared +* @param key2 Key being compared to +* @param maxlen Maximum length of the key to hash +* @return 0 if equal, negative if lower and positive if higher +* @see DBType#DB_UINT +* @see #DBComparator +* @see #db_default_cmp(DBType) +*/ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { (void)maxlen;//not used @@ -885,17 +885,17 @@ static int db_uint_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** - * Default comparator for DB_STRING databases. - * Compares key1 to key2. - * Return 0 if equal, negative if lower and positive if higher. - * @param key1 Key to be compared - * @param key2 Key being compared to - * @param maxlen Maximum length of the key to hash - * @return 0 if equal, negative if lower and positive if higher - * @see DBType#DB_STRING - * @see #DBComparator - * @see #db_default_cmp(DBType) - */ +* Default comparator for DB_STRING databases. +* Compares key1 to key2. +* Return 0 if equal, negative if lower and positive if higher. +* @param key1 Key to be compared +* @param key2 Key being compared to +* @param maxlen Maximum length of the key to hash +* @return 0 if equal, negative if lower and positive if higher +* @see DBType#DB_STRING +* @see #DBComparator +* @see #db_default_cmp(DBType) +*/ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { DB_COUNTSTAT(db_string_cmp); @@ -903,17 +903,17 @@ static int db_string_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** - * Default comparator for DB_ISTRING databases. - * Compares key1 to key2 case insensitively. - * Return 0 if equal, negative if lower and positive if higher. - * @param key1 Key to be compared - * @param key2 Key being compared to - * @param maxlen Maximum length of the key to hash - * @return 0 if equal, negative if lower and positive if higher - * @see DBType#DB_ISTRING - * @see #DBComparator - * @see #db_default_cmp(DBType) - */ +* Default comparator for DB_ISTRING databases. +* Compares key1 to key2 case insensitively. +* Return 0 if equal, negative if lower and positive if higher. +* @param key1 Key to be compared +* @param key2 Key being compared to +* @param maxlen Maximum length of the key to hash +* @return 0 if equal, negative if lower and positive if higher +* @see DBType#DB_ISTRING +* @see #DBComparator +* @see #db_default_cmp(DBType) +*/ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) { DB_COUNTSTAT(db_istring_cmp); @@ -921,16 +921,16 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** - * Default hasher for DB_INT databases. - * Returns the value of the key as an unsigned int. - * maxlen is ignored. - * @param key Key to be hashed - * @param maxlen Maximum length of the key to hash - * @return hash of the key - * @see DBType#DB_INT - * @see #DBHasher - * @see #db_default_hash(DBType) - */ +* Default hasher for DB_INT databases. +* Returns the value of the key as an unsigned int. +* maxlen is ignored. +* @param key Key to be hashed +* @param maxlen Maximum length of the key to hash +* @return hash of the key +* @see DBType#DB_INT +* @see #DBHasher +* @see #db_default_hash(DBType) +*/ static unsigned int db_int_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used @@ -939,16 +939,16 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen) } /** - * Default hasher for DB_UINT databases. - * Just returns the value of the key. - * maxlen is ignored. - * @param key Key to be hashed - * @param maxlen Maximum length of the key to hash - * @return hash of the key - * @see DBType#DB_UINT - * @see #DBHasher - * @see #db_default_hash(DBType) - */ +* Default hasher for DB_UINT databases. +* Just returns the value of the key. +* maxlen is ignored. +* @param key Key to be hashed +* @param maxlen Maximum length of the key to hash +* @return hash of the key +* @see DBType#DB_UINT +* @see #DBHasher +* @see #db_default_hash(DBType) +*/ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used @@ -957,14 +957,14 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) } /** - * Default hasher for DB_STRING databases. - * @param key Key to be hashed - * @param maxlen Maximum length of the key to hash - * @return hash of the key - * @see DBType#DB_STRING - * @see #DBHasher - * @see #db_default_hash(DBType) - */ +* Default hasher for DB_STRING databases. +* @param key Key to be hashed +* @param maxlen Maximum length of the key to hash +* @return hash of the key +* @see DBType#DB_STRING +* @see #DBHasher +* @see #db_default_hash(DBType) +*/ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; @@ -984,13 +984,13 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) } /** - * Default hasher for DB_ISTRING databases. - * @param key Key to be hashed - * @param maxlen Maximum length of the key to hash - * @return hash of the key - * @see DBType#DB_ISTRING - * @see #db_default_hash(DBType) - */ +* Default hasher for DB_ISTRING databases. +* @param key Key to be hashed +* @param maxlen Maximum length of the key to hash +* @return hash of the key +* @see DBType#DB_ISTRING +* @see #db_default_hash(DBType) +*/ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; @@ -1010,14 +1010,14 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) } /** - * Releaser that releases nothing. - * @param key Key of the database entry - * @param data Data of the database entry - * @param which What is being requested to be released - * @protected - * @see #DBReleaser - * @see #db_default_releaser(DBType,DBOptions) - */ +* Releaser that releases nothing. +* @param key Key of the database entry +* @param data Data of the database entry +* @param which What is being requested to be released +* @protected +* @see #DBReleaser +* @see #db_default_releaser(DBType,DBOptions) +*/ static void db_release_nothing(DBKey key, DBData data, DBRelease which) { (void)key;(void)data;(void)which;//not used @@ -1025,14 +1025,14 @@ static void db_release_nothing(DBKey key, DBData data, DBRelease which) } /** - * Releaser that only releases the key. - * @param key Key of the database entry - * @param data Data of the database entry - * @param which What is being requested to be released - * @protected - * @see #DBReleaser - * @see #db_default_release(DBType,DBOptions) - */ +* Releaser that only releases the key. +* @param key Key of the database entry +* @param data Data of the database entry +* @param which What is being requested to be released +* @protected +* @see #DBReleaser +* @see #db_default_release(DBType,DBOptions) +*/ static void db_release_key(DBKey key, DBData data, DBRelease which) { (void)data;//not used @@ -1041,16 +1041,16 @@ static void db_release_key(DBKey key, DBData data, DBRelease which) } /** - * Releaser that only releases the data. - * @param key Key of the database entry - * @param data Data of the database entry - * @param which What is being requested to be released - * @protected - * @see #DBData - * @see #DBRelease - * @see #DBReleaser - * @see #db_default_release(DBType,DBOptions) - */ +* Releaser that only releases the data. +* @param key Key of the database entry +* @param data Data of the database entry +* @param which What is being requested to be released +* @protected +* @see #DBData +* @see #DBRelease +* @see #DBReleaser +* @see #db_default_release(DBType,DBOptions) +*/ static void db_release_data(DBKey key, DBData data, DBRelease which) { (void)key;//not used @@ -1059,17 +1059,17 @@ static void db_release_data(DBKey key, DBData data, DBRelease which) } /** - * Releaser that releases both key and data. - * @param key Key of the database entry - * @param data Data of the database entry - * @param which What is being requested to be released - * @protected - * @see #DBKey - * @see #DBData - * @see #DBRelease - * @see #DBReleaser - * @see #db_default_release(DBType,DBOptions) - */ +* Releaser that releases both key and data. +* @param key Key of the database entry +* @param data Data of the database entry +* @param which What is being requested to be released +* @protected +* @see #DBKey +* @see #DBData +* @see #DBRelease +* @see #DBReleaser +* @see #db_default_release(DBType,DBOptions) +*/ static void db_release_both(DBKey key, DBData data, DBRelease which) { DB_COUNTSTAT(db_release_both); @@ -1078,52 +1078,52 @@ static void db_release_both(DBKey key, DBData data, DBRelease which) } /*****************************************************************************\ - * (4) Section with protected functions used in the interface of the * - * database and interface of the iterator. * - * dbit_obj_first - Fetches the first entry from the database. * - * dbit_obj_last - Fetches the last entry from the database. * - * dbit_obj_next - Fetches the next entry from the database. * - * dbit_obj_prev - Fetches the previous entry from the database. * - * dbit_obj_exists - Returns true if the current entry exists. * - * dbit_obj_remove - Remove the current entry from the database. * - * dbit_obj_destroy - Destroys the iterator, unlocking the database and * - * freeing used memory. * - * db_obj_iterator - Return a new database iterator. * - * db_obj_exists - Checks if an entry exists. * - * db_obj_get - Get the data identified by the key. * - * db_obj_vgetall - Get the data of the matched entries. * - * db_obj_getall - Get the data of the matched entries. * - * db_obj_vensure - Get the data identified by the key, creating if it * - * doesn't exist yet. * - * db_obj_ensure - Get the data identified by the key, creating if it * - * doesn't exist yet. * - * db_obj_put - Put data identified by the key in the database. * - * db_obj_remove - Remove an entry from the database. * - * db_obj_vforeach - Apply a function to every entry in the database. * - * db_obj_foreach - Apply a function to every entry in the database. * - * db_obj_vclear - Remove all entries from the database. * - * db_obj_clear - Remove all entries from the database. * - * db_obj_vdestroy - Destroy the database, freeing all the used memory. * - * db_obj_destroy - Destroy the database, freeing all the used memory. * - * db_obj_size - Return the size of the database. * - * db_obj_type - Return the type of the database. * - * db_obj_options - Return the options of the database. * +* (4) Section with protected functions used in the interface of the * +* database and interface of the iterator. * +* dbit_obj_first - Fetches the first entry from the database. * +* dbit_obj_last - Fetches the last entry from the database. * +* dbit_obj_next - Fetches the next entry from the database. * +* dbit_obj_prev - Fetches the previous entry from the database. * +* dbit_obj_exists - Returns true if the current entry exists. * +* dbit_obj_remove - Remove the current entry from the database. * +* dbit_obj_destroy - Destroys the iterator, unlocking the database and * +* freeing used memory. * +* db_obj_iterator - Return a new database iterator. * +* db_obj_exists - Checks if an entry exists. * +* db_obj_get - Get the data identified by the key. * +* db_obj_vgetall - Get the data of the matched entries. * +* db_obj_getall - Get the data of the matched entries. * +* db_obj_vensure - Get the data identified by the key, creating if it * +* doesn't exist yet. * +* db_obj_ensure - Get the data identified by the key, creating if it * +* doesn't exist yet. * +* db_obj_put - Put data identified by the key in the database. * +* db_obj_remove - Remove an entry from the database. * +* db_obj_vforeach - Apply a function to every entry in the database. * +* db_obj_foreach - Apply a function to every entry in the database. * +* db_obj_vclear - Remove all entries from the database. * +* db_obj_clear - Remove all entries from the database. * +* db_obj_vdestroy - Destroy the database, freeing all the used memory. * +* db_obj_destroy - Destroy the database, freeing all the used memory. * +* db_obj_size - Return the size of the database. * +* db_obj_type - Return the type of the database. * +* db_obj_options - Return the options of the database. * \*****************************************************************************/ /** - * Fetches the first entry in the database. - * Returns the data of the entry. - * Puts the key in out_key, if out_key is not NULL. - * @param self Iterator - * @param out_key Key of the entry - * @return Data of the entry - * @protected - * @see DBIterator#first - */ +* Fetches the first entry in the database. +* Returns the data of the entry. +* Puts the key in out_key, if out_key is not NULL. +* @param self Iterator +* @param out_key Key of the entry +* @return Data of the entry +* @protected +* @see DBIterator#first +*/ DBData* dbit_obj_first(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; - + DB_COUNTSTAT(dbit_first); // position before the first entry it->ht_index = -1; @@ -1133,19 +1133,19 @@ DBData* dbit_obj_first(DBIterator* self, DBKey* out_key) } /** - * Fetches the last entry in the database. - * Returns the data of the entry. - * Puts the key in out_key, if out_key is not NULL. - * @param self Iterator - * @param out_key Key of the entry - * @return Data of the entry - * @protected - * @see DBIterator#last - */ +* Fetches the last entry in the database. +* Returns the data of the entry. +* Puts the key in out_key, if out_key is not NULL. +* @param self Iterator +* @param out_key Key of the entry +* @return Data of the entry +* @protected +* @see DBIterator#last +*/ DBData* dbit_obj_last(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; - + DB_COUNTSTAT(dbit_last); // position after the last entry it->ht_index = HASH_SIZE; @@ -1155,15 +1155,15 @@ DBData* dbit_obj_last(DBIterator* self, DBKey* out_key) } /** - * Fetches the next entry in the database. - * Returns the data of the entry. - * Puts the key in out_key, if out_key is not NULL. - * @param self Iterator - * @param out_key Key of the entry - * @return Data of the entry - * @protected - * @see DBIterator#next - */ +* Fetches the next entry in the database. +* Returns the data of the entry. +* Puts the key in out_key, if out_key is not NULL. +* @param self Iterator +* @param out_key Key of the entry +* @return Data of the entry +* @protected +* @see DBIterator#next +*/ DBData* dbit_obj_next(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1231,15 +1231,15 @@ DBData* dbit_obj_next(DBIterator* self, DBKey* out_key) } /** - * Fetches the previous entry in the database. - * Returns the data of the entry. - * Puts the key in out_key, if out_key is not NULL. - * @param self Iterator - * @param out_key Key of the entry - * @return Data of the entry - * @protected - * @see DBIterator#prev - */ +* Fetches the previous entry in the database. +* Returns the data of the entry. +* Puts the key in out_key, if out_key is not NULL. +* @param self Iterator +* @param out_key Key of the entry +* @return Data of the entry +* @protected +* @see DBIterator#prev +*/ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1267,7 +1267,7 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) node = &fake; } - + while( node ) {// next node if( node->left ) @@ -1308,14 +1308,14 @@ DBData* dbit_obj_prev(DBIterator* self, DBKey* out_key) } /** - * Returns true if the fetched entry exists. - * The databases entries might have NULL data, so use this to to test if - * the iterator is done. - * @param self Iterator - * @return true if the entry exists - * @protected - * @see DBIterator#exists - */ +* Returns true if the fetched entry exists. +* The databases entries might have NULL data, so use this to to test if +* the iterator is done. +* @param self Iterator +* @return true if the entry exists +* @protected +* @see DBIterator#exists +*/ bool dbit_obj_exists(DBIterator* self) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1325,17 +1325,17 @@ bool dbit_obj_exists(DBIterator* self) } /** - * Removes the current entry from the database. - * NOTE: {@link DBIterator#exists} will return false until another entry - * is fetched - * Puts data of the removed entry in out_data, if out_data is not NULL. - * @param self Iterator - * @param out_data Data of the removed entry. - * @return 1 if entry was removed, 0 otherwise - * @protected - * @see DBMap#remove - * @see DBIterator#remove - */ +* Removes the current entry from the database. +* NOTE: {@link DBIterator#exists} will return false until another entry +* is fetched +* Puts data of the removed entry in out_data, if out_data is not NULL. +* @param self Iterator +* @param out_data Data of the removed entry. +* @return 1 if entry was removed, 0 otherwise +* @protected +* @see DBMap#remove +* @see DBIterator#remove +*/ int dbit_obj_remove(DBIterator* self, DBData *out_data) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1359,10 +1359,10 @@ int dbit_obj_remove(DBIterator* self, DBData *out_data) } /** - * Destroys this iterator and unlocks the database. - * @param self Iterator - * @protected - */ +* Destroys this iterator and unlocks the database. +* @param self Iterator +* @protected +*/ void dbit_obj_destroy(DBIterator* self) { DBIterator_impl* it = (DBIterator_impl*)self; @@ -1375,14 +1375,14 @@ void dbit_obj_destroy(DBIterator* self) } /** - * Returns a new iterator for this database. - * The iterator keeps the database locked until it is destroyed. - * The database will keep functioning normally but will only free internal - * memory when unlocked, so destroy the iterator as soon as possible. - * @param self Database - * @return New iterator - * @protected - */ +* Returns a new iterator for this database. +* The iterator keeps the database locked until it is destroyed. +* The database will keep functioning normally but will only free internal +* memory when unlocked, so destroy the iterator as soon as possible. +* @param self Database +* @return New iterator +* @protected +*/ static DBIterator* db_obj_iterator(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -1408,13 +1408,13 @@ static DBIterator* db_obj_iterator(DBMap* self) } /** - * Returns true if the entry exists. - * @param self Interface of the database - * @param key Key that identifies the entry - * @return true is the entry exists - * @protected - * @see DBMap#exists - */ +* Returns true if the entry exists. +* @param self Interface of the database +* @param key Key that identifies the entry +* @return true is the entry exists +* @protected +* @see DBMap#exists +*/ static bool db_obj_exists(DBMap* self, DBKey key) { DBMap_impl* db = (DBMap_impl*)self; @@ -1459,13 +1459,13 @@ static bool db_obj_exists(DBMap* self, DBKey key) } /** - * Get the data of the entry identified by the key. - * @param self Interface of the database - * @param key Key that identifies the entry - * @return Data of the entry or NULL if not found - * @protected - * @see DBMap#get - */ +* Get the data of the entry identified by the key. +* @param self Interface of the database +* @param key Key that identifies the entry +* @return Data of the entry or NULL if not found +* @protected +* @see DBMap#get +*/ static DBData* db_obj_get(DBMap* self, DBKey key) { DBMap_impl* db = (DBMap_impl*)self; @@ -1511,21 +1511,21 @@ static DBData* db_obj_get(DBMap* self, DBKey key) } /** - * Get the data of the entries matched by match. - * It puts a maximum of max entries into buf. - * If buf is NULL, it only counts the matches. - * Returns the number of entries that matched. - * NOTE: if the value returned is greater than max, only the - * first max entries found are put into the buffer. - * @param self Interface of the database - * @param buf Buffer to put the data of the matched entries - * @param max Maximum number of data entries to be put into buf - * @param match Function that matches the database entries - * @param ... Extra arguments for match - * @return The number of entries that matched - * @protected - * @see DBMap#vgetall - */ +* Get the data of the entries matched by match. +* It puts a maximum of max entries into buf. +* If buf is NULL, it only counts the matches. +* Returns the number of entries that matched. +* NOTE: if the value returned is greater than max, only the +* first max entries found are put into the buffer. +* @param self Interface of the database +* @param buf Buffer to put the data of the matched entries +* @param max Maximum number of data entries to be put into buf +* @param match Function that matches the database entries +* @param ... Extra arguments for match +* @return The number of entries that matched +* @protected +* @see DBMap#vgetall +*/ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1554,17 +1554,17 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, } va_end(argscopy); } - + if (node->left) { node = node->left; continue; } - + if (node->right) { node = node->right; continue; } - + while (node) { parent = node->parent; if (parent && parent->right && parent->left == node) { @@ -1581,23 +1581,23 @@ static unsigned int db_obj_vgetall(DBMap* self, DBData **buf, unsigned int max, } /** - * Just calls {@link DBMap#vgetall}. - * Get the data of the entries matched by match. - * It puts a maximum of max entries into buf. - * If buf is NULL, it only counts the matches. - * Returns the number of entries that matched. - * NOTE: if the value returned is greater than max, only the - * first max entries found are put into the buffer. - * @param self Interface of the database - * @param buf Buffer to put the data of the matched entries - * @param max Maximum number of data entries to be put into buf - * @param match Function that matches the database entries - * @param ... Extra arguments for match - * @return The number of entries that matched - * @protected - * @see DBMap#vgetall - * @see DBMap#getall - */ +* Just calls {@link DBMap#vgetall}. +* Get the data of the entries matched by match. +* It puts a maximum of max entries into buf. +* If buf is NULL, it only counts the matches. +* Returns the number of entries that matched. +* NOTE: if the value returned is greater than max, only the +* first max entries found are put into the buffer. +* @param self Interface of the database +* @param buf Buffer to put the data of the matched entries +* @param max Maximum number of data entries to be put into buf +* @param match Function that matches the database entries +* @param ... Extra arguments for match +* @return The number of entries that matched +* @protected +* @see DBMap#vgetall +* @see DBMap#getall +*/ static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, DBMatcher match, ...) { va_list args; @@ -1613,17 +1613,17 @@ static unsigned int db_obj_getall(DBMap* self, DBData **buf, unsigned int max, D } /** - * Get the data of the entry identified by the key. - * If the entry does not exist, an entry is added with the data returned by - * create. - * @param self Interface of the database - * @param key Key that identifies the entry - * @param create Function used to create the data if the entry doesn't exist - * @param args Extra arguments for create - * @return Data of the entry - * @protected - * @see DBMap#vensure - */ +* Get the data of the entry identified by the key. +* If the entry does not exist, an entry is added with the data returned by +* create. +* @param self Interface of the database +* @param key Key that identifies the entry +* @param create Function used to create the data if the entry doesn't exist +* @param args Extra arguments for create +* @return Data of the entry +* @protected +* @see DBMap#vensure +*/ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1666,9 +1666,9 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li va_list argscopy; if (db->item_count == UINT32_MAX) { ShowError("db_vensure: item_count overflow, aborting item insertion.\n" - "Database allocated at %s:%d", - db->alloc_file, db->alloc_line); - return NULL; + "Database allocated at %s:%d", + db->alloc_file, db->alloc_line); + return NULL; } DB_COUNTSTAT(db_node_alloc); node = ers_alloc(db->nodes, struct dbn); @@ -1711,19 +1711,19 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li } /** - * Just calls {@link DBMap#vensure}. - * Get the data of the entry identified by the key. - * If the entry does not exist, an entry is added with the data returned by - * create. - * @param self Interface of the database - * @param key Key that identifies the entry - * @param create Function used to create the data if the entry doesn't exist - * @param ... Extra arguments for create - * @return Data of the entry - * @protected - * @see DBMap#vensure - * @see DBMap#ensure - */ +* Just calls {@link DBMap#vensure}. +* Get the data of the entry identified by the key. +* If the entry does not exist, an entry is added with the data returned by +* create. +* @param self Interface of the database +* @param key Key that identifies the entry +* @param create Function used to create the data if the entry doesn't exist +* @param ... Extra arguments for create +* @return Data of the entry +* @protected +* @see DBMap#vensure +* @see DBMap#ensure +*/ static DBData* db_obj_ensure(DBMap* self, DBKey key, DBCreateData create, ...) { va_list args; @@ -1739,18 +1739,18 @@ static DBData* db_obj_ensure(DBMap* self, DBKey key, DBCreateData create, ...) } /** - * Put the data identified by the key in the database. - * Puts the previous data in out_data, if out_data is not NULL. - * NOTE: Uses the new key, the old one is released. - * @param self Interface of the database - * @param key Key that identifies the data - * @param data Data to be put in the database - * @param out_data Previous data if the entry exists - * @return 1 if if the entry already exists, 0 otherwise - * @protected - * @see #db_malloc_dbn(void) - * @see DBMap#put - */ +* Put the data identified by the key in the database. +* Puts the previous data in out_data, if out_data is not NULL. +* NOTE: Uses the new key, the old one is released. +* @param self Interface of the database +* @param key Key that identifies the data +* @param data Data to be put in the database +* @param out_data Previous data if the entry exists +* @return 1 if if the entry already exists, 0 otherwise +* @protected +* @see #db_malloc_dbn(void) +* @see DBMap#put +*/ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) { DBMap_impl* db = (DBMap_impl*)self; @@ -1763,8 +1763,8 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_put: Database is being destroyed, aborting entry insertion.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; // nullpo candidate } if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) { @@ -1778,8 +1778,8 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) if (db->item_count == UINT32_MAX) { ShowError("db_put: item_count overflow, aborting item insertion.\n" - "Database allocated at %s:%d", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d", + db->alloc_file, db->alloc_line); return 0; } // search for an equal node @@ -1845,17 +1845,17 @@ static int db_obj_put(DBMap* self, DBKey key, DBData data, DBData *out_data) } /** - * Remove an entry from the database. - * Puts the previous data in out_data, if out_data is not NULL. - * NOTE: The key (of the database) is released in {@link #db_free_add(DBMap_impl*,DBNode,DBNode *)}. - * @param self Interface of the database - * @param key Key that identifies the entry - * @param out_data Previous data if the entry exists - * @return 1 if if the entry already exists, 0 otherwise - * @protected - * @see #db_free_add(DBMap_impl*,DBNode,DBNode *) - * @see DBMap#remove - */ +* Remove an entry from the database. +* Puts the previous data in out_data, if out_data is not NULL. +* NOTE: The key (of the database) is released in {@link #db_free_add(DBMap_impl*,DBNode,DBNode *)}. +* @param self Interface of the database +* @param key Key that identifies the entry +* @param out_data Previous data if the entry exists +* @return 1 if if the entry already exists, 0 otherwise +* @protected +* @see #db_free_add(DBMap_impl*,DBNode,DBNode *) +* @see DBMap#remove +*/ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) { DBMap_impl* db = (DBMap_impl*)self; @@ -1867,8 +1867,8 @@ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_remove: Database is being destroyed. Aborting entry deletion.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; // nullpo candidate } if (!(db->options&DB_OPT_ALLOW_NULL_KEY) && db_is_key_null(db->type, key)) { @@ -1902,15 +1902,15 @@ static int db_obj_remove(DBMap* self, DBKey key, DBData *out_data) } /** - * Apply func to every entry in the database. - * Returns the sum of values returned by func. - * @param self Interface of the database - * @param func Function to be applied - * @param args Extra arguments for func - * @return Sum of the values returned by func - * @protected - * @see DBMap#vforeach - */ +* Apply func to every entry in the database. +* Returns the sum of values returned by func. +* @param self Interface of the database +* @param func Function to be applied +* @param args Extra arguments for func +* @return Sum of the values returned by func +* @protected +* @see DBMap#vforeach +*/ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -1960,17 +1960,17 @@ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args) } /** - * Just calls {@link DBMap#vforeach}. - * Apply func to every entry in the database. - * Returns the sum of values returned by func. - * @param self Interface of the database - * @param func Function to be applyed - * @param ... Extra arguments for func - * @return Sum of the values returned by func - * @protected - * @see DBMap#vforeach - * @see DBMap#foreach - */ +* Just calls {@link DBMap#vforeach}. +* Apply func to every entry in the database. +* Returns the sum of values returned by func. +* @param self Interface of the database +* @param func Function to be applyed +* @param ... Extra arguments for func +* @return Sum of the values returned by func +* @protected +* @see DBMap#vforeach +* @see DBMap#foreach +*/ static int db_obj_foreach(DBMap* self, DBApply func, ...) { va_list args; @@ -1986,17 +1986,17 @@ static int db_obj_foreach(DBMap* self, DBApply func, ...) } /** - * Removes all entries from the database. - * Before deleting an entry, func is applied to it. - * Releases the key and the data. - * Returns the sum of values returned by func, if it exists. - * @param self Interface of the database - * @param func Function to be applied to every entry before deleting - * @param args Extra arguments for func - * @return Sum of values returned by func - * @protected - * @see DBMap#vclear - */ +* Removes all entries from the database. +* Before deleting an entry, func is applied to it. +* Releases the key and the data. +* Returns the sum of values returned by func, if it exists. +* @param self Interface of the database +* @param func Function to be applied to every entry before deleting +* @param args Extra arguments for func +* @return Sum of values returned by func +* @protected +* @see DBMap#vclear +*/ static int db_obj_vclear(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -2056,21 +2056,21 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args) } /** - * Just calls {@link DBMap#vclear}. - * Removes all entries from the database. - * Before deleting an entry, func is applied to it. - * Releases the key and the data. - * Returns the sum of values returned by func, if it exists. - * NOTE: This locks the database globally. Any attempt to insert or remove - * a database entry will give an error and be aborted (except for clearing). - * @param self Interface of the database - * @param func Function to be applied to every entry before deleting - * @param ... Extra arguments for func - * @return Sum of values returned by func - * @protected - * @see DBMap#vclear - * @see DBMap#clear - */ +* Just calls {@link DBMap#vclear}. +* Removes all entries from the database. +* Before deleting an entry, func is applied to it. +* Releases the key and the data. +* Returns the sum of values returned by func, if it exists. +* NOTE: This locks the database globally. Any attempt to insert or remove +* a database entry will give an error and be aborted (except for clearing). +* @param self Interface of the database +* @param func Function to be applied to every entry before deleting +* @param ... Extra arguments for func +* @return Sum of values returned by func +* @protected +* @see DBMap#vclear +* @see DBMap#clear +*/ static int db_obj_clear(DBMap* self, DBApply func, ...) { va_list args; @@ -2086,18 +2086,18 @@ static int db_obj_clear(DBMap* self, DBApply func, ...) } /** - * Finalize the database, feeing all the memory it uses. - * Before deleting an entry, func is applied to it. - * Returns the sum of values returned by func, if it exists. - * NOTE: This locks the database globally. Any attempt to insert or remove - * a database entry will give an error and be aborted (except for clearing). - * @param self Interface of the database - * @param func Function to be applied to every entry before deleting - * @param args Extra arguments for func - * @return Sum of values returned by func - * @protected - * @see DBMap#vdestroy - */ +* Finalize the database, feeing all the memory it uses. +* Before deleting an entry, func is applied to it. +* Returns the sum of values returned by func, if it exists. +* NOTE: This locks the database globally. Any attempt to insert or remove +* a database entry will give an error and be aborted (except for clearing). +* @param self Interface of the database +* @param func Function to be applied to every entry before deleting +* @param args Extra arguments for func +* @return Sum of values returned by func +* @protected +* @see DBMap#vdestroy +*/ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) { DBMap_impl* db = (DBMap_impl*)self; @@ -2107,21 +2107,21 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) if (db == NULL) return 0; // nullpo candidate if (db->global_lock) { ShowError("db_vdestroy: Database is already locked for destruction. Aborting second database destruction.\n" - "Database allocated at %s:%d\n", - db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->alloc_file, db->alloc_line); return 0; } if (db->free_lock) ShowWarning("db_vdestroy: Database is still in use, %u lock(s) left. Continuing database destruction.\n" - "Database allocated at %s:%d\n", - db->free_lock, db->alloc_file, db->alloc_line); + "Database allocated at %s:%d\n", + db->free_lock, db->alloc_file, db->alloc_line); #ifdef DB_ENABLE_STATS switch (db->type) { - case DB_INT: DB_COUNTSTAT(db_int_destroy); break; - case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break; - case DB_STRING: DB_COUNTSTAT(db_string_destroy); break; - case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break; + case DB_INT: DB_COUNTSTAT(db_int_destroy); break; + case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break; + case DB_STRING: DB_COUNTSTAT(db_string_destroy); break; + case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break; } #endif /* DB_ENABLE_STATS */ db_free_lock(db); @@ -2137,21 +2137,21 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) } /** - * Just calls {@link DBMap#db_vdestroy}. - * Finalize the database, feeing all the memory it uses. - * Before deleting an entry, func is applied to it. - * Releases the key and the data. - * Returns the sum of values returned by func, if it exists. - * NOTE: This locks the database globally. Any attempt to insert or remove - * a database entry will give an error and be aborted. - * @param self Database - * @param func Function to be applied to every entry before deleting - * @param ... Extra arguments for func - * @return Sum of values returned by func - * @protected - * @see DBMap#vdestroy - * @see DBMap#destroy - */ +* Just calls {@link DBMap#db_vdestroy}. +* Finalize the database, feeing all the memory it uses. +* Before deleting an entry, func is applied to it. +* Releases the key and the data. +* Returns the sum of values returned by func, if it exists. +* NOTE: This locks the database globally. Any attempt to insert or remove +* a database entry will give an error and be aborted. +* @param self Database +* @param func Function to be applied to every entry before deleting +* @param ... Extra arguments for func +* @return Sum of values returned by func +* @protected +* @see DBMap#vdestroy +* @see DBMap#destroy +*/ static int db_obj_destroy(DBMap* self, DBApply func, ...) { va_list args; @@ -2167,13 +2167,13 @@ static int db_obj_destroy(DBMap* self, DBApply func, ...) } /** - * Return the size of the database (number of items in the database). - * @param self Interface of the database - * @return Size of the database - * @protected - * @see DBMap_impl#item_count - * @see DBMap#size - */ +* Return the size of the database (number of items in the database). +* @param self Interface of the database +* @return Size of the database +* @protected +* @see DBMap_impl#item_count +* @see DBMap#size +*/ static unsigned int db_obj_size(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2190,13 +2190,13 @@ static unsigned int db_obj_size(DBMap* self) } /** - * Return the type of database. - * @param self Interface of the database - * @return Type of the database - * @protected - * @see DBMap_impl#type - * @see DBMap#type - */ +* Return the type of database. +* @param self Interface of the database +* @return Type of the database +* @protected +* @see DBMap_impl#type +* @see DBMap#type +*/ static DBType db_obj_type(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2213,13 +2213,13 @@ static DBType db_obj_type(DBMap* self) } /** - * Return the options of the database. - * @param self Interface of the database - * @return Options of the database - * @protected - * @see DBMap_impl#options - * @see DBMap#options - */ +* Return the options of the database. +* @param self Interface of the database +* @return Options of the database +* @protected +* @see DBMap_impl#options +* @see DBMap#options +*/ static DBOptions db_obj_options(DBMap* self) { DBMap_impl* db = (DBMap_impl*)self; @@ -2236,120 +2236,121 @@ static DBOptions db_obj_options(DBMap* self) } /*****************************************************************************\ - * (5) Section with public functions. - * db_fix_options - Apply database type restrictions to the options. - * db_default_cmp - Get the default comparator for a type of database. - * db_default_hash - Get the default hasher for a type of database. - * db_default_release - Get the default releaser for a type of database with the specified options. - * db_custom_release - Get a releaser that behaves a certains way. - * db_alloc - Allocate a new database. - * db_i2key - Manual cast from 'int' to 'DBKey'. - * db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. - * db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. - * db_i2data - Manual cast from 'int' to 'DBData'. - * db_ui2data - Manual cast from 'unsigned int' to 'DBData'. - * db_ptr2data - Manual cast from 'void*' to 'DBData'. - * db_data2i - Gets 'int' value from 'DBData'. - * db_data2ui - Gets 'unsigned int' value from 'DBData'. - * db_data2ptr - Gets 'void*' value from 'DBData'. - * db_init - Initializes the database system. - * db_final - Finalizes the database system. +* (5) Section with public functions. +* db_fix_options - Apply database type restrictions to the options. +* db_default_cmp - Get the default comparator for a type of database. +* db_default_hash - Get the default hasher for a type of database. +* db_default_release - Get the default releaser for a type of database with the specified options. +* db_custom_release - Get a releaser that behaves a certains way. +* db_alloc - Allocate a new database. +* db_i2key - Manual cast from 'int' to 'DBKey'. +* db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. +* db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. +* db_i2data - Manual cast from 'int' to 'DBData'. +* db_ui2data - Manual cast from 'unsigned int' to 'DBData'. +* db_ptr2data - Manual cast from 'void*' to 'DBData'. +* db_data2i - Gets 'int' value from 'DBData'. +* db_data2ui - Gets 'unsigned int' value from 'DBData'. +* db_data2ptr - Gets 'void*' value from 'DBData'. +* db_init - Initializes the database system. +* db_final - Finalizes the database system. \*****************************************************************************/ /** - * Returns the fixed options according to the database type. - * Sets required options and unsets unsupported options. - * For numeric databases DB_OPT_DUP_KEY and DB_OPT_RELEASE_KEY are unset. - * @param type Type of the database - * @param options Original options of the database - * @return Fixed options of the database - * @private - * @see #db_default_release(DBType,DBOptions) - * @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short) - */ +* Returns the fixed options according to the database type. +* Sets required options and unsets unsupported options. +* For numeric databases DB_OPT_DUP_KEY and DB_OPT_RELEASE_KEY are unset. +* @param type Type of the database +* @param options Original options of the database +* @return Fixed options of the database +* @private +* @see #db_default_release(DBType,DBOptions) +* @see #db_alloc(const char *,int,DBType,DBOptions,unsigned short) +*/ DBOptions db_fix_options(DBType type, DBOptions options) { DB_COUNTSTAT(db_fix_options); switch (type) { - case DB_INT: - case DB_UINT: // Numeric database, do nothing with the keys - return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)); - - default: - ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options); - case DB_STRING: - case DB_ISTRING: // String databases, no fix required - return options; + case DB_INT: + case DB_UINT: // Numeric database, do nothing with the keys + return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)); + + default: + ShowError("db_fix_options: Unknown database type %u with options %x\n", type, options); + case DB_STRING: + case DB_ISTRING: // String databases, no fix required + return options; } } + /** - * Returns the default comparator for the specified type of database. - * @param type Type of database - * @return Comparator for the type of database or NULL if unknown database - * @public - * @see #db_int_cmp(DBKey,DBKey,unsigned short) - * @see #db_uint_cmp(DBKey,DBKey,unsigned short) - * @see #db_string_cmp(DBKey,DBKey,unsigned short) - * @see #db_istring_cmp(DBKey,DBKey,unsigned short) - */ +* Returns the default comparator for the specified type of database. +* @param type Type of database +* @return Comparator for the type of database or NULL if unknown database +* @public +* @see #db_int_cmp(DBKey,DBKey,unsigned short) +* @see #db_uint_cmp(DBKey,DBKey,unsigned short) +* @see #db_string_cmp(DBKey,DBKey,unsigned short) +* @see #db_istring_cmp(DBKey,DBKey,unsigned short) +*/ DBComparator db_default_cmp(DBType type) { DB_COUNTSTAT(db_default_cmp); switch (type) { - case DB_INT: return &db_int_cmp; - case DB_UINT: return &db_uint_cmp; - case DB_STRING: return &db_string_cmp; - case DB_ISTRING: return &db_istring_cmp; - default: - ShowError("db_default_cmp: Unknown database type %u\n", type); - return NULL; + case DB_INT: return &db_int_cmp; + case DB_UINT: return &db_uint_cmp; + case DB_STRING: return &db_string_cmp; + case DB_ISTRING: return &db_istring_cmp; + default: + ShowError("db_default_cmp: Unknown database type %u\n", type); + return NULL; } } /** - * Returns the default hasher for the specified type of database. - * @param type Type of database - * @return Hasher of the type of database or NULL if unknown database - * @public - * @see #db_int_hash(DBKey,unsigned short) - * @see #db_uint_hash(DBKey,unsigned short) - * @see #db_string_hash(DBKey,unsigned short) - * @see #db_istring_hash(DBKey,unsigned short) - */ +* Returns the default hasher for the specified type of database. +* @param type Type of database +* @return Hasher of the type of database or NULL if unknown database +* @public +* @see #db_int_hash(DBKey,unsigned short) +* @see #db_uint_hash(DBKey,unsigned short) +* @see #db_string_hash(DBKey,unsigned short) +* @see #db_istring_hash(DBKey,unsigned short) +*/ DBHasher db_default_hash(DBType type) { DB_COUNTSTAT(db_default_hash); switch (type) { - case DB_INT: return &db_int_hash; - case DB_UINT: return &db_uint_hash; - case DB_STRING: return &db_string_hash; - case DB_ISTRING: return &db_istring_hash; - default: - ShowError("db_default_hash: Unknown database type %u\n", type); - return NULL; + case DB_INT: return &db_int_hash; + case DB_UINT: return &db_uint_hash; + case DB_STRING: return &db_string_hash; + case DB_ISTRING: return &db_istring_hash; + default: + ShowError("db_default_hash: Unknown database type %u\n", type); + return NULL; } } /** - * Returns the default releaser for the specified type of database with the - * specified options. - * NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)} - * before choosing the releaser. - * @param type Type of database - * @param options Options of the database - * @return Default releaser for the type of database with the specified options - * @public - * @see #db_release_nothing(DBKey,DBData,DBRelease) - * @see #db_release_key(DBKey,DBData,DBRelease) - * @see #db_release_data(DBKey,DBData,DBRelease) - * @see #db_release_both(DBKey,DBData,DBRelease) - * @see #db_custom_release(DBRelease) - */ +* Returns the default releaser for the specified type of database with the +* specified options. +* NOTE: the options are fixed with {@link #db_fix_options(DBType,DBOptions)} +* before choosing the releaser. +* @param type Type of database +* @param options Options of the database +* @return Default releaser for the type of database with the specified options +* @public +* @see #db_release_nothing(DBKey,DBData,DBRelease) +* @see #db_release_key(DBKey,DBData,DBRelease) +* @see #db_release_data(DBKey,DBData,DBRelease) +* @see #db_release_both(DBKey,DBData,DBRelease) +* @see #db_custom_release(DBRelease) +*/ DBReleaser db_default_release(DBType type, DBOptions options) { DB_COUNTSTAT(db_default_release); - options = db_fix_options(type, options); + options = DB->fix_options(type, options); if (options&DB_OPT_RELEASE_DATA) { // Release data, what about the key? if (options&(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)) return &db_release_both; // Release both key and data @@ -2361,45 +2362,45 @@ DBReleaser db_default_release(DBType type, DBOptions options) } /** - * Returns the releaser that releases the specified release options. - * @param which Options that specified what the releaser releases - * @return Releaser for the specified release options - * @public - * @see #db_release_nothing(DBKey,DBData,DBRelease) - * @see #db_release_key(DBKey,DBData,DBRelease) - * @see #db_release_data(DBKey,DBData,DBRelease) - * @see #db_release_both(DBKey,DBData,DBRelease) - * @see #db_default_release(DBType,DBOptions) - */ +* Returns the releaser that releases the specified release options. +* @param which Options that specified what the releaser releases +* @return Releaser for the specified release options +* @public +* @see #db_release_nothing(DBKey,DBData,DBRelease) +* @see #db_release_key(DBKey,DBData,DBRelease) +* @see #db_release_data(DBKey,DBData,DBRelease) +* @see #db_release_both(DBKey,DBData,DBRelease) +* @see #db_default_release(DBType,DBOptions) +*/ DBReleaser db_custom_release(DBRelease which) { DB_COUNTSTAT(db_custom_release); switch (which) { - case DB_RELEASE_NOTHING: return &db_release_nothing; - case DB_RELEASE_KEY: return &db_release_key; - case DB_RELEASE_DATA: return &db_release_data; - case DB_RELEASE_BOTH: return &db_release_both; - default: - ShowError("db_custom_release: Unknown release options %u\n", which); - return NULL; + case DB_RELEASE_NOTHING: return &db_release_nothing; + case DB_RELEASE_KEY: return &db_release_key; + case DB_RELEASE_DATA: return &db_release_data; + case DB_RELEASE_BOTH: return &db_release_both; + default: + ShowError("db_custom_release: Unknown release options %u\n", which); + return NULL; } } /** - * Allocate a new database of the specified type. - * NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)} - * before creating the database. - * @param file File where the database is being allocated - * @param line Line of the file where the database is being allocated - * @param type Type of database - * @param options Options of the database - * @param maxlen Maximum length of the string to be used as key in string - * databases. If 0, the maximum number of maxlen is used (64K). - * @return The interface of the database - * @public - * @see #DBMap_impl - * @see #db_fix_options(DBType,DBOptions) - */ +* Allocate a new database of the specified type. +* NOTE: the options are fixed by {@link #db_fix_options(DBType,DBOptions)} +* before creating the database. +* @param file File where the database is being allocated +* @param line Line of the file where the database is being allocated +* @param type Type of database +* @param options Options of the database +* @param maxlen Maximum length of the string to be used as key in string +* databases. If 0, the maximum number of maxlen is used (64K). +* @return The interface of the database +* @public +* @see #DBMap_impl +* @see #db_fix_options(DBType,DBOptions) +*/ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen) { DBMap_impl* db; @@ -2408,15 +2409,15 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi #ifdef DB_ENABLE_STATS DB_COUNTSTAT(db_alloc); switch (type) { - case DB_INT: DB_COUNTSTAT(db_int_alloc); break; - case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break; - case DB_STRING: DB_COUNTSTAT(db_string_alloc); break; - case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; + case DB_INT: DB_COUNTSTAT(db_int_alloc); break; + case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break; + case DB_STRING: DB_COUNTSTAT(db_string_alloc); break; + case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; } #endif /* DB_ENABLE_STATS */ db = ers_alloc(db_alloc_ers, struct DBMap_impl); - options = db_fix_options(type, options); + options = DB->fix_options(type, options); /* Interface of the database */ db->vtable.iterator = db_obj_iterator; db->vtable.exists = db_obj_exists; @@ -2446,9 +2447,9 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi db->free_lock = 0; /* Other */ db->nodes = ers_new(sizeof(struct dbn),"db.c::db_alloc",ERS_OPT_NONE); - db->cmp = db_default_cmp(type); - db->hash = db_default_hash(type); - db->release = db_default_release(type, options); + db->cmp = DB->default_cmp(type); + db->hash = DB->default_hash(type); + db->release = DB->default_release(type, options); for (i = 0; i < HASH_SIZE; i++) db->ht[i] = NULL; db->cache = NULL; @@ -2465,11 +2466,11 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi } /** - * Manual cast from 'int' to the union DBKey. - * @param key Key to be casted - * @return The key as a DBKey union - * @public - */ +* Manual cast from 'int' to the union DBKey. +* @param key Key to be casted +* @return The key as a DBKey union +* @public +*/ DBKey db_i2key(int key) { DBKey ret; @@ -2480,11 +2481,11 @@ DBKey db_i2key(int key) } /** - * Manual cast from 'unsigned int' to the union DBKey. - * @param key Key to be casted - * @return The key as a DBKey union - * @public - */ +* Manual cast from 'unsigned int' to the union DBKey. +* @param key Key to be casted +* @return The key as a DBKey union +* @public +*/ DBKey db_ui2key(unsigned int key) { DBKey ret; @@ -2495,11 +2496,11 @@ DBKey db_ui2key(unsigned int key) } /** - * Manual cast from 'const char *' to the union DBKey. - * @param key Key to be casted - * @return The key as a DBKey union - * @public - */ +* Manual cast from 'const char *' to the union DBKey. +* @param key Key to be casted +* @return The key as a DBKey union +* @public +*/ DBKey db_str2key(const char *key) { DBKey ret; @@ -2510,11 +2511,11 @@ DBKey db_str2key(const char *key) } /** - * Manual cast from 'int' to the struct DBData. - * @param data Data to be casted - * @return The data as a DBData struct - * @public - */ +* Manual cast from 'int' to the struct DBData. +* @param data Data to be casted +* @return The data as a DBData struct +* @public +*/ DBData db_i2data(int data) { DBData ret; @@ -2526,11 +2527,11 @@ DBData db_i2data(int data) } /** - * Manual cast from 'unsigned int' to the struct DBData. - * @param data Data to be casted - * @return The data as a DBData struct - * @public - */ +* Manual cast from 'unsigned int' to the struct DBData. +* @param data Data to be casted +* @return The data as a DBData struct +* @public +*/ DBData db_ui2data(unsigned int data) { DBData ret; @@ -2542,11 +2543,11 @@ DBData db_ui2data(unsigned int data) } /** - * Manual cast from 'void *' to the struct DBData. - * @param data Data to be casted - * @return The data as a DBData struct - * @public - */ +* Manual cast from 'void *' to the struct DBData. +* @param data Data to be casted +* @return The data as a DBData struct +* @public +*/ DBData db_ptr2data(void *data) { DBData ret; @@ -2558,12 +2559,12 @@ DBData db_ptr2data(void *data) } /** - * Gets int type data from struct DBData. - * If data is not int type, returns 0. - * @param data Data - * @return Integer value of the data. - * @public - */ +* Gets int type data from struct DBData. +* If data is not int type, returns 0. +* @param data Data +* @return Integer value of the data. +* @public +*/ int db_data2i(DBData *data) { DB_COUNTSTAT(db_data2i); @@ -2573,12 +2574,12 @@ int db_data2i(DBData *data) } /** - * Gets unsigned int type data from struct DBData. - * If data is not unsigned int type, returns 0. - * @param data Data - * @return Unsigned int value of the data. - * @public - */ +* Gets unsigned int type data from struct DBData. +* If data is not unsigned int type, returns 0. +* @param data Data +* @return Unsigned int value of the data. +* @public +*/ unsigned int db_data2ui(DBData *data) { DB_COUNTSTAT(db_data2ui); @@ -2588,12 +2589,12 @@ unsigned int db_data2ui(DBData *data) } /** - * Gets void* type data from struct DBData. - * If data is not void* type, returns NULL. - * @param data Data - * @return Void* value of the data. - * @public - */ +* Gets void* type data from struct DBData. +* If data is not void* type, returns NULL. +* @param data Data +* @return Void* value of the data. +* @public +*/ void* db_data2ptr(DBData *data) { DB_COUNTSTAT(db_data2ptr); @@ -2603,10 +2604,10 @@ void* db_data2ptr(DBData *data) } /** - * Initializes the database system. - * @public - * @see #db_final(void) - */ +* Initializes the database system. +* @public +* @see #db_final(void) +*/ void db_init(void) { db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_NONE); db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_NONE); @@ -2614,93 +2615,93 @@ void db_init(void) { } /** - * Finalizes the database system. - * @public - * @see #db_init(void) - */ +* Finalizes the database system. +* @public +* @see #db_init(void) +*/ void db_final(void) { #ifdef DB_ENABLE_STATS DB_COUNTSTAT(db_final); ShowInfo(CL_WHITE"Database nodes"CL_RESET":\n" - "allocated %u, freed %u\n", - stats.db_node_alloc, stats.db_node_free); + "allocated %u, freed %u\n", + stats.db_node_alloc, stats.db_node_free); ShowInfo(CL_WHITE"Database types"CL_RESET":\n" - "DB_INT : allocated %10u, destroyed %10u\n" - "DB_UINT : allocated %10u, destroyed %10u\n" - "DB_STRING : allocated %10u, destroyed %10u\n" - "DB_ISTRING : allocated %10u, destroyed %10u\n", - stats.db_int_alloc, stats.db_int_destroy, - stats.db_uint_alloc, stats.db_uint_destroy, - stats.db_string_alloc, stats.db_string_destroy, - stats.db_istring_alloc, stats.db_istring_destroy); + "DB_INT : allocated %10u, destroyed %10u\n" + "DB_UINT : allocated %10u, destroyed %10u\n" + "DB_STRING : allocated %10u, destroyed %10u\n" + "DB_ISTRING : allocated %10u, destroyed %10u\n", + stats.db_int_alloc, stats.db_int_destroy, + stats.db_uint_alloc, stats.db_uint_destroy, + stats.db_string_alloc, stats.db_string_destroy, + stats.db_istring_alloc, stats.db_istring_destroy); ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n" - "db_rotate_left %10u, db_rotate_right %10u,\n" - "db_rebalance %10u, db_rebalance_erase %10u,\n" - "db_is_key_null %10u,\n" - "db_dup_key %10u, db_dup_key_free %10u,\n" - "db_free_add %10u, db_free_remove %10u,\n" - "db_free_lock %10u, db_free_unlock %10u,\n" - "db_int_cmp %10u, db_uint_cmp %10u,\n" - "db_string_cmp %10u, db_istring_cmp %10u,\n" - "db_int_hash %10u, db_uint_hash %10u,\n" - "db_string_hash %10u, db_istring_hash %10u,\n" - "db_release_nothing %10u, db_release_key %10u,\n" - "db_release_data %10u, db_release_both %10u,\n" - "dbit_first %10u, dbit_last %10u,\n" - "dbit_next %10u, dbit_prev %10u,\n" - "dbit_exists %10u, dbit_remove %10u,\n" - "dbit_destroy %10u, db_iterator %10u,\n" - "db_exits %10u, db_get %10u,\n" - "db_getall %10u, db_vgetall %10u,\n" - "db_ensure %10u, db_vensure %10u,\n" - "db_put %10u, db_remove %10u,\n" - "db_foreach %10u, db_vforeach %10u,\n" - "db_clear %10u, db_vclear %10u,\n" - "db_destroy %10u, db_vdestroy %10u,\n" - "db_size %10u, db_type %10u,\n" - "db_options %10u, db_fix_options %10u,\n" - "db_default_cmp %10u, db_default_hash %10u,\n" - "db_default_release %10u, db_custom_release %10u,\n" - "db_alloc %10u, db_i2key %10u,\n" - "db_ui2key %10u, db_str2key %10u,\n" - "db_i2data %10u, db_ui2data %10u,\n" - "db_ptr2data %10u, db_data2i %10u,\n" - "db_data2ui %10u, db_data2ptr %10u,\n" - "db_init %10u, db_final %10u\n", - stats.db_rotate_left, stats.db_rotate_right, - stats.db_rebalance, stats.db_rebalance_erase, - stats.db_is_key_null, - stats.db_dup_key, stats.db_dup_key_free, - stats.db_free_add, stats.db_free_remove, - stats.db_free_lock, stats.db_free_unlock, - stats.db_int_cmp, stats.db_uint_cmp, - stats.db_string_cmp, stats.db_istring_cmp, - stats.db_int_hash, stats.db_uint_hash, - stats.db_string_hash, stats.db_istring_hash, - stats.db_release_nothing, stats.db_release_key, - stats.db_release_data, stats.db_release_both, - stats.dbit_first, stats.dbit_last, - stats.dbit_next, stats.dbit_prev, - stats.dbit_exists, stats.dbit_remove, - stats.dbit_destroy, stats.db_iterator, - stats.db_exists, stats.db_get, - stats.db_getall, stats.db_vgetall, - stats.db_ensure, stats.db_vensure, - stats.db_put, stats.db_remove, - stats.db_foreach, stats.db_vforeach, - stats.db_clear, stats.db_vclear, - stats.db_destroy, stats.db_vdestroy, - stats.db_size, stats.db_type, - stats.db_options, stats.db_fix_options, - stats.db_default_cmp, stats.db_default_hash, - stats.db_default_release, stats.db_custom_release, - stats.db_alloc, stats.db_i2key, - stats.db_ui2key, stats.db_str2key, - stats.db_i2data, stats.db_ui2data, - stats.db_ptr2data, stats.db_data2i, - stats.db_data2ui, stats.db_data2ptr, - stats.db_init, stats.db_final); + "db_rotate_left %10u, db_rotate_right %10u,\n" + "db_rebalance %10u, db_rebalance_erase %10u,\n" + "db_is_key_null %10u,\n" + "db_dup_key %10u, db_dup_key_free %10u,\n" + "db_free_add %10u, db_free_remove %10u,\n" + "db_free_lock %10u, db_free_unlock %10u,\n" + "db_int_cmp %10u, db_uint_cmp %10u,\n" + "db_string_cmp %10u, db_istring_cmp %10u,\n" + "db_int_hash %10u, db_uint_hash %10u,\n" + "db_string_hash %10u, db_istring_hash %10u,\n" + "db_release_nothing %10u, db_release_key %10u,\n" + "db_release_data %10u, db_release_both %10u,\n" + "dbit_first %10u, dbit_last %10u,\n" + "dbit_next %10u, dbit_prev %10u,\n" + "dbit_exists %10u, dbit_remove %10u,\n" + "dbit_destroy %10u, db_iterator %10u,\n" + "db_exits %10u, db_get %10u,\n" + "db_getall %10u, db_vgetall %10u,\n" + "db_ensure %10u, db_vensure %10u,\n" + "db_put %10u, db_remove %10u,\n" + "db_foreach %10u, db_vforeach %10u,\n" + "db_clear %10u, db_vclear %10u,\n" + "db_destroy %10u, db_vdestroy %10u,\n" + "db_size %10u, db_type %10u,\n" + "db_options %10u, db_fix_options %10u,\n" + "db_default_cmp %10u, db_default_hash %10u,\n" + "db_default_release %10u, db_custom_release %10u,\n" + "db_alloc %10u, db_i2key %10u,\n" + "db_ui2key %10u, db_str2key %10u,\n" + "db_i2data %10u, db_ui2data %10u,\n" + "db_ptr2data %10u, db_data2i %10u,\n" + "db_data2ui %10u, db_data2ptr %10u,\n" + "db_init %10u, db_final %10u\n", + stats.db_rotate_left, stats.db_rotate_right, + stats.db_rebalance, stats.db_rebalance_erase, + stats.db_is_key_null, + stats.db_dup_key, stats.db_dup_key_free, + stats.db_free_add, stats.db_free_remove, + stats.db_free_lock, stats.db_free_unlock, + stats.db_int_cmp, stats.db_uint_cmp, + stats.db_string_cmp, stats.db_istring_cmp, + stats.db_int_hash, stats.db_uint_hash, + stats.db_string_hash, stats.db_istring_hash, + stats.db_release_nothing, stats.db_release_key, + stats.db_release_data, stats.db_release_both, + stats.dbit_first, stats.dbit_last, + stats.dbit_next, stats.dbit_prev, + stats.dbit_exists, stats.dbit_remove, + stats.dbit_destroy, stats.db_iterator, + stats.db_exists, stats.db_get, + stats.db_getall, stats.db_vgetall, + stats.db_ensure, stats.db_vensure, + stats.db_put, stats.db_remove, + stats.db_foreach, stats.db_vforeach, + stats.db_clear, stats.db_vclear, + stats.db_destroy, stats.db_vdestroy, + stats.db_size, stats.db_type, + stats.db_options, stats.db_fix_options, + stats.db_default_cmp, stats.db_default_hash, + stats.db_default_release, stats.db_custom_release, + stats.db_alloc, stats.db_i2key, + stats.db_ui2key, stats.db_str2key, + stats.db_i2data, stats.db_ui2data, + stats.db_ptr2data, stats.db_data2i, + stats.db_data2ui, stats.db_data2ptr, + stats.db_init, stats.db_final); #endif /* DB_ENABLE_STATS */ ers_destroy(db_iterator_ers); ers_destroy(db_alloc_ers); @@ -2828,3 +2829,25 @@ void linkdb_final( struct linkdb_node** head ) } *head = NULL; } + +void db_defaults(void) +{ + DB = &DB_s; + DB->alloc = db_alloc; + DB->custom_release = db_custom_release; + DB->data2i = db_data2i; + DB->data2ptr = db_data2ptr; + DB->data2ui = db_data2ui; + DB->default_cmp = db_default_cmp; + DB->default_hash = db_default_hash; + DB->default_release = db_default_release; + DB->final = db_final; + DB->fix_options = db_fix_options; + DB->i2data = db_i2data; + DB->i2key = db_i2key; + DB->init = db_init; + DB->ptr2data = db_ptr2data; + DB->str2key = db_str2key; + DB->ui2data = db_ui2data; + DB->ui2key = db_ui2key; +} \ No newline at end of file diff --git a/src/common/db.h b/src/common/db.h index 4fe6a93d6..f1f6146be 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -599,73 +599,73 @@ struct DBMap { // For easy access to the common functions. #define db_exists(db,k) ( (db)->exists((db),(k)) ) -#define idb_exists(db,k) ( (db)->exists((db),db_i2key(k)) ) -#define uidb_exists(db,k) ( (db)->exists((db),db_ui2key(k)) ) -#define strdb_exists(db,k) ( (db)->exists((db),db_str2key(k)) ) +#define idb_exists(db,k) ( (db)->exists((db),DB->i2key(k)) ) +#define uidb_exists(db,k) ( (db)->exists((db),DB->ui2key(k)) ) +#define strdb_exists(db,k) ( (db)->exists((db),DB->str2key(k)) ) // Get pointer-type data from DBMaps of various key types -#define db_get(db,k) ( db_data2ptr((db)->get((db),(k))) ) -#define idb_get(db,k) ( db_data2ptr((db)->get((db),db_i2key(k))) ) -#define uidb_get(db,k) ( db_data2ptr((db)->get((db),db_ui2key(k))) ) -#define strdb_get(db,k) ( db_data2ptr((db)->get((db),db_str2key(k))) ) +#define db_get(db,k) ( DB->data2ptr((db)->get((db),(k))) ) +#define idb_get(db,k) ( DB->data2ptr((db)->get((db),DB->i2key(k))) ) +#define uidb_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui2key(k))) ) +#define strdb_get(db,k) ( DB->data2ptr((db)->get((db),DB->str2key(k))) ) // Get int-type data from DBMaps of various key types -#define db_iget(db,k) ( db_data2i((db)->get((db),(k))) ) -#define idb_iget(db,k) ( db_data2i((db)->get((db),db_i2key(k))) ) -#define uidb_iget(db,k) ( db_data2i((db)->get((db),db_ui2key(k))) ) -#define strdb_iget(db,k) ( db_data2i((db)->get((db),db_str2key(k))) ) +#define db_iget(db,k) ( DB->data2i((db)->get((db),(k))) ) +#define idb_iget(db,k) ( DB->data2i((db)->get((db),DB->i2key(k))) ) +#define uidb_iget(db,k) ( DB->data2i((db)->get((db),DB->ui2key(k))) ) +#define strdb_iget(db,k) ( DB->data2i((db)->get((db),DB->str2key(k))) ) // Get uint-type data from DBMaps of various key types -#define db_uiget(db,k) ( db_data2ui((db)->get((db),(k))) ) -#define idb_uiget(db,k) ( db_data2ui((db)->get((db),db_i2key(k))) ) -#define uidb_uiget(db,k) ( db_data2ui((db)->get((db),db_ui2key(k))) ) -#define strdb_uiget(db,k) ( db_data2ui((db)->get((db),db_str2key(k))) ) +#define db_uiget(db,k) ( DB->data2ui((db)->get((db),(k))) ) +#define idb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i2key(k))) ) +#define uidb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui2key(k))) ) +#define strdb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->str2key(k))) ) // Put pointer-type data into DBMaps of various key types -#define db_put(db,k,d) ( (db)->put((db),(k),db_ptr2data(d),NULL) ) -#define idb_put(db,k,d) ( (db)->put((db),db_i2key(k),db_ptr2data(d),NULL) ) -#define uidb_put(db,k,d) ( (db)->put((db),db_ui2key(k),db_ptr2data(d),NULL) ) -#define strdb_put(db,k,d) ( (db)->put((db),db_str2key(k),db_ptr2data(d),NULL) ) +#define db_put(db,k,d) ( (db)->put((db),(k),DB->ptr2data(d),NULL) ) +#define idb_put(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) ) +#define uidb_put(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) ) +#define strdb_put(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) ) // Put int-type data into DBMaps of various key types -#define db_iput(db,k,d) ( (db)->put((db),(k),db_i2data(d),NULL) ) -#define idb_iput(db,k,d) ( (db)->put((db),db_i2key(k),db_i2data(d),NULL) ) -#define uidb_iput(db,k,d) ( (db)->put((db),db_ui2key(k),db_i2data(d),NULL) ) -#define strdb_iput(db,k,d) ( (db)->put((db),db_str2key(k),db_i2data(d),NULL) ) +#define db_iput(db,k,d) ( (db)->put((db),(k),DB->i2data(d),NULL) ) +#define idb_iput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) ) +#define uidb_iput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) ) +#define strdb_iput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) ) // Put uint-type data into DBMaps of various key types -#define db_uiput(db,k,d) ( (db)->put((db),(k),db_ui2data(d),NULL) ) -#define idb_uiput(db,k,d) ( (db)->put((db),db_i2key(k),db_ui2data(d),NULL) ) -#define uidb_uiput(db,k,d) ( (db)->put((db),db_ui2key(k),db_ui2data(d),NULL) ) -#define strdb_uiput(db,k,d) ( (db)->put((db),db_str2key(k),db_ui2data(d),NULL) ) +#define db_uiput(db,k,d) ( (db)->put((db),(k),DB->ui2data(d),NULL) ) +#define idb_uiput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) ) +#define uidb_uiput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) ) +#define strdb_uiput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) ) // Remove entry from DBMaps of various key types #define db_remove(db,k) ( (db)->remove((db),(k),NULL) ) -#define idb_remove(db,k) ( (db)->remove((db),db_i2key(k),NULL) ) -#define uidb_remove(db,k) ( (db)->remove((db),db_ui2key(k),NULL) ) -#define strdb_remove(db,k) ( (db)->remove((db),db_str2key(k),NULL) ) +#define idb_remove(db,k) ( (db)->remove((db),DB->i2key(k),NULL) ) +#define uidb_remove(db,k) ( (db)->remove((db),DB->ui2key(k),NULL) ) +#define strdb_remove(db,k) ( (db)->remove((db),DB->str2key(k),NULL) ) //These are discarding the possible vargs you could send to the function, so those //that require vargs must not use these defines. -#define db_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),(k),(f))) ) -#define idb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_i2key(k),(f))) ) -#define uidb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_ui2key(k),(f))) ) -#define strdb_ensure(db,k,f) ( db_data2ptr((db)->ensure((db),db_str2key(k),(f))) ) +#define db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),(k),(f))) ) +#define idb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) ) +#define uidb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) ) +#define strdb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) ) // Database creation and destruction macros -#define idb_alloc(opt) db_alloc(__FILE__,__LINE__,DB_INT,(opt),sizeof(int)) -#define uidb_alloc(opt) db_alloc(__FILE__,__LINE__,DB_UINT,(opt),sizeof(unsigned int)) -#define strdb_alloc(opt,maxlen) db_alloc(__FILE__,__LINE__,DB_STRING,(opt),(maxlen)) -#define stridb_alloc(opt,maxlen) db_alloc(__FILE__,__LINE__,DB_ISTRING,(opt),(maxlen)) +#define idb_alloc(opt) DB->alloc(__FILE__,__LINE__,DB_INT,(opt),sizeof(int)) +#define uidb_alloc(opt) DB->alloc(__FILE__,__LINE__,DB_UINT,(opt),sizeof(unsigned int)) +#define strdb_alloc(opt,maxlen) DB->alloc(__FILE__,__LINE__,DB_STRING,(opt),(maxlen)) +#define stridb_alloc(opt,maxlen) DB->alloc(__FILE__,__LINE__,DB_ISTRING,(opt),(maxlen)) #define db_destroy(db) ( (db)->destroy((db),NULL) ) // Other macros #define db_clear(db) ( (db)->clear(db,NULL) ) #define db_size(db) ( (db)->size(db) ) #define db_iterator(db) ( (db)->iterator(db) ) -#define dbi_first(dbi) ( db_data2ptr((dbi)->first(dbi,NULL)) ) -#define dbi_last(dbi) ( db_data2ptr((dbi)->last(dbi,NULL)) ) -#define dbi_next(dbi) ( db_data2ptr((dbi)->next(dbi,NULL)) ) -#define dbi_prev(dbi) ( db_data2ptr((dbi)->prev(dbi,NULL)) ) +#define dbi_first(dbi) ( DB->data2ptr((dbi)->first(dbi,NULL)) ) +#define dbi_last(dbi) ( DB->data2ptr((dbi)->last(dbi,NULL)) ) +#define dbi_next(dbi) ( DB->data2ptr((dbi)->next(dbi,NULL)) ) +#define dbi_prev(dbi) ( DB->data2ptr((dbi)->prev(dbi,NULL)) ) #define dbi_remove(dbi) ( (dbi)->remove(dbi,NULL) ) #define dbi_exists(dbi) ( (dbi)->exists(dbi) ) #define dbi_destroy(dbi) ( (dbi)->destroy(dbi) ) @@ -692,6 +692,7 @@ struct DBMap { * db_final - Finalizes the database system. * \*****************************************************************************/ +struct db_interface { /** * Returns the fixed options according to the database type. * Sets required options and unsets unsupported options. @@ -704,7 +705,7 @@ struct DBMap { * @see #DBOptions * @see #db_default_release(DBType,DBOptions) */ -DBOptions db_fix_options(DBType type, DBOptions options); +DBOptions (*fix_options) (DBType type, DBOptions options); /** * Returns the default comparator for the type of database. @@ -714,7 +715,7 @@ DBOptions db_fix_options(DBType type, DBOptions options); * @see #DBType * @see #DBComparator */ -DBComparator db_default_cmp(DBType type); +DBComparator (*default_cmp) (DBType type); /** * Returns the default hasher for the specified type of database. @@ -724,7 +725,7 @@ DBComparator db_default_cmp(DBType type); * @see #DBType * @see #DBHasher */ -DBHasher db_default_hash(DBType type); +DBHasher (*default_hash) (DBType type); /** * Returns the default releaser for the specified type of database with the @@ -741,7 +742,7 @@ DBHasher db_default_hash(DBType type); * @see #db_fix_options(DBType,DBOptions) * @see #db_custom_release(DBRelease) */ -DBReleaser db_default_release(DBType type, DBOptions options); +DBReleaser (*default_release) (DBType type, DBOptions options); /** * Returns the releaser that behaves as which specifies. @@ -752,7 +753,7 @@ DBReleaser db_default_release(DBType type, DBOptions options); * @see #DBReleaser * @see #db_default_release(DBType,DBOptions) */ -DBReleaser db_custom_release(DBRelease which); +DBReleaser (*custom_release) (DBRelease which); /** * Allocate a new database of the specified type. @@ -775,7 +776,7 @@ DBReleaser db_custom_release(DBRelease which); * @see #db_default_release(DBType,DBOptions) * @see #db_fix_options(DBType,DBOptions) */ -DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsigned short maxlen); +DBMap* (*alloc) (const char *file, int line, DBType type, DBOptions options, unsigned short maxlen); /** * Manual cast from 'int' to the union DBKey. @@ -783,7 +784,7 @@ DBMap* db_alloc(const char *file, int line, DBType type, DBOptions options, unsi * @return The key as a DBKey union * @public */ -DBKey db_i2key(int key); +DBKey (*i2key) (int key); /** * Manual cast from 'unsigned int' to the union DBKey. @@ -791,7 +792,7 @@ DBKey db_i2key(int key); * @return The key as a DBKey union * @public */ -DBKey db_ui2key(unsigned int key); +DBKey (*ui2key) (unsigned int key); /** * Manual cast from 'unsigned char *' to the union DBKey. @@ -799,7 +800,7 @@ DBKey db_ui2key(unsigned int key); * @return The key as a DBKey union * @public */ -DBKey db_str2key(const char *key); +DBKey (*str2key) (const char *key); /** * Manual cast from 'int' to the struct DBData. @@ -807,7 +808,7 @@ DBKey db_str2key(const char *key); * @return The data as a DBData struct * @public */ -DBData db_i2data(int data); +DBData (*i2data) (int data); /** * Manual cast from 'unsigned int' to the struct DBData. @@ -815,7 +816,7 @@ DBData db_i2data(int data); * @return The data as a DBData struct * @public */ -DBData db_ui2data(unsigned int data); +DBData (*ui2data) (unsigned int data); /** * Manual cast from 'void *' to the struct DBData. @@ -823,7 +824,7 @@ DBData db_ui2data(unsigned int data); * @return The data as a DBData struct * @public */ -DBData db_ptr2data(void *data); +DBData (*ptr2data) (void *data); /** * Gets int type data from struct DBData. @@ -832,7 +833,7 @@ DBData db_ptr2data(void *data); * @return Integer value of the data. * @public */ -int db_data2i(DBData *data); +int (*data2i) (DBData *data); /** * Gets unsigned int type data from struct DBData. @@ -841,7 +842,7 @@ int db_data2i(DBData *data); * @return Unsigned int value of the data. * @public */ -unsigned int db_data2ui(DBData *data); +unsigned int (*data2ui) (DBData *data); /** * Gets void* type data from struct DBData. @@ -850,14 +851,14 @@ unsigned int db_data2ui(DBData *data); * @return Void* value of the data. * @public */ -void* db_data2ptr(DBData *data); +void* (*data2ptr) (DBData *data); /** * Initialize the database system. * @public * @see #db_final(void) */ -void db_init(void); +void (*init) (void); /** * Finalize the database system. @@ -865,8 +866,12 @@ void db_init(void); * @public * @see #db_init(void) */ -void db_final(void); +void (*final) (void); +} DB_s; +struct db_interface *DB; + +void db_defaults(void); // Link DB System - From jAthena struct linkdb_node { struct linkdb_node *next; diff --git a/src/common/malloc.c b/src/common/malloc.c index d8799b2a1..77eef2508 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -130,21 +130,21 @@ void aFree_(void *p, const char *file, int line, const char *func) /* USE_MEMMGR */ /* - * Memory manager - * able to handle malloc and free efficiently - * Since the complex processing, I might be slightly heavier. - * - * (I'm sorry for the poor description ^ ^;) such as data structures - * Divided into "blocks" of a plurality of memory, "unit" of a plurality of blocks further - * I have to divide. Size of the unit, a plurality of distribution equal to the capacity of one block - * That's what you have. For example, if one unit of 32KB, one block 1 Yu 32Byte - * Knit, or are able to gather 1024, gathered 512 units 64Byte - * I can be or have. (Excluding padding, the unit_head) - * - * Lead-linked list (block_prev, block_next) in each other is the same size block - * Linked list (hash_prev, hash_nect) even among such one in the block with the figure - * I like to have. Thus, reuse of memory no longer needed can be performed efficiently. - */ +* Memory manager +* able to handle malloc and free efficiently +* Since the complex processing, I might be slightly heavier. +* +* (I'm sorry for the poor description ^ ^;) such as data structures +* Divided into "blocks" of a plurality of memory, "unit" of a plurality of blocks further +* I have to divide. Size of the unit, a plurality of distribution equal to the capacity of one block +* That's what you have. For example, if one unit of 32KB, one block 1 Yu 32Byte +* Knit, or are able to gather 1024, gathered 512 units 64Byte +* I can be or have. (Excluding padding, the unit_head) +* +* Lead-linked list (block_prev, block_next) in each other is the same size block +* Linked list (hash_prev, hash_nect) even among such one in the block with the figure +* I like to have. Thus, reuse of memory no longer needed can be performed efficiently. +*/ /* Alignment of the block */ #define BLOCK_ALIGNMENT1 16 @@ -210,7 +210,7 @@ static unsigned short size2hash( size_t size ) return (unsigned short)(size + BLOCK_ALIGNMENT1 - 1) / BLOCK_ALIGNMENT1; } else if( size <= BLOCK_DATA_SIZE ){ return (unsigned short)(size - BLOCK_DATA_SIZE1 + BLOCK_ALIGNMENT2 - 1) / BLOCK_ALIGNMENT2 - + BLOCK_DATA_COUNT1; + + BLOCK_DATA_COUNT1; } else { return 0xffff; // If it exceeds the block length hash I do not } @@ -235,7 +235,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) ShowError("_mmalloc: %d\n", size); return NULL; } - + if(size == 0) { return NULL; } @@ -332,7 +332,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func ) void* _mcalloc(size_t num, size_t size, const char *file, int line, const char *func ) { - void *p = _mmalloc(num * size,file,line,func); + void *p = malloclib->malloc(num * size,file,line,func); memset(p,0,num * size); return p; } @@ -341,7 +341,7 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c { size_t old_size; if(memblock == NULL) { - return _mmalloc(size,file,line,func); + return malloclib->malloc(size,file,line,func); } old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; @@ -353,11 +353,11 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c return memblock; } else { // Size Large - void *p = _mmalloc(size,file,line,func); + void *p = malloclib->malloc(size,file,line,func); if(p != NULL) { memcpy(p,memblock,old_size); } - _mfree(memblock,file,line,func); + malloclib->free(memblock,file,line,func); return p; } } @@ -368,7 +368,7 @@ char* _mstrdup(const char *p, const char *file, int line, const char *func ) return NULL; } else { size_t len = strlen(p); - char *string = (char *)_mmalloc(len + 1,file,line,func); + char *string = (char *)malloclib->malloc(len + 1,file,line,func); memcpy(string,p,len+1); return string; } @@ -544,7 +544,7 @@ static void memmgr_log (char *buf) t = localtime(&raw); fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (rev %s).\n", (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, - git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); + git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); } fprintf(log_fp, "%s", buf); return; @@ -621,7 +621,7 @@ static void memmgr_final (void) memmgr_log (buf); #endif /* LOG_MEMMGR */ // get block pointer and free it [celest] - _mfree(ptr, ALC_MARK); + malloclib->free(ptr, ALC_MARK); } } } @@ -663,9 +663,9 @@ static void memmgr_init (void) /*====================================== - * Initialise - *-------------------------------------- - */ +* Initialise +*-------------------------------------- +*/ /// Tests the memory for errors and memory leaks. @@ -719,3 +719,28 @@ void malloc_init (void) memmgr_init (); #endif } + +void malloc_defaults() +{ + malloclib = &malloclib_s; + malloclib->init = malloc_init; + malloclib->final = malloc_final; + malloclib->memory_check = malloc_memory_check; + malloclib->usage = malloc_usage; + malloclib->verify_ptr = malloc_verify_ptr; + +// Athena's built-in Memory Manager +#ifdef USE_MEMMGR + malloclib->malloc = _mmalloc; + malloclib->calloc = _mcalloc; + malloclib->realloc = _mrealloc; + malloclib->strdup = _mstrdup; + malloclib->free = _mfree; +#else + malloclib->malloc = aMalloc_; + malloclib->calloc = aCalloc_; + malloclib->realloc = aRealloc_; + malloclib->strdup = aStrdup_; + malloclib->free = aFree_; +#endif +} diff --git a/src/common/malloc.h b/src/common/malloc.h index 6b4e8e5c4..2e745481f 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -22,9 +22,6 @@ ////////////////////////////////////////////////////////////////////// -// Athena's built-in Memory Manager -#ifdef USE_MEMMGR - // Enable memory manager logging by default #define LOG_MEMMGR @@ -33,46 +30,24 @@ #undef LOG_MEMMGR #endif -# define aMalloc(n) _mmalloc(n,ALC_MARK) -# define aCalloc(m,n) _mcalloc(m,n,ALC_MARK) -# define aRealloc(p,n) _mrealloc(p,n,ALC_MARK) -# define aStrdup(p) _mstrdup(p,ALC_MARK) -# define aFree(p) _mfree(p,ALC_MARK) - - void* _mmalloc (size_t size, const char *file, int line, const char *func); - void* _mcalloc (size_t num, size_t size, const char *file, int line, const char *func); - void* _mrealloc (void *p, size_t size, const char *file, int line, const char *func); - char* _mstrdup (const char *p, const char *file, int line, const char *func); - void _mfree (void *p, const char *file, int line, const char *func); - -#else - -# define aMalloc(n) aMalloc_((n),ALC_MARK) -# define aCalloc(m,n) aCalloc_((m),(n),ALC_MARK) -# define aRealloc(p,n) aRealloc_(p,n,ALC_MARK) -# define aStrdup(p) aStrdup_(p,ALC_MARK) -# define aFree(p) aFree_(p,ALC_MARK) - - void* aMalloc_ (size_t size, const char *file, int line, const char *func); - void* aCalloc_ (size_t num, size_t size, const char *file, int line, const char *func); - void* aRealloc_ (void *p, size_t size, const char *file, int line, const char *func); - char* aStrdup_ (const char *p, const char *file, int line, const char *func); - void aFree_ (void *p, const char *file, int line, const char *func); - -#endif +# define aMalloc(n) malloclib->malloc (n,ALC_MARK) +# define aCalloc(m,n) malloclib->calloc (m,n,ALC_MARK) +# define aRealloc(p,n) malloclib->realloc (p,n,ALC_MARK) +# define aStrdup(p) malloclib->strdup (p,ALC_MARK) +# define aFree(p) malloclib->free (p,ALC_MARK) /////////////// Buffer Creation ///////////////// // Full credit for this goes to Shinomori [Ajarn] #ifdef __GNUC__ // GCC has variable length arrays - #define CREATE_BUFFER(name, type, size) type name[size] - #define DELETE_BUFFER(name) +#define CREATE_BUFFER(name, type, size) type name[size] +#define DELETE_BUFFER(name) #else // others don't, so we emulate them - #define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc (size, sizeof(type)) - #define DELETE_BUFFER(name) aFree(name) +#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc (size, sizeof(type)) +#define DELETE_BUFFER(name) aFree(name) #endif @@ -83,10 +58,27 @@ //////////////////////////////////////////////// -void malloc_memory_check(void); -bool malloc_verify_ptr(void* ptr); -size_t malloc_usage (void); -void malloc_init (void); -void malloc_final (void); - +//void malloc_memory_check(void); +//bool malloc_verify_ptr(void* ptr); +//size_t malloc_usage (void); +//void malloc_init (void); +//void malloc_final (void); + +void malloc_defaults(void); + +struct malloc_interface { + void* (*malloc )(size_t size, const char *file, int line, const char *func); + void* (*calloc )(size_t num, size_t size, const char *file, int line, const char *func); + void* (*realloc )(void *p, size_t size, const char *file, int line, const char *func); + char* (*strdup )(const char *p, const char *file, int line, const char *func); + void (*free ) (void *p, const char *file, int line, const char *func); + + void (*memory_check)(void); + bool (*verify_ptr)(void* ptr); + size_t (*usage) (void); + void (*init) (void); + void (*final) (void); +} malloclib_s; + +struct malloc_interface *malloclib; #endif /* _MALLOC_H_ */ diff --git a/src/login/login.c b/src/login/login.c index 09dd938db..8dd5ce20a 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -109,7 +109,7 @@ static DBData create_online_user(DBKey key, va_list args) p->account_id = key.i; p->char_server = -1; p->waiting_disconnect = INVALID_TIMER; - return db_ptr2data(p); + return DB->ptr2data(p); } struct online_login_data* add_online_user(int char_server, int account_id) @@ -154,7 +154,7 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t */ static int online_db_setoffline(DBKey key, DBData *data, va_list ap) { - struct online_login_data* p = db_data2ptr(data); + struct online_login_data* p = DB->data2ptr(data); int server = va_arg(ap, int); if( server == -1 ) { @@ -175,7 +175,7 @@ static int online_db_setoffline(DBKey key, DBData *data, va_list ap) */ static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) { - struct online_login_data *character= db_data2ptr(data); + struct online_login_data *character= DB->data2ptr(data); if (character->char_server == -2) //Unknown server.. set them offline remove_online_user(character->account_id); return 0; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 8a6399568..d923027dd 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5350,12 +5350,12 @@ ACMD(skillid) { iter = db_iterator(skilldb_name2id); for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { - idx = skill->get_index(db_data2i(data)); + idx = skill->get_index(DB->data2i(data)); if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_db[idx].desc, message, skillen) == 0) { - sprintf(atcmd_output, msg_txt(1164), db_data2i(data), skill_db[idx].desc, key.str); // skill %d: %s (%s) + sprintf(atcmd_output, msg_txt(1164), DB->data2i(data), skill_db[idx].desc, key.str); // skill %d: %s (%s) clif->message(fd, atcmd_output); } else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill_db[idx].desc,message) ) ) { - snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(1164), db_data2i(data), skill_db[idx].desc, key.str); + snprintf(partials[found++], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_txt(1164), DB->data2i(data), skill_db[idx].desc, key.str); } } @@ -9206,7 +9206,7 @@ ACMD(channel) { iter = db_iterator(channel->banned); for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { - struct hChSysBanEntry * entry = db_data2ptr(data); + struct hChSysBanEntry * entry = DB->data2ptr(data); if( !isA ) sprintf(atcmd_output, msg_txt(1444), entry->name);// - %s %s diff --git a/src/map/battleground.c b/src/map/battleground.c index fa4db436a..618679406 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -222,7 +222,7 @@ int bg_send_message(struct map_session_data *sd, const char *mes, int len) */ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { - struct battleground_data *bg = db_data2ptr(data); + struct battleground_data *bg = DB->data2ptr(data); struct map_session_data *sd; int i; nullpo_ret(bg); diff --git a/src/map/chrif.c b/src/map/chrif.c index 05f56029b..efe976942 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -479,7 +479,7 @@ int chrif_connectack(int fd) { * @see DBApply */ static int chrif_reconnect(DBKey key, DBData *data, va_list ap) { - struct auth_node *node = db_data2ptr(data); + struct auth_node *node = DB->data2ptr(data); switch (node->state) { case ST_LOGIN: @@ -687,7 +687,7 @@ void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used ( * @see DBApply */ int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) { - struct auth_node *node = db_data2ptr(data); + struct auth_node *node = DB->data2ptr(data); const char* states[] = { "Login", "Logout", "Map change" }; if(DIFF_TICK(gettick(),node->node_created)>60000) { @@ -1596,7 +1596,7 @@ void chrif_send_report(char* buf, int len) { * @see DBApply */ int auth_db_final(DBKey key, DBData *data, va_list ap) { - struct auth_node *node = db_data2ptr(data); + struct auth_node *node = DB->data2ptr(data); if (node->char_dat) aFree(node->char_dat); diff --git a/src/map/guild.c b/src/map/guild.c index 9e7dc9b0f..b83f05f00 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -296,7 +296,7 @@ int guild_payexp_timer_sub(DBKey key, DBData *data, va_list ap) { struct guild_expcache *c; struct guild *g; - c = db_data2ptr(data); + c = DB->data2ptr(data); if ( (g = guild->search(c->guild_id)) == NULL || @@ -331,7 +331,7 @@ int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data) */ int guild_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { - struct guild *g = db_data2ptr(data); + struct guild *g = DB->data2ptr(data); int i; nullpo_ret(g); @@ -439,8 +439,8 @@ int guild_npc_request_info(int guild_id,const char *event) ev=(struct eventlist *)aCalloc(sizeof(struct eventlist),1); memcpy(ev->name,event,strlen(event)); //The one in the db (if present) becomes the next event from this. - if (guild_infoevent_db->put(guild_infoevent_db, db_i2key(guild_id), db_ptr2data(ev), &prev)) - ev->next = db_data2ptr(&prev); + if (guild_infoevent_db->put(guild_infoevent_db, DB->i2key(guild_id), DB->ptr2data(ev), &prev)) + ev->next = DB->data2ptr(&prev); } return guild->request_info(guild_id); @@ -615,8 +615,8 @@ int guild_recv_info(struct guild *sg) { } //Occurrence of an event - if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) { - struct eventlist *ev = db_data2ptr(&data), *ev2; + if (guild_infoevent_db->remove(guild_infoevent_db, DB->i2key(sg->guild_id), &data)) { + struct eventlist *ev = DB->data2ptr(&data), *ev2; while(ev) { npc_event_do(ev->name); ev2=ev->next; @@ -1243,7 +1243,7 @@ static DBData create_expcache(DBKey key, va_list args) c->account_id = sd->status.account_id; c->char_id = sd->status.char_id; c->exp = 0; - return db_ptr2data(c); + return DB->ptr2data(c); } /*==================================================== @@ -1269,7 +1269,7 @@ unsigned int guild_payexp(struct map_session_data *sd,unsigned int exp) { exp = exp * per / 100; //Otherwise tax everything. - c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd)); + c = DB->data2ptr(guild_expcache_db->ensure(guild_expcache_db, DB->i2key(sd->status.char_id), create_expcache, sd)); if (c->exp > UINT64_MAX - exp) c->exp = UINT64_MAX; @@ -1292,7 +1292,7 @@ int guild_getexp(struct map_session_data *sd,int exp) if (sd->status.guild_id == 0 || sd->guild == NULL) return 0; - c = db_data2ptr(guild_expcache_db->ensure(guild_expcache_db, db_i2key(sd->status.char_id), create_expcache, sd)); + c = DB->data2ptr(guild_expcache_db->ensure(guild_expcache_db, DB->i2key(sd->status.char_id), create_expcache, sd)); if (c->exp > UINT64_MAX - exp) c->exp = UINT64_MAX; else @@ -1692,7 +1692,7 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id */ int guild_broken_sub(DBKey key, DBData *data, va_list ap) { - struct guild *g = db_data2ptr(data); + struct guild *g = DB->data2ptr(data); int guild_id=va_arg(ap,int); int i,j; struct map_session_data *sd=NULL; @@ -1717,7 +1717,7 @@ int guild_broken_sub(DBKey key, DBData *data, va_list ap) */ int castle_guild_broken_sub(DBKey key, DBData *data, va_list ap) { - struct guild_castle *gc = db_data2ptr(data); + struct guild_castle *gc = DB->data2ptr(data); int guild_id = va_arg(ap, int); nullpo_ret(gc); @@ -2145,7 +2145,7 @@ void guild_flag_remove(struct npc_data *nd) { */ static int eventlist_db_final(DBKey key, DBData *data, va_list ap) { struct eventlist *next = NULL; - struct eventlist *current = db_data2ptr(data); + struct eventlist *current = DB->data2ptr(data); while (current != NULL) { next = current->next; aFree(current); @@ -2158,7 +2158,7 @@ static int eventlist_db_final(DBKey key, DBData *data, va_list ap) { * @see DBApply */ static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) { - ers_free(expcache_ers, db_data2ptr(data)); + ers_free(expcache_ers, DB->data2ptr(data)); return 0; } @@ -2166,7 +2166,7 @@ static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) { * @see DBApply */ static int guild_castle_db_final(DBKey key, DBData *data, va_list ap) { - struct guild_castle* gc = db_data2ptr(data); + struct guild_castle* gc = DB->data2ptr(data); if( gc->temp_guardians ) aFree(gc->temp_guardians); aFree(gc); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 590a0cf57..2a5fa48de 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -30,7 +30,7 @@ struct item_data dummy_item; //This is the default dummy item used for non-exist */ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap) { - struct item_data *item = db_data2ptr(data), **dst, **dst2; + struct item_data *item = DB->data2ptr(data), **dst, **dst2; char *str; str=va_arg(ap,char *); dst=va_arg(ap,struct item_data **); @@ -83,7 +83,7 @@ struct item_data* itemdb_searchname(const char *str) */ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap) { - struct item_data *item = db_data2ptr(&data); + struct item_data *item = DB->data2ptr(&data); char *str; str=va_arg(ap,char *); if (item == &dummy_item) @@ -127,7 +127,7 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str) size -= count; db_count = itemdb_other->getall(itemdb_other, (DBData**)&db_data, size, itemdb_searchname_array_sub, str); for (i = 0; i < db_count; i++) - data[count++] = db_data2ptr(db_data[i]); + data[count++] = DB->data2ptr(db_data[i]); count += db_count; } return count; @@ -1376,7 +1376,7 @@ static void destroy_item_data(struct item_data* self, int free_self) */ static int itemdb_final_sub(DBKey key, DBData *data, va_list ap) { - struct item_data *id = db_data2ptr(data); + struct item_data *id = DB->data2ptr(data); if( id != &dummy_item ) destroy_item_data(id, 1); diff --git a/src/map/map.c b/src/map/map.c index 49aef6c4c..6f61375fe 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1479,7 +1479,7 @@ static DBData create_charid2nick(DBKey key, va_list args) { struct charid2nick *p; CREATE(p, struct charid2nick, 1); - return db_ptr2data(p); + return DB->ptr2data(p); } /// Adds(or replaces) the nick of charid to nick_db and fullfils pending requests. @@ -1515,7 +1515,7 @@ void map_delnickdb(int charid, const char* name) struct map_session_data* sd; DBData data; - if (!nick_db->remove(nick_db, db_i2key(charid), &data) || (p = db_data2ptr(&data)) == NULL) + if (!nick_db->remove(nick_db, DB->i2key(charid), &data) || (p = DB->data2ptr(&data)) == NULL) return; while( p->requests ) { @@ -2703,7 +2703,7 @@ static DBData create_map_data_other_server(DBKey key, va_list args) mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server)); mdos->index = mapindex; memcpy(mdos->name, mapindex_id2name(mapindex), MAP_NAME_LENGTH); - return db_ptr2data(mdos); + return DB->ptr2data(mdos); } /*========================================== @@ -2733,7 +2733,7 @@ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port) */ int map_eraseallipport_sub(DBKey key, DBData *data, va_list va) { - struct map_data_other_server *mdos = db_data2ptr(data); + struct map_data_other_server *mdos = DB->data2ptr(data); if(mdos->cell == NULL) { db_remove(map_db,key); aFree(mdos); @@ -4854,7 +4854,7 @@ void read_map_zone_db(void) { */ int map_db_final(DBKey key, DBData *data, va_list ap) { - struct map_data_other_server *mdos = db_data2ptr(data); + struct map_data_other_server *mdos = DB->data2ptr(data); if(mdos && mdos->cell == NULL) aFree(mdos); return 0; @@ -4865,7 +4865,7 @@ int map_db_final(DBKey key, DBData *data, va_list ap) */ int nick_db_final(DBKey key, DBData *data, va_list args) { - struct charid2nick* p = db_data2ptr(data); + struct charid2nick* p = DB->data2ptr(data); struct charid_request* req; if( p == NULL ) @@ -4913,7 +4913,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) */ static int cleanup_db_sub(DBKey key, DBData *data, va_list va) { - return cleanup_sub(db_data2ptr(data), va); + return cleanup_sub(DB->data2ptr(data), va); } /*========================================== diff --git a/src/map/npc.c b/src/map/npc.c index 77ee8d486..090c03e58 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -353,7 +353,7 @@ int npc_event_doall_sub(DBKey key, DBData *data, va_list ap) const char* name; int rid; - nullpo_ret(ev = db_data2ptr(data)); + nullpo_ret(ev = DB->data2ptr(data)); nullpo_ret(c = va_arg(ap, int *)); nullpo_ret(name = va_arg(ap, const char *)); rid = va_arg(ap, int); @@ -381,7 +381,7 @@ static int npc_event_do_sub(DBKey key, DBData *data, va_list ap) int* c; const char* name; - nullpo_ret(ev = db_data2ptr(data)); + nullpo_ret(ev = DB->data2ptr(data)); nullpo_ret(c = va_arg(ap, int *)); nullpo_ret(name = va_arg(ap, const char *)); @@ -1785,7 +1785,7 @@ int npc_remove_map(struct npc_data* nd) */ static int npc_unload_ev(DBKey key, DBData *data, va_list ap) { - struct event_data* ev = db_data2ptr(data); + struct event_data* ev = DB->data2ptr(data); char* npcname = va_arg(ap, char *); if(strcmp(ev->nd->exname,npcname)==0){ @@ -2302,7 +2302,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const int npc_convertlabel_db(DBKey key, DBData *data, va_list ap) { const char* lname = (const char*)key.str; - int lpos = db_data2i(data); + int lpos = DB->data2i(data); struct npc_label_list** label_list; int* label_list_num; const char* filepath; @@ -2972,9 +2972,9 @@ static const char* npc_parse_function(char* w1, char* w2, char* w3, char* w4, co return end; func_db = script_get_userfunc_db(); - if (func_db->put(func_db, db_str2key(w3), db_ptr2data(script), &old_data)) + if (func_db->put(func_db, DB->str2key(w3), DB->ptr2data(script), &old_data)) { - struct script_code *oldscript = (struct script_code*)db_data2ptr(&old_data); + struct script_code *oldscript = (struct script_code*)DB->data2ptr(&old_data); ShowInfo("npc_parse_function: Overwriting user function [%s] (%s:%d)\n", w3, filepath, strline(buffer,start-buffer)); script_free_vars(oldscript->script_vars); aFree(oldscript->script_buf); @@ -3776,7 +3776,7 @@ void npc_read_event_script(void) for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { const char* p = key.str; - struct event_data* ed = db_data2ptr(data); + struct event_data* ed = DB->data2ptr(data); unsigned char count = script_event[i].event_count; if( count >= ARRAYLENGTH(script_event[i].event) ) diff --git a/src/map/script.c b/src/map/script.c index 76092f4ce..41f8e7472 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -3658,7 +3658,7 @@ int script_config_read(char *cfgName) */ static int db_script_free_code_sub(DBKey key, DBData *data, va_list ap) { - struct script_code *code = db_data2ptr(data); + struct script_code *code = DB->data2ptr(data); if (code) script_free_code(code); return 0; diff --git a/src/map/skill.c b/src/map/skill.c index bbc88d9d2..06bfca5f8 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -15363,7 +15363,7 @@ int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) { * @see DBApply */ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { - struct skill_unit* unit = db_data2ptr(data); + struct skill_unit* unit = DB->data2ptr(data); struct skill_unit_group* group = unit->group; unsigned int tick = va_arg(ap,unsigned int); bool dissonance; diff --git a/src/map/storage.c b/src/map/storage.c index fda80735a..01da53907 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -73,7 +73,7 @@ void do_final_storage(void) // by [MC Cameri] */ static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap) { - struct guild_storage *stor = db_data2ptr(data); + struct guild_storage *stor = DB->data2ptr(data); if (stor->dirty && stor->storage_status == 0) //Save closed storages. storage_guild_storagesave(0, stor->guild_id,0); @@ -352,7 +352,7 @@ static DBData create_guildstorage(DBKey key, va_list args) struct guild_storage *gs = NULL; gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1); gs->guild_id=key.i; - return db_ptr2data(gs); + return DB->ptr2data(gs); } struct guild_storage *guild2storage(int guild_id) -- cgit v1.2.3-70-g09d2