浏览代码

Bug fixes for Auth Glitch and Map server crash through script warp when changing map servers.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12473 54d463be-8e91-2dee-dedb-b68131a5f0ec
Kevin 17 年之前
父节点
当前提交
e45a10cf13
共有 4 个文件被更改,包括 28 次插入8 次删除
  1. 9 0
      Changelog-Trunk.txt
  2. 14 5
      src/char_sql/char.c
  3. 4 0
      src/map/chrif.c
  4. 1 3
      src/map/pc.c

+ 9 - 0
Changelog-Trunk.txt

@@ -3,6 +3,15 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2008/04/04
+	* Bug fixes for Auth Glitch and Map server crash through script warp when
+	- changing map servers.
+	* When char receives the request to go back to char selection it sets
+	- the character as "at char select" in the online_char_db, and
+	- set_char_offline now deletes the entry in the online_char_db unless
+	- the user is at the character screen (to prevent unecessary callocs/frees.
+	* Script warp was just a simple misplacement of a free statement, freeing the
+	- users session data before the scripting subsystem was finished with it. [Kevin]
 2008/04/03
 	* More login server work
 	- Renamed 'connect_until_time' to 'expiration_time'

+ 14 - 5
src/char_sql/char.c

@@ -233,7 +233,7 @@ void set_char_online(int map_id, int char_id, int account_id)
 	}
 
 	character = (struct online_char_data*)idb_ensure(online_char_db, account_id, create_online_char_data);
-	if (online_check && character->char_id != -1 && character->server > -1 && character->server != map_id)
+	if (online_check && character->char_id != -1 && character->server > -1 && character->server != map_id && map_id != -3)
 	{
 		//char == 99 <- Character logging in, so someone has logged in while one
 		//char is still on map-server, so kick him out, but don't print "error"
@@ -294,13 +294,17 @@ void set_char_offline(int char_id, int account_id)
 	{	//We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex]
 		if( character->server > -1 )
 			server[character->server].users--;
-		
-		character->char_id = -1;
-		character->server = -1;
+
 		if(character->waiting_disconnect != -1){
 			delete_timer(character->waiting_disconnect, chardb_waiting_disconnect);
 			character->waiting_disconnect = -1;
 		}
+
+		//If user is NOT at char screen, delete entry [Kevin]
+		if(character->char_id != -1)
+		{
+			idb_remove(online_char_db, account_id);
+		}
 	}
 	
 	if (login_fd > 0 && !session[login_fd]->flag.eof)
@@ -2394,6 +2398,10 @@ int parse_frommap(int fd)
 			auth_fifo[auth_fifo_pos].expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
 			auth_fifo[auth_fifo_pos].ip = ntohl(RFIFOL(fd,14));
 			auth_fifo_pos++;
+
+			//Set char to "@ char select" in online db [Kevin]
+			set_char_online(-3, 99, RFIFOL(fd,2));
+
 			WFIFOHEAD(fd,7);
 			WFIFOW(fd,0) = 0x2b03;
 			WFIFOL(fd,2) = RFIFOL(fd,2);
@@ -2827,7 +2835,8 @@ int parse_char(int fd)
 		{	// already authed client
 			struct online_char_data* data = (struct online_char_data*)idb_get(online_char_db, sd->account_id);
 			if( data == NULL || data->server == -1) //If it is not in any server, send it offline. [Skotlex]
-				set_char_offline(99,sd->account_id);
+													//send -1 as char id (99 means at char select) [Kevin]
+				set_char_offline(-1,sd->account_id);
 			if( data != NULL && data->fd == fd)
 				data->fd = -1;
 		}

+ 4 - 0
src/map/chrif.c

@@ -400,8 +400,12 @@ int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int c
 	} else
 		clif_changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
 
+	//Free session data from this map server [Kevin]
+	unit_free_pc(sd);
+
 	//Player has been saved already, remove him from memory. [Skotlex]
 	chrif_auth_delete(account_id, char_id, ST_MAPCHANGE);
+
 	return 0;
 }
 

+ 1 - 3
src/map/pc.c

@@ -3594,9 +3594,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
 		pc_clean_skilltree(sd);
 		chrif_save(sd,2);
 		chrif_changemapserver(sd, ip, (short)port);
-		//It is important to invoke remove_map separately from unit_free before
-		//saving so that the data saved corresponds to that AFTER warping.
-		unit_free_pc(sd);
+
 		return 0;
 	}