소스 검색

- 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://svn.code.sf.net/p/rathena/svn/trunk@7600 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 19 년 전
부모
커밋
924284f1b9
14개의 변경된 파일176개의 추가작업 그리고 238개의 파일을 삭제
  1. 16 0
      Changelog-Trunk.txt
  2. 0 6
      conf-tmpl/inter_athena.conf
  3. 63 55
      src/char/char.c
  4. 0 3
      src/char/inter.c
  5. 0 1
      src/char/inter.h
  6. 76 136
      src/char_sql/char.c
  7. 0 4
      src/char_sql/inter.c
  8. 0 1
      src/char_sql/inter.h
  9. 6 1
      src/login/login.c
  10. 7 0
      src/login_sql/login.c
  11. 3 23
      src/map/chrif.c
  12. 4 3
      src/map/clif.c
  13. 1 4
      src/map/map.c
  14. 0 1
      src/map/map.h

+ 16 - 0
Changelog-Trunk.txt

@@ -4,6 +4,22 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/07/10
+	* Added login-char packet 0x2737. Sets all characters offline (login-server
+	  side). [Skotlex]
+	* 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. [Skotlex]
+	* Cleaned up the char-sql reconnect code. It no longer sets everyone to
+	  offline. [Skotlex]
+	* 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). [Skotlex]
 	* Added a check in pc_equipitem so that when switching weapons and you have
 	  the skill_range_by_weapon setting active, the skill info block (which
 	  includes range) will be resent when the new weapon to equip has a range

+ 0 - 6
conf-tmpl/inter_athena.conf

@@ -31,12 +31,6 @@ inter_log_filename: log/inter.log
 // Level range for sharing within a party
 party_share_level: 10
 
-// Disconnect players when the map server loses the connection to the char server?
-// NOTE: The default is 1 (yes) to prevent any kinds of exploits, but large servers experience connection loss
-// during high load times, in which case it might be desirable to set this to '0'.
-// NOTE: Don't use 'yes/no' here, use 1 (yes)/ 0 (no).
-kick_on_disconnect: 1
-
 // SQL version options only
 
 // Char-Save method

+ 63 - 55
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);

+ 0 - 3
src/char/inter.c

@@ -37,7 +37,6 @@ struct accreg {
 };
 
 unsigned int party_share_level = 10;
-int kick_on_disconnect = 1;
 
 // ‘—�MƒpƒPƒbƒg’·ƒŠƒXƒg
 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) {

+ 0 - 1
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;
 

+ 76 - 136
src/char_sql/char.c

@@ -290,38 +290,55 @@ static int char_db_setoffline(DBKey key, void* data, va_list ap) {
 	return 0;
 }
 
-void set_all_offline(void) {
-	MYSQL_RES*       sql_res2; //Needed because it is used inside inter_guild_CharOffline; [Skotlex]
-	int char_id;
-	sprintf(tmp_sql, "SELECT `account_id`, `char_id`, `guild_id` FROM `%s` WHERE `online`='1'",char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
+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);
+	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);
+}
+
+void set_all_offline_sql(void) {
+	//Set all players to 'OFFLINE'
+	sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", char_db);
+	if(mysql_query(&mysql_handle, tmp_sql)){
 		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
 	}
-	ShowNotice("Sending all users offline.\n");
-	sql_res2 = mysql_store_result(&mysql_handle);
-	if (sql_res2) {
-		while((sql_row = mysql_fetch_row(sql_res2))) {
-			char_id = atoi(sql_row[1]);
-			inter_guild_CharOffline(char_id, atoi(sql_row[2]));
-
-			if ( login_fd > 0 ) {
-				ShowInfo("send user offline: %d\n",char_id);
-				WFIFOW(login_fd,0) = 0x272c;
-				WFIFOL(login_fd,2) = char_id;
-				WFIFOSET(login_fd,6);
-			}
-		}
-		mysql_free_result(sql_res2);
-	}
-
-	sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
+	sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", guild_member_db);
+	if(mysql_query(&mysql_handle, tmp_sql)){
 		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
 	}
-	online_char_db->foreach(online_char_db,char_db_setoffline,-1);
+	sprintf(tmp_sql, "UPDATE `%s` SET `connect_member` = '0'", guild_db);
+	if(mysql_query(&mysql_handle, tmp_sql)){
+		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
+		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
 }
+
 //----------------------------------------------------------------------
 // Determine if an account (id) is a GM account
 // and returns its level (or 0 if it isn't a GM account or if not found)
@@ -1812,13 +1829,8 @@ int parse_tologin(int fd) {
 				//exit(1); //fixed for server shutdown.
 			}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 online accounts to login server.
 				send_accounts_tologin(-1, gettick(), 0, 0);
 			
 				// if no map-server already connected, display a message...
@@ -2453,8 +2465,7 @@ int parse_frommap(int fd) {
 				ShowStatus("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
 				       id, j, p[0], p[1], p[2], p[3], server[id].port);
 				ShowStatus("Map-server %d loading complete.\n", 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]
 			}
@@ -2951,8 +2962,7 @@ int parse_frommap(int fd) {
 			break;
 		// 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;
 		// Character set online [Wizputer]
@@ -3751,112 +3761,41 @@ 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, users);
 		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) {
-		struct char_session_data *sd;
-		int i, cc;
-		unsigned char buf[16];
-
-		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);
-		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 (!kick_on_disconnect)
-			return 0; //Do not perform on-connect cleanup duties.
-
-		//(re)connected to login-server,
-		//now wi'll look in sql which player's are ON and set them OFF
-		//AND send to all mapservers (if we have one / ..) to kick the players
-		//so the bug is fixed, if'ure using more than one charservers (worlds)
-		//that the player'S got reejected from server after a 'world' crash^^
-		//2b1f AID.L B1
-
-		sprintf(tmp_sql, "SELECT `account_id`, `online` FROM `%s` WHERE `online` = '1'", char_db);
-		if(mysql_query(&mysql_handle, tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			return -1;
-		}
-
-		sql_res = mysql_store_result(&mysql_handle);
-		if(sql_res){
-			cc = (int)mysql_num_rows(sql_res);
-			ShowStatus("Setting %d Players offline\n", cc);
-			while((sql_row = mysql_fetch_row(sql_res))){
-				//sql_row[0] == AID
-				//tell the loginserver
-				WFIFOW(login_fd, 0) = 0x272c; //set off
-				WFIFOL(login_fd, 2) = atoi(sql_row[0]); //AID
-				WFIFOSET(login_fd, 6);
-
-				//tell map to 'kick' the player (incase of 'on' ..)
-				WBUFW(buf, 0) = 0x2b1f;
-				WBUFL(buf, 2) = atoi(sql_row[0]);
-				WBUFB(buf, 6) = 1;
-				mapif_sendall(buf, 7);
-
-				//kick the player if he's on charselect
-				for(i = 0; i < fd_max; i++){
-					if(session[i] && (sd = (struct char_session_data*)session[i]->session_data)){
-						if(sd->account_id == atoi(sql_row[0])){
-							session[i]->eof = 1;
-							break;
-						}
-					}
-				}
-
-			}
-			mysql_free_result(sql_res);
-		}else{
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-			return -1;
-		}
+	struct char_session_data *sd;
+	int i, cc;
+	unsigned char buf[16];
 
-		//Now Update all players to 'OFFLINE'
-		sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", char_db);
-		if(mysql_query(&mysql_handle, tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-		sprintf(tmp_sql, "UPDATE `%s` SET `online` = '0'", guild_member_db);
-		if(mysql_query(&mysql_handle, tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
-		sprintf(tmp_sql, "UPDATE `%s` SET `connect_member` = '0'", guild_db);
-		if(mysql_query(&mysql_handle, tmp_sql)){
-			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
-			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
-		}
+	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;
 	}
+	session[login_fd]->func_parse = parse_tologin;
+	realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
+	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 0;
 }
 
@@ -3951,7 +3890,8 @@ void do_final(void) {
 	//check SQL save progress.
 	//wait until save char complete
 
-	set_all_offline();
+	set_all_offline(-1);
+	set_all_offline_sql();
 
 	inter_final();
 
@@ -4107,7 +4047,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) {

+ 0 - 4
src/char_sql/inter.c

@@ -30,7 +30,6 @@ static struct accreg *accreg_pt;
 
 
 unsigned int party_share_level = 10;
-int kick_on_disconnect = 1;
 MYSQL mysql_handle;
 MYSQL_RES* 	sql_res ;
 MYSQL_ROW	sql_row ;
@@ -256,9 +255,6 @@ int inter_config_read(const char *cfgName) {
 			strcpy(login_server_db, w2);
 			ShowStatus ("set login_server_db : %s\n",w2);
 		}
-		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);
 		}

+ 0 - 1
src/char_sql/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; //For deciding whether characters are kicked or not on reconnections. [Skotlex]
 extern char inter_log_filename[1024];
 
 #ifdef __WIN32

+ 6 - 1
src/login/login.c

@@ -1952,7 +1952,6 @@ int parse_fromchar(int fd) {
 				WFIFOSET(fd,WFIFOW(fd,2));
 			}
 			break;
-
 		case 0x2736: // WAN IP update from char-server
 			if (RFIFOREST(fd) < 6)
 				return 0;
@@ -1963,6 +1962,12 @@ int parse_fromchar(int fd) {
 			RFIFOSKIP(fd,6);
 			break;
 
+		case 0x2737: //Request to set all offline.
+			ShowInfo("Setting accounts from char-server %d offline.\n", id);
+			online_db->foreach(online_db,online_db_setoffline,id);
+			RFIFOSKIP(fd,2);
+			break;
+
 		case 0x3000: //change sex for chrif_changesex()
 			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 				return 0;

+ 7 - 0
src/login_sql/login.c

@@ -1401,6 +1401,13 @@ int parse_fromchar(int fd){
 			server[id].ip = RFIFOL(fd,2);
 			RFIFOSKIP(fd,6);
 			break;
+
+		case 0x2737: //Request to set all offline.
+			ShowInfo("Setting accounts from char-server %d offline.\n", id);
+			online_db->foreach(online_db,online_db_setoffline,id);
+			RFIFOSKIP(fd,2);
+			break;
+
 		default:
 			ShowError("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
 			session[fd]->eof = 1;

+ 3 - 23
src/map/chrif.c

@@ -454,7 +454,7 @@ int chrif_scdata_request(int account_id, int char_id)
 #endif
 	chrif_check(-1);
 
-        WFIFOHEAD(char_fd, 10);
+	WFIFOHEAD(char_fd, 10);
 	WFIFOW(char_fd, 0) = 0x2afc;
 	WFIFOL(char_fd, 2) = account_id;
 	WFIFOL(char_fd, 6) = char_id;
@@ -1344,7 +1344,7 @@ int chrif_char_offline(struct map_session_data *sd)
 {
 	chrif_check(-1);
 
-        WFIFOHEAD(char_fd, 10);
+	WFIFOHEAD(char_fd, 10);
 	WFIFOW(char_fd,0) = 0x2b17;
 	WFIFOL(char_fd,2) = sd->status.char_id;
 	WFIFOL(char_fd,6) = sd->status.account_id;
@@ -1374,7 +1374,7 @@ int chrif_flush_fifo(void) {
 int chrif_char_reset_offline(void) {
 	chrif_check(-1);
 
-        WFIFOHEAD(char_fd, 2);
+	WFIFOHEAD(char_fd, 2);
 	WFIFOW(char_fd,0) = 0x2b18;
 	WFIFOSET(char_fd,2);
 
@@ -1399,35 +1399,15 @@ int chrif_char_online(struct map_session_data *sd)
 	return 0;
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
-int chrif_disconnect_sub(struct map_session_data* sd,va_list va) {
-	if (sd->fd)
-		clif_authfail_fd(sd->fd,1);
-	else
-		map_quit(sd);
-	return 0;
-}
-
 int chrif_disconnect(int fd) {
 	if(fd == char_fd) {
 		char_fd = 0;
 		ShowWarning("Map Server disconnected from Char Server.\n\n");
-		if (kick_on_disconnect)
-			clif_foreachclient(chrif_disconnect_sub);
 		chrif_connected = 0;
 		
 	 	other_mapserver_count=0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
 		map_eraseallipport();
 
-		// ‘qŒÉƒLƒƒƒbƒVƒ…‚ð�Á‚·
-		if (kick_on_disconnect)
-		{	//Do not clean the storage if players are gonna be left inside. [Skotlex]
-			do_final_storage();
-			do_init_storage();
-		}
 		//Attempt to reconnect in a second. [Skotlex]
 		add_timer(gettick() + 1000, check_connect_char_server, 0, 0);
 	}

+ 4 - 3
src/map/clif.c

@@ -11390,9 +11390,9 @@ int clif_parse(int fd) {
 	}
 
 	sd = (struct map_session_data*)session[fd]->session_data;
-
-	// 接続が切れてるので後始末
-	if (!chrif_isconnect() && kick_on_disconnect)
+/* This behaviour has been deprecated due to actually causing trouble instead
+ * of helping against exploits ~.~ [Skotlex]
+	if (!chrif_isconnect())
 	{
 		ShowInfo("Closing session #%d (Not connected to Char server)\n", fd);
 		if (sd && sd->state.auth)
@@ -11400,6 +11400,7 @@ int clif_parse(int fd) {
 		do_close(fd);
 		return 0;
 	} else
+	*/
 	if (session[fd]->eof) {
 		if (sd && sd->state.autotrade) {
 			//Disassociate character from the socket connection.

+ 1 - 4
src/map/map.c

@@ -172,7 +172,6 @@ int save_settings = 0xFFFF;
 int charsave_method = 0; //Default 'OLD' Save method (SQL ONLY!) [Sirius]
 int agit_flag = 0;
 int night_flag = 0; // 0=day, 1=night [Yor]
-int kick_on_disconnect = 1;
 
 struct charid2nick {
 	char nick[NAME_LENGTH];
@@ -3383,9 +3382,7 @@ int inter_config_read(char *cfgName)
 		i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
 		if(i!=2)
 			continue;
-		if(strcmpi(w1,"kick_on_disconnect")==0){
-			kick_on_disconnect = battle_config_switch(w2);
-		} else if(strcmpi(w1,"party_share_level")==0){
+		if(strcmpi(w1,"party_share_level")==0){
 			party_share_level = battle_config_switch(w2);
 		} else if(strcmpi(w1,"lowest_gm_level")==0){
 			lowest_gm_level = atoi(w2);

+ 0 - 1
src/map/map.h

@@ -1247,7 +1247,6 @@ extern int autosave_interval;
 extern int save_settings;
 extern int agit_flag;
 extern int night_flag; // 0=day, 1=night [Yor]
-extern int kick_on_disconnect; //To allow inter-server reconnections without kicking players out [Skotlex]
 extern int enable_spy; //Determines if @spy commands are active.
 extern char db_path[256];