From 85bdc1dc6c13036984310f39428c82968ecffba7 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 10 Jul 2006 19:41:25 +0000 Subject: - Added login-char packet 0x2737. Sets all characters offline (login-server side). - Cleaned up char server "set all offline" implementation to remove only characters from the map-server from which the packet was invoked. It will also now correctly kick/set-character offline from the map-server if they are connected. - Cleaned up the char-sql reconnect code. It no longer sets everyone to offline. - Removed setting "kick_on_disconnect", servers will no longer kick characters out when there's a disconnection. Instead, it'll use the most logical approach: Set characters into a "lost" state when there's a disconnection, on reconnect, resent the list of online-characters, do a sync, and let the difference be characters to be removed. Also, the map-server won't release character data until it's saved and the ack returns from the char-server to prevent data loss (all this data is resent on reconnect for saving anyway). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7600 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 118 +++++++++++++++++++++++++++++-------------------------- src/char/inter.c | 3 -- src/char/inter.h | 1 - 3 files changed, 63 insertions(+), 59 deletions(-) (limited to 'src/char') diff --git a/src/char/char.c b/src/char/char.c index a0d34e14e..6c2e529f8 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -334,16 +334,36 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap) { return 0; } -void set_all_offline(void) { - online_char_db->foreach(online_char_db,char_db_setoffline,-1); - if (login_fd <= 0 || session[login_fd]->eof) - return; - WFIFOHEAD(login_fd, 6); - WFIFOW(login_fd,0) = 0x272c; - WFIFOL(login_fd,2) = 99; - WFIFOSET(login_fd,6); +static int char_db_kickoffline(DBKey key, void* data, va_list ap) { + struct online_char_data* character = (struct online_char_data*)data; + int server = va_arg(ap, int); - //printf ("set all offline\n"); + if (server > -1 && character->server != server) + return 0; + + //Kick out any connected characters, and set them offline as appropiate. + if (character->server > -1) + mapif_disconnectplayer(server_fd[character->server], + character->account_id, character->char_id, 1); + else if (!character->waiting_disconnect) + set_char_offline(character->char_id, character->account_id); + else return 0; + return 1; +} + +void set_all_offline(int id) { + if (id < 0) + ShowNotice("Sending all users offline.\n"); + else + ShowNotice("Sending users of map-server %d offline.\n", id); + online_char_db->foreach(online_char_db,char_db_kickoffline,id); + + if (id >= 0 || login_fd <= 0 || session[login_fd]->eof) + return; + //Tell login-server to also mark all our characters as offline. + WFIFOHEAD(login_fd, 2); + WFIFOW(login_fd,0) = 0x2737; + WFIFOSET(login_fd,2); } /*--------------------------------------------------- @@ -1284,11 +1304,6 @@ static int create_online_files_sub(DBKey key, void* data, va_list va) j = character->server; if (server_fd[j] < 0) { server[j].users = 0; - if (kick_on_disconnect) - { - character->char_id = -1; - character->server = -1; - } return -1; } // search position of character in char_dat and sort online characters. @@ -1864,13 +1879,8 @@ int parse_tologin(int fd) { exit(1); } else { ShowStatus("Connected to login-server (connection #%d).\n", fd); -// Don't set them offline as there's no packet to tell the map server -// to kick everyone out. Also, a disconnection from the login server is -// NOT something serious to the data integrity as a char-map disconnect -// is. [Skotlex] -// if (kick_on_disconnect) -// set_all_offline(); -// However, on reconnect, DO send our connected accounts to login. + + //Send to login accounts currently connected. send_accounts_tologin(-1, gettick(), 0, 0); // if no map-server already connected, display a message... @@ -2621,8 +2631,7 @@ int parse_frommap(int fd) { ShowStatus("Map-server %d loading complete.\n", id); char_log("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d. Map-server %d loading complete." RETCODE, id, j, p[0], p[1], p[2], p[3], server[id].port, id); - if (kick_on_disconnect) - set_all_offline(); + if (max_account_id != DEFAULT_MAX_ACCOUNT_ID || max_char_id != DEFAULT_MAX_CHAR_ID) mapif_send_maxid(max_account_id, max_char_id); //Send the current max ids to the server to keep in sync [Skotlex] } @@ -3078,8 +3087,7 @@ int parse_frommap(int fd) { // Reset all chars to offline [Wizputer] case 0x2b18: - ShowNotice("Map server [%d] requested to set all characters offline.\n", id); - set_all_offline(); + set_all_offline(id); RFIFOSKIP(fd,2); break; @@ -3881,40 +3889,39 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, int data) { WFIFOL(login_fd,4) = users; online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i); WFIFOW(login_fd,2) = 8+ i*4; - if (i > 0) - WFIFOSET(login_fd,WFIFOW(login_fd,2)); + WFIFOSET(login_fd,WFIFOW(login_fd,2)); } return 0; } int check_connect_login_server(int tid, unsigned int tick, int id, int data) { - if (login_fd <= 0 || session[login_fd] == NULL) { - ShowInfo("Attempt to connect to login-server...\n"); - login_fd = make_connection(login_ip, login_port); - if (login_fd == -1) - { //Try again later... [Skotlex] - login_fd = 0; - return 0; - } - session[login_fd]->func_parse = parse_tologin; - realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); - WFIFOHEAD(login_fd, 86); - WFIFOW(login_fd,0) = 0x2710; - memcpy(WFIFOP(login_fd,2), userid, 24); - memcpy(WFIFOP(login_fd,26), passwd, 24); - WFIFOL(login_fd,50) = 0; - WFIFOL(login_fd,54) = char_ip; - WFIFOL(login_fd,58) = char_port; - memset(WFIFOP(login_fd,60), 0, 20); - memcpy(WFIFOP(login_fd,60), server_name, strlen(server_name) < 20 ? strlen(server_name) : 20); - WFIFOW(login_fd,80) = 0; - WFIFOW(login_fd,82) = char_maintenance; - - WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] - - WFIFOSET(login_fd,86); + if (login_fd > 0 && session[login_fd] != NULL) + return 0; + + ShowInfo("Attempt to connect to login-server...\n"); + login_fd = make_connection(login_ip, login_port); + if (login_fd == -1) + { //Try again later... [Skotlex] + login_fd = 0; + return 0; } - return 0; + session[login_fd]->func_parse = parse_tologin; + realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); + WFIFOHEAD(login_fd, 86); + WFIFOW(login_fd,0) = 0x2710; + memcpy(WFIFOP(login_fd,2), userid, 24); + memcpy(WFIFOP(login_fd,26), passwd, 24); + WFIFOL(login_fd,50) = 0; + WFIFOL(login_fd,54) = char_ip; + WFIFOL(login_fd,58) = char_port; + memcpy(WFIFOP(login_fd,60), server_name, 20); + WFIFOW(login_fd,80) = 0; + WFIFOW(login_fd,82) = char_maintenance; + + WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] + + WFIFOSET(login_fd,86); + return 1; } //------------------------------------------------ @@ -4031,7 +4038,7 @@ int char_config_read(const char *cfgName) { } else if (strcmpi(w1, "passwd") == 0) { strncpy(passwd, w2, 24); } else if (strcmpi(w1, "server_name") == 0) { - memcpy(server_name, w2, sizeof(server_name)); + strncpy(server_name, w2, 20); server_name[sizeof(server_name) - 1] = '\0'; ShowStatus("%s server has been initialized\n", w2); } else if (strcmpi(w1, "wisp_server_name") == 0) { @@ -4205,7 +4212,8 @@ void do_final(void) { mmo_char_sync(); inter_save(); - set_all_offline(); + set_all_offline(-1); + flush_fifos(); if(gm_account) aFree(gm_account); if(char_dat) aFree(char_dat); diff --git a/src/char/inter.c b/src/char/inter.c index 80d9f653a..414250ae6 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -37,7 +37,6 @@ struct accreg { }; unsigned int party_share_level = 10; -int kick_on_disconnect = 1; // 送信パケット長リスト int inter_send_packet_length[] = { @@ -206,8 +205,6 @@ int inter_config_read(const char *cfgName) { strncpy(accreg_txt, w2, sizeof(accreg_txt)); } else if (strcmpi(w1, "guild_storage_txt") == 0) { strncpy(guild_storage_txt, w2, sizeof(guild_storage_txt)); - } else if (strcmpi(w1, "kick_on_disconnect") == 0) { - kick_on_disconnect = atoi(w2); } else if (strcmpi(w1, "party_share_level") == 0) { party_share_level = (unsigned int)atof(w2); } else if (strcmpi(w1, "inter_log_filename") == 0) { diff --git a/src/char/inter.h b/src/char/inter.h index b95d041dd..7f9ed0a64 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -19,7 +19,6 @@ int inter_log(char *fmt,...); #define inter_cfgName "conf/inter_athena.conf" extern unsigned int party_share_level; -extern int kick_on_disconnect; extern char inter_log_filename[1024]; extern int log_inter; -- cgit v1.2.3-60-g2f50