diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 16 | ||||
-rw-r--r-- | src/map/chrif.c | 99 | ||||
-rw-r--r-- | src/map/chrif.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 16 | ||||
-rw-r--r-- | src/map/clif.h | 2 | ||||
-rw-r--r-- | src/map/map.c | 29 | ||||
-rw-r--r-- | src/map/map.h | 10 |
7 files changed, 119 insertions, 55 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index e58f07880..04cc872b7 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3903,23 +3903,9 @@ ACMD_FUNC(agitend2) *------------------------------------------*/ ACMD_FUNC(mapexit) { - struct map_session_data* pl_sd; - struct s_mapiterator* iter; - nullpo_retr(-1, sd); - iter = mapit_getallusers(); - for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) - if (sd->status.account_id != pl_sd->status.account_id) - clif_GM_kick(NULL, pl_sd); - mapit_free(iter); - - clif_GM_kick(NULL, sd); - - flush_fifos(); - - runflag = 0; - + do_shutdown(); return 0; } diff --git a/src/map/chrif.c b/src/map/chrif.c index c4eeea3d9..8edeb9efb 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -31,6 +31,8 @@ #include <sys/types.h> #include <time.h> +static int check_connect_char_server(int tid, unsigned int tick, int id, intptr data); + static struct eri *auth_db_ers; //For reutilizing player login structures. static DBMap* auth_db; // int id -> struct auth_node* @@ -94,7 +96,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free //2b27: Incoming, chrif_authfail -> 'client authentication failed' int chrif_connected = 0; -int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex] +int char_fd = -1; int srvinfo; static char char_ip_str[128]; static uint32 char_ip = 0; @@ -110,6 +112,28 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl //This define should spare writing the check in every function. [Skotlex] #define chrif_check(a) { if(!chrif_isconnected()) return a; } + +/// Resets all the data. +void chrif_reset(void) +{ + // TODO kick everyone out and reset everything [FlavioJS] + 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 chrif_check_shutdown(void) +{ + if( runflag != MAPSERVER_ST_SHUTDOWN ) + return; + if( auth_db->size(auth_db) > 0 ) + return; + runflag = CORE_ST_STOP; +} + + struct auth_node* chrif_search(int account_id) { return (struct auth_node*)idb_get(auth_db, account_id); @@ -363,6 +387,7 @@ int chrif_removemap(int fd) static void chrif_save_ack(int fd) { chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT); + chrif_check_shutdown(); } // request to move a character between mapservers @@ -472,19 +497,13 @@ static int chrif_reconnect(DBKey key,void *data,va_list ap) return 0; } -/*========================================== - * - *------------------------------------------*/ -int chrif_sendmapack(int fd) -{ - if (RFIFOB(fd,2)) { - ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2)); - exit(EXIT_FAILURE); - } - memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH); - ShowStatus("Map sending complete. Map Server is now online.\n"); +/// Called when all the connection steps are completed. +void chrif_on_ready(void) +{ + ShowStatus("Map Server is now online.\n"); chrif_state = 2; + chrif_check_shutdown(); //If there are players online, send them to the char-server. [Skotlex] send_users_tochar(); @@ -494,7 +513,21 @@ int chrif_sendmapack(int fd) //Re-save any storages that were modified in the disconnection time. [Skotlex] do_reconnect_storage(); +} + + +/*========================================== + * + *------------------------------------------*/ +int chrif_sendmapack(int fd) +{ + if (RFIFOB(fd,2)) { + ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2)); + exit(EXIT_FAILURE); + } + memcpy(wisp_server_name, RFIFOP(fd,3), NAME_LENGTH); + chrif_on_ready(); return 0; } @@ -592,7 +625,8 @@ void chrif_authok(int fd) } sd = node->sd; - if(node->char_dat == NULL && + if( runflag == MAPSERVER_ST_RUNNING && + node->char_dat == NULL && node->account_id == account_id && node->char_id == char_id && node->login_id1 == login_id1 ) @@ -1292,22 +1326,22 @@ int chrif_char_online(struct map_session_data *sd) return 0; } -int chrif_disconnect(int fd) + +/// Called when the connection to Char Server is disconnected. +void chrif_on_disconnect(void) { - if(fd == char_fd) { - char_fd = 0; - ShowWarning("Map Server disconnected from Char Server.\n\n"); - chrif_connected = 0; - - other_mapserver_count=0; //Reset counter. We receive ALL maps from all map-servers on reconnect. - map_eraseallipport(); + if( chrif_connected != 1 ) + ShowWarning("Connection to Char Server lost.\n\n"); + chrif_connected = 0; + + other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect. + map_eraseallipport(); - //Attempt to reconnect in a second. [Skotlex] - add_timer(gettick() + 1000, check_connect_char_server, 0, 0); - } - return 0; + //Attempt to reconnect in a second. [Skotlex] + add_timer(gettick() + 1000, check_connect_char_server, 0, 0); } + void chrif_update_ip(int fd) { uint32 new_ip; @@ -1352,10 +1386,9 @@ int chrif_parse(int fd) if (session[fd]->flag.eof) { - if (chrif_connected == 1) - chrif_disconnect(fd); - do_close(fd); + char_fd = -1; + chrif_on_disconnect(); return 0; } @@ -1393,7 +1426,7 @@ int chrif_parse(int fd) case 0x2afb: chrif_sendmapack(fd); break; case 0x2afd: chrif_authok(fd); break; case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break; - case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break; + case 0x2b03: clif_charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break; case 0x2b04: chrif_recvmap(fd); break; case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break; case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break; @@ -1476,7 +1509,7 @@ int send_users_tochar(void) * timer関数 * char鯖との接続を確認し、もし切れていたら再度接続する *------------------------------------------*/ -int check_connect_char_server(int tid, unsigned int tick, int id, intptr data) +static int check_connect_char_server(int tid, unsigned int tick, int id, intptr data) { static int displayed = 0; if (char_fd <= 0 || session[char_fd] == NULL) @@ -1491,7 +1524,6 @@ int check_connect_char_server(int tid, unsigned int tick, int id, intptr data) char_fd = make_connection(char_ip, char_port); if (char_fd == -1) { //Attempt to connect later. [Skotlex] - char_fd = 0; return 0; } @@ -1532,8 +1564,11 @@ int auth_db_final(DBKey k,void *d,va_list ap) *------------------------------------------*/ int do_final_chrif(void) { - if (char_fd > 0) + if( char_fd != -1 ) + { do_close(char_fd); + char_fd = -1; + } auth_db->destroy(auth_db, auth_db_final); ers_destroy(auth_db_ers); diff --git a/src/map/chrif.h b/src/map/chrif.h index 9ff5b9a0e..1f11cc6f2 100644 --- a/src/map/chrif.h +++ b/src/map/chrif.h @@ -25,6 +25,7 @@ int chrif_setip(const char* ip); void chrif_setport(uint16 port); int chrif_isconnected(void); +void chrif_check_shutdown(void); extern int chrif_connected; extern int other_mapserver_count; @@ -55,7 +56,6 @@ int send_users_tochar(void); int chrif_char_online(struct map_session_data *sd); int chrif_changesex(struct map_session_data *sd); int chrif_chardisconnect(struct map_session_data *sd); -int check_connect_char_server(int tid, unsigned int tick, int id, intptr data); int chrif_divorce(int partner_id1, int partner_id2); int do_final_chrif(void); diff --git a/src/map/clif.c b/src/map/clif.c index bffb708d5..ac8382a63 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -581,10 +581,10 @@ int clif_authfail_fd(int fd, int type) return 0; } -/*========================================== - * - *------------------------------------------*/ -int clif_charselectok(int id) +/// Reply from char-server. +/// Tells the player if it can connect to the char-server to select a character. +/// ok=1 : client disconnects and tries to connect to the char-server +int clif_charselectok(int id, uint8 ok) { struct map_session_data* sd; int fd; @@ -595,7 +595,7 @@ int clif_charselectok(int id) fd = sd->fd; WFIFOHEAD(fd,packet_len(0xb3)); WFIFOW(fd,0) = 0xb3; - WFIFOB(fd,2) = 1; + WFIFOB(fd,2) = ok; WFIFOSET(fd,packet_len(0xb3)); return 0; @@ -8392,6 +8392,12 @@ void clif_parse_WantToConnection(int fd, TBL_PC* sd) return; } + if( runflag != MAPSERVER_ST_RUNNING ) + {// not allowed + clif_authfail_fd(fd,1);// server closed + return; + } + //Check for double login. bl = map_id2bl(account_id); if(bl && bl->type != BL_PC) { diff --git a/src/map/clif.h b/src/map/clif.h index 1d50461a6..0feeb22b5 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -220,7 +220,7 @@ uint16 clif_getport(void); int clif_authok(struct map_session_data *); int clif_authfail_fd(int fd,int type); -int clif_charselectok(int); +int clif_charselectok(int id, uint8 ok); int clif_dropflooritem(struct flooritem_data *); int clif_clearflooritem(struct flooritem_data *,int); diff --git a/src/map/map.c b/src/map/map.c index c086b73c0..8209c1033 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3491,7 +3491,7 @@ void do_final(void) #ifndef TXT_ONLY map_sql_close(); #endif /* not TXT_ONLY */ - ShowStatus("Successfully terminated.\n"); + ShowStatus("Finished.\n"); } static int map_abort_sub(struct map_session_data* sd, va_list ap) @@ -3573,6 +3573,27 @@ void set_server_type(void) SERVER_TYPE = ATHENA_SERVER_MAP; } + +/// Called when a terminate signal is received. +void do_shutdown(void) +{ + if( runflag != MAPSERVER_ST_SHUTDOWN ) + { + runflag = MAPSERVER_ST_SHUTDOWN; + ShowStatus("Shutting down...\n"); + { + struct map_session_data* sd; + struct s_mapiterator* iter = mapit_getallusers(); + for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) + clif_GM_kick(NULL, sd); + mapit_free(iter); + flush_fifos(); + } + chrif_check_shutdown(); + } +} + + int do_init(int argc, char *argv[]) { int i; @@ -3710,6 +3731,12 @@ int do_init(int argc, char *argv[]) ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port); + + if( runflag != CORE_ST_STOP ) + { + shutdown_callback = do_shutdown; + runflag = MAPSERVER_ST_RUNNING; + } return 0; } diff --git a/src/map/map.h b/src/map/map.h index f1e7e49b3..06514f5d2 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -7,6 +7,7 @@ #ifndef _CBASETYPES_H_ #include "../common/cbasetypes.h" #endif +#include "../common/core.h" // CORE_ST_LAST #include "../common/mmo.h" #include "../common/mapindex.h" #include "../common/db.h" @@ -16,6 +17,13 @@ struct npc_data; struct item_data; +enum E_MAPSERVER_ST +{ + MAPSERVER_ST_RUNNING = CORE_ST_LAST, + MAPSERVER_ST_SHUTDOWN, + MAPSERVER_ST_LAST +}; + //Uncomment to enable the Cell Stack Limit mod. //It's only config is the battle_config cell_stack_limit. //Only chars affected are those defined in BL_CHAR (mobs and players currently) @@ -695,4 +703,6 @@ extern char mob_db2_db[32]; #endif /* not TXT_ONLY */ +void do_shutdown(void); + #endif /* _MAP_H_ */ |