diff options
Diffstat (limited to 'src/char_sql')
-rw-r--r-- | src/char_sql/CMakeLists.txt | 57 | ||||
-rw-r--r-- | src/char_sql/Makefile.in | 21 | ||||
-rw-r--r-- | src/char_sql/char.c | 398 | ||||
-rw-r--r-- | src/char_sql/char.h | 11 | ||||
-rw-r--r-- | src/char_sql/int_auction.c | 4 | ||||
-rw-r--r-- | src/char_sql/int_guild.c | 2 |
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. |