diff options
Diffstat (limited to 'src/login')
-rw-r--r-- | src/login/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/login/Makefile.in | 33 | ||||
-rw-r--r-- | src/login/account_txt.c | 6 | ||||
-rw-r--r-- | src/login/ipban_sql.c | 4 | ||||
-rw-r--r-- | src/login/login.c | 130 | ||||
-rw-r--r-- | src/login/login.h | 8 | ||||
-rw-r--r-- | src/login/sql/CMakeLists.txt | 43 | ||||
-rw-r--r-- | src/login/txt/CMakeLists.txt | 43 |
8 files changed, 235 insertions, 44 deletions
diff --git a/src/login/CMakeLists.txt b/src/login/CMakeLists.txt new file mode 100644 index 000000000..afa4e5f20 --- /dev/null +++ b/src/login/CMakeLists.txt @@ -0,0 +1,12 @@ + +# +# setup +# +set( LOGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) + + +# +# targets +# +add_subdirectory( txt ) +add_subdirectory( sql ) diff --git a/src/login/Makefile.in b/src/login/Makefile.in index c153d95b3..fa1933964 100644 --- a/src/login/Makefile.in +++ b/src/login/Makefile.in @@ -3,16 +3,20 @@ 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/md5calc.o + ../common/obj_all/ers.o ../common/obj_all/md5calc.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/md5calc.h + ../common/ers.h ../common/md5calc.h ../common/random.h COMMON_SQL_OBJ = ../common/obj_sql/sql.o COMMON_SQL_H = ../common/sql.h +MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o +MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h +MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar + LOGIN_OBJ = login.o LOGIN_TXT_OBJ = $(LOGIN_OBJ:%=obj_txt/%) \ obj_txt/account_txt.o obj_txt/ipban_txt.o obj_txt/loginlog_txt.o @@ -22,10 +26,11 @@ LOGIN_H = login.h account.h ipban.h loginlog.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) - LOGIN_SERVER_SQL_DEPENDS=obj_sql $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) + LOGIN_SERVER_SQL_DEPENDS=obj_sql $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) else LOGIN_SERVER_SQL_DEPENDS=needs_mysql endif +LOGIN_SERVER_TXT_DEPENDS=obj_txt $(LOGIN_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @SET_MAKE@ @@ -63,19 +68,25 @@ obj_sql: test -d obj_sql || mkdir obj_sql #executables -login-server: $(LOGIN_TXT_OBJ) $(COMMON_OBJ) - @CC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_TXT_OBJ) $(COMMON_OBJ) @LIBS@ +login-server: $(LOGIN_SERVER_TXT_DEPENDS) + @CC@ @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_TXT_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@ login-server_sql: $(LOGIN_SERVER_SQL_DEPENDS) - @CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) @LIBS@ @MYSQL_LIBS@ + @CC@ @LDFLAGS@ -o ../../login-server_sql@EXEEXT@ $(LOGIN_SQL_OBJ) $(COMMON_OBJ) $(COMMON_SQL_OBJ) $(MT19937AR_OBJ) @LIBS@ @MYSQL_LIBS@ # login object files -obj_txt/%.o: %.c $(LOGIN_H) $(COMMON_H) - @CC@ @CFLAGS@ -DWITH_TXT @CPPFLAGS@ -c $(OUTPUT_OPTION) $< +obj_txt/%.o: %.c $(LOGIN_H) $(COMMON_H) $(MT19937AR_H) + @CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DWITH_TXT @CPPFLAGS@ -c $(OUTPUT_OPTION) $< -obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H) - @CC@ @CFLAGS@ -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< +obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H) $(MT19937AR_H) + @CC@ @CFLAGS@ $(MT19937AR_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< -# missing common object files +# missing object files ../common/obj_all/%.o: + @$(MAKE) -C ../common txt + +../common/obj_sql/%.o: @$(MAKE) -C ../common sql + +MT19937AR_OBJ: + @$(MAKE) -C ../../3rdparty/mt19937ar diff --git a/src/login/account_txt.c b/src/login/account_txt.c index 758a2c24e..821e26df5 100644 --- a/src/login/account_txt.c +++ b/src/login/account_txt.c @@ -58,7 +58,7 @@ static bool account_db_txt_iter_next(AccountDBIterator* self, struct mmo_account static bool mmo_auth_fromstr(struct mmo_account* acc, char* str, unsigned int version); static bool mmo_auth_tostr(const struct mmo_account* acc, char* str); static void mmo_auth_sync(AccountDB_TXT* self); -static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr data); +static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr_t data); /// public constructor AccountDB* account_db_txt(void) @@ -183,7 +183,7 @@ static bool account_db_txt_init(AccountDB* self) // initialize data saving timer add_timer_func_list(mmo_auth_sync_timer, "mmo_auth_sync_timer"); - db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr)db, AUTH_SAVING_INTERVAL); + db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr_t)db, AUTH_SAVING_INTERVAL); return true; } @@ -634,7 +634,7 @@ static void mmo_auth_sync(AccountDB_TXT* db) db->auths_before_save = AUTHS_BEFORE_SAVE; } -static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr data) +static int mmo_auth_sync_timer(int tid, unsigned int tick, int id, intptr_t data) { AccountDB_TXT* db = (AccountDB_TXT*)data; diff --git a/src/login/ipban_sql.c b/src/login/ipban_sql.c index ef463905e..c75a1f956 100644 --- a/src/login/ipban_sql.c +++ b/src/login/ipban_sql.c @@ -35,7 +35,7 @@ static Sql* sql_handle = NULL; static int cleanup_timer_id = INVALID_TIMER; static bool ipban_inited = false; -int ipban_cleanup(int tid, unsigned int tick, int id, intptr data); +int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data); // initialize @@ -246,7 +246,7 @@ void ipban_log(uint32 ip) } // remove expired bans -int ipban_cleanup(int tid, unsigned int tick, int id, intptr data) +int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data) { if( !login_config.ipban ) return 0;// ipban disabled diff --git a/src/login/login.c b/src/login/login.c index 6d8043baf..e57293a4c 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -101,7 +101,7 @@ struct online_login_data { }; static DBMap* online_db; // int account_id -> struct online_login_data* -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr data); +static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data); static void* create_online_user(DBKey key, va_list args) { @@ -138,7 +138,7 @@ void remove_online_user(int account_id) idb_remove(online_db, account_id); } -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr data) +static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data) { struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id); if( p != NULL && p->waiting_disconnect == tid && p->account_id == id ) @@ -176,7 +176,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_db->foreach(online_db, online_data_cleanup_sub); return 0; @@ -190,7 +190,7 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len) { int i, c; - for( i = 0, c = 0; i < MAX_SERVERS; ++i ) + for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i ) { int fd = server[i].fd; if( session_isValid(fd) && fd != sfd ) @@ -206,10 +206,46 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len) } +/// Initializes a server structure. +void chrif_server_init(int id) +{ + memset(&server[id], 0, sizeof(server[id])); + server[id].fd = -1; +} + + +/// Destroys a server structure. +void chrif_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 chrif_server_reset(int id) +{ + online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline. + chrif_server_destroy(id); + chrif_server_init(id); +} + + +/// Called when the connection to Char Server is disconnected. +void chrif_on_disconnect(int id) +{ + ShowStatus("Char-server '%s' has disconnected.\n", server[id].name); + chrif_server_reset(id); +} + + //----------------------------------------------------- // periodic ip address synchronization //----------------------------------------------------- -static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr data) +static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr_t data) { uint8 buf[2]; ShowInfo("IP Sync in progress...\n"); @@ -381,9 +417,10 @@ int parse_fromchar(int fd) uint32 ipl; char ip[16]; - ARR_FIND( 0, MAX_SERVERS, id, server[id].fd == fd ); - if( id == MAX_SERVERS ) + ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd ); + if( id == ARRAYLENGTH(server) ) {// not a char server + ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd); set_eof(fd); do_close(fd); return 0; @@ -391,11 +428,9 @@ int parse_fromchar(int fd) if( session[fd]->flag.eof ) { - ShowStatus("Char-server '%s' has disconnected.\n", server[id].name); - online_db->foreach(online_db, online_db_setoffline, id); //Set all chars from this char server to offline. - memset(&server[id], 0, sizeof(struct mmo_char_server)); - server[id].fd = -1; do_close(fd); + server[id].fd = -1; + chrif_on_disconnect(id); return 0; } @@ -424,8 +459,9 @@ int parse_fromchar(int fd) RFIFOSKIP(fd,23); node = (struct auth_node*)idb_get(auth_db, account_id); - if( node != NULL && - node->account_id == account_id && + if( runflag == LOGINSERVER_ST_RUNNING && + node != NULL && + node->account_id == account_id && node->login_id1 == login_id1 && node->login_id2 == login_id2 && node->sex == sex_num2str(sex) /*&& @@ -1059,6 +1095,16 @@ void login_auth_ok(struct login_session_data* sd) struct auth_node* node; int i; + if( runflag != LOGINSERVER_ST_RUNNING ) + { + // players can only login while running + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x81; + WFIFOB(fd,2) = 1;// server closed + WFIFOSET(fd,3); + return; + } + if( sd->level < login_config.min_level_to_connect ) { ShowStatus("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d).\n", login_config.min_level_to_connect, sd->userid, sd->level); @@ -1070,8 +1116,8 @@ void login_auth_ok(struct login_session_data* sd) } server_num = 0; - for( i = 0; i < MAX_SERVERS; ++i ) - if( session_isValid(server[i].fd) ) + for( i = 0; i < ARRAYLENGTH(server); ++i ) + if( session_isActive(server[i].fd) ) server_num++; if( server_num == 0 ) @@ -1133,7 +1179,7 @@ void login_auth_ok(struct login_session_data* sd) memset(WFIFOP(fd,20), 0, 24); WFIFOW(fd,44) = 0; // unknown WFIFOB(fd,46) = sex_str2num(sd->sex); - for( i = 0, n = 0; i < MAX_SERVERS; ++i ) + for( i = 0, n = 0; i < ARRAYLENGTH(server); ++i ) { if( !session_isValid(server[i].fd) ) continue; @@ -1404,7 +1450,11 @@ int parse_login(int fd) login_log(session[fd]->client_addr, sd->userid, 100, message); result = mmo_auth(sd); - if( result == -1 && sd->sex == 'S' && sd->account_id < MAX_SERVERS && server[sd->account_id].fd == -1 ) + if( runflag == LOGINSERVER_ST_RUNNING && + result == -1 && + sd->sex == 'S' && + sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) && + !session_isValid(server[sd->account_id].fd) ) { ShowStatus("Connection of the char-server '%s' accepted.\n", server_name); safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name)); @@ -1592,7 +1642,7 @@ static AccountDB* get_account_engine(void) //-------------------------------------- void do_final(void) { - int i, fd; + int i; login_log(0, "login server", 100, "login server shutdown"); ShowStatus("Terminating...\n"); @@ -1614,15 +1664,15 @@ void do_final(void) accounts = NULL; // destroyed in account_engines online_db->destroy(online_db, NULL); auth_db->destroy(auth_db, NULL); + + for( i = 0; i < ARRAYLENGTH(server); ++i ) + chrif_server_destroy(i); - for (i = 0; i < MAX_SERVERS; i++) { - if ((fd = server[i].fd) >= 0) { - memset(&server[i], 0, sizeof(struct mmo_char_server)); - server[i].fd = -1; - do_close(fd); - } + if( login_fd != -1 ) + { + do_close(login_fd); + login_fd = -1; } - do_close(login_fd); ShowStatus("Finished.\n"); } @@ -1640,6 +1690,24 @@ void set_server_type(void) SERVER_TYPE = ATHENA_SERVER_LOGIN; } + +/// Called when a terminate signal is received. +void do_shutdown(void) +{ + if( runflag != LOGINSERVER_ST_SHUTDOWN ) + { + int id; + runflag = LOGINSERVER_ST_SHUTDOWN; + ShowStatus("Shutting down...\n"); + // TODO proper shutdown procedure; kick all characters, wait for acks, ... [FlavioJS] + for( id = 0; id < ARRAYLENGTH(server); ++id ) + chrif_server_reset(id); + flush_fifos(); + runflag = CORE_ST_STOP; + } +} + + //------------------------------ // Login server initialization //------------------------------ @@ -1657,9 +1725,9 @@ int do_init(int argc, char** argv) login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME); srand((unsigned int)time(NULL)); - - for( i = 0; i < MAX_SERVERS; i++ ) - server[i].fd = -1; + + for( i = 0; i < ARRAYLENGTH(server); ++i ) + chrif_server_init(i); // initialize logging if( login_config.log_login ) @@ -1713,6 +1781,12 @@ int do_init(int argc, char** argv) // server port open & binding login_fd = make_listen_bind(login_config.login_ip, login_config.login_port); + + if( runflag != CORE_ST_STOP ) + { + shutdown_callback = do_shutdown; + runflag = LOGINSERVER_ST_RUNNING; + } ShowStatus("The login-server is "CL_GREEN"ready"CL_RESET" (Server is listening on the port %u).\n\n", login_config.login_port); login_log(0, "login server", 100, "login server started"); diff --git a/src/login/login.h b/src/login/login.h index f338a09e1..07f05f18b 100644 --- a/src/login/login.h +++ b/src/login/login.h @@ -5,6 +5,14 @@ #define _LOGIN_H_ #include "../common/mmo.h" // NAME_LENGTH,SEX_* +#include "../common/core.h" // CORE_ST_LAST + +enum E_LOGINSERVER_ST +{ + LOGINSERVER_ST_RUNNING = CORE_ST_LAST, + LOGINSERVER_ST_SHUTDOWN, + LOGINSERVER_ST_LAST +}; #define LOGIN_CONF_NAME "conf/login_athena.conf" #define LAN_CONF_NAME "conf/subnet_athena.conf" diff --git a/src/login/sql/CMakeLists.txt b/src/login/sql/CMakeLists.txt new file mode 100644 index 000000000..ac7d464c9 --- /dev/null +++ b/src/login/sql/CMakeLists.txt @@ -0,0 +1,43 @@ + +# +# login sql +# +if( HAVE_common_sql ) +message( STATUS "Creating target login-server_sql" ) +set( SQL_LOGIN_HEADERS + "${LOGIN_SOURCE_DIR}/account.h" + "${LOGIN_SOURCE_DIR}/ipban.h" + "${LOGIN_SOURCE_DIR}/login.h" + "${LOGIN_SOURCE_DIR}/loginlog.h" + ) +set( SQL_LOGIN_SOURCES + "${LOGIN_SOURCE_DIR}/account_sql.c" + "${LOGIN_SOURCE_DIR}/ipban_sql.c" + "${LOGIN_SOURCE_DIR}/login.c" + "${LOGIN_SOURCE_DIR}/loginlog_sql.c" + ) +set( DEPENDENCIES common_sql ) +set( LIBRARIES ${GLOBAL_LIBRARIES} ) +set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ) +set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_SQL ) +set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} ) +source_group( common FILES ${COMMON_BASE_HEADERS} ${COMMON_SQL_HEADERS} ) +source_group( login FILES ${SQL_LOGIN_HEADERS} ${SQL_LOGIN_SOURCES} ) +include_directories( ${INCLUDE_DIRS} ) +add_executable( login-server_sql ${SOURCE_FILES} ) +add_dependencies( login-server_sql ${DEPENDENCIES} ) +target_link_libraries( login-server_sql ${LIBRARIES} ${DEPENDENCIES} ) +set_target_properties( login-server_sql PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" ) +if( WITH_COMPONENT_RUNTIME ) + cpack_add_component( Runtime_loginserver_sql DESCRIPTION "login-server (sql version)" DISPLAY_NAME "login-server_sql" GROUP Runtime ) + install( TARGETS login-server_sql + DESTINATION "." + COMPONENT Runtime_loginserver_sql ) +endif() +message( STATUS "Creating target login-server_sql - done" ) +set( HAVE_login-server_sql ON CACHE BOOL "login-server_sql target is available" ) +mark_as_advanced( HAVE_login-server_sql ) +else() +message( STATUS "Skipping target login-server_sql (requires common_sql)" ) +unset( HAVE_login-server_sql CACHE ) +endif() diff --git a/src/login/txt/CMakeLists.txt b/src/login/txt/CMakeLists.txt new file mode 100644 index 000000000..9d57103e9 --- /dev/null +++ b/src/login/txt/CMakeLists.txt @@ -0,0 +1,43 @@ + +# +# login txt +# +if( HAVE_common_base ) +message( STATUS "Creating target login-server" ) +set( TXT_LOGIN_HEADERS + "${LOGIN_SOURCE_DIR}/account.h" + "${LOGIN_SOURCE_DIR}/ipban.h" + "${LOGIN_SOURCE_DIR}/login.h" + "${LOGIN_SOURCE_DIR}/loginlog.h" + ) +set( TXT_LOGIN_SOURCES + "${LOGIN_SOURCE_DIR}/account_txt.c" + "${LOGIN_SOURCE_DIR}/ipban_txt.c" + "${LOGIN_SOURCE_DIR}/login.c" + "${LOGIN_SOURCE_DIR}/loginlog_txt.c" + ) +set( DEPENDENCIES common_base ) +set( LIBRARIES ${GLOBAL_LIBRARIES} ) +set( INCLUDE_DIRS ${GLOBAL_INCLUDE_DIRS} ) +set( DEFINITIONS ${GLOBAL_DEFINITIONS} WITH_TXT ) +set( SOURCE_FILES ${COMMON_BASE_HEADERS} ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} ) +source_group( common FILES ${COMMON_BASE_HEADERS} ) +source_group( login FILES ${TXT_LOGIN_HEADERS} ${TXT_LOGIN_SOURCES} ) +include_directories( ${INCLUDE_DIRS} ) +add_executable( login-server ${SOURCE_FILES} ) +add_dependencies( login-server ${DEPENDENCIES} ) +target_link_libraries( login-server ${LIBRARIES} ${DEPENDENCIES} ) +set_target_properties( login-server PROPERTIES COMPILE_DEFINITIONS "${DEFINITIONS}" ) +if( WITH_COMPONENT_RUNTIME ) + cpack_add_component( Runtime_loginserver_txt DESCRIPTION "login-server (txt version)" DISPLAY_NAME "login-server" GROUP Runtime ) + install( TARGETS login-server + DESTINATION "." + COMPONENT Runtime_loginserver_txt ) +endif() +message( STATUS "Creating target login-server - done" ) +set( HAVE_login-server ON CACHE BOOL "login-server target is available" ) +mark_as_advanced( HAVE_login-server ) +else() +message( STATUS "Skipping target login-server (requires common_base)" ) +unset( HAVE_login-server CACHE ) +endif() |