summaryrefslogtreecommitdiff
path: root/src/char_sql
diff options
context:
space:
mode:
authorai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-07-10 06:17:06 +0000
committerai4rei <ai4rei@54d463be-8e91-2dee-dedb-b68131a5f0ec>2011-07-10 06:17:06 +0000
commit9ef634559f3cde232586b1dc6fd00bea3f3d8e53 (patch)
tree541295af8a6fbfe15b09da353680be6dd4d6b3ff /src/char_sql
parent9c100697bf79604fcef8b7eedbadeed45c63b41b (diff)
downloadhercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.gz
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.bz2
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.tar.xz
hercules-9ef634559f3cde232586b1dc6fd00bea3f3d8e53.zip
* Merged changes from trunk [14827:14894/trunk].
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/renewal@14895 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/char_sql')
-rw-r--r--src/char_sql/CMakeLists.txt57
-rw-r--r--src/char_sql/Makefile.in21
-rw-r--r--src/char_sql/char.c398
-rw-r--r--src/char_sql/char.h11
-rw-r--r--src/char_sql/int_auction.c4
-rw-r--r--src/char_sql/int_guild.c2
6 files changed, 369 insertions, 124 deletions
diff --git a/src/char_sql/CMakeLists.txt b/src/char_sql/CMakeLists.txt
new file mode 100644
index 000000000..f2d1cd0f0
--- /dev/null
+++ b/src/char_sql/CMakeLists.txt
@@ -0,0 +1,57 @@
+
+#
+# char sql
+#
+if( HAVE_common_sql )
+message( STATUS "Creating target char-server_sql" )
+set( SQL_CHAR_HEADERS
+ "${CMAKE_CURRENT_SOURCE_DIR}/char.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_auction.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_guild.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_homun.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_mail.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_mercenary.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_party.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_pet.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_quest.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_storage.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/inter.h"
+ )
+set( SQL_CHAR_SOURCES
+ "${CMAKE_CURRENT_SOURCE_DIR}/char.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_auction.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_guild.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_homun.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_mail.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_mercenary.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_party.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_pet.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_quest.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/int_storage.c"
+ "${CMAKE_CURRENT_SOURCE_DIR}/inter.c"
+ )
+set( DEPENDENCIES common_sql )
+set( LIBRARIES ${GLOBAL_LIBRARIES} )
+set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} )
+set( DEFINITIONS ${GLOBAL_DEFINITIONS} )
+set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
+source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} )
+source_group( char FILES ${SQL_CHAR_HEADERS} ${SQL_CHAR_SOURCES} )
+include_directories( ${INCLUDE_DIRS} )
+add_executable( char-server_sql ${SOURCE_FILES} )
+add_dependencies( char-server_sql ${DEPENDENCIES} )
+target_link_libraries( char-server_sql ${LIBRARIES} ${DEPENDENCIES} )
+set_target_properties( char-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" )
+if( WITH_COMPONENT_RUNTIME )
+ cpack_add_component( Runtime_charserver_sql DESCRIPTION "char-server (sql version)" DISPLAY_NAME "char-server_sql" GROUP Runtime )
+ install( TARGETS char-server_sql
+ DESTINATION "."
+ COMPONENT Runtime_charserver_sql )
+endif()
+message( STATUS "Creating target char-server_sql - done" )
+set( HAVE_char-server_sql ON CACHE BOOL "char-server_sql target is available" )
+mark_as_advanced( HAVE_char-server_sql )
+else()
+message( STATUS "Skipping target char-server_sql (requires common_sql)" )
+unset( HAVE_char-server_sql CACHE )
+endif()
diff --git a/src/char_sql/Makefile.in b/src/char_sql/Makefile.in
index 82c0a7c3f..a8cf8e08c 100644
--- a/src/char_sql/Makefile.in
+++ b/src/char_sql/Makefile.in
@@ -3,12 +3,16 @@ COMMON_OBJ = ../common/obj_all/core.o ../common/obj_all/socket.o ../common/obj_a
../common/obj_all/db.o ../common/obj_all/plugins.o ../common/obj_all/lock.o \
../common/obj_all/malloc.o ../common/obj_all/showmsg.o ../common/obj_all/utils.o \
../common/obj_all/strlib.o ../common/obj_all/grfio.o \
- ../common/obj_all/mapindex.o ../common/obj_all/ers.o
+ ../common/obj_all/mapindex.o ../common/obj_all/ers.o ../common/obj_all/random.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/mapindex.h ../common/ers.h ../common/random.h
+
+MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o
+MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h
+MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar
COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_H = ../common/sql.h
@@ -19,7 +23,7 @@ CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homu
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
- CHAR_SERVER_SQL_DEPENDS=obj_sql $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ)
+ CHAR_SERVER_SQL_DEPENDS=obj_sql $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ)
else
CHAR_SERVER_SQL_DEPENDS=needs_mysql
endif
@@ -32,7 +36,7 @@ endif
all: char-server_sql
char-server_sql: $(CHAR_SERVER_SQL_DEPENDS)
- @CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @MYSQL_LIBS@
+ @CC@ @LDFLAGS@ -o ../../char-server_sql@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @MYSQL_LIBS@
clean:
rm -rf *.o obj_sql ../../char-server_sql@EXEEXT@
@@ -53,12 +57,15 @@ needs_mysql:
obj_sql:
-mkdir obj_sql
-obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(COMMON_SQL_H)
- @CC@ @CFLAGS@ @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
+obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(COMMON_SQL_H) $(MT19937AR_H)
+ @CC@ @CFLAGS@ $(MT19937AR_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-# missing common object files
+# missing object files
../common/obj_all/%.o:
@$(MAKE) -C ../common sql
../common/obj_sql/%.o:
@$(MAKE) -C ../common sql
+
+MT19937AR_OBJ:
+ @$(MAKE) -C ../../3rdparty/mt19937ar
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 5ad5a273b..b1c171ebf 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -194,7 +194,7 @@ struct online_char_data {
};
static DBMap* online_char_db; // int account_id -> struct online_char_data*
-static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data);
+static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
static void* create_online_char_data(DBKey key, va_list args)
{
@@ -590,11 +590,11 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
//insert here.
for( i = 0, count = 0; i < MAX_SKILL; ++i )
{
- if(p->skill[i].id && p->skill[i].flag!=1)
+ if(p->skill[i].id != 0 && p->skill[i].flag != SKILL_FLAG_TEMPORARY)
{
if( count )
StringBuf_AppendStr(&buf, ",");
- StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == 0 ? p->skill[i].lv : p->skill[i].flag - 2));
+ StringBuf_Printf(&buf, "('%d','%d','%d')", char_id, p->skill[i].id, (p->skill[i].flag == SKILL_FLAG_PERMANENT ? p->skill[i].lv : p->skill[i].flag - SKILL_FLAG_REPLACED_LV_0));
++count;
}
}
@@ -1107,7 +1107,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_skill.lv, 0, NULL, NULL) )
SqlStmt_ShowDebug(stmt);
- tmp_skill.flag = 0;
+ tmp_skill.flag = SKILL_FLAG_PERMANENT;
for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
@@ -1543,7 +1543,7 @@ int count_users(void)
int i, users;
users = 0;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
if (server[i].fd > 0) {
users += server[i].users;
}
@@ -1778,24 +1778,75 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
// continues when account data is received...
}
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data);
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
+void mapif_server_reset(int id);
-int parse_fromlogin(int fd)
+
+/// Resets all the data.
+void loginif_reset(void)
+{
+ int id;
+ // TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
+ mapif_server_reset(id);
+ flush_fifos();
+ exit(EXIT_FAILURE);
+}
+
+
+/// Checks the conditions for the server to stop.
+/// Releases the cookie when all characters are saved.
+/// If all the conditions are met, it stops the core loop.
+void loginif_check_shutdown(void)
+{
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
+ return;
+ runflag = CORE_ST_STOP;
+}
+
+
+/// Called when the connection to Login Server is disconnected.
+void loginif_on_disconnect(void)
+{
+ ShowWarning("Connection to Login Server lost.\n\n");
+}
+
+
+/// Called when all the connection steps are completed.
+void loginif_on_ready(void)
{
int i;
- struct char_session_data *sd;
- // only login-server can have an access to here.
- // so, if it isn't the login-server, we disconnect the session.
+ loginif_check_shutdown();
+
+ //Send online accounts to login server.
+ send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
+
+ // if no map-server already connected, display a message...
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd > 0 && server[i].map[0] );
+ if( i == ARRAYLENGTH(server) )
+ ShowStatus("Awaiting maps from map-server.\n");
+}
+
+
+int parse_fromlogin(int fd)
+{
+ struct char_session_data* sd = NULL;
+ int i;
+
+ // only process data from the login-server
if( fd != login_fd )
- set_eof(fd);
+ {
+ ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd);
+ do_close(fd);
+ return 0;
+ }
- if(session[fd]->flag.eof) {
- if (fd == login_fd) {
- ShowWarning("Connection to login-server lost (connection #%d).\n", fd);
- login_fd = -1;
- }
+ if( session[fd]->flag.eof )
+ {
do_close(fd);
+ login_fd = -1;
+ loginif_on_disconnect();
return 0;
}
@@ -1819,16 +1870,11 @@ int parse_fromlogin(int fd)
ShowError("The server communication passwords (default s1/p1) are probably invalid.\n");
ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n");
ShowError("The communication passwords are set in map_athena.conf and char_athena.conf\n");
+ set_eof(fd);
+ return 0;
} else {
ShowStatus("Connected to login-server (connection #%d).\n", fd);
-
- //Send online accounts to login server.
- send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
-
- // if no map-server already connected, display a message...
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd > 0 && server[i].map[0] );
- if( i == MAX_MAP_SERVERS )
- ShowStatus("Awaiting maps from map-server.\n");
+ loginif_on_ready();
}
RFIFOSKIP(fd,3);
break;
@@ -2096,6 +2142,34 @@ int parse_fromlogin(int fd)
return 0;
}
+int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
+int ping_login_server(int tid, unsigned int tick, int id, intptr_t data);
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
+
+void do_init_loginif(void)
+{
+ // establish char-login connection if not present
+ add_timer_func_list(check_connect_login_server, "check_connect_login_server");
+ add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
+
+ // keep the char-login connection alive
+ add_timer_func_list(ping_login_server, "ping_login_server");
+ add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
+
+ // send a list of all online account IDs to login server
+ add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
+ add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
+}
+
+void do_final_loginif(void)
+{
+ if( login_fd != -1 )
+ {
+ do_close(login_fd);
+ login_fd = -1;
+ }
+}
+
int request_accreg2(int account_id, int char_id)
{
if (login_fd > 0) {
@@ -2252,39 +2326,79 @@ int char_loadName(int char_id, char* name)
int search_mapserver(unsigned short map, uint32 ip, uint16 port);
+
+/// Initializes a server structure.
+void mapif_server_init(int id)
+{
+ memset(&server[id], 0, sizeof(server[id]));
+ server[id].fd = -1;
+}
+
+
+/// Destroys a server structure.
+void mapif_server_destroy(int id)
+{
+ if( server[id].fd == -1 )
+ {
+ do_close(server[id].fd);
+ server[id].fd = -1;
+ }
+}
+
+
+/// Resets all the data related to a server.
+void mapif_server_reset(int id)
+{
+ int i,j;
+ unsigned char buf[16384];
+ int fd = server[id].fd;
+ //Notify other map servers that this one is gone. [Skotlex]
+ WBUFW(buf,0) = 0x2b20;
+ WBUFL(buf,4) = htonl(server[id].ip);
+ WBUFW(buf,8) = htons(server[id].port);
+ j = 0;
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ if (server[id].map[i])
+ WBUFW(buf,10+(j++)*4) = server[id].map[i];
+ if (j > 0) {
+ WBUFW(buf,2) = j * 4 + 10;
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+ if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server[id].fd) )
+ Sql_ShowDebug(sql_handle);
+ online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
+ mapif_server_destroy(id);
+ mapif_server_init(id);
+}
+
+
+/// Called when the connection to a Map Server is disconnected.
+void mapif_on_disconnect(int id)
+{
+ ShowStatus("Map-server #%d has disconnected.\n", id);
+ mapif_server_reset(id);
+}
+
+
int parse_frommap(int fd)
{
int i, j;
int id;
- ARR_FIND( 0, MAX_MAP_SERVERS, id, server[id].fd == fd );
- if(id == MAX_MAP_SERVERS)
- set_eof(fd);
- if(session[fd]->flag.eof) {
- if (id < MAX_MAP_SERVERS) {
- unsigned char buf[16384];
- ShowStatus("Map-server %d (session #%d) has disconnected.\n", id, fd);
- //Notify other map servers that this one is gone. [Skotlex]
- WBUFW(buf,0) = 0x2b20;
- WBUFL(buf,4) = htonl(server[id].ip);
- WBUFW(buf,8) = htons(server[id].port);
- j = 0;
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
- if (server[id].map[i])
- WBUFW(buf,10+(j++)*4) = server[id].map[i];
- if (j > 0) {
- WBUFW(buf,2) = j * 4 + 10;
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
- memset(&server[id], 0, sizeof(struct mmo_map_server));
- if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server[id].fd) )
- Sql_ShowDebug(sql_handle);
- server[id].fd = -1;
- online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
- }
+ ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
+ if( id == ARRAYLENGTH(server) )
+ {// not a map server
+ ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd);
do_close(fd);
return 0;
}
+ if( session[fd]->flag.eof )
+ {
+ do_close(fd);
+ server[id].fd = -1;
+ mapif_on_disconnect(id);
+ return 0;
+ }
while(RFIFOREST(fd) >= 2)
{
@@ -2330,14 +2444,14 @@ int parse_frommap(int fd)
mapif_sendallwos(fd, buf, WBUFW(buf,2));
}
// Transmitting the maps of the other map-servers to the new map-server
- for(x = 0; x < MAX_MAP_SERVERS; x++) {
+ for(x = 0; x < ARRAYLENGTH(server); x++) {
if (server[x].fd > 0 && x != id) {
- WFIFOHEAD(fd,10 +4*MAX_MAP_PER_SERVER);
+ WFIFOHEAD(fd,10 +4*ARRAYLENGTH(server));
WFIFOW(fd,0) = 0x2b04;
WFIFOL(fd,4) = htonl(server[x].ip);
WFIFOW(fd,8) = htons(server[x].port);
j = 0;
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ for(i = 0; i < ARRAYLENGTH(server); i++)
if (server[x].map[i])
WFIFOW(fd,10+(j++)*4) = server[x].map[i];
if (j > 0) {
@@ -2491,27 +2605,38 @@ int parse_frommap(int fd)
uint32 login_id2 = RFIFOL(fd,10);
uint32 ip = RFIFOL(fd,14);
RFIFOSKIP(fd,18);
-
- // create temporary auth entry
- CREATE(node, struct auth_node, 1);
- node->account_id = account_id;
- node->char_id = 0;
- node->login_id1 = login_id1;
- node->login_id2 = login_id2;
- //node->sex = 0;
- node->ip = ntohl(ip);
- //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
- //node->gmlevel = 0;
- idb_put(auth_db, account_id, node);
-
- //Set char to "@ char select" in online db [Kevin]
- set_char_charselect(account_id);
-
- WFIFOHEAD(fd,7);
- WFIFOW(fd,0) = 0x2b03;
- WFIFOL(fd,2) = account_id;
- WFIFOB(fd,6) = 0;
- WFIFOSET(fd,7);
+
+ if( runflag != CHARSERVER_ST_RUNNING )
+ {
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b03;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 0;// not ok
+ WFIFOSET(fd,7);
+ }
+ else
+ {
+ // create temporary auth entry
+ CREATE(node, struct auth_node, 1);
+ node->account_id = account_id;
+ node->char_id = 0;
+ node->login_id1 = login_id1;
+ node->login_id2 = login_id2;
+ //node->sex = 0;
+ node->ip = ntohl(ip);
+ //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
+ //node->gmlevel = 0;
+ idb_put(auth_db, account_id, node);
+
+ //Set char to "@ char select" in online db [Kevin]
+ set_char_charselect(account_id);
+
+ WFIFOHEAD(fd,7);
+ WFIFOW(fd,0) = 0x2b03;
+ WFIFOL(fd,2) = account_id;
+ WFIFOB(fd,6) = 1;// ok
+ WFIFOSET(fd,7);
+ }
}
break;
@@ -2534,8 +2659,10 @@ int parse_frommap(int fd)
mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
}
-
- if (map_fd >= 0 && session[map_fd] && char_data)
+
+ if( runflag == CHARSERVER_ST_RUNNING &&
+ session_isActive(map_fd) &&
+ char_data )
{ //Send the map server the auth of this player.
struct auth_node* node;
@@ -2879,7 +3006,9 @@ int parse_frommap(int fd)
mmo_char_fromsql(char_id, &char_dat, true);
cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
}
- if( node != NULL && cd != NULL &&
+ if( runflag == CHARSERVER_ST_RUNNING &&
+ cd != NULL &&
+ node != NULL &&
node->account_id == account_id &&
node->char_id == char_id &&
node->login_id1 == login_id1 &&
@@ -2942,13 +3071,27 @@ int parse_frommap(int fd)
return 0;
}
+void do_init_mapif(void)
+{
+ int i;
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ mapif_server_init(i);
+}
+
+void do_final_mapif(void)
+{
+ int i;
+ for( i = 0; i < ARRAYLENGTH(server); ++i )
+ mapif_server_destroy(i);
+}
+
// Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
// If found, returns the server's index in the 'server' array (otherwise returns -1).
int search_mapserver(unsigned short map, uint32 ip, uint16 port)
{
int i, j;
- for(i = 0; i < MAX_MAP_SERVERS; i++)
+ for(i = 0; i < ARRAYLENGTH(server); i++)
{
if (server[i].fd > 0
&& (ip == (uint32)-1 || server[i].ip == ip)
@@ -3276,6 +3419,15 @@ int parse_char(int fd)
WFIFOL(fd,0) = account_id;
WFIFOSET(fd,4);
+ if( runflag != CHARSERVER_ST_RUNNING )
+ {
+ WFIFOHEAD(fd,3);
+ WFIFOW(fd,0) = 0x6c;
+ WFIFOB(fd,2) = 0;// rejected from server
+ WFIFOSET(fd,3);
+ break;
+ }
+
// search authentification
node = (struct auth_node*)idb_get(auth_db, account_id);
if( node != NULL &&
@@ -3361,8 +3513,8 @@ int parse_char(int fd)
if (i < 0) {
unsigned short j;
//First check that there's actually a map server online.
- ARR_FIND( 0, MAX_MAP_SERVERS, j, server[j].fd >= 0 && server[j].map[0] );
- if (j == MAX_MAP_SERVERS) {
+ ARR_FIND( 0, ARRAYLENGTH(server), j, server[j].fd >= 0 && server[j].map[0] );
+ if (j == ARRAYLENGTH(server)) {
ShowInfo("Connection Closed. No map servers available.\n");
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x81;
@@ -3665,8 +3817,12 @@ int parse_char(int fd)
char* l_pass = (char*)RFIFOP(fd,26);
l_user[23] = '\0';
l_pass[23] = '\0';
- ARR_FIND( 0, MAX_MAP_SERVERS, i, server[i].fd <= 0 );
- if (i == MAX_MAP_SERVERS || strcmp(l_user, userid) || strcmp(l_pass, passwd)) {
+ ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 );
+ if( runflag != CHARSERVER_ST_RUNNING ||
+ i == ARRAYLENGTH(server) ||
+ strcmp(l_user, userid) != 0 ||
+ strcmp(l_pass, passwd) != 0 )
+ {
WFIFOHEAD(fd,3);
WFIFOW(fd,0) = 0x2af9;
WFIFOB(fd,2) = 3;
@@ -3729,7 +3885,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len)
int i, c;
c = 0;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0) {
WFIFOHEAD(fd,len);
@@ -3747,7 +3903,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
int i, c;
c = 0;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ for(i = 0; i < ARRAYLENGTH(server); i++) {
int fd;
if ((fd = server[i].fd) > 0 && fd != sfd) {
WFIFOHEAD(fd,len);
@@ -3765,8 +3921,8 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
int i;
if (fd >= 0) {
- ARR_FIND( 0, MAX_MAP_SERVERS, i, fd == server[i].fd );
- if( i < MAX_MAP_SERVERS )
+ ARR_FIND( 0, ARRAYLENGTH(server), i, fd == server[i].fd );
+ if( i < ARRAYLENGTH(server) )
{
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
@@ -3777,7 +3933,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len)
return 0;
}
-int broadcast_user_count(int tid, unsigned int tick, int id, intptr data)
+int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
{
uint8 buf[6];
int users = count_users();
@@ -3820,7 +3976,7 @@ static int send_accounts_tologin_sub(DBKey key, void* data, va_list ap)
return 0;
}
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
+int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd])
{
@@ -3838,7 +3994,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr data)
return 0;
}
-int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
+int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
return 0;
@@ -3871,7 +4027,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr data)
}
// sends a ping packet to login server (will receive pong 0x2718)
-int ping_login_server(int tid, unsigned int tick, int id, intptr data)
+int ping_login_server(int tid, unsigned int tick, int id, intptr_t data)
{
if (login_fd > 0 && session[login_fd] != NULL)
{
@@ -3886,7 +4042,7 @@ int ping_login_server(int tid, unsigned int tick, int id, intptr data)
//Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't
//replies/disconnect the player we tried to kick. [Skotlex]
//------------------------------------------------
-static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr data)
+static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data)
{
struct online_char_data* character;
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
@@ -3910,7 +4066,7 @@ static int online_data_cleanup_sub(DBKey key, void *data, va_list ap)
return 0;
}
-static int online_data_cleanup(int tid, unsigned int tick, int id, intptr data)
+static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data)
{
online_char_db->foreach(online_char_db, online_data_cleanup_sub);
return 0;
@@ -4211,7 +4367,7 @@ int char_config_read(const char* cfgName)
void do_final(void)
{
- ShowStatus("Terminating server.\n");
+ ShowStatus("Terminating...\n");
set_all_offline(-1);
set_all_offline_sql();
@@ -4219,6 +4375,9 @@ void do_final(void)
inter_final();
flush_fifos();
+
+ do_final_mapif();
+ do_final_loginif();
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `ragsrvinfo`") )
Sql_ShowDebug(sql_handle);
@@ -4227,13 +4386,16 @@ void do_final(void)
online_char_db->destroy(online_char_db, NULL);
auth_db->destroy(auth_db, NULL);
- if (login_fd > 0)
- do_close(login_fd);
- if (char_fd > 0)
+ if( char_fd != -1 )
+ {
do_close(char_fd);
+ char_fd = -1;
+ }
Sql_Free(sql_handle);
mapindex_final();
+
+ ShowStatus("Finished.\n");
}
//------------------------------
@@ -4249,15 +4411,27 @@ void set_server_type(void)
SERVER_TYPE = ATHENA_SERVER_CHAR;
}
-int do_init(int argc, char **argv)
-{
- int i;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
- memset(&server[i], 0, sizeof(struct mmo_map_server));
- server[i].fd = -1;
+/// Called when a terminate signal is received.
+void do_shutdown(void)
+{
+ if( runflag != CHARSERVER_ST_SHUTDOWN )
+ {
+ int id;
+ runflag = CHARSERVER_ST_SHUTDOWN;
+ ShowStatus("Shutting down...\n");
+ // TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
+ for( id = 0; id < ARRAYLENGTH(server); ++id )
+ mapif_server_reset(id);
+ loginif_check_shutdown();
+ flush_fifos();
+ runflag = CORE_ST_STOP;
}
+}
+
+int do_init(int argc, char **argv)
+{
//Read map indexes
mapindex_init();
start_point.map = mapindex_name2id("new_zone01");
@@ -4284,8 +4458,6 @@ int do_init(int argc, char **argv)
char_read_fame_list(); //Read fame lists.
ShowInfo("char server initialized.\n");
- set_defaultparse(parse_char);
-
if ((naddr_ != 0) && (!login_ip || !char_ip))
{
char ip_str[16];
@@ -4305,22 +4477,13 @@ int do_init(int argc, char **argv)
}
}
- // establish char-login connection if not present
- add_timer_func_list(check_connect_login_server, "check_connect_login_server");
- add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
-
- // keep the char-login connection alive
- add_timer_func_list(ping_login_server, "ping_login_server");
- add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000);
+ do_init_loginif();
+ do_init_mapif();
// periodically update the overall user count on all mapservers + login server
add_timer_func_list(broadcast_user_count, "broadcast_user_count");
add_timer_interval(gettick() + 1000, broadcast_user_count, 0, 0, 5 * 1000);
- // send a list of all online account IDs to login server
- add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
- add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
-
// ???
add_timer_func_list(chardb_waiting_disconnect, "chardb_waiting_disconnect");
@@ -4351,9 +4514,16 @@ int do_init(int argc, char **argv)
ShowInfo("End of char server initilization function.\n");
+ set_defaultparse(parse_char);
ShowInfo("open port %d.....\n",char_port);
char_fd = make_listen_bind(bind_ip, char_port);
ShowStatus("The char-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %d).\n\n", char_port);
+
+ if( runflag != CORE_ST_STOP )
+ {
+ shutdown_callback = do_shutdown;
+ runflag = CHARSERVER_ST_RUNNING;
+ }
return 0;
}
diff --git a/src/char_sql/char.h b/src/char_sql/char.h
index a40340cfb..c9ec54a16 100644
--- a/src/char_sql/char.h
+++ b/src/char_sql/char.h
@@ -4,6 +4,17 @@
#ifndef _CHAR_SQL_H_
#define _CHAR_SQL_H_
+#include "../common/core.h" // CORE_ST_LAST
+
+#ifndef TXT_SQL_CONVERT
+enum E_CHARSERVER_ST
+{
+ CHARSERVER_ST_RUNNING = CORE_ST_LAST,
+ CHARSERVER_ST_SHUTDOWN,
+ CHARSERVER_ST_LAST
+};
+#endif
+
struct mmo_charstatus;
#define MAX_MAP_SERVERS 30
diff --git a/src/char_sql/int_auction.c b/src/char_sql/int_auction.c
index bba693256..04e321062 100644
--- a/src/char_sql/int_auction.c
+++ b/src/char_sql/int_auction.c
@@ -21,7 +21,7 @@
static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data*
void auction_delete(struct auction_data *auction);
-static int auction_end_timer(int tid, unsigned int tick, int id, intptr data);
+static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data);
static int auction_count(int char_id, bool buy)
{
@@ -136,7 +136,7 @@ static void mapif_Auction_message(int char_id, unsigned char result)
mapif_sendall(buf,7);
}
-static int auction_end_timer(int tid, unsigned int tick, int id, intptr data)
+static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct auction_data *auction;
if( (auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL )
diff --git a/src/char_sql/int_guild.c b/src/char_sql/int_guild.c
index 0b3d77f07..9b5692689 100644
--- a/src/char_sql/int_guild.c
+++ b/src/char_sql/int_guild.c
@@ -47,7 +47,7 @@ int mapif_guild_info(int fd,struct guild *g);
int guild_break_sub(int key,void *data,va_list ap);
int inter_guild_tosql(struct guild *g,int flag);
-static int guild_save_timer(int tid, unsigned int tick, int id, intptr data)
+static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data)
{
static int last_id = 0; //To know in which guild we were.
int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving.