diff options
Diffstat (limited to 'src/map/chrif.c')
-rw-r--r-- | src/map/chrif.c | 114 |
1 files changed, 74 insertions, 40 deletions
diff --git a/src/map/chrif.c b/src/map/chrif.c index c4eeea3d9..a14200a36 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_t 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); @@ -244,9 +268,8 @@ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); - if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out. - pc_makesavestatus(sd); - + pc_makesavestatus(sd); + if (flag && sd->state.active) //Store player data which is quitting. { //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] @@ -363,6 +386,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 +496,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 +512,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 +624,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 ) @@ -661,7 +694,7 @@ int auth_db_cleanup_sub(DBKey key,void *data,va_list ap) return 0; } -int auth_db_cleanup(int tid, unsigned int tick, int id, intptr data) +int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) { if(!chrif_isconnected()) return 0; auth_db->foreach(auth_db, auth_db_cleanup_sub); @@ -838,7 +871,7 @@ int chrif_changedsex(int fd) if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) { // remove specifical skills of Bard classes for(i = 315; i <= 322; i++) { - if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { + if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) { sd->status.skill_point += sd->status.skill[i].lv; sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; @@ -846,7 +879,7 @@ int chrif_changedsex(int fd) } // remove specifical skills of Dancer classes for(i = 323; i <= 330; i++) { - if (sd->status.skill[i].id > 0 && !sd->status.skill[i].flag) { + if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) { sd->status.skill_point += sd->status.skill[i].lv; sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; @@ -1292,22 +1325,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 +1385,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 +1425,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; @@ -1423,7 +1455,7 @@ int chrif_parse(int fd) return 0; } -int ping_char_server(int tid, unsigned int tick, int id, intptr data) +int ping_char_server(int tid, unsigned int tick, int id, intptr_t data) { chrif_check(-1); chrif_keepalive(char_fd); @@ -1431,7 +1463,7 @@ int ping_char_server(int tid, unsigned int tick, int id, intptr data) } // unused -int send_usercount_tochar(int tid, unsigned int tick, int id, intptr data) +int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) { chrif_check(-1); @@ -1476,7 +1508,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_t data) { static int displayed = 0; if (char_fd <= 0 || session[char_fd] == NULL) @@ -1491,7 +1523,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 +1563,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); |