* 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
This commit is contained in:
FlavioJS 2007-09-20 11:09:36 +00:00
parent 4c01114652
commit 65642f6f1c
109 changed files with 6521 additions and 5863 deletions

View File

@ -3,6 +3,23 @@ Date Added
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.
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
* Several skills with a splash area (except ground based ones) will now hit
Ice-walls when casted by mobs.

253
Makefile
View File

@ -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
Makefile.in Normal file
View File

@ -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)

View File

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

256
configure vendored
View File

@ -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
configure.in Normal file
View File

@ -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

View File

@ -117,15 +117,23 @@ Global
{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-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.Build.0 = 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.Build.0 = 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.Build.0 = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,5 +1,3 @@
all txt: char-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 \
@ -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_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/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:
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
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)
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)

View File

@ -11,17 +11,19 @@
#include "../common/strlib.h"
#include "../common/showmsg.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 "inter.h"
#include "int_guild.h"
#include "int_homun.h"
#include "int_pet.h"
#include "int_party.h"
#include "int_storage.h"
#ifdef ENABLE_SC_SAVING
#include "int_status.h"
#endif
#include "char.h"
#include <sys/types.h>

View File

@ -5,7 +5,6 @@
#define _CHAR_H_
#include "../common/mmo.h"
#include "../common/mapindex.h"
#define START_CHAR_NUM 150000
#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_byname(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 mapif_sendall(unsigned char *buf, unsigned int len);

View File

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

View File

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

View File

@ -1,10 +1,6 @@
// 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 "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/socket.h"
@ -15,6 +11,10 @@
#include "inter.h"
#include "int_homun.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char homun_txt[1024]="save/homun.txt";
static struct dbt *homun_db;

View File

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

View File

@ -1,10 +1,6 @@
// 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 "../common/cbasetypes.h"
#include "../common/mmo.h"
#include "../common/malloc.h"
@ -16,6 +12,10 @@
#include "inter.h"
#include "int_party.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char party_txt[1024] = "save/party.txt";
#ifndef TXT_SQL_CONVERT
struct party_data {

View File

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

View File

@ -1,10 +1,6 @@
// 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 "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/socket.h"
@ -15,6 +11,10 @@
#include "inter.h"
#include "int_pet.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char pet_txt[1024]="save/pet.txt";
#ifndef TXT_SQL_CONVERT

View File

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

View File

@ -1,13 +1,14 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// 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/lock.h"
#include "../common/malloc.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]
char scdata_txt[1024]="save/scdata.txt"; //By [Skotlex]

View File

@ -4,7 +4,7 @@
#ifndef _INT_STATUS_H_
#define _INT_STATUS_H_
#include "char.h"
struct status_change_data;
struct scdata {
int account_id, char_id;
@ -14,12 +14,10 @@ struct scdata {
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 inter_status_save(void);
void status_init(void);
void status_final(void);
#endif
#endif /* _INT_STATUS_H_ */

View File

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

View File

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

View File

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

View File

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

View File

@ -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
src/char_sql/Makefile.in Normal file
View File

@ -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 Load Diff

View File

@ -4,37 +4,13 @@
#ifndef _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 MAX_MAP_SERVERS 30
#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 {
TABLE_INVENTORY,
TABLE_CART,
@ -42,7 +18,7 @@ enum {
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_sendallwos(int fd,unsigned char *buf,unsigned int len);

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,6 @@
#ifndef _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_MEMBER 0x0002
#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_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.
int inter_guild_tosql(struct guild *g,int flag);
int inter_guildcastle_tosql(struct guild_castle *gc);

View File

@ -1,15 +1,20 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/strlib.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>
#include "char.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/showmsg.h"
struct s_homunculus *homun_pt;
int inter_homunculus_sql_init(void){
@ -68,154 +73,150 @@ int mapif_homunculus_created(int fd, int account_id, struct s_homunculus *sh, un
// Save/Update Homunculus Skills
int mapif_save_homunculus_skills(struct s_homunculus *hd)
{
SqlStmt* stmt;
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;
}
}
}
SqlStmt_Free(stmt);
return 1;
}
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`) "
"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
{
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( 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(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(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;
}
// Load an homunculus
int mapif_load_homunculus(int fd){
int mapif_load_homunculus(int fd)
{
int i;
RFIFOHEAD(fd);
char* data;
size_t len;
memset(homun_pt, 0, sizeof(struct s_homunculus));
RFIFOHEAD(fd);
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);
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;
}
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) )
{
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);
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]);
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
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;
}
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]);
}
}
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);
mysql_free_result(sql_res);
if (save_log)
if( save_log )
ShowInfo("Homunculus loaded (%d - %s).\n", homun_pt->hom_id, homun_pt->name);
return mapif_info_homunculus(fd, RFIFOL(fd,2), homun_pt);
}
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))
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);
return 0;
}
sprintf(tmp_sql, "DELETE FROM `skill_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);
Sql_ShowDebug(sql_handle);
return 0;
}
return 1;

View File

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

View File

@ -1,18 +1,22 @@
// 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 "../common/cbasetypes.h"
#include "../common/mmo.h"
#include "../common/db.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/socket.h"
#include "../common/showmsg.h"
#include "../common/mapindex.h"
#include "../common/sql.h"
#include "char.h"
#include "inter.h"
#include "int_party.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef TXT_SQL_CONVERT
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)
{
// '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;
if (p == NULL || p->party_id == 0)
if( p == NULL || p->party_id == 0 )
return 0;
party_id = p->party_id;
#ifdef NOISY
ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
#endif
jstrescapecpy(t_name, p->name);
Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
#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]
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
idb_remove(party_db_, party_id);
return 1;
}
#endif //TXT_SQL_CONVERT
if(flag&PS_CREATE) { //Create party
if( flag & PS_CREATE )
{// Create party
#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`) "
"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;
}
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
//During conversion, you want to specify the id, and allow overwriting
//(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`) "
"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;
}
#endif
}
#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
if (save_log)
if( save_log )
ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
return 1;
}
@ -212,74 +196,69 @@ int inter_party_tosql(struct party *p, int flag, int index)
// Read party from mysql
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
ShowInfo("Load party request ("CL_BOLD"%d"CL_RESET")\n", party_id);
#endif
if (party_id <=0)
if( party_id <= 0 )
return NULL;
//Load from memory
if ((p = idb_get(party_db_, party_id)) != NULL)
p = idb_get(party_db_, party_id);
if( p != NULL )
return p;
p = party_pt;
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;
}
sql_res = mysql_store_result(&mysql_handle) ;
if (!sql_res)
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
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;
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
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;
}
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);
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);
if( save_log )
ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
//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));
//init state
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]
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;
}
@ -318,27 +293,23 @@ void inter_party_sql_final(void)
}
// 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;
char esc_name[NAME_LENGTH*2+1];
char* data;
struct party_data* p = NULL;
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)
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.
@ -627,12 +598,10 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
int i,j=-1;
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;
}
@ -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);
}
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;
}
sql_res = mysql_store_result(&mysql_handle) ;
if(sql_res == NULL)
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
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)
return 0; //No party...
@ -859,22 +829,22 @@ int inter_party_CharOffline(int char_id, int party_id) {
struct party_data *p=NULL;
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;
}
sql_res = mysql_store_result(&mysql_handle) ;
if(sql_res == NULL)
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
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)
return 0; //No party...

View File

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

View File

@ -1,53 +1,52 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/socket.h"
#include "../common/strlib.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>
#include "char.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/showmsg.h"
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`)
char t_name[NAME_LENGTH*2];
char esc_name[NAME_LENGTH*2+1];// escaped pet name
jstrescapecpy(t_name, p->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(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` "
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`) "
"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;
}
}
@ -57,7 +56,10 @@ int inter_pet_tosql(int pet_id, struct s_pet *p) {
return 1;
}
#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
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`)
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;
}
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->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;
}
//----------------------------------------------
@ -119,11 +114,8 @@ void inter_pet_sql_final(void){
int inter_pet_delete(int 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;
}
//------------------------------------------------------

View File

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

View File

@ -1,17 +1,19 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// 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 <string.h>
#include <stdlib.h>
#include "char.h"
#include "itemdb.h"
#include "../common/malloc.h"
#include "../common/showmsg.h"
#define STORAGE_MEMINC 16
@ -19,166 +21,130 @@
// reset by inter_config_read()
struct storage *storage_pt=NULL;
struct guild_storage *guild_storage_pt=NULL;
#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;
}
#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;
// DB -> storage data conversion
int storage_fromsql(int account_id, struct storage *p){
int i=0,j;
char * str_p = tmp_sql;
memset(p,0,sizeof(struct storage)); //clean up memory
memset(p, 0, sizeof(struct storage)); //clean up memory
p->storage_amount = 0;
p->account_id = account_id;
// 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) ;
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_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++;
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;
}
#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;
}
#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
#ifndef TXT_SQL_CONVERT
/// 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->guild_id = guild_id;
// 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`");
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);
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_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
Sql_ShowDebug(sql_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_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;
}
//---------------------------------------------------------
// storage data initialize
int inter_storage_sql_init(void){
int inter_storage_sql_init(void)
{
//memory alloc
ShowDebug("interserver storage memory initialize....(%d byte)\n",sizeof(struct storage));
storage_pt = (struct storage*)aCalloc(sizeof(struct 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;
}
@ -192,20 +158,14 @@ void inter_storage_sql_final(void)
// q?f[^?
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;
}
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;
}
@ -213,7 +173,8 @@ int inter_guild_storage_delete(int guild_id)
// packet from map server
// 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
WFIFOHEAD(fd, sizeof(struct storage)+8);
storage_fromsql(account_id, storage_pt);
@ -225,7 +186,8 @@ int mapif_load_storage(int fd,int account_id){
return 0;
}
// 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);
WFIFOW(fd,0)=0x3811;
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 guild_exist=1;
WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
WFIFOW(fd,0)=0x3818;
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);
#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);
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;
}
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;
}
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;
}
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
// recive request about storage data
int mapif_parse_LoadStorage(int fd){
int mapif_parse_LoadStorage(int fd)
{
RFIFOHEAD(fd);
mapif_load_storage(fd,RFIFOL(fd,2));
return 0;
}
// storage data recive and save
int mapif_parse_SaveStorage(int fd){
int mapif_parse_SaveStorage(int fd)
{
int account_id;
int len;
RFIFOHEAD(fd);
@ -318,45 +271,38 @@ int mapif_parse_LoadGuildStorage(int fd)
int mapif_parse_SaveGuildStorage(int fd)
{
int guild_exist=1;
int guild_id;
int len;
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);
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;
}
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) {
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;
}
int inter_storage_parse_frommap(int fd){
int inter_storage_parse_frommap(int fd)
{
RFIFOHEAD(fd);
switch(RFIFOW(fd,0)){
case 0x3010: mapif_parse_LoadStorage(fd); break;

View File

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

View File

@ -1,34 +1,31 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// 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/strlib.h"
#include "../common/showmsg.h"
#include "../common/socket.h"
#include "../common/timer.h"
#include "char.h"
#include "inter.h"
#include "int_party.h"
#include "int_guild.h"
#include "int_storage.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 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;
char char_server_ip[32] = "127.0.0.1";
@ -89,50 +86,59 @@ int inter_sql_test (void);
#endif //TXT_SQL_CONVERT
//--------------------------------------------------------
// 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;
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;
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);
}
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;
}
#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)
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));
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`)
switch (type) {
switch( type )
{
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
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
ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
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);
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)));
}
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);
}
reg->reg_num=j;
reg->reg_num = i;
Sql_FreeResult(sql_handle);
return 1;
}
@ -277,18 +293,17 @@ static int inter_config_read(const char* cfgName)
int inter_log(char* fmt, ...)
{
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_start(ap,fmt);
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);
}
vsnprintf(str, sizeof(str), fmt, ap);
va_end(ap);
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);
return 0;
}
@ -298,30 +313,23 @@ int inter_log(char* fmt, ...)
int inter_sql_ping(int tid, unsigned int tick, int id, int data)
{
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;
}
int sql_ping_init(void)
{
int connection_timeout, connection_ping_interval;
uint32 connection_timeout, connection_ping_interval;
// set a default value first
connection_timeout = 28800; // 8 hours
// 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
connection_ping_interval = connection_timeout - 30; // 30-second reserve
@ -342,13 +350,13 @@ int inter_init_sql(const char *file)
inter_config_read(file);
//DB connection initialized
mysql_init(&mysql_handle);
sql_handle = Sql_Malloc();
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
else if (inter_sql_test()) {
@ -356,30 +364,27 @@ int inter_init_sql(const char *file)
}
if(char_gm_read) {
mysql_init(&lmysql_handle);
lsql_handle = Sql_Malloc();
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");
}
}
#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
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
}
@ -405,32 +410,30 @@ int inter_sql_test (void)
"fame", // version 1491
};
char buf[1024] = "";
char* p;
size_t len;
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
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);
if( lsql_handle )
Sql_Free(lsql_handle);
Sql_Free(sql_handle);
exit(1);
}
}
mysql_free_result(sql_res);
return 1;
}
@ -636,7 +639,11 @@ int mapif_parse_WisRequest(int fd)
{
struct WisData* wd;
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
@ -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]
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
if (!(sql_row = mysql_fetch_row(sql_res))) {
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
{
unsigned char buf[27];
WBUFW(buf, 0) = 0x3802;
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
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
Sql_GetData(sql_handle, 0, &data, &len);
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 (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;
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
mapif_send(fd, buf, 27);
} else {
}
else
{
CREATE(wd, struct WisData, 1);
@ -695,12 +704,8 @@ int mapif_parse_WisRequest(int fd)
mapif_wis_message(wd);
}
}
//Freeing ... O.o
if(sql_res){
mysql_free_result(sql_res);
}
Sql_FreeResult(sql_handle);
return 0;
}

View File

@ -4,9 +4,8 @@
#ifndef _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);
void inter_final(void);
@ -25,21 +24,8 @@ int inter_log(char *fmt,...);
extern unsigned int party_share_level;
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 char char_server_ip[32];

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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:
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 \
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/mapindex.o obj/ers.o obj/md5calc.o
common_sql: obj_sql/sql.o
obj/%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
@CC@ @CFLAGS@ @LDFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
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)
ifeq ($(findstring /,$(HAVESVN)), /)
@ -38,19 +76,20 @@ obj/minimalloc.o: malloc.c malloc.h
# DO NOT DELETE
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/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/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/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/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/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/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
@touch mmo.h

View File

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

View File

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

View File

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

View File

@ -173,7 +173,7 @@ void MD5_String2binary(const char * string, char * output)
//Step 1.Append Padding Bits (extension of a mark bit)
//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.
//1-2 Repeat calculation until length becomes less than 64 bytes.

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// For more information, see LICENCE in the main folder
#include "../common/cbasetypes.h"
#include "../common/utils.h"
#include "../common/strlib.h" // StringBuf
#include "showmsg.h"
#include <stdio.h>
@ -59,7 +59,7 @@ int msg_silent = 0; //Specifies how silent the console is.
#define NEWBUF(buf) \
struct { \
char s_[SBUF_SIZE]; \
struct StringBuf *d_; \
StringBuf *d_; \
char *v_; \
int l_; \
} 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;
NEWBUF(tempbuf); // temporary buffer
@ -218,8 +218,8 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
p = BUFVAL(tempbuf);
while ((q = strchr(p, 0x1b)) != NULL)
{ // 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]!='[' )
{ // 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
q=q+2;
while(1)
for(;;)
{
if( ISDIGIT(*q) )
{ // 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( 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);
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");
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_STATUS && msg_silent&2) ||
(flag == MSG_NOTICE && msg_silent&4) ||

View File

@ -111,8 +111,9 @@ void set_defaultparse(ParseFunc defaultparse)
void set_nonblocking(int fd, unsigned long yes)
{
// 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.
// 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) )
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 (s_errno == S_ECONNABORTED) {
@ -203,7 +204,7 @@ int send_from_fifo(int fd)
if (session[fd]->wdata_size == 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 (s_errno == S_ECONNABORTED) {
@ -457,7 +458,7 @@ int realloc_writefifo(int fd, size_t addition)
return 0;
}
int RFIFOSKIP(int fd, int len)
int RFIFOSKIP(int fd, size_t len)
{
struct socket_data *s;
@ -477,7 +478,7 @@ int RFIFOSKIP(int fd, int len)
return 0;
}
int WFIFOSET(int fd, int len)
int WFIFOSET(int fd, size_t len)
{
size_t newreserve;
struct socket_data* s = session[fd];

View File

@ -104,8 +104,8 @@ int make_listen_bind(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_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_parsepacket(void);

851
src/common/sql.c Normal file
View File

@ -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
src/common/sql.h Normal file
View File

@ -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_ */

View File

@ -3,7 +3,6 @@
#include "../common/cbasetypes.h"
#include "../common/malloc.h"
#include "../common/utils.h"
#include "strlib.h"
#include <stdio.h>
@ -258,7 +257,7 @@ int e_mail_check(char* email)
{
char ch;
char* last_arobas;
int len = strlen(email);
size_t len = strlen(email);
// athena limits
if (len < 3 || len > 39)
@ -310,3 +309,134 @@ char* safestrncpy(char* dst, const char* src, size_t n)
ret[n - 1] = '\0';
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);
}

View File

@ -7,6 +7,7 @@
#ifndef _CBASETYPES_H_
#include "../common/cbasetypes.h"
#endif
#include <stdarg.h>
char* jstrescape (char* pt);
char* jstrescapecpy (char* pt, const char* spt);
@ -33,4 +34,25 @@ int config_switch(const char* str);
/// always nul-terminates the string
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_ */

View File

@ -55,118 +55,6 @@ void dump(FILE* fp, const unsigned char* buffer, int length)
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
@ -293,35 +181,43 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
}
#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)
{
return
((uint16)(byte0 ))|
((uint16)(byte1 << 0x08));
return byte0 | (byte1 << 0x08);
}
uint32 MakeDWord(uint16 word0, uint16 word1)
{
return
((uint32)(word0 ))|
((uint32)(word1 << 0x10));
( (uint32)(word0 ) )|
( (uint32)(word1 << 0x10) );
}

View File

@ -4,29 +4,15 @@
#ifndef _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'
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*));
//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]
//////////////////////////////////////////////////////////////////////////
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 uint32 MakeDWord(uint16 word0, uint16 word1);

View File

@ -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
src/ladmin/Makefile.in Normal file
View File

@ -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) $<

View File

@ -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
src/login/Makefile.in Normal file
View File

@ -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) $<

View File

@ -2,6 +2,7 @@
// For more information, see LICENCE in the main folder
#include "../common/cbasetypes.h"
#include "../common/mmo.h"
#include "../common/core.h"
#include "../common/socket.h"
#include "../common/db.h"
@ -9,7 +10,6 @@
#include "../common/lock.h"
#include "../common/malloc.h"
#include "../common/strlib.h"
#include "../common/mmo.h"
#include "../common/showmsg.h"
#include "../common/version.h"
#include "../common/md5calc.h"
@ -17,10 +17,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> // for stat/lstat/fstat
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h> // for stat/lstat/fstat
uint32 account_id_count = START_ACCOUNT_NUM;
bool new_account_flag = true;
@ -1092,20 +1090,18 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email)
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);
} 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].logincount = 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;
if (start_limited_time < 0)
auth_dat[i].connect_until_time = 0; // unlimited
else { // limited time
@ -1128,9 +1124,9 @@ int mmo_auth_new(struct mmo_account* account, char sex, char* email)
return (account_id_count - 1);
}
//---------------------------------------
//-----------------------------------------------------
// Check/authentication of a connection
//---------------------------------------
//-----------------------------------------------------
int mmo_auth(struct mmo_account* account, int fd)
{
unsigned int i;
@ -1138,14 +1134,14 @@ int mmo_auth(struct mmo_account* account, int fd)
char tmpstr[256];
int len;
int newaccount = 0;
char user_password[256];
char user_password[32+1]; // reserve for md5-ed pw
char ip[16];
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]);
// DNS Blacklist check
if(use_dnsbl)
if( use_dnsbl )
{
char r_ip[16];
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]);
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);
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
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]
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;
}
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
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 (!newaccount && i == auth_num) {
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).
}
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
}
if(use_md5_passwds)
if( use_md5_passwds )
MD5_String(account->passwd, user_password);
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
}
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
case 1: // 0 = Unregistered ID
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);
if (data && data->char_server > -1) {
if( data && data->char_server > -1 )
{
//Request char servers to kick this account out. [Skotlex]
unsigned char buf[8];
ShowNotice("User [%d] is already online - Rejected.\n",auth_dat[i].account_id);
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = auth_dat[i].account_id;
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);
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
} 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();
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
if(DIFF_TICK(tick, new_reg_tick) > 0)
if( DIFF_TICK(tick, new_reg_tick) > 0 )
{ //Update the registration check.
num_regs = 0;
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
// Platform/Compiler dependant clock() for time check is removed. [Lance]
// 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->login_id1 = 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;
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);
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++;
// 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 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
if (RFIFOREST(fd) < 86)
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);
return 0;
@ -3362,7 +3348,7 @@ int parse_login(int fd)
//-----------------------
// Console Command Parser [Wizputer]
//-----------------------
int parse_console(char*buf)
int parse_console(char* buf)
{
char command[256];
@ -3377,13 +3363,15 @@ int parse_console(char*buf)
strcmpi("quit", command) == 0 ||
strcmpi("end", command) == 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");
else if( strcmpi("help", command) == 0 ){
else
if( strcmpi("help", command) == 0 ) {
printf(CL_BOLD"Help of commands:"CL_RESET"\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(" 'alive|status'\n");
}

View File

@ -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
src/login_sql/Makefile.in Normal file
View File

@ -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 Load Diff

View File

@ -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
src/map/Makefile.in Normal file
View File

@ -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)

View File

@ -10,6 +10,7 @@
#include "../common/malloc.h"
#include "../common/socket.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "atcommand.h"
#include "log.h"
@ -273,6 +274,7 @@ ACMD_FUNC(checkmail); // [Valaris]
ACMD_FUNC(listmail); // [Valaris]
ACMD_FUNC(listnewmail); // [Valaris]
ACMD_FUNC(readmail); // [Valaris]
ACMD_FUNC(deletemail); // [Valaris]
ACMD_FUNC(sendmail); // [Valaris]
ACMD_FUNC(sendprioritymail); // [Valaris]
ACMD_FUNC(deletemail); // [Valaris]
@ -577,7 +579,7 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_ListMail, "@listmail", 1, atcommand_listmail }, // [Valaris]
{ AtCommand_ListNewMail, "@listnewmail", 1, atcommand_listmail }, // [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_SendPriorityMail, "@sendprioritymail",80, atcommand_sendmail }, // [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);
if(strlen(command)==12)
if(strlen(command)==12) // @listnewmail
mail_check(sd,3);
else if(strlen(command)==9)
else if(strlen(command)==9) // @listmail
mail_check(sd,2);
else
else // @checkmail
mail_check(sd,1);
return 0;
}
@ -7926,10 +7928,31 @@ int atcommand_readmail(const int fd, struct map_session_data* sd, const char* co
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;
}
@ -7954,7 +7977,7 @@ int atcommand_sendmail(const int fd, struct map_session_data* sd, const char* co
return 0;
}
if(strlen(command)==17)
if(strlen(command)==17) // @sendprioritymail
mail_send(sd,name,text,1);
else
mail_send(sd,name,text,0);

View File

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

View File

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

View File

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

View File

@ -9,6 +9,7 @@
#include "../common/showmsg.h"
#include "../common/ers.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "map.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)
{ // Run One NPC_Event[OnAgitBreak]
char *evname;
char* evname;
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...
// It's a little impossible to null point with player disconnect in this!
// But Script will be stop, so nothing...

View File

@ -1497,7 +1497,7 @@ int intif_parse(int fd)
case 0x3802: intif_parse_WisEnd(fd); break;
case 0x3803: mapif_parse_WisToGM(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 0x3811: intif_parse_SaveStorage(fd); break;
case 0x3818: intif_parse_LoadGuildStorage(fd); break;

View File

@ -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
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;
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,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->flag.available = 1;
id->flag.value_notdc = 0;
id->flag.value_notoc = 0;
}
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);
}
// 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);
}
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.
return 0;
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);
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 true;
}
#endif /* not TXT_ONLY */
/*==========================================
*
*------------------------------------------*/
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" };
char* filename[] = { "item_db.txt", "item_db2.txt" };
int fi;
for(i=0;i<2;i++){
sprintf(line, "%s/%s", db_path, filename[i]);
fp=fopen(line,"r");
if(fp==NULL){
if(i>0)
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;
ShowFatalError("can't read %s\n",line);
exit(1);
return -1;
}
lines=0;
// process rows one by one
while(fgets(line, sizeof(line), fp))
{
char *str[32], *p, *np;
int i;
lines++;
if(line[0]=='/' && line[1]=='/')
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;
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);
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;
}
}
// 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);
str[i] = p;
if ((p = strchr(p,',')) != NULL) {
*p++ = '\0'; np = p;
}
}
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((p=strchr(np,'{'))==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)
continue;
str[19] = p; //Script
np = strchr(p,'}');
while (np && np[1] && np[1] != ',')
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
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
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)
continue;
str[20] = p; //Equip Script
np = strchr(p,'}');
while (np && np[1] && np[1] != ',')
np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
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
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)
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);
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
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++;
}
// 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;
}
#endif /* not TXT_ONLY */
/*====================================
* Removed item_value_db, don't re-add
* read all item-related databases
*------------------------------------*/
static void itemdb_read(void)
{

View File

@ -19,6 +19,8 @@ struct Log_Config log_config;
char timestring[255];
time_t curtime;
static int should_log_item(int filter, int nameid, int amount); //log filter check
//FILTER OPTIONS
//0 = Don't log
//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)
{
#ifndef TXT_ONLY
char t_name[NAME_LENGTH*2];
#endif
FILE *logfp;
if(!log_config.enable_logs)
return 0;
nullpo_retr(0, sd);
#ifndef TXT_ONLY
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 1;
SqlStmt_Free(stmt);
}
else
#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;
}
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);
//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
if(log_config.sql_logs > 0)
{
if (itm==NULL) {
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 {
//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((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
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);
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
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);
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));
}
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;
}
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
}
//Mob picked item
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);
//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)
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) {
//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 {
//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;
}
}
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;
}
return 1;
}
else
#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));
{
FILE *logfp;
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);
if((logfp=fopen(log_config.log_pick,"a+")) == NULL)
return 0;
time(&curtime);
strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime));
} 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);
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
}
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;
nullpo_retr(0, sd);
#ifndef TXT_ONLY
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 1;
}
else
#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)
{
FILE *logfp;
if(!log_config.enable_logs)
return 0;
nullpo_retr(0, sd);
#ifndef TXT_ONLY
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 1;
}
else
#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)
return 0;
nullpo_retr(0, sd);
#ifndef TXT_ONLY
if(log_config.sql_logs > 0)
{
SqlStmt* stmt;
if (strlen(message) > CHAT_SIZE) {
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;
}
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 1;
SqlStmt_Free(stmt);
}
else
#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;
}
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)
return 0;
nullpo_retr(0, sd);
#ifndef TXT_ONLY
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 1;
SqlStmt_Free(stmt);
}
else
#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;
}
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)
// 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
//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
if(log_config.chat <= 0)
return 0; //Deactivated
#ifndef TXT_ONLY
if(log_config.sql_logs > 0){
if(log_config.sql_logs > 0)
{
SqlStmt* stmt;
if (strlen(message) > CHAT_SIZE) {
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;
}
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
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;
}

View File

@ -9,12 +9,6 @@ struct map_session_data;
struct mob_data;
struct item;
#ifndef TXT_ONLY
extern char db_server_logdb[32];
#endif //NOT TXT_ONLY
//New logs
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);
@ -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 should_log_item(int filter, int nameid, int amount); //log filter check
enum log_what {
LOG_ALL = 0xFFF,
LOG_TRADES = 0x002,

View File

@ -2,9 +2,6 @@
// For more information, see LICENCE in the main folder
#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/socket.h"
@ -27,318 +24,345 @@
int MAIL_CHECK_TIME = 120000;
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];
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;
}
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));
mysql_free_result(mail_res);
return 0;
}
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(!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 if(type==2){
snprintf(message, 80, msg_txt(513), i, mail_row[2]);
clif_displaymessage(sd->fd, message);
}
}
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);
if( Sql_NumRows(mail_handle) == 0)
{
clif_displaymessage(sd->fd, msg_txt(516)); // "You have no messages."
Sql_FreeResult(mail_handle);
return 0;
}
}
if(i>0 && new_>0 && type==1) {
//sprintf(message, "You have %d new messages.", new_);
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);
}
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)"
}
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, from_char_name);
clif_displaymessage(sd->fd, message); // "%d - From : %s"
}
}
Sql_FreeResult(mail_handle);
if( new_ > 0 && (type == 0 || type == 1) )
{
sprintf(message, msg_txt(514), new_);
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(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));
}
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;
}
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];
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);
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 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;
}
}
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);
}
}
//sprintf(message, "Reading message from %s", mail_row[2]);
sprintf(message, msg_txt(518), mail_row[2]);
clif_displaymessage(sd->fd, jstrescape(message));
sprintf(message, "%s", mail_row[3]);
clif_displaymessage(sd->fd, jstrescape(message));
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);
}
}
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;
}
int mail_delete(struct map_session_data *sd, int message_id)
{
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 (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;
}
}
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); 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);
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);
// 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);
}
} else {
ShowSQL("DB error - %s\n",mysql_error(&mail_handle));
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
sprintf(output, msg_txt(518), from_char_name);
clif_displaymessage(sd->fd, output); // "Reading message from %s"
clif_displaymessage(sd->fd, message);
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;
}
int mail_send(struct map_session_data *sd, char *name, char *message, int flag)
/// 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);
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( 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(strcmp(name,"*")==0) {
if(pc_isGM(sd) < 80) {
//clif_displaymessage(sd->fd, "Access Denied.");
clif_displaymessage(sd->fd, msg_txt(523));
if( 0 == Sql_NumRows(mail_handle) )
{
clif_displaymessage(sd->fd, msg_txt(517)); // "Message not found."
Sql_FreeResult(mail_handle);
return 0;
}
if( SQL_ERROR == Sql_NextRow(mail_handle) )
{
Sql_ShowDebug(mail_handle);
Sql_FreeResult(mail_handle);
return 0;
}
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);
Sql_FreeResult(mail_handle);
if( !read_flag && priority_flag )
{
clif_displaymessage(sd->fd,msg_txt(519)); // "Cannot delete unread priority mail."
return 0;
}
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;
}
/// 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);
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;
}
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;
}
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
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;
}
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(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;
}
}
}
//clif_displaymessage(sd->fd,"Mail has been sent.");
clif_displaymessage(sd->fd,msg_txt(525));
if( 0 == Sql_NumRows(mail_handle) )
{
clif_displaymessage(sd->fd,msg_txt(524)); // "Character does not exist."
Sql_FreeResult(mail_handle);
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);
if(pc_isGM(sd) < 80)
sd->mail_counter = 5;
clif_displaymessage(sd->fd,msg_txt(525)); // "Mail has been sent."
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--;
if(sd->status.account_id==id)
clif_displaymessage(sd->fd, msg_txt(526)); //you got new email.
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)
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;
}
mail_res = mysql_store_result(&mail_handle);
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;
}
while ((mail_row = mysql_fetch_row(mail_res)))
clif_foreachclient(mail_check_timer_sub, atoi(mail_row[0]));
}
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);
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."
}
mail_timer=add_timer(gettick()+MAIL_CHECK_TIME,mail_check_timer,0,0);
Sql_FreeResult(mail_handle);
// decrease the send-blocking counter
clif_foreachclient(mail_check_timer_sub);
// 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);
return 0;
}
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;
}

View File

@ -5,8 +5,8 @@
#define _MAIL_H_
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 do_init_mail(void);

View File

@ -11,6 +11,7 @@
#include "../common/version.h"
#include "../common/nullpo.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "map.h"
#include "chrif.h"
@ -34,11 +35,8 @@
#include "mercenary.h" //[orn]
#include "atcommand.h"
#include "charcommand.h"
#include "log.h"
#include "irc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -50,10 +48,20 @@
#endif
#ifndef TXT_ONLY
#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] = "";
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_pw[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;
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_pw[32] = "ragnarok";
char log_db[32] = "log";
MYSQL logmysql_handle;
MYSQL_RES* logsql_res;
MYSQL_ROW logsql_row;
Sql* logmysql_handle;
// mail system
int mail_server_enable = 0;
@ -91,9 +95,7 @@ char mail_server_id[32] = "ragnarok";
char mail_server_pw[32] = "ragnarok";
char mail_server_db[32] = "ragnarok";
char mail_db[32] = "mail";
MYSQL mail_handle;
MYSQL_RES* mail_res;
MYSQL_ROW mail_row;
Sql* mail_handle;
#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)
{ //Adjust final position to fit in the given area.
//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;
my1 = y0 + (y1 - y0)*length/k;
len_limit = MAGNITUDE2(x0,y0, mx1,my1);
@ -2951,43 +2953,30 @@ int inter_config_read(char *cfgName)
*---------------------------------------*/
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");
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));
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( strlen(default_codepage) > 0 )
if ( SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage) )
Sql_ShowDebug(mmysql_handle);
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);
}
else {
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 ) {
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( strlen(default_codepage) > 0 )
if ( SQL_ERROR == Sql_SetEncoding(mail_handle, default_codepage) )
Sql_ShowDebug(mail_handle);
}
return 0;
@ -2995,13 +2984,15 @@ int map_sql_init(void)
int map_sql_close(void)
{
mysql_close(&mmysql_handle);
ShowStatus("Close Map DB Connection....\n");
Sql_Free(mmysql_handle);
mmysql_handle = NULL;
if (log_config.sql_logs)
{
mysql_close(&logmysql_handle);
ShowStatus("Close Log DB Connection....\n");
Sql_Free(logmysql_handle);
logmysql_handle = NULL;
}
return 0;
@ -3009,25 +3000,18 @@ int map_sql_close(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);
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);
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;
}
@ -3037,31 +3021,25 @@ int log_sql_init(void)
int map_sql_ping(int tid, unsigned int tick, int id, int data)
{
ShowInfo("Pinging SQL server to keep connection alive...\n");
mysql_ping(&mmysql_handle);
Sql_Ping(mmysql_handle);
if (log_config.sql_logs)
mysql_ping(&logmysql_handle);
Sql_Ping(logmysql_handle);
if(mail_server_enable)
mysql_ping(&mail_handle);
Sql_Ping(mail_handle);
return 0;
}
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
// 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
connection_ping_interval = connection_timeout - 30; // 30-second reserve

View File

@ -795,7 +795,7 @@ struct map_session_data {
char fakename[NAME_LENGTH]; // fake names [Valaris]
#ifndef TXT_ONLY
int mail_counter; // mail counter for mail system [Valaris]
int mail_counter; // mail counter for mail system (antiflood protection)
#endif
int duel_group; // duel vars [LuzZza]
@ -1396,37 +1396,6 @@ extern char *MSG_CONF_NAME;
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]
typedef struct map_session_data TBL_PC;
typedef struct npc_data TBL_NPC;
@ -1444,4 +1413,24 @@ typedef struct homun_data TBL_HOM;
extern int lowest_gm_level;
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_ */

View File

@ -9,6 +9,7 @@
#include "../common/showmsg.h"
#include "../common/ers.h"
#include "../common/strlib.h"
#include "../common/utils.h"
#include "map.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);
}
int mob_parse_dbrow(char** str)
/*==========================================
* processes one mobdb entry
*------------------------------------------*/
static bool mob_parse_dbrow(char** str)
{
struct mob_db *db;
struct status_data *status;
@ -3220,15 +3224,15 @@ int mob_parse_dbrow(char** str)
class_ = str[0] ? atoi(str[0]) : 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) {
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_)) {
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)
@ -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)
{
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(fi > 0)
continue;
return -1;
}
// process rows one by one
while(fgets(line, sizeof(line), fp))
{
char *str[38+2*MAX_MOB_DROP], *p, *np;
int i;
lines++;
if(line[0] == '/' && line[1] == '/')
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) {
str[i] = p; *np = 0; p = np + 1;
} else
str[i] = p;
*np = '\0'; p = np + 1;
}
}
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;
}
if (!mob_parse_dbrow(str))
continue;
ln++; // counts the number of correctly parsed entries
count++;
}
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;
}
#ifndef TXT_ONLY
/*==========================================
* SQL reading
* mob_db table reading
*------------------------------------------*/
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;
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;
}
sql_res = mysql_store_result(&mmysql_handle);
if (sql_res) {
while((sql_row = mysql_fetch_row(sql_res))){
// 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);
if (!mob_parse_dbrow(sql_row))
continue;
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;
}

View File

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

View File

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

View File

@ -8,6 +8,7 @@
#include "../common/showmsg.h"
#include "../common/socket.h" // RFIFO*()
#include "../common/timer.h"
#include "../common/utils.h"
#include "atcommand.h" // get_atcommand_level()
#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
if(mail_server_enable)
mail_check(sd,1); // check mail at login [Valaris]
mail_check(sd,0); // check mail at login [Valaris]
#endif
// message of the limited time of the account

View File

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

View File

@ -226,13 +226,10 @@ int potion_hp=0, potion_per_hp=0, potion_sp=0, potion_per_sp=0;
int potion_target=0;
#if !defined(TXT_ONLY) && defined(MAPREGSQL)
// [zBuffer] SQL Mapreg Saving/Loading Database Declaration
char mapregsql_db[32] = "mapreg";
char mapregsql_db_varname[32] = "varname";
char mapregsql_db_index[32] = "index";
char mapregsql_db_value[32] = "value";
char tmp_sql[65535];
// --------------------------------------------------------
#endif
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)
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 !defined(TXT_ONLY) && defined(MAPREGSQL)
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.
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);
}
#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;
}
/*==========================================
*
*------------------------------------------*/
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)
int i = num >> 24;
char* name = str_buf + str_data[num&0x00ffffff].str;
if( str==NULL || *str==0 ) {
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);
mapreg_dirty=1;
mapreg_dirty = 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]
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
mapreg_dirty=1;
mapreg_dirty = 1;
return 1;
}
@ -3310,83 +3298,87 @@ int mapreg_setregstr(int num,const char *str)
static int script_load_mapreg(void)
{
#if defined(TXT_ONLY) || !defined(MAPREGSQL)
FILE *fp;
FILE* fp;
char line[1024];
if( (fp=fopen(mapreg_txt,"rt"))==NULL )
if( (fp=fopen(mapreg_txt,"rt")) == NULL )
return -1;
while(fgets(line,sizeof(line),fp))
{
char buf1[256],buf2[1024],*p;
char buf1[256],buf2[1024];
char* p;
int n,v,s,i;
if( sscanf(line,"%255[^,],%d\t%n",buf1,&i,&n)!=2 &&
(i=0,sscanf(line,"%[^\t]\t%n",buf1,&n)!=1) )
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;
}
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;
}
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);
mapreg_dirty=0;
mapreg_dirty = 0;
return 0;
#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;
}
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;
#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)
{
#if defined(TXT_ONLY) || !defined(MAPREGSQL)
FILE *fp=va_arg(ap,FILE*);
int num=key.i&0x00ffffff, i=key.i>>24;
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)
fprintf(fp,"%s\t%d\n", name, (int)data);
else
fprintf(fp,"%s,%d\t%d\n", name, i, (int)data);
}
return 0;
#else
int num=key.i&0x00ffffff, i=key.i>>24; // [zBuffer]
char *name=str_buf+str_data[num].str;
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
return 0;
}
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;
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)
fprintf(fp,"%s\t%s\n", name, (char *)data);
else
fprintf(fp,"%s,%d\t%s\n", name, i, (char *)data);
}
return 0;
#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] != '@') {
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
return 0;
}
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);
lock_fclose(fp,mapreg_txt,&lock);
#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);
perfomance = ((unsigned int)time(NULL) - perfomance);
if(perfomance > 2)
ShowWarning("Slow Query: MapregSQL Saving @ %d second(s).\n", perfomance);
#endif
mapreg_dirty=0;
return 0;
@ -3688,9 +3670,8 @@ int do_init_script()
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;
}
@ -12098,6 +12079,7 @@ BUILDIN_FUNC(checkcell)
// <--- [zBuffer] List of mathematics 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)
{
set_reg(st, sd, add_str(varname)+(elem<<24), varname, value, ref);
@ -12131,80 +12113,78 @@ BUILDIN_FUNC(setd)
BUILDIN_FUNC(query_sql)
{
#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);
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;
}
// 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);
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 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);
// 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)
{
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; // Nothing to store
}
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;
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++;
}
// Free data
mysql_free_result(sql_res);
}
// 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
Sql_FreeResult(mmysql_handle);
script_pushint(st,i);
#else
//for TXT version, we always return -1
script_pushint(st,-1);
#endif
return 0;
}

View File

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

View File

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

View File

@ -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
src/plugins/Makefile.in Normal file
View File

@ -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)

View File

@ -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
src/tool/Makefile.in Normal file
View File

@ -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"
#####################################################################

View File

@ -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

View File

@ -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

View File

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

View File

@ -6,16 +6,12 @@
#include "../common/core.h"
#include "../common/db.h"
#include "../common/showmsg.h"
#include "../common/sql.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <winsock2.h>
#endif
#include <mysql.h>
char login_account_id[256]="account_id";
char login_userid[256]="userid";
char login_user_pass[256]="user_pass";
@ -90,8 +86,8 @@ int read_gm_account()
int convert_login(void)
{
MYSQL mysql_handle;
char tmpsql[1024];
Sql* mysql_handle;
SqlStmt* stmt;
int line_counter = 0;
FILE *fp;
int account_id, logincount, user_level, state, n, i;
@ -100,11 +96,12 @@ int convert_login(void)
time_t connect_until_time;
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");
@ -133,21 +130,27 @@ int convert_login(void)
user_level = isGM(account_id);
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` "
"(`account_id`, `userid`, `user_pass`, `lastlogin`, `sex`, `logincount`, `email`, `level`, `error_message`, `connect_until`, `last_ip`, `memo`, `ban_until`, `state`) "
"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`
// then remove the 'dummy' buffer
}
fclose(fp);
Sql_Free(mysql_handle);
ShowStatus("Convert end...\n");

View File

@ -147,6 +147,14 @@ SOURCE=..\src\common\socket.h
# End 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
# End Source File
# Begin Source File
@ -233,14 +241,6 @@ SOURCE=..\src\char_sql\inter.c
SOURCE=..\src\char_sql\inter.h
# 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 Target
# End Project

View File

@ -155,6 +155,14 @@ SOURCE=..\src\common\socket.h
# End 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
# End Source File
# Begin Source File

View File

@ -155,6 +155,14 @@ SOURCE=..\src\common\socket.h
# End 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
# End Source File
# Begin Source File

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