Browse Source

* Merged the tmpsql branch:
- Abstraction for the sql code (sql.c/h).
- New configure script and makefiles.
- Restored txt zeny logging code. (r10814)
- Rewrote mapserver's sql code - itemdb, mobdb, mapreg, logs. (r10814)
- Fixed a precedence issue (&& and ) in char_sql/char.c. (r10833)
- Improved db reading code a bit for consistency. (r11077)
- Added separate atcommand for mail deletion. (r11077)
- Corrected a few messages that said "new" instead of "unread". (r11077)
- Broadcast (*) messages now use "*" as the target's name (not ""). (r11077)
- Moved StringBuf code from utils.c/h to strlib.c/h. (r11084 r11117)
- Some misc login server cleanups (reformatting etc). (r11136)
- Corrected/modified some header entries. (r11141 r11147 11148)
- Adjusted VS project files. (r11147)
- Adjusted the way the sql charserver does item saving. (r11192)
- Corrected usage of reserved keyword 'friend' in mmo.h. (r11192)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11245 54d463be-8e91-2dee-dedb-b68131a5f0ec

FlavioJS 17 years ago
parent
commit
65642f6f1c
100 changed files with 5511 additions and 4577 deletions
  1. 17 0
      Changelog-Trunk.txt
  2. 0 253
      Makefile
  3. 181 0
      Makefile.in
  4. 2 2
      conf-tmpl/msg_athena.conf
  5. 0 256
      configure
  6. 295 0
      configure.in
  7. 8 0
      eAthena-8.sln
  8. 26 11
      src/char/Makefile.in
  9. 5 3
      src/char/char.c
  10. 1 2
      src/char/char.h
  11. 4 4
      src/char/int_guild.c
  12. 3 0
      src/char/int_guild.h
  13. 4 4
      src/char/int_homun.c
  14. 0 1
      src/char/int_homun.h
  15. 4 4
      src/char/int_party.c
  16. 2 2
      src/char/int_party.h
  17. 4 4
      src/char/int_pet.c
  18. 2 0
      src/char/int_pet.h
  19. 4 3
      src/char/int_status.c
  20. 2 4
      src/char/int_status.h
  21. 5 4
      src/char/int_storage.c
  22. 3 1
      src/char/int_storage.h
  23. 4 5
      src/char/inter.c
  24. 2 0
      src/char/inter.h
  25. 0 28
      src/char_sql/Makefile
  26. 56 0
      src/char_sql/Makefile.in
  27. 413 509
      src/char_sql/char.c
  28. 2 26
      src/char_sql/char.h
  29. 384 410
      src/char_sql/int_guild.c
  30. 14 11
      src/char_sql/int_guild.h
  31. 109 108
      src/char_sql/int_homun.c
  32. 2 0
      src/char_sql/int_homun.h
  33. 144 174
      src/char_sql/int_party.c
  34. 2 0
      src/char_sql/int_party.h
  35. 66 74
      src/char_sql/int_pet.c
  36. 2 0
      src/char_sql/int_pet.h
  37. 152 206
      src/char_sql/int_storage.c
  38. 3 0
      src/char_sql/int_storage.h
  39. 163 158
      src/char_sql/inter.c
  40. 4 18
      src/char_sql/inter.h
  41. 0 219
      src/char_sql/itemdb.c
  42. 0 44
      src/char_sql/itemdb.h
  43. 53 14
      src/common/Makefile.in
  44. 0 1
      src/common/db.c
  45. 2 1
      src/common/ers.c
  46. 2 0
      src/common/ers.h
  47. 1 1
      src/common/md5calc.c
  48. 3 4
      src/common/mmo.h
  49. 2 2
      src/common/plugins.c
  50. 12 9
      src/common/showmsg.c
  51. 7 6
      src/common/socket.c
  52. 2 2
      src/common/socket.h
  53. 851 0
      src/common/sql.c
  54. 343 0
      src/common/sql.h
  55. 132 2
      src/common/strlib.c
  56. 22 0
      src/common/strlib.h
  57. 25 129
      src/common/utils.c
  58. 7 21
      src/common/utils.h
  59. 0 18
      src/ladmin/Makefile
  60. 31 0
      src/ladmin/Makefile.in
  61. 0 25
      src/login/Makefile
  62. 35 0
      src/login/Makefile.in
  63. 144 156
      src/login/login.c
  64. 0 22
      src/login_sql/Makefile
  65. 46 0
      src/login_sql/Makefile.in
  66. 322 326
      src/login_sql/login.c
  67. 0 103
      src/map/Makefile
  68. 148 0
      src/map/Makefile.in
  69. 32 9
      src/map/atcommand.c
  70. 1 0
      src/map/battle.c
  71. 1 0
      src/map/charcommand.c
  72. 1 0
      src/map/clif.c
  73. 3 3
      src/map/guild.c
  74. 1 1
      src/map/intif.c
  75. 189 307
      src/map/itemdb.c
  76. 209 183
      src/map/log.c
  77. 0 8
      src/map/log.h
  78. 244 220
      src/map/mail.c
  79. 2 2
      src/map/mail.h
  80. 58 80
      src/map/map.c
  81. 21 32
      src/map/map.h
  82. 73 39
      src/map/mob.c
  83. 1 0
      src/map/npc.c
  84. 1 0
      src/map/party.c
  85. 2 1
      src/map/pc.c
  86. 1 0
      src/map/pet.c
  87. 176 196
      src/map/script.c
  88. 1 0
      src/map/skill.c
  89. 1 0
      src/map/status.c
  90. 0 42
      src/plugins/Makefile
  91. 67 0
      src/plugins/Makefile.in
  92. 0 14
      src/tool/Makefile
  93. 28 0
      src/tool/Makefile.in
  94. 0 24
      src/txt-converter/Makefile
  95. 68 0
      src/txt-converter/Makefile.in
  96. 1 0
      src/txt-converter/char-converter.c
  97. 21 18
      src/txt-converter/login-converter.c
  98. 8 8
      vcproj-6/char-server_sql.dsp
  99. 8 0
      vcproj-6/login-server_sql.dsp
  100. 8 0
      vcproj-6/map-server_sql.dsp

+ 17 - 0
Changelog-Trunk.txt

@@ -3,6 +3,23 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
+2007/09/20
+	* Merged the tmpsql branch: [FlavioJS]
+	- Abstraction for the sql code (sql.c/h).
+	- New configure script and makefiles.
+	- Restored txt zeny logging code. (r10814)
+	- Rewrote mapserver's sql code - itemdb, mobdb, mapreg, logs. (r10814)
+	- Fixed a precedence issue (&& and ) in char_sql/char.c. (r10833)
+	- Improved db reading code a bit for consistency. (r11077)
+	- Added separate atcommand for mail deletion. (r11077)
+	- Corrected a few messages that said "new" instead of "unread". (r11077)
+	- Broadcast (*) messages now use "*" as the target's name (not ""). (r11077)
+	- Moved StringBuf code from utils.c/h to strlib.c/h. (r11084 r11117)
+	- Some misc login server cleanups (reformatting etc). (r11136)
+	- Corrected/modified some header entries. (r11141 r11147 11148)
+	- Adjusted VS project files. (r11147)
+	- Adjusted the way the sql charserver does item saving. (r11192)
+	- Corrected usage of reserved keyword 'friend' in mmo.h. (r11192)
 2007/09/17
 2007/09/17
 	* Several skills with a splash area (except ground based ones) will now hit
 	* Several skills with a splash area (except ground based ones) will now hit
 	  Ice-walls when casted by mobs.
 	  Ice-walls when casted by mobs.

+ 0 - 253
Makefile

@@ -1,253 +0,0 @@
-
-CACHED = $(shell ls | grep Makefile.cache)
-ifeq ($(findstring Makefile.cache,$(CACHED)), Makefile.cache)
-MKDEF = $(shell cat Makefile.cache)
-else
-
-CC = gcc -pipe
-# CC = g++ --pipe
-
-MAKE = make
-# MAKE = gmake
-
-# Detecting gcc version
-GCC_VERSION = $(shell $(CC) -v 2>&1 | grep version | cut -d' ' -f3  | cut -d'.' -f1)
-
-OPT = -g
-OPT += -O2
-# OPT += -O3
-# OPT += -mmmx
-# OPT += -msse
-# OPT += -msse2
-# OPT += -msse3
-# OPT += -rdynamic
-OPT += -ffast-math
-# OPT += -fbounds-checking
-# OPT += -fstack-protector
-# OPT += -fomit-frame-pointer
-OPT += -Wall -Wno-sign-compare
-ifeq ($(GCC_VERSION), 4)
-	OPT += -Wno-unused-parameter -Wno-pointer-sign
-endif
-# Server Packet Protocol version (also defined in src/common/mmo.h)
-# OPT += -DPACKETVER=8
-# Makes map-wide script variables be saved to SQL instead of TXT files.
-# OPT += -DMAPREGSQL
-# Enable the perl regular expression support for scripts
-# OPT += -DPCRE_SUPPORT
-# OPT += -DGCOLLECT
-# OPT += -DMEMWATCH
-# OPT += -DDMALLOC -DDMALLOC_FUNC_CHECK
-# OPT += -DBCHECK
-
-# LIBS += -lgc
-# LIBS += -ldmalloc
-# LIBS += -L/usr/local/lib -lpcre
-
-PLATFORM = $(shell uname)
-ARCH = $(shell uname -m)
-
-ifeq ($(findstring Linux,$(PLATFORM)), Linux)
-   LIBS += -ldl
-endif
-
-ifeq ($(findstring SunOS,$(PLATFORM)), SunOS)
-   LIBS += -lsocket -lnsl -ldl
-   MAKE = gmake
-endif
-
-ifeq ($(findstring FreeBSD,$(PLATFORM)), FreeBSD)
-   MAKE = gmake
-   OS_TYPE = -D__FREEBSD__
-endif
-
-ifeq ($(findstring NetBSD,$(PLATFORM)), NetBSD)
-   MAKE = gmake
-   OS_TYPE = -D__NETBSD__
-endif
-
-ifeq ($(findstring CYGWIN,$(PLATFORM)), CYGWIN)
-   OPT += -DFD_SETSIZE=4096
-   OS_TYPE = -DCYGWIN
-endif
-
-ifeq ($(findstring mingw,$(shell gcc --version)), mingw)
-   IS_MINGW = 1
-   OS_TYPE = -DMINGW
-   OPT += -DFD_SETSIZE=4096
-#   CFLAGS += -I../zlib
-#   LIBS += -L../../lib
-   LIBS += -lws2_32
-endif
-
-
-ifeq ($(findstring x86_64,$(ARCH)), x86_64)
-    OPT += -m32
-endif
-
-CFLAGS = $(OPT) -I../common $(OS_TYPE)
-
-ifdef SQLFLAG
-  ifdef IS_MINGW
-    CFLAGS += -I../mysql
-    LIBS += -lmysql
-  else
-    MYSQLFLAG_CONFIG = $(shell which mysql_config)
-    ifeq ($(findstring /,$(MYSQLFLAG_CONFIG)), /)
-      MYSQLFLAG_VERSION = $(shell $(MYSQLFLAG_CONFIG) --version | sed s:\\..*::)
-      ifeq ($(findstring 5,$(MYSQLFLAG_VERSION)), 5)
-        MYSQLFLAG_CONFIG_ARGUMENT = --include
-      else
-        MYSQLFLAG_CONFIG_ARGUMENT = --cflags
-      endif
-      CFLAGS += $(shell $(MYSQLFLAG_CONFIG) $(MYSQLFLAG_CONFIG_ARGUMENT))
-      LIBS += $(shell $(MYSQLFLAG_CONFIG) --libs)
-    else
-      CFLAGS += -I/usr/local/include/mysql
-      LIBS += -L/usr/local/lib/mysql -lmysqlclient
-    endif
-  endif
-endif
-
-ifneq ($(findstring -lz,$(LIBS)), -lz)
-   LIBS += -lz
-endif
-ifneq ($(findstring -lm,$(LIBS)), -lm)
-   LIBS += -lm
-endif
-
-MKDEF = CC="$(CC)" CFLAGS="$(CFLAGS)" LIB_S="$(LIBS)"
-
-endif
-
-.PHONY: txt sql common login login_sql char char_sql map map_sql ladmin converters \
-	addons plugins tools clean depend
-
-txt : Makefile.cache conf common login char map ladmin
-
-ifdef SQLFLAG
-sql: Makefile.cache conf common login_sql char_sql map_sql
-else
-sql:
-	$(MAKE) SQLFLAG=1 $@
-endif
-
-conf:
-	cp -r conf-tmpl conf
-	cp -r save-tmpl save
-	rm -rf conf/.svn conf/*/.svn save/.svn
-
-common: src/common/GNUmakefile
-	$(MAKE) -C src/$@ $(MKDEF)
-
-login: src/login/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF) txt
-
-char: src/char/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF) txt
-
-map: src/map/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF) txt
-
-login_sql: src/login_sql/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF) sql
-
-char_sql: src/char_sql/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF) sql
-
-map_sql: src/map/GNUmakefile common
-	$(MAKE) -C src/map $(MKDEF) sql
-
-ladmin: src/ladmin/GNUmakefile common
-	$(MAKE) -C src/$@ $(MKDEF)
-
-plugins addons: src/plugins/GNUmakefile common
-	$(MAKE) -C src/plugins $(MKDEF)
-
-tools:
-	$(MAKE) -C src/tool $(MKDEF)
-	
-ifdef SQLFLAG
-converters: src/txt-converter/GNUmakefile common
-	$(MAKE) -C src/txt-converter $(MKDEF)
-else
-converters:
-	$(MAKE) SQLFLAG=1 $@
-endif
-
-clean: src/common/GNUmakefile src/login/GNUmakefile src/login_sql/GNUmakefile \
-	src/char/GNUmakefile src/char_sql/GNUmakefile src/map/GNUmakefile \
-	src/ladmin/GNUmakefile src/plugins/GNUmakefile src/txt-converter/GNUmakefile
-	rm -f Makefile.cache
-	$(MAKE) -C src/common $@
-	$(MAKE) -C src/login $@
-	$(MAKE) -C src/login_sql $@
-	$(MAKE) -C src/char $@
-	$(MAKE) -C src/char_sql $@
-	$(MAKE) -C src/map $@
-	$(MAKE) -C src/ladmin $@
-	$(MAKE) -C src/plugins $@
-	$(MAKE) -C src/txt-converter $@
-
-depend: src/common/GNUmakefile src/login/GNUmakefile src/login_sql/GNUmakefile \
-	src/char/GNUmakefile src/char_sql/GNUmakefile src/map/GNUmakefile \
-	src/ladmin/GNUmakefile src/plugins/GNUmakefile src/txt-converter/GNUmakefile
-	cd src/common; makedepend -fGNUmakefile -pobj/ -Y. *.c; cd ../..;
-	cd src/login; makedepend -DTXT_ONLY -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	cd src/login_sql; makedepend -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	cd src/char; makedepend -DTXT_ONLY -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	cd src/char_sql; makedepend -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	cd src/map; makedepend -DTXT_ONLY -fGNUmakefile -ptxtobj/ -Y. -Y../common *.c; cd ../..;
-	cd src/map; makedepend -fGNUmakefile -a -psqlobj/ -Y. -Y../common *.c; cd ../..;
-	cd src/ladmin; makedepend -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	cd src/txt-converter; makedepend -DTXT_SQL_CONVERT -fGNUmakefile -Y. -Y../common *.c; cd ../..;
-	$(MAKE) -C src/plugins $@
-
-Makefile.cache:
-	printf "$(subst ",\",$(MKDEF))" > Makefile.cache
-
-src/%/GNUmakefile: src/%/Makefile
-	sed -e 's/$$>/$$^/' $< > $@
-
-src/common/GNUmakefile: src/common/Makefile
-src/login/GNUmakefile: src/login/Makefile
-src/login_sql/GNUmakefile: src/login_sql/Makefile
-src/char/GNUmakefile: src/char/Makefile
-src/char_sql/GNUmakefile: src/char_sql/Makefile
-src/map/GNUmakefile: src/map/Makefile
-src/plugins/GNUmakefile: src/plugins/Makefile
-src/ladmin/GNUmakefile: src/ladmin/Makefile
-src/txt-converter/GNUmakefile: src/txt-converter/Makefile
-
-install:	conf/%.conf conf/%.txt
-	$(shell mkdir -p /opt/eathena/bin/)
-	$(shell mkdir -p /opt/eathena/etc/eathena/)
-	$(shell mkdir -p /opt/eathena/var/log/eathena/)
-	$(shell mv save /opt/eathena/etc/eathena/save)
-	$(shell mv db /opt/eathena/etc/eathena/db)
-	$(shell mv conf /opt/eathena/etc/eathena/conf)
-	$(shell mv npc /opt/eathena/etc/eathena/npc)
-	$(shell mv log/* /opt/eathena/var/log/eathena/)
-	$(shell cp *-server* /opt/eathena/bin/)
-	$(shell cp ladmin /opt/eathena/bin/)
-	$(shell ln -s /opt/eathena/etc/eathena/save/ /opt/eathena/bin/)
-	$(shell ln -s /opt/eathena/etc/eathena/db/ /opt/eathena/bin/)
-	$(shell ln -s /opt/eathena/etc/eathena/conf/ /opt/eathena/bin/)
-	$(shell ln -s /opt/eathena/etc/eathena/npc/ /opt/eathena/bin/)
-	$(shell ln -s /opt/eathena/var/log/eathena/ /opt/eathena/bin/log)
-
-bin-clean:
-	$(shell rm /opt/eathena/bin/login-server*)
-	$(shell rm /opt/eathena/bin/char-server*)
-	$(shell rm /opt/eathena/bin/map-server*)
-	$(shell rm /opt/eathena/bin/ladmin)
-
-uninstall:
-	bin-clean
-	$(shell rm /opt/eathena/bin/save)
-	$(shell rm /opt/eathena/bin/db)
-	$(shell rm /opt/eathena/bin/conf)
-	$(shell rm /opt/eathena/bin/npc)
-	$(shell rm /opt/eathena/bin/log)
-	$(shell rm -rf /opt/eathena/etc/eathena)
-	$(shell rm -rf /opt/eathena/var/log/eathena)

+ 181 - 0
Makefile.in

@@ -0,0 +1,181 @@
+@SET_MAKE@
+
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	ALL_DEPENDS=common common_sql login login_sql char char_sql map map_sql ladmin tools converters plugins conf
+	SQL_DEPENDS=common_sql login_sql char_sql map_sql conf
+	COMMON_SQL_DEPENDS=
+	LOGIN_SQL_DEPENDS=common_sql
+	CHAR_SQL_DEPENDS=common_sql
+	MAP_SQL_DEPENDS=common_sql
+	CONVERTERS_DEPENDS=common_sql
+else
+	ALL_DEPENDS=common login char map ladmin tools plugins conf
+	SQL_DEPENDS=needs_mysql
+	COMMON_SQL_DEPENDS=needs_mysql
+	LOGIN_SQL_DEPENDS=needs_mysql
+	CHAR_SQL_DEPENDS=needs_mysql
+	MAP_SQL_DEPENDS=needs_mysql
+	CONVERTERS_DEPENDS=needs_mysql
+endif
+
+#####################################################################
+.PHONY: txt sql common common_sql login login_sql char char_sql map map_sql \
+	ladmin tools converters plugins addons conf clean help depend
+
+all: $(ALL_DEPENDS)
+
+txt: common login char map conf
+
+sql: $(SQL_DEPENDS)
+
+common:
+	@$(MAKE) -C src/common txt
+
+common_sql: $(COMMON_SQL_DEPENDS)
+	@$(MAKE) -C src/common sql
+
+login: common
+	@$(MAKE) -C src/login
+
+login_sql: $(LOGIN_SQL_DEPENDS)
+	@$(MAKE) -C src/login_sql
+
+char: common
+	@$(MAKE) -C src/char
+
+char_sql: $(CHAR_SQL_DEPENDS)
+	@$(MAKE) -C src/char_sql
+
+map: common
+	@$(MAKE) -C src/map txt
+
+map_sql: $(MAP_SQL_DEPENDS)
+	@$(MAKE) -C src/map sql
+
+ladmin: common
+	@$(MAKE) -C src/ladmin
+
+tools:
+	@$(MAKE) -C src/tool
+
+converters: $(CONVERTERS_DEPENDS)
+	@$(MAKE) -C src/txt-converter
+
+plugins addons: common
+	@$(MAKE) -C src/plugins
+
+conf:
+# conf:
+# 1) create conf and conf/import folders
+# 2) add missing import files
+# 3) copy the rest of the files and folders
+# 4) remove remaining .svn folders
+	@echo "building conf folder..."
+	@if test ! -d conf ; then mkdir conf ; fi
+	@if test ! -d conf/import ; then mkdir conf/import ; fi
+	@for f in $$(ls conf-tmpl/import) ; do if test ! -e conf/import/$$f ; then cp conf-tmpl/import/$$f conf/import ; fi ; done
+	@for f in $$(ls conf-tmpl) ; do if test "$$f" != "import" ; then cp -rf conf-tmpl/$$f conf ; fi ; done
+	@rm -rf conf/*/.svn
+# save:
+# 1)  create save folder
+# 2) add missing files
+	@echo "building save folder..."
+	@if test ! -d save ; then mkdir save ; fi
+	@for f in $$(ls save-tmpl) ; do if test ! -e save/$$f ; then cp save-tmpl/$$f save ; fi ; done
+
+clean:
+	@$(MAKE) -C src/common $@
+	@$(MAKE) -C src/login $@
+	@$(MAKE) -C src/login_sql $@
+	@$(MAKE) -C src/char $@
+	@$(MAKE) -C src/char_sql $@
+	@$(MAKE) -C src/map $@
+	@$(MAKE) -C src/ladmin $@
+	@$(MAKE) -C src/plugins $@
+	@$(MAKE) -C src/tool $@
+	@$(MAKE) -C src/txt-converter $@
+
+help:
+	@echo "most common targets are 'all' 'txt' 'sql' 'clean' 'help'"
+	@echo "possible targets are:"
+	@echo "'common'      - builds object files used in TXT servers"
+	@echo "'common_sql'  - builds object files used in SQL servers"
+	@echo "'login'       - builds login server (TXT version)"
+	@echo "'login_sql'   - builds login server (SQL version)"
+	@echo "'char'        - builds char server (TXT version)"
+	@echo "'char_sql'    - builds char server (SQL version)"
+	@echo "'map'         - builds map server (TXT version)"
+	@echo "'map_sql'     - builds map server (SQL version)"
+	@echo "'ladmin'      - builds remote administration tool"
+	@echo "'tools'       - builds all the tools in src/tools"
+	@echo "'converters'  - builds the login/char converters"
+	@echo "'plugins'     - builds all the plugins in src/plugins"
+	@echo "'addons'"
+	@echo "'conf'        - builds conf and save folders from the templates"
+	@echo "'all'         - builds all above targets"
+	@echo "'txt'         - builds txt servers (targets 'common' 'login' 'char' 'map' and"
+	@echo "                'conf')"
+	@echo "'sql'         - builds sql servers (targets 'common_sql' 'login_sql' 'char_sql'"
+	@echo "                'map_sql' and 'conf')"
+	@echo "'clean'       - cleans builds and objects"
+	@echo "'help'        - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
+
+#####################################################################
+# TODO
+
+# Server Packet Protocol version (also defined in src/common/mmo.h)
+# CFLAGS += -DPACKETVER=8
+
+# Makes map-wide script variables be saved to SQL instead of TXT files.
+# CFLAGS += -DMAPREGSQL
+
+# OPT += -DGCOLLECT
+# LIBS += -lgc
+
+# OPT += -DMEMWATCH
+
+# OPT += -DDMALLOC -DDMALLOC_FUNC_CHECK
+# LIBS += -ldmalloc
+
+# OPT += -DBCHECK
+
+
+install:	conf/%.conf conf/%.txt
+	$(shell mkdir -p /opt/eathena/bin/)
+	$(shell mkdir -p /opt/eathena/etc/eathena/)
+	$(shell mkdir -p /opt/eathena/var/log/eathena/)
+	$(shell mv save /opt/eathena/etc/eathena/save)
+	$(shell mv db /opt/eathena/etc/eathena/db)
+	$(shell mv conf /opt/eathena/etc/eathena/conf)
+	$(shell mv npc /opt/eathena/etc/eathena/npc)
+	$(shell mv log/* /opt/eathena/var/log/eathena/)
+	$(shell cp *-server* /opt/eathena/bin/)
+	$(shell cp ladmin /opt/eathena/bin/)
+	$(shell ln -s /opt/eathena/etc/eathena/save/ /opt/eathena/bin/)
+	$(shell ln -s /opt/eathena/etc/eathena/db/ /opt/eathena/bin/)
+	$(shell ln -s /opt/eathena/etc/eathena/conf/ /opt/eathena/bin/)
+	$(shell ln -s /opt/eathena/etc/eathena/npc/ /opt/eathena/bin/)
+	$(shell ln -s /opt/eathena/var/log/eathena/ /opt/eathena/bin/log)
+
+bin-clean:
+	$(shell rm /opt/eathena/bin/login-server*)
+	$(shell rm /opt/eathena/bin/char-server*)
+	$(shell rm /opt/eathena/bin/map-server*)
+	$(shell rm /opt/eathena/bin/ladmin)
+
+uninstall:
+	bin-clean
+	$(shell rm /opt/eathena/bin/save)
+	$(shell rm /opt/eathena/bin/db)
+	$(shell rm /opt/eathena/bin/conf)
+	$(shell rm /opt/eathena/bin/npc)
+	$(shell rm /opt/eathena/bin/log)
+	$(shell rm -rf /opt/eathena/etc/eathena)
+	$(shell rm -rf /opt/eathena/var/log/eathena)

+ 2 - 2
conf-tmpl/msg_athena.conf

@@ -436,9 +436,9 @@
 511: %d - From : %s (New - Priority)
 511: %d - From : %s (New - Priority)
 512: %d - From : %s (New)
 512: %d - From : %s (New)
 513: %d - From : %s
 513: %d - From : %s
-514: You have %d new messages.
+514: You have %d unread messages.
 515: You have %d unread priority messages.
 515: You have %d unread priority messages.
-516: You have no new messages.
+516: You have no unread messages.
 517: Message not found.
 517: Message not found.
 518: Reading message from %s.
 518: Reading message from %s.
 519: Cannot delete unread priority mail.
 519: Cannot delete unread priority mail.

+ 0 - 256
configure

@@ -1,256 +0,0 @@
-#!/bin/bash
-## NOTE:
-## I know this is not a clean way to check for some stuff
-## and edit the Makefile, but hey, it does work!
-
-#    Configure script for eAthena
-#    Copyright (C) 2005  dontBR
-#
-#    This program is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation; either version 2 of the License, or
-#    (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-# Default variables
-status_mmx="No"
-status_sse="No"
-status_sse2="No"
-status_sse3="No"
-status_pcre="No"
-prefix='/opt/eathena/'
-
-# Functions
-function check_sed {
-	echo -n "Checking for sed... "
-	if [ -f $(which sed) ]; then
-		echo "yes"
-	else
-		echo "Error: sed not found in $PATH"
-		exit 1
-	fi
-}
-
-function check_gcc {
-	echo -n "Checking for gcc... "
-	if [ -f $(which gcc) ]; then
-		echo "yes"
-	else
-		echo "Error: GCC not found in $PATH"
-		exit 1
-	fi
-}
-
-function check_make {
-	echo -n "Checking for (g)make... "
-	if [ -f $(which make) ]; then
-		maker=make
-		echo "yes"
-	else	if [ -f $(which gmake) ]; then
-			maker=gmake
-			echo "yes"
-			else
-			echo "Error: (g)make not found in $PATH"
-			exit 1
-		fi
-	fi
-}
-
-function check_sockets {
-	echo -n "Checking for sockets... "
-	echo "#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-int main(){
-}" > test_sockets.c
-	if $(gcc test_sockets.c -o test_sockets); then
-		echo "yes"
-		rm -f test_sockets.c test_sockets
-	else
-		echo "Error: Unix sockets not found/working."
-		exit 1
-		rm -f test_sockets.c
-	fi
-}
-
-function check_mysql_headers {
-	echo -n "Checking for MySQL headers... "
-	if [ -d /usr/local/lib/mysql ]; then		# Default
-		echo "yes"
-		mysql_headers_path='/usr/local/lib/mysql'
-	else
-		if [ -d /usr/include/mysql ]; then	# Gentoo/Debian/?
-			echo "yes"
-			mysql_headers_path='/usr/include/mysql'
-	else
-		echo "Error: MySQL headers not found."
-		mysql_headers_path='Not found.'
-	fi
-	fi
-}
-
-function optimize {
-	case $@ in
-		mmx )	status_mmx="Yes" ;;
-		sse )	status_sse="Yes" ;;
-		sse2 )	status_sse2="Yes" ;;
-		sse3 )	status_sse3="Yes" ;;
-		all )	status_mmx="Yes"
-			status_sse="Yes"
-			status_sse2="Yes"
-			status_sse3="Yes" ;;
-	esac
-}
-
-function make_changes {
-	if [ "$maker" != "make" ]; then
-		sed -e 's,MAKE = make,MAKE = '$maker',g' Makefile -i
-	fi
-	if [ "$status_mmx" = "Yes" ]; then
-		sed -e 's,# OPT += -mmmx,OPT += -mmmx,g' Makefile -i
-	fi
-	if [ "$status_sse" = "Yes" ]; then
-		sed -e 's,# OPT += -msse,OPT += -msse,g' Makefile -i
-	fi
-	if [ "$status_sse2" = "Yes" ]; then
-		sed -e 's,# OPT += -msse2,OPT += -msse2,g' Makefile -i
-	fi
-	if [ "$status_sse3" = "Yes" ]; then
-		sed -e 's,# OPT += -msse3,OPT += -msse3,g' Makefile -i
-	fi
-	if [ "$status_pcre" = "Yes" ]; then
-		sed -e 's,# OPT += -DPCRE_SUPPORT,OPT += -DPCRE_SUPPORT,g' Makefile -i
-	fi
-	if [ "$mysql_headers_path" != "/usr/local/lib/mysql" ] && [ "$mysql_headers_path" != "Not found." ]; then
-		sed -e 's,LIBS += -L/usr/local/lib/mysql -lmysqlclient,LIBS += -L'$mysql_headers_path' -lmysqlclient,g' Makefile -i
-	fi
-}
-
-function opt_check_pcre {
-	echo -n "Checking for PCRE... "
-	if [ -f /usr/local/lib/pcre.h ]; then
-		echo "yes"
-		status_pcre="Yes"
-	else
-		echo "Error: PCRE not found."
-		status_pcre="No"
-	fi
-}
-
-function make_report {
-	echo "Configuration report:"
-	echo eAthena
-
-	echo
-	echo Enable PCRE support..... : $status_pcre
-	echo
-	echo Enable MMX optimization. : $status_mmx
-	echo Enable SSE optimization. : $status_sse
-	echo Enable SSE2 optimization : $status_sse2
-	echo Enable SSE3 optimization : $status_sse3
-	echo
-	echo MySQL headers path...... : $mysql_headers_path
-	echo
-	echo eAthena will be installed in $prefix
-	echo Please type \'make txt\' or \'make sql\' now to compile eAthena.
-}
-
-function helptext {
-	echo "eAthena Configure Script version 0.1"
-	echo
-	echo "Options:"
-	echo
-	echo "	-h	Display this help message and exit."
-	echo "	-d	Enter debug mode."
-	echo "	-o	Turn on optimization flags."
-	echo "		Supported:"
-	echo "		mmx"
-	echo "		sse"
-	echo "		sse2"
-	echo "		sse3"
-	echo "		all"
-	echo "	-e	Enable PCRE support."
-	echo "	-p	Root directory where eA is going to be installed."
-	echo "		DON'T FORGET THE LAST SLASH!"
-	echo "		For example:"
-	echo "		./configure -p /usr/local/"
-	echo "		This will create /usr/local/bin/login-server,"
-	echo "		/usr/local/etc/eathena/save/account.txt, etc"
-	echo "		Default is /opt/eathena/"
-	echo
-	echo "Report bugs (about the configure script) to dontBR at the eAthena Support Board."
-}
-
-function make_installable {
-	echo	-e ''										>>	Makefile
-	echo	-e 'install:	conf/%.conf conf/%.txt'					>>	Makefile
-	echo	-e '		$(shell mkdir -p '$prefix'bin/)'				>>	Makefile
-	echo	-e '		$(shell mkdir -p '$prefix'etc/eathena/)'			>>	Makefile
-	echo	-e '		$(shell mkdir -p '$prefix'var/log/eathena/)'			>>	Makefile
-	echo	-e '		$(shell mv save '$prefix'etc/eathena/save)'			>>	Makefile
-	echo	-e '		$(shell mv db '$prefix'etc/eathena/db)'			>>	Makefile
-	echo	-e '		$(shell mv conf '$prefix'etc/eathena/conf)'			>>	Makefile
-	echo	-e '		$(shell mv npc '$prefix'etc/eathena/npc)'			>>	Makefile
-	echo	-e '		$(shell mv log/* '$prefix'var/log/eathena/)'			>>	Makefile
-	echo	-e '		$(shell cp *-server* '$prefix'bin/)'				>>	Makefile
-	echo	-e '		$(shell cp ladmin '$prefix'bin/)'				>>	Makefile
-	echo	-e '		$(shell ln -s '$prefix'etc/eathena/save/ '$prefix'bin/)'	>>	Makefile
-	echo	-e '		$(shell ln -s '$prefix'etc/eathena/db/ '$prefix'bin/)'	>>	Makefile
-	echo	-e '		$(shell ln -s '$prefix'etc/eathena/conf/ '$prefix'bin/)'	>>	Makefile
-	echo	-e '		$(shell ln -s '$prefix'etc/eathena/npc/ '$prefix'bin/)'	>>	Makefile
-	echo	-e '		$(shell ln -s '$prefix'var/log/eathena/ '$prefix'bin/log)'	>>	Makefile
-	echo			''								>>	Makefile
-	echo	-e 'bin-clean:'									>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/login-server*)'			>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/char-server*)'				>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/map-server*)'				>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/ladmin)'				>>	Makefile
-	echo	 		''								>>	Makefile
-	echo	-e 'uninstall:'									>>	Makefile
-	echo	-e '		bin-clean'							>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/save)'					>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/db)'					>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/conf)'					>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/npc)'					>>	Makefile
-	echo	-e '		$(shell rm '$prefix'bin/log)'					>>	Makefile
-	echo	-e '		$(shell rm -rf '$prefix'etc/eathena)'				>>	Makefile
-	echo	-e '		$(shell rm -rf '$prefix'var/log/eathena)'			>>	Makefile
-}
-
-
-# Arguments
-while getopts ":hdo:ep:" opt; do
-	case $opt in
-		h )	helptext ; exit ;;
-		d )	set -x ;;
-		o ) 	optimize ${OPTARG} ;;
-		e )	opt_check_pcre ;;
-		p )	prefix=${OPTARG} ; [ -d ${OPTARG} ] || echo "The directory $prefix does not exist. Creating...";;
-	esac
-done
-
-
-# Execution
-echo "eAthena configure script"
-echo "Note: This is ALPHA software! Do NOT use it on a production server!"
-echo
-echo "Checking for dependencies.."
-check_sed
-check_gcc
-check_make
-check_sockets
-check_mysql_headers
-make_changes
-make_installable
-echo
-make_report
-exit

+ 295 - 0
configure.in

@@ -0,0 +1,295 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT(eAthena)
+AC_REVISION($Revision$)
+AC_PREREQ([2.61])
+AC_CONFIG_SRCDIR([src/common/cbasetypes.h])
+AC_CONFIG_FILES([Makefile src/common/Makefile])
+AC_CONFIG_FILES([src/char/Makefile src/login/Makefile src/ladmin/Makefile])
+AC_CONFIG_FILES([src/char_sql/Makefile src/login_sql/Makefile src/txt-converter/Makefile])
+AC_CONFIG_FILES([src/map/Makefile src/plugins/Makefile src/tool/Makefile])
+
+
+#
+# Enable/disable MySql and optionally specify the path (optional library)
+#
+AC_ARG_WITH(
+	[mysql],
+	AC_HELP_STRING(
+		[--with-mysql=@<:@ARG@:>@],
+		[use MySQL client library @<:@default=yes@:>@, optionally specify path to the mysql_config executable]
+	),
+	[
+		if test "$withval" = "no" ; then
+			want_mysql="no"
+		elif test "$withval" = "yes" ; then
+			want_mysql="yes"
+		else
+			want_mysql="yes"
+			MYSQL_CONFIG_HOME="$withval"
+		fi
+	],
+	[want_mysql="yes"]
+)
+
+
+#
+# Enable/disable PCRE and optionally specify the path (optional library)
+#
+AC_ARG_WITH(
+	[pcre],
+	AC_HELP_STRING(
+		[--with-pcre=@<:@ARG@:>@],
+		[use PCRE library @<:@default=yes@:>@, optionally specify the root directory path of pcre installation]
+	),
+	[
+		if test "$withval" = "no" ; then
+			want_pcre="no"
+		elif test "$withval" = "yes" ; then
+			want_pcre="yes"
+		else
+			want_pcre="yes"
+			PCRE_HOME="$withval"
+		fi
+	],
+	[want_pcre="yes"]
+)
+
+
+#
+# Specify the path of the zlib library (required library)
+#
+AC_ARG_WITH(
+	[zlib],
+	AC_HELP_STRING(
+		[--with-zlib=DIR],
+		[root directory path of zlib installation (defaults to /usr/local or /usr if not found in /usr/local)]
+	),
+	[
+		test -n "$withval" && ZLIB_HOME="$withval"
+	],
+	[
+		ZLIB_HOME=/usr/local
+		test ! -f "${ZLIB_HOME}/include/zlib.h" && ZLIB_HOME=/usr
+	]
+)
+
+
+
+###############################################################################
+# Checks for programs and types.
+
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_CPP
+AC_LANG([C])
+
+
+CFLAGS="$CFLAGS -pipe -ffast-math -Wall -Wno-sign-compare"
+CPPFLAGS="$CPPFLAGS -I../common"
+
+
+AC_C_BIGENDIAN(
+	[AC_MSG_ERROR([[bigendian is not supported... stopping]])],
+	,
+	[AC_MSG_WARN([[unable to determine endianess, only little endian is supported]])]
+)
+
+
+AC_MSG_CHECKING([whether pointers can be stored in ints (old code)])
+pointers_fit_in_ints="no"
+AC_COMPILE_IFELSE(
+	[AC_LANG_PROGRAM([[int hw[(sizeof(int) == sizeof(void *))];]])],
+	[pointers_fit_in_ints="yes"],
+	[]
+)
+if test "$pointers_fit_in_ints" = "no" ; then
+	CFLAGS="$CFLAGS -m32"
+	AC_COMPILE_IFELSE(
+		[AC_LANG_PROGRAM([[int hw[(sizeof(int) == sizeof(void *))];]])],
+		[pointers_fit_in_ints="yes (with -m32)"],
+		[]
+	)
+fi
+AC_MSG_RESULT($pointers_fit_in_ints)
+if test "$pointers_fit_in_ints" = "no" ; then
+	AC_MSG_ERROR([pointers cannot be stored in ints, required for old code... stopping])
+fi
+
+
+AC_MSG_CHECKING([whether $CC supports -Wno-unused-parameter])
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wno-unused-parameter"
+AC_COMPILE_IFELSE(
+	[int foo;],
+	[AC_MSG_RESULT([yes])],
+	[
+		AC_MSG_RESULT([no])
+		CFLAGS="$OLD_CFLAGS"
+	]
+)
+
+
+AC_MSG_CHECKING([whether $CC supports -Wno-pointer-sign])
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CPPFLAGS -Wno-pointer-sign"
+AC_COMPILE_IFELSE(
+	[int foo;],
+	[AC_MSG_RESULT([yes])],
+	[
+		AC_MSG_RESULT([no])
+		CFLAGS="$OLD_CFLAGS"
+	]
+)
+
+
+###############################################################################
+# Checks for libraries and header files.
+
+
+
+dnl
+dnl Check MySQL library (optional)
+dnl
+
+MYSQL_VERSION=""
+MYSQL_CFLAGS=""
+MYSQL_LIBS=""
+
+if test "$want_mysql" = "no" ; then
+	AC_MSG_NOTICE([ignoring MySQL (optional)])
+else
+	if test -z "$MYSQL_CONFIG_HOME" -o test; then
+		AC_PATH_PROG([MYSQL_CONFIG_HOME], [mysql_config], [no])
+	fi
+
+	AC_MSG_CHECKING([MySQL library (optional)])
+	if test "$MYSQL_CONFIG_HOME" != "no" ; then
+		HAVE_MYSQL="yes"
+		MYSQL_VERSION="`$MYSQL_CONFIG_HOME --version`"
+		MYSQL_CFLAGS="`$MYSQL_CONFIG_HOME --cflags`"
+		MYSQL_LIBS="`$MYSQL_CONFIG_HOME --libs`"
+		AC_MSG_RESULT([yes ($MYSQL_VERSION)])
+	else
+		AC_MSG_RESULT([no])
+		AC_MSG_NOTICE([disabling MySQL (optional)])
+	fi
+fi
+
+AC_SUBST([HAVE_MYSQL])
+AC_SUBST([MYSQL_VERSION])
+AC_SUBST([MYSQL_CFLAGS])
+AC_SUBST([MYSQL_LIBS])
+
+
+
+dnl
+dnl Check PCRE libraries (optional)
+dnl
+
+##TODO PCRE version
+PCRE_LIBS=""
+PCRE_CFLAGS=""
+
+if test "$want_pcre" = "no" ; then
+	AC_MSG_NOTICE([ignoring PCRE (optional)])
+else
+	if test -z "$PCRE_HOME" ; then
+		AC_CHECK_LIB([pcre], [pcre_study], [HAVE_PCRE="yes"], [])
+		if test "$HAVE_PCRE" = "yes" ; then
+			PCRE_LIBS="-lpcre"
+		fi
+	else
+		PCRE_OLD_LDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS -L$PCRE_HOME/lib"
+		PCRE_OLD_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$PCRE_HOME/include"
+		AC_CHECK_LIB(pcre, pcre_compile, [HAVE_PCRE="yes"], [])
+		CPPFLAGS="$PCRE_OLD_CPPFLAGS"
+		LDFLAGS="$PCRE_OLD_LDFLAGS"
+		if test "$HAVE_PCRE" = "yes" ; then
+			PCRE_LIBS="-L$PCRE_HOME/lib -lpcre"
+			test -d "$PCRE_HOME/include" && PCRE_CFLAGS="-I$PCRE_HOME/include"
+		fi
+	fi
+	AC_MSG_CHECKING([PCRE library (optional)])
+	if test "$HAVE_PCRE" = "yes" ; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		AC_MSG_NOTICE([disabling PCRE (optional)])
+	fi
+fi
+
+AC_SUBST([HAVE_PCRE])
+AC_SUBST([PCRE_LIBS])
+AC_SUBST([PCRE_CFLAGS])
+
+
+
+dnl
+dnl zlib library (required)
+dnl
+
+if test -n "${ZLIB_HOME}" ; then
+	LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
+	CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
+fi
+AC_CHECK_LIB([z], [inflateEnd], ,[AC_MSG_ERROR([zlib library not found, please specify the correct path with --with-zlib=DIR... stopping])])
+AC_CHECK_HEADER([zlib.h], , [AC_MSG_ERROR([zlib header not found, please specify the correct path with --with-zlib=DIR... stopping])])
+
+
+
+dnl
+dnl math library (required)
+dnl
+
+AC_CHECK_LIB([m], [sqrt], [], [AC_MSG_ERROR([math library not found... stopping])])
+
+
+
+dnl
+dnl Host specific stuff
+dnl
+
+AC_MSG_CHECKING([host OS])
+host_os="`uname`"
+AC_MSG_RESULT([$host_os])
+fd_setsize=""
+DLLEXT=".so"
+case $host_os in
+Solaris* )
+	LIBS="$LIBS -lsocket -lnsl -ldl"
+	;;
+Linux* )
+	LIBS="$LIBS -ldl"
+	;;
+FreeBSD*)
+	CPPFLAGS="$CPPFLAGS -D__FREEBSD__"
+	;;
+NetBSD*)
+	CPPFLAGS="$CPPFLAGS -D__NETBSD__"
+	;;
+CYGWIN*)
+	CPPFLAGS="$CPPFLAGS -DFD_SETSIZE=4096 -DCYGWIN"
+	fd_setsize="done"
+	DLLEXT=".dll"
+	;;
+esac
+AC_SUBST([DLLEXT])
+
+AC_MSG_CHECKING([for MinGW])
+if test -n "`$CC --version | grep -i mingw`" ; then
+	AC_MSG_RESULT([yes])
+	CPPFLAGS="$CPPFLAGS -DMINGW"
+	if test -z "$fd_setsize" ; then
+		CPPFLAGS="$CPPFLAGS -DFD_SETSIZE=4096"
+	fi
+	LIBS="$LIBS -lws2_32"
+else
+	AC_MSG_RESULT([no])
+fi
+
+
+
+###############################################################################
+AC_OUTPUT

+ 8 - 0
eAthena-8.sln

@@ -117,15 +117,23 @@ Global
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug-sql|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug-sql|Win32.ActiveCfg = Debug|Win32
+		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug-txt|Win32.ActiveCfg = Debug|Win32
+		{D356871D-58E1-450B-967A-E9E9646175AF}.Debug-txt|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release|Win32.Build.0 = Release|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release|Win32.Build.0 = Release|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release-sql|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-E9E9646175AF}.Release-sql|Win32.ActiveCfg = Release|Win32
+		{D356871D-58E1-450B-967A-E9E9646175AF}.Release-txt|Win32.ActiveCfg = Release|Win32
+		{D356871D-58E1-450B-967A-E9E9646175AF}.Release-txt|Win32.Build.0 = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug-sql|Win32.ActiveCfg = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug-sql|Win32.ActiveCfg = Debug|Win32
+		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug-txt|Win32.ActiveCfg = Debug|Win32
+		{D356871D-58E1-450B-967A-EAE9646175AF}.Debug-txt|Win32.Build.0 = Debug|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release|Win32.Build.0 = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release|Win32.Build.0 = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release-sql|Win32.ActiveCfg = Release|Win32
 		{D356871D-58E1-450B-967A-EAE9646175AF}.Release-sql|Win32.ActiveCfg = Release|Win32
+		{D356871D-58E1-450B-967A-EAE9646175AF}.Release-txt|Win32.ActiveCfg = Release|Win32
+		{D356871D-58E1-450B-967A-EAE9646175AF}.Release-txt|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 26 - 11
src/char/Makefile → src/char/Makefile.in

@@ -1,5 +1,3 @@
-all txt: char-server
-
 COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
 COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
 	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
 	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
 	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
 	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
@@ -7,21 +5,38 @@ COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
 	../common/obj/mapindex.o ../common/obj/ers.o
 	../common/obj/mapindex.o ../common/obj/ers.o
 COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
 COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
 	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
 	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
-	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
-	../common/grfio.h ../common/mapindex.h
+	../common/malloc.h ../common/showmsg.h ../common/utils.h \
+	../common/strlib.h ../common/grfio.h \
+	../common/mapindex.h ../common/ers.h
 
 
-%.o: %.c
-	$(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $<
-	
-char-server: char.o inter.o int_party.o int_guild.o int_status.o int_storage.o int_pet.o int_homun.o $(COMMON_OBJ)
-	$(CC) -o ../../$@ $> $(LIB_S)
+CHAR_OBJ = char.o inter.o int_party.o int_guild.o int_storage.o int_status.o int_pet.o int_homun.o
+
+#####################################################################
+.PHONY : all char-server clean help
+
+all: char-server
+
+char-server: $(CHAR_OBJ) $(COMMON_OBJ)
+	@CC@ @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) @LIBS@
 
 
 clean:
 clean:
-	rm -f *.o ../../char-server GNUmakefile
+	rm -f *.o ../../char-server@EXEEXT@
+
+help:
+	@echo "possible targets are 'char-server' 'all' 'clean' 'help'"
+	@echo "'char-server'  - char server (TXT version)"
+	@echo "'all'          - builds all above targets"
+	@echo "'clean'        - cleans builds and objects"
+	@echo "'help'         - outputs this message"
+
+#####################################################################
+
+%.o: %.c
+	@CC@ @CFLAGS@ -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
 
 
 # DO NOT DELETE
 # DO NOT DELETE
 
 
-char.o: char.c char.h inter.h int_pet.h $(COMMON_H) ../common/version.h
+char.o: char.c char.h inter.h int_pet.h $(COMMON_H)
 inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h char.h $(COMMON_H)
 inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h char.h $(COMMON_H)
 int_party.o: int_party.c int_party.h inter.h char.h $(COMMON_H)
 int_party.o: int_party.c int_party.h inter.h char.h $(COMMON_H)
 int_guild.o: int_guild.c int_guild.h int_storage.h inter.h char.h $(COMMON_H)
 int_guild.o: int_guild.c int_guild.h int_storage.h inter.h char.h $(COMMON_H)

+ 5 - 3
src/char/char.c

@@ -11,17 +11,19 @@
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/timer.h"
 #include "../common/timer.h"
+#include "../common/lock.h"
+#include "../common/malloc.h"
+#include "../common/mapindex.h"
+#include "../common/showmsg.h"
+#include "../common/utils.h"
 #include "../common/version.h"
 #include "../common/version.h"
-
 #include "inter.h"
 #include "inter.h"
 #include "int_guild.h"
 #include "int_guild.h"
 #include "int_homun.h"
 #include "int_homun.h"
 #include "int_pet.h"
 #include "int_pet.h"
 #include "int_party.h"
 #include "int_party.h"
 #include "int_storage.h"
 #include "int_storage.h"
-#ifdef ENABLE_SC_SAVING
 #include "int_status.h"
 #include "int_status.h"
-#endif
 #include "char.h"
 #include "char.h"
 
 
 #include <sys/types.h>
 #include <sys/types.h>

+ 1 - 2
src/char/char.h

@@ -5,7 +5,6 @@
 #define _CHAR_H_
 #define _CHAR_H_
 
 
 #include "../common/mmo.h"
 #include "../common/mmo.h"
-#include "../common/mapindex.h"
 
 
 #define START_CHAR_NUM 150000
 #define START_CHAR_NUM 150000
 #define MAX_MAP_SERVERS 30
 #define MAX_MAP_SERVERS 30
@@ -21,7 +20,7 @@ struct character_data {
 struct mmo_charstatus* search_character(int aid, int cid);
 struct mmo_charstatus* search_character(int aid, int cid);
 struct mmo_charstatus* search_character_byname(char* character_name);
 struct mmo_charstatus* search_character_byname(char* character_name);
 int search_character_index(char* character_name);
 int search_character_index(char* character_name);
-char * search_character_name(int index);
+char* search_character_name(int index);
 int search_character_online(int aid, int cid);
 int search_character_online(int aid, int cid);
 
 
 int mapif_sendall(unsigned char *buf, unsigned int len);
 int mapif_sendall(unsigned char *buf, unsigned int len);

+ 4 - 4
src/char/int_guild.c

@@ -1,10 +1,6 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
@@ -17,6 +13,10 @@
 #include "int_storage.h"
 #include "int_storage.h"
 #include "int_guild.h"
 #include "int_guild.h"
 
 
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 char guild_txt[1024] = "save/guild.txt";
 char guild_txt[1024] = "save/guild.txt";
 char castle_txt[1024] = "save/castle.txt";
 char castle_txt[1024] = "save/castle.txt";
 
 

+ 3 - 0
src/char/int_guild.h

@@ -4,6 +4,9 @@
 #ifndef _INT_GUILD_H_
 #ifndef _INT_GUILD_H_
 #define _INT_GUILD_H_
 #define _INT_GUILD_H_
 
 
+struct guild;
+struct guild_castle;
+
 int inter_guild_init(void);
 int inter_guild_init(void);
 void inter_guild_final(void);
 void inter_guild_final(void);
 int inter_guild_save(void);
 int inter_guild_save(void);

+ 4 - 4
src/char/int_homun.c

@@ -1,10 +1,6 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
@@ -15,6 +11,10 @@
 #include "inter.h"
 #include "inter.h"
 #include "int_homun.h"
 #include "int_homun.h"
 
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 char homun_txt[1024]="save/homun.txt";
 char homun_txt[1024]="save/homun.txt";
 
 
 static struct dbt *homun_db;
 static struct dbt *homun_db;

+ 0 - 1
src/char/int_homun.h

@@ -8,7 +8,6 @@ int inter_homun_init(void);
 void inter_homun_final(void);
 void inter_homun_final(void);
 int inter_homun_save(void);
 int inter_homun_save(void);
 int inter_homun_delete(int homun_id);
 int inter_homun_delete(int homun_id);
-
 int inter_homun_parse_frommap(int fd);
 int inter_homun_parse_frommap(int fd);
 
 
 extern char homun_txt[1024];
 extern char homun_txt[1024];

+ 4 - 4
src/char/int_party.c

@@ -1,10 +1,6 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
@@ -16,6 +12,10 @@
 #include "inter.h"
 #include "inter.h"
 #include "int_party.h"
 #include "int_party.h"
 
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 char party_txt[1024] = "save/party.txt";
 char party_txt[1024] = "save/party.txt";
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
 struct party_data {
 struct party_data {

+ 2 - 2
src/char/int_party.h

@@ -4,12 +4,12 @@
 #ifndef _INT_PARTY_H_
 #ifndef _INT_PARTY_H_
 #define _INT_PARTY_H_
 #define _INT_PARTY_H_
 
 
+struct party;
+
 int inter_party_init(void);
 int inter_party_init(void);
 void inter_party_final(void);
 void inter_party_final(void);
 int inter_party_save(void);
 int inter_party_save(void);
-
 int inter_party_parse_frommap(int fd);
 int inter_party_parse_frommap(int fd);
-
 int inter_party_leave(int party_id,int account_id, int char_id);
 int inter_party_leave(int party_id,int account_id, int char_id);
 
 
 extern char party_txt[1024];
 extern char party_txt[1024];

+ 4 - 4
src/char/int_pet.c

@@ -1,10 +1,6 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
@@ -15,6 +11,10 @@
 #include "inter.h"
 #include "inter.h"
 #include "int_pet.h"
 #include "int_pet.h"
 
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 char pet_txt[1024]="save/pet.txt";
 char pet_txt[1024]="save/pet.txt";
 
 
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT

+ 2 - 0
src/char/int_pet.h

@@ -4,6 +4,8 @@
 #ifndef _INT_PET_H_
 #ifndef _INT_PET_H_
 #define _INT_PET_H_
 #define _INT_PET_H_
 
 
+struct s_pet;
+
 int inter_pet_init(void);
 int inter_pet_init(void);
 void inter_pet_final(void);
 void inter_pet_final(void);
 int inter_pet_save(void);
 int inter_pet_save(void);

+ 4 - 3
src/char/int_status.c

@@ -1,13 +1,14 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-
-#include "int_status.h"
+#include "../common/mmo.h"
 #include "../common/db.h"
 #include "../common/db.h"
 #include "../common/lock.h"
 #include "../common/lock.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "int_status.h"
+
+#include <stdio.h>
 
 
 static struct dbt * scdata_db = NULL;	//Contains all the status change data in-memory. [Skotlex]
 static struct dbt * scdata_db = NULL;	//Contains all the status change data in-memory. [Skotlex]
 char scdata_txt[1024]="save/scdata.txt"; //By [Skotlex]
 char scdata_txt[1024]="save/scdata.txt"; //By [Skotlex]

+ 2 - 4
src/char/int_status.h

@@ -4,7 +4,7 @@
 #ifndef _INT_STATUS_H_
 #ifndef _INT_STATUS_H_
 #define _INT_STATUS_H_
 #define _INT_STATUS_H_
 
 
-#include "char.h"
+struct status_change_data;
 
 
 struct scdata {
 struct scdata {
 	int account_id, char_id;
 	int account_id, char_id;
@@ -14,12 +14,10 @@ struct scdata {
 
 
 extern char scdata_txt[1024];
 extern char scdata_txt[1024];
 
 
-#ifdef ENABLE_SC_SAVING
-struct scdata *status_search_scdata(int aid, int cid);
+struct scdata* status_search_scdata(int aid, int cid);
 void status_delete_scdata(int aid, int cid);
 void status_delete_scdata(int aid, int cid);
 void inter_status_save(void);
 void inter_status_save(void);
 void status_init(void);
 void status_init(void);
 void status_final(void);
 void status_final(void);
-#endif
 
 
 #endif /* _INT_STATUS_H_ */
 #endif /* _INT_STATUS_H_ */

+ 5 - 4
src/char/int_storage.c

@@ -1,22 +1,23 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
 #include "../common/db.h"
 #include "../common/db.h"
 #include "../common/lock.h"
 #include "../common/lock.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
 #include "char.h"
 #include "char.h"
 #include "inter.h"
 #include "inter.h"
 #include "int_storage.h"
 #include "int_storage.h"
 #include "int_pet.h"
 #include "int_pet.h"
 #include "int_guild.h"
 #include "int_guild.h"
 
 
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
 // ファイル名のデフォルト
 // ファイル名のデフォルト
 // inter_config_read()で再設定される
 // inter_config_read()で再設定される
 char storage_txt[1024]="save/storage.txt";
 char storage_txt[1024]="save/storage.txt";

+ 3 - 1
src/char/int_storage.h

@@ -4,13 +4,15 @@
 #ifndef _INT_STORAGE_H_
 #ifndef _INT_STORAGE_H_
 #define _INT_STORAGE_H_
 #define _INT_STORAGE_H_
 
 
+struct storage;
+struct guild_storage;
+
 int inter_storage_init(void);
 int inter_storage_init(void);
 void inter_storage_final(void);
 void inter_storage_final(void);
 int inter_storage_save(void);
 int inter_storage_save(void);
 int inter_guild_storage_save(void);
 int inter_guild_storage_save(void);
 int inter_storage_delete(int account_id);
 int inter_storage_delete(int account_id);
 int inter_guild_storage_delete(int guild_id);
 int inter_guild_storage_delete(int guild_id);
-
 int inter_storage_parse_frommap(int fd);
 int inter_storage_parse_frommap(int fd);
 
 
 extern char storage_txt[1024];
 extern char storage_txt[1024];

+ 4 - 5
src/char/inter.c

@@ -1,10 +1,6 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include "../common/db.h"
 #include "../common/db.h"
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
@@ -12,7 +8,6 @@
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/lock.h"
 #include "../common/lock.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
-
 #include "char.h"
 #include "char.h"
 #include "inter.h"
 #include "inter.h"
 #include "int_party.h"
 #include "int_party.h"
@@ -22,6 +17,10 @@
 #include "int_pet.h"
 #include "int_pet.h"
 #include "int_homun.h"
 #include "int_homun.h"
 
 
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
 #define WISDATA_TTL (60*1000)	// Existence time of Wisp/page data (60 seconds)
 #define WISDATA_TTL (60*1000)	// Existence time of Wisp/page data (60 seconds)
                              	// that is the waiting time of answers of all map-servers
                              	// that is the waiting time of answers of all map-servers
 #define WISDELLIST_MAX 256   	// Number of elements of Wisp/page data deletion list
 #define WISDELLIST_MAX 256   	// Number of elements of Wisp/page data deletion list

+ 2 - 0
src/char/inter.h

@@ -4,6 +4,8 @@
 #ifndef _INTER_H_
 #ifndef _INTER_H_
 #define _INTER_H_
 #define _INTER_H_
 
 
+struct accreg;
+
 int inter_init_txt(const char *file);
 int inter_init_txt(const char *file);
 void inter_final(void);
 void inter_final(void);
 int inter_save(void);
 int inter_save(void);

+ 0 - 28
src/char_sql/Makefile

@@ -1,28 +0,0 @@
-all sql: char-server_sql
-
-COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
-	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
-	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
-	../common/obj/strlib.o ../common/obj/grfio.o \
-	../common/obj/mapindex.o ../common/obj/ers.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
-	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
-	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
-	../common/grfio.h ../common/mapindex.h
-
-char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o int_homun.o itemdb.o $(COMMON_OBJ)
-	$(CC) -o ../../$@ $^ $(LIB_S)
-
-clean:
-	rm -f *.o ../../char-server_sql GNUmakefile
-
-# DO NOT DELETE
-
-char.o: char.c char.h ../common/strlib.h itemdb.h ../common/showmsg.h
-inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h ../common/mmo.h char.h ../common/socket.h ../common/showmsg.h
-int_party.o: int_party.c int_party.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/timer.h ../common/db.h ../common/showmsg.h
-int_guild.o: int_guild.c int_guild.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/db.h ../common/showmsg.h
-int_storage.o: int_storage.c int_storage.h char.h itemdb.h ../common/showmsg.h
-int_pet.o: int_pet.c int_pet.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
-int_homun.o: int_homun.c int_homun.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
-itemdb.o: itemdb.c itemdb.h ../common/db.h ../common/mmo.h ../common/showmsg.h

+ 56 - 0
src/char_sql/Makefile.in

@@ -0,0 +1,56 @@
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
+	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
+	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
+	../common/obj/strlib.o ../common/obj/grfio.o \
+	../common/obj/mapindex.o ../common/obj/ers.o ../common/obj_sql/sql.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
+	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
+	../common/malloc.h ../common/showmsg.h ../common/utils.h \
+	../common/strlib.h ../common/grfio.h \
+	../common/mapindex.h ../common/ers.h ../common/sql.h
+
+CHAR_OBJ = char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o int_homun.o
+
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	CHAR_SERVER_SQL_DEPENDS=$(CHAR_OBJ) $(COMMON_OBJ)
+else
+	CHAR_SERVER_SQL_DEPENDS=needs_mysql
+endif
+
+#####################################################################
+.PHONY : all char-server_sql clean help
+
+all: char-server_sql
+
+char-server_sql: $(CHAR_SERVER_SQL_DEPENDS)
+	@CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) @LIBS@ @MYSQL_LIBS@
+
+clean:
+	rm -f *.o ../../char-server_sql@EXEEXT@
+
+help:
+	@echo "possible targets are 'char-server_sql' 'all' 'clean' 'help'"
+	@echo "'char-server_sql'  - char server (SQL version)"
+	@echo "'all'              - builds all above targets"
+	@echo "'clean'            - cleans builds and objects"
+	@echo "'help'             - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
+
+%.o: %.c
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+
+# DO NOT DELETE
+
+char.o: char.c char.h $(COMMON_H)
+inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h $(COMMON_H)
+int_party.o: int_party.c int_party.h inter.h $(COMMON_H)
+int_guild.o: int_guild.c int_guild.h inter.h $(COMMON_H)
+int_storage.o: int_storage.c int_storage.h char.h $(COMMON_H)
+int_pet.o: int_pet.c int_pet.h inter.h char.h $(COMMON_H)
+int_homun.o: int_homun.c int_homun.h inter.h char.h $(COMMON_H)

File diff suppressed because it is too large
+ 413 - 509
src/char_sql/char.c


+ 2 - 26
src/char_sql/char.h

@@ -4,37 +4,13 @@
 #ifndef _CHAR_SQL_H_
 #ifndef _CHAR_SQL_H_
 #define _CHAR_SQL_H_
 #define _CHAR_SQL_H_
 
 
-#include "../common/core.h"
-#include "../common/socket.h"
-#include "../common/timer.h"
-#include "../common/mmo.h"
-#include "../common/version.h"
-#include "../common/db.h"
-#include "../common/mapindex.h"
-
-#include "inter.h"
-#include "int_pet.h"
-#include "int_guild.h"
-#include "int_party.h"
-#include "int_storage.h"
-#include "itemdb.h"
+struct mmo_charstatus;
 
 
 #define START_CHAR_NUM 150000
 #define START_CHAR_NUM 150000
 #define MAX_MAP_SERVERS 30
 #define MAX_MAP_SERVERS 30
 
 
 #define DEFAULT_AUTOSAVE_INTERVAL 300*1000
 #define DEFAULT_AUTOSAVE_INTERVAL 300*1000
 
 
-struct itemtmp {
-	int flag;//checked = 1 else 0
-	int id;
-	short nameid;
-	short amount;
-	unsigned short equip;
-	char identify;
-	char refine;
-	char attribute;
-	short card[4];
-};
 enum {
 enum {
 	TABLE_INVENTORY,
 	TABLE_INVENTORY,
 	TABLE_CART,
 	TABLE_CART,
@@ -42,7 +18,7 @@ enum {
 	TABLE_GUILD_STORAGE,
 	TABLE_GUILD_STORAGE,
 };
 };
 
 
-int memitemdata_to_sql(struct itemtmp mapitem[], int count, int char_id,int tableswitch);
+int memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch);
 
 
 int mapif_sendall(unsigned char *buf,unsigned int len);
 int mapif_sendall(unsigned char *buf,unsigned int len);
 int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);
 int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);

File diff suppressed because it is too large
+ 384 - 410
src/char_sql/int_guild.c


+ 14 - 11
src/char_sql/int_guild.h

@@ -4,17 +4,6 @@
 #ifndef _INT_GUILD_SQL_H_
 #ifndef _INT_GUILD_SQL_H_
 #define _INT_GUILD_SQL_H_
 #define _INT_GUILD_SQL_H_
 
 
-int inter_guild_parse_frommap(int fd);
-int inter_guild_sql_init(void);
-void inter_guild_sql_final(void);
-int inter_guild_mapif_init(int fd);
-int inter_guild_leave(int guild_id,int account_id,int char_id);
-int mapif_parse_BreakGuild(int fd,int guild_id);
-int inter_guild_broken(int guild_id);
-int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender);
-int inter_guild_CharOnline(int char_id, int guild_id);
-int inter_guild_CharOffline(int char_id, int guild_id);
-
 #define GS_BASIC 0x0001
 #define GS_BASIC 0x0001
 #define GS_MEMBER 0x0002
 #define GS_MEMBER 0x0002
 #define GS_POSITION 0x0004
 #define GS_POSITION 0x0004
@@ -29,6 +18,20 @@ int inter_guild_CharOffline(int char_id, int guild_id);
 #define GS_BASIC_MASK (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES)
 #define GS_BASIC_MASK (GS_BASIC | GS_EMBLEM | GS_CONNECT | GS_LEVEL | GS_MES)
 #define GS_REMOVE 0x8000
 #define GS_REMOVE 0x8000
 
 
+struct guild;
+struct guild_castle;
+
+int inter_guild_parse_frommap(int fd);
+int inter_guild_sql_init(void);
+void inter_guild_sql_final(void);
+int inter_guild_mapif_init(int fd);
+int inter_guild_leave(int guild_id,int account_id,int char_id);
+int mapif_parse_BreakGuild(int fd,int guild_id);
+int inter_guild_broken(int guild_id);
+int inter_guild_sex_changed(int guild_id,int account_id,int char_id, int gender);
+int inter_guild_CharOnline(int char_id, int guild_id);
+int inter_guild_CharOffline(int char_id, int guild_id);
+
 //For the TXT->SQL converter.
 //For the TXT->SQL converter.
 int inter_guild_tosql(struct guild *g,int flag);
 int inter_guild_tosql(struct guild *g,int flag);
 int inter_guildcastle_tosql(struct guild_castle *gc);
 int inter_guildcastle_tosql(struct guild_castle *gc);

+ 109 - 108
src/char_sql/int_homun.c

@@ -1,14 +1,19 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "char.h"
+#include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/socket.h"
+#include "../common/utils.h"
+#include "../common/sql.h"
+#include "char.h"
+#include "inter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 
 struct s_homunculus *homun_pt;
 struct s_homunculus *homun_pt;
 
 
@@ -68,154 +73,150 @@ int mapif_homunculus_created(int fd, int account_id, struct s_homunculus *sh, un
 // Save/Update Homunculus Skills
 // Save/Update Homunculus Skills
 int mapif_save_homunculus_skills(struct s_homunculus *hd)
 int mapif_save_homunculus_skills(struct s_homunculus *hd)
 {
 {
+	SqlStmt* stmt;
 	int i;
 	int i;
 
 
-	for(i=0; i<MAX_HOMUNSKILL; i++)
+	stmt = SqlStmt_Malloc(sql_handle);
+	if( SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `skill_homunculus` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", hd->hom_id) )
+		SqlStmt_ShowDebug(stmt);
+	for( i = 0; i < MAX_HOMUNSKILL; ++i )
 	{
 	{
-		if(hd->hskill[i].id != 0 && hd->hskill[i].lv != 0 )
+		if( hd->hskill[i].id > 0 && hd->hskill[i].lv != 0 )
 		{
 		{
-			sprintf(tmp_sql,"REPLACE INTO `skill_homunculus` (`homun_id`, `id`, `lv`) VALUES (%d, %d, %d)",
-				hd->hom_id, hd->hskill[i].id, hd->hskill[i].lv);
-
-			if(mysql_query(&mysql_handle, tmp_sql)){
-				ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			SqlStmt_BindParam(stmt, 0, SQLDT_USHORT, &hd->hskill[i].id, 0);
+			SqlStmt_BindParam(stmt, 1, SQLDT_USHORT, &hd->hskill[i].lv, 0);
+			if( SQL_ERROR == SqlStmt_Execute(stmt) )
+			{
+				SqlStmt_ShowDebug(stmt);
+				SqlStmt_Free(stmt);
 				return 0;
 				return 0;
 			}
 			}
 		}
 		}
 	}
 	}
+	SqlStmt_Free(stmt);
 
 
 	return 1;
 	return 1;
 }
 }
 
 
 int mapif_save_homunculus(int fd, int account_id, struct s_homunculus *hd)
 int mapif_save_homunculus(int fd, int account_id, struct s_homunculus *hd)
 {
 {
-	int flag =1;
-	char t_name[NAME_LENGTH*2];
-	jstrescapecpy(t_name, hd->name);
+	int flag = 1;
+	char esc_name[NAME_LENGTH*2+1];
 
 
-	if(hd->hom_id==0) // new homunculus
-	{
-		sprintf(tmp_sql, "INSERT INTO `homunculus` "
+	Sql_EscapeStringLen(sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH));
+
+	if( hd->hom_id == 0 )
+	{// new homunculus
+		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `homunculus` "
 			"(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
 			"(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
 			"VALUES ('%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
 			"VALUES ('%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
-			hd->char_id, hd->class_,t_name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
-			hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize);
-
+			hd->char_id, hd->class_, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize) )
+		{
+			Sql_ShowDebug(sql_handle);
+			flag = 0;
+		}
+		else
+		{
+			hd->hom_id = (int)Sql_LastInsertId(sql_handle);
+		}
 	}
 	}
 	else
 	else
 	{
 	{
-		sprintf(tmp_sql, "UPDATE `homunculus` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
-			hd->char_id, hd->class_,t_name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
-			hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id);
-	}
-
-	if(mysql_query(&mysql_handle, tmp_sql)){
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		flag =  0;
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `homunculus` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
+			hd->char_id, hd->class_, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
+			hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id) )
+		{
+			Sql_ShowDebug(sql_handle);
+			flag = 0;
+		}
+		else
+		{
+			flag = mapif_save_homunculus_skills(hd);
+			mapif_saved_homunculus(fd, account_id, flag);
+		}
 	}
 	}
 
 
-	if(hd->hom_id==0 && flag!=0)
-		hd->hom_id = (int)mysql_insert_id(&mysql_handle); // new homunculus
-	else
-	{
-		flag = mapif_save_homunculus_skills(hd);
-		mapif_saved_homunculus(fd, account_id, flag);
-	}
 	return flag;
 	return flag;
 }
 }
 
 
 
 
 
 
 // Load an homunculus
 // Load an homunculus
-int mapif_load_homunculus(int fd){
+int mapif_load_homunculus(int fd)
+{
 	int i;
 	int i;
-	RFIFOHEAD(fd);
-	memset(homun_pt, 0, sizeof(struct s_homunculus));
+	char* data;
+	size_t len;
 
 
-	sprintf(tmp_sql,"SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%u'", RFIFOL(fd,6));
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	memset(homun_pt, 0, sizeof(struct s_homunculus));
+	RFIFOHEAD(fd);
 
 
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%u'", RFIFOL(fd,6)) )
+	{
+		Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
 	}
 	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		sql_row = mysql_fetch_row(sql_res);
-
-		homun_pt->hom_id = RFIFOL(fd,6) ; //RFIFOL(fd,2);
-		homun_pt->class_ = atoi(sql_row[2]);
-		strncpy(homun_pt->name, sql_row[3], NAME_LENGTH);
-		homun_pt->char_id = atoi(sql_row[1]);
-		homun_pt->level = atoi(sql_row[4]);
-		homun_pt->exp = atoi(sql_row[5]);
-		homun_pt->intimacy = atoi(sql_row[6]);
-		homun_pt->hunger = atoi(sql_row[7]);
-		homun_pt->str = atoi(sql_row[8]);
-		homun_pt->agi = atoi(sql_row[9]);
-		homun_pt->vit = atoi(sql_row[10]);
-		homun_pt->int_ = atoi(sql_row[11]);
-		homun_pt->dex = atoi(sql_row[12]);
-		homun_pt->luk = atoi(sql_row[13]);
-		homun_pt->hp = atoi(sql_row[14]);
-		homun_pt->max_hp = atoi(sql_row[15]);
-		homun_pt->sp = atoi(sql_row[16]);
-		homun_pt->max_sp = atoi(sql_row[17]);
-		homun_pt->skillpts = atoi(sql_row[18]);
-		homun_pt->rename_flag = atoi(sql_row[19]);
-		homun_pt->vaporize = atoi(sql_row[20]);
+	if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+	{
+		homun_pt->hom_id = RFIFOL(fd,6);
+		Sql_GetData(sql_handle,  1, &data, NULL); homun_pt->char_id = atoi(data);
+		Sql_GetData(sql_handle,  2, &data, NULL); homun_pt->class_ = atoi(data);
+		Sql_GetData(sql_handle,  3, &data, &len); memcpy(homun_pt->name, data, min(len, NAME_LENGTH));
+		Sql_GetData(sql_handle,  4, &data, NULL); homun_pt->level = atoi(data);
+		Sql_GetData(sql_handle,  5, &data, NULL); homun_pt->exp = atoi(data);
+		Sql_GetData(sql_handle,  6, &data, NULL); homun_pt->intimacy = (unsigned int)strtoul(data, NULL, 10);
+		homun_pt->intimacy = cap_value(homun_pt->intimacy, 0, 100000);
+		Sql_GetData(sql_handle,  7, &data, NULL); homun_pt->hunger = atoi(data);
+		homun_pt->hunger = cap_value(homun_pt->hunger, 0, 100);
+		Sql_GetData(sql_handle,  8, &data, NULL); homun_pt->str = atoi(data);
+		Sql_GetData(sql_handle,  9, &data, NULL); homun_pt->agi = atoi(data);
+		Sql_GetData(sql_handle, 10, &data, NULL); homun_pt->vit = atoi(data);
+		Sql_GetData(sql_handle, 11, &data, NULL); homun_pt->int_ = atoi(data);
+		Sql_GetData(sql_handle, 12, &data, NULL); homun_pt->dex = atoi(data);
+		Sql_GetData(sql_handle, 13, &data, NULL); homun_pt->luk = atoi(data);
+		Sql_GetData(sql_handle, 14, &data, NULL); homun_pt->hp = atoi(data);
+		Sql_GetData(sql_handle, 15, &data, NULL); homun_pt->max_hp = atoi(data);
+		Sql_GetData(sql_handle, 16, &data, NULL); homun_pt->sp = atoi(data);
+		Sql_GetData(sql_handle, 17, &data, NULL); homun_pt->max_sp = atoi(data);
+		Sql_GetData(sql_handle, 18, &data, NULL); homun_pt->skillpts = atoi(data);
+		Sql_GetData(sql_handle, 19, &data, NULL); homun_pt->rename_flag = atoi(data);
+		Sql_GetData(sql_handle, 20, &data, NULL); homun_pt->vaporize = atoi(data);
+
+		Sql_FreeResult(sql_handle);
 	}
 	}
-	if(homun_pt->hunger < 0)
-		homun_pt->hunger = 0;
-	else if(homun_pt->hunger > 100)
-		homun_pt->hunger = 100;
-	if(homun_pt->intimacy > 100000)
-		homun_pt->intimacy = 100000;
-
-	mysql_free_result(sql_res);
 
 
 	// Load Homunculus Skill
 	// Load Homunculus Skill
-	memset(homun_pt->hskill, 0, sizeof(homun_pt->hskill));
-
-	sprintf(tmp_sql,"SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d",homun_pt->hom_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d", homun_pt->hom_id) )
+	{
+		Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
 	}
 	}
-	sql_res = mysql_store_result(&mysql_handle);
-         if(sql_res){
-         	while((sql_row = mysql_fetch_row(sql_res))){
-						i = (atoi(sql_row[0])-HM_SKILLBASE-1);
-						homun_pt->hskill[i].id = atoi(sql_row[0]);
-                        homun_pt->hskill[i].lv = atoi(sql_row[1]);
-                 }
-         }
-
-	mysql_free_result(sql_res);
-
-	if (save_log)
+	while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+	{
+		// id
+		Sql_GetData(sql_handle, 0, &data, NULL);
+		i = atoi(data);
+		if( i < HM_SKILLBASE || i >= HM_SKILLBASE + MAX_HOMUNSKILL )
+			continue;// invalid guild skill
+		homun_pt->hskill[i].id = (unsigned short)i;
+		// lv
+		Sql_GetData(sql_handle, 1, &data, NULL);
+		homun_pt->hskill[i].lv = (unsigned short)atoi(data);
+	}
+	Sql_FreeResult(sql_handle);
+
+	if( save_log )
 		ShowInfo("Homunculus loaded (%d - %s).\n", homun_pt->hom_id, homun_pt->name);
 		ShowInfo("Homunculus loaded (%d - %s).\n", homun_pt->hom_id, homun_pt->name);
 	return mapif_info_homunculus(fd, RFIFOL(fd,2), homun_pt);
 	return mapif_info_homunculus(fd, RFIFOL(fd,2), homun_pt);
 }
 }
 
 
 int inter_delete_homunculus(int hom_id)
 int inter_delete_homunculus(int hom_id)
 {
 {
-	sprintf(tmp_sql, "DELETE FROM `homunculus` WHERE `homun_id` = '%u'", hom_id);
-	if(mysql_query(&mysql_handle, tmp_sql))
-	{
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		return 0;
-	}
-	
-	sprintf(tmp_sql, "DELETE FROM `skill_homunculus` WHERE `homun_id` = '%u'", hom_id);
-	if(mysql_query(&mysql_handle, tmp_sql))
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `homunculus` WHERE `homun_id` = '%u'", hom_id) ||
+		SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `skill_homunculus` WHERE `homun_id` = '%u'", hom_id) )
 	{
 	{
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
 	}
 	}
 	return 1;
 	return 1;

+ 2 - 0
src/char_sql/int_homun.h

@@ -4,6 +4,8 @@
 #ifndef _INT_HOMUN_SQL_H_
 #ifndef _INT_HOMUN_SQL_H_
 #define _INT_HOMUN_SQL_H_
 #define _INT_HOMUN_SQL_H_
 
 
+struct s_homunculus;
+
 int inter_homunculus_sql_init(void);
 int inter_homunculus_sql_init(void);
 void inter_homunculus_sql_final(void);
 void inter_homunculus_sql_final(void);
 int mapif_save_homunculus(struct s_homunculus *hd);
 int mapif_save_homunculus(struct s_homunculus *hd);

+ 144 - 174
src/char_sql/int_party.c

@@ -1,18 +1,22 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
+#include "../common/mmo.h"
 #include "../common/db.h"
 #include "../common/db.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
-
+#include "../common/mapindex.h"
+#include "../common/sql.h"
 #include "char.h"
 #include "char.h"
+#include "inter.h"
+#include "int_party.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
 struct party_data {
 struct party_data {
@@ -103,108 +107,88 @@ static void int_party_calc_state(struct party_data *p)
 int inter_party_tosql(struct party *p, int flag, int index)
 int inter_party_tosql(struct party *p, int flag, int index)
 {
 {
 	// 'party' ('party_id','name','exp','item','leader_id','leader_char')
 	// 'party' ('party_id','name','exp','item','leader_id','leader_char')
-	char t_name[NAME_LENGTH*2]; //Required for jstrescapecpy [Skotlex]
+	char esc_name[NAME_LENGTH*2+1];// escaped party name
 	int party_id;
 	int party_id;
-	if (p == NULL || p->party_id == 0)
+
+	if( p == NULL || p->party_id == 0 )
 		return 0;
 		return 0;
 	party_id = p->party_id;
 	party_id = p->party_id;
 
 
 #ifdef NOISY
 #ifdef NOISY
 	ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
 	ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
 #endif
 #endif
-	jstrescapecpy(t_name, p->name);
+	Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
 
 
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-	if (flag&PS_BREAK) { //Break the party
+	if( flag & PS_BREAK )
+	{// Break the party
 		// we'll skip name-checking and just reset everyone with the same party id [celest]
 		// we'll skip name-checking and just reset everyone with the same party id [celest]
-		sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-		sprintf(tmp_sql, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
+			Sql_ShowDebug(sql_handle);
+		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
+			Sql_ShowDebug(sql_handle);
 		//Remove from memory
 		//Remove from memory
 		idb_remove(party_db_, party_id);
 		idb_remove(party_db_, party_id);
 		return 1;
 		return 1;
 	}
 	}
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
-	if(flag&PS_CREATE) { //Create party
+	if( flag & PS_CREATE )
+	{// Create party
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-		sprintf(tmp_sql, "INSERT INTO `%s` "
+		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
 			"(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
 			"(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
 			"VALUES ('%s', '%d', '%d', '%d', '%d')",
 			"VALUES ('%s', '%d', '%d', '%d', '%d')",
-			party_db, t_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
+		{
+			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
 		}
 		}
-		if(mysql_field_count(&mysql_handle) == 0 &&
-			mysql_insert_id(&mysql_handle) != 0)
-			party_id = p->party_id = (int)mysql_insert_id(&mysql_handle);
-		else //Failed to retrieve ID??
-			return 0;
+		party_id = p->party_id = (int)Sql_LastInsertId(sql_handle);
 #else
 #else
 		//During conversion, you want to specify the id, and allow overwriting
 		//During conversion, you want to specify the id, and allow overwriting
 		//(in case someone is re-running the process.
 		//(in case someone is re-running the process.
-		sprintf(tmp_sql, "REPLACE INTO `%s` "
+
+		if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` "
 			"(`party_id`, `name`, `exp`, `item`, `leader_id`, `leader_char`) "
 			"(`party_id`, `name`, `exp`, `item`, `leader_id`, `leader_char`) "
 			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d')",
 			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d')",
-			party_db, p->party_id, t_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			party_db, p->party_id, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
+		{
+			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
 		}
 		}
 #endif
 #endif
 	}
 	}
 
 
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-	if (flag&PS_BASIC) {
-		//Update party info.
-		sprintf(tmp_sql, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
-			party_db, t_name, p->exp, p->item, party_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( flag & PS_BASIC )
+	{// Update party info.
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
+			party_db, esc_name, p->exp, p->item, party_id) )
+			Sql_ShowDebug(sql_handle);
 	}
 	}
 
 
-	if (flag&PS_LEADER) {
-		//Update leader
-		sprintf(tmp_sql, "UPDATE `%s`  SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
-			party_db, p->member[index].account_id, p->member[index].char_id, party_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( flag & PS_LEADER )
+	{// Update leader
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s`  SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
+			party_db, p->member[index].account_id, p->member[index].char_id, party_id) )
+			Sql_ShowDebug(sql_handle);
 	}
 	}
 	
 	
-	if (flag&PS_ADDMEMBER) {
-		//Add one party member.
-		sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
-			char_db, party_id, p->member[index].account_id, p->member[index].char_id);
-		if (mysql_query (&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( flag & PS_ADDMEMBER )
+	{// Add one party member.
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
+			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
+			Sql_ShowDebug(sql_handle);
 	}
 	}
 
 
-	if (flag&PS_DELMEMBER) {
-		//Remove one party member.
-		sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
-			char_db, party_id, p->member[index].account_id, p->member[index].char_id);
-		if (mysql_query (&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( flag & PS_DELMEMBER )
+	{// Remove one party member.
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
+			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
+			Sql_ShowDebug(sql_handle);
 	}
 	}
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
-	if (save_log)
+	if( save_log )
 		ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
 		ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
 	return 1;
 	return 1;
 }
 }
@@ -212,74 +196,69 @@ int inter_party_tosql(struct party *p, int flag, int index)
 // Read party from mysql
 // Read party from mysql
 struct party_data *inter_party_fromsql(int party_id)
 struct party_data *inter_party_fromsql(int party_id)
 {
 {
-	int leader_id = 0, leader_char = 0;
-	struct party_data *p;
+	int leader_id = 0;
+	int leader_char = 0;
+	struct party_data* p;
+	struct party_member* m;
+	char* data;
+	size_t len;
+	int i;
+
 #ifdef NOISY
 #ifdef NOISY
 	ShowInfo("Load party request ("CL_BOLD"%d"CL_RESET")\n", party_id);
 	ShowInfo("Load party request ("CL_BOLD"%d"CL_RESET")\n", party_id);
 #endif
 #endif
-	if (party_id <=0)
+	if( party_id <= 0 )
 		return NULL;
 		return NULL;
 	
 	
 	//Load from memory
 	//Load from memory
-	if ((p = idb_get(party_db_, party_id)) != NULL)
+	p = idb_get(party_db_, party_id);
+	if( p != NULL )
 		return p;
 		return p;
-	
+
 	p = party_pt;
 	p = party_pt;
 	memset(p, 0, sizeof(struct party_data));
 	memset(p, 0, sizeof(struct party_data));
 
 
-	sprintf(tmp_sql, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'",
-		party_db, party_id); // TBR
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
+	{
+		Sql_ShowDebug(sql_handle);
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-	sql_res = mysql_store_result(&mysql_handle) ;
-	if (!sql_res)
+	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
 		return NULL;
 		return NULL;
-	sql_row = mysql_fetch_row(sql_res);
-	if (!sql_row) {
-		mysql_free_result(sql_res);
-		return NULL;
-	}
+
 	p->party.party_id = party_id;
 	p->party.party_id = party_id;
-	strncpy(p->party.name, sql_row[1], NAME_LENGTH);
-	p->party.exp = atoi(sql_row[2])?1:0;
-	p->party.item = atoi(sql_row[3]);
-	leader_id = atoi(sql_row[4]);
-	leader_char = atoi(sql_row[5]);
-	mysql_free_result(sql_res);
+	Sql_GetData(sql_handle, 1, &data, &len); memcpy(p->party.name, data, min(len, NAME_LENGTH));
+	Sql_GetData(sql_handle, 2, &data, NULL); p->party.exp = (atoi(data) ? 1 : 0);
+	Sql_GetData(sql_handle, 3, &data, NULL); p->party.item = atoi(data);
+	Sql_GetData(sql_handle, 4, &data, NULL); leader_id = atoi(data);
+	Sql_GetData(sql_handle, 5, &data, NULL); leader_char = atoi(data);
+	Sql_FreeResult(sql_handle);
 
 
 	// Load members
 	// Load members
-	sprintf(tmp_sql,"SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'",
-		char_db, party_id); // TBR
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`name`,`base_level`,`last_map`,`online`,`class` FROM `%s` WHERE `party_id`='%d'", char_db, party_id) )
+	{
+		Sql_ShowDebug(sql_handle);
 		return NULL;
 		return NULL;
 	}
 	}
-	sql_res = mysql_store_result(&mysql_handle);
-	if (sql_res) {
-		int i;
-		for (i = 0; i<MAX_PARTY && (sql_row = mysql_fetch_row(sql_res)); i++) {
-			struct party_member *m = &p->party.member[i];
-			m->account_id = atoi(sql_row[0]);
-			m->char_id = atoi(sql_row[1]);
-			m->leader = (m->account_id == leader_id && m->char_id == leader_char)?1:0;
-			memcpy(m->name, sql_row[2], NAME_LENGTH);
-			m->lv = atoi(sql_row[3]);
-			m->map = mapindex_name2id(sql_row[4]);
-			m->online = atoi(sql_row[5])?1:0;
-			m->class_ = atoi(sql_row[6]);
-		}
-		mysql_free_result(sql_res);
-	}
-
-	if (save_log)
-		ShowInfo("Party loaded (%d - %s).\n",party_id, p->party.name);
+	for( i = 0; i < MAX_PARTY && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+	{
+		m = &p->party.member[i];
+		Sql_GetData(sql_handle, 0, &data, NULL); m->account_id = atoi(data);
+		Sql_GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data);
+		Sql_GetData(sql_handle, 2, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH));
+		Sql_GetData(sql_handle, 3, &data, NULL); m->lv = atoi(data);
+		Sql_GetData(sql_handle, 4, &data, NULL); m->map = mapindex_name2id(data);
+		Sql_GetData(sql_handle, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0);
+		Sql_GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data);
+		m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0);
+	}
+	Sql_FreeResult(sql_handle);
+
+	if( save_log )
+		ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
 	//Add party to memory.
 	//Add party to memory.
-	p = aCalloc(1, sizeof(struct party_data));
+	CREATE(p, struct party_data, 1);
 	memcpy(p, party_pt, sizeof(struct party_data));
 	memcpy(p, party_pt, sizeof(struct party_data));
 	//init state
 	//init state
 	int_party_calc_state(p);
 	int_party_calc_state(p);
@@ -299,13 +278,9 @@ int inter_party_sql_init(void)
 
 
 	/* Uncomment the following if you want to do a party_db cleanup (remove parties with no members) on startup.[Skotlex]
 	/* Uncomment the following if you want to do a party_db cleanup (remove parties with no members) on startup.[Skotlex]
 	ShowStatus("cleaning party table...\n");
 	ShowStatus("cleaning party table...\n");
-	sprintf (tmp_sql,
-		"DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
-		party_db, party_db, char_db, party_db, char_db, party_db, char_db, char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
+		party_db, party_db, char_db, party_db, char_db, party_db, char_db, char_db) )
+		Sql_ShowDebug(sql_handle);
 	*/
 	*/
 	return 0;
 	return 0;
 }
 }
@@ -318,27 +293,23 @@ void inter_party_sql_final(void)
 }
 }
 
 
 // Search for the party according to its name
 // Search for the party according to its name
-struct party_data* search_partyname(char *str)
+struct party_data* search_partyname(char* str)
 {
 {
-	char t_name[NAME_LENGTH*2];
-	int party_id;
-
-	sprintf(tmp_sql,"SELECT `party_id` FROM `%s` WHERE `name`='%s'",party_db, jstrescapecpy(t_name,str));
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res==NULL || mysql_num_rows(sql_res)<=0)
+	char esc_name[NAME_LENGTH*2+1];
+	char* data;
+	struct party_data* p = NULL;
+
+	Sql_EscapeStringLen(sql_handle, esc_name, str, strnlen(str, NAME_LENGTH));
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", party_db, esc_name) )
+		Sql_ShowDebug(sql_handle);
+	else if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
 	{
 	{
-		if (sql_res) mysql_free_result(sql_res);
-		return NULL;
+		Sql_GetData(sql_handle, 0, &data, NULL);
+		p = inter_party_fromsql(atoi(data));
 	}
 	}
-	sql_row = mysql_fetch_row(sql_res);
-	party_id = sql_row?atoi(sql_row[0]):0;
-	mysql_free_result(sql_res);
+	Sql_FreeResult(sql_handle);
 
 
-	return inter_party_fromsql(party_id);
+	return p;
 }
 }
 
 
 // Returns whether this party can keep having exp share or not.
 // Returns whether this party can keep having exp share or not.
@@ -627,12 +598,10 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
 	int i,j=-1;
 	int i,j=-1;
 
 
 	p = inter_party_fromsql(party_id);
 	p = inter_party_fromsql(party_id);
-	if (!p) { //Party does not exists?
-		sprintf(tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( p == NULL )
+	{// Party does not exists?
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
+			Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -809,26 +778,27 @@ int inter_party_leave(int party_id,int account_id, int char_id)
 	return mapif_parse_PartyLeave(-1,party_id,account_id, char_id);
 	return mapif_parse_PartyLeave(-1,party_id,account_id, char_id);
 }
 }
 
 
-int inter_party_CharOnline(int char_id, int party_id) {
-   struct party_data *p;
-   int i;
-   
-	if (party_id == -1) {
-		//Get party_id from the database
-		sprintf (tmp_sql , "SELECT party_id FROM `%s` WHERE char_id='%d'",char_db,char_id);
-		if(mysql_query(&mysql_handle, tmp_sql) ) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+int inter_party_CharOnline(int char_id, int party_id)
+{
+	struct party_data* p;
+	int i;
+
+	if( party_id == -1 )
+	{// Get party_id from the database
+		char* data;
+
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+		{
+			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
 		}
 		}
 
 
-		sql_res = mysql_store_result(&mysql_handle) ;
-		if(sql_res == NULL)
+		if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
 			return 0; //Eh? No party?
 			return 0; //Eh? No party?
-		
-		sql_row = mysql_fetch_row(sql_res);
-		party_id = sql_row?atoi(sql_row[0]):0;
-		mysql_free_result(sql_res);
+
+		Sql_GetData(sql_handle, 0, &data, NULL);
+		party_id = atoi(data);
+		Sql_FreeResult(sql_handle);
 	}
 	}
 	if (party_id == 0)
 	if (party_id == 0)
 		return 0; //No party...
 		return 0; //No party...
@@ -859,22 +829,22 @@ int inter_party_CharOffline(int char_id, int party_id) {
 	struct party_data *p=NULL;
 	struct party_data *p=NULL;
 	int i;
 	int i;
 
 
-	if (party_id == -1) {
-		//Get guild_id from the database
-		sprintf (tmp_sql , "SELECT party_id FROM `%s` WHERE char_id='%d'",char_db,char_id);
-		if(mysql_query(&mysql_handle, tmp_sql) ) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( party_id == -1 )
+	{// Get guild_id from the database
+		char* data;
+
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT party_id FROM `%s` WHERE char_id='%d'", char_db, char_id) )
+		{
+			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
 		}
 		}
 
 
-		sql_res = mysql_store_result(&mysql_handle) ;
-		if(sql_res == NULL)
+		if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
 			return 0; //Eh? No party?
 			return 0; //Eh? No party?
-		
-		sql_row = mysql_fetch_row(sql_res);
-		party_id = sql_row?atoi(sql_row[0]):0;
-		mysql_free_result(sql_res);
+
+		Sql_GetData(sql_handle, 0, &data, NULL);
+		party_id = atoi(data);
+		Sql_FreeResult(sql_handle);
 	}
 	}
 	if (party_id == 0)
 	if (party_id == 0)
 		return 0; //No party...
 		return 0; //No party...

+ 2 - 0
src/char_sql/int_party.h

@@ -18,6 +18,8 @@
 //Specify that this party must be deleted.
 //Specify that this party must be deleted.
 #define PS_BREAK 0x20
 #define PS_BREAK 0x20
 
 
+struct party;
+
 int inter_party_parse_frommap(int fd);
 int inter_party_parse_frommap(int fd);
 int inter_party_sql_init(void);
 int inter_party_sql_init(void);
 void inter_party_sql_final(void);
 void inter_party_sql_final(void);

+ 66 - 74
src/char_sql/int_pet.c

@@ -1,53 +1,52 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "char.h"
+#include "../common/mmo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
+#include "../common/socket.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
+#include "../common/sql.h"
+#include "char.h"
+#include "inter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 
 struct s_pet *pet_pt;
 struct s_pet *pet_pt;
 
 
 //---------------------------------------------------------
 //---------------------------------------------------------
-int inter_pet_tosql(int pet_id, struct s_pet *p) {
+int inter_pet_tosql(int pet_id, struct s_pet* p)
+{
 	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
 	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
-	char t_name[NAME_LENGTH*2];
-
-	jstrescapecpy(t_name, p->name);
-
-	if(p->hungry < 0)
-		p->hungry = 0;
-	else if(p->hungry > 100)
-		p->hungry = 100;
-	if(p->intimate < 0)
-		p->intimate = 0;
-	else if(p->intimate > 1000)
-		p->intimate = 1000;
-	if (pet_id == -1) //New pet.
-		sprintf(tmp_sql,"INSERT INTO `%s` "
+	char esc_name[NAME_LENGTH*2+1];// escaped pet name
+
+	Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
+	p->hungry = cap_value(p->hungry, 0, 100);
+	p->intimate = cap_value(p->intimate, 0, 1000);
+
+	if( pet_id == -1 )
+	{// New pet.
+		if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
 			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
 			"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
 			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
 			"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
-			pet_db, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate);
-
-	else	//Update pet.
-		sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
-			pet_db, p->class_, t_name, p->account_id, p->char_id, p->level, p->egg_id,
-			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		return 0;
-	} else if (pet_id == -1) { //New pet inserted.
-		if(mysql_field_count(&mysql_handle) == 0 &&
-			mysql_insert_id(&mysql_handle) != 0) {
-			p->pet_id = pet_id = (int)mysql_insert_id(&mysql_handle);
-		} else {
-			ShowError("inter_pet_tosql: Failed to retrieve new pet_id for '%s'. Pet creation aborted.\n", p->name);
+			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate) )
+		{
+			Sql_ShowDebug(sql_handle);
+			return 0;
+		}
+		p->pet_id = (int)Sql_LastInsertId(sql_handle);
+	}
+	else
+	{// Update pet.
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
+			pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
+			p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id) )
+		{
+			Sql_ShowDebug(sql_handle);
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
@@ -57,7 +56,10 @@ int inter_pet_tosql(int pet_id, struct s_pet *p) {
 	return 1;
 	return 1;
 }
 }
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-int inter_pet_fromsql(int pet_id, struct s_pet *p){
+int inter_pet_fromsql(int pet_id, struct s_pet* p)
+{
+	char* data;
+	size_t len;
 
 
 #ifdef NOISY
 #ifdef NOISY
 	ShowInfo("Loading pet (%d)...\n",pet_id);
 	ShowInfo("Loading pet (%d)...\n",pet_id);
@@ -66,42 +68,35 @@ int inter_pet_fromsql(int pet_id, struct s_pet *p){
 
 
 	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
 	//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
 
 
-	sprintf(tmp_sql,"SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'",pet_db, pet_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
+	{
+		Sql_ShowDebug(sql_handle);
 		return 0;
 		return 0;
 	}
 	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		sql_row = mysql_fetch_row(sql_res);
 
 
+	if( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+	{
 		p->pet_id = pet_id;
 		p->pet_id = pet_id;
-		p->class_ = atoi(sql_row[1]);
-		strncpy(p->name, sql_row[2], NAME_LENGTH);
-		p->account_id = atoi(sql_row[3]);
-		p->char_id = atoi(sql_row[4]);
-		p->level = atoi(sql_row[5]);
-		p->egg_id = atoi(sql_row[6]);
-		p->equip = atoi(sql_row[7]);
-		p->intimate = atoi(sql_row[8]);
-		p->hungry = atoi(sql_row[9]);
-		p->rename_flag = atoi(sql_row[10]);
-		p->incuvate = atoi(sql_row[11]);
+		Sql_GetData(sql_handle,  1, &data, NULL); p->class_ = atoi(data);
+		Sql_GetData(sql_handle,  2, &data, &len); memcpy(p->name, data, min(len, NAME_LENGTH));
+		Sql_GetData(sql_handle,  3, &data, NULL); p->account_id = atoi(data);
+		Sql_GetData(sql_handle,  4, &data, NULL); p->char_id = atoi(data);
+		Sql_GetData(sql_handle,  5, &data, NULL); p->level = atoi(data);
+		Sql_GetData(sql_handle,  6, &data, NULL); p->egg_id = atoi(data);
+		Sql_GetData(sql_handle,  7, &data, NULL); p->equip = atoi(data);
+		Sql_GetData(sql_handle,  8, &data, NULL); p->intimate = atoi(data);
+		Sql_GetData(sql_handle,  9, &data, NULL); p->hungry = atoi(data);
+		Sql_GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
+		Sql_GetData(sql_handle, 11, &data, NULL); p->incuvate = atoi(data);
+
+		Sql_FreeResult(sql_handle);
+
+		p->hungry = cap_value(p->hungry, 0, 100);
+		p->intimate = cap_value(p->intimate, 0, 1000);
+
+		if( save_log )
+			ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
 	}
 	}
-	if(p->hungry < 0)
-		p->hungry = 0;
-	else if(p->hungry > 100)
-		p->hungry = 100;
-	if(p->intimate < 0)
-		p->intimate = 0;
-	else if(p->intimate > 1000)
-		p->intimate = 1000;
-
-	mysql_free_result(sql_res);
-
-	if (save_log)
-		ShowInfo("Pet loaded (%d - %s).\n", pet_id, p->name);
 	return 0;
 	return 0;
 }
 }
 //----------------------------------------------
 //----------------------------------------------
@@ -119,11 +114,8 @@ void inter_pet_sql_final(void){
 int inter_pet_delete(int pet_id){
 int inter_pet_delete(int pet_id){
 	ShowInfo("delete pet request: %d...\n",pet_id);
 	ShowInfo("delete pet request: %d...\n",pet_id);
 
 
-	sprintf(tmp_sql,"DELETE FROM `%s` WHERE `pet_id`='%d'",pet_db, pet_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `pet_id`='%d'", pet_db, pet_id) )
+		Sql_ShowDebug(sql_handle);
 	return 0;
 	return 0;
 }
 }
 //------------------------------------------------------
 //------------------------------------------------------

+ 2 - 0
src/char_sql/int_pet.h

@@ -4,6 +4,8 @@
 #ifndef _INT_PET_SQL_H_
 #ifndef _INT_PET_SQL_H_
 #define _INT_PET_SQL_H_
 #define _INT_PET_SQL_H_
 
 
+struct s_pet;
+
 int inter_pet_init(void);
 int inter_pet_init(void);
 void inter_pet_sql_final(void);
 void inter_pet_sql_final(void);
 int inter_pet_save(void);
 int inter_pet_save(void);

+ 152 - 206
src/char_sql/int_storage.c

@@ -1,17 +1,19 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-// original code from athena
-// SQL conversion by Jioh L. Jung
+#include "../common/mmo.h"
+#include "../common/malloc.h"
+#include "../common/showmsg.h"
+#include "../common/socket.h"
+#include "../common/strlib.h" // StringBuf
+#include "../common/sql.h"
+#include "char.h"
+#include "inter.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-#include "char.h"
-#include "itemdb.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
 
 
 #define STORAGE_MEMINC	16
 #define STORAGE_MEMINC	16
 
 
@@ -19,166 +21,130 @@
 // reset by inter_config_read()
 // reset by inter_config_read()
 struct storage *storage_pt=NULL;
 struct storage *storage_pt=NULL;
 struct guild_storage *guild_storage_pt=NULL;
 struct guild_storage *guild_storage_pt=NULL;
-
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
-// storage data -> DB conversion
-int storage_tosql(int account_id,struct storage *p){
-	int i,j;
-//	int eqcount=1;
-//	int noteqcount=1;
-	int count=0;
-	struct itemtmp mapitem[MAX_STORAGE];
-	for(i=0;i<MAX_STORAGE;i++){
-		if(p->storage_[i].nameid>0){
-			mapitem[count].flag=0;
-			mapitem[count].id = p->storage_[i].id;
-			mapitem[count].nameid=p->storage_[i].nameid;
-			mapitem[count].amount = p->storage_[i].amount;
-			mapitem[count].equip = p->storage_[i].equip;
-			mapitem[count].identify = p->storage_[i].identify;
-			mapitem[count].refine = p->storage_[i].refine;
-			mapitem[count].attribute = p->storage_[i].attribute;
-			for(j=0; j<MAX_SLOTS; j++)
-				mapitem[count].card[j] = p->storage_[i].card[j];
-			count++;
-		}
-	}
 
 
-	memitemdata_to_sql(mapitem, count, account_id,TABLE_STORAGE);
-
-	//printf ("storage dump to DB - id: %d (total: %d)\n", account_id, j);
+/// Save guild_storage data to sql
+int storage_tosql(int account_id,struct storage* p)
+{
+	memitemdata_to_sql(p->storage_, MAX_STORAGE, account_id, TABLE_STORAGE);
+	//ShowInfo ("storage save to DB - account: %d\n", account_id);
 	return 0;
 	return 0;
 }
 }
-#ifndef TXT_SQL_CONVERT
 
 
-// DB -> storage data conversion
-int storage_fromsql(int account_id, struct storage *p){
-	int i=0,j;
-	char * str_p = tmp_sql;
+#ifndef TXT_SQL_CONVERT
+/// Load guild_storage data to mem
+int storage_fromsql(int account_id, struct storage* p)
+{
+	StringBuf buf;
+	struct item* item;
+	char* data;
+	int i;
+	int j;
 
 
-	memset(p,0,sizeof(struct storage)); //clean up memory
+	memset(p, 0, sizeof(struct storage)); //clean up memory
 	p->storage_amount = 0;
 	p->storage_amount = 0;
 	p->account_id = account_id;
 	p->account_id = account_id;
 
 
 	// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
 	// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
-	str_p += sprintf(str_p,"SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
-	
-	for (j=0; j<MAX_SLOTS; j++)
-		str_p += sprintf(str_p, ", `card%d`", j);
-	
-	str_p += sprintf(str_p," FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
-	
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-
-	if (sql_res) {
-		while((sql_row = mysql_fetch_row(sql_res)) && i<MAX_STORAGE) {	//start to fetch
-			p->storage_[i].id= atoi(sql_row[0]);
-			p->storage_[i].nameid= atoi(sql_row[1]);
-			p->storage_[i].amount= atoi(sql_row[2]);
-			p->storage_[i].equip= atoi(sql_row[3]);
-			p->storage_[i].identify= atoi(sql_row[4]);
-			p->storage_[i].refine= atoi(sql_row[5]);
-			p->storage_[i].attribute= atoi(sql_row[6]);
-			for (j=0; j<MAX_SLOTS; j++)
-				p->storage_[i].card[j]= atoi(sql_row[7+j]);
-			i++;
+	StringBuf_Init(&buf);
+	StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
+	for( j = 0; j < MAX_SLOTS; ++j )
+		StringBuf_Printf(&buf, ",`card%d`", j);
+	StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
+
+	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+		Sql_ShowDebug(sql_handle);
+
+	StringBuf_Destroy(&buf);
+
+	for( i = 0; i < MAX_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+	{
+		item = &p->storage_[i];
+		Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data);
+		Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data);
+		Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data);
+		Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data);
+		Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data);
+		Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
+		Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
+		for( j = 0; j < MAX_SLOTS; ++j )
+		{
+			Sql_GetData(sql_handle, 7+j, &data, NULL); item->card[j] = atoi(data);
 		}
 		}
-		p->storage_amount = i;
-		mysql_free_result(sql_res);
 	}
 	}
+	p->storage_amount = i;
+	Sql_FreeResult(sql_handle);
 
 
-	ShowInfo ("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
+	ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
 	return 1;
 	return 1;
 }
 }
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
-// Save guild_storage data to sql
-int guild_storage_tosql(int guild_id, struct guild_storage *p){
-	int i,j;
-//	int eqcount=1;
-//	int noteqcount=1;
-	int count=0;
-	struct itemtmp mapitem[MAX_GUILD_STORAGE];
-	for(i=0;i<MAX_GUILD_STORAGE;i++){
-		if(p->storage_[i].nameid>0){
-			mapitem[count].flag=0;
-			mapitem[count].id = p->storage_[i].id;
-			mapitem[count].nameid=p->storage_[i].nameid;
-			mapitem[count].amount = p->storage_[i].amount;
-			mapitem[count].equip = p->storage_[i].equip;
-			mapitem[count].identify = p->storage_[i].identify;
-			mapitem[count].refine = p->storage_[i].refine;
-			mapitem[count].attribute = p->storage_[i].attribute;
-			for (j=0; j<MAX_SLOTS; j++)
-				mapitem[count].card[j] = p->storage_[i].card[j];
-			count++;
-		}
-	}
 
 
-	memitemdata_to_sql(mapitem, count, guild_id,TABLE_GUILD_STORAGE);
-
-	ShowInfo ("guild storage save to DB - id: %d (total: %d)\n", guild_id,i);
+/// Save guild_storage data to sql
+int guild_storage_tosql(int guild_id, struct guild_storage* p)
+{
+	memitemdata_to_sql(p->storage_, MAX_GUILD_STORAGE, guild_id, TABLE_GUILD_STORAGE);
+	ShowInfo ("guild storage save to DB - guild: %d\n", guild_id);
 	return 0;
 	return 0;
 }
 }
+
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-// Load guild_storage data to mem
-int guild_storage_fromsql(int guild_id, struct guild_storage *p){
-	int i=0,j;
-	struct guild_storage *gs=guild_storage_pt;
-	char * str_p = tmp_sql;
-	p=gs;
-
-	memset(p,0,sizeof(struct guild_storage)); //clean up memory
+/// Load guild_storage data to mem
+int guild_storage_fromsql(int guild_id, struct guild_storage* p)
+{
+	StringBuf buf;
+	struct item* item;
+	char* data;
+	int i;
+	int j;
+
+	memset(p, 0, sizeof(struct guild_storage)); //clean up memory
 	p->storage_amount = 0;
 	p->storage_amount = 0;
 	p->guild_id = guild_id;
 	p->guild_id = guild_id;
 
 
 	// storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
 	// storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
-	str_p += sprintf(str_p,"SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
-
-	for (j=0; j<MAX_SLOTS; j++)
-		str_p += sprintf(str_p, ", `card%d`",  j);
-	
-	str_p += sprintf(str_p," FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
-	
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-
-	if (sql_res) {
-		while((sql_row = mysql_fetch_row(sql_res)) && i < MAX_GUILD_STORAGE) {	//start to fetch
-			p->storage_[i].id= atoi(sql_row[0]);
-			p->storage_[i].nameid= atoi(sql_row[1]);
-			p->storage_[i].amount= atoi(sql_row[2]);
-			p->storage_[i].equip= atoi(sql_row[3]);
-			p->storage_[i].identify= atoi(sql_row[4]);
-			p->storage_[i].refine= atoi(sql_row[5]);
-			p->storage_[i].attribute= atoi(sql_row[6]);
-			for (j=0; j<MAX_SLOTS; j++)
-				p->storage_[i].card[j] = atoi(sql_row[7+j]);
-			i++;
+	StringBuf_Init(&buf);
+	StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`");
+	for( j = 0; j < MAX_SLOTS; ++j )
+		StringBuf_Printf(&buf, ",`card%d`", j);
+	StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
+
+	if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
+		Sql_ShowDebug(sql_handle);
+
+	StringBuf_Destroy(&buf);
+
+	for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+	{
+		item = &p->storage_[i];
+		Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data);
+		Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data);
+		Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data);
+		Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data);
+		Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data);
+		Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data);
+		Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
+		for( j = 0; j < MAX_SLOTS; ++j )
+		{
+			Sql_GetData(sql_handle, 7+j, &data, NULL); item->card[j] = atoi(data);
 		}
 		}
-		p->storage_amount = i;
-		mysql_free_result(sql_res);
 	}
 	}
-	ShowInfo ("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount);
+	p->storage_amount = i;
+	Sql_FreeResult(sql_handle);
+
+	ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount);
 	return 0;
 	return 0;
 }
 }
 
 
 //---------------------------------------------------------
 //---------------------------------------------------------
 // storage data initialize
 // storage data initialize
-int inter_storage_sql_init(void){
+int inter_storage_sql_init(void)
+{
 
 
 	//memory alloc
 	//memory alloc
 	ShowDebug("interserver storage memory initialize....(%d byte)\n",sizeof(struct storage));
 	ShowDebug("interserver storage memory initialize....(%d byte)\n",sizeof(struct storage));
 	storage_pt = (struct storage*)aCalloc(sizeof(struct storage), 1);
 	storage_pt = (struct storage*)aCalloc(sizeof(struct storage), 1);
 	guild_storage_pt = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
 	guild_storage_pt = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
-//	memset(storage_pt,0,sizeof(struct storage)); //Calloc sets stuff to 0 already. [Skotlex]
-//	memset(guild_storage_pt,0,sizeof(struct guild_storage));
 
 
 	return 1;
 	return 1;
 }
 }
@@ -192,20 +158,14 @@ void inter_storage_sql_final(void)
 // q?f[^?
 // q?f[^?
 int inter_storage_delete(int account_id)
 int inter_storage_delete(int account_id)
 {
 {
-		sprintf(tmp_sql, "DELETE FROM `%s` WHERE `account_id`='%d'",storage_db, account_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", storage_db, account_id) )
+		Sql_ShowDebug(sql_handle);
 	return 0;
 	return 0;
 }
 }
 int inter_guild_storage_delete(int guild_id)
 int inter_guild_storage_delete(int guild_id)
 {
 {
-	sprintf(tmp_sql, "DELETE FROM `%s` WHERE `guild_id`='%d'",guild_storage_db, guild_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", guild_storage_db, guild_id) )
+		Sql_ShowDebug(sql_handle);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -213,7 +173,8 @@ int inter_guild_storage_delete(int guild_id)
 // packet from map server
 // packet from map server
 
 
 // recive packet about storage data
 // recive packet about storage data
-int mapif_load_storage(int fd,int account_id){
+int mapif_load_storage(int fd,int account_id)
+{
 	//load from DB
 	//load from DB
 	WFIFOHEAD(fd, sizeof(struct storage)+8);
 	WFIFOHEAD(fd, sizeof(struct storage)+8);
 	storage_fromsql(account_id, storage_pt);
 	storage_fromsql(account_id, storage_pt);
@@ -225,7 +186,8 @@ int mapif_load_storage(int fd,int account_id){
 	return 0;
 	return 0;
 }
 }
 // send ack to map server which is "storage data save ok."
 // send ack to map server which is "storage data save ok."
-int mapif_save_storage_ack(int fd,int account_id){
+int mapif_save_storage_ack(int fd,int account_id)
+{
 	WFIFOHEAD(fd, 7);
 	WFIFOHEAD(fd, 7);
 	WFIFOW(fd,0)=0x3811;
 	WFIFOW(fd,0)=0x3811;
 	WFIFOL(fd,2)=account_id;
 	WFIFOL(fd,2)=account_id;
@@ -236,40 +198,29 @@ int mapif_save_storage_ack(int fd,int account_id){
 
 
 int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 {
 {
-	int guild_exist=1;
-	WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
-	WFIFOW(fd,0)=0x3818;
-
-#if 0	// innodb guilds should render this check unnecessary [Aru]
-	// Check if guild exists, I may write a function for this later, coz I use it several times.
-	//printf("- Check if guild %d exists\n",g->guild_id);
-	sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id`='%d'",guild_db, guild_id);
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle) ;
-	if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-		sql_row = mysql_fetch_row(sql_res);
-		guild_exist =  atoi (sql_row[0]);
-		//printf("- Check if guild %d exists : %s\n",g->guild_id,((guild_exist==0)?"No":"Yes"));
-	}
-	mysql_free_result(sql_res) ; //resource free
-#endif
-	if(guild_exist==1) {
-		guild_storage_fromsql(guild_id,guild_storage_pt);
-		WFIFOW(fd,2)=sizeof(struct guild_storage)+12;
-		WFIFOL(fd,4)=account_id;
-		WFIFOL(fd,8)=guild_id;
-		memcpy(WFIFOP(fd,12),guild_storage_pt,sizeof(struct guild_storage));
-	}
-	else {
-		WFIFOW(fd,2)=12;
-		WFIFOL(fd,4)=account_id;
-		WFIFOL(fd,8)=0;
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
+		Sql_ShowDebug(sql_handle);
+	else if( Sql_NumRows(sql_handle) > 0 )
+	{// guild exists
+		guild_storage_fromsql(guild_id, guild_storage_pt);
+
+		WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
+		WFIFOW(fd,0) = 0x3818;
+		WFIFOW(fd,2) = sizeof(struct guild_storage)+12;
+		WFIFOL(fd,4) = account_id;
+		WFIFOL(fd,8) = guild_id;
+		memcpy(WFIFOP(fd,12), guild_storage_pt, sizeof(struct guild_storage));
+		WFIFOSET(fd, WFIFOW(fd,2));
+		return 0;
 	}
 	}
-	WFIFOSET(fd,WFIFOW(fd,2));
-
+	// guild does not exist
+	Sql_FreeResult(sql_handle);
+	WFIFOHEAD(fd, 12);
+	WFIFOW(fd,0) = 0x3818;
+	WFIFOW(fd,2) = 12;
+	WFIFOL(fd,4) = account_id;
+	WFIFOL(fd,8) = 0;
+	WFIFOSET(fd, 12);
 	return 0;
 	return 0;
 }
 }
 int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
@@ -287,13 +238,15 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 // packet from map server
 // packet from map server
 
 
 // recive request about storage data
 // recive request about storage data
-int mapif_parse_LoadStorage(int fd){
+int mapif_parse_LoadStorage(int fd)
+{
 	RFIFOHEAD(fd);
 	RFIFOHEAD(fd);
 	mapif_load_storage(fd,RFIFOL(fd,2));
 	mapif_load_storage(fd,RFIFOL(fd,2));
 	return 0;
 	return 0;
 }
 }
 // storage data recive and save
 // storage data recive and save
-int mapif_parse_SaveStorage(int fd){
+int mapif_parse_SaveStorage(int fd)
+{
 	int account_id;
 	int account_id;
 	int len;
 	int len;
 	RFIFOHEAD(fd);
 	RFIFOHEAD(fd);
@@ -318,45 +271,38 @@ int mapif_parse_LoadGuildStorage(int fd)
 
 
 int mapif_parse_SaveGuildStorage(int fd)
 int mapif_parse_SaveGuildStorage(int fd)
 {
 {
-	int guild_exist=1;
 	int guild_id;
 	int guild_id;
 	int len;
 	int len;
+
 	RFIFOHEAD(fd);
 	RFIFOHEAD(fd);
-	guild_id=RFIFOL(fd,8);
-	len=RFIFOW(fd,2);
-	if(sizeof(struct guild_storage)!=len-12){
-		ShowError("inter storage: data size error %d %d\n",sizeof(struct guild_storage),len-12);
+	guild_id = RFIFOL(fd,8);
+	len = RFIFOW(fd,2);
+
+	if( sizeof(struct guild_storage) != len - 12 )
+	{
+		ShowError("inter storage: data size error %d != %d\n", sizeof(struct guild_storage), len - 12);
 	}
 	}
-	else {
-#if 0	// Again, innodb key checks make the check pointless
-		// Check if guild exists, I may write a function for this later, coz I use it several times.
-		//printf("- Check if guild %d exists\n",g->guild_id);
-		sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `guild_id`='%d'",guild_db, guild_id);
-		if(mysql_query(&mysql_handle, tmp_sql) ) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-		sql_res = mysql_store_result(&mysql_handle) ;
-		if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
-			sql_row = mysql_fetch_row(sql_res);
-			guild_exist =  atoi (sql_row[0]);
-			//printf("- Check if guild %d exists : %s\n",g->guild_id,((guild_exist==0)?"No":"Yes"));
+	else
+	{
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
+			Sql_ShowDebug(sql_handle);
+		else if( Sql_NumRows(sql_handle) > 0 )
+		{// guild exists
+			Sql_FreeResult(sql_handle);
+			memcpy(guild_storage_pt, RFIFOP(fd,12), sizeof(struct guild_storage));
+			guild_storage_tosql(guild_id, guild_storage_pt);
+			mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 0);
+			return 0;
 		}
 		}
-		mysql_free_result(sql_res) ; //resource free
-#endif
-		if(guild_exist==1) {
-			memcpy(guild_storage_pt,RFIFOP(fd,12),sizeof(struct guild_storage));
-			guild_storage_tosql(guild_id,guild_storage_pt);
-			mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,0);
-		}
-		else
-			mapif_save_guild_storage_ack(fd,RFIFOL(fd,4),guild_id,1);
+		Sql_FreeResult(sql_handle);
 	}
 	}
+	mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1);
 	return 0;
 	return 0;
 }
 }
 
 
 
 
-int inter_storage_parse_frommap(int fd){
+int inter_storage_parse_frommap(int fd)
+{
 	RFIFOHEAD(fd);
 	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
 	switch(RFIFOW(fd,0)){
 	case 0x3010: mapif_parse_LoadStorage(fd); break;
 	case 0x3010: mapif_parse_LoadStorage(fd); break;

+ 3 - 0
src/char_sql/int_storage.h

@@ -4,6 +4,9 @@
 #ifndef _INT_STORAGE_SQL_H_
 #ifndef _INT_STORAGE_SQL_H_
 #define _INT_STORAGE_SQL_H_
 #define _INT_STORAGE_SQL_H_
 
 
+struct storage;
+struct guild_storage;
+
 int inter_storage_sql_init(void);
 int inter_storage_sql_init(void);
 void inter_storage_sql_final(void);
 void inter_storage_sql_final(void);
 int inter_storage_delete(int account_id);
 int inter_storage_delete(int account_id);

+ 163 - 158
src/char_sql/inter.c

@@ -1,34 +1,31 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "char.h"
+#include "../common/mmo.h"
+#include "../common/db.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "char.h"
 #include "inter.h"
 #include "inter.h"
 #include "int_party.h"
 #include "int_party.h"
 #include "int_guild.h"
 #include "int_guild.h"
 #include "int_storage.h"
 #include "int_storage.h"
 #include "int_pet.h"
 #include "int_pet.h"
-#include "int_homun.h" //albator
+#include "int_homun.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 
 
 #define WISDATA_TTL (60*1000)	// Wisデータの生存時間(60秒)
 #define WISDATA_TTL (60*1000)	// Wisデータの生存時間(60秒)
 #define WISDELLIST_MAX 256			// Wisデータ削除リストの要素数
 #define WISDELLIST_MAX 256			// Wisデータ削除リストの要素数
 
 
 
 
-MYSQL mysql_handle;
-MYSQL_RES* 	sql_res ;
-MYSQL_ROW	sql_row ;
-int sql_fields, sql_cnt;
-char tmp_sql[65535];
-
-MYSQL lmysql_handle;
-MYSQL_RES* 	lsql_res ;
-MYSQL_ROW	lsql_row ;
+Sql* sql_handle = NULL;
+Sql* lsql_handle = NULL;
 
 
 int char_server_port = 3306;
 int char_server_port = 3306;
 char char_server_ip[32] = "127.0.0.1";
 char char_server_ip[32] = "127.0.0.1";
@@ -89,50 +86,59 @@ int inter_sql_test (void);
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
 //--------------------------------------------------------
 //--------------------------------------------------------
 // Save registry to sql
 // Save registry to sql
-int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type){
+int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type)
+{
+	struct global_reg* r;
+	SqlStmt* stmt;
+	int i;
 
 
-	int j;
-	char temp_str[64]; //Needs be twice the source to ensure it fits [Skotlex]
-	char temp_str2[512];
-	if (account_id<=0) return 0;
-	reg->account_id=account_id;
+	if( account_id <= 0 )
+		return 0;
+	reg->account_id = account_id;
 	reg->char_id = char_id;
 	reg->char_id = char_id;
 
 
-	switch (type) {
-		case 3: //Char Reg
-		//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
-			sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, char_id);
-			break;
-		case 2: //Account Reg
-		//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
-			sprintf(tmp_sql,"DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'",reg_db, account_id);
-			break;
-		case 1: //Account2 Reg
-			ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
-			return 0;
-		default:
-			ShowError("inter_accreg_tosql: Invalid type %d\n", type);
-			return 0;
-			
-	}	
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
+	switch( type )
+	{
+	case 3: //Char Reg
+		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+			Sql_ShowDebug(sql_handle);
+		account_id = 0;
+		break;
+	case 2: //Account Reg
+		if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
+			Sql_ShowDebug(sql_handle);
+		char_id = 0;
+		break;
+	case 1: //Account2 Reg
+		ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
+		return 0;
+	default:
+		ShowError("inter_accreg_tosql: Invalid type %d\n", type);
+		return 0;
 	}
 	}
 
 
-	if (reg->reg_num<=0) return 0;
-
-	for(j=0;j<reg->reg_num;j++){
-		if(reg->reg[j].str != NULL){
-			sprintf(tmp_sql,"INSERT INTO `%s` (`type`, `account_id`, `char_id`, `str`, `value`) VALUES ('%d','%d','%d','%s','%s')",
-				reg_db, type, type!=3?reg->account_id:0, type==3?reg->char_id:0,
-				jstrescapecpy(temp_str,reg->reg[j].str), jstrescapecpy(temp_str2,reg->reg[j].value));
-			if(mysql_query(&mysql_handle, tmp_sql) ) {
-				ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+	if( reg->reg_num <= 0 )
+		return 0;
+
+	stmt = SqlStmt_Malloc(sql_handle);
+	if( SQL_ERROR == SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `char_id`, `str`, `value`) VALUES ('%d','%d','%d',?,?)", reg_db, type, account_id, char_id) )
+		SqlStmt_ShowDebug(stmt);
+	for( i = 0; i < reg->reg_num; ++i )
+	{
+		r = &reg->reg[i];
+		if( r->str[0] != '\0' && r->value != '\0' )
+		{
+			// str
+			SqlStmt_BindParam(stmt, 0, SQLDT_STRING, r->str, strnlen(r->str, sizeof(r->str)));
+			// value
+			SqlStmt_BindParam(stmt, 1, SQLDT_STRING, r->value, strnlen(r->value, sizeof(r->value)));
+
+			if( SQL_ERROR == SqlStmt_Execute(stmt) )
+				SqlStmt_ShowDebug(stmt);
 		}
 		}
 	}
 	}
+	SqlStmt_Free(stmt);
 	return 1;
 	return 1;
 }
 }
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
@@ -140,38 +146,48 @@ int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type
 // Load account_reg from sql (type=2)
 // Load account_reg from sql (type=2)
 int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type)
 int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type)
 {
 {
-	int j=0;
-	if (reg==NULL) return 0;
+	struct global_reg* r;
+	char* data;
+	size_t len;
+	int i;
+
+	if( reg == NULL)
+		return 0;
+
 	memset(reg, 0, sizeof(struct accreg));
 	memset(reg, 0, sizeof(struct accreg));
-	reg->account_id=account_id;
-	reg->char_id=char_id;
+	reg->account_id = account_id;
+	reg->char_id = char_id;
 
 
 	//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
 	//`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`)
-	switch (type) {
+	switch( type )
+	{
 	case 3: //char reg
 	case 3: //char reg
-		sprintf (tmp_sql, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'",reg_db, reg->char_id);
-	break;
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) )
+			Sql_ShowDebug(sql_handle);
+		break;
 	case 2: //account reg
 	case 2: //account reg
-		sprintf (tmp_sql, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'",reg_db, reg->account_id);
-	break;
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) )
+			Sql_ShowDebug(sql_handle);
+		break;
 	case 1: //account2 reg
 	case 1: //account2 reg
 		ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
 		ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
 		return 0;
 		return 0;
+	default:
+		ShowError("inter_accreg_fromsql: Invalid type %d\n", type);
+		return 0;
 	}
 	}
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle);
-
-	if (sql_res) {
-		for(j=0;(sql_row = mysql_fetch_row(sql_res));j++){
-			strcpy(reg->reg[j].str, sql_row[0]);
-			strcpy(reg->reg[j].value, sql_row[1]);
-		}
-		mysql_free_result(sql_res);
+	for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+	{
+		r = &reg->reg[i];
+		// str
+		Sql_GetData(sql_handle, 0, &data, &len);
+		memcpy(r->str, data, min(len, sizeof(r->str)));
+		// value
+		Sql_GetData(sql_handle, 1, &data, &len);
+		memcpy(r->value, data, min(len, sizeof(r->value)));
 	}
 	}
-	reg->reg_num=j;
+	reg->reg_num = i;
+	Sql_FreeResult(sql_handle);
 	return 1;
 	return 1;
 }
 }
 
 
@@ -277,18 +293,17 @@ static int inter_config_read(const char* cfgName)
 int inter_log(char* fmt, ...)
 int inter_log(char* fmt, ...)
 {
 {
 	char str[255];
 	char str[255];
-	char temp_str[510]; //Needs be twice as long as str[] //Skotlex
+	char esc_str[sizeof(str)*2+1];// escaped str
 	va_list ap;
 	va_list ap;
+
 	va_start(ap,fmt);
 	va_start(ap,fmt);
+	vsnprintf(str, sizeof(str), fmt, ap);
+	va_end(ap);
 
 
-	vsprintf(str,fmt,ap);
-	sprintf(tmp_sql,"INSERT INTO `%s` (`time`, `log`) VALUES (NOW(),  '%s')",interlog_db, jstrescapecpy(temp_str,str));
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	Sql_EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str)));
+	if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(),  '%s')", interlog_db, esc_str) )
+		Sql_ShowDebug(sql_handle);
 
 
-	va_end(ap);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -298,30 +313,23 @@ int inter_log(char* fmt, ...)
 int inter_sql_ping(int tid, unsigned int tick, int id, int data) 
 int inter_sql_ping(int tid, unsigned int tick, int id, int data) 
 {
 {
 	ShowInfo("Pinging SQL server to keep connection alive...\n");
 	ShowInfo("Pinging SQL server to keep connection alive...\n");
-	mysql_ping(&mysql_handle);
-	if(char_gm_read)
-		mysql_ping(&lmysql_handle);
+	Sql_Ping(sql_handle);
+	if( char_gm_read )
+		Sql_Ping(lsql_handle);
 	return 0;
 	return 0;
 }
 }
 
 
 
 
 int sql_ping_init(void)
 int sql_ping_init(void)
 {
 {
-	int connection_timeout, connection_ping_interval;
+	uint32 connection_timeout, connection_ping_interval;
 
 
 	// set a default value first
 	// set a default value first
 	connection_timeout = 28800; // 8 hours
 	connection_timeout = 28800; // 8 hours
 
 
 	// ask the mysql server for the timeout value
 	// ask the mysql server for the timeout value
-	if (!mysql_query(&mysql_handle, "SHOW VARIABLES LIKE 'wait_timeout'")
-	&& (sql_res = mysql_store_result(&mysql_handle)) != NULL) {
-		sql_row = mysql_fetch_row(sql_res);
-		if (sql_row)
-			connection_timeout = atoi(sql_row[1]);
-		if (connection_timeout < 60)
-			connection_timeout = 60;
-		mysql_free_result(sql_res);
-	}
+	if( SQL_SUCCESS == Sql_GetTimeout(sql_handle, &connection_timeout) && connection_timeout < 60 )
+		connection_timeout = 60;
 
 
 	// establish keepalive
 	// establish keepalive
 	connection_ping_interval = connection_timeout - 30; // 30-second reserve
 	connection_ping_interval = connection_timeout - 30; // 30-second reserve
@@ -342,13 +350,13 @@ int inter_init_sql(const char *file)
 	inter_config_read(file);
 	inter_config_read(file);
 
 
 	//DB connection initialized
 	//DB connection initialized
-	mysql_init(&mysql_handle);
+	sql_handle = Sql_Malloc();
 	ShowInfo("Connect Character DB server.... (Character Server)\n");
 	ShowInfo("Connect Character DB server.... (Character Server)\n");
-	if(!mysql_real_connect(&mysql_handle, char_server_ip, char_server_id, char_server_pw,
-		char_server_db ,char_server_port, (char *)NULL, 0)) {
-			//pointer check
-			ShowFatalError("%s\n",mysql_error(&mysql_handle));
-			exit(1);
+	if( SQL_ERROR == Sql_Connect(sql_handle, char_server_id, char_server_pw, char_server_ip, (uint16)char_server_port, char_server_db) )
+	{
+		Sql_ShowDebug(sql_handle);
+		Sql_Free(sql_handle);
+		exit(1);
 	}
 	}
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
 	else if (inter_sql_test()) {
 	else if (inter_sql_test()) {
@@ -356,30 +364,27 @@ int inter_init_sql(const char *file)
 	}
 	}
 
 
 	if(char_gm_read) {
 	if(char_gm_read) {
-		mysql_init(&lmysql_handle);
+		lsql_handle = Sql_Malloc();
 		ShowInfo("Connect Character DB server.... (login server)\n");
 		ShowInfo("Connect Character DB server.... (login server)\n");
-		if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw,
-			login_server_db ,login_server_port, (char *)NULL, 0)) {
-				//pointer check
-				ShowFatalError("%s\n",mysql_error(&lmysql_handle));
-				exit(1);
-		}else {
+		if( SQL_ERROR == Sql_Connect(lsql_handle, login_server_id, login_server_pw, login_server_ip, (uint16)login_server_port, login_server_db) )
+		{
+			Sql_ShowDebug(lsql_handle);
+			Sql_Free(lsql_handle);
+			Sql_Free(sql_handle);
+			exit(1);
+		}
+		else
+		{
 			ShowStatus ("Connect Success! (Login Server)\n");
 			ShowStatus ("Connect Success! (Login Server)\n");
 		}
 		}
 	}
 	}
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
-	if(strlen(default_codepage) > 0 ) {
-		sprintf( tmp_sql, "SET NAMES %s", default_codepage );
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if( *default_codepage ) {
+		if( SQL_ERROR == Sql_SetEncoding(sql_handle, default_codepage) )
+			Sql_ShowDebug(sql_handle);
 #ifndef TXT_SQL_CONVERT
 #ifndef TXT_SQL_CONVERT
-		if(char_gm_read)
-			if (mysql_query(&lmysql_handle, tmp_sql)) {
-				ShowSQL("DB error - %s\n",mysql_error(&lmysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+		if( char_gm_read && SQL_ERROR == Sql_SetEncoding(lsql_handle, default_codepage) )
+			Sql_ShowDebug(lsql_handle);
 #endif //TXT_SQL_CONVERT
 #endif //TXT_SQL_CONVERT
 	}
 	}
 
 
@@ -405,32 +410,30 @@ int inter_sql_test (void)
 		"fame",		// version 1491
 		"fame",		// version 1491
 	};	
 	};	
 	char buf[1024] = "";
 	char buf[1024] = "";
+	char* p;
+	size_t len;
 	int i;
 	int i;
 
 
-	sprintf(tmp_sql, "EXPLAIN `%s`",char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle);
-	// store DB fields
-	if (sql_res) {
-		while((sql_row = mysql_fetch_row(sql_res))) {
-			strcat (buf, sql_row[0]);
-			strcat (buf, " ");
-		}
-	}
+	if( SQL_ERROR == Sql_GetColumnNames(sql_handle, char_db, buf, sizeof(buf), '\n') )
+		Sql_ShowDebug(sql_handle);
 
 
 	// check DB strings
 	// check DB strings
-	for (i = 0; i < (int)(sizeof(fields) / sizeof(fields[0])); i++) {
-		if(!strstr(buf, fields[i])) {
+	for( i = 0; i < ARRAYLENGTH(fields); ++i )
+	{
+		len = strlen(fields[i]);
+		p = strstr(buf, fields[i]);
+		while( p != NULL && p[len] != '\n' )
+			p = strstr(p, fields[i]);
+		if( p == NULL )
+		{
 			ShowSQL ("Field `%s` not be found in `%s`. Consider updating your database!\n", fields[i], char_db);
 			ShowSQL ("Field `%s` not be found in `%s`. Consider updating your database!\n", fields[i], char_db);
+			if( lsql_handle )
+				Sql_Free(lsql_handle);
+			Sql_Free(sql_handle);
 			exit(1);
 			exit(1);
 		}
 		}
 	}
 	}
 
 
-	mysql_free_result(sql_res);
-
 	return 1;
 	return 1;
 }
 }
 
 
@@ -636,7 +639,11 @@ int mapif_parse_WisRequest(int fd)
 {
 {
 	struct WisData* wd;
 	struct WisData* wd;
 	static int wisid = 0;
 	static int wisid = 0;
-	char name[NAME_LENGTH], t_name[NAME_LENGTH*2]; //Needs space to allocate names with escaped chars [Skotlex]
+	char name[NAME_LENGTH];
+	char esc_name[NAME_LENGTH*2+1];// escaped name
+	char* data;
+	size_t len;
+
 
 
 	if ( fd <= 0 ) {return 0;} // check if we have a valid fd
 	if ( fd <= 0 ) {return 0;} // check if we have a valid fd
 
 
@@ -649,35 +656,37 @@ int mapif_parse_WisRequest(int fd)
 	}
 	}
 	memcpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
 	memcpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
 	name[NAME_LENGTH-1]= '\0';
 	name[NAME_LENGTH-1]= '\0';
-	
-	sprintf (tmp_sql, "SELECT `name` FROM `%s` WHERE `name`='%s'",
-		char_db, jstrescapecpy(t_name, name));
-	if(mysql_query(&mysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
-	sql_res = mysql_store_result(&mysql_handle);
+
+	Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
+	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) )
+		Sql_ShowDebug(sql_handle);
 
 
 	// search if character exists before to ask all map-servers
 	// search if character exists before to ask all map-servers
-	if (!(sql_row = mysql_fetch_row(sql_res))) {
+	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+	{
 		unsigned char buf[27];
 		unsigned char buf[27];
 		WBUFW(buf, 0) = 0x3802;
 		WBUFW(buf, 0) = 0x3802;
 		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
 		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
 		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 		mapif_send(fd, buf, 27);
 		mapif_send(fd, buf, 27);
-	// Character exists. So, ask all map-servers
-	} else {
+	}
+	else
+	{// Character exists. So, ask all map-servers
 		// to be sure of the correct name, rewrite it
 		// to be sure of the correct name, rewrite it
+		Sql_GetData(sql_handle, 0, &data, &len);
 		memset(name, 0, NAME_LENGTH);
 		memset(name, 0, NAME_LENGTH);
-		strncpy(name, sql_row[0], NAME_LENGTH);
+		memcpy(name, data, min(len, NAME_LENGTH));
 		// if source is destination, don't ask other servers.
 		// if source is destination, don't ask other servers.
-		if (strcmp((char*)RFIFOP(fd,4),name) == 0) {
-			unsigned char buf[27];
+		if( strncmp((const char*)RFIFOP(fd,4), name, NAME_LENGTH) == 0 )
+		{
+			uint8 buf[27];
 			WBUFW(buf, 0) = 0x3802;
 			WBUFW(buf, 0) = 0x3802;
 			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
 			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
 			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 			mapif_send(fd, buf, 27);
 			mapif_send(fd, buf, 27);
-		} else {
+		}
+		else
+		{
 
 
 			CREATE(wd, struct WisData, 1);
 			CREATE(wd, struct WisData, 1);
 
 
@@ -695,12 +704,8 @@ int mapif_parse_WisRequest(int fd)
 			mapif_wis_message(wd);
 			mapif_wis_message(wd);
 		}
 		}
 	}
 	}
-	
-	//Freeing ... O.o 
-	if(sql_res){
-		mysql_free_result(sql_res);
-	}
-	
+
+	Sql_FreeResult(sql_handle);
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 18
src/char_sql/inter.h

@@ -4,9 +4,8 @@
 #ifndef _INTER_SQL_H_
 #ifndef _INTER_SQL_H_
 #define _INTER_SQL_H_
 #define _INTER_SQL_H_
 
 
-#ifndef _CBASETYPES_H_
-#include "../common/cbasetypes.h"
-#endif
+struct accreg;
+#include "../common/sql.h"
 
 
 int inter_init_sql(const char *file);
 int inter_init_sql(const char *file);
 void inter_final(void);
 void inter_final(void);
@@ -25,21 +24,8 @@ int inter_log(char *fmt,...);
 extern unsigned int party_share_level;
 extern unsigned int party_share_level;
 extern char inter_log_filename[1024];
 extern char inter_log_filename[1024];
 
 
-#ifdef WIN32
-#include <winsock2.h>
-#endif
-//add include for DBMS(mysql)
-#include <mysql.h>
-
-extern MYSQL mysql_handle;
-extern char tmp_sql[65535];
-extern MYSQL_RES* 	sql_res ;
-extern MYSQL_ROW	sql_row ;
-extern int 	sql_cnt;
-
-extern MYSQL lmysql_handle;
-extern MYSQL_RES* 	lsql_res ;
-extern MYSQL_ROW	lsql_row ;
+extern Sql* sql_handle;
+extern Sql* lsql_handle;
 
 
 extern int char_server_port;
 extern int char_server_port;
 extern char char_server_ip[32];
 extern char char_server_ip[32];

+ 0 - 219
src/char_sql/itemdb.c

@@ -1,219 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "itemdb.h"
-#include "db.h"
-#include "inter.h"
-#include "char.h"
-#include "utils.h"
-#include "../common/malloc.h"
-#include "../common/showmsg.h"
-
-#define MAX_RANDITEM	2000
-
-// ** ITEMDB_OVERRIDE_NAME_VERBOSE **
-//   定義すると、itemdb.txtとgrfで名前が異なる場合、表示します.
-//#define ITEMDB_OVERRIDE_NAME_VERBOSE	1
-
-char item_db_db[256]="item_db"; // added to specify item_db sql table [Valaris]
-char item_db2_db[256]="item_db2";
-
-static struct dbt* item_db;
-
-static void* create_item(DBKey key, va_list args) {
-	struct item_data *id;
-	int nameid = key.i;
-	CREATE(id, struct item_data, 1);
-	id->nameid = nameid;
-	id->type = IT_ETC;
-	return id;
-}
-/*==========================================
- * DBの検索
- *------------------------------------------*/
-struct item_data* itemdb_search(int nameid)
-{
-	return idb_ensure(item_db,nameid,create_item);
-}
-
-/*==========================================
- *
- *------------------------------------------*/
-int itemdb_isequip(int nameid)
-{
-	int type=itemdb_type(nameid);
-	if(type==IT_HEALING || type==IT_USABLE || type==IT_ETC || type==IT_CARD || type==IT_AMMO)
-		return 0;
-	return 1;
-}
-/*==========================================
- *
- *------------------------------------------*/
-int itemdb_isequip2(struct item_data *data)
-{
-	if(data) {
-		int type=data->type;
-		if(type==IT_HEALING || type==IT_USABLE || type==IT_ETC || type==IT_CARD || type==IT_AMMO)
-			return 0;
-		else
-			return 1;
-	}
-	return 0;
-}
-
-
-
-/*==========================================
- * アイテムデータベースの読み込み
- *------------------------------------------*/
-static int itemdb_readdb(void)
-{
-	FILE *fp;
-	char line[1024];
-	int ln=0,lines=0;
-	int nameid,j;
-	char *str[32],*p,*np;
-	struct item_data *id;
-	int i=0;
-	char *filename[]={ "item_db.txt","item_db2.txt" };
-
-	for(i=0;i<2;i++){
-		sprintf(line, "%s/%s", db_path, filename[i]);
-		fp=fopen(line,"r");
-		if(fp==NULL){
-			if(i>0)
-				continue;
-			ShowFatalError("can't read %s\n",line);
-			exit(1);
-		}
-
-		lines=0;
-		while(fgets(line, sizeof(line), fp))
-		{
-			lines++;
-			if(line[0]=='/' && line[1]=='/')
-				continue;
-			memset(str,0,sizeof(str));
-			for(j=0,np=p=line;j<4 && p;j++){
-				str[j]=p;
-				p=strchr(p,',');
-				if(p){ *p++=0; np=p; }
-			}
-			if(str[0]==NULL)
-				continue;
-
-			nameid=atoi(str[0]);
-			if(nameid<=0)
-				continue;
-			if (j < 4)
-			{	//Crash-fix on broken item lines. [Skotlex]
-				ShowWarning("Reading %s: Insufficient fields for item with id %d, skipping.\n", filename[i], nameid);
-				continue;
-			}
-			ln++;
-
-			//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
-			id=itemdb_search(nameid);
-			strncpy(id->name, str[1], ITEM_NAME_LENGTH-1);
-			strncpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
-			id->type=atoi(str[3]);
-			if (id->type == IT_DELAYCONSUME)
-				id->type = IT_USABLE;
-		}
-		fclose(fp);
-		if (ln > 0) {
-			ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]);
-		}
-		ln=0;	// reset to 0
-	}
-	return 0;
-}
-
-static int itemdb_read_sqldb(void) // sql item_db read, shortened version of map-server item_db read [Valaris]
-{
-	unsigned short nameid;
-	struct item_data *id;
-	char *item_db_name[] = { item_db_db, item_db2_db };
-	long unsigned int ln = 0;
-	int i;	
-
-	// ----------
-
-	for (i = 0; i < 2; i++) {
-		sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_name[i]);
-
-		// Execute the query; if the query execution succeeded...
-		if (mysql_query(&mysql_handle, tmp_sql) == 0) {
-			sql_res = mysql_store_result(&mysql_handle);
-
-			// If the storage of the query result succeeded...
-			if (sql_res) {
-				// Parse each row in the query result into sql_row
-				while ((sql_row = mysql_fetch_row(sql_res)))
-				{	/*Table structure is:
-					00  id
-					01  name_english
-					02  name_japanese
-					03  type
-					...
-					*/
-					nameid = atoi(sql_row[0]);
-
-					// If the identifier is not within the valid range, process the next row
-					if (nameid == 0)
-						continue;
-
-					ln++;
-
-					// ----------
-         		id=itemdb_search(nameid);
-					
-					strncpy(id->name, sql_row[1], ITEM_NAME_LENGTH-1);
-					strncpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1);
-
-					id->type = atoi(sql_row[3]);
-					if (id->type == IT_DELAYCONSUME)
-						id->type = IT_USABLE;
-				}
-				ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, item_db_name[i]);
-				ln = 0;
-			} else {
-				ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
-
-			// Free the query result
-			mysql_free_result(sql_res);
-		} else {
-			ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-	}
-
-	return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------*/
-void do_final_itemdb(void)
-{
-	if(item_db){
-		item_db->destroy(item_db,NULL);
-		item_db=NULL;
-	}
-}
-int do_init_itemdb(void)
-{
-	item_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
-
-	if (db_use_sqldbs) // it db_use_sqldbs in inter config are yes, will read from item_db for char server display [Valaris]
-		itemdb_read_sqldb();
-	else
-		itemdb_readdb();
-	return 0;
-}

+ 0 - 44
src/char_sql/itemdb.h

@@ -1,44 +0,0 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef _ITEMDB_H_
-#define _ITEMDB_H_
-
-#include "mmo.h"
-
-//FIXME: Maybe it would be better to move this enum to mmo.h,
-//instead of having it twice on the map server and here? [Skotlex]
-enum {
-	IT_HEALING = 0,
-	IT_UNKNOWN, //1
-	IT_USABLE,  //2
-	IT_ETC,     //3
-	IT_WEAPON,  //4
-	IT_ARMOR,   //5
-	IT_CARD,    //6
-	IT_PETEGG,  //7
-	IT_PETARMOR,//8
-	IT_UNKNOWN2,//9
-	IT_AMMO,    //10
-	IT_DELAYCONSUME,//11
-	IT_MAX 
-} item_types;
-
-struct item_data {
-	int nameid;
-	char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
-	int type;
-};
-
-extern char item_db_db[256];
-extern char item_db2_db[256];
-struct item_data* itemdb_search(int nameid);
-#define itemdb_type(n) itemdb_search(n)->type
-
-int itemdb_isequip(int);
-int itemdb_isequip2(struct item_data *);
-
-void do_final_itemdb(void);
-int do_init_itemdb(void);
-
-#endif /* _ITEMDB_H_ */

+ 53 - 14
src/common/Makefile → src/common/Makefile.in

@@ -1,24 +1,62 @@
-txt sql all: obj common
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	ALL_DEPENDS=txt sql
+	SQL_DEPENDS=txt obj_sql common_sql
+else
+	ALL_TARGET=txt
+	SQL_DEPENDS=needs_mysql
+endif
+
+#####################################################################
+.PHONY : all txt sql clean help
+
+all: $(ALL_DEPENDS)
+
+txt: obj common
+
+sql: $(SQL_DEPENDS)
+
+clean:
+	rm -rf *.o obj obj_sql
+
+help:
+	@echo "possible targets are 'txt' 'sql' 'all' 'clean' 'help'"
+	@echo "'txt'    - builds object files used in txt servers"
+	@echo "'sql'    - builds object files used in sql servers"
+	@echo "'all'    - builds all above targets"
+	@echo "'clean'  - cleans builds and objects"
+	@echo "'help'   - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
 
 
 obj:
 obj:
-	mkdir obj
+	-mkdir obj
+
+obj_sql:
+	-mkdir obj_sql
 
 
 common: obj/core.o obj/socket.o obj/timer.o obj/db.o obj/plugins.o obj/lock.o \
 common: obj/core.o obj/socket.o obj/timer.o obj/db.o obj/plugins.o obj/lock.o \
 	obj/nullpo.o obj/malloc.o obj/showmsg.o  obj/strlib.o obj/utils.o \
 	obj/nullpo.o obj/malloc.o obj/showmsg.o  obj/strlib.o obj/utils.o \
 	obj/grfio.o obj/minicore.o obj/minisocket.o obj/minimalloc.o \
 	obj/grfio.o obj/minicore.o obj/minisocket.o obj/minimalloc.o \
 	obj/mapindex.o obj/ers.o obj/md5calc.o
 	obj/mapindex.o obj/ers.o obj/md5calc.o
 
 
+common_sql: obj_sql/sql.o
+
 
 
 obj/%.o: %.c
 obj/%.o: %.c
-	$(COMPILE.c) $(OUTPUT_OPTION) $<
+	@CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
 
 
 obj/mini%.o: %.c
 obj/mini%.o: %.c
-	$(COMPILE.c) -DMINICORE $(OUTPUT_OPTION) $<
+	@CC@ @CFLAGS@ -DMINICORE @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+
+obj_sql/%.o: %.c
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
 
 
 
 
-clean:
-	rm -rf *.o obj GNUmakefile
-	rm -rf svnversion.h
 HAVESVN = $(shell which svnversion)
 HAVESVN = $(shell which svnversion)
 
 
 ifeq ($(findstring /,$(HAVESVN)), /)
 ifeq ($(findstring /,$(HAVESVN)), /)
@@ -38,19 +76,20 @@ obj/minimalloc.o: malloc.c malloc.h
 # DO NOT DELETE
 # DO NOT DELETE
 
 
 obj/core.o: core.c core.h showmsg.h svnversion.h
 obj/core.o: core.c core.h showmsg.h svnversion.h
-obj/socket.o: socket.c socket.h mmo.h showmsg.h plugins.h
-obj/timer.o: timer.c timer.h showmsg.h
-obj/ers.o: ers.c ers.h cbasetypes.h
 obj/db.o: db.c db.h showmsg.h ers.h
 obj/db.o: db.c db.h showmsg.h ers.h
-obj/lock.o: lock.c lock.h showmsg.h
+obj/ers.o: ers.c ers.h cbasetypes.h
 obj/grfio.o: grfio.c grfio.h
 obj/grfio.o: grfio.c grfio.h
-obj/nullpo.o: nullpo.c nullpo.h showmsg.h
+obj/lock.o: lock.c lock.h showmsg.h
 obj/malloc.o: malloc.c malloc.h showmsg.h
 obj/malloc.o: malloc.c malloc.h showmsg.h
+obj/mapindex.o: mapindex.c mapindex.h
+obj/md5calc.o: md5calc.c md5calc.h
+obj/nullpo.o: nullpo.c nullpo.h showmsg.h
 obj/plugins.o: plugins.c plugins.h plugin.h
 obj/plugins.o: plugins.c plugins.h plugin.h
 obj/showmsg.o: showmsg.c showmsg.h
 obj/showmsg.o: showmsg.c showmsg.h
+obj/socket.o: socket.c socket.h mmo.h showmsg.h plugins.h
 obj/strlib.o: strlib.c strlib.h utils.h
 obj/strlib.o: strlib.c strlib.h utils.h
-obj/mapindex.o: mapindex.c mapindex.h
+obj/timer.o: timer.c timer.h showmsg.h
 obj/utils.o: utils.c utils.h malloc.h showmsg.h mmo.h
 obj/utils.o: utils.c utils.h malloc.h showmsg.h mmo.h
-obj/md5calc.o: md5calc.c md5calc.h
+obj_sql/sql.o: sql.c sql.h cbasetypes.h malloc.h showmsg.h utils.h
 mmo.h: cbasetypes.h
 mmo.h: cbasetypes.h
 	@touch mmo.h
 	@touch mmo.h

+ 0 - 1
src/common/db.c

@@ -70,7 +70,6 @@
 
 
 #include "db.h"
 #include "db.h"
 #include "../common/mmo.h"
 #include "../common/mmo.h"
-#include "../common/utils.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/ers.h"
 #include "../common/ers.h"

+ 2 - 1
src/common/ers.c

@@ -40,9 +40,10 @@
 \*****************************************************************************/
 \*****************************************************************************/
 #include <stdlib.h>
 #include <stdlib.h>
 
 
-#include "ers.h"
+#include "../common/cbasetypes.h"
 #include "../common/malloc.h" // CREATE, RECREATE, aMalloc, aFree
 #include "../common/malloc.h" // CREATE, RECREATE, aMalloc, aFree
 #include "../common/showmsg.h" // ShowMessage, ShowError, ShowFatalError, CL_BOLD, CL_NORMAL
 #include "../common/showmsg.h" // ShowMessage, ShowError, ShowFatalError, CL_BOLD, CL_NORMAL
+#include "ers.h"
 
 
 #ifndef DISABLE_ERS
 #ifndef DISABLE_ERS
 /*****************************************************************************\
 /*****************************************************************************\

+ 2 - 0
src/common/ers.h

@@ -40,7 +40,9 @@
 #ifndef _ERS_H_
 #ifndef _ERS_H_
 #define _ERS_H_
 #define _ERS_H_
 
 
+#ifndef _CBASETYPES_H_
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
+#endif
 
 
 /*****************************************************************************\
 /*****************************************************************************\
  *  (1) All public parts of the Entry Reusage System.                        *
  *  (1) All public parts of the Entry Reusage System.                        *

+ 1 - 1
src/common/md5calc.c

@@ -173,7 +173,7 @@ void MD5_String2binary(const char * string, char * output)
 
 
    //Step 1.Append Padding Bits (extension of a mark bit)
    //Step 1.Append Padding Bits (extension of a mark bit)
    //1-1
    //1-1
-   string_byte_len = strlen(string);    //The byte chief of a character sequence is acquired.
+   string_byte_len = (unsigned int)strlen(string);    //The byte chief of a character sequence is acquired.
    pstring = (unsigned char *)string; //The position of the present character sequence is set.
    pstring = (unsigned char *)string; //The position of the present character sequence is set.
 
 
    //1-2  Repeat calculation until length becomes less than 64 bytes.
    //1-2  Repeat calculation until length becomes less than 64 bytes.

+ 3 - 4
src/common/mmo.h

@@ -4,9 +4,8 @@
 #ifndef	_MMO_H_
 #ifndef	_MMO_H_
 #define	_MMO_H_
 #define	_MMO_H_
 
 
-#include <time.h>
 #include "cbasetypes.h"
 #include "cbasetypes.h"
-#include "utils.h" // _WIN32
+#include <time.h>
 
 
 #define FIFOSIZE_SERVERLINK	256*1024
 #define FIFOSIZE_SERVERLINK	256*1024
 
 
@@ -179,7 +178,7 @@ struct s_homunculus {	//[orn]
 	int luk ;
 	int luk ;
 };
 };
 
 
-struct friend {
+struct s_friend {
 	int account_id;
 	int account_id;
 	int char_id;
 	int char_id;
 	char name[NAME_LENGTH];
 	char name[NAME_LENGTH];
@@ -229,7 +228,7 @@ struct mmo_charstatus {
 	struct item inventory[MAX_INVENTORY],cart[MAX_CART];
 	struct item inventory[MAX_INVENTORY],cart[MAX_CART];
 	struct skill skill[MAX_SKILL];
 	struct skill skill[MAX_SKILL];
 
 
-	struct friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
+	struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
 #ifdef HOTKEY_SAVING
 #ifdef HOTKEY_SAVING
 	struct hotkey hotkeys[HOTKEY_SAVING];
 	struct hotkey hotkeys[HOTKEY_SAVING];
 #endif
 #endif

+ 2 - 2
src/common/plugins.c

@@ -1,15 +1,15 @@
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
-#include "plugins.h"
 #include "../common/mmo.h"
 #include "../common/mmo.h"
 #include "../common/core.h"
 #include "../common/core.h"
 #include "../common/timer.h"
 #include "../common/timer.h"
-#include "../common/utils.h"
+#include "../common/utils.h" // findfile()
 #include "../common/socket.h"
 #include "../common/socket.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/version.h"
 #include "../common/version.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "plugins.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>

+ 12 - 9
src/common/showmsg.c

@@ -2,7 +2,7 @@
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
-#include "../common/utils.h"
+#include "../common/strlib.h" // StringBuf
 #include "showmsg.h"
 #include "showmsg.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
@@ -59,7 +59,7 @@ int msg_silent = 0; //Specifies how silent the console is.
 #define NEWBUF(buf)				\
 #define NEWBUF(buf)				\
 	struct {					\
 	struct {					\
 		char s_[SBUF_SIZE];		\
 		char s_[SBUF_SIZE];		\
-		struct StringBuf *d_;	\
+		StringBuf *d_;			\
 		char *v_;				\
 		char *v_;				\
 		int l_;					\
 		int l_;					\
 	} buf ={"",NULL,NULL,0};	\
 	} buf ={"",NULL,NULL,0};	\
@@ -198,7 +198,7 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 	*/
 	*/
 
 
 	/////////////////////////////////////////////////////////////////
 	/////////////////////////////////////////////////////////////////
-	unsigned long	written;
+	DWORD written;
 	char *p, *q;
 	char *p, *q;
 	NEWBUF(tempbuf); // temporary buffer
 	NEWBUF(tempbuf); // temporary buffer
 
 
@@ -218,8 +218,8 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 	p = BUFVAL(tempbuf);
 	p = BUFVAL(tempbuf);
 	while ((q = strchr(p, 0x1b)) != NULL)
 	while ((q = strchr(p, 0x1b)) != NULL)
 	{	// find the escape character
 	{	// find the escape character
-		if( 0==WriteConsole(handle, p, q-p, &written, 0) ) // write up to the escape
-			WriteFile(handle, p, q-p, &written, 0);
+		if( 0==WriteConsole(handle, p, (DWORD)(q-p), &written, 0) ) // write up to the escape
+			WriteFile(handle, p, (DWORD)(q-p), &written, 0);
 
 
 		if( q[1]!='[' )
 		if( q[1]!='[' )
 		{	// write the escape char (whatever purpose it has) 
 		{	// write the escape char (whatever purpose it has) 
@@ -240,7 +240,7 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 
 
 			// skip escape and bracket
 			// skip escape and bracket
 			q=q+2;	
 			q=q+2;	
-			while(1)
+			for(;;)
 			{
 			{
 				if( ISDIGIT(*q) ) 
 				if( ISDIGIT(*q) ) 
 				{	// add number to number array, only accept 2digits, shift out the rest
 				{	// add number to number array, only accept 2digits, shift out the rest
@@ -501,8 +501,8 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 		}
 		}
 	}
 	}
 	if (*p)	// write the rest of the buffer
 	if (*p)	// write the rest of the buffer
-		if( 0==WriteConsole(handle, p, strlen(p), &written, 0) )
-			WriteFile(handle,p, strlen(p), &written, 0);
+		if( 0==WriteConsole(handle, p, (DWORD)strlen(p), &written, 0) )
+			WriteFile(handle, p, (DWORD)strlen(p), &written, 0);
 	FREEBUF(tempbuf);
 	FREEBUF(tempbuf);
 	return 0;
 	return 0;
 }
 }
@@ -689,7 +689,10 @@ int _vShowMessage(enum msg_type flag, const char *string, va_list ap)
 		ShowError("Empty string passed to _vShowMessage().\n");
 		ShowError("Empty string passed to _vShowMessage().\n");
 		return 1;
 		return 1;
 	}
 	}
-	if ((flag == MSG_DEBUG && !SHOW_DEBUG_MSG) ||
+	if (
+#if !defined(SHOW_DEBUG_MSG)
+			(flag == MSG_DEBUG) ||
+#endif
 	    (flag == MSG_INFORMATION && msg_silent&1) ||
 	    (flag == MSG_INFORMATION && msg_silent&1) ||
 	    (flag == MSG_STATUS && msg_silent&2) ||
 	    (flag == MSG_STATUS && msg_silent&2) ||
 	    (flag == MSG_NOTICE && msg_silent&4) ||
 	    (flag == MSG_NOTICE && msg_silent&4) ||

+ 7 - 6
src/common/socket.c

@@ -111,8 +111,9 @@ void set_defaultparse(ParseFunc defaultparse)
 void set_nonblocking(int fd, unsigned long yes)
 void set_nonblocking(int fd, unsigned long yes)
 {
 {
 	// TCP_NODELAY BOOL Disables the Nagle algorithm for send coalescing.
 	// TCP_NODELAY BOOL Disables the Nagle algorithm for send coalescing.
-	if(MODE_NODELAY)
-		setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof yes);
+#if defined(MODE_NODELAY) && MODE_NODELAY == 1
+	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof yes);
+#endif
 	
 	
 	// FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s. 
 	// FIONBIO Use with a nonzero argp parameter to enable the nonblocking mode of socket s. 
 	// The argp parameter is zero if nonblocking is to be disabled. 
 	// The argp parameter is zero if nonblocking is to be disabled. 
@@ -169,7 +170,7 @@ int recv_to_fifo(int fd)
 	if( !session_isActive(fd) )
 	if( !session_isActive(fd) )
 		return -1;
 		return -1;
 
 
-	len = recv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, RFIFOSPACE(fd), 0);
+	len = recv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0);
 
 
 	if (len == SOCKET_ERROR) {
 	if (len == SOCKET_ERROR) {
 		if (s_errno == S_ECONNABORTED) {
 		if (s_errno == S_ECONNABORTED) {
@@ -203,7 +204,7 @@ int send_from_fifo(int fd)
 	if (session[fd]->wdata_size == 0)
 	if (session[fd]->wdata_size == 0)
 		return 0;
 		return 0;
 
 
-	len = send(fd, (const char *) session[fd]->wdata, session[fd]->wdata_size, 0);
+	len = send(fd, (const char *) session[fd]->wdata, (int)session[fd]->wdata_size, 0);
 
 
 	if (len == SOCKET_ERROR) {
 	if (len == SOCKET_ERROR) {
 		if (s_errno == S_ECONNABORTED) {
 		if (s_errno == S_ECONNABORTED) {
@@ -457,7 +458,7 @@ int realloc_writefifo(int fd, size_t addition)
 	return 0;
 	return 0;
 }
 }
 
 
-int RFIFOSKIP(int fd, int len)
+int RFIFOSKIP(int fd, size_t len)
 {
 {
     struct socket_data *s;
     struct socket_data *s;
 
 
@@ -477,7 +478,7 @@ int RFIFOSKIP(int fd, int len)
 	return 0;
 	return 0;
 }
 }
 
 
-int WFIFOSET(int fd, int len)
+int WFIFOSET(int fd, size_t len)
 {
 {
 	size_t newreserve;
 	size_t newreserve;
 	struct socket_data* s = session[fd];
 	struct socket_data* s = session[fd];

+ 2 - 2
src/common/socket.h

@@ -104,8 +104,8 @@ int make_listen_bind(uint32 ip, uint16 port);
 int make_connection(uint32 ip, uint16 port);
 int make_connection(uint32 ip, uint16 port);
 int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
 int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
 int realloc_writefifo(int fd, size_t addition);
 int realloc_writefifo(int fd, size_t addition);
-int WFIFOSET(int fd, int len);
-int RFIFOSKIP(int fd, int len);
+int WFIFOSET(int fd, size_t len);
+int RFIFOSKIP(int fd, size_t len);
 
 
 int do_sendrecv(int next);
 int do_sendrecv(int next);
 int do_parsepacket(void);
 int do_parsepacket(void);

+ 851 - 0
src/common/sql.c

@@ -0,0 +1,851 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/cbasetypes.h"
+#include "../common/malloc.h"
+#include "../common/showmsg.h"
+#include "../common/strlib.h"
+#include "sql.h"
+
+#ifdef WIN32
+#include <winsock2.h>
+#endif
+#include <mysql.h>
+#include <string.h>// strlen/strnlen/memcpy/memset
+#include <stdlib.h>// strtoul
+
+
+
+/// Sql handle
+struct Sql
+{
+	StringBuf buf;
+	MYSQL handle;
+	MYSQL_RES* result;
+	MYSQL_ROW row;
+	unsigned long* lengths;
+};
+
+
+
+// Column length receiver.
+// Takes care of the possible size missmatch between uint32 and unsigned long.
+struct s_column_length
+{
+	uint32* out_length;
+	unsigned long length;
+};
+typedef struct s_column_length s_column_length;
+
+
+
+/// Sql statement
+struct SqlStmt
+{
+	StringBuf buf;
+	MYSQL_STMT* stmt;
+	MYSQL_BIND* params;
+	MYSQL_BIND* columns;
+	s_column_length* column_lengths;
+	size_t max_params;
+	size_t max_columns;
+	bool bind_params;
+	bool bind_columns;
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Sql Handle
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+/// Allocates and initializes a new Sql handle.
+Sql* Sql_Malloc(void)
+{
+	Sql* self;
+	CREATE(self, Sql, 1);
+	mysql_init(&self->handle);
+	StringBuf_Init(&self->buf);
+	return self;
+}
+
+
+
+/// Establishes a connection.
+int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	StringBuf_Clear(&self->buf);
+	if( !mysql_real_connect(&self->handle, host, user, passwd, db, (unsigned int)port, NULL/*unix_socket*/, 0/*clientflag*/) )
+	{
+		ShowSQL("%s\n", mysql_error(&self->handle));
+		return SQL_ERROR;
+	}
+	return SQL_SUCCESS;
+}
+
+
+
+/// Retrieves the timeout of the connection.
+int Sql_GetTimeout(Sql* self, uint32* out_timeout)
+{
+	if( self && out_timeout && SQL_SUCCESS == Sql_Query(self, "SHOW VARIABLES LIKE 'wait_timeout'") )
+	{
+		char* data;
+		size_t len;
+		if( SQL_SUCCESS == Sql_NextRow(self) &&
+			SQL_SUCCESS == Sql_GetData(self, 1, &data, &len) )
+		{
+			*out_timeout = (uint32)strtoul(data, NULL, 10);
+			Sql_FreeResult(self);
+			return SQL_SUCCESS;
+		}
+		Sql_FreeResult(self);
+	}
+	return SQL_ERROR;
+}
+
+
+
+/// Retrieves the name of the columns of a table into out_buf, with the separator after each name.
+int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep)
+{
+	char* data;
+	size_t len;
+	size_t off = 0;
+
+	if( self == NULL || SQL_ERROR == Sql_Query(self, "EXPLAIN `%s`", table) )
+		return SQL_ERROR;
+
+	out_buf[off] = '\0';
+	while( SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 0, &data, &len) )
+	{
+		len = strnlen(data, len);
+		if( off + len + 2 > buf_len )
+		{
+			ShowDebug("Sql_GetColumns: output buffer is too small\n");
+			*out_buf = '\0';
+			return SQL_ERROR;
+		}
+		memcpy(out_buf+off, data, len);
+		off += len;
+		out_buf[off++] = sep;
+	}
+	out_buf[off] = '\0';
+	Sql_FreeResult(self);
+	return SQL_SUCCESS;
+}
+
+
+
+/// Changes the encoding of the connection.
+int Sql_SetEncoding(Sql* self, const char* encoding)
+{
+	return Sql_Query(self, "SET NAMES %s", encoding);
+}
+
+
+
+/// Pings the connection.
+int Sql_Ping(Sql* self)
+{
+	if( self && mysql_ping(&self->handle) == 0 )
+		return SQL_SUCCESS;
+	return  SQL_ERROR;
+}
+
+
+
+/// Escapes a string.
+size_t Sql_EscapeString(Sql* self, char *out_to, const char *from)
+{
+	if( self )
+		return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)strlen(from));
+	else
+		return (size_t)mysql_escape_string(out_to, from, (unsigned long)strlen(from));
+}
+
+
+
+/// Escapes a string.
+size_t Sql_EscapeStringLen(Sql* self, char *out_to, const char *from, size_t from_len)
+{
+	if( self )
+		return (size_t)mysql_real_escape_string(&self->handle, out_to, from, (unsigned long)from_len);
+	else
+		return (size_t)mysql_escape_string(out_to, from, (unsigned long)from_len);
+}
+
+
+
+/// Executes a query.
+int Sql_Query(Sql* self, const char* query, ...)
+{
+	int res;
+	va_list args;
+
+	va_start(args, query);
+	res = Sql_QueryV(self, query, args);
+	va_end(args);
+
+	return res;
+}
+
+
+
+/// Executes a query.
+int Sql_QueryV(Sql* self, const char* query, va_list args)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	Sql_FreeResult(self);
+	StringBuf_Clear(&self->buf);
+	StringBuf_Vprintf(&self->buf, query, args);
+	if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+	{
+		ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+		return SQL_ERROR;
+	}
+	self->result = mysql_store_result(&self->handle);
+	if( mysql_errno(&self->handle) != 0 )
+	{
+		ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+		return SQL_ERROR;
+	}
+	return SQL_SUCCESS;
+}
+
+
+
+/// Executes a query.
+int Sql_QueryStr(Sql* self, const char* query)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	Sql_FreeResult(self);
+	StringBuf_Clear(&self->buf);
+	StringBuf_AppendStr(&self->buf, query);
+	if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+	{
+		ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+		return SQL_ERROR;
+	}
+	self->result = mysql_store_result(&self->handle);
+	if( mysql_errno(&self->handle) != 0 )
+	{
+		ShowSQL("DB error - %s\n", mysql_error(&self->handle));
+		return SQL_ERROR;
+	}
+	return SQL_SUCCESS;
+}
+
+
+
+/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query.
+uint64 Sql_LastInsertId(Sql* self)
+{
+	if( self )
+		return (uint64)mysql_insert_id(&self->handle);
+	else
+		return 0;
+}
+
+
+
+/// Returns the number of columns in each row of the result.
+uint32 Sql_NumColumns(Sql* self)
+{
+	if( self && self->result )
+		return (uint32)mysql_num_fields(self->result);
+	return 0;
+}
+
+
+
+/// Returns the number of rows in the result.
+uint64 Sql_NumRows(Sql* self)
+{
+	if( self && self->result )
+		return (uint64)mysql_num_rows(self->result);
+	return 0;
+}
+
+
+
+/// Fetches the next row.
+int Sql_NextRow(Sql* self)
+{
+	if( self && self->result )
+	{
+		self->row = mysql_fetch_row(self->result);
+		if( self->row )
+		{
+			self->lengths = mysql_fetch_lengths(self->result);
+			return SQL_SUCCESS;
+		}
+		self->lengths = NULL;
+		if( mysql_errno(&self->handle) == 0 )
+			return SQL_NO_DATA;
+	}
+	return SQL_ERROR;
+}
+
+
+
+/// Gets the data of a column.
+int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len)
+{
+	if( self && self->row )
+	{
+		if( col < Sql_NumColumns(self) )
+		{
+			if( out_buf ) *out_buf = self->row[col];
+			if( out_len ) *out_len = (size_t)self->lengths[col];
+		}
+		else
+		{// out of range - ignore
+			if( out_buf ) *out_buf = NULL;
+			if( out_len ) *out_len = 0;
+		}
+		return SQL_SUCCESS;
+	}
+	return SQL_ERROR;
+}
+
+
+
+/// Frees the result of the query.
+void Sql_FreeResult(Sql* self)
+{
+	if( self && self->result )
+	{
+		mysql_free_result(self->result);
+		self->result = NULL;
+		self->row = NULL;
+		self->lengths = NULL;
+	}
+}
+
+
+
+/// Shows debug information (last query).
+void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line)
+{
+	if( self == NULL )
+		ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line);
+	else if( StringBuf_Length(&self->buf) > 0 )
+		ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
+	else
+		ShowDebug("at %s:%lu\n", debug_file, debug_line);
+}
+
+
+
+/// Frees a Sql handle returned by Sql_Malloc.
+void Sql_Free(Sql* self) 
+{
+	if( self )
+	{
+		Sql_FreeResult(self);
+		StringBuf_Destroy(&self->buf);
+		aFree(self);
+	}
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Prepared Statements
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+/// Returns the mysql integer type for the target size.
+///
+/// @private
+static enum enum_field_types Sql_P_SizeToMysqlIntType(int sz)
+{
+	switch( sz )
+	{
+	case 1: return MYSQL_TYPE_TINY;
+	case 2: return MYSQL_TYPE_SHORT;
+	case 4: return MYSQL_TYPE_LONG;
+	case 8: return MYSQL_TYPE_LONGLONG;
+	default:
+		ShowDebug("SizeToMysqlIntType: unsupported size (%d)\n", sz);
+		return MYSQL_TYPE_NULL;
+	}
+}
+
+
+
+/// Binds a parameter/result.
+///
+/// @private
+static int Sql_P_BindSqlDataType(MYSQL_BIND* bind, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, unsigned long* out_length, int8* out_is_null)
+{
+	memset(bind, 0, sizeof(MYSQL_BIND));
+	switch( buffer_type )
+	{
+	case SQLDT_NULL: bind->buffer_type = MYSQL_TYPE_NULL;
+		break;
+	// fixed size
+	case SQLDT_UINT8: bind->is_unsigned = 1;
+	case SQLDT_INT8: bind->buffer_type = MYSQL_TYPE_TINY;
+		break;
+	case SQLDT_UINT16: bind->is_unsigned = 1;
+	case SQLDT_INT16: bind->buffer_type = MYSQL_TYPE_SHORT;
+		break;
+	case SQLDT_UINT32: bind->is_unsigned = 1;
+	case SQLDT_INT32: bind->buffer_type = MYSQL_TYPE_LONG;
+		break;
+	case SQLDT_UINT64: bind->is_unsigned = 1;
+	case SQLDT_INT64: bind->buffer_type = MYSQL_TYPE_LONGLONG;
+		break;
+	// platform dependent size
+	case SQLDT_UCHAR: bind->is_unsigned = 1;
+	case SQLDT_CHAR: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(char));
+		break;
+	case SQLDT_USHORT: bind->is_unsigned = 1;
+	case SQLDT_SHORT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(short));
+		break;
+	case SQLDT_UINT: bind->is_unsigned = 1;
+	case SQLDT_INT: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(int));
+		break;
+	case SQLDT_ULONG: bind->is_unsigned = 1;
+	case SQLDT_LONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(long));
+		break;
+	case SQLDT_ULONGLONG: bind->is_unsigned = 1;
+	case SQLDT_LONGLONG: bind->buffer_type = Sql_P_SizeToMysqlIntType(sizeof(long long));
+		break;
+	// floating point
+	case SQLDT_FLOAT: bind->buffer_type = MYSQL_TYPE_FLOAT;
+		break;
+	case SQLDT_DOUBLE: bind->buffer_type = MYSQL_TYPE_DOUBLE;
+		break;
+	// other
+	case SQLDT_STRING:
+	case SQLDT_ENUM: bind->buffer_type = MYSQL_TYPE_STRING;
+		break;
+	case SQLDT_BLOB: bind->buffer_type = MYSQL_TYPE_BLOB;
+		break;
+	default:
+		ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%d)\n", buffer_type);
+		return SQL_ERROR;
+	}
+	bind->buffer = buffer;
+	bind->buffer_length = (unsigned long)buffer_len;
+	bind->length = out_length;
+	bind->is_null = (my_bool*)out_is_null;
+	return SQL_SUCCESS;
+}
+
+
+
+/// Prints debug information about a field (type and length).
+///
+/// @private
+static void Sql_P_ShowDebugMysqlFieldInfo(const char* prefix, enum enum_field_types type, int is_unsigned, unsigned long length, const char* length_postfix)
+{
+	const char* sign = (is_unsigned ? "UNSIGNED " : "");
+	const char* type_string;
+	switch( type )
+	{
+	default:
+		ShowDebug("%stype=%s%u, length=%d\n", prefix, sign, type, length);
+		return;
+#define SHOW_DEBUG_OF(x) case x: type_string = #x; break
+	SHOW_DEBUG_OF(MYSQL_TYPE_TINY);
+	SHOW_DEBUG_OF(MYSQL_TYPE_SHORT);
+	SHOW_DEBUG_OF(MYSQL_TYPE_LONG);
+	SHOW_DEBUG_OF(MYSQL_TYPE_INT24);
+	SHOW_DEBUG_OF(MYSQL_TYPE_LONGLONG);
+	SHOW_DEBUG_OF(MYSQL_TYPE_DECIMAL);
+	SHOW_DEBUG_OF(MYSQL_TYPE_FLOAT);
+	SHOW_DEBUG_OF(MYSQL_TYPE_DOUBLE);
+	SHOW_DEBUG_OF(MYSQL_TYPE_TIMESTAMP);
+	SHOW_DEBUG_OF(MYSQL_TYPE_DATE);
+	SHOW_DEBUG_OF(MYSQL_TYPE_TIME);
+	SHOW_DEBUG_OF(MYSQL_TYPE_DATETIME);
+	SHOW_DEBUG_OF(MYSQL_TYPE_YEAR);
+	SHOW_DEBUG_OF(MYSQL_TYPE_STRING);
+	SHOW_DEBUG_OF(MYSQL_TYPE_VAR_STRING);
+	SHOW_DEBUG_OF(MYSQL_TYPE_BLOB);
+	SHOW_DEBUG_OF(MYSQL_TYPE_SET);
+	SHOW_DEBUG_OF(MYSQL_TYPE_ENUM);
+	SHOW_DEBUG_OF(MYSQL_TYPE_NULL);
+#undef SHOW_DEBUG_TYPE_OF
+	}
+	ShowDebug("%stype=%s%s, length=%d%s\n", prefix, sign, type_string, length, length_postfix); 
+}
+
+
+
+/// Allocates and initializes a new SqlStmt handle.
+SqlStmt* SqlStmt_Malloc(Sql* sql)
+{
+	SqlStmt* self;
+	MYSQL_STMT* stmt;
+
+	if( sql == NULL )
+		return NULL;
+
+	stmt = mysql_stmt_init(&sql->handle);
+	if( stmt == NULL )
+	{
+		ShowSQL("DB error - %s\n", mysql_error(&sql->handle));
+		return NULL;
+	}
+	CREATE(self, SqlStmt, 1);
+	StringBuf_Init(&self->buf);
+	self->stmt = stmt;
+	self->params = NULL;
+	self->columns = NULL;
+	self->column_lengths = NULL;
+	self->max_params = 0;
+	self->max_columns = 0;
+	self->bind_params = false;
+	self->bind_columns = false;
+
+	return self;
+}
+
+
+
+/// Prepares the statement.
+int SqlStmt_Prepare(SqlStmt* self, const char* query, ...)
+{
+	int res;
+	va_list args;
+
+	va_start(args, query);
+	res = SqlStmt_PrepareV(self, query, args);
+	va_end(args);
+
+	return res;
+}
+
+
+
+/// Prepares the statement.
+int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	SqlStmt_FreeResult(self);
+	StringBuf_Clear(&self->buf);
+	StringBuf_Vprintf(&self->buf, query, args);
+	if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+	{
+		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+		return SQL_ERROR;
+	}
+	self->bind_params = false;
+
+	return SQL_SUCCESS;
+}
+
+
+
+/// Prepares the statement.
+int SqlStmt_PrepareStr(SqlStmt* self, const char* query)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	SqlStmt_FreeResult(self);
+	StringBuf_Clear(&self->buf);
+	StringBuf_AppendStr(&self->buf, query);
+	if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) )
+	{
+		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+		return SQL_ERROR;
+	}
+	self->bind_params = false;
+
+	return SQL_SUCCESS;
+}
+
+
+
+/// Returns the number of parameters in the prepared statement.
+size_t SqlStmt_NumParams(SqlStmt* self)
+{
+	if( self )
+		return (size_t)mysql_stmt_param_count(self->stmt);
+	else
+		return 0;
+}
+
+
+
+/// Binds a parameter to a buffer.
+int SqlStmt_BindParam(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	if( !self->bind_params )
+	{// initialize the bindings
+		size_t i;
+		size_t count;
+
+		count = SqlStmt_NumParams(self);
+		if( self->max_params < count )
+		{
+			self->max_params = count;
+			RECREATE(self->params, MYSQL_BIND, count);
+		}
+		memset(self->params, 0, count*sizeof(MYSQL_BIND));
+		for( i = 0; i < count; ++i )
+			self->params[i].buffer_type = MYSQL_TYPE_NULL;
+		self->bind_params = true;
+	}
+	if( idx < self->max_params )
+		return Sql_P_BindSqlDataType(self->params+idx, buffer_type, buffer, buffer_len, NULL, NULL);
+	else
+		return SQL_SUCCESS;// out of range - ignore
+}
+
+
+
+/// Executes the prepared statement.
+int SqlStmt_Execute(SqlStmt* self)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	SqlStmt_FreeResult(self);
+	if( (self->bind_params && mysql_stmt_bind_param(self->stmt, self->params)) ||
+		mysql_stmt_execute(self->stmt) )
+	{
+		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+		return SQL_ERROR;
+	}
+	self->bind_columns = false;
+	if( mysql_stmt_store_result(self->stmt) )// store all the data
+	{
+		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+		return SQL_ERROR;
+	}
+
+	return SQL_SUCCESS;
+}
+
+
+
+/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE statement.
+uint64 SqlStmt_LastInsertId(SqlStmt* self)
+{
+	if( self )
+		return (uint64)mysql_stmt_insert_id(self->stmt);
+	else
+		return 0;
+}
+
+
+
+/// Returns the number of columns in each row of the result.
+size_t SqlStmt_NumColumns(SqlStmt* self)
+{
+	if( self )
+		return (size_t)mysql_stmt_field_count(self->stmt);
+	else
+		return 0;
+}
+
+
+
+/// Binds the result of a column to a buffer.
+int SqlStmt_BindColumn(SqlStmt* self, size_t idx, enum SqlDataType buffer_type, void* buffer, size_t buffer_len, uint32* out_length, int8* out_is_null)
+{
+	if( self == NULL )
+		return SQL_ERROR;
+
+	if( buffer_type == SQLDT_STRING || buffer_type == SQLDT_ENUM )
+	{
+		if( buffer_len < 1 )
+		{
+			ShowDebug("SqlStmt_BindColumn: buffer_len(%d) is too small, no room for the nul-terminator\n", buffer_len);
+			return SQL_ERROR;
+		}
+		--buffer_len;// nul-terminator
+	}
+	if( !self->bind_columns )
+	{// initialize the bindings
+		size_t i;
+		size_t cols;
+
+		cols = SqlStmt_NumColumns(self);
+		if( self->max_columns < cols )
+		{
+			self->max_columns = cols;
+			RECREATE(self->columns, MYSQL_BIND, cols);
+			RECREATE(self->column_lengths, s_column_length, cols);
+		}
+		memset(self->columns, 0, cols*sizeof(MYSQL_BIND));
+		memset(self->column_lengths, 0, cols*sizeof(s_column_length));
+		for( i = 0; i < cols; ++i )
+			self->columns[i].buffer_type = MYSQL_TYPE_NULL;
+		self->bind_columns = true;
+	}
+	if( idx < self->max_columns )
+	{
+		self->column_lengths[idx].out_length = out_length;
+		return Sql_P_BindSqlDataType(self->columns+idx, buffer_type, buffer, buffer_len, &self->column_lengths[idx].length, out_is_null);
+	}
+	else
+	{
+		return SQL_SUCCESS;// out of range - ignore
+	}
+}
+
+
+
+/// Returns the number of rows in the result.
+uint64 SqlStmt_NumRows(SqlStmt* self)
+{
+	if( self )
+		return (uint64)mysql_stmt_num_rows(self->stmt);
+	else
+		return 0;
+}
+
+
+
+/// Fetches the next row.
+int SqlStmt_NextRow(SqlStmt* self)
+{
+	int err;
+	size_t i;
+	size_t cols;
+	MYSQL_BIND* column;
+	unsigned long length;
+
+	if( self == NULL )
+		return SQL_ERROR;
+
+	// bind columns
+	if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) )
+		err = 1;// error binding columns
+	else
+		err = mysql_stmt_fetch(self->stmt);// fetch row
+
+	// check for errors
+	if( err == MYSQL_NO_DATA )
+		return SQL_NO_DATA;
+	if( err == MYSQL_DATA_TRUNCATED )
+	{
+		my_bool truncated;
+
+		if( !self->bind_columns )
+		{
+			ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n");
+			return SQL_ERROR;
+		}
+
+		// find truncated column
+		cols = SqlStmt_NumColumns(self);
+		for( i = 0; i < cols; ++i )
+		{
+			column = &self->columns[i];
+			column->error = &truncated;
+			mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0);
+			column->error = NULL;
+			if( truncated )
+			{// report truncated column
+				MYSQL_RES* meta;
+				MYSQL_FIELD* field;
+
+				meta = mysql_stmt_result_metadata(self->stmt);
+				field = mysql_fetch_field_direct(meta, (unsigned int)i);
+				ShowSQL("DB error - data of field '%s' was truncated.\n", field->name);
+				ShowDebug("column - %lu\n", (unsigned long)i);
+				Sql_P_ShowDebugMysqlFieldInfo("data   - ", field->type, field->flags&UNSIGNED_FLAG, self->column_lengths[i].length, "");
+				if( column->buffer_type == MYSQL_TYPE_STRING )
+					Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "+1(nul-terminator)");
+				else
+					Sql_P_ShowDebugMysqlFieldInfo("buffer - ", column->buffer_type, column->is_unsigned, column->buffer_length, "");
+				mysql_free_result(meta);
+				return SQL_ERROR;
+			}
+		}
+		ShowSQL("DB error - data truncated (unknown source)\n");
+		return SQL_ERROR;
+	}
+	if( err )
+	{
+		ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt));
+		return SQL_ERROR;
+	}
+
+	// propagate column lengths and clear unused parts of string/enum/blob buffers
+	cols = SqlStmt_NumColumns(self);
+	for( i = 0; i < cols; ++i )
+	{
+		length = self->column_lengths[i].length;
+		if( self->column_lengths[i].out_length )
+			*self->column_lengths[i].out_length = (uint32)length;
+		column = &self->columns[i];
+		if( column->buffer_type == MYSQL_TYPE_STRING )
+		{// clear unused part of the string/enum buffer (and nul-terminate)
+			memset((char*)column->buffer + length, 0, column->buffer_length - length + 1);
+		}
+		else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length )
+		{// clear unused part of the blob buffer
+			memset((char*)column->buffer + length, 0, column->buffer_length - length);
+		}
+	}
+
+	return SQL_SUCCESS;
+}
+
+
+
+/// Frees the result of the statement execution.
+void SqlStmt_FreeResult(SqlStmt* self)
+{
+	if( self )
+		mysql_stmt_free_result(self->stmt);
+}
+
+
+
+/// Shows debug information (with statement).
+void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line)
+{
+	if( self == NULL )
+		ShowDebug("at %s:%lu -  self is NULL\n", debug_file, debug_line);
+	if( StringBuf_Length(&self->buf) > 0 )
+		ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf));
+	else
+		ShowDebug("at %s:%lu\n", debug_file, debug_line);
+}
+
+
+
+/// Frees a SqlStmt returned by SqlStmt_Malloc.
+void SqlStmt_Free(SqlStmt* self)
+{
+	if( self )
+	{
+		SqlStmt_FreeResult(self);
+		StringBuf_Destroy(&self->buf);
+		mysql_stmt_close(self->stmt);
+		if( self->params )
+			aFree(self->params);
+		if( self->columns )
+		{
+			aFree(self->columns);
+			aFree(self->column_lengths);
+		}
+		aFree(self);
+	}
+}

+ 343 - 0
src/common/sql.h

@@ -0,0 +1,343 @@
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef _COMMON_SQL_H_
+#define _COMMON_SQL_H_
+
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+#include <stdarg.h>// va_list
+
+
+
+// Return codes
+#define SQL_ERROR -1
+#define SQL_SUCCESS 0
+#define SQL_NO_DATA 100
+
+
+
+/// Data type identifier.
+/// String, enum and blob data types need the buffer length specified.
+enum SqlDataType
+{
+	SQLDT_NULL,
+	// fixed size
+	SQLDT_INT8,
+	SQLDT_INT16,
+	SQLDT_INT32,
+	SQLDT_INT64,
+	SQLDT_UINT8,
+	SQLDT_UINT16,
+	SQLDT_UINT32,
+	SQLDT_UINT64,
+	// platform dependent size
+	SQLDT_CHAR,
+	SQLDT_SHORT,
+	SQLDT_INT,
+	SQLDT_LONG,
+	SQLDT_LONGLONG,
+	SQLDT_UCHAR,
+	SQLDT_USHORT,
+	SQLDT_UINT,
+	SQLDT_ULONG,
+	SQLDT_ULONGLONG,
+	// floating point
+	SQLDT_FLOAT,
+	SQLDT_DOUBLE,
+	// other
+	SQLDT_STRING,
+	SQLDT_ENUM,
+	// Note: An ENUM is a string with restricted values. When an invalid value
+	//       is inserted, it is saved as an empty string (numerical value 0).
+	SQLDT_BLOB,
+	SQLDT_LASTID
+};
+
+struct Sql;// Sql handle (private access)
+struct SqlStmt;// Sql statement (private access)
+
+typedef enum SqlDataType SqlDataType;
+typedef struct Sql Sql;
+typedef struct SqlStmt SqlStmt;
+
+
+/// Allocates and initializes a new Sql handle.
+struct Sql* Sql_Malloc(void);
+
+
+
+/// Establishes a connection.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db);
+
+
+
+
+/// Retrieves the timeout of the connection.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_GetTimeout(Sql* self, uint32* out_timeout);
+
+
+
+
+/// Retrieves the name of the columns of a table into out_buf, with the separator after each name.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep);
+
+
+
+
+/// Changes the encoding of the connection.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_SetEncoding(Sql* self, const char* encoding);
+
+
+
+/// Pings the connection.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_Ping(Sql* self);
+
+
+
+/// Escapes a string.
+/// The output buffer must be at least strlen(from)*2+1 in size.
+///
+/// @return The size of the escaped string
+size_t Sql_EscapeString(Sql* self, char* out_to, const char* from);
+
+
+
+/// Escapes a string.
+/// The output buffer must be at least from_len*2+1 in size.
+///
+/// @return The size of the escaped string
+size_t Sql_EscapeStringLen(Sql* self, char* out_to, const char* from, size_t from_len);
+
+
+
+/// Executes a query.
+/// Any previous result is freed.
+/// The query is constructed as if it was sprintf.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_Query(Sql* self, const char* query, ...);
+
+
+
+/// Executes a query.
+/// Any previous result is freed.
+/// The query is constructed as if it was svprintf.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_QueryV(Sql* self, const char* query, va_list args);
+
+
+
+/// Executes a query.
+/// Any previous result is freed.
+/// The query is used directly.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_QueryStr(Sql* self, const char* query);
+
+
+
+/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query.
+///
+/// @return Value of the auto-increment column
+uint64 Sql_LastInsertId(Sql* self);
+
+
+
+/// Returns the number of columns in each row of the result.
+///
+/// @return Number of columns
+uint32 Sql_NumColumns(Sql* self);
+
+
+
+/// Returns the number of rows in the result.
+///
+/// @return Number of rows
+uint64 Sql_NumRows(Sql* self);
+
+
+
+/// Fetches the next row.
+/// The data of the previous row is no longer valid.
+///
+/// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA
+int Sql_NextRow(Sql* self);
+
+
+
+/// Gets the data of a column.
+/// The data remains valid until the next row is fetched or the result is freed.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len);
+
+
+
+/// Frees the result of the query.
+void Sql_FreeResult(Sql* self);
+
+
+
+#if defined(SQL_REMOVE_SHOWDEBUG)
+#define Sql_ShowDebug(self) (void)0
+#else
+#define Sql_ShowDebug(self) Sql_ShowDebug_(self, __FILE__, __LINE__)
+#endif
+/// Shows debug information (last query).
+void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line);
+
+
+
+/// Frees a Sql handle returned by Sql_Malloc.
+void Sql_Free(Sql* self);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Prepared Statements
+///////////////////////////////////////////////////////////////////////////////
+// Parameters are placed in the statement by embedding question mark ('?') 
+// characters into the query at the appropriate positions.
+// The markers are legal only in places where they represent data.
+// The markers cannot be inside quotes. Quotes will be added automatically 
+// when they are required.
+//
+// example queries with parameters:
+// 1) SELECT col FROM table WHERE id=?
+// 2) INSERT INTO table(col1,col2) VALUES(?,?)
+
+
+
+/// Allocates and initializes a new SqlStmt handle.
+/// It uses the connection of the parent Sql handle.
+/// Queries in Sql and SqlStmt are independent and don't affect each other.
+///
+/// @return SqlStmt handle or NULL if an error occured
+struct SqlStmt* SqlStmt_Malloc(Sql* sql);
+
+
+
+/// Prepares the statement.
+/// Any previous result is freed and all parameter bindings are removed.
+/// The query is constructed as if it was sprintf.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_Prepare(SqlStmt* self, const char* query, ...);
+
+
+
+/// Prepares the statement.
+/// Any previous result is freed and all parameter bindings are removed.
+/// The query is constructed as if it was svprintf.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args);
+
+
+
+/// Prepares the statement.
+/// Any previous result is freed and all parameter bindings are removed.
+/// The query is used directly.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_PrepareStr(SqlStmt* self, const char* query);
+
+
+
+/// Returns the number of parameters in the prepared statement.
+///
+/// @return Number or paramenters
+size_t SqlStmt_NumParams(SqlStmt* self);
+
+
+
+/// Binds a parameter to a buffer.
+/// The buffer data will be used when the statement is executed.
+/// All parameters should have bindings.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_BindParam(SqlStmt* self, size_t idx, SqlDataType buffer_type, void* buffer, size_t buffer_len);
+
+
+
+/// Executes the prepared statement.
+/// Any previous result is freed and all column bindings are removed.
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_Execute(SqlStmt* self);
+
+
+
+/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE statement.
+///
+/// @return Value of the auto-increment column
+uint64 SqlStmt_LastInsertId(SqlStmt* self);
+
+
+
+/// Returns the number of columns in each row of the result.
+///
+/// @return Number of columns
+size_t SqlStmt_NumColumns(SqlStmt* self);
+
+
+
+/// Binds the result of a column to a buffer.
+/// The buffer will be filled with data when the next row is fetched.
+/// For string/enum buffer types there has to be enough space for the data 
+/// and the nul-terminator (an extra byte).
+///
+/// @return SQL_SUCCESS or SQL_ERROR
+int SqlStmt_BindColumn(SqlStmt* self, size_t idx, SqlDataType buffer_type, void* buffer, size_t buffer_len, uint32* out_length, int8* out_is_null);
+
+
+
+/// Returns the number of rows in the result.
+///
+/// @return Number of rows
+uint64 SqlStmt_NumRows(SqlStmt* self);
+
+
+
+/// Fetches the next row.
+/// All column bindings will be filled with data.
+///
+/// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA
+int SqlStmt_NextRow(SqlStmt* self);
+
+
+
+/// Frees the result of the statement execution.
+void SqlStmt_FreeResult(SqlStmt* self);
+
+
+
+#if defined(SQL_REMOVE_SHOWDEBUG)
+#define SqlStmt_ShowDebug(self) (void)0
+#else
+#define SqlStmt_ShowDebug(self) SqlStmt_ShowDebug_(self, __FILE__, __LINE__)
+#endif
+/// Shows debug information (with statement).
+void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line);
+
+
+
+/// Frees a SqlStmt returned by SqlStmt_Malloc.
+void SqlStmt_Free(SqlStmt* self);
+
+
+
+#endif /* _COMMON_SQL_H_ */

+ 132 - 2
src/common/strlib.c

@@ -3,7 +3,6 @@
 
 
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
-#include "../common/utils.h"
 #include "strlib.h"
 #include "strlib.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
@@ -258,7 +257,7 @@ int e_mail_check(char* email)
 {
 {
 	char ch;
 	char ch;
 	char* last_arobas;
 	char* last_arobas;
-	int len = strlen(email);
+	size_t len = strlen(email);
 
 
 	// athena limits
 	// athena limits
 	if (len < 3 || len > 39)
 	if (len < 3 || len > 39)
@@ -310,3 +309,134 @@ char* safestrncpy(char* dst, const char* src, size_t n)
 		ret[n - 1] = '\0';
 		ret[n - 1] = '\0';
 	return ret;
 	return ret;
 }
 }
+
+
+/////////////////////////////////////////////////////////////////////
+// StringBuf - dynamic string
+//
+// @author MouseJstr (original)
+
+/// Allocates a StringBuf
+StringBuf* StringBuf_Malloc() 
+{
+	StringBuf* self;
+	CREATE(self, StringBuf, 1);
+	StringBuf_Init(self);
+	return self;
+}
+
+/// Initializes a previously allocated StringBuf
+void StringBuf_Init(StringBuf* self)
+{
+	self->max_ = 1024;
+	self->ptr_ = self->buf_ = (char*)aMallocA(self->max_ + 1);
+}
+
+/// Appends the result of printf to the StringBuf
+int StringBuf_Printf(StringBuf* self, const char* fmt, ...)
+{
+	int len;
+	va_list ap;
+
+	va_start(ap, fmt);
+	len = StringBuf_Vprintf(self, fmt, ap);
+	va_end(ap);
+
+	return len;
+}
+
+/// Appends the result of vprintf to the StringBuf
+int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap)
+{
+	int n, size, off;
+
+	for(;;)
+	{
+		/* Try to print in the allocated space. */
+		size = self->max_ - (self->ptr_ - self->buf_);
+		n = vsnprintf(self->ptr_, size, fmt, ap);
+		/* If that worked, return the length. */
+		if( n > -1 && n < size )
+		{
+			self->ptr_ += n;
+			return (int)(self->ptr_ - self->buf_);
+		}
+		/* Else try again with more space. */
+		self->max_ *= 2; // twice the old size
+		off = (int)(self->ptr_ - self->buf_);
+		self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+		self->ptr_ = self->buf_ + off;
+	}
+}
+
+/// Appends the contents of another StringBuf to the StringBuf
+int StringBuf_Append(StringBuf* self, const StringBuf* sbuf)
+{
+	int available = self->max_ - (self->ptr_ - self->buf_);
+	int needed = (int)(sbuf->ptr_ - sbuf->buf_);
+
+	if( needed >= available )
+	{
+		int off = (int)(self->ptr_ - self->buf_);
+		self->max_ += needed;
+		self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+		self->ptr_ = self->buf_ + off;
+	}
+
+	memcpy(self->ptr_, sbuf->buf_, needed);
+	self->ptr_ += needed;
+	return (int)(self->ptr_ - self->buf_);
+}
+
+// Appends str to the StringBuf
+int StringBuf_AppendStr(StringBuf* self, const char* str) 
+{
+	int available = self->max_ - (self->ptr_ - self->buf_);
+	int needed = (int)strlen(str);
+
+	if( needed >= available )
+	{// not enough space, expand the buffer (minimum expansion = 1024)
+		int off = (int)(self->ptr_ - self->buf_);
+		self->max_ += max(needed, 1024);
+		self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1);
+		self->ptr_ = self->buf_ + off;
+	}
+
+	memcpy(self->ptr_, str, needed);
+	self->ptr_ += needed;
+	return (int)(self->ptr_ - self->buf_);
+}
+
+// Returns the length of the data in the Stringbuf
+int StringBuf_Length(StringBuf* self) 
+{
+	return (int)(self->ptr_ - self->buf_);
+}
+
+/// Returns the data in the StringBuf
+char* StringBuf_Value(StringBuf* self) 
+{
+	*self->ptr_ = '\0';
+	return self->buf_;
+}
+
+/// Clears the contents of the StringBuf
+void StringBuf_Clear(StringBuf* self) 
+{
+	self->ptr_ = self->buf_;
+}
+
+/// Destroys the StringBuf
+void StringBuf_Destroy(StringBuf* self)
+{
+	aFree(self->buf_);
+	self->ptr_ = self->buf_ = 0;
+	self->max_ = 0;
+}
+
+// Frees a StringBuf returned by StringBuf_Malloc
+void StringBuf_Free(StringBuf* self) 
+{
+	StringBuf_Destroy(self);
+	aFree(self);
+}

+ 22 - 0
src/common/strlib.h

@@ -7,6 +7,7 @@
 #ifndef _CBASETYPES_H_
 #ifndef _CBASETYPES_H_
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
 #endif
 #endif
+#include <stdarg.h>
 
 
 char* jstrescape (char* pt);
 char* jstrescape (char* pt);
 char* jstrescapecpy (char* pt, const char* spt);
 char* jstrescapecpy (char* pt, const char* spt);
@@ -33,4 +34,25 @@ int config_switch(const char* str);
 /// always nul-terminates the string
 /// always nul-terminates the string
 char* safestrncpy(char* dst, const char* src, size_t n);
 char* safestrncpy(char* dst, const char* src, size_t n);
 
 
+/// StringBuf - dynamic string
+struct StringBuf
+{
+	char *buf_;
+	char *ptr_;
+	unsigned int max_;
+};
+typedef struct StringBuf StringBuf;
+
+StringBuf* StringBuf_Malloc(void);
+void StringBuf_Init(StringBuf* self);
+int StringBuf_Printf(StringBuf* self, const char* fmt, ...);
+int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list args);
+int StringBuf_Append(StringBuf* self, const StringBuf *sbuf);
+int StringBuf_AppendStr(StringBuf* self, const char* str);
+int StringBuf_Length(StringBuf* self);
+char* StringBuf_Value(StringBuf* self);
+void StringBuf_Clear(StringBuf* self);
+void StringBuf_Destroy(StringBuf* self);
+void StringBuf_Free(StringBuf* self);
+
 #endif /* _STRLIB_H_ */
 #endif /* _STRLIB_H_ */

+ 25 - 129
src/common/utils.c

@@ -55,118 +55,6 @@ void dump(FILE* fp, const unsigned char* buffer, int length)
 	fprintf(fp, "\n");
 	fprintf(fp, "\n");
 }
 }
 
 
-// Allocate a StringBuf  [MouseJstr]
-struct StringBuf * StringBuf_Malloc() 
-{
-	struct StringBuf * ret = (struct StringBuf *) aMallocA(sizeof(struct StringBuf));
-	StringBuf_Init(ret);
-	return ret;
-}
-
-// Initialize a previously allocated StringBuf [MouseJstr]
-void StringBuf_Init(struct StringBuf * sbuf)  {
-	sbuf->max_ = 1024;
-	sbuf->ptr_ = sbuf->buf_ = (char *) aMallocA(sbuf->max_ + 1);
-}
-
-// vprintf into a StringBuf, moving the pointer [MouseJstr]
-int StringBuf_Vprintf(struct StringBuf *sbuf,const char *fmt,va_list ap) 
-{
-	int n, size, off;
-
-	while (1) {
-		/* Try to print in the allocated space. */
-		size = sbuf->max_ - (sbuf->ptr_ - sbuf->buf_);
-		n = vsnprintf (sbuf->ptr_, size, fmt, ap);
-		/* If that worked, return the length. */
-		if (n > -1 && n < size) {
-			sbuf->ptr_ += n;
-			return (int)(sbuf->ptr_ - sbuf->buf_);
-		}
-		/* Else try again with more space. */
-		sbuf->max_ *= 2; // twice the old size
-		off = (int)(sbuf->ptr_ - sbuf->buf_);
-		sbuf->buf_ = (char *) aRealloc(sbuf->buf_, sbuf->max_ + 1);
-		sbuf->ptr_ = sbuf->buf_ + off;
-	}
-}
-
-// printf into a StringBuf, moving the pointer [MouseJstr]
-int StringBuf_Printf(struct StringBuf *sbuf,const char *fmt,...) 
-{
-	int len;
-	va_list ap;
-
-	va_start(ap,fmt);
-	len = StringBuf_Vprintf(sbuf,fmt,ap);
-	va_end(ap);
-
-	return len;
-}
-
-// Append buf2 onto the end of buf1 [MouseJstr]
-int StringBuf_Append(struct StringBuf *buf1,const struct StringBuf *buf2) 
-{
-	int buf1_avail = buf1->max_ - (buf1->ptr_ - buf1->buf_);
-	int size2 = (int)(buf2->ptr_ - buf2->buf_);
-
-	if (size2 >= buf1_avail)  {
-		int off = (int)(buf1->ptr_ - buf1->buf_);
-		buf1->max_ += size2;
-		buf1->buf_ = (char *) aRealloc(buf1->buf_, buf1->max_ + 1);
-		buf1->ptr_ = buf1->buf_ + off;
-	}
-
-	memcpy(buf1->ptr_, buf2->buf_, size2);
-	buf1->ptr_ += size2;
-	return (int)(buf1->ptr_ - buf1->buf_);
-}
-
-// Appends str onto the end of buf
-int StringBuf_AppendStr(struct StringBuf* sbuf, const char* str) 
-{
-	int available = sbuf->max_ - (sbuf->ptr_ - sbuf->buf_);
-	int size = (int)strlen(str);
-
-	if( size >= available )
-	{// not enough space, expand the buffer (minimum expansion = 1024)
-		int off = (int)(sbuf->ptr_ - sbuf->buf_);
-		sbuf->max_ += max(size, 1024);
-		sbuf->buf_ = (char *) aRealloc(sbuf->buf_, sbuf->max_ + 1);
-		sbuf->ptr_ = sbuf->buf_ + off;
-	}
-
-	memcpy(sbuf->ptr_, str, size);
-	sbuf->ptr_ += size;
-	return (int)(sbuf->ptr_ - sbuf->buf_);
-}
-
-// Returns the length of the data in a Stringbuf
-int StringBuf_Length(struct StringBuf *sbuf) 
-{
-	return (int)(sbuf->ptr_ - sbuf->buf_);
-}
-
-// Destroy a StringBuf [MouseJstr]
-void StringBuf_Destroy(struct StringBuf *sbuf) 
-{
-	aFree(sbuf->buf_);
-	sbuf->ptr_ = sbuf->buf_ = 0;
-}
-
-// Free a StringBuf returned by StringBuf_Malloc [MouseJstr]
-void StringBuf_Free(struct StringBuf *sbuf) 
-{
-	StringBuf_Destroy(sbuf);
-	aFree(sbuf);
-}
-
-// Return the built string from the StringBuf [MouseJstr]
-char * StringBuf_Value(struct StringBuf *sbuf) 
-{
-	*sbuf->ptr_ = '\0';
-	return sbuf->buf_;
-}
 
 
 #ifdef WIN32
 #ifdef WIN32
 
 
@@ -293,35 +181,43 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
 }
 }
 #endif
 #endif
 
 
-uint8 GetByte(uint32 val, size_t num)
+uint8 GetByte(uint32 val, int idx)
 {
 {
-	switch( num )
+	switch( idx )
 	{
 	{
-	case 0:  return (uint8)((val & 0x000000FF)        );
-	case 1:	 return (uint8)((val & 0x0000FF00) >> 0x08);
-	case 2:	 return (uint8)((val & 0x00FF0000) >> 0x10);
-	case 3:	 return (uint8)((val & 0xFF000000) >> 0x18);
-	default: return 0;	//better throw something here
+	case 0: return (uint8)( (val & 0x000000FF)         );
+	case 1: return (uint8)( (val & 0x0000FF00) >> 0x08 );
+	case 2: return (uint8)( (val & 0x00FF0000) >> 0x10 );
+	case 3: return (uint8)( (val & 0xFF000000) >> 0x18 );
+	default:
+#if defined(DEBUG)
+		ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
+#endif
+		return 0;
 	}
 	}
 }
 }
-uint16 GetWord(uint32 val, size_t num)
+
+uint16 GetWord(uint32 val, int idx)
 {
 {
-	switch( num )
+	switch( idx )
 	{
 	{
-	case 0:  return (uint16)((val & 0x0000FFFF)        );
-	case 1:  return (uint16)((val & 0xFFFF0000) >> 0x10);
-	default: return 0;	//better throw something here
+	case 0: return (uint16)( (val & 0x0000FFFF)         );
+	case 1: return (uint16)( (val & 0xFFFF0000) >> 0x10 );
+	default:
+#if defined(DEBUG)
+		ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
+#endif
+		return 0;
 	}
 	}
 }
 }
 uint16 MakeWord(uint8 byte0, uint8 byte1)
 uint16 MakeWord(uint8 byte0, uint8 byte1)
 {
 {
-	return
-		((uint16)(byte0        ))|
-		((uint16)(byte1 << 0x08));
+	return byte0 | (byte1 << 0x08);
 }
 }
+
 uint32 MakeDWord(uint16 word0, uint16 word1)
 uint32 MakeDWord(uint16 word0, uint16 word1)
 {
 {
 	return
 	return
-		((uint32)(word0        ))|
-		((uint32)(word1 << 0x10));
+		( (uint32)(word0        ) )|
+		( (uint32)(word1 << 0x10) );
 }
 }

+ 7 - 21
src/common/utils.h

@@ -4,29 +4,15 @@
 #ifndef _UTILS_H_
 #ifndef _UTILS_H_
 #define _UTILS_H_
 #define _UTILS_H_
 
 
-#include <stdio.h>
-#include <stdarg.h>
+#ifndef _CBASETYPES_H_
+#include "../common/cbasetypes.h"
+#endif
+
+#include <stdio.h> // FILE*
 
 
 // generate a hex dump of the first 'length' bytes of 'buffer'
 // generate a hex dump of the first 'length' bytes of 'buffer'
 void dump(FILE* fp, const unsigned char* buffer, int length);
 void dump(FILE* fp, const unsigned char* buffer, int length);
 
 
-struct StringBuf {
-	char *buf_;
-	char *ptr_;
-	unsigned int max_;
-};
-
-struct StringBuf * StringBuf_Malloc(void);
-void StringBuf_Init(struct StringBuf *);
-int StringBuf_Vprintf(struct StringBuf *,const char *,va_list);
-int StringBuf_Printf(struct StringBuf *,const char *,...);
-int StringBuf_Append(struct StringBuf *,const struct StringBuf *);
-int StringBuf_AppendStr(struct StringBuf* sbuf, const char* str);
-int StringBuf_Length(struct StringBuf* sbuf);
-char * StringBuf_Value(struct StringBuf *);
-void StringBuf_Destroy(struct StringBuf *);
-void StringBuf_Free(struct StringBuf *);
-
 void findfile(const char *p, const char *pat, void (func)(const char*));
 void findfile(const char *p, const char *pat, void (func)(const char*));
 
 
 //Caps values to min/max
 //Caps values to min/max
@@ -36,8 +22,8 @@ void findfile(const char *p, const char *pat, void (func)(const char*));
 // byte word dword access [Shinomori]
 // byte word dword access [Shinomori]
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
 
-extern uint8 GetByte(uint32 val, size_t num);
-extern uint16 GetWord(uint32 val, size_t num);
+extern uint8 GetByte(uint32 val, int idx);
+extern uint16 GetWord(uint32 val, int idx);
 extern uint16 MakeWord(uint8 byte0, uint8 byte1);
 extern uint16 MakeWord(uint8 byte0, uint8 byte1);
 extern uint32 MakeDWord(uint16 word0, uint16 word1);
 extern uint32 MakeDWord(uint16 word0, uint16 word1);
 
 

+ 0 - 18
src/ladmin/Makefile

@@ -1,18 +0,0 @@
-all txt sql: ladmin
-
-COMMON_OBJ = ../common/obj/minicore.o ../common/obj/minisocket.o ../common/obj/timer.o \
-	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o \
-	../common/obj/utils.o ../common/obj/md5calc.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
-	../common/version.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h \
-	../common/utils.h ../common/md5calc.h
-
-ladmin: ladmin.o $(COMMON_OBJ)
-	$(CC) -o ../../$@ ladmin.o $(COMMON_OBJ) $(LIB_S)
-
-clean:
-	rm -f *.o ../../ladmin GNUmakefile
-
-# DO NOT DELETE
-
-ladmin.o: ladmin.c ladmin.h $(COMMON_H)

+ 31 - 0
src/ladmin/Makefile.in

@@ -0,0 +1,31 @@
+COMMON_OBJ = ../common/obj/minicore.o ../common/obj/minisocket.o ../common/obj/timer.o \
+	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o \
+	../common/obj/utils.o ../common/obj/md5calc.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
+	../common/version.h ../common/malloc.h ../common/showmsg.h ../common/strlib.h \
+	../common/utils.h ../common/md5calc.h
+
+#####################################################################
+.PHONY : all ladmin clean help
+
+all: ladmin
+
+ladmin: ladmin.o $(COMMON_OBJ)
+	@CC@ @LDFLAGS@ -o ../../ladmin@EXEEXT@ ladmin.o $(COMMON_OBJ) @LIBS@
+
+clean:
+	rm -f *.o ../../ladmin@EXEEXT@
+
+help:
+	@echo "possible targets are 'ladmin' 'all' 'clean' 'help'"
+	@echo "'ladmin'  - remote administration tool"
+	@echo "'all'     - builds all above targets"
+	@echo "'clean'   - cleans builds and objects"
+	@echo "'help'    - outputs this message"
+
+#####################################################################
+
+# DO NOT DELETE
+
+ladmin.o: ladmin.c ladmin.h $(COMMON_H)
+	@CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<

+ 0 - 25
src/login/Makefile

@@ -1,25 +0,0 @@
-all txt: login-server
-
-COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
-	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
-	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
-	../common/obj/strlib.o ../common/obj/grfio.o \
-	../common/obj/mapindex.o ../common/obj/ers.o ../common/obj/md5calc.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
-	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
-	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
-	../common/grfio.h ../common/mapindex.h \
-	../common/md5calc.h
-
-%.o: %.c
-	$(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $<
-
-login-server: login.o $(COMMON_OBJ)
-	$(CC) -o ../../$@ login.o $(COMMON_OBJ) $(LIB_S)
-	
-clean:
-	rm -f *.o ../../login-server GNUmakefile
-
-# DO NOT DELETE
-
-login.o: login.c login.h $(COMMON_H)

+ 35 - 0
src/login/Makefile.in

@@ -0,0 +1,35 @@
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
+	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
+	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
+	../common/obj/strlib.o ../common/obj/grfio.o ../common/obj/mapindex.o \
+	../common/obj/ers.o ../common/obj/md5calc.o
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
+	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
+	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
+	../common/grfio.h ../common/mapindex.h \
+	../common/ers.h ../common/md5calc.h
+
+#####################################################################
+.PHONY : all login-server clean help
+
+all: login-server
+
+login-server: login.o $(COMMON_OBJ)
+	@CC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ login.o $(COMMON_OBJ) @LIBS@ 
+
+clean:
+	rm -f *.o ../../login-server@EXEEXT@
+
+help:
+	@echo "possible targets are 'login-server' 'all' 'clean' 'help'"
+	@echo "'login-server'  - login server (TXT version)"
+	@echo "'all'           - builds all above targets"
+	@echo "'clean'         - cleans builds and objects"
+	@echo "'help'          - outputs this message"
+
+#####################################################################
+
+# DO NOT DELETE
+
+login.o: login.c login.h $(COMMON_H)
+	@CC@ @CFLAGS@ -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<

+ 144 - 156
src/login/login.c

@@ -2,6 +2,7 @@
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
 #include "../common/cbasetypes.h"
 #include "../common/cbasetypes.h"
+#include "../common/mmo.h"
 #include "../common/core.h"
 #include "../common/core.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
 #include "../common/db.h"
 #include "../common/db.h"
@@ -9,7 +10,6 @@
 #include "../common/lock.h"
 #include "../common/lock.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
-#include "../common/mmo.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/version.h"
 #include "../common/version.h"
 #include "../common/md5calc.h"
 #include "../common/md5calc.h"
@@ -17,10 +17,8 @@
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
-#include <sys/stat.h> // for stat/lstat/fstat
-#include <signal.h>
-#include <fcntl.h>
 #include <string.h>
 #include <string.h>
+#include <sys/stat.h> // for stat/lstat/fstat
 
 
 uint32 account_id_count = START_ACCOUNT_NUM;
 uint32 account_id_count = START_ACCOUNT_NUM;
 bool new_account_flag = true;
 bool new_account_flag = true;
@@ -1092,20 +1090,18 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email)
 		account_id_count++;
 		account_id_count++;
 
 
 	auth_dat[i].account_id = account_id_count++;
 	auth_dat[i].account_id = account_id_count++;
-	strncpy(auth_dat[i].userid, account->userid, NAME_LENGTH); auth_dat[i].userid[23] = '\0';
-	if (use_md5_passwds) {
+	safestrncpy(auth_dat[i].userid, account->userid, NAME_LENGTH);
+	if( use_md5_passwds )
 		MD5_String(account->passwd, auth_dat[i].pass);
 		MD5_String(account->passwd, auth_dat[i].pass);
-	} else {
-		strncpy(auth_dat[i].pass, account->passwd, NAME_LENGTH); auth_dat[i].pass[23] = '\0';
-	}
-	memcpy(auth_dat[i].lastlogin, "-", 2);
+	else
+		safestrncpy(auth_dat[i].pass, account->passwd, NAME_LENGTH);
+	safestrncpy(auth_dat[i].lastlogin, "-", sizeof(auth_dat[i].lastlogin));
 	auth_dat[i].sex = (sex == 'M' || sex == 'm');
 	auth_dat[i].sex = (sex == 'M' || sex == 'm');
 	auth_dat[i].logincount = 0;
 	auth_dat[i].logincount = 0;
 	auth_dat[i].state = 0;
 	auth_dat[i].state = 0;
-	strncpy(auth_dat[i].email, e_mail_check(email) ? email : "a@a.com", 40);
-	strncpy(auth_dat[i].error_message, "-", 20);
+	safestrncpy(auth_dat[i].email, e_mail_check(email) ? email : "a@a.com", sizeof(auth_dat[i].email));
+	safestrncpy(auth_dat[i].error_message, "-", sizeof(auth_dat[i].error_message));
 	auth_dat[i].ban_until_time = 0;
 	auth_dat[i].ban_until_time = 0;
-
 	if (start_limited_time < 0)
 	if (start_limited_time < 0)
 		auth_dat[i].connect_until_time = 0; // unlimited
 		auth_dat[i].connect_until_time = 0; // unlimited
 	else { // limited time
 	else { // limited time
@@ -1128,9 +1124,9 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email)
 	return (account_id_count - 1);
 	return (account_id_count - 1);
 }
 }
 
 
-//---------------------------------------
+//-----------------------------------------------------
 // Check/authentication of a connection
 // Check/authentication of a connection
-//---------------------------------------
+//-----------------------------------------------------
 int mmo_auth(struct mmo_account* account, int fd)
 int mmo_auth(struct mmo_account* account, int fd)
 {
 {
 	unsigned int i;
 	unsigned int i;
@@ -1138,14 +1134,14 @@ int mmo_auth(struct mmo_account* account, int fd)
 	char tmpstr[256];
 	char tmpstr[256];
 	int len;
 	int len;
 	int newaccount = 0;
 	int newaccount = 0;
-	char user_password[256];
+	char user_password[32+1]; // reserve for md5-ed pw
 
 
 	char ip[16];
 	char ip[16];
 	uint8* sin_addr = (uint8*)&session[fd]->client_addr;
 	uint8* sin_addr = (uint8*)&session[fd]->client_addr;
 	sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
 	sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
 
 
 	// DNS Blacklist check
 	// DNS Blacklist check
-	if(use_dnsbl)
+	if( use_dnsbl )
 	{
 	{
 		char r_ip[16];
 		char r_ip[16];
 		char ip_dnsbl[256];
 		char ip_dnsbl[256];
@@ -1154,31 +1150,34 @@ int mmo_auth(struct mmo_account* account, int fd)
 
 
 		sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
 		sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
 
 
-		for (dnsbl_serv = strtok(dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,","))
+		for( dnsbl_serv = strtok(dnsbl_servs,","); !matched && dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",") )
 		{
 		{
-			if (!matched) {
-				sprintf(ip_dnsbl, "%s.%s", r_ip, dnsbl_serv);
-				if(host2ip(ip_dnsbl))
-					matched = true;
-			}
+			sprintf(ip_dnsbl, "%s.%s", r_ip, dnsbl_serv);
+			if( host2ip(ip_dnsbl) )
+				matched = true;
 		}
 		}
 
 
-		if (matched) {
+		if( matched )
+		{
 			ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip);
 			ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip);
 			return 3;
 			return 3;
 		}
 		}
 	}
 	}
 
 
+	//Client Version check
+	if( check_client_version && account->version != 0 &&
+		account->version != client_version_to_connect )
+		return 5;
 
 
-	len = strlen(account->userid) - 2;
+	len = strnlen(account->userid, NAME_LENGTH);
 
 
 	// Account creation with _M/_F
 	// Account creation with _M/_F
-	if (new_account_flag)
+	if( new_account_flag )
 	{
 	{
-		if (account->passwdenc == 0 && account->userid[len] == '_' &&
-			(account->userid[len+1] == 'F' || account->userid[len+1] == 'M' ||
-			account->userid[len+1] == 'f' || account->userid[len+1] == 'm') &&
-			account_id_count <= END_ACCOUNT_NUM && len >= 4 && strlen(account->passwd) >= 4)
+		if( len > 2 && strnlen(account->passwd, NAME_LENGTH) >= 4 && // valid user and password lengths
+			account->passwdenc == 0 && // unencoded password
+			account->userid[len-2] == '_' && memchr("FfMm", (unsigned char)account->userid[len-1], 4) && // _M/_F suffix
+			account_id_count <= END_ACCOUNT_NUM )
 		{
 		{
 			//only continue if amount in this time limit is allowed (account registration flood protection)[Kevin]
 			//only continue if amount in this time limit is allowed (account registration flood protection)[Kevin]
 			if(DIFF_TICK(gettick(), new_reg_tick) < 0 && num_regs >= allowed_regs) {
 			if(DIFF_TICK(gettick(), new_reg_tick) < 0 && num_regs >= allowed_regs) {
@@ -1187,20 +1186,13 @@ int mmo_auth(struct mmo_account* account, int fd)
 				return 3;
 				return 3;
 			}
 			}
 			newaccount = 1;
 			newaccount = 1;
-			account->userid[len] = '\0';
+			account->userid[len-2] = '\0';
 		}
 		}
 	}
 	}
 	
 	
-	//Client Version check
-	if (check_client_version && account->version != 0 &&
-		account->version != client_version_to_connect)
-		return 5;
-	
 	// Strict account search
 	// Strict account search
-	for(i = 0; i < auth_num; i++) {
-		if (strcmp(account->userid, auth_dat[i].userid) == 0)
-			break;
-	}
+	ARR_FIND(0, auth_num, i, strcmp(account->userid, auth_dat[i].userid) == 0);
+
 	// if there is no creation request and strict account search fails, we do a no sensitive case research for index
 	// if there is no creation request and strict account search fails, we do a no sensitive case research for index
 	if (!newaccount && i == auth_num) {
 	if (!newaccount && i == auth_num) {
 		i = search_account_index(account->userid);
 		i = search_account_index(account->userid);
@@ -1210,28 +1202,47 @@ int mmo_auth(struct mmo_account* account, int fd)
 			memcpy(account->userid, auth_dat[i].userid, NAME_LENGTH); // for the possible tests/checks afterwards (copy correcte sensitive case).
 			memcpy(account->userid, auth_dat[i].userid, NAME_LENGTH); // for the possible tests/checks afterwards (copy correcte sensitive case).
 	}
 	}
 
 
-	if (i != auth_num) {
-		if (newaccount) {
-			login_log("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s, ip: %s)\n",
-			          account->userid, account->userid[len+1], auth_dat[i].pass, account->passwd, ip);
+	if( i != auth_num )
+	{
+		if (newaccount)
+		{
+			login_log("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s, ip: %s)\n", account->userid, account->userid[len-1], auth_dat[i].pass, account->passwd, ip);
 			return 1; // 1 = Incorrect Password
 			return 1; // 1 = Incorrect Password
 		}
 		}
 
 
-		if(use_md5_passwds)
+		if( use_md5_passwds )
 			MD5_String(account->passwd, user_password);
 			MD5_String(account->passwd, user_password);
 		else
 		else
-			memcpy(user_password, account->passwd, NAME_LENGTH);
+			safestrncpy(user_password, account->passwd, NAME_LENGTH);
 
 
-		if (!check_password(session[fd]->session_data, account->passwdenc, user_password, auth_dat[i].pass))
+		if( !check_password(session[fd]->session_data, account->passwdenc, user_password, auth_dat[i].pass) )
 		{
 		{
-			login_log("Invalid password (account: %s, pass: %s, received pass: %s, ip: %s)\n",
-			          account->userid, auth_dat[i].pass, (account->passwdenc) ? "[MD5]" : account->passwd, ip);
+			login_log("Invalid password (account: %s, pass: %s, received pass: %s, ip: %s)\n", account->userid, auth_dat[i].pass, (account->passwdenc) ? "[MD5]" : account->passwd, ip);
 			return 1; // 1 = Incorrect Password
 			return 1; // 1 = Incorrect Password
 		}
 		}
 
 
-		if (auth_dat[i].state) {
-			login_log("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n",
-			          account->userid, account->passwd, auth_dat[i].state, ip);
+		if( auth_dat[i].connect_until_time != 0 && auth_dat[i].connect_until_time < time(NULL) )
+		{
+			login_log("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", account->userid, account->passwd, ip);
+			return 2; // 2 = This ID is expired
+		}
+
+		if( auth_dat[i].ban_until_time != 0 )
+		{	// account is banned
+			strftime(tmpstr, 20, date_format, localtime(&auth_dat[i].ban_until_time));
+			tmpstr[19] = '\0';
+			if( auth_dat[i].ban_until_time > time(NULL) ) { // always banned
+				login_log("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", account->userid, account->passwd, tmpstr, ip);
+				return 6; // 6 = Your are Prohibited to log in until %s
+			} else { // ban is over
+				login_log("End of ban (account: %s, pass: %s, previously banned until %s -> not more banned, ip: %s)\n", account->userid, account->passwd, tmpstr, ip);
+				auth_dat[i].ban_until_time = 0; // reset the ban time
+			}
+		}
+
+		if( auth_dat[i].state )
+		{
+			login_log("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", account->userid, account->passwd, auth_dat[i].state, ip);
 			switch(auth_dat[i].state) { // packet 0x006a value + 1
 			switch(auth_dat[i].state) { // packet 0x006a value + 1
 			case 1: // 0 = Unregistered ID
 			case 1: // 0 = Unregistered ID
 			case 2: // 1 = Incorrect Password
 			case 2: // 1 = Incorrect Password
@@ -1261,55 +1272,38 @@ int mmo_auth(struct mmo_account* account, int fd)
 			}
 			}
 		}
 		}
 
 
-		if (online_check) {
+		if( online_check )
+		{
 			struct online_login_data* data = idb_get(online_db,auth_dat[i].account_id);
 			struct online_login_data* data = idb_get(online_db,auth_dat[i].account_id);
-			if (data && data->char_server > -1) {
+			if( data && data->char_server > -1 )
+			{
 				//Request char servers to kick this account out. [Skotlex]
 				//Request char servers to kick this account out. [Skotlex]
 				unsigned char buf[8];
 				unsigned char buf[8];
 				ShowNotice("User [%d] is already online - Rejected.\n",auth_dat[i].account_id);
 				ShowNotice("User [%d] is already online - Rejected.\n",auth_dat[i].account_id);
 				WBUFW(buf,0) = 0x2734;
 				WBUFW(buf,0) = 0x2734;
 				WBUFL(buf,2) = auth_dat[i].account_id;
 				WBUFL(buf,2) = auth_dat[i].account_id;
 				charif_sendallwos(-1, buf, 6);
 				charif_sendallwos(-1, buf, 6);
-				if (data->waiting_disconnect == -1)
+				if( data->waiting_disconnect == -1 )
 					data->waiting_disconnect = add_timer(gettick()+30000, waiting_disconnect_timer, auth_dat[i].account_id, 0);
 					data->waiting_disconnect = add_timer(gettick()+30000, waiting_disconnect_timer, auth_dat[i].account_id, 0);
 				return 3; // Rejected
 				return 3; // Rejected
 			}
 			}
 		}
 		}
-
-		if (auth_dat[i].ban_until_time != 0) { // if account is banned
-			strftime(tmpstr, 20, date_format, localtime(&auth_dat[i].ban_until_time));
-			tmpstr[19] = '\0';
-			if (auth_dat[i].ban_until_time > time(NULL)) { // always banned
-				login_log("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n",
-				          account->userid, account->passwd, tmpstr, ip);
-				return 6; // 6 = Your are Prohibited to log in until %s
-			} else { // ban is finished
-				login_log("End of ban (account: %s, pass: %s, previously banned until %s -> not more banned, ip: %s)\n",
-				          account->userid, account->passwd, tmpstr, ip);
-				auth_dat[i].ban_until_time = 0; // reset the ban time
-			}
-		}
-
-		if (auth_dat[i].connect_until_time != 0 && auth_dat[i].connect_until_time < time(NULL)) {
-			login_log("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n",
-			          account->userid, account->passwd, ip);
-			return 2; // 2 = This ID is expired
-		}
-
-		login_log("Authentification accepted (account: %s (id: %d), ip: %s)\n", account->userid, auth_dat[i].account_id, ip);
-	} else {
-		if (!newaccount) {
-			login_log("Unknown account (account: %s, received pass: %s, ip: %s)\n",
-			          account->userid, account->passwd, ip);
+	}
+	else
+	{
+		if( !newaccount )
+		{
+			login_log("Unknown account (account: %s, received pass: %s, ip: %s)\n", account->userid, account->passwd, ip);
 			return 0; // 0 = Unregistered ID
 			return 0; // 0 = Unregistered ID
-		} else {
-			int new_id = mmo_auth_new(account, account->userid[len+1], "a@a.com");
+		}
+		else
+		{
+			int new_id = mmo_auth_new(account, account->userid[len-1], "a@a.com");
 			unsigned int tick = gettick();
 			unsigned int tick = gettick();
-			login_log("Account creation and authentification accepted (account %s (id: %d), pass: %s, sex: %c, connection with _F/_M, ip: %s)\n",
-			          account->userid, new_id, account->passwd, account->userid[len+1], ip);
+			login_log("Account creation and authentification accepted (account %s (id: %d), pass: %s, sex: %c, connection with _F/_M, ip: %s)\n", account->userid, new_id, account->passwd, account->userid[len-1], ip);
 			auth_before_save_file = 0; // Creation of an account -> save accounts file immediatly
 			auth_before_save_file = 0; // Creation of an account -> save accounts file immediatly
 			
 			
-			if(DIFF_TICK(tick, new_reg_tick) > 0)
+			if( DIFF_TICK(tick, new_reg_tick) > 0 )
 			{	//Update the registration check.
 			{	//Update the registration check.
 				num_regs = 0;
 				num_regs = 0;
 				new_reg_tick=tick +time_allowed*1000;
 				new_reg_tick=tick +time_allowed*1000;
@@ -1318,6 +1312,8 @@ int mmo_auth(struct mmo_account* account, int fd)
 		}
 		}
 	}
 	}
 
 
+	login_log("Authentification accepted (account: %s (id: %d), ip: %s)\n", account->userid, auth_dat[i].account_id, ip);
+
 	// auth start : time seed
 	// auth start : time seed
 	// Platform/Compiler dependant clock() for time check is removed. [Lance]
 	// Platform/Compiler dependant clock() for time check is removed. [Lance]
 	// clock() is originally used to track processing ticks on program execution.
 	// clock() is originally used to track processing ticks on program execution.
@@ -1327,13 +1323,14 @@ int mmo_auth(struct mmo_account* account, int fd)
 	account->account_id = auth_dat[i].account_id;
 	account->account_id = auth_dat[i].account_id;
 	account->login_id1 = rand();
 	account->login_id1 = rand();
 	account->login_id2 = rand();
 	account->login_id2 = rand();
-	memcpy(account->lastlogin, auth_dat[i].lastlogin, 24);
-	memcpy(auth_dat[i].lastlogin, tmpstr, 24);
+	safestrncpy(account->lastlogin, auth_dat[i].lastlogin, 24);
 	account->sex = auth_dat[i].sex;
 	account->sex = auth_dat[i].sex;
-	if (account->sex != 2 && account->account_id < START_ACCOUNT_NUM)
+
+	if( account->sex != 2 && account->account_id < START_ACCOUNT_NUM )
 		ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", account->userid, account->account_id, START_ACCOUNT_NUM);
 		ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", account->userid, account->account_id, START_ACCOUNT_NUM);
 
 
-	strncpy(auth_dat[i].last_ip, ip, 16);
+	safestrncpy(auth_dat[i].lastlogin, tmpstr, sizeof(auth_dat[i].lastlogin));
+	safestrncpy(auth_dat[i].last_ip, ip, sizeof(auth_dat[i].last_ip));
 	auth_dat[i].logincount++;
 	auth_dat[i].logincount++;
 
 
 	// Save until for change ip/time of auth is not very useful => limited save for that
 	// Save until for change ip/time of auth is not very useful => limited save for that
@@ -2952,14 +2949,8 @@ int parse_admin(int fd)
 int lan_subnetcheck(uint32 ip)
 int lan_subnetcheck(uint32 ip)
 {
 {
 	int i;
 	int i;
-
-	for(i = 0; i < subnet_count; i++) {
-		if(subnet[i].subnet == (ip & subnet[i].mask)) {
-			return subnet[i].char_ip;
-		}
-	}
-
-	return 0;
+	ARR_FIND( 0, subnet_count, i, subnet[i].subnet == (ip & subnet[i].mask) );
+	return ( i < subnet_count ) ? subnet[i].char_ip : 0;
 }
 }
 
 
 //----------------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------------
@@ -3175,61 +3166,56 @@ int parse_login(int fd)
 		case 0x2710:	// Connection request of a char-server
 		case 0x2710:	// Connection request of a char-server
 			if (RFIFOREST(fd) < 86)
 			if (RFIFOREST(fd) < 86)
 				return 0;
 				return 0;
+		{
+			char* server_name;
+			uint32 server_ip;
+			uint16 server_port;
+			
+			memset(&account, 0, sizeof(account));
+			safestrncpy(account.userid, RFIFOP(fd,2), NAME_LENGTH); remove_control_chars(account.userid);
+			safestrncpy(account.passwd, RFIFOP(fd,26), NAME_LENGTH); remove_control_chars(account.passwd);
+			account.passwdenc = 0;
+			server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0'; remove_control_chars(server_name);
+			server_ip = ntohl(RFIFOL(fd, 54));
+			server_port = ntohs(RFIFOW(fd, 58));
+			
+			ShowInfo("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, account.userid, account.passwd, ip);
+			login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (account: '%s', pass: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, account.userid, account.passwd, ip);
+			
+			result = mmo_auth(&account, fd);
+			if( result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1 )
 			{
 			{
-				char* server_name;
-				uint32 server_ip;
-				uint16 server_port;
-
-				memset(&account, 0, sizeof(account));
-				memcpy(account.userid, RFIFOP(fd,2), NAME_LENGTH); account.userid[23] = '\0'; remove_control_chars(account.userid);
-				memcpy(account.passwd, RFIFOP(fd,26), NAME_LENGTH); account.passwd[23] = '\0'; remove_control_chars(account.passwd);
-				account.passwdenc = 0;
-				server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0'; remove_control_chars(server_name);
-				server_ip = ntohl(RFIFOL(fd, 54));
-				server_port = ntohs(RFIFOW(fd, 58));
-				login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)\n",
-				          server_name, CONVIP(server_ip), server_port, ip);
-
-				result = mmo_auth(&account, fd);
-				if (result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1) {
-					login_log("Connection of the char-server '%s' accepted (account: %s, pass: %s, ip: %s)\n",
-					          server_name, account.userid, account.passwd, ip);
-					ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
-					memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
-					server[account.account_id].ip = ntohl(RFIFOL(fd,54));
-					server[account.account_id].port = ntohs(RFIFOW(fd,58));
-					memcpy(server[account.account_id].name, server_name, 20);
-					server[account.account_id].users = 0;
-					server[account.account_id].maintenance = RFIFOW(fd,82);
-					server[account.account_id].new_ = RFIFOW(fd,84);
-					server_fd[account.account_id] = fd;
-
-	 				WFIFOHEAD(fd,3);
-					WFIFOW(fd,0) = 0x2711;
-					WFIFOB(fd,2) = 0;
-					WFIFOSET(fd,3);
-
-					session[fd]->func_parse = parse_fromchar;
-					realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-					
-					send_GM_accounts(fd); // send GM account to char-server
-				} else {
-					if (server_fd[account.account_id] != -1) {
-						ShowNotice("Connection of the char-server '%s' REFUSED - already connected (account: %ld-%s, pass: %s, ip: %s)\n",
-					        server_name, account.account_id, account.userid, account.passwd, ip);
-						login_log("Connexion of the char-server '%s' REFUSED - already connected (account: %ld-%s, pass: %s, ip: %s)\n",
-					          server_name, account.account_id, account.userid, account.passwd, ip);
-					} else {
-						ShowNotice("Connection of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s).\n", server_name, account.userid, account.passwd, ip);
-						login_log("Connexion of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s)\n",
-					          	server_name, account.userid, account.passwd, ip);
-					}
-					WFIFOHEAD(fd,3);
-					WFIFOW(fd,0) = 0x2711;
-					WFIFOB(fd,2) = 3;
-					WFIFOSET(fd,3);
-				}
+				ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
+				login_log("Connection of the char-server '%s' accepted.\n", server_name);
+				memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
+				server[account.account_id].ip = ntohl(RFIFOL(fd,54));
+				server[account.account_id].port = ntohs(RFIFOW(fd,58));
+				safestrncpy(server[account.account_id].name, server_name, sizeof(server[account.account_id].name));
+				server[account.account_id].users = 0;
+				server[account.account_id].maintenance = RFIFOW(fd,82);
+				server[account.account_id].new_ = RFIFOW(fd,84);
+				server_fd[account.account_id] = fd;
+				
+ 				WFIFOHEAD(fd,3);
+				WFIFOW(fd,0) = 0x2711;
+				WFIFOB(fd,2) = 0;
+				WFIFOSET(fd,3);
+				
+				session[fd]->func_parse = parse_fromchar;
+				realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+				
+				send_GM_accounts(fd); // send GM account to char-server
+			}
+			else
+			{
+				ShowNotice("Connection of the char-server '%s' REFUSED.\n", server_name);
+				login_log("Connection of the char-server '%s' REFUSED.\n", server_name);
+				WFIFOHEAD(fd,3);
+				WFIFOW(fd,0) = 0x2711;
+				WFIFOB(fd,2) = 3;
+				WFIFOSET(fd,3);
 			}
 			}
+		}
 
 
 			RFIFOSKIP(fd,86);
 			RFIFOSKIP(fd,86);
 			return 0;
 			return 0;
@@ -3362,7 +3348,7 @@ int parse_login(int fd)
 //-----------------------
 //-----------------------
 // Console Command Parser [Wizputer]
 // Console Command Parser [Wizputer]
 //-----------------------
 //-----------------------
-int parse_console(char*buf)
+int parse_console(char* buf)
 {
 {
 	char command[256];
 	char command[256];
 
 
@@ -3377,13 +3363,15 @@ int parse_console(char*buf)
 		strcmpi("quit", command) == 0 ||
 		strcmpi("quit", command) == 0 ||
 		strcmpi("end", command) == 0 )
 		strcmpi("end", command) == 0 )
 		runflag = 0;
 		runflag = 0;
-	else if( strcmpi("alive", command) == 0 ||
-			strcmpi("status", command) == 0 )
+	else
+	if( strcmpi("alive", command) == 0 ||
+		strcmpi("status", command) == 0 )
 		ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
 		ShowInfo(CL_CYAN"Console: "CL_BOLD"I'm Alive."CL_RESET"\n");
-	else if( strcmpi("help", command) == 0 ){
+	else
+	if( strcmpi("help", command) == 0 ) {
 		printf(CL_BOLD"Help of commands:"CL_RESET"\n");
 		printf(CL_BOLD"Help of commands:"CL_RESET"\n");
 		printf("  To shutdown the server:\n");
 		printf("  To shutdown the server:\n");
-		printf("  'shutdown|exit|qui|end'\n");
+		printf("  'shutdown|exit|quit|end'\n");
 		printf("  To know if server is alive:\n");
 		printf("  To know if server is alive:\n");
 		printf("  'alive|status'\n");
 		printf("  'alive|status'\n");
 	}
 	}

+ 0 - 22
src/login_sql/Makefile

@@ -1,22 +0,0 @@
-all sql: login-server_sql
-
-COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
-	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
-	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
-	../common/obj/strlib.o ../common/obj/grfio.o \
-	../common/obj/mapindex.o ../common/obj/ers.o ../common/obj/md5calc.o
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
-	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
-	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
-	../common/grfio.h ../common/mapindex.h \
-	../common/md5calc.h
-
-login-server_sql: login.o $(COMMON_OBJ)
-	$(CC) -o ../../$@ $^ $(LIB_S)
-
-clean:
-	rm -f *.o ../../login-server_sql GNUmakefile
-
-# DO NOT DELETE
-
-login.o: login.c login.h $(COMMON_H)

+ 46 - 0
src/login_sql/Makefile.in

@@ -0,0 +1,46 @@
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
+	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
+	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \
+	../common/obj/strlib.o ../common/obj/grfio.o ../common/obj/mapindex.o \
+	../common/obj/ers.o ../common/obj/md5calc.o ../common/obj_sql/sql.o 
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \
+	../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \
+	../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
+	../common/grfio.h ../common/mapindex.h \
+	../common/ers.h ../common/md5calc.h  ../common/sql.h 
+
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	LOGIN_SERVER_SQL_DEPENDS=login.o $(COMMON_OBJ)
+else
+	LOGIN_SERVER_SQL_DEPENDS=needs_mysql
+endif
+
+#####################################################################
+.PHONY : all login-server_sql clean help
+
+all: login-server_sql
+
+login-server_sql: $(LOGIN_SERVER_SQL_DEPENDS)
+	@CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ login.o $(COMMON_OBJ) @LIBS@ @MYSQL_LIBS@
+
+clean:
+	rm -f *.o ../../login-server_sql@EXEEXT@
+
+help:
+	@echo "possible targets are 'login-server_sql' 'all' 'clean' 'help'"
+	@echo "'login-server_sql'  - login server (SQL version)"
+	@echo "'all'               - builds all above targets"
+	@echo "'clean'             - cleans builds and objects"
+	@echo "'help'              - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
+
+# DO NOT DELETE
+
+login.o: login.c login.h $(COMMON_H)
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<

File diff suppressed because it is too large
+ 322 - 326
src/login_sql/login.c


+ 0 - 103
src/map/Makefile

@@ -1,103 +0,0 @@
-all txt: txtobj map-server
-
-sql: sqlobj map-server_sql
-
-txtobj:
-	mkdir txtobj
-
-sqlobj:
-	mkdir sqlobj
-
-COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
-	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
-	../common/obj/nullpo.o ../common/obj/malloc.o ../common/obj/showmsg.o \
-	../common/obj/utils.o ../common/obj/strlib.o ../common/obj/grfio.o \
-	../common/obj/mapindex.o ../common/obj/ers.o
-
-COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/db.h \
-	../common/plugins.h ../common/lock.h ../common/nullpo.h ../common/malloc.h \
-	../common/showmsg.h ../common/utils.h ../common/strlib.h ../common/grfio.h \
-	../common/mapindex.h
-
-OBJECTS = obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/status.o obj/npc.o \
-	obj/npc_chat.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o \
-	obj/storage.o obj/skill.o obj/atcommand.o obj/charcommand.o obj/battle.o \
-	obj/intif.o obj/trade.o obj/party.o obj/vending.o obj/guild.o obj/pet.o \
-	obj/log.o obj/mail.o obj/date.o obj/irc.o obj/unit.o obj/mercenary.o \
-	$(COMMON_OBJ)
-
-map-server: $(OBJECTS:obj/%=txtobj/%)
-	$(CC) -o ../../$@ $> $(LIBS) $(LIB_S)
-
-map-server_sql: $(OBJECTS:obj/%=sqlobj/%)
-	$(CC) -o ../../$@ $> $(LIB_S)
-
-txtobj/%.o: %.c
-	$(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $<
-
-sqlobj/%.o: %.c
-	$(COMPILE.c) $(OUTPUT_OPTION) $<
-
-clean:
-	rm -rf *.o ../../map-server ../../map-server_sql sqlobj txtobj GNUmakefile
-
-# DO NOT DELETE
-
-txtobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h irc.h $(COMMON_H)
-txtobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H)
-txtobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h irc.h $(COMMON_H)
-txtobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h $(COMMON_H)
-txtobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H)
-txtobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
-txtobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
-txtobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H)
-txtobj/path.o: path.c map.h battle.h $(COMMON_H)
-txtobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H)
-txtobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h date.h irc.h $(COMMON_H)
-txtobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h irc.h $(COMMON_H)
-txtobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H)
-txtobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h date.h $(COMMON_H)
-txtobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
-txtobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H)
-txtobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H)
-txtobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h $(COMMON_H)
-txtobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H)
-txtobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h irc.h $(COMMON_H)
-txtobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H)
-txtobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H)
-txtobj/log.o: log.c log.h map.h $(COMMON_H)
-txtobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
-txtobj/date.o: date.c date.h $(COMMON_H)
-txtobj/irc.o: irc.c irc.h map.h pc.h $(COMMON_H)
-txtobj/unit.o: unit.c unit.h $(COMMON_H)
-txtobj/mercenary.o: mercenary.c mercenary.h $(COMMON_H)
-
-sqlobj/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h irc.h $(COMMON_H)
-sqlobj/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H)
-sqlobj/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_H)
-sqlobj/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h $(COMMON_H)
-sqlobj/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H)
-sqlobj/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
-sqlobj/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
-sqlobj/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H)
-sqlobj/path.o: path.c map.h battle.h $(COMMON_H)
-sqlobj/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H)
-sqlobj/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h date.h irc.h $(COMMON_H)
-sqlobj/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h irc.h $(COMMON_H)
-sqlobj/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H)
-sqlobj/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h date.h $(COMMON_H)
-sqlobj/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
-sqlobj/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H)
-sqlobj/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H)
-sqlobj/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h $(COMMON_H)
-sqlobj/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H)
-sqlobj/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h irc.h $(COMMON_H)
-sqlobj/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h irc.h $(COMMON_H)
-sqlobj/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H)
-sqlobj/mail.o: mail.c mail.h $(COMMON_H)
-sqlobj/log.o: log.c log.h map.h $(COMMON_H)
-sqlobj/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
-sqlobj/date.o: date.c date.h $(COMMON_H)
-sqlobj/irc.o: irc.c irc.h map.h pc.h $(COMMON_H)
-sqlobj/unit.o: unit.c unit.h $(COMMON_H)
-sqlobj/mercenary.o: mercenary.c mercenary.h $(COMMON_H)

+ 148 - 0
src/map/Makefile.in

@@ -0,0 +1,148 @@
+
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	ALL_DEPENDS=txt sql
+	SQL_DEPENDS=obj_sql map-server_sql
+else
+	ALL_TARGET=txt
+	SQL_DEPENDS=needs_mysql
+endif
+
+HAVE_PCRE=@HAVE_PCRE@
+ifeq ($(HAVE_PCRE),yes)
+	PCRE_CFLAGS=-DPCRE_SUPPORT @PCRE_CFLAGS@
+else
+	PCRE_CFLAGS=
+endif
+
+
+#####################################################################
+.PHONY : all txt sql clean help
+
+all: $(ALL_DEPENDS)
+
+txt: obj_txt map-server
+
+sql: $(SQL_DEPENDS)
+
+clean:
+	rm -rf *.o ../../map-server@EXEEXT@ ../../map-server_sql@EXEEXT@ obj_txt obj_sql
+
+help:
+ifeq ($(HAVE_MYSQL),yes)
+	@echo "possible targets are 'sql' 'txt' 'all' 'clean' 'help'"
+	@echo "'sql'   - map server (SQL version)"
+else
+	@echo "possible targets are 'txt' 'all' 'clean' 'help'"
+endif
+	@echo "'txt'   - map server (TXT version)"
+	@echo "'all'   - builds all above targets"
+	@echo "'clean' - cleans builds and objects"
+	@echo "'help'  - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
+
+obj_txt:
+	-mkdir obj_txt
+
+obj_sql:
+	-mkdir obj_sql
+
+COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \
+	../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \
+	../common/obj/nullpo.o ../common/obj/malloc.o ../common/obj/showmsg.o \
+	../common/obj/utils.o ../common/obj/strlib.o ../common/obj/grfio.o \
+	../common/obj/mapindex.o ../common/obj/ers.o
+
+COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h \
+	../common/db.h ../common/plugins.h ../common/lock.h \
+	../common/nullpo.h ../common/malloc.h ../common/showmsg.h \
+	../common/utils.h ../common/strlib.h ../common/grfio.h \
+	../common/mapindex.h ../common/ers.h
+
+COMMON_SQL_OBJ = $(COMMON_OBJ) ../common/obj_sql/sql.o
+
+COMMON_SQL_H = $(COMMON_H) ../common/sql.h
+
+MAP_OBJ = obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/status.o obj/npc.o \
+	obj/npc_chat.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o \
+	obj/storage.o obj/skill.o obj/atcommand.o obj/charcommand.o obj/battle.o \
+	obj/intif.o obj/trade.o obj/party.o obj/vending.o obj/guild.o obj/pet.o \
+	obj/log.o obj/mail.o obj/date.o obj/irc.o obj/unit.o obj/mercenary.o
+
+map-server: $(MAP_OBJ:obj/%=obj_txt/%) $(COMMON_OBJ)
+	@CC@ @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_OBJ:obj/%=obj_txt/%) $(COMMON_OBJ) @LIBS@ @PCRE_LIBS@
+
+map-server_sql: $(MAP_OBJ:obj/%=obj_sql/%) $(COMMON_SQL_OBJ)
+	@CC@ @LDFLAGS@ -o ../../map-server_sql@EXEEXT@ $(MAP_OBJ:obj/%=obj_sql/%) $(COMMON_SQL_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@
+
+obj_txt/%.o: %.c
+	@CC@ @CFLAGS@ $(PCRE_CFLAGS) -DTXT_ONLY @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+
+obj_sql/%.o: %.c
+	@CC@ @CFLAGS@ $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+
+# DO NOT DELETE
+
+obj_txt/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h irc.h $(COMMON_H)
+obj_txt/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_H)
+obj_txt/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h irc.h $(COMMON_H)
+obj_txt/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h $(COMMON_H)
+obj_txt/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_H)
+obj_txt/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+obj_txt/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_H)
+obj_txt/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_H)
+obj_txt/path.o: path.c map.h battle.h $(COMMON_H)
+obj_txt/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_H)
+obj_txt/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h date.h irc.h $(COMMON_H)
+obj_txt/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h irc.h $(COMMON_H)
+obj_txt/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_H)
+obj_txt/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h date.h $(COMMON_H)
+obj_txt/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
+obj_txt/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_H)
+obj_txt/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_H)
+obj_txt/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h $(COMMON_H)
+obj_txt/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_H)
+obj_txt/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h irc.h $(COMMON_H)
+obj_txt/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h $(COMMON_H)
+obj_txt/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_H)
+obj_txt/log.o: log.c log.h map.h $(COMMON_H)
+obj_txt/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_H)
+obj_txt/date.o: date.c date.h $(COMMON_H)
+obj_txt/irc.o: irc.c irc.h map.h pc.h $(COMMON_H)
+obj_txt/unit.o: unit.c unit.h $(COMMON_H)
+obj_txt/mercenary.o: mercenary.c mercenary.h $(COMMON_H)
+
+obj_sql/map.o: map.c map.h chrif.h clif.h npc.h pc.h mob.h chat.h skill.h itemdb.h storage.h party.h pet.h atcommand.h log.h irc.h $(COMMON_SQL_H)
+obj_sql/chrif.o: chrif.c map.h battle.h chrif.h clif.h intif.h pc.h npc.h $(COMMON_SQL_H)
+obj_sql/clif.o: clif.c map.h chrif.h clif.h mob.h intif.h pc.h npc.h itemdb.h chat.h script.h storage.h party.h guild.h atcommand.h pet.h charcommand.h $(COMMON_SQL_H)
+obj_sql/pc.o: pc.c map.h clif.h intif.h pc.h npc.h mob.h itemdb.h battle.h skill.h script.h party.h guild.h pet.h trade.h storage.h chat.h vending.h log.h $(COMMON_SQL_H)
+obj_sql/status.o: status.c pc.h map.h clif.h status.h mob.h itemdb.h battle.h skill.h script.h pet.h guild.h $(COMMON_SQL_H)
+obj_sql/npc.o: npc.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_SQL_H)
+obj_sql/npc_chat.o: npc_chat.c map.h npc.h clif.h pc.h script.h mob.h itemdb.h battle.h $(COMMON_SQL_H)
+obj_sql/chat.o: chat.c map.h clif.h pc.h chat.h $(COMMON_SQL_H)
+obj_sql/path.o: path.c map.h battle.h $(COMMON_SQL_H)
+obj_sql/itemdb.o: itemdb.c map.h battle.h itemdb.h $(COMMON_SQL_H)
+obj_sql/mob.o: mob.c map.h clif.h intif.h pc.h mob.h skill.h battle.h npc.h itemdb.h log.h date.h irc.h $(COMMON_SQL_H)
+obj_sql/script.o: script.c itemdb.h map.h pc.h mob.h clif.h intif.h npc.h script.h storage.h skill.h pet.h battle.h log.h irc.h $(COMMON_SQL_H)
+obj_sql/storage.o: storage.c itemdb.h pc.h clif.h intif.h storage.h guild.h $(COMMON_SQL_H)
+obj_sql/skill.o: skill.c skill.h map.h clif.h pc.h mob.h battle.h itemdb.h script.h log.h date.h $(COMMON_SQL_H)
+obj_sql/atcommand.o: atcommand.c atcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_SQL_H)
+obj_sql/battle.o: battle.c battle.h skill.h map.h mob.h pc.h pet.h guild.h $(COMMON_SQL_H)
+obj_sql/intif.o: intif.c intif.h chrif.h clif.h party.h guild.h storage.h map.h battle.h pet.h $(COMMON_SQL_H)
+obj_sql/trade.o: trade.c trade.h clif.h itemdb.h map.h pc.h npc.h log.h $(COMMON_SQL_H)
+obj_sql/party.o: party.c party.h clif.h intif.h pc.h map.h battle.h $(COMMON_SQL_H)
+obj_sql/vending.o: vending.c vending.h clif.h itemdb.h map.h pc.h log.h irc.h $(COMMON_SQL_H)
+obj_sql/guild.o: guild.c guild.h storage.h battle.h clif.h intif.h pc.h npc.h map.h irc.h $(COMMON_SQL_H)
+obj_sql/pet.o: pet.c pet.h map.h clif.h chrif.h intif.h pc.h itemdb.h battle.h mob.h npc.h script.h $(COMMON_SQL_H)
+obj_sql/mail.o: mail.c mail.h $(COMMON_SQL_H)
+obj_sql/log.o: log.c log.h map.h $(COMMON_SQL_H)
+obj_sql/charcommand.o: charcommand.c charcommand.h itemdb.h pc.h map.h skill.h clif.h mob.h intif.h battle.h storage.h guild.h pet.h log.h $(COMMON_SQL_H)
+obj_sql/date.o: date.c date.h $(COMMON_SQL_H)
+obj_sql/irc.o: irc.c irc.h map.h pc.h $(COMMON_SQL_H)
+obj_sql/unit.o: unit.c unit.h $(COMMON_SQL_H)
+obj_sql/mercenary.o: mercenary.c mercenary.h $(COMMON_SQL_H)

+ 32 - 9
src/map/atcommand.c

@@ -10,6 +10,7 @@
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "atcommand.h"
 #include "atcommand.h"
 #include "log.h"
 #include "log.h"
@@ -273,6 +274,7 @@ ACMD_FUNC(checkmail); // [Valaris]
 ACMD_FUNC(listmail); // [Valaris]
 ACMD_FUNC(listmail); // [Valaris]
 ACMD_FUNC(listnewmail); // [Valaris]
 ACMD_FUNC(listnewmail); // [Valaris]
 ACMD_FUNC(readmail); // [Valaris]
 ACMD_FUNC(readmail); // [Valaris]
+ACMD_FUNC(deletemail); // [Valaris]
 ACMD_FUNC(sendmail); // [Valaris]
 ACMD_FUNC(sendmail); // [Valaris]
 ACMD_FUNC(sendprioritymail); // [Valaris]
 ACMD_FUNC(sendprioritymail); // [Valaris]
 ACMD_FUNC(deletemail); // [Valaris]
 ACMD_FUNC(deletemail); // [Valaris]
@@ -577,7 +579,7 @@ static AtCommandInfo atcommand_info[] = {
 	{ AtCommand_ListMail,			"@listmail",		 1, atcommand_listmail }, // [Valaris]
 	{ AtCommand_ListMail,			"@listmail",		 1, atcommand_listmail }, // [Valaris]
 	{ AtCommand_ListNewMail,		"@listnewmail", 	 1, atcommand_listmail }, // [Valaris]
 	{ AtCommand_ListNewMail,		"@listnewmail", 	 1, atcommand_listmail }, // [Valaris]
 	{ AtCommand_ReadMail,			"@readmail",		 1, atcommand_readmail }, // [Valaris]
 	{ AtCommand_ReadMail,			"@readmail",		 1, atcommand_readmail }, // [Valaris]
-	{ AtCommand_DeleteMail, 		"@deletemail",		 1, atcommand_readmail }, // [Valaris]
+	{ AtCommand_DeleteMail, 		"@deletemail",		 1, atcommand_deletemail }, // [Valaris]
 	{ AtCommand_SendMail,			"@sendmail",		 1, atcommand_sendmail }, // [Valaris]
 	{ AtCommand_SendMail,			"@sendmail",		 1, atcommand_sendmail }, // [Valaris]
 	{ AtCommand_SendPriorityMail,	"@sendprioritymail",80, atcommand_sendmail }, // [Valaris]
 	{ AtCommand_SendPriorityMail,	"@sendprioritymail",80, atcommand_sendmail }, // [Valaris]
 	{ AtCommand_RefreshOnline,		"@refreshonline",	99, atcommand_refreshonline }, // [Valaris]
 	{ AtCommand_RefreshOnline,		"@refreshonline",	99, atcommand_refreshonline }, // [Valaris]
@@ -7898,11 +7900,11 @@ int atcommand_listmail(const int fd, struct map_session_data* sd, const char* co
 
 
 	nullpo_retr(-1, sd);
 	nullpo_retr(-1, sd);
 
 
-	if(strlen(command)==12)
+	if(strlen(command)==12) // @listnewmail
 		mail_check(sd,3);
 		mail_check(sd,3);
-	else if(strlen(command)==9)
+	else if(strlen(command)==9) // @listmail
 		mail_check(sd,2);
 		mail_check(sd,2);
-	else
+	else // @checkmail
 		mail_check(sd,1);
 		mail_check(sd,1);
 	return 0;
 	return 0;
 }
 }
@@ -7926,10 +7928,31 @@ int atcommand_readmail(const int fd, struct map_session_data* sd, const char* co
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if(strlen(command)==11)
-		mail_delete(sd,index);
-	else
-		mail_read(sd,index);
+	mail_read(sd,index);
+
+	return 0;
+}
+
+int atcommand_deletemail(const int fd, struct map_session_data* sd, const char* command, const char* message)
+{
+	int index;
+	if(!mail_server_enable)
+		return 0;
+
+	nullpo_retr(-1, sd);
+
+	if (!message || !*message) {
+		clif_displaymessage(sd->fd,"You must specify a message number.");
+		return 0;
+	}
+
+	index = atoi(message);
+	if (index < 1) {
+		clif_displaymessage(sd->fd,"Message number cannot be negative or zero.");
+		return 0;
+	}
+
+	mail_delete(sd,index);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -7954,7 +7977,7 @@ int atcommand_sendmail(const int fd, struct map_session_data* sd, const char* co
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if(strlen(command)==17)
+	if(strlen(command)==17) // @sendprioritymail
 		mail_send(sd,name,text,1);
 		mail_send(sd,name,text,1);
 	else
 	else
 		mail_send(sd,name,text,0);
 		mail_send(sd,name,text,0);

+ 1 - 0
src/map/battle.c

@@ -8,6 +8,7 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "map.h"
 #include "map.h"
 #include "pc.h"
 #include "pc.h"

+ 1 - 0
src/map/charcommand.c

@@ -6,6 +6,7 @@
 #include "../common/timer.h"
 #include "../common/timer.h"
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
 
 
 #include "log.h"
 #include "log.h"
 #include "clif.h"
 #include "clif.h"

+ 1 - 0
src/map/clif.c

@@ -9,6 +9,7 @@
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "map.h"
 #include "map.h"
 #include "chrif.h"
 #include "chrif.h"

+ 3 - 3
src/map/guild.c

@@ -9,6 +9,7 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "map.h"
 #include "map.h"
 #include "guild.h"
 #include "guild.h"
@@ -1922,12 +1923,11 @@ int guild_save_sub(int tid,unsigned int tick,int id,int data)
 
 
 int guild_agit_break(struct mob_data *md)
 int guild_agit_break(struct mob_data *md)
 {	// Run One NPC_Event[OnAgitBreak]
 {	// Run One NPC_Event[OnAgitBreak]
-	char *evname;
+	char* evname;
 
 
 	if(!agit_flag) return 0;	// Agit already End
 	if(!agit_flag) return 0;	// Agit already End
-	evname=(char *)aMallocA((strlen(md->npc_event) + 1)*sizeof(char));
 
 
-	strcpy(evname,md->npc_event);
+	evname = aStrdup(md->npc_event);
 // Now By User to Run [OnAgitBreak] NPC Event...
 // Now By User to Run [OnAgitBreak] NPC Event...
 // It's a little impossible to null point with player disconnect in this!
 // It's a little impossible to null point with player disconnect in this!
 // But Script will be stop, so nothing...
 // But Script will be stop, so nothing...

+ 1 - 1
src/map/intif.c

@@ -1497,7 +1497,7 @@ int intif_parse(int fd)
 	case 0x3802:	intif_parse_WisEnd(fd); break;
 	case 0x3802:	intif_parse_WisEnd(fd); break;
 	case 0x3803:	mapif_parse_WisToGM(fd); break;
 	case 0x3803:	mapif_parse_WisToGM(fd); break;
 	case 0x3804:	intif_parse_Registers(fd); break;
 	case 0x3804:	intif_parse_Registers(fd); break;
-	case 0x3806:   intif_parse_ChangeNameOk(fd); break;
+	case 0x3806:	intif_parse_ChangeNameOk(fd); break;
 	case 0x3810:	intif_parse_LoadStorage(fd); break;
 	case 0x3810:	intif_parse_LoadStorage(fd); break;
 	case 0x3811:	intif_parse_SaveStorage(fd); break;
 	case 0x3811:	intif_parse_SaveStorage(fd); break;
 	case 0x3818:	intif_parse_LoadGuildStorage(fd); break;
 	case 0x3818:	intif_parse_LoadGuildStorage(fd); break;

+ 189 - 307
src/map/itemdb.c

@@ -615,369 +615,251 @@ static int itemdb_gendercheck(struct item_data *id)
 	if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
 	if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
 		return 0;
 		return 0;
 
 
-	return (battle_config.ignore_items_gender?2:id->sex);
+	return (battle_config.ignore_items_gender) ? 2 : id->sex;
 }
 }
-#ifndef TXT_ONLY
 
 
-/*======================================
- * SQL
- *======================================*/
-static int itemdb_read_sqldb(void)
-{
+/*==========================================
+ * processes one itemdb entry
+ *------------------------------------------*/
+static bool itemdb_parse_dbrow(char** str, char* source, int line)
+{
+	/*
+		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+		| 00 |      01      |       02      |  03  |     04    |     05     |   06   |   07   |    08   |   09  |   10  |     11     |      12     |       13      |        14       |      15      |      16     |     17     |  18  |   19   |      20      |        21      |
+		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+		| id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
+		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
+	*/
 	unsigned short nameid;
 	unsigned short nameid;
-	struct item_data *id;
-	char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator
-	char *item_db_name[] = { item_db_db, item_db2_db };
-	long unsigned int ln = 0;
-	int i;	
-
-	// ----------
-
-	for (i = 0; i < 2; i++) {
-		sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_name[i]);
-
-		// Execute the query; if the query execution succeeded...
-		if (mysql_query(&mmysql_handle, tmp_sql) == 0) {
-			sql_res = mysql_store_result(&mmysql_handle);
-
-			// If the storage of the query result succeeded...
-			if (sql_res) {
-				// Parse each row in the query result into sql_row
-				while ((sql_row = mysql_fetch_row(sql_res)))
-				{	/*Table structure is:
-					00  id
-					01  name_english
-					02  name_japanese
-					03  type
-					04  price_buy
-					05  price_sell
-					06  weight
-					07  attack
-					08  defence
-					09  range
-					10  slots
-					11  equip_jobs
-					12  equip_upper
-					13  equip_genders
-					14  equip_locations
-					15  weapon_level
-					16  equip_level
-					17  refineable
-					18  view
-					19  script
-					20  equip_script
-					21  unequip_script
-					*/
-					nameid = atoi(sql_row[0]);
-
-					// If the identifier is not within the valid range, process the next row
-					if (nameid == 0)
-						continue;
-
-					ln++;
-
-					// ----------
-					id = itemdb_load(nameid);
-					
-					strncpy(id->name, sql_row[1], ITEM_NAME_LENGTH-1);
-					strncpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1);
-
-					id->type = atoi(sql_row[3]);
-					if (id->type == IT_DELAYCONSUME)
-					{	//Items that are consumed upon target confirmation
-						//(yggdrasil leaf, spells & pet lures) [Skotlex]
-						id->type = IT_USABLE;
-						id->flag.delay_consume=1;
-					} else //In case of an itemdb reload and the item type changed.
-						id->flag.delay_consume=0;
-
-					// If price_buy is not NULL and price_sell is not NULL...
-					if ((sql_row[4] != NULL) && (sql_row[5] != NULL)) {
-						id->value_buy = atoi(sql_row[4]);
-						id->value_sell = atoi(sql_row[5]);
-					}
-					// If price_buy is not NULL and price_sell is NULL...
-					else if ((sql_row[4] != NULL) && (sql_row[5] == NULL)) {
-						id->value_buy = atoi(sql_row[4]);
-						id->value_sell = atoi(sql_row[4]) / 2;
-					}
-					// If price_buy is NULL and price_sell is not NULL...
-					else if ((sql_row[4] == NULL) && (sql_row[5] != NULL)) {
-						id->value_buy = atoi(sql_row[5]) * 2;
-						id->value_sell = atoi(sql_row[5]);
-					}
-					// If price_buy is NULL and price_sell is NULL...
-					if ((sql_row[4] == NULL) && (sql_row[5] == NULL)) {
-						id->value_buy = 0;
-						id->value_sell = 0;
-					}
-
-					id->weight	= atoi(sql_row[6]);
-					id->atk		= (sql_row[7] != NULL) ? atoi(sql_row[7]) : 0;
-					id->def		= (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0;
-					id->range	= (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0;
-					id->slot	= (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0;
-					if (id->slot > MAX_SLOTS)
-					{
-						ShowWarning("itemdb_read_sqldb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
-						id->slot = MAX_SLOTS;
-					}
-					itemdb_jobid2mapid(id->class_base, (sql_row[11] != NULL) ? (unsigned int)strtoul(sql_row[11], NULL, 0) : 0);
-					id->class_upper= (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0;
-					id->sex		= (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0;
-					id->equip	= (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0;
-					if (!id->equip && itemdb_isequip2(id))
-					{
-						ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
-						id->type = 3;
-					}
-					id->wlv		= (sql_row[15] != NULL) ? atoi(sql_row[15]) : 0;
-					id->elv		= (sql_row[16] != NULL)	? atoi(sql_row[16]) : 0;
-					id->flag.no_refine = (sql_row[17] == NULL || atoi(sql_row[17]) == 1)?0:1;
-					id->look	= (sql_row[18] != NULL) ? atoi(sql_row[18]) : 0;
-					id->view_id	= 0;
-					id->sex = itemdb_gendercheck(id); //Apply gender filtering.
-
-					// ----------
-					
-					if (id->script)
-						script_free_code(id->script);
-					if (sql_row[19] != NULL) {
-						if (sql_row[19][0] == '{')
-							id->script = parse_script(sql_row[19],item_db_name[i], ln, 0);
-						else {
-							sprintf(script, "{%s}", sql_row[19]);
-							id->script = parse_script(script, item_db_name[i], ln, 0);
-						}
-					} else id->script = NULL;
+	struct item_data* id;
 	
 	
-					if (id->equip_script)
-						script_free_code(id->equip_script);
-					if (sql_row[20] != NULL) {
-						if (sql_row[20][0] == '{')
-							id->equip_script = parse_script(sql_row[20], item_db_name[i], ln, 0);
-						else {
-							sprintf(script, "{%s}", sql_row[20]);
-							id->equip_script = parse_script(script, item_db_name[i], ln, 0);
-						}
-					} else id->equip_script = NULL;
+	nameid = atoi(str[0]);
+	if(nameid <= 0)
+		return false;
 	
 	
-					if (id->unequip_script)
-						script_free_code(id->unequip_script);
-					if (sql_row[21] != NULL) {
-						if (sql_row[21][0] == '{')
-							id->unequip_script = parse_script(sql_row[21],item_db_name[i], ln, 0);
-						else {
-							sprintf(script, "{%s}", sql_row[21]);
-							id->unequip_script = parse_script(script, item_db_name[i], ln, 0);
-						}
-					} else id->unequip_script = NULL;
-				
-					// ----------
-
-					id->flag.available	= 1;
-					id->flag.value_notdc	= 0;
-					id->flag.value_notoc	= 0;
-				}
+	//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
+	id = itemdb_load(nameid);
+	safestrncpy(id->name, str[1], ITEM_NAME_LENGTH-1);
+	safestrncpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
+	
+	id->type = atoi(str[3]);
+	if (id->type == IT_DELAYCONSUME)
+	{	//Items that are consumed only after target confirmation
+		id->type = IT_USABLE;
+		id->flag.delay_consume = 1;
+	} else //In case of an itemdb reload and the item type changed.
+		id->flag.delay_consume = 0;
+
+	id->value_buy = atoi(str[4]);
+	id->value_sell = atoi(str[5]);
+	if (id->value_buy < id->value_sell * 2) id->value_buy = id->value_sell * 2; // prevent exploit
+	if (id->value_buy == 0 && id->value_sell > 0) id->value_buy = id->value_sell * 2;
+	if (id->value_sell == 0 && id->value_buy > 0) id->value_sell = id->value_buy / 2;
+	
+	id->weight = atoi(str[6]);
+	id->atk = atoi(str[7]);
+	id->def = atoi(str[8]);
+	id->range = atoi(str[9]);
+	id->slot = atoi(str[10]);
+	
+	if (id->slot > MAX_SLOTS)
+	{
+		ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
+		id->slot = MAX_SLOTS;
+	}
+	
+	itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
+	id->class_upper = atoi(str[12]);
+	id->sex	= atoi(str[13]);
+	id->equip = atoi(str[14]);
+	
+	if (!id->equip && itemdb_isequip2(id))
+	{
+		ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
+		id->type = IT_ETC;
+	}
+	
+	id->wlv = atoi(str[15]);
+	id->elv = atoi(str[16]);
+	id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
+	id->look = atoi(str[18]);
+	
+	id->flag.available = 1;
+	id->flag.value_notdc = 0;
+	id->flag.value_notoc = 0;
+	id->view_id = 0;
+	id->sex = itemdb_gendercheck(id); //Apply gender filtering.
 
 
-				ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, item_db_name[i]);
-				ln = 0;
-			} else {
-				ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+	if (id->script)
+		script_free_code(id->script);
+	if (id->equip_script)
+		script_free_code(id->equip_script);
+	if (id->unequip_script)
+		script_free_code(id->unequip_script);
 
 
-			// Free the query result
-			mysql_free_result(sql_res);
-		} else {
-			ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-	}
+	if (*str[19])
+		id->script = parse_script(str[19], source, line, 0);
+	if (*str[20])
+		id->equip_script = parse_script(str[20], source, line, 0);
+	if (*str[21])
+		id->unequip_script = parse_script(str[21], source, line, 0);
 
 
-	return 0;
+	return true;
 }
 }
-#endif /* not TXT_ONLY */
 
 
 /*==========================================
 /*==========================================
  * アイテムデータベースの読み込み
  * アイテムデータベースの読み込み
  *------------------------------------------*/
  *------------------------------------------*/
 static int itemdb_readdb(void)
 static int itemdb_readdb(void)
 {
 {
-	FILE *fp;
-	char line[1024];
-	int ln=0,lines=0;
-	int nameid,j;
-	char *str[32],*p,*np;
-	struct item_data *id;
-	int i=0;
-	char *filename[]={ "item_db.txt","item_db2.txt" };
-
-	for(i=0;i<2;i++){
-		sprintf(line, "%s/%s", db_path, filename[i]);
-		fp=fopen(line,"r");
-		if(fp==NULL){
-			if(i>0)
+	char* filename[] = { "item_db.txt", "item_db2.txt" };
+	int fi;
+
+	for(fi = 0; fi < 2; fi++)
+	{
+		uint32 lines = 0, count = 0;
+		char line[1024];
+
+		char path[256];
+		FILE* fp;
+
+		sprintf(path, "%s/%s", db_path, filename[fi]);
+		fp = fopen(path, "r");
+		if(fp == NULL) {
+			if(fi > 0)
 				continue;
 				continue;
-			ShowFatalError("can't read %s\n",line);
-			exit(1);
+			return -1;
 		}
 		}
 
 
-		lines=0;
+		// process rows one by one
 		while(fgets(line, sizeof(line), fp))
 		while(fgets(line, sizeof(line), fp))
 		{
 		{
-			lines++;
-			if(line[0]=='/' && line[1]=='/')
-				continue;
-			memset(str,0,sizeof(str));
-			for(j=0,np=p=line;j<19 && p;j++){
-				str[j]=p;
-				p=strchr(p,',');
-				if(p){ *p++=0; np=p; }
-			}
-			if(str[0]==NULL)
-				continue;
+			char *str[32], *p, *np;
+			int i;
 
 
-			nameid=atoi(str[0]);
-			if(nameid<=0)
-				continue;
-			if (j < 19)
-			{	//Crash-fix on broken item lines. [Skotlex]
-				ShowWarning("Reading %s: Insufficient fields for item with id %d, skipping.\n", filename[i], nameid);
+			lines++;
+			if(line[0] == '/' && line[1] == '/')
 				continue;
 				continue;
-			}
-			ln++;
-
-			//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
-			id=itemdb_load(nameid);
-			strncpy(id->name, str[1], ITEM_NAME_LENGTH-1);
-			strncpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
-			id->type=atoi(str[3]);
-			if (id->type == IT_DELAYCONSUME)
-			{	//Items that are consumed upon target confirmation
-				//(yggdrasil leaf, spells & pet lures) [Skotlex]
-				id->type = IT_USABLE;
-				id->flag.delay_consume=1;
-			} else //In case of an itemdb reload and the item type changed.
-				id->flag.delay_consume=0;
-
+			memset(str, 0, sizeof(str));
+			for(i = 0, np = p = line; i < 19 && p; i++)
 			{
 			{
-				int buy = atoi(str[4]), sell = atoi(str[5]);
-				// if buying price > selling price * 2 consider it valid and don't change it [celest]
-				if (buy && sell && buy > sell*2){
-					id->value_buy = buy;
-					id->value_sell = sell;
-				} else {
-					// buy≠sell*2 は item_value_db.txt で指定してください。
-					if (sell) {		// sell値を優先とする
-						id->value_buy = sell*2;
-						id->value_sell = sell;
-					} else {
-						id->value_buy = buy;
-						id->value_sell = buy/2;
-					}
+				str[i] = p;
+				if ((p = strchr(p,',')) != NULL) {
+					*p++ = '\0'; np = p;
 				}
 				}
-				// check for bad prices that can possibly cause exploits
-				if (id->value_buy*75/100 < id->value_sell*124/100) {
-					ShowWarning ("Item %s [%d] buying:%d < selling:%d\n",
-						id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100);
-				}
-			}
-			id->weight=atoi(str[6]);
-			id->atk=atoi(str[7]);
-			id->def=atoi(str[8]);
-			id->range=atoi(str[9]);
-			id->slot=atoi(str[10]);
-			if (id->slot > MAX_SLOTS)
-			{
-				ShowWarning("itemdb_readdb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
-				id->slot = MAX_SLOTS;
-			}
-			itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
-			id->class_upper = atoi(str[12]);
-			id->sex	= atoi(str[13]);
-			if(id->equip != atoi(str[14])){
-				id->equip=atoi(str[14]);
-			}
-			if (!id->equip && itemdb_isequip2(id))
-			{
-				ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
-				id->type = 3;
-			}
-			id->wlv=atoi(str[15]);
-			id->elv=atoi(str[16]);
-			id->flag.no_refine = atoi(str[17])?0:1;	//If the refine column is 1, no_refine is 0
-			id->look=atoi(str[18]);
-			id->flag.available=1;
-			id->flag.value_notdc=0;
-			id->flag.value_notoc=0;
-			id->view_id=0;
-			id->sex = itemdb_gendercheck(id); //Apply gender filtering.
-
-			if (id->script) {
-				script_free_code(id->script);
-				id->script=NULL;
 			}
 			}
-			if (id->equip_script) {
-				script_free_code(id->equip_script);
-				id->equip_script=NULL;
-			}
-			if (id->unequip_script) {
-				script_free_code(id->unequip_script);
-				id->unequip_script=NULL;
+
+			if (i < 19) {
+				ShowWarning("itemdb_readdb: Insufficient columns for item with id %d, skipping.\n", atoi(str[0]));
+				continue;
 			}
 			}
 
 
-			if((p=strchr(np,'{'))==NULL)
+			if((p=strchr(np,'{')) == NULL)
 				continue;
 				continue;
-			
 			str[19] = p; //Script
 			str[19] = p; //Script
 			np = strchr(p,'}');
 			np = strchr(p,'}');
-
 			while (np && np[1] && np[1] != ',')
 			while (np && np[1] && np[1] != ',')
 				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
 				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
 			if (!np || !np[1]) {
 			if (!np || !np[1]) {
-				//Couldn't find the end of the script field.
-				id->script = parse_script(str[19],filename[i],lines,0);
-				continue;
+				continue; //Couldn't find the end of the script field.
 			}
 			}
 			np[1] = '\0'; //Set end of script
 			np[1] = '\0'; //Set end of script
-			id->script = parse_script(str[19],filename[i],lines,0);
-			np+=2; //Skip to next field
+			np += 2; //Skip to next field
 
 
 			if(!np || (p=strchr(np,'{'))==NULL)
 			if(!np || (p=strchr(np,'{'))==NULL)
 				continue;
 				continue;
-
 			str[20] = p; //Equip Script
 			str[20] = p; //Equip Script
 			np = strchr(p,'}');
 			np = strchr(p,'}');
-
 			while (np && np[1] && np[1] != ',')
 			while (np && np[1] && np[1] != ',')
 				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
 				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
 			if (!np || !np[1]) {
 			if (!np || !np[1]) {
-				//Couldn't find the end of the script field.
-				id->equip_script = parse_script(str[20],filename[i],lines,0);
-				continue;
+				continue; //Couldn't find the end of the script field.
 			}
 			}
-
 			np[1] = '\0'; //Set end of script
 			np[1] = '\0'; //Set end of script
-			id->equip_script = parse_script(str[20],filename[i],lines,0);
-			np+=2; //Skip comma, to next field
+			np += 2; //Skip comma, to next field
 
 
 			if(!np || (p=strchr(np,'{'))==NULL)
 			if(!np || (p=strchr(np,'{'))==NULL)
 				continue;
 				continue;
-			//Unequip script, last column.
-			id->unequip_script = parse_script(p,filename[i],lines,0);
+			str[21] = p; //Unequip script, last column.
+
+			if (!itemdb_parse_dbrow(str, filename[fi], lines))
+				continue;
+			
+			count++;
 		}
 		}
+
 		fclose(fp);
 		fclose(fp);
-		if (ln > 0) {
-			ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]);
+
+		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
+	}
+
+	return 0;
+}
+
+#ifndef TXT_ONLY
+/*======================================
+ * item_db table reading
+ *======================================*/
+static int itemdb_read_sqldb(void)
+{
+	char* item_db_name[] = { item_db_db, item_db2_db };
+	int fi;
+	
+	for (fi = 0; fi < 2; fi++)
+	{
+		uint32 lines = 0, count = 0;
+		
+		// retrieve all rows from the item database
+		if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) )
+		{
+			Sql_ShowDebug(mmysql_handle);
+			continue;
+		}
+		
+		// process rows one by one
+		while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) )
+		{
+			// wrap the result into a TXT-compatible format
+			char line[1024];
+			char* str[22];
+			char* p;
+			int i;
+			
+			lines++;
+			for (i = 0, p = line; i < 22; i++)
+			{
+				char* data;
+				size_t len;
+				Sql_GetData(mmysql_handle, i, &data, &len);
+				
+				if (data == NULL)
+					p[0] = '\0';
+				else if (i >= 19 && data[0] != '{') {
+					sprintf(p, "{ %s }", data); len+= 4;
+				} else
+					strcpy(p, data);
+				str[i] = p;
+				p+= len + 1;
+			}
+			
+			if (!itemdb_parse_dbrow(str, item_db_name[fi], lines))
+				continue;
+			
+			count++;
 		}
 		}
-		ln=0;	// reset to 0
+		
+		// free the query result
+		Sql_FreeResult(mmysql_handle);
+		
+		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]);
 	}
 	}
+
 	return 0;
 	return 0;
 }
 }
+#endif /* not TXT_ONLY */
 
 
 /*====================================
 /*====================================
- * Removed item_value_db, don't re-add
+ * read all item-related databases
  *------------------------------------*/
  *------------------------------------*/
 static void itemdb_read(void)
 static void itemdb_read(void)
 {
 {

+ 209 - 183
src/map/log.c

@@ -19,6 +19,8 @@ struct Log_Config log_config;
 char timestring[255];
 char timestring[255];
 time_t curtime;
 time_t curtime;
 
 
+static int should_log_item(int filter, int nameid, int amount); //log filter check
+
 //FILTER OPTIONS
 //FILTER OPTIONS
 //0 = Don't log
 //0 = Don't log
 //1 = Log any item
 //1 = Log any item
@@ -58,104 +60,105 @@ int should_log_item(int filter, int nameid, int amount)
 
 
 int log_branch(struct map_session_data *sd)
 int log_branch(struct map_session_data *sd)
 {
 {
-#ifndef TXT_ONLY
-	char t_name[NAME_LENGTH*2];
-#endif
-	FILE *logfp;
-
 	if(!log_config.enable_logs)
 	if(!log_config.enable_logs)
 		return 0;
 		return 0;
+
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
+
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')",
-			log_config.log_branch_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), mapindex_id2name(sd->mapindex));
-		if(mysql_query(&logmysql_handle, tmp_sql))
+		SqlStmt* stmt;
+		stmt = SqlStmt_Malloc(logmysql_handle);
+		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", log_config.log_branch_db, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+		||  SQL_SUCCESS != SqlStmt_Execute(stmt) )
 		{
 		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			SqlStmt_ShowDebug(stmt);
+			SqlStmt_Free(stmt);
 			return 0;
 			return 0;
 		}
 		}
-		return 1;
+		SqlStmt_Free(stmt);
 	}
 	}
+	else
 #endif
 #endif
-	if((logfp=fopen(log_config.log_branch,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-	fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex));
-	fclose(logfp);
+	{
+		FILE* logfp;
+		if((logfp = fopen(log_config.log_branch, "a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex));
+		fclose(logfp);
+	}
+
 	return 1;
 	return 1;
 }
 }
 
 
 
 
 int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int amount, struct item *itm)
 int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int amount, struct item *itm)
 {
 {
-	FILE *logfp;
-	char *mapname;
-
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
-	//Should we log this item? [Lupus]
-	if (!should_log_item(log_config.filter,nameid, amount))
-		return 0; //we skip logging this items set - they doesn't met our logging conditions [Lupus]
 
 
-	mapname = (char*)mapindex_id2name(sd->mapindex);
-
-	if(mapname==NULL)
-		mapname="";
+	if (!should_log_item(log_config.filter, nameid, amount))
+		return 0; //we skip logging this item set - it doesn't meet our logging conditions [Lupus]
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
-		if (itm==NULL) {
-		//We log common item
-			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%s')",
-			 log_config.log_pick_db, sd->status.char_id, type, nameid, amount, mapname);
+		if (itm == NULL) {
+			//We log common item
+			if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%s')",
+				log_config.log_pick_db, sd->status.char_id, type, nameid, amount, mapindex_id2name(sd->mapindex)) )
+			{
+				Sql_ShowDebug(logmysql_handle);
+				return 0;
+			}
 		} else {
 		} else {
-		//We log Extended item
-			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
-			 log_config.log_pick_db, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
+			//We log Extended item
+			if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
+				log_config.log_pick_db, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapindex_id2name(sd->mapindex)) )
+			{
+				Sql_ShowDebug(logmysql_handle);
+				return 0;
+			}
 		}
 		}
+	}
+	else
+#endif
+	{
+		FILE* logfp;
 
 
-		if(mysql_query(&logmysql_handle, tmp_sql))
-		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		if((logfp = fopen(log_config.log_pick, "a+")) == NULL)
 			return 0;
 			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+
+		if (itm == NULL) {
+		//We log common item
+			fprintf(logfp,"%s - %d\t%s\t%d,%d,%s\n",
+				timestring, sd->status.char_id, type, nameid, amount, mapindex_id2name(sd->mapindex));
+
+		} else {
+		//We log Extended item
+			fprintf(logfp,"%s - %d\t%s\t%d,%d,%d,%d,%d,%d,%d,%s\n",
+				timestring, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapindex_id2name(sd->mapindex));
 		}
 		}
-		return 1;
+		fclose(logfp);
 	}
 	}
-#endif
-	if((logfp=fopen(log_config.log_pick,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-
-	if (itm==NULL) {
-	//We log common item
-		fprintf(logfp,"%s - %d\t%s\t%d,%d,%s\n",
-			timestring, sd->status.char_id, type, nameid, amount, mapname);
-
-	} else {
-	//We log Extended item
-		fprintf(logfp,"%s - %d\t%s\t%d,%d,%d,%d,%d,%d,%d,%s\n",
-			timestring, sd->status.char_id, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
-	}
-	fclose(logfp);
+	
 	return 1; //Logged
 	return 1; //Logged
 }
 }
 
 
 //Mob picked item
 //Mob picked item
 int log_pick_mob(struct mob_data *md, const char *type, int nameid, int amount, struct item *itm)
 int log_pick_mob(struct mob_data *md, const char *type, int nameid, int amount, struct item *itm)
 {
 {
-	FILE *logfp;
-	char *mapname;
+	char* mapname;
 
 
 	nullpo_retr(0, md);
 	nullpo_retr(0, md);
-	//Should we log this item? [Lupus]
-	if (!should_log_item(log_config.filter,nameid, amount))
-		return 0; //we skip logging this items set - they doesn't met our logging conditions [Lupus]
+
+	if (!should_log_item(log_config.filter, nameid, amount))
+		return 0; //we skip logging this item set - it doesn't meet our logging conditions [Lupus]
 
 
 	//either PLAYER or MOB (here we get map name and objects ID)
 	//either PLAYER or MOB (here we get map name and objects ID)
 	mapname = map[md->bl.m].name;
 	mapname = map[md->bl.m].name;
@@ -167,180 +170,200 @@ int log_pick_mob(struct mob_data *md, const char *type, int nameid, int amount,
 	{
 	{
 		if (itm==NULL) {
 		if (itm==NULL) {
 		//We log common item
 		//We log common item
-			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%s')",
-			 log_config.log_pick_db, md->class_, type, nameid, amount, mapname);
+			if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%s')",
+				log_config.log_pick_db, md->class_, type, nameid, amount, mapname) )
+			{
+				Sql_ShowDebug(logmysql_handle);
+				return 0;
+			}
 		} else {
 		} else {
 		//We log Extended item
 		//We log Extended item
-			sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
-			 log_config.log_pick_db, md->class_, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
+			if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`) VALUES (NOW(), '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s')",
+				log_config.log_pick_db, md->class_, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname) )
+			{
+				Sql_ShowDebug(logmysql_handle);
+				return 0;
+			}
 		}
 		}
+	}
+	else
+#endif
+	{
+		FILE *logfp;
 
 
-		if(mysql_query(&logmysql_handle, tmp_sql))
-		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		if((logfp=fopen(log_config.log_pick,"a+")) == NULL)
 			return 0;
 			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+
+		if (itm==NULL) {
+		//We log common item
+			fprintf(logfp,"%s - %d\t%s\t%d,%d,%s\n",
+				timestring, md->class_, type, nameid, amount, mapname);
+
+		} else {
+		//We log Extended item
+			fprintf(logfp,"%s - %d\t%s\t%d,%d,%d,%d,%d,%d,%d,%s\n",
+				timestring, md->class_, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
 		}
 		}
-		return 1;
-	}
-#endif
-	if((logfp=fopen(log_config.log_pick,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-
-	if (itm==NULL) {
-	//We log common item
-		fprintf(logfp,"%s - %d\t%s\t%d,%d,%s\n",
-			timestring, md->class_, type, nameid, amount, mapname);
-
-	} else {
-	//We log Extended item
-		fprintf(logfp,"%s - %d\t%s\t%d,%d,%d,%d,%d,%d,%d,%s\n",
-			timestring, md->class_, type, itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], mapname);
+		fclose(logfp);
 	}
 	}
-	fclose(logfp);
+	
 	return 1; //Logged
 	return 1; //Logged
 }
 }
 
 
 int log_zeny(struct map_session_data *sd, char *type, struct map_session_data *src_sd, int amount)
 int log_zeny(struct map_session_data *sd, char *type, struct map_session_data *src_sd, int amount)
 {
 {
-//	FILE *logfp;
-	if(!log_config.enable_logs || (log_config.zeny!=1 && abs(amount)<log_config.zeny))
+	if(!log_config.enable_logs || (log_config.zeny != 1 && abs(amount) < log_config.zeny))
 		return 0;
 		return 0;
 
 
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
+
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%s')",
-			 log_config.log_zeny_db, sd->status.char_id, src_sd->status.char_id, type, amount, mapindex_id2name(sd->mapindex));
-		if(mysql_query(&logmysql_handle, tmp_sql))
+		if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%d', '%s')",
+			 log_config.log_zeny_db, sd->status.char_id, src_sd->status.char_id, type, amount, mapindex_id2name(sd->mapindex)) )
 		{
 		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			Sql_ShowDebug(logmysql_handle);
 			return 0;
 			return 0;
 		}
 		}
-		return 1;
 	}
 	}
+	else
 #endif
 #endif
-//		if((logfp=fopen(log_config.log_zeny,"a+")) == NULL)
-//			return 0;
-//		time(&curtime);
-//		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-//		fprintf(logfp,"%s - %s[%d]\t%s[%d]\t%d\n", timestring, sd->status.name, sd->status.account_id, target_sd->status.name, target_sd->status.account_id, sd->deal.zeny);
-//		fclose(logfp);
-//		return 1;
-	return 0;
+	{
+		FILE* logfp;
+		if((logfp=fopen(log_config.log_zeny,"a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp, "%s - %s[%d]\t%s[%d]\t%d\t\n", timestring, src_sd->status.name, src_sd->status.account_id, sd->status.name, sd->status.account_id, amount);
+		fclose(logfp);
+	}
+
+	return 1;
 }
 }
 
 
 int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp)
 int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp)
 {
 {
-	FILE *logfp;
-
 	if(!log_config.enable_logs)
 	if(!log_config.enable_logs)
 		return 0;
 		return 0;
+
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
+
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ", log_config.log_mvpdrop_db, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex));
-		if(mysql_query(&logmysql_handle, tmp_sql))
+		if (SQL_ERROR == Sql_Query(logmysql_handle, "INSERT DELAYED INTO `%s` (`mvp_date`, `kill_char_id`, `monster_id`, `prize`, `mvpexp`, `map`) VALUES (NOW(), '%d', '%d', '%d', '%d', '%s') ",
+			log_config.log_mvpdrop_db, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1], mapindex_id2name(sd->mapindex)) )
 		{
 		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			Sql_ShowDebug(logmysql_handle);
 			return 0;
 			return 0;
 		}
 		}
-		return 1;
 	}
 	}
+	else
 #endif
 #endif
-	if((logfp=fopen(log_config.log_mvpdrop,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-	fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1]);
-	fclose(logfp);
-	return 0;
+	{
+		FILE* logfp;
+		if((logfp=fopen(log_config.log_mvpdrop,"a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp,"%s - %s[%d:%d]\t%d\t%d,%d\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, monster_id, log_mvp[0], log_mvp[1]);
+		fclose(logfp);
+	}
+
+	return 1;
 }
 }
 
 
 
 
-int log_atcommand(struct map_session_data *sd, const char *message)
+int log_atcommand(struct map_session_data* sd, const char* message)
 {
 {
-	FILE *logfp;
-#ifndef TXT_ONLY
-	char t_name[NAME_LENGTH*2];
-	char t_msg[CHAT_SIZE*2+1]; //These are the contents of an @ call, so there shouldn't be overflow danger here?
-#endif
-
 	if(!log_config.enable_logs)
 	if(!log_config.enable_logs)
 		return 0;
 		return 0;
+
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
+
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
+		SqlStmt* stmt;
+
 		if (strlen(message) > CHAT_SIZE) {
 		if (strlen(message) > CHAT_SIZE) {
 			if (battle_config.error_log)
 			if (battle_config.error_log)
-				ShowError("log atcommand: Received message too long from player %s (%d:%d)!\n",
-					sd->status.name, sd->status.account_id, sd->status.char_id);
+				ShowError("log atcommand: Received message too long from player %s (%d:%d)!\n", sd->status.name, sd->status.account_id, sd->status.char_id);
 			return 0;
 			return 0;
 		}
 		}
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ",
-			log_config.log_gm_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), mapindex_id2name(sd->mapindex), jstrescapecpy(t_msg, (char *)message));
-		if(mysql_query(&logmysql_handle, tmp_sql))
+
+		stmt = SqlStmt_Malloc(logmysql_handle);
+		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm_db, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex), message)
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, strnlen(message, 255))
+		||  SQL_SUCCESS != SqlStmt_Execute(stmt) )
 		{
 		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			SqlStmt_ShowDebug(stmt);
+			SqlStmt_Free(stmt);
 			return 0;
 			return 0;
 		}
 		}
-		return 1;
+		SqlStmt_Free(stmt);
 	}
 	}
+	else
 #endif
 #endif
-	if((logfp=fopen(log_config.log_gm,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-	fprintf(logfp,"%s - %s[%d]: %s\n",timestring,sd->status.name,sd->status.account_id,message);
-	fclose(logfp);
+	{
+		FILE* logfp;
+		if((logfp = fopen(log_config.log_gm, "a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
+		fclose(logfp);
+	}
+	
 	return 1;
 	return 1;
 }
 }
 
 
-int log_npc(struct map_session_data *sd, const char *message)
-{	//[Lupus]
-	FILE *logfp;
-#ifndef TXT_ONLY
-	char t_name[NAME_LENGTH*2];
-	char t_msg[255+1]; //it's 255 chars MAX. 
-#endif
-
+int log_npc(struct map_session_data* sd, const char* message)
+{
 	if(!log_config.enable_logs)
 	if(!log_config.enable_logs)
 		return 0;
 		return 0;
+
 	nullpo_retr(0, sd);
 	nullpo_retr(0, sd);
+
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(log_config.sql_logs > 0)
 	if(log_config.sql_logs > 0)
 	{
 	{
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES(NOW(), '%d', '%d', '%s', '%s', '%s') ",
-			log_config.log_npc_db, sd->status.account_id, sd->status.char_id, jstrescapecpy(t_name, sd->status.name), mapindex_id2name(sd->mapindex), jstrescapecpy(t_msg, (char *)message));
-		if(mysql_query(&logmysql_handle, tmp_sql))
+		SqlStmt* stmt;
+		stmt = SqlStmt_Malloc(logmysql_handle);
+		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_npc_db, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex), message)
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, strnlen(message, 255))
+		||  SQL_SUCCESS != SqlStmt_Execute(stmt) )
 		{
 		{
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+			SqlStmt_ShowDebug(stmt);
+			SqlStmt_Free(stmt);
 			return 0;
 			return 0;
 		}
 		}
-		return 1;
+		SqlStmt_Free(stmt);
 	}
 	}
+	else
 #endif
 #endif
-	if((logfp=fopen(log_config.log_npc,"a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-	fprintf(logfp,"%s - %s[%d]: %s\n",timestring,sd->status.name,sd->status.account_id,message);
-	fclose(logfp);
+	{
+		FILE* logfp;
+		if((logfp = fopen(log_config.log_npc, "a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message);
+		fclose(logfp);
+	}
+
 	return 1;
 	return 1;
 }
 }
 
 
-
 int log_chat(const char* type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message)
 int log_chat(const char* type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message)
 {
 {
+	//FIXME: the actual filtering is being done by the calling code instead of in here, why!?
+
 	// Log CHAT (Global, Whisper, Party, Guild, Main chat)
 	// Log CHAT (Global, Whisper, Party, Guild, Main chat)
 	// LOGGING FILTERS [Lupus]
 	// LOGGING FILTERS [Lupus]
 	//=============================================================
 	//=============================================================
@@ -353,42 +376,45 @@ int log_chat(const char* type, int type_id, int src_charid, int src_accid, const
 	//16 - Log Main chat messages
 	//16 - Log Main chat messages
 	//32 - Don't log anything when WOE is on
 	//32 - Don't log anything when WOE is on
 
 
-	FILE *logfp;
-#ifndef TXT_ONLY
-	char t_charname[NAME_LENGTH*2];
-	char t_msg[CHAT_SIZE*2+1]; //Chat line fully escaped, with an extra space just in case.
-#endif
-	
 	//Check ON/OFF
 	//Check ON/OFF
 	if(log_config.chat <= 0)
 	if(log_config.chat <= 0)
 		return 0; //Deactivated
 		return 0; //Deactivated
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
-	if(log_config.sql_logs > 0){
+	if(log_config.sql_logs > 0)
+	{
+		SqlStmt* stmt;
+		
 		if (strlen(message) > CHAT_SIZE) {
 		if (strlen(message) > CHAT_SIZE) {
 			if (battle_config.error_log)
 			if (battle_config.error_log)
-				ShowError("log chat: Received message too long from type %d (%d:%d)!\n",
-					type_id, src_accid, src_charid);
+				ShowError("log chat: Received message too long from type %d (%d:%d)!\n", type_id, src_accid, src_charid);
 			return 0;
 			return 0;
 		}
 		}
-		sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '%d', '%d', '%s', '%s')", 
-		 	log_config.log_chat_db, type, type_id, src_charid, src_accid, map, x, y, jstrescapecpy(t_charname, dst_charname), jstrescapecpy(t_msg, message));
-	
-		if(mysql_query(&logmysql_handle, tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			return 0;	
+
+		stmt = SqlStmt_Malloc(logmysql_handle);
+		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", log_config.log_chat_db, type, type_id, src_charid, src_accid, map, x, y)
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (char*)dst_charname, strnlen(dst_charname, NAME_LENGTH))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, strnlen(message, CHAT_SIZE))
+		||  SQL_SUCCESS != SqlStmt_Execute(stmt) )
+		{
+			SqlStmt_ShowDebug(stmt);
+			SqlStmt_Free(stmt);
+			return 0;
 		}
 		}
-		return 1;
+		SqlStmt_Free(stmt);
 	}
 	}
+	else
 #endif
 #endif
-	if((logfp = fopen(log_config.log_chat, "a+")) == NULL)
-		return 0;
-	time(&curtime);
-	strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
-	fprintf(logfp, "%s - %s,%d,%d,%d,%s,%d,%d,%s,%s\n", 
-		timestring, type, type_id, src_charid, src_accid, map, x, y, dst_charname, message);
-	fclose(logfp);
+	{
+		FILE* logfp;
+		if((logfp = fopen(log_config.log_chat, "a+")) == NULL)
+			return 0;
+		time(&curtime);
+		strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
+		fprintf(logfp, "%s - %s,%d,%d,%d,%s,%d,%d,%s,%s\n", timestring, type, type_id, src_charid, src_accid, map, x, y, dst_charname, message);
+		fclose(logfp);
+	}
+
 	return 1;
 	return 1;
 }
 }
 
 

+ 0 - 8
src/map/log.h

@@ -9,12 +9,6 @@ struct map_session_data;
 struct mob_data;
 struct mob_data;
 struct item;
 struct item;
 
 
-#ifndef TXT_ONLY
-
-extern char db_server_logdb[32];
-
-#endif //NOT TXT_ONLY
-
 //New logs
 //New logs
 int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int amount, struct item *itm);
 int log_pick_pc(struct map_session_data *sd, const char *type, int nameid, int amount, struct item *itm);
 int log_pick_mob(struct mob_data *md, const char *type, int nameid, int amount, struct item *itm);
 int log_pick_mob(struct mob_data *md, const char *type, int nameid, int amount, struct item *itm);
@@ -30,8 +24,6 @@ int log_mvpdrop(struct map_session_data *sd, int monster_id, int *log_mvp);
 
 
 int log_config_read(char *cfgName);
 int log_config_read(char *cfgName);
 
 
-int should_log_item(int filter, int nameid, int amount); //log filter check
-
 enum log_what {
 enum log_what {
 	LOG_ALL                 = 0xFFF,
 	LOG_ALL                 = 0xFFF,
 	LOG_TRADES              = 0x002,
 	LOG_TRADES              = 0x002,

+ 244 - 220
src/map/mail.c

@@ -2,9 +2,6 @@
 // For more information, see LICENCE in the main folder
 // For more information, see LICENCE in the main folder
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
-// Mail System for eAthena SQL
-// Created by Valaris
-// moved all strings to msg_athena.conf [Lupus]
 
 
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/socket.h"
 #include "../common/socket.h"
@@ -27,318 +24,345 @@
 
 
 int MAIL_CHECK_TIME = 120000;
 int MAIL_CHECK_TIME = 120000;
 int mail_timer;
 int mail_timer;
-//extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
 
 
-int mail_check(struct map_session_data *sd,int type)
+/// type: 0 - mail check at login, silent if there aren't any new messages
+///       1 - @checkmail, just print the number of messages
+///       2 - @listmail, shows both read and unread messages
+///       3 - @listnewmail, shows only unread messages
+int mail_check(struct map_session_data* sd, int type)
 {
 {
-	int i = 0, new_ = 0, priority = 0;
+	int i = 0, new_ = 0, priority = 0; // counters
 	char message[80];
 	char message[80];
 
 
 	nullpo_retr (0, sd);
 	nullpo_retr (0, sd);
 
 
-	sprintf(tmp_sql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` "
-		"FROM `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id`", mail_db, sd->status.account_id);
-
-	if (mysql_query(&mail_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	// retrieve all existing messages for this player
+	if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` FROM `%s` WHERE `to_account_id` = %d ORDER by `message_id`", mail_db, sd->status.account_id) )
+	{
+		Sql_ShowDebug(mail_handle);
 		return 0;
 		return 0;
 	}
 	}
 
 
-   	mail_res = mysql_store_result(&mail_handle);
-	if(mail_res) {
-		if (mysql_num_rows(mail_res) == 0) {
-			//clif_displaymessage(sd->fd,"You have no messages.");
-			clif_displaymessage(sd->fd, msg_txt(516));
+	if( Sql_NumRows(mail_handle) == 0)
+	{
+		clif_displaymessage(sd->fd, msg_txt(516)); // "You have no messages."
+		Sql_FreeResult(mail_handle);
+		return 0;
+	}
 
 
-			mysql_free_result(mail_res);
-			return 0;
+	while( SQL_SUCCESS == Sql_NextRow(mail_handle) )
+	{
+		char* data;
+		int message_id;
+		int to_account_id;
+		char from_char_name[NAME_LENGTH];
+		bool read_flag, priority_flag, check_flag;
+
+		Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data);
+		Sql_GetData(mail_handle, 1, &data, NULL); to_account_id = atoi(data);
+		Sql_GetData(mail_handle, 2, &data, NULL); safestrncpy(from_char_name, data, sizeof(from_char_name));
+		Sql_GetData(mail_handle, 3, &data, NULL); read_flag = (bool) atoi(data);
+		Sql_GetData(mail_handle, 4, &data, NULL); priority_flag = (bool) atoi(data);
+		Sql_GetData(mail_handle, 5, &data, NULL); check_flag = (bool) atoi(data);
+
+		i++;
+
+		if( !check_flag )
+		{
+			// mark this message as checked
+			if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) )
+				Sql_ShowDebug(mail_handle);
 		}
 		}
 
 
-		while ((mail_row = mysql_fetch_row(mail_res))) {
-			i++;
-			if(!atoi(mail_row[5])) {
-				sprintf(tmp_sql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
-				if(mysql_query(&mail_handle, tmp_sql) ) {
-					ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-					ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		if( !read_flag )
+		{
+			new_++;
+			if(priority_flag)
+				priority++;
+
+			if( type == 2 || type == 3 )
+			{
+				if( priority_flag )
+				{
+					snprintf(message, 80, msg_txt(511), i, from_char_name);
+					clif_displaymessage(sd->fd, message); // "%d - From : %s (New - Priority)"
 				}
 				}
-			}
-
-			if(!atoi(mail_row[3])) {
-				new_++;
-				if(atoi(mail_row[4]))
-					priority++;
-				if(type==2 || type==3) {
-					if(atoi(mail_row[4])) {
-						snprintf(message, 80, msg_txt(511), i, mail_row[2]);
-						clif_displaymessage(sd->fd, message);
-					} else {
-						//sprintf(message, "%d - From : %s (New)", i, mail_row[2]);
-						snprintf(message, 80, msg_txt(512), i, mail_row[2]);
-						clif_displaymessage(sd->fd, message);
-					}
+				else
+				{
+					snprintf(message, 80, msg_txt(512), i, from_char_name);
+					clif_displaymessage(sd->fd, message); // "%d - From : %s (New)"
 				}
 				}
-			} else if(type==2){
-				snprintf(message, 80, msg_txt(513), i, mail_row[2]);
-				clif_displaymessage(sd->fd, message);
 			}
 			}
 		}
 		}
+		else if( type == 2 )
+		{
+			snprintf(message, 80, msg_txt(513), i, from_char_name);
+			clif_displaymessage(sd->fd, message); // "%d - From : %s"
+		}
+	}
 
 
-		mysql_free_result(mail_res);
-	} else {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		return 0;
-    }
-
-	if(i>0 && new_>0 && type==1) {
-		//sprintf(message, "You have %d new messages.", new_);
+	Sql_FreeResult(mail_handle);
+	
+	if( new_ > 0 && (type == 0 || type == 1) )
+	{
 		sprintf(message, msg_txt(514), new_);
 		sprintf(message, msg_txt(514), new_);
-
-		clif_displaymessage(sd->fd, jstrescape(message));
-	}
-	if(i>0 && new_>0 && priority>0 && type==1) {
-		//sprintf(message, "You have %d unread priority messages.", priority);
-		sprintf(message, msg_txt(515), priority);
-		clif_displaymessage(sd->fd, jstrescape(message));
+		clif_displaymessage(sd->fd, message); // "You have %d unread messages."
+		if (priority > 0)
+		{
+			sprintf(message, msg_txt(515), priority);
+			clif_displaymessage(sd->fd, message); // "You have %d unread priority messages."
+		}
 	}
 	}
-	if(!new_) {
-		//clif_displaymessage(sd->fd, "You have no new messages.");
-		clif_displaymessage(sd->fd, msg_txt(516));
+	if( new_ == 0 && type != 0 )
+	{
+		clif_displaymessage(sd->fd, msg_txt(516)); // "You have no unread messages."
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-int mail_read(struct map_session_data *sd, int message_id)
+/// displays the selected message
+int mail_read(struct map_session_data* sd, int index)
 {
 {
-
+	char* data;
+	int message_id;
+	char from_char_name[NAME_LENGTH];
 	char message[80];
 	char message[80];
+	bool read_flag, priority_flag, check_flag;
+	char output[100];
 
 
-	nullpo_retr (0, sd);
+	nullpo_retr(0, sd);
 
 
-	sprintf(tmp_sql,"SELECT `message_id`,`to_account_id`,`from_char_name`,`message`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1);
+	// retrieve the 'index'-th message 
+	if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`from_char_name`,`message`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = %d ORDER by `message_id` LIMIT %d, 1", mail_db, sd->status.account_id, index-1) )
+	{
+		Sql_ShowDebug(mail_handle);
+		return 0;
+	}
 
 
-	if (mysql_query(&mail_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( 0 == Sql_NumRows(mail_handle) )
+	{
+		clif_displaymessage(sd->fd, msg_txt(517)); // "Message not found."
+		Sql_FreeResult(mail_handle);
 		return 0;
 		return 0;
-   	}
-
-   	mail_res = mysql_store_result(&mail_handle);
-	if(mail_res) {
-		if (mysql_num_rows(mail_res) == 0) {
-			mysql_free_result(mail_res);
-			//clif_displaymessage(sd->fd, "Message not found.");
-			clif_displaymessage(sd->fd, msg_txt(517));
-		       return 0;
-		}
+	}
 
 
-		if ((mail_row = mysql_fetch_row(mail_res))) {
-			if(!atoi(mail_row[6])) {
-				sprintf(tmp_sql,"UPDATE `%s` SET `check_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
-				if(mysql_query(&mail_handle, tmp_sql) ) {
-					ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-					ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-				}
-			}
+	if( SQL_ERROR == Sql_NextRow(mail_handle) )
+	{
+		Sql_ShowDebug(mail_handle);
+		Sql_FreeResult(mail_handle);
+		return 0;
+	}
 
 
-			//sprintf(message, "Reading message from %s", mail_row[2]);
-			sprintf(message, msg_txt(518), mail_row[2]);
-			clif_displaymessage(sd->fd, jstrescape(message));
+	Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data);
+	Sql_GetData(mail_handle, 1, &data, NULL); safestrncpy(from_char_name, data, sizeof(from_char_name));
+	Sql_GetData(mail_handle, 2, &data, NULL); safestrncpy(message, data, sizeof(message));
+	Sql_GetData(mail_handle, 3, &data, NULL); read_flag = (bool) atoi(data);
+	Sql_GetData(mail_handle, 4, &data, NULL); priority_flag = (bool) atoi(data);
+	Sql_GetData(mail_handle, 5, &data, NULL); check_flag = (bool) atoi(data);
 
 
-			sprintf(message, "%s", mail_row[3]);
-			clif_displaymessage(sd->fd, jstrescape(message));
+	Sql_FreeResult(mail_handle);
 
 
-			sprintf(tmp_sql,"UPDATE `%s` SET `read_flag`='1' WHERE `message_id`= \"%d\"", mail_db, atoi(mail_row[0]));
-			if(mysql_query(&mail_handle, tmp_sql) ) {
-				ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
-		}
+	// mark mail as checked
+	if( !check_flag )
+	{
+		if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) )
+		Sql_ShowDebug(mail_handle);
+	}
 
 
-		mysql_free_result(mail_res);
+	sprintf(output, msg_txt(518), from_char_name);
+	clif_displaymessage(sd->fd, output); // "Reading message from %s"
+	clif_displaymessage(sd->fd, message);
 
 
-	} else {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-    }
+	if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `read_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) )
+	{
+		Sql_ShowDebug(mail_handle);
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-int mail_delete(struct map_session_data *sd, int message_id)
+/// message deletion
+int mail_delete(struct map_session_data* sd, int index)
 {
 {
+	char* data;
+	int message_id;
+	bool read_flag, priority_flag, check_flag;
+
 	nullpo_retr (0, sd);
 	nullpo_retr (0, sd);
 
 
-	sprintf(tmp_sql,"SELECT `message_id`,`to_account_id`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = \"%d\" ORDER by `message_id` LIMIT %d, 1",mail_db,sd->status.account_id,message_id-1);
+	if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = %d ORDER by `message_id` LIMIT %d, 1", mail_db, sd->status.account_id, index-1) )
+	{
+		Sql_ShowDebug(mail_handle);
+		return 0;
+	}
 
 
-	if (mysql_query(&mail_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( 0 == Sql_NumRows(mail_handle) )
+	{
+		clif_displaymessage(sd->fd, msg_txt(517)); // "Message not found."
+		Sql_FreeResult(mail_handle);
 		return 0;
 		return 0;
-   	}
-
-   	mail_res = mysql_store_result(&mail_handle);
-	if(mail_res) {
-		if (mysql_num_rows(mail_res) == 0) {
-			mysql_free_result(mail_res);
-			//clif_displaymessage(sd->fd, "Message not found.");
-			clif_displaymessage(sd->fd, msg_txt(517));
-			return 0;
-		}
+	}
+
+	if( SQL_ERROR == Sql_NextRow(mail_handle) )
+	{
+		Sql_ShowDebug(mail_handle);
+		Sql_FreeResult(mail_handle);
+		return 0;
+	}
 
 
-		if ((mail_row = mysql_fetch_row(mail_res))) {
-			if(!atoi(mail_row[2]) && atoi(mail_row[3])) {
-				mysql_free_result(mail_res);
-				//clif_displaymessage(sd->fd,"Cannot delete unread priority mail.");
-				clif_displaymessage(sd->fd,msg_txt(519));
+	Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data);
+	Sql_GetData(mail_handle, 1, &data, NULL); read_flag = (bool)atoi(data);
+	Sql_GetData(mail_handle, 2, &data, NULL); priority_flag = (bool)atoi(data);
+	Sql_GetData(mail_handle, 3, &data, NULL); check_flag = (bool)atoi(data);
 
 
-				return 0;
-			}
-			if(!atoi(mail_row[4])) {
-				mysql_free_result(mail_res);
-				//clif_displaymessage(sd->fd,"You have received new mail, use @listmail before deleting.");
-				clif_displaymessage(sd->fd,msg_txt(520));
-				return 0;
-			}
-			sprintf(tmp_sql,"DELETE FROM `%s` WHERE `message_id` = \"%d\"", mail_db, atoi(mail_row[0]));
-			if(mysql_query(&mail_handle, tmp_sql) ) {
-				mysql_free_result(mail_res);
-				ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-				return 0;
-			}
-			//else clif_displaymessage(sd->fd,"Message deleted.");
-			else clif_displaymessage(sd->fd,msg_txt(521));
-		}
+	Sql_FreeResult(mail_handle);
 
 
-		mysql_free_result(mail_res);
+	if( !read_flag && priority_flag )
+	{
+		clif_displaymessage(sd->fd,msg_txt(519)); // "Cannot delete unread priority mail."
+		return 0;
+	}
 
 
-	} else {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	if( !check_flag )
+	{
+		clif_displaymessage(sd->fd,msg_txt(520)); // "You have received new mail, use @listmail before deleting."
+		return 0;
 	}
 	}
 
 
+	if( SQL_ERROR == Sql_Query(mail_handle, "DELETE FROM `%s` WHERE `message_id` = %d", mail_db, message_id) )
+	{
+		Sql_ShowDebug(mail_handle);
+		return 0;
+	}
+
+	clif_displaymessage(sd->fd,msg_txt(521)); // "Message deleted."
+
 	return 0;
 	return 0;
 }
 }
 
 
-int mail_send(struct map_session_data *sd, char *name, char *message, int flag)
+/// for sending normal and priority messages
+int mail_send(struct map_session_data* sd, char* name, char* message, int flag)
 {
 {
+	SqlStmt* stmt;
+
 	nullpo_retr (0, sd);
 	nullpo_retr (0, sd);
 
 
-	if(pc_isGM(sd) < 80 && sd->mail_counter > 0) {
-		//clif_displaymessage(sd->fd,"You must wait 10 minutes before sending another message");
-		clif_displaymessage(sd->fd,msg_txt(522));
+	if( pc_isGM(sd) < 80 && sd->mail_counter > 0 )
+	{
+		clif_displaymessage(sd->fd,msg_txt(522)); // "You must wait 10 minutes before sending another message"
+		return 0;
+	}
+
+	if( strcmp(name,"*") == 0 && pc_isGM(sd) < 80 )
+	{
+		clif_displaymessage(sd->fd, msg_txt(523)); // "Access Denied."
 		return 0;
 		return 0;
 	}
 	}
 
 
-	if(strcmp(name,"*")==0) {
-		if(pc_isGM(sd) < 80) {
-			//clif_displaymessage(sd->fd, "Access Denied.");
-			clif_displaymessage(sd->fd, msg_txt(523));
+	if( strcmp(name,"*") == 0 )
+	{
+		if( SQL_ERROR == Sql_Query(mail_handle, "SELECT DISTINCT `account_id` FROM `%s` WHERE `account_id` != '%d' ORDER BY `account_id`", char_db, sd->status.account_id) )
+		{
+			Sql_ShowDebug(mail_handle);
 			return 0;
 			return 0;
 		}
 		}
-		else
-			sprintf(tmp_sql,"SELECT DISTINCT `account_id` FROM `%s` WHERE `account_id` <> '%d' ORDER BY `account_id`", char_db, sd->status.account_id);
 	}
 	}
 	else
 	else
-		sprintf(tmp_sql,"SELECT `account_id`,`name` FROM `%s` WHERE `name` = \"%s\"", char_db, jstrescape(name));
-
-	if (mysql_query(&mail_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		return 0;
-  	}
-
-   	mail_res = mysql_store_result(&mail_handle);
-	if(mail_res) {
-		if (mysql_num_rows(mail_res) == 0) {
-			mysql_free_result(mail_res);
-			//clif_displaymessage(sd->fd,"Character does not exist.");
-			clif_displaymessage(sd->fd,msg_txt(524));
+	{
+		char name_[2*NAME_LENGTH];
+		Sql_EscapeString(mail_handle, name_, name);
+		if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `account_id` FROM `%s` WHERE `name` = '%s'", char_db, name_) )
+		{
+			Sql_ShowDebug(mail_handle);
 			return 0;
 			return 0;
 		}
 		}
+	}
 
 
-		while ((mail_row = mysql_fetch_row(mail_res))) {
-			if(strcmp(name,"*")==0) {
-				sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`to_account_id`,`from_account_id`,`from_char_name`,`message`,`priority`)"
-					" VALUES ('%d', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), sd->status.account_id, sd->status.name, jstrescape(message), flag);
-			}
-			else {
-				sprintf(tmp_sql, "INSERT DELAYED INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`)"
-					" VALUES ('%d', '%s', '%d', '%s', '%s', '%d')",mail_db, atoi(mail_row[0]), mail_row[1], sd->status.account_id, sd->status.name, jstrescape(message), flag);
-				if(pc_isGM(sd) < 80)
-					sd->mail_counter=5;
-			}
+	if( 0 == Sql_NumRows(mail_handle) )
+	{
+		clif_displaymessage(sd->fd,msg_txt(524)); // "Character does not exist."
+		Sql_FreeResult(mail_handle);
+		return 0;
+	}
 
 
-			if(mysql_query(&mail_handle, tmp_sql) ) {
-				mysql_free_result(mail_res);
-				ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-				return 0;
-			}
-		}
+	stmt = SqlStmt_Malloc(mail_handle);
+	SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`) VALUES (?, ?, '%d', ?, ?, '%d')", mail_db, sd->status.account_id, flag);
+	SqlStmt_BindParam(stmt, 1, SQLDT_STRING, name, strnlen(name, NAME_LENGTH));
+	SqlStmt_BindParam(stmt, 2, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH));
+	SqlStmt_BindParam(stmt, 3, SQLDT_STRING, message, strnlen(message, 80));
+
+	while( SQL_SUCCESS == Sql_NextRow(mail_handle) )
+	{
+		int id;
+		char* data;
+		Sql_GetData(mail_handle, 0, &data, NULL); id = atoi(data);
+		SqlStmt_BindParam(stmt, 0, SQLDT_INT, &id, sizeof(id));
+		if( SQL_ERROR == SqlStmt_Execute(stmt) )
+			SqlStmt_ShowDebug(stmt);
 	}
 	}
+	Sql_FreeResult(mail_handle);
+	SqlStmt_Free(stmt);
 
 
-	//clif_displaymessage(sd->fd,"Mail has been sent.");
-	clif_displaymessage(sd->fd,msg_txt(525));
+	if(pc_isGM(sd) < 80)
+		sd->mail_counter = 5;
+
+	clif_displaymessage(sd->fd,msg_txt(525)); // "Mail has been sent."
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int mail_check_timer_sub(struct map_session_data *sd, va_list va)
+/// invoked every MAIL_CHECK_TIME ms, decreases the send blocking counter
+static int mail_check_timer_sub(struct map_session_data* sd, va_list va)
 {
 {
-	int id = va_arg(va, int);
-	if(pc_isGM(sd) < 80 && sd->mail_counter > 0)
+	if(sd->mail_counter > 0)
 		sd->mail_counter--;
 		sd->mail_counter--;
-	if(sd->status.account_id==id)
-		clif_displaymessage(sd->fd, msg_txt(526)); //you got new email.
 	return 0;
 	return 0;
 }
 }
 
 
-int mail_check_timer(int tid,unsigned int tick,int id,int data)
+/// periodically checks for new messages and notifies about them
+int mail_check_timer(int tid, unsigned int tick, int id, int data)
 {
 {
 	if(mail_timer != tid)
 	if(mail_timer != tid)
 		return 0;
 		return 0;
 
 
-	sprintf(tmp_sql,"SELECT DISTINCT `to_account_id` FROM `%s` WHERE `read_flag` = '0' AND `check_flag` = '0'", mail_db);
+	mail_timer = add_timer(gettick() + MAIL_CHECK_TIME, mail_check_timer, 0, 0);
 
 
-	if (mysql_query(&mail_handle, tmp_sql)) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
+	// fetch account ids of people who received new mail since the last iteration
+	if( SQL_ERROR == Sql_Query(mail_handle, "SELECT DISTINCT `to_account_id` FROM `%s` WHERE `read_flag` = '0' AND `check_flag` = '0'", mail_db) )
+	{
+		Sql_ShowDebug(mail_handle);
 		return 0;
 		return 0;
-   	}
+	}
 
 
-	mail_res = mysql_store_result(&mail_handle);
+	while( SQL_SUCCESS == Sql_NextRow(mail_handle) )
+	{
+		char* id;
+		struct map_session_data* sd;
+		Sql_GetData(mail_handle, 0, &id, NULL);
+		if( (sd = map_id2sd(atoi(id))) != NULL )
+			clif_displaymessage(sd->fd, msg_txt(526)); // "You have new mail."
+	}
 
 
-	if (mail_res) {
-		if (mysql_num_rows(mail_res) == 0) {
-			mysql_free_result(mail_res);
-			mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
-			return 0;
-		}
+	Sql_FreeResult(mail_handle);
 
 
-		while ((mail_row = mysql_fetch_row(mail_res)))
-			clif_foreachclient(mail_check_timer_sub, atoi(mail_row[0]));
-	}
+	// decrease the send-blocking counter
+	clif_foreachclient(mail_check_timer_sub);
 
 
-	sprintf(tmp_sql,"UPDATE `%s` SET `check_flag`='1' WHERE `check_flag`= '0' ", mail_db);
-	if(mysql_query(&mail_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-	}
+	// The 'check_flag' indicates whether the player was informed about the message.
+	// All online players were notified by the above code, and offline players will get the notice at next login.
+	// Therefore it is safe to simply set the flag to '1' for all existing mails.
+	if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `check_flag` = 0", mail_db) )
+		Sql_ShowDebug(mail_handle);
 
 
-	mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
 	return 0;
 	return 0;
 }
 }
 
 
 int do_init_mail(void)
 int do_init_mail(void)
 {
 {
-	add_timer_func_list(mail_check_timer,"mail_check_timer");
-	mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
+	add_timer_func_list(mail_check_timer, "mail_check_timer");
+	mail_timer = add_timer(gettick() + MAIL_CHECK_TIME, mail_check_timer, 0, 0);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 2
src/map/mail.h

@@ -5,8 +5,8 @@
 #define _MAIL_H_
 #define _MAIL_H_
 
 
 int mail_check(struct map_session_data *sd, int type);
 int mail_check(struct map_session_data *sd, int type);
-int mail_read(struct map_session_data *sd, int message_id);
-int mail_delete(struct map_session_data *sd, int message_id);
+int mail_read(struct map_session_data *sd, int index);
+int mail_delete(struct map_session_data *sd, int index);
 int mail_send(struct map_session_data *sd, char *name, char *message, int flag);
 int mail_send(struct map_session_data *sd, char *name, char *message, int flag);
 
 
 int do_init_mail(void);
 int do_init_mail(void);

+ 58 - 80
src/map/map.c

@@ -11,6 +11,7 @@
 #include "../common/version.h"
 #include "../common/version.h"
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "map.h"
 #include "map.h"
 #include "chrif.h"
 #include "chrif.h"
@@ -34,11 +35,8 @@
 #include "mercenary.h"	//[orn]
 #include "mercenary.h"	//[orn]
 #include "atcommand.h"
 #include "atcommand.h"
 #include "charcommand.h"
 #include "charcommand.h"
-
 #include "log.h"
 #include "log.h"
-
 #include "irc.h"
 #include "irc.h"
-
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
@@ -50,10 +48,20 @@
 #endif
 #endif
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
-
 #include "mail.h"
 #include "mail.h"
+#endif
 
 
-char tmp_sql[65535]="";
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+
+#ifndef TXT_ONLY
 char default_codepage[32] = "";
 char default_codepage[32] = "";
 
 
 int map_server_port = 3306;
 int map_server_port = 3306;
@@ -61,9 +69,7 @@ char map_server_ip[32] = "127.0.0.1";
 char map_server_id[32] = "ragnarok";
 char map_server_id[32] = "ragnarok";
 char map_server_pw[32] = "ragnarok";
 char map_server_pw[32] = "ragnarok";
 char map_server_db[32] = "ragnarok";
 char map_server_db[32] = "ragnarok";
-MYSQL mmysql_handle;
-MYSQL_RES* sql_res;
-MYSQL_ROW sql_row;
+Sql* mmysql_handle;
 
 
 int db_use_sqldbs = 0;
 int db_use_sqldbs = 0;
 char item_db_db[32] = "item_db";
 char item_db_db[32] = "item_db";
@@ -79,9 +85,7 @@ int log_db_port = 3306;
 char log_db_id[32] = "ragnarok";
 char log_db_id[32] = "ragnarok";
 char log_db_pw[32] = "ragnarok";
 char log_db_pw[32] = "ragnarok";
 char log_db[32] = "log";
 char log_db[32] = "log";
-MYSQL logmysql_handle;
-MYSQL_RES* logsql_res;
-MYSQL_ROW logsql_row;
+Sql* logmysql_handle;
 
 
 // mail system
 // mail system
 int mail_server_enable = 0;
 int mail_server_enable = 0;
@@ -91,9 +95,7 @@ char mail_server_id[32] = "ragnarok";
 char mail_server_pw[32] = "ragnarok";
 char mail_server_pw[32] = "ragnarok";
 char mail_server_db[32] = "ragnarok";
 char mail_server_db[32] = "ragnarok";
 char mail_db[32] = "mail";
 char mail_db[32] = "mail";
-MYSQL mail_handle;
-MYSQL_RES* mail_res;
-MYSQL_ROW mail_row;
+Sql* mail_handle;
 
 
 #endif /* not TXT_ONLY */
 #endif /* not TXT_ONLY */
 
 
@@ -1096,7 +1098,7 @@ int map_foreachinpath(int (*func)(struct block_list*,va_list),int m,int x0,int y
 	if (length)
 	if (length)
 	{	//Adjust final position to fit in the given area.
 	{	//Adjust final position to fit in the given area.
 		//TODO: Find an alternate method which does not requires a square root calculation.
 		//TODO: Find an alternate method which does not requires a square root calculation.
-		k = sqrt(magnitude2);
+		k = (int)sqrt(magnitude2);
 		mx1 = x0 + (x1 - x0)*length/k;
 		mx1 = x0 + (x1 - x0)*length/k;
 		my1 = y0 + (y1 - y0)*length/k;
 		my1 = y0 + (y1 - y0)*length/k;
 		len_limit = MAGNITUDE2(x0,y0, mx1,my1);
 		len_limit = MAGNITUDE2(x0,y0, mx1,my1);
@@ -2951,43 +2953,30 @@ int inter_config_read(char *cfgName)
  *---------------------------------------*/
  *---------------------------------------*/
 int map_sql_init(void)
 int map_sql_init(void)
 {
 {
-	mysql_init(&mmysql_handle);
+	// main db connection
+	mmysql_handle = Sql_Malloc();
 
 
-	//DB connection start
 	ShowInfo("Connecting to the Map DB Server....\n");
 	ShowInfo("Connecting to the Map DB Server....\n");
-	if(!mysql_real_connect(&mmysql_handle, map_server_ip, map_server_id, map_server_pw,
-		map_server_db ,map_server_port, (char *)NULL, 0)) {
-			//pointer check
-			ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-			exit(1);
-	}
-	else {
-		ShowStatus("connect success! (Map Server Connection)\n");
-	}
+	if( SQL_ERROR == Sql_Connect(mmysql_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db) )
+		exit(1);
+	ShowStatus("connect success! (Map Server Connection)\n");
 
 
-	if(mail_server_enable) { // mail system [Valaris]
-		mysql_init(&mail_handle);
-	        ShowInfo("Connecting to the Mail DB Server....\n");
-		if(!mysql_real_connect(&mail_handle, mail_server_ip, mail_server_id, mail_server_pw,
-			mail_server_db ,mail_server_port, (char *)NULL, 0)) {
-				ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-				exit(1);
-		}
-		if( strlen(default_codepage) > 0 ) {
-			sprintf( tmp_sql, "SET NAMES %s", default_codepage );
-			if (mysql_query(&mail_handle, tmp_sql)) {
-				ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
-		}
-	}
+	if( strlen(default_codepage) > 0 )
+		if ( SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage) )
+			Sql_ShowDebug(mmysql_handle);
 
 
-	if( strlen(default_codepage) > 0 ) {
-		sprintf( tmp_sql, "SET NAMES %s", default_codepage );
-		if (mysql_query(&mmysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	if(mail_server_enable)
+	{ 
+		// mail system
+		mail_handle = Sql_Malloc();
+
+		ShowInfo("Connecting to the Mail DB Server....\n");
+		if( SQL_ERROR == Sql_Connect(mail_handle, mail_server_id, mail_server_pw, mail_server_ip, mail_server_port, mail_server_db) )
+			exit(1);
+
+		if( strlen(default_codepage) > 0 )
+			if ( SQL_ERROR == Sql_SetEncoding(mail_handle, default_codepage) )
+				Sql_ShowDebug(mail_handle);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -2995,13 +2984,15 @@ int map_sql_init(void)
 
 
 int map_sql_close(void)
 int map_sql_close(void)
 {
 {
-	mysql_close(&mmysql_handle);
 	ShowStatus("Close Map DB Connection....\n");
 	ShowStatus("Close Map DB Connection....\n");
+	Sql_Free(mmysql_handle);
+	mmysql_handle = NULL;
 
 
 	if (log_config.sql_logs)
 	if (log_config.sql_logs)
 	{
 	{
-		mysql_close(&logmysql_handle);
 		ShowStatus("Close Log DB Connection....\n");
 		ShowStatus("Close Log DB Connection....\n");
+		Sql_Free(logmysql_handle);
+		logmysql_handle = NULL;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -3009,25 +3000,18 @@ int map_sql_close(void)
 
 
 int log_sql_init(void)
 int log_sql_init(void)
 {
 {
-    mysql_init(&logmysql_handle);
+	// log db connection
+	logmysql_handle = Sql_Malloc();
 
 
-	//DB connection start
 	ShowInfo(""CL_WHITE"[SQL]"CL_RESET": Connecting to the Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db,log_db_ip);
 	ShowInfo(""CL_WHITE"[SQL]"CL_RESET": Connecting to the Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db,log_db_ip);
-	if(!mysql_real_connect(&logmysql_handle, log_db_ip, log_db_id, log_db_pw,
-		log_db ,log_db_port, (char *)NULL, 0)) {
-			//pointer check
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			exit(1);
-	}
-  
+	if ( SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db) )
+		exit(1);
 	ShowStatus(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db);
 	ShowStatus(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db);
-	if( strlen(default_codepage) > 0 ) {
-		sprintf( tmp_sql, "SET NAMES %s", default_codepage );
-		if (mysql_query(&logmysql_handle, tmp_sql)) {
-			ShowSQL("DB error - %s\n",mysql_error(&logmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-	}
+
+	if( strlen(default_codepage) > 0 )
+		if ( SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage) )
+			Sql_ShowDebug(logmysql_handle);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -3037,31 +3021,25 @@ int log_sql_init(void)
 int map_sql_ping(int tid, unsigned int tick, int id, int data) 
 int map_sql_ping(int tid, unsigned int tick, int id, int data) 
 {
 {
 	ShowInfo("Pinging SQL server to keep connection alive...\n");
 	ShowInfo("Pinging SQL server to keep connection alive...\n");
-	mysql_ping(&mmysql_handle);
+	Sql_Ping(mmysql_handle);
 	if (log_config.sql_logs)
 	if (log_config.sql_logs)
-		mysql_ping(&logmysql_handle);
+		Sql_Ping(logmysql_handle);
 	if(mail_server_enable)
 	if(mail_server_enable)
-		mysql_ping(&mail_handle);
+		Sql_Ping(mail_handle);
 	return 0;
 	return 0;
 }
 }
 
 
 int sql_ping_init(void)
 int sql_ping_init(void)
 {
 {
-	int connection_timeout, connection_ping_interval;
+	uint32 connection_timeout, connection_ping_interval;
 
 
-	// set a default value first
+	// set a default value
 	connection_timeout = 28800; // 8 hours
 	connection_timeout = 28800; // 8 hours
 
 
 	// ask the mysql server for the timeout value
 	// ask the mysql server for the timeout value
-	if (!mysql_query(&mmysql_handle, "SHOW VARIABLES LIKE 'wait_timeout'")
-	&& (sql_res = mysql_store_result(&mmysql_handle)) != NULL) {
-		sql_row = mysql_fetch_row(sql_res);
-		if (sql_row)
-			connection_timeout = atoi(sql_row[1]);
-		if (connection_timeout < 60)
-			connection_timeout = 60;
-		mysql_free_result(sql_res);
-	}
+	Sql_GetTimeout(mmysql_handle, &connection_timeout);
+	if (connection_timeout < 60)
+		connection_timeout = 60;
 
 
 	// establish keepalive
 	// establish keepalive
 	connection_ping_interval = connection_timeout - 30; // 30-second reserve
 	connection_ping_interval = connection_timeout - 30; // 30-second reserve

+ 21 - 32
src/map/map.h

@@ -795,7 +795,7 @@ struct map_session_data {
 	char fakename[NAME_LENGTH]; // fake names [Valaris]
 	char fakename[NAME_LENGTH]; // fake names [Valaris]
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
-	int mail_counter;	// mail counter for mail system [Valaris]
+	int mail_counter;	// mail counter for mail system (antiflood protection)
 #endif
 #endif
 
 
 	int duel_group; // duel vars [LuzZza]
 	int duel_group; // duel vars [LuzZza]
@@ -1396,37 +1396,6 @@ extern char *MSG_CONF_NAME;
 
 
 extern char *map_server_dns;
 extern char *map_server_dns;
 
 
-#ifndef TXT_ONLY
-
-#ifdef WIN32
-#include <winsock2.h>
-#endif
-#include <mysql.h>
-
-extern char tmp_sql[65535];
-
-extern int db_use_sqldbs;
-extern MYSQL mmysql_handle;
-extern MYSQL_RES*	sql_res ;
-extern MYSQL_ROW	sql_row ;
-
-extern MYSQL logmysql_handle;
-extern MYSQL_RES*	logsql_res ;
-extern MYSQL_ROW	logsql_row ;
-
-extern int mail_server_enable;
-extern MYSQL mail_handle;
-extern MYSQL_RES* 	mail_res ;
-extern MYSQL_ROW	mail_row ;
-
-extern char item_db_db[32];
-extern char item_db2_db[32];
-extern char mob_db_db[32];
-extern char mob_db2_db[32];
-extern char char_db[32];
-extern char mail_db[32];
-
-#endif /* not TXT_ONLY */
 //Useful typedefs from jA [Skotlex]
 //Useful typedefs from jA [Skotlex]
 typedef struct map_session_data TBL_PC;
 typedef struct map_session_data TBL_PC;
 typedef struct npc_data         TBL_NPC;
 typedef struct npc_data         TBL_NPC;
@@ -1444,4 +1413,24 @@ typedef struct homun_data       TBL_HOM;
 extern int lowest_gm_level;
 extern int lowest_gm_level;
 extern char main_chat_nick[16];
 extern char main_chat_nick[16];
 
 
+#ifndef TXT_ONLY
+
+#include "../common/sql.h"
+
+extern int db_use_sqldbs;
+extern int mail_server_enable;
+
+extern Sql* mmysql_handle;
+extern Sql* logmysql_handle;
+extern Sql* mail_handle;
+
+extern char item_db_db[32];
+extern char item_db2_db[32];
+extern char mob_db_db[32];
+extern char mob_db2_db[32];
+extern char char_db[32];
+extern char mail_db[32];
+
+#endif /* not TXT_ONLY */
+
 #endif /* _MAP_H_ */
 #endif /* _MAP_H_ */

+ 73 - 39
src/map/mob.c

@@ -9,6 +9,7 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 
 
 #include "map.h"
 #include "map.h"
 #include "clif.h"
 #include "clif.h"
@@ -3210,7 +3211,10 @@ static unsigned int mob_drop_adjust(int rate, int rate_adjust, unsigned short ra
 	return cap_value(rate,rate_min,rate_max);
 	return cap_value(rate,rate_min,rate_max);
 }
 }
 
 
-int mob_parse_dbrow(char** str)
+/*==========================================
+ * processes one mobdb entry
+ *------------------------------------------*/
+static bool mob_parse_dbrow(char** str)
 {
 {
 	struct mob_db *db;
 	struct mob_db *db;
 	struct status_data *status;
 	struct status_data *status;
@@ -3220,15 +3224,15 @@ int mob_parse_dbrow(char** str)
 	
 	
 	class_ = str[0] ? atoi(str[0]) : 0;
 	class_ = str[0] ? atoi(str[0]) : 0;
 	if (class_ == 0)
 	if (class_ == 0)
-		return 0; //Leave blank lines alone... [Skotlex]
+		return false; //Leave blank lines alone... [Skotlex]
 	
 	
 	if (class_ <= 1000 || class_ > MAX_MOB_DB) {
 	if (class_ <= 1000 || class_ > MAX_MOB_DB) {
 		ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
 		ShowWarning("Mob with ID: %d not loaded. ID must be in range [%d-%d]\n", class_, 1000, MAX_MOB_DB);
-		return 0;
+		return false;
 	}
 	}
 	if (pcdb_checkid(class_)) {
 	if (pcdb_checkid(class_)) {
 		ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n");
 		ShowWarning("Mob with ID: %d not loaded. That ID is reserved for player classes.\n");
-		return 0;
+		return false;
 	}
 	}
 	
 	
 	if (mob_db_data[class_] == NULL)
 	if (mob_db_data[class_] == NULL)
@@ -3432,7 +3436,7 @@ int mob_parse_dbrow(char** str)
 		}
 		}
 	}
 	}
 	
 	
-	return 1;
+	return true;
 }
 }
 
 
 /*==========================================
 /*==========================================
@@ -3440,83 +3444,113 @@ int mob_parse_dbrow(char** str)
  *------------------------------------------*/
  *------------------------------------------*/
 static int mob_readdb(void)
 static int mob_readdb(void)
 {
 {
-	FILE *fp;
-	char line[1024];
-	char *filename[]={ "mob_db.txt","mob_db2.txt" };
-	int i, fi;
-	unsigned int ln = 0;
+	char* filename[] = { "mob_db.txt", "mob_db2.txt" };
+	int fi;
 	
 	
-	for(fi = 0; fi < 2; fi++) {
-		sprintf(line, "%s/%s", db_path, filename[fi]);
-		fp = fopen(line, "r");
+	for(fi = 0; fi < 2; fi++)
+	{
+		uint32 lines = 0, count = 0;
+		char line[1024];
+		char path[256];
+		FILE* fp;
+		
+		sprintf(path, "%s/%s", db_path, filename[fi]);
+		fp = fopen(path, "r");
 		if(fp == NULL) {
 		if(fp == NULL) {
 			if(fi > 0)
 			if(fi > 0)
 				continue;
 				continue;
 			return -1;
 			return -1;
 		}
 		}
 		
 		
+		// process rows one by one
 		while(fgets(line, sizeof(line), fp))
 		while(fgets(line, sizeof(line), fp))
 		{
 		{
 			char *str[38+2*MAX_MOB_DROP], *p, *np;
 			char *str[38+2*MAX_MOB_DROP], *p, *np;
+			int i;
 			
 			
+			lines++;
 			if(line[0] == '/' && line[1] == '/')
 			if(line[0] == '/' && line[1] == '/')
 				continue;
 				continue;
 			
 			
-			for(i = 0, p = line; i < 38 + 2*MAX_MOB_DROP; i++) {
+			for(i = 0, p = line; i < 38 + 2*MAX_MOB_DROP; i++)
+			{
+				str[i] = p;
 				if((np = strchr(p, ',')) != NULL) {
 				if((np = strchr(p, ',')) != NULL) {
-					str[i] = p; *np = 0; p = np + 1;
-				} else
-					str[i] = p;
+					*np = '\0'; p = np + 1;
+				}
 			}
 			}
 			
 			
 			if(i < 38 + 2*MAX_MOB_DROP) {
 			if(i < 38 + 2*MAX_MOB_DROP) {
-				ShowWarning("mob_readdb: Insufficient columns for mob with ID: %d\n", str[0] ? atoi(str[0]) : 0);
+				ShowWarning("mob_readdb: Insufficient columns for mob with id: %d, skipping.\n", atoi(str[0]));
 				continue;
 				continue;
 			}
 			}
 			
 			
 			if (!mob_parse_dbrow(str))
 			if (!mob_parse_dbrow(str))
 				continue;
 				continue;
 			
 			
-			ln++; // counts the number of correctly parsed entries
+			count++;
 		}
 		}
+
 		fclose(fp);
 		fclose(fp);
-		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, filename[fi]);
-		ln = 0;
+
+		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
 	}
 	}
+
 	return 0;
 	return 0;
 }
 }
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 /*==========================================
 /*==========================================
- * SQL reading
+ * mob_db table reading
  *------------------------------------------*/
  *------------------------------------------*/
 static int mob_read_sqldb(void)
 static int mob_read_sqldb(void)
 {
 {
-	char *mob_db_name[] = { mob_db_db, mob_db2_db };
+	char* mob_db_name[] = { mob_db_db, mob_db2_db };
 	int fi;
 	int fi;
-	unsigned int ln = 0;
 	
 	
-	for (fi = 0; fi < 2; fi++) {
-		sprintf (tmp_sql, "SELECT * FROM `%s`", mob_db_name[fi]);
-		if (mysql_query(&mmysql_handle, tmp_sql)) {
-			ShowSQL("DB error (%s) - %s\n", mob_db_name[fi], mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+	for (fi = 0; fi < 2; fi++)
+	{
+		uint32 lines = 0, count = 0;
+		
+		// retrieve all rows from the mob database
+		if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", mob_db_name[fi]) )
+		{
+			Sql_ShowDebug(mmysql_handle);
 			continue;
 			continue;
 		}
 		}
-		sql_res = mysql_store_result(&mmysql_handle);
-		if (sql_res) {
-			while((sql_row = mysql_fetch_row(sql_res))){
-				
-				if (!mob_parse_dbrow(sql_row))
-					continue;
+		
+		// process rows one by one
+		while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) )
+		{
+			// wrap the result into a TXT-compatible format
+			char line[1024];
+			char* str[38+2*MAX_MOB_DROP];
+			char* p;
+			int i;
+			
+			lines++;
+			for(i = 0, p = line; i < 38 + 2*MAX_MOB_DROP; i++)
+			{
+				char* data;
+				size_t len;
+				Sql_GetData(mmysql_handle, i, &data, &len);
 				
 				
-				ln++; // counts the number of correctly parsed entries
+				strcpy(p, data);
+				str[i] = p;
+				p+= len + 1;
 			}
 			}
 			
 			
-			mysql_free_result(sql_res);
-			ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, mob_db_name[fi]);
-			ln = 0;
+			if (!mob_parse_dbrow(str))
+				continue;
+			
+			count++;
 		}
 		}
+		
+		// free the query result
+		Sql_FreeResult(mmysql_handle);
+		
+		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_db_name[fi]);
+		count = 0;
 	}
 	}
 	return 0;
 	return 0;
 }
 }

+ 1 - 0
src/map/npc.c

@@ -6,6 +6,7 @@
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 #include "../common/db.h"
 #include "../common/db.h"
 #include "map.h"
 #include "map.h"

+ 1 - 0
src/map/party.c

@@ -7,6 +7,7 @@
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
 
 
 #include "party.h"
 #include "party.h"
 #include "atcommand.h"	//msg_txt()
 #include "atcommand.h"	//msg_txt()

+ 2 - 1
src/map/pc.c

@@ -8,6 +8,7 @@
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/socket.h" // RFIFO*()
 #include "../common/socket.h" // RFIFO*()
 #include "../common/timer.h"
 #include "../common/timer.h"
+#include "../common/utils.h"
 
 
 #include "atcommand.h" // get_atcommand_level()
 #include "atcommand.h" // get_atcommand_level()
 #include "battle.h" // battle_config
 #include "battle.h" // battle_config
@@ -742,7 +743,7 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
 
 
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
 	if(mail_server_enable)
 	if(mail_server_enable)
-		mail_check(sd,1); // check mail at login [Valaris]
+		mail_check(sd,0); // check mail at login [Valaris]
 #endif
 #endif
 
 
 	// message of the limited time of the account
 	// message of the limited time of the account

+ 1 - 0
src/map/pet.c

@@ -6,6 +6,7 @@
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/utils.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 
 
 #include "pc.h"
 #include "pc.h"

+ 176 - 196
src/map/script.c

@@ -226,13 +226,10 @@ int potion_hp=0, potion_per_hp=0, potion_sp=0, potion_per_sp=0;
 int potion_target=0;
 int potion_target=0;
 
 
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
-// [zBuffer] SQL Mapreg Saving/Loading Database Declaration
 char mapregsql_db[32] = "mapreg";
 char mapregsql_db[32] = "mapreg";
 char mapregsql_db_varname[32] = "varname";
 char mapregsql_db_varname[32] = "varname";
 char mapregsql_db_index[32] = "index";
 char mapregsql_db_index[32] = "index";
 char mapregsql_db_value[32] = "value";
 char mapregsql_db_value[32] = "value";
-char tmp_sql[65535];
-// --------------------------------------------------------
 #endif
 #endif
 
 
 int get_com(unsigned char *script,int *pos);
 int get_com(unsigned char *script,int *pos);
@@ -3222,85 +3219,76 @@ void run_script_main(struct script_state *st)
 /*==========================================
 /*==========================================
  * マップ変数の変更
  * マップ変数の変更
  *------------------------------------------*/
  *------------------------------------------*/
-int mapreg_setreg(int num,int val)
+int mapreg_setreg(int num, int val)
 {
 {
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
-	int i=num>>24;
-	char *name=str_buf+str_data[num&0x00ffffff].str;
-	char tmp_str[64];
-#endif
+	int i = num >> 24;
+	char* name = str_buf + str_data[num&0x00ffffff].str;
 
 
-	if(val!=0) {
+	if( val != 0 ) {
 		if(idb_put(mapreg_db,num,(void*)val))
 		if(idb_put(mapreg_db,num,(void*)val))
 			;
 			;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
 		else if(name[1] != '@') {
 		else if(name[1] != '@') {
-			sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%d')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,val);
-			if(mysql_query(&mmysql_handle,tmp_sql)){
-				ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+			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`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%d')", mapregsql_db, mapregsql_db_varname, mapregsql_db_index, mapregsql_db_value, tmp_str, i, val) )
+				Sql_ShowDebug(mmysql_handle);
 		}
 		}
-#endif
-	} else { // [zBuffer]
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
+	} else { // val == 0
 		if(name[1] != '@') { // Remove from database because it is unused.
 		if(name[1] != '@') { // Remove from database because it is unused.
-			sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
-			if(mysql_query(&mmysql_handle,tmp_sql)){
-				ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+			if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'", mapregsql_db, mapregsql_db_varname, name, mapregsql_db_index, i) )
+				Sql_ShowDebug(mmysql_handle);
 		}
 		}
-#endif
 		idb_remove(mapreg_db,num);
 		idb_remove(mapreg_db,num);
 	}
 	}
+#else
+	if(val != 0)
+		idb_put(mapreg_db,num,(void*)val);
+	else
+		idb_remove(mapreg_db,num);
+#endif
 
 
-	mapreg_dirty=1;
+	mapreg_dirty = 1;
 	return 1;
 	return 1;
 }
 }
 /*==========================================
 /*==========================================
  * 文字列型マップ変数の変更
  * 文字列型マップ変数の変更
  *------------------------------------------*/
  *------------------------------------------*/
-int mapreg_setregstr(int num,const char *str)
+int mapreg_setregstr(int num, const char* str)
 {
 {
-	char *p;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
-	char tmp_str[64];
-	char tmp_str2[512];
-	int i=num>>24; // [zBuffer]
-	char *name=str_buf+str_data[num&0x00ffffff].str;
-#endif
-
-	if( str==NULL || *str==0 ){
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
 #if !defined(TXT_ONLY) && defined(MAPREGSQL)
+	int i = num >> 24;
+	char* name = str_buf + str_data[num&0x00ffffff].str;
+	
+	if( str==NULL || *str==0 ) {
 		if(name[1] != '@') {
 		if(name[1] != '@') {
-			sprintf(tmp_sql,"DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_varname,name,mapregsql_db_index,i);
-			if(mysql_query(&mmysql_handle,tmp_sql)){
-				ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			}
+			if( SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `%s`='%s' AND `%s`='%d'", mapregsql_db, mapregsql_db_varname, name, mapregsql_db_index, i) )
+				Sql_ShowDebug(mmysql_handle);
 		}
 		}
-#endif
 		idb_remove(mapregstr_db,num);
 		idb_remove(mapregstr_db,num);
-		mapreg_dirty=1;
+		mapreg_dirty = 1;
 		return 1;
 		return 1;
 	}
 	}
-	p=(char *)aMallocA((strlen(str)+1)*sizeof(char));
-	strcpy(p,str);
 	
 	
-	if (idb_put(mapregstr_db,num,p))
+	if (idb_put(mapregstr_db,num, aStrdup(str)))
 		;
 		;
-#if !defined(TXT_ONLY) && defined(MAPREGSQL)
-	else if(name[1] != '@'){ //put returned null, so we must insert.
+	else if(name[1] != '@') { //put returned null, so we must insert.
 		// Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
 		// Someone is causing a database size infinite increase here without name[1] != '@' [Lance]
-		sprintf(tmp_sql,"INSERT INTO `%s`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%s')",mapregsql_db,mapregsql_db_varname,mapregsql_db_index,mapregsql_db_value,jstrescapecpy(tmp_str,name),i,jstrescapecpy(tmp_str2,p));
-		if(mysql_query(&mmysql_handle,tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+		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`(`%s`,`%s`,`%s`) VALUES ('%s','%d','%s')", mapregsql_db, mapregsql_db_varname, mapregsql_db_index, mapregsql_db_value, tmp_str, i, tmp_str2) )
+			Sql_ShowDebug(mmysql_handle);
 	}
 	}
+#else
+	if( str==NULL || *str==0 )
+		idb_remove(mapregstr_db,num);
+	else
+		idb_put(mapregstr_db,num,aStrdup(str));
 #endif
 #endif
-	mapreg_dirty=1;
+
+	mapreg_dirty = 1;
 	return 1;
 	return 1;
 }
 }
 
 
@@ -3310,83 +3298,87 @@ int mapreg_setregstr(int num,const char *str)
 static int script_load_mapreg(void)
 static int script_load_mapreg(void)
 {
 {
 #if defined(TXT_ONLY) || !defined(MAPREGSQL)
 #if defined(TXT_ONLY) || !defined(MAPREGSQL)
-	FILE *fp;
+	FILE* fp;
 	char line[1024];
 	char line[1024];
 
 
-	if( (fp=fopen(mapreg_txt,"rt"))==NULL )
+	if( (fp=fopen(mapreg_txt,"rt")) == NULL )
 		return -1;
 		return -1;
 
 
 	while(fgets(line,sizeof(line),fp))
 	while(fgets(line,sizeof(line),fp))
 	{
 	{
-		char buf1[256],buf2[1024],*p;
+		char buf1[256],buf2[1024];
+		char* p;
 		int n,v,s,i;
 		int n,v,s,i;
 		if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 &&
 		if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 &&
 			(i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) )
 			(i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) )
 			continue;
 			continue;
-		if( buf1[strlen(buf1)-1]=='$' ){
-			if( sscanf(line+n,"%[^\n\r]",buf2)!=1 ){
-				ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
+		if( buf1[strlen(buf1)-1] == '$' ) {
+			if( sscanf(line + n, "%[^\n\r]", buf2) != 1 ) {
+				ShowError("%s: %s broken data !\n", mapreg_txt, buf1);
 				continue;
 				continue;
 			}
 			}
-			p=(char *)aMallocA((strlen(buf2) + 1)*sizeof(char));
-			strcpy(p,buf2);
-			s= add_str(buf1);
-			idb_put(mapregstr_db,(i<<24)|s,p);
-		}else{
-			if( sscanf(line+n,"%d",&v)!=1 ){
-				ShowError("%s: %s broken data !\n",mapreg_txt,buf1);
+			p = aStrdup(buf2);
+			s = add_str(buf1);
+			idb_put(mapregstr_db, (i<<24)|s, p);
+		} else {
+			if( sscanf(line + n, "%d", &v) != 1 ) {
+				ShowError("%s: %s broken data !\n", mapreg_txt, buf1);
 				continue;
 				continue;
 			}
 			}
-			s= add_str(buf1);
-			idb_put(mapreg_db,(i<<24)|s,(void*)v);
+			s = add_str(buf1);
+			idb_put(mapreg_db, (i<<24)|s, (void*)v);
 		}
 		}
 	}
 	}
 	fclose(fp);
 	fclose(fp);
-	mapreg_dirty=0;
+
+	mapreg_dirty = 0;
 	return 0;
 	return 0;
 #else
 #else
-	// SQL mapreg code start [zBuffer]
 	/*
 	/*
-	     0       1       2
-	+-------------------------+
-	| varname | index | value |
-	+-------------------------+
-	*/
-	unsigned int perfomance = (unsigned int)time(NULL);
-	sprintf(tmp_sql,"SELECT * FROM `%s`",mapregsql_db);
-	ShowInfo("Querying script_load_mapreg ...\n");
-	if(mysql_query(&mmysql_handle, tmp_sql) ) {
-		ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
+		     0       1       2
+		+-------------------------+
+		| varname | index | value |
+		+-------------------------+
+	 */
+
+	SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
+	char varname[32+1];
+	int index;
+	char value[255+1];
+	uint32 length;
+
+	if ( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `%s`, `%s`, `%s` FROM `%s`", mapregsql_db_varname, mapregsql_db_index, mapregsql_db_value, mapregsql_db)
+	  || SQL_ERROR == SqlStmt_Execute(stmt)
+	  ) {
+		SqlStmt_ShowDebug(stmt);
+		SqlStmt_Free(stmt);
 		return -1;
 		return -1;
 	}
 	}
-	ShowInfo("Success! Returning results ...\n");
-	sql_res = mysql_store_result(&mmysql_handle);
-	if (sql_res) {
-        while ((sql_row = mysql_fetch_row(sql_res))) {
-			char buf1[33], *p = NULL;
-			int i,v,s;
-			strcpy(buf1,sql_row[0]);
-			if( buf1[strlen(buf1)-1]=='$' ){
-				i = atoi(sql_row[1]);
-				p=(char *)aMallocA((strlen(sql_row[2]) + 1)*sizeof(char));
-				strcpy(p,sql_row[2]);
-				s= add_str(buf1);
-				idb_put(mapregstr_db,(i<<24)|s,p);
-			}else{
-				s= add_str(buf1);
-				v= atoi(sql_row[2]);
-				i = atoi(sql_row[1]);
-				idb_put(mapreg_db,(i<<24)|s,(void *)v);
-			}
-	    }        
+
+	SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], 32, &length, NULL);
+	SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL);
+	SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], 255, NULL, NULL);
+	
+	while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
+	{
+		if( varname[length-1] == '$' ) {
+			int s = add_str(varname);
+			int i = index;
+			char* p = aStrdup(value);
+			idb_put(mapregstr_db, (i<<24)|s, p);
+		} else {
+			int s = add_str(varname);
+			int i = index;
+			int v = atoi(value);
+			idb_put(mapreg_db, (i<<24)|s, (void *)v);			
+		}
 	}
 	}
-	ShowInfo("Freeing results...\n");
-	mysql_free_result(sql_res);
-	mapreg_dirty=0;
-	perfomance = (((unsigned int)time(NULL)) - perfomance);
-	ShowInfo("SQL Mapreg Loading Completed Under %d Seconds.\n",perfomance);
+	
+	SqlStmt_Free(stmt);
+
+	mapreg_dirty = 0;
 	return 0;
 	return 0;
+
 #endif /* TXT_ONLY */
 #endif /* TXT_ONLY */
 }
 }
 /*==========================================
 /*==========================================
@@ -3394,56 +3386,50 @@ static int script_load_mapreg(void)
  *------------------------------------------*/
  *------------------------------------------*/
 static int script_save_mapreg_intsub(DBKey key,void *data,va_list ap)
 static int script_save_mapreg_intsub(DBKey key,void *data,va_list ap)
 {
 {
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
-	FILE *fp=va_arg(ap,FILE*);
 	int num=key.i&0x00ffffff, i=key.i>>24;
 	int num=key.i&0x00ffffff, i=key.i>>24;
 	char *name=str_buf+str_data[num].str;
 	char *name=str_buf+str_data[num].str;
-	if( name[1]!='@' ){
+
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+	FILE *fp=va_arg(ap,FILE*);
+	if( name[1]!='@' ) {
 		if(i==0)
 		if(i==0)
 			fprintf(fp,"%s\t%d\n", name, (int)data);
 			fprintf(fp,"%s\t%d\n", name, (int)data);
 		else
 		else
 			fprintf(fp,"%s,%d\t%d\n", name, i, (int)data);
 			fprintf(fp,"%s,%d\t%d\n", name, i, (int)data);
 	}
 	}
-	return 0;
 #else
 #else
-	int num=key.i&0x00ffffff, i=key.i>>24; // [zBuffer]
-	char *name=str_buf+str_data[num].str;
 	if ( name[1] != '@') {
 	if ( name[1] != '@') {
-		sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%d' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,(int)data,mapregsql_db_varname,name,mapregsql_db_index,i);
-		if(mysql_query(&mmysql_handle, tmp_sql) ) {
-			ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+		if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `%s`='%d' WHERE `%s`='%s' AND `%s`='%d'", mapregsql_db, mapregsql_db_value, (int)data, mapregsql_db_varname, name, mapregsql_db_index, i) )
+			Sql_ShowDebug(mmysql_handle);
 	}
 	}
-	return 0;
 #endif
 #endif
+
+	return 0;
 }
 }
+
 static int script_save_mapreg_strsub(DBKey key,void *data,va_list ap)
 static int script_save_mapreg_strsub(DBKey key,void *data,va_list ap)
 {
 {
-#if defined(TXT_ONLY) || !defined(MAPREGSQL)
-	FILE *fp=va_arg(ap,FILE*);
 	int num=key.i&0x00ffffff, i=key.i>>24;
 	int num=key.i&0x00ffffff, i=key.i>>24;
 	char *name=str_buf+str_data[num].str;
 	char *name=str_buf+str_data[num].str;
-	if( name[1]!='@' ){
+
+#if defined(TXT_ONLY) || !defined(MAPREGSQL)
+	FILE *fp=va_arg(ap,FILE*);
+	if( name[1]!='@' ) {
 		if(i==0)
 		if(i==0)
 			fprintf(fp,"%s\t%s\n", name, (char *)data);
 			fprintf(fp,"%s\t%s\n", name, (char *)data);
 		else
 		else
 			fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data);
 			fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data);
 	}
 	}
-	return 0;
 #else
 #else
-	char tmp_str2[512];
-	int num=key.i&0x00ffffff, i=key.i>>24;
-	char *name=str_buf+str_data[num].str;
 	if ( name[1] != '@') {
 	if ( name[1] != '@') {
-		sprintf(tmp_sql,"UPDATE `%s` SET `%s`='%s' WHERE `%s`='%s' AND `%s`='%d'",mapregsql_db,mapregsql_db_value,jstrescapecpy(tmp_str2,(char *)data),mapregsql_db_varname,name,mapregsql_db_index,i);
-		if(mysql_query(&mmysql_handle, tmp_sql) ) {
-			ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+		char tmp_str2[2*255+1];
+		Sql_EscapeStringLen(mmysql_handle, tmp_str2, (char*)data, strnlen((char*)data, 255));
+		if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `%s`='%s' WHERE `%s`='%s' AND `%s`='%d'", mapregsql_db, mapregsql_db_value, tmp_str2, mapregsql_db_varname, name, mapregsql_db_index, i) )
+			Sql_ShowDebug(mmysql_handle);
 	}
 	}
-	return 0;
 #endif
 #endif
+
+	return 0;
 }
 }
 static int script_save_mapreg(void)
 static int script_save_mapreg(void)
 {
 {
@@ -3459,12 +3445,8 @@ static int script_save_mapreg(void)
 	mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub,fp);
 	mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub,fp);
 	lock_fclose(fp,mapreg_txt,&lock);
 	lock_fclose(fp,mapreg_txt,&lock);
 #else
 #else
-	unsigned int perfomance = (unsigned int)time(NULL);
-	mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub);  // [zBuffer]
+	mapreg_db->foreach(mapreg_db,script_save_mapreg_intsub);
 	mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub);
 	mapregstr_db->foreach(mapregstr_db,script_save_mapreg_strsub);
-	perfomance = ((unsigned int)time(NULL) - perfomance);
-	if(perfomance > 2)
-		ShowWarning("Slow Query: MapregSQL Saving @ %d second(s).\n", perfomance);
 #endif
 #endif
 	mapreg_dirty=0;
 	mapreg_dirty=0;
 	return 0;
 	return 0;
@@ -3688,9 +3670,8 @@ int do_init_script()
 	
 	
 	script_load_mapreg();
 	script_load_mapreg();
 
 
-	add_timer_func_list(script_autosave_mapreg,"script_autosave_mapreg");
-	add_timer_interval(gettick()+MAPREG_AUTOSAVE_INTERVAL,
-		script_autosave_mapreg,0,0,MAPREG_AUTOSAVE_INTERVAL);
+	add_timer_func_list(script_autosave_mapreg, "script_autosave_mapreg");
+	add_timer_interval(gettick() + MAPREG_AUTOSAVE_INTERVAL, script_autosave_mapreg, 0, 0, MAPREG_AUTOSAVE_INTERVAL);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -12098,6 +12079,7 @@ BUILDIN_FUNC(checkcell)
 
 
 // <--- [zBuffer] List of mathematics commands
 // <--- [zBuffer] List of mathematics commands
 // [zBuffer] List of dynamic var commands --->
 // [zBuffer] List of dynamic var commands --->
+//FIXME: some other functions are using this private function
 void setd_sub(struct script_state *st, TBL_PC *sd, char *varname, int elem, void *value, struct linkdb_node **ref)
 void setd_sub(struct script_state *st, TBL_PC *sd, char *varname, int elem, void *value, struct linkdb_node **ref)
 {
 {
 	set_reg(st, sd, add_str(varname)+(elem<<24), varname, value, ref);
 	set_reg(st, sd, add_str(varname)+(elem<<24), varname, value, ref);
@@ -12131,80 +12113,78 @@ BUILDIN_FUNC(setd)
 BUILDIN_FUNC(query_sql)
 BUILDIN_FUNC(query_sql)
 {
 {
 #ifndef TXT_ONLY
 #ifndef TXT_ONLY
-	char *name = NULL;
-	const char *query;
-	int num, i = 0,j, nb_rows;
-	struct { char * dst_var_name; char type; } row[32];
-	TBL_PC *sd = (st->rid)? script_rid2sd(st) : NULL;
+	int i, j, nb_rows;
+	struct { char* dst_var_name; char type; } row[32];
+	TBL_PC* sd = (st->rid) ? script_rid2sd(st) : NULL;
 
 
-	query = script_getstr(st,2);
-	strcpy(tmp_sql, query);
-	if(mysql_query(&mmysql_handle,tmp_sql)){
-		ShowSQL("DB error - %s\n",mysql_error(&mmysql_handle));
-		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		script_pushint(st,0);
+	const char* query = script_getstr(st,2);
+	if (SQL_ERROR == Sql_Query(mmysql_handle, query) )
+	{
+		Sql_ShowDebug(mmysql_handle);
+		script_pushint(st, 0);
 		return 1;
 		return 1;
 	}
 	}
 
 
-	// If some data was returned
-	if((sql_res = mysql_store_result(&mmysql_handle))){
-		// Count the number of rows to store
-		nb_rows = mysql_num_fields(sql_res);
+	// Count the number of rows to store
+	nb_rows = Sql_NumColumns(mmysql_handle);
+	//FIXME: what sick mind would write something like this?
 
 
-		// Can't store more row than variable
-		if (nb_rows > st->end - (st->start+3))
-			nb_rows = st->end - (st->start+3);
+	// Can't store more row than variable
+	if (nb_rows > st->end - (st->start+3))
+		nb_rows = st->end - (st->start+3);
 
 
-		if (!nb_rows)
-		{
-			script_pushint(st,0);
-			return 0; // Nothing to store
-		}
+	if (!nb_rows)
+	{
+		script_pushint(st,0);
+		return 0; // Nothing to store
+	}
 
 
-		if (nb_rows > 32)
-		{
-			ShowWarning("buildin_query_sql: too many rows!\n");
-			script_pushint(st,0);
-			return 1;
-		}
+	if (nb_rows > 32)
+	{
+		ShowWarning("buildin_query_sql: too many rows!\n");
+		script_pushint(st,0);
+		return 1;
+	}
 
 
-		memset(row, 0, sizeof(row));
-		// Verify argument types
-		for(j=0; j < nb_rows; j++)
-		{
-			if(!data_isreference(script_getdata(st, 3+j))){
-				ShowWarning("buildin_query_sql: Parameter %d is not a variable!\n", j);
-				script_pushint(st,0);
-				return 0;
-			} else {
-				// Store type of variable (string = 0/int = 1)
-				num=st->stack->stack_data[st->start+3+j].u.num;
-				name=(char *)(str_buf+str_data[num&0x00ffffff].str);
-				if(name[strlen(name)-1] != '$') {
-					row[j].type = 1;
-				}
-				row[j].dst_var_name = name;
+	memset(row, 0, sizeof(row));
+	// Verify argument types
+	for(j=0; j < nb_rows; j++)
+	{
+		if(!data_isreference(script_getdata(st, 3+j))){
+			ShowWarning("buildin_query_sql: Parameter %d is not a variable!\n", j);
+			script_pushint(st,0);
+			return 0;
+		} else {
+			// Store type of variable (string = 0/int = 1)
+			int num = st->stack->stack_data[st->start+3+j].u.num;
+			char* name = str_buf + str_data[num&0x00ffffff].str;
+			if(name[strlen(name)-1] != '$') {
+				row[j].type = 1;
 			}
 			}
+			row[j].dst_var_name = name;
 		}
 		}
-		// Store data
-		while(i<128 && (sql_row = mysql_fetch_row(sql_res))){
-			for(j=0; j < nb_rows; j++)
-			{
-				if (row[j].type == 1)
-					setd_sub(st,sd, row[j].dst_var_name, i, (void *)atoi(sql_row[j]),script_getref(st,3+j));
-				else
-					setd_sub(st,sd, row[j].dst_var_name, i, (void *)sql_row[j],script_getref(st,3+j));
-			}
-			i++;
+	}
+	// Store data
+	for (i = 0; i < 128 && SQL_SUCCESS == Sql_NextRow(mmysql_handle); i++)
+	{
+		char* data;
+		Sql_GetData(mmysql_handle, j, &data, NULL);
+		for(j = 0; j < nb_rows; j++) {
+			if (row[j].type == 1)
+				setd_sub(st,sd, row[j].dst_var_name, i, (void *)atoi(data), script_getref(st,3+j));
+			else
+				setd_sub(st,sd, row[j].dst_var_name, i, (void *)data, script_getref(st,3+j));
 		}
 		}
-		// Free data
-		mysql_free_result(sql_res);
 	}
 	}
+	// Free data
+	Sql_FreeResult(mmysql_handle);
+
 	script_pushint(st,i);
 	script_pushint(st,i);
 #else
 #else
 	//for TXT version, we always return -1
 	//for TXT version, we always return -1
 	script_pushint(st,-1);
 	script_pushint(st,-1);
 #endif
 #endif
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
src/map/skill.c

@@ -7,6 +7,7 @@
 #include "../common/malloc.h"
 #include "../common/malloc.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/utils.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 
 
 #include "skill.h"
 #include "skill.h"

+ 1 - 0
src/map/status.c

@@ -6,6 +6,7 @@
 #include "../common/nullpo.h"
 #include "../common/nullpo.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/malloc.h"
 #include "../common/malloc.h"
+#include "../common/utils.h"
 
 
 #include "pc.h"
 #include "pc.h"
 #include "map.h"
 #include "map.h"

+ 0 - 42
src/plugins/Makefile

@@ -1,42 +0,0 @@
-
-OBJECTS = sample.dll sig.dll pid.dll gui.dll upnp.dll console.dll
-
-ifdef CYGWIN
-   PLUGINEXT = dll
-else
-   PLUGINEXT = so
-endif
-
-PLUGINS = $(OBJECTS:%.dll=%.$(PLUGINEXT))
-COMMON_H = ../common/plugin.h ../common/cbasetypes.h
-
-txt sql all: $(PLUGINS)
-
-%.$(PLUGINEXT): %.c
-	$(CC) $(CFLAGS) -shared -o ../../plugins/$@ $<
-
-sig.$(PLUGINEXT): sig.c
-	$(CC) $(CFLAGS) -shared -o ../../plugins/$@ $< \
-	../common/obj/showmsg.o ../common/obj/utils.o \
-	../common/obj/minimalloc.o
-
-gui.$(PLUGINEXT): ../../plugins/gui.conf
-upnp.$(PLUGINEXT): ../../plugins/upnp.conf
-
-../../plugins/%.conf: %.txt
-	cp -r $< $@
-
-../../plugins/gui.conf: gui.txt
-../../plugins/upnp.conf: upnp.txt
-
-depend:
-	makedepend -fGNUmakefile -o.$(PLUGINEXT) -Y. -Y../common *.c $(PLUGINS:%=../../plugins/%)
-clean:
-	rm -rf $(PLUGINS) GNUmakefile
-
-# DO NOT DELETE
-
-sample.$(PLUGINEXT): sample.c $(COMMON_H)
-sig.$(PLUGINEXT): sig.c $(COMMON_H)
-pid.$(PLUGINEXT): pid.c $(COMMON_H)
-gui.$(PLUGINEXT): gui.c $(COMMON_H)

+ 67 - 0
src/plugins/Makefile.in

@@ -0,0 +1,67 @@
+@SET_MAKE@
+
+PLUGINS = sample sig pid gui upnp console
+
+COMMON_H = ../common/plugin.h ../common/cbasetypes.h
+
+#####################################################################
+.PHONY : all $(PLUGINS) clean help
+
+all: $(PLUGINS)
+
+sample: sample@DLLEXT@
+
+sig: sig@DLLEXT@
+
+pid: pid@DLLEXT@
+
+gui: gui@DLLEXT@
+
+upnp: upnp@DLLEXT@
+
+console: console@DLLEXT@
+
+clean:
+	rm -rf *.o
+
+help:
+	@echo "possible targets are $(PLUGINS:%='%') 'all' 'clean' 'help'"
+	@echo "'sample'   - sample plugin"
+	@echo "'sig'      - signal handler plugin"
+	@echo "'pid'      - process id plugin"
+	@echo "'gui'      - gui plugin"
+	@echo "'upnp'     - upnp plugin"
+	@echo "'console'  - console plugin"
+	@echo "'all'      - builds all above targets"
+	@echo "'clean'    - cleans builds and objects"
+	@echo "'help'     - outputs this message"
+
+#####################################################################
+
+%@DLLEXT@: %.c
+	@CC@ @CFLAGS@ @CPPFLAGS@ -shared -o ../../plugins/$@ $<
+
+sig@DLLEXT@: sig.c
+	@$(MAKE) -C ../common txt
+	@CC@ @CFLAGS@ @CPPFLAGS@ -shared -o ../../plugins/$@ $< \
+	../common/obj/showmsg.o ../common/obj/utils.o ../common/obj/strlib.o \
+	../common/obj/minimalloc.o
+
+gui@DLLEXT@: ../../plugins/gui.conf
+upnp@DLLEXT@: ../../plugins/upnp.conf
+
+../../plugins/%.conf: %.txt
+	cp -r $< $@
+
+../../plugins/gui.conf: gui.txt
+../../plugins/upnp.conf: upnp.txt
+
+# DO NOT DELETE
+
+sample@DLLEXT@: sample.c $(COMMON_H)
+sig@DLLEXT@: sig.c $(COMMON_H)
+pid@DLLEXT@: pid.c $(COMMON_H)
+gui@DLLEXT@: gui.c $(COMMON_H)
+#TODO where is upnp.c? [FlavioJS]
+#upnp@DLLEXT@: upnp.c $(COMMON_H)
+console@DLLEXT@: console.c $(COMMON_H)

+ 0 - 14
src/tool/Makefile

@@ -1,14 +0,0 @@
-all: adduser convert mapcache
-
-adduser:
-	$(CC) -o ../../tools/$@ adduser.c
-
-convert:
-	$(CC) -o ../../tools/$@ convert.c
-
-mapcache:
-	$(CC) -c -o grfio.o grfio.c
-	$(CC) -o ../../$@ mapcache.c grfio.o -lz
-
-clean:
-	rm -rf *.o ../../tools/adduser ../../tools/convert ../../mapcache

+ 28 - 0
src/tool/Makefile.in

@@ -0,0 +1,28 @@
+#####################################################################
+.PHONY : all adduser convert mapcache clean help
+
+all: adduser convert mapcache
+
+adduser:
+	@CC@ -o ../../tools/adduser@EXEEXT@ adduser.c
+
+convert:
+	@CC@ -o ../../tools/convert@EXEEXT@ convert.c
+
+mapcache:
+	@CC@ -c -o grfio.o grfio.c
+	@CC@ -o ../../mapcache@EXEEXT@ mapcache.c grfio.o -lz
+
+clean:
+	rm -rf *.o ../../tools/adduser@EXEEXT@ ../../tools/convert@EXEEXT@ ../../mapcache@EXEEXT@
+
+help:
+	@echo "possible targets are 'adduser' 'convert' 'mapcache' 'all' 'clean' 'help'"
+	@echo "'adduser'   - ???"
+	@echo "'convert'   - ???"
+	@echo "'mapcache'  - mapcache generator"
+	@echo "'all'       - builds all above targets"
+	@echo "'clean'     - cleans builds and objects"
+	@echo "'help'      - outputs this message"
+
+#####################################################################

+ 0 - 24
src/txt-converter/Makefile

@@ -1,24 +0,0 @@
-all sql: char-converter login-converter
-
-char-converter: char-converter.o ../common/obj/minicore.o \
-	../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/strlib.o \
-	../common/obj/mapindex.o ../common/obj/ers.o ../common/obj/utils.o \
-	../char/char.o ../char/int_pet.o ../char/int_storage.o ../char/inter.o \
-	../char/int_party.o ../char/int_guild.o \
-	../char_sql/char.o ../char_sql/int_pet.o ../char_sql/int_storage.o \
-	../char_sql/inter.o ../char_sql/int_party.o ../char_sql/int_guild.o
-	$(CC) -o ../../tools/$@ $^ $(LIB_S)
-
-login-converter: login-converter.o ../common/obj/minicore.o ../common/obj/db.o ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/ers.o ../common/obj/utils.o
-	$(CC) -o ../../tools/$@ $^ $(LIB_S)
-
-clean:
-	rm -f *.o ../../tools/login-converter ../../tools/char-converter GNUmakefile
-
-# DO NOT DELETE
-
-%.o: %.c
-	$(COMPILE.c) -DTXT_SQL_CONVERT $(OUTPUT_OPTION) $<
-
-char-converter.o: char-converter.c
-login-converter.o: login-converter.c

+ 68 - 0
src/txt-converter/Makefile.in

@@ -0,0 +1,68 @@
+LOGIN_CONVERTER_OBJ = login-converter.o ../common/obj/minicore.o \
+	../common/obj/malloc.o ../common/obj/strlib.o ../common/obj/showmsg.o \
+	../common/obj/utils.o ../common/obj/ers.o ../common/obj/db.o \
+	../common/obj_sql/sql.o
+CHAR_CONVERTER_OBJ = char-converter.o ../common/obj/minicore.o \
+	../common/obj/malloc.o ../common/obj/strlib.o ../common/obj/showmsg.o \
+	../common/obj/utils.o ../common/obj/ers.o ../common/obj/mapindex.o \
+	../common/obj_sql/sql.o \
+	obj_txt/char.o obj_txt/int_pet.o obj_txt/int_storage.o obj_txt/inter.o \
+	obj_txt/int_party.o obj_txt/int_guild.o \
+	obj_sql/char.o obj_sql/int_pet.o obj_sql/int_storage.o \
+	obj_sql/inter.o obj_sql/int_party.o obj_sql/int_guild.o
+
+HAVE_MYSQL=@HAVE_MYSQL@
+ifeq ($(HAVE_MYSQL),yes)
+	LOGIN_CONVERTER_DEPENDS=$(LOGIN_CONVERTER_OBJ)
+	CHAR_CONVERTER_DEPENDS=obj $(CHAR_CONVERTER_OBJ)
+else
+	LOGIN_CONVERTER_DEPENDS=needs_mysql
+	CHAR_CONVERTER_DEPENDS=needs_mysql
+endif
+
+#####################################################################
+.PHONY : all login-converter char-converter clean help
+
+all: login-converter char-converter
+
+login-converter: $(LOGIN_CONVERTER_DEPENDS)
+	@CC@ @LDFLAGS@ -o ../../tools/login-converter@EXEEXT@ $(LOGIN_CONVERTER_OBJ) @LIBS@ @MYSQL_LIBS@
+
+char-converter: $(CHAR_CONVERTER_DEPENDS)
+	@CC@ @LDFLAGS@ -o ../../tools/char-converter@EXEEXT@ $(CHAR_CONVERTER_OBJ) @LIBS@ @MYSQL_LIBS@
+
+clean:
+	rm -rf *.o obj_txt obj_sql ../../tools/login-converter@EXEEXT@ ../../tools/char-converter@EXEEXT@
+
+help:
+	@echo "possible targets are 'login-converter' 'char-converter' 'all' 'clean' 'help'"
+	@echo "'login-converter'  - login server converter"
+	@echo "'char-converter'   - char server converter"
+	@echo "'all'              - builds all above targets"
+	@echo "'clean'            - cleans builds and objects"
+	@echo "'help'             - outputs this message"
+
+#####################################################################
+
+needs_mysql:
+	@echo "MySQL not found or disabled by the configure script"
+	@exit 1
+
+obj:
+	-mkdir obj_txt
+	-mkdir obj_sql
+
+
+# DO NOT DELETE
+
+%.o: %.c
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -DTXT_SQL_CONVERT -c $(OUTPUT_OPTION) $<
+
+obj_txt/%.o: ../char/%.c
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -DTXT_SQL_CONVERT -c $(OUTPUT_OPTION) $<
+
+obj_sql/%.o: ../char_sql/%.c
+	@CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -DTXT_SQL_CONVERT -c $(OUTPUT_OPTION) $<
+
+char-converter.o: char-converter.c
+login-converter.o: login-converter.c

+ 1 - 0
src/txt-converter/char-converter.c

@@ -7,6 +7,7 @@
 #include "../common/strlib.h"
 #include "../common/strlib.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
 #include "../common/mapindex.h"
 #include "../common/mapindex.h"
+#include "../common/utils.h"
 
 
 #include "../char/char.h"
 #include "../char/char.h"
 #include "../char/int_storage.h"
 #include "../char/int_storage.h"

+ 21 - 18
src/txt-converter/login-converter.c

@@ -6,16 +6,12 @@
 #include "../common/core.h"
 #include "../common/core.h"
 #include "../common/db.h"
 #include "../common/db.h"
 #include "../common/showmsg.h"
 #include "../common/showmsg.h"
+#include "../common/sql.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 
 
-#ifdef WIN32
-#include <winsock2.h>
-#endif
-#include <mysql.h>
-
 char login_account_id[256]="account_id";
 char login_account_id[256]="account_id";
 char login_userid[256]="userid";
 char login_userid[256]="userid";
 char login_user_pass[256]="user_pass";
 char login_user_pass[256]="user_pass";
@@ -90,8 +86,8 @@ int read_gm_account()
 
 
 int convert_login(void)
 int convert_login(void)
 {
 {
-	MYSQL mysql_handle;
-	char tmpsql[1024];
+	Sql* mysql_handle;
+	SqlStmt* stmt;
 	int line_counter = 0;
 	int line_counter = 0;
 	FILE *fp;
 	FILE *fp;
 	int account_id, logincount, user_level, state, n, i;
 	int account_id, logincount, user_level, state, n, i;
@@ -100,11 +96,12 @@ int convert_login(void)
 	time_t connect_until_time;
 	time_t connect_until_time;
 	char dummy[2048];
 	char dummy[2048];
 
 
-	mysql_init(&mysql_handle);
-	if(!mysql_real_connect(&mysql_handle, db_server_ip, db_server_id, db_server_pw, db_server_logindb ,db_server_port, (char *)NULL, 0)) {
-			//pointer check
-			printf("%s\n",mysql_error(&mysql_handle));
-			exit(1);
+	mysql_handle = Sql_Malloc();
+	if ( SQL_ERROR == Sql_Connect(mysql_handle, db_server_id, db_server_pw, db_server_ip, db_server_port, db_server_logindb) )
+	{
+		Sql_ShowDebug(mysql_handle);
+		Sql_Free(mysql_handle);
+		exit(1);
 	}
 	}
 	ShowStatus("Connect: Success!\n");
 	ShowStatus("Connect: Success!\n");
 	
 	
@@ -133,21 +130,27 @@ int convert_login(void)
 
 
 		user_level = isGM(account_id);
 		user_level = isGM(account_id);
 		ShowInfo("Converting user (id: %d, name: %s, gm level: %d)\n", account_id, userid, user_level);
 		ShowInfo("Converting user (id: %d, name: %s, gm level: %d)\n", account_id, userid, user_level);
-		sprintf(tmpsql,
+		
+		stmt = SqlStmt_Malloc(mysql_handle);
+		if( SQL_ERROR == SqlStmt_Prepare(stmt, 
 			"REPLACE INTO `login` "
 			"REPLACE INTO `login` "
 			"(`account_id`, `userid`, `user_pass`, `lastlogin`, `sex`, `logincount`, `email`, `level`, `error_message`, `connect_until`, `last_ip`, `memo`, `ban_until`, `state`) "
 			"(`account_id`, `userid`, `user_pass`, `lastlogin`, `sex`, `logincount`, `email`, `level`, `error_message`, `connect_until`, `last_ip`, `memo`, `ban_until`, `state`) "
 			"VALUES "
 			"VALUES "
-			"(%d, '%s', '%s', '%s', '%c', %d, '%s', %d, '%s', %u, '%s', '%s', %u, %d)",
-			account_id , userid, pass, lastlogin, sex, logincount, email, user_level, error_message, (uint32)connect_until_time, last_ip, memo, (uint32)ban_until_time, state);
-		if(mysql_query(&mysql_handle, tmpsql) ) {
-			ShowError("DB server Error - %s\n", mysql_error(&mysql_handle) );
-			ShowError("Query: %s\n", tmpsql);
+			"(%d, ?, ?, '%s', '%c', %d, '%s', %d, '%s', %u, '%s', '%s', %u, %d)",
+			account_id, lastlogin, sex, logincount, email, user_level, error_message, (uint32)connect_until_time, last_ip, memo, (uint32)ban_until_time, state)
+		||	SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_STRING, userid, strnlen(userid, 255))
+		||	SQL_ERROR == SqlStmt_BindParam(stmt, 1, SQLDT_STRING, pass, strnlen(pass, 32))
+		||	SQL_ERROR == SqlStmt_Execute(stmt) )
+		{
+			SqlStmt_ShowDebug(stmt);
 		}
 		}
+		SqlStmt_Free(stmt);
 	
 	
 		//TODO: parse the rest of the line to read the login-stored account variables, and import them to `global_reg_value`
 		//TODO: parse the rest of the line to read the login-stored account variables, and import them to `global_reg_value`
 		//      then remove the 'dummy' buffer
 		//      then remove the 'dummy' buffer
 	}
 	}
 	fclose(fp);
 	fclose(fp);
+	Sql_Free(mysql_handle);
 
 
 	ShowStatus("Convert end...\n");
 	ShowStatus("Convert end...\n");
 
 

+ 8 - 8
vcproj-6/char-server_sql.dsp

@@ -147,6 +147,14 @@ SOURCE=..\src\common\socket.h
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
 
 
+SOURCE=..\src\common\sql.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\sql.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\common\strlib.c
 SOURCE=..\src\common\strlib.c
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
@@ -233,14 +241,6 @@ SOURCE=..\src\char_sql\inter.c
 
 
 SOURCE=..\src\char_sql\inter.h
 SOURCE=..\src\char_sql\inter.h
 # End Source File
 # End Source File
-# Begin Source File
-
-SOURCE=..\src\char_sql\itemdb.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\src\char_sql\itemdb.h
-# End Source File
 # End Group
 # End Group
 # End Target
 # End Target
 # End Project
 # End Project

+ 8 - 0
vcproj-6/login-server_sql.dsp

@@ -155,6 +155,14 @@ SOURCE=..\src\common\socket.h
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
 
 
+SOURCE=..\src\common\sql.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\sql.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\common\strlib.c
 SOURCE=..\src\common\strlib.c
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File

+ 8 - 0
vcproj-6/map-server_sql.dsp

@@ -155,6 +155,14 @@ SOURCE=..\src\common\socket.h
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File
 
 
+SOURCE=..\src\common\sql.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\sql.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\common\strlib.c
 SOURCE=..\src\common\strlib.c
 # End Source File
 # End Source File
 # Begin Source File
 # Begin Source File

Some files were not shown because too many files changed in this diff