Prechádzať zdrojové kódy

- Added all the missing FIFOHEADs in the login/sql servers (required for TURBO support)
- Fixed the fact that the TURBO code breaks when you attempt to handle more than one connection at a time within the same function. However this broke map-server compilation, therefore, don't use TURBO yet! It needs more fixing (and I need more time to fix it)
- While at it, cleaned a few packet implementations in the char/login servers which were not only ugly, but had some really stupid flaws within (stuff like escaping a string, and then using the non-escaped variable to insert to SQL? T_T) And will someone explain me why the TXT servers are coded much more cleanly, and without such horribly broken code as I find in the SQL ones? T_T;


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9307 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 18 rokov pred
rodič
commit
cfee0ccf63

+ 7 - 0
Changelog-Trunk.txt

@@ -3,6 +3,13 @@ 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.
 
+2006/11/24
+	* Fixed the fact that the TURBO code breaks when you attempt to handle more
+	  than one connection at a time within the same function. However this broke
+	  map-server compilation, therefore, don't use TURBO yet! [Skotlex]
+	* While at it, cleaned a few packet implementations in the char/login
+	  servers which were not only ugly, but had some really stupid flaws within.
+	  [Skotlex]
 2006/11/23
 	* Completed Reddozen's hanging mapwarp code to support party and old syntax. [Lance]
 	* Updated sql files [Playtester]

+ 1 - 0
Makefile

@@ -28,6 +28,7 @@ OPT += -Wall -Wno-sign-compare
 # Makes map-wide script variables be saved to SQL instead of TXT files.
 # OPT += -DMAPREGSQL
 # Turbo is an alternate socket access implementation which should be faster.
+# DO NOT ENABLE YET as it isn't quite ready for general usage.
 # OPT += -DTURBO
 # Enable the perl regular expression support for scripts
 # OPT += -DPCRE_SUPPORT

+ 89 - 70
src/char/char.c

@@ -1995,7 +1995,7 @@ int parse_tologin(int fd) {
 					} else {
 						// refuse connection: too much online players
 //						printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user);
-                                                WFIFOHEAD(fd, 3);
+						WFIFOHEAD(i, 3);
 						WFIFOW(i,0) = 0x6c;
 						WFIFOW(i,2) = 0;
 						WFIFOSET(i,3);
@@ -2403,7 +2403,7 @@ int parse_tologin(int fd) {
 						for(i = 0; i < fd_max; i++) {
 							if (session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid)
 							{
-								WFIFOHEAD(fd, 3);
+								WFIFOHEAD(i, 3);
 								WFIFOW(i,0) = 0x81;
 								WFIFOB(i,2) = 2;
 								WFIFOSET(i,3);
@@ -2502,7 +2502,7 @@ int char_parse_Registry(int account_id, int char_id, unsigned char *buf, int buf
 //Reply to map server with acc reg values.
 int char_account_reg_reply(int fd,int account_id,int char_id) {
 	int i,j,p;
-	WFIFOHEAD(login_fd, GLOBAL_REG_NUM*288 + 13);
+	WFIFOHEAD(fd, GLOBAL_REG_NUM*288 + 13);
 	WFIFOW(fd,0)=0x3804;
 	WFIFOL(fd,4)=account_id;
 	WFIFOL(fd,8)=char_id;
@@ -2894,6 +2894,7 @@ int parse_frommap(int fd) {
 				if (map_fd>=0 && session[map_fd] && char_data) 
 				{	//Send the map server the auth of this player.
 					//Update the "last map" as this is where the player must be spawned on the new map server.
+					WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
 					char_data->last_point.map = RFIFOW(fd,18);
 					char_data->last_point.x = RFIFOW(fd,20);
 					char_data->last_point.y = RFIFOW(fd,22);
@@ -2949,10 +2950,12 @@ int parse_frommap(int fd) {
 				return 0;
 //			printf("parse_frommap: change gm -> login, account: %d, pass: '%s'.\n", RFIFOL(fd,4), RFIFOP(fd,8));
 			if (login_fd > 0) { // don't send request if no login-server
+				WFIFOHEAD(login_fd, RFIFOW(fd,2));
 				WFIFOW(login_fd,0) = 0x2720;
 				memcpy(WFIFOP(login_fd,2), RFIFOP(fd,2), RFIFOW(fd,2)-2);
 				WFIFOSET(login_fd, RFIFOW(fd,2));
 			} else {
+				WFIFOHEAD(fd, 10);
 				WFIFOW(fd,0) = 0x2b0b;
 				WFIFOL(fd,2) = RFIFOL(fd,4);
 				WFIFOL(fd,6) = 0;
@@ -2966,6 +2969,7 @@ int parse_frommap(int fd) {
 			if (RFIFOREST(fd) < 86)
 				return 0;
 			if (login_fd > 0) { // don't send request if no login-server
+				WFIFOHEAD(login_fd, 86);
 				memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
 				WFIFOW(login_fd,0) = 0x2722;
 				WFIFOSET(login_fd, 86);
@@ -2996,6 +3000,7 @@ int parse_frommap(int fd) {
 				case 1: // block
 					if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) {
 						if (login_fd > 0) { // don't send request if no login-server
+							WFIFOHEAD(login_fd, 10);
 							WFIFOW(login_fd,0) = 0x2724;
 							WFIFOL(login_fd,2) = char_dat[i].status.account_id; // account value
 							WFIFOL(login_fd,6) = 5; // status of the account
@@ -3009,6 +3014,7 @@ int parse_frommap(int fd) {
 				case 2: // ban
 					if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) {
 						if (login_fd > 0) { // don't send request if no login-server
+							WFIFOHEAD(login_fd,18);
 							WFIFOW(login_fd, 0) = 0x2725;
 							WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value
 							WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year
@@ -3028,6 +3034,7 @@ int parse_frommap(int fd) {
 				case 3: // unblock
 					if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) {
 						if (login_fd > 0) { // don't send request if no login-server
+							WFIFOHEAD(login_fd, 10);
 							WFIFOW(login_fd,0) = 0x2724;
 							WFIFOL(login_fd,2) = char_dat[i].status.account_id; // account value
 							WFIFOL(login_fd,6) = 0; // status of the account
@@ -3041,6 +3048,7 @@ int parse_frommap(int fd) {
 				case 4: // unban
 					if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) {
 						if (login_fd > 0) { // don't send request if no login-server
+							WFIFOHEAD(login_fd, 6);
 							WFIFOW(login_fd, 0) = 0x272a;
 							WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value
 							WFIFOSET(login_fd, 6);
@@ -3053,6 +3061,7 @@ int parse_frommap(int fd) {
 				case 5: // changesex
 					if (acc == -1 || isGM(acc) >= isGM(char_dat[i].status.account_id)) {
 						if (login_fd > 0) { // don't send request if no login-server
+							WFIFOHEAD(login_fd, 6);
 							WFIFOW(login_fd, 0) = 0x2727;
 							WFIFOL(login_fd, 2) = char_dat[i].status.account_id; // account value
 							WFIFOSET(login_fd, 6);
@@ -3341,29 +3350,26 @@ int parse_char(int fd) {
 				return 0;
 		  {
 			int GM_value;
-			if ((GM_value = isGM(RFIFOL(fd,2))))
-				ShowInfo("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), GM_value);
-			else
-				ShowInfo("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
-			if (sd == NULL) {
-				sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1);
-				session[fd]->session_data = sd;
-
-//				memset(sd, 0, sizeof(struct char_session_data)); aCalloc does this [Skotlex]
-				strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail
-				sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
-			} else {
+			WFIFOHEAD(fd, 4);
+			if (sd) {
 				//Received again auth packet for already authentified account?? Discard it.
 				//TODO: Perhaps log this as a hack attempt?
 				RFIFOSKIP(fd,17);
 				break;
 			}
+			if ((GM_value = isGM(RFIFOL(fd,2))))
+				ShowInfo("Account Logged On; Account ID: %d (GM level %d).\n", RFIFOL(fd,2), GM_value);
+			else
+				ShowInfo("Account Logged On; Account ID: %d.\n", RFIFOL(fd,2));
+			sd = (struct char_session_data*)aCalloc(sizeof(struct char_session_data), 1);
+			session[fd]->session_data = sd;
+			strncpy(sd->email, "no mail", 40); // put here a mail without '@' to refuse deletion if we don't receive the e-mail
+			sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
 			sd->account_id = RFIFOL(fd,2);
 			sd->login_id1 = RFIFOL(fd,6);
 			sd->login_id2 = RFIFOL(fd,10);
 			sd->sex = RFIFOB(fd,16);
 			// send back account_id
-			WFIFOHEAD(fd, 4);
 			WFIFOL(fd,0) = RFIFOL(fd,2);
 			WFIFOSET(fd,4);
 			// search authentification
@@ -3417,6 +3423,7 @@ int parse_char(int fd) {
 					if (max_connect_user == 0 || count_users() < max_connect_user) {
 						if (login_fd > 0) { // don't send request if no login-server
 							// request to login-server to obtain e-mail/time limit
+							WFIFOHEAD(login_fd, 6);
 							WFIFOW(login_fd,0) = 0x2716;
 							WFIFOL(login_fd,2) = sd->account_id;
 							WFIFOSET(login_fd,6);
@@ -3435,6 +3442,7 @@ int parse_char(int fd) {
 			// authentification not found
 			if (i == AUTH_FIFO_SIZE) {
 				if (login_fd > 0) { // don't send request if no login-server
+					WFIFOHEAD(login_fd,19);
 					WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
 					WFIFOL(login_fd,2) = sd->account_id;
 					WFIFOL(login_fd,6) = sd->login_id1;
@@ -3443,6 +3451,7 @@ int parse_char(int fd) {
 					WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
 					WFIFOSET(login_fd,19);
 				} else { // if no login-server, we must refuse connection
+					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x6c;
 					WFIFOW(fd,2) = 0;
 					WFIFOSET(fd,3);
@@ -3527,20 +3536,24 @@ int parse_char(int fd) {
 				ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(cd->last_point.map), mapindex_id2name(j));
 				cd->last_point.map = j;
 			}
-			WFIFOHEAD(fd, 28);
-			WFIFOW(fd,0) = 0x71;
-			WFIFOL(fd,2) = cd->char_id;
-			memcpy(WFIFOP(fd,6), mapindex_id2name(cd->last_point.map), MAP_NAME_LENGTH);
-			ShowInfo("Character selection '%s' (account: %d, slot: %d).\n", cd->name, sd->account_id, ch);
+			{	//Send player to map
+				WFIFOHEAD(fd, 28);
+				WFIFOW(fd,0) = 0x71;
+				WFIFOL(fd,2) = cd->char_id;
+				memcpy(WFIFOP(fd,6), mapindex_id2name(cd->last_point.map), MAP_NAME_LENGTH);
 			
-			// Advanced subnet check [LuzZza]
-			if((subnet_map_ip = lan_subnetcheck((long *)p)))
-				WFIFOL(fd,22) = subnet_map_ip;
-			else
-				WFIFOL(fd,22) = server[i].ip;
+				// Advanced subnet check [LuzZza]
+				if((subnet_map_ip = lan_subnetcheck((long *)p)))
+					WFIFOL(fd,22) = subnet_map_ip;
+				else
+					WFIFOL(fd,22) = server[i].ip;
+
+				WFIFOW(fd,26) = server[i].port;
+				WFIFOSET(fd,28);
 
-			WFIFOW(fd,26) = server[i].port;
-			WFIFOSET(fd,28);
+				ShowInfo("Character selection '%s' (account: %d, slot: %d).\n",
+					cd->name, sd->account_id, ch);
+			}
 			if (auth_fifo_pos >= AUTH_FIFO_SIZE)
 				auth_fifo_pos = 0;
 			auth_fifo[auth_fifo_pos].account_id = sd->account_id;
@@ -3556,6 +3569,7 @@ int parse_char(int fd) {
 			//Send NEW auth packet [Kevin]
 			if ((map_fd = server_fd[i]) < 1 || session[map_fd] == NULL)
 			{	//0 Should not be a valid server_fd [Skotlex]
+				WFIFOHEAD(fd, 3);
 				ShowError("parse_char: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", map_fd, i);
 				server_fd[i] = -1;
 				memset(&server[i], 0, sizeof(struct mmo_map_server));
@@ -3565,15 +3579,17 @@ int parse_char(int fd) {
 				WFIFOSET(fd,3);
 				break;
 			}	
-			WFIFOW(map_fd,0) = 0x2afd;
-			WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
-			WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id;
-			WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1;
-			WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2;
-			WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time;
-			memcpy(WFIFOP(map_fd,20), cd, sizeof(struct mmo_charstatus));
-			WFIFOSET(map_fd, WFIFOW(map_fd,2));
-
+			{	//Send auth to server.
+				WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
+				WFIFOW(map_fd,0) = 0x2afd;
+				WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
+				WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id;
+				WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1;
+				WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2;
+				WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time;
+				memcpy(WFIFOP(map_fd,20), cd, sizeof(struct mmo_charstatus));
+				WFIFOSET(map_fd, WFIFOW(map_fd,2));
+			}
 			set_char_online(i, cd->char_id, cd->account_id);
 			//Sets char online in the party and breaks even share if needed.
 			inter_party_logged(cd->party_id, cd->account_id, cd->char_id);
@@ -3589,34 +3605,22 @@ int parse_char(int fd) {
 				i = -2;
 			else
 				i = make_new_char(fd, RFIFOP(fd,2));
-				
-			if(i == -1){ //added some better faile reporting to client on the txt version [Kevin]
-                         //already exists
-                            WFIFOHEAD(fd, 3);
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x00;
-                            WFIFOSET(fd, 3);
-                            RFIFOSKIP(fd, 37);
-                            break;
-                        }else if(i == -2){
-                            //denied
-                            WFIFOHEAD(fd, 3);
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x02;
-                            WFIFOSET(fd, 3); 
-                            RFIFOSKIP(fd, 37);                           
-                            break;
-                        }else if(i == -3){
-                            //underaged XD
-                            WFIFOHEAD(fd, 3);
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x01;
-                            WFIFOSET(fd, 3);
-                            RFIFOSKIP(fd, 37);
-                            break;
-                        }
-
-                        WFIFOHEAD(fd, 108);
+			//added some better fail reporting to client on the txt version [Kevin]
+			if (i < 0)
+			{
+				WFIFOHEAD(fd, 3);
+				WFIFOW(fd, 0) = 0x6e;
+				switch (i) {
+				case -1: WFIFOB(fd, 2) = 0x00; break;
+				case -2: WFIFOB(fd, 2) = 0x02; break;
+				case -3: WFIFOB(fd, 2) = 0x01; break;
+				}
+				WFIFOSET(fd, 3);
+				RFIFOSKIP(fd, 37);
+				break;
+			}
+		{	//Send to player.
+			WFIFOHEAD(fd, 108);
 			WFIFOW(fd,0) = 0x6d;
 			memset(WFIFOP(fd,2), 0, 106);
 
@@ -3658,6 +3662,7 @@ int parse_char(int fd) {
 
 			WFIFOSET(fd,108);
 			RFIFOSKIP(fd,37);
+		}
 			for(ch = 0; ch < 9; ch++) {
 				if (sd->found_char[ch] == -1) {
 					sd->found_char[ch] = i;
@@ -3667,7 +3672,9 @@ int parse_char(int fd) {
 
 		case 0x68:	// delete char //Yor's Fix
 			FIFOSD_CHECK(46);
-
+		{
+			WFIFOHEAD(fd, 46);
+			WFIFOHEAD(login_fd,46);
 			memcpy(email, RFIFOP(fd,6), 40);
 			if (e_mail_check(email) == 0)
 				strncpy(email, "a@a.com", 40); // default e-mail
@@ -3760,17 +3767,26 @@ int parse_char(int fd) {
 				}
 				RFIFOSKIP(fd,46);
 			}
+		}
 			break;
 
 		case 0x2af8:	// マップサーバーログイン
 			if (RFIFOREST(fd) < 60)
 				return 0;
+		{
+			char *l_user = RFIFOP(fd, 2);
+			char *l_pass = RFIFOP(fd, 26);
+			WFIFOHEAD(fd, 4+5*GM_num);
+			l_user[23] = '\0';
+			l_pass[23] = '\0';
 			WFIFOW(fd,0) = 0x2af9;
 			for(i = 0; i < MAX_MAP_SERVERS; i++) {
 				if (server_fd[i] < 0)
 					break;
 			}
-			if (i == MAX_MAP_SERVERS || strcmp((char*)RFIFOP(fd,2), userid) || strcmp((char*)RFIFOP(fd,26), passwd)){
+			if (i == MAX_MAP_SERVERS ||
+				strcmp(l_user, userid) ||
+				strcmp(l_pass, passwd)){
 				WFIFOB(fd,2) = 3;
 				WFIFOSET(fd,3);
 				RFIFOSKIP(fd,60);
@@ -3799,6 +3815,7 @@ int parse_char(int fd) {
 				WFIFOSET(fd,len);
 				return 0;
 			}
+		}
 			break;
 
 		case 0x187:	// Alive信号?
@@ -3808,6 +3825,8 @@ int parse_char(int fd) {
 			break;
 
 		case 0x7530:	// Athena情報所得
+		{
+			WFIFOHEAD(fd, 10);
 			WFIFOW(fd,0) = 0x7531;
 			WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
 			WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
@@ -3819,7 +3838,7 @@ int parse_char(int fd) {
 			WFIFOSET(fd,10);
 			RFIFOSKIP(fd,2);
 			return 0;
-
+		}
 		case 0x7532:	// 接続の切断(defaultと処理は一緒だが明示的にするため)
 		default:
 			session[fd]->eof = 1;
@@ -3862,6 +3881,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
 	for(i = 0; i < MAX_MAP_SERVERS; i++) {
 		int fd;
 		if ((fd = server_fd[i]) >= 0) {
+#if 0 //This seems to have been fixed long long ago.
 			if (session[fd] == NULL)
 			{	//Could this be the crash's source? [Skotlex]
 				ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i);
@@ -3869,9 +3889,8 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
 				memset(&server[i], 0, sizeof(struct mmo_map_server));
 				continue;
 			}
+#endif
 			WFIFOHEAD(fd, len);
-			if (WFIFOSPACE(fd) < len) //Increase buffer size.
-				realloc_writefifo(fd, len);
 			memcpy(WFIFOP(fd,0), buf, len);
 			WFIFOSET(fd,len);
 			c++;

+ 163 - 143
src/char_sql/char.c

@@ -249,12 +249,13 @@ void set_char_online(int map_id, int char_id, int account_id) {
 		cp = idb_get(char_db_,char_id);
  		inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
 	}
-	if (login_fd <= 0 || session[login_fd]->eof)
-		return;
-	
-	WFIFOW(login_fd,0) = 0x272b;
-	WFIFOL(login_fd,2) = account_id;
-	WFIFOSET(login_fd,6);
+	if (login_fd > 0 && !session[login_fd]->eof)
+	{	
+		WFIFOHEAD(login_fd,6);
+		WFIFOW(login_fd,0) = 0x272b;
+		WFIFOL(login_fd,2) = account_id;
+		WFIFOSET(login_fd,6);
+	}
 }
 
 void set_char_offline(int char_id, int account_id) {
@@ -285,12 +286,13 @@ void set_char_offline(int char_id, int account_id) {
 		character->waiting_disconnect = 0;
 	}
 	
-   if (login_fd <= 0 || session[login_fd]->eof)
-	return;
-
-   WFIFOW(login_fd,0) = 0x272c;
-   WFIFOL(login_fd,2) = account_id;
-   WFIFOSET(login_fd,6);
+   if (login_fd > 0 && !session[login_fd]->eof)
+	{
+		WFIFOHEAD(login_fd,6);
+		WFIFOW(login_fd,0) = 0x272c;
+		WFIFOL(login_fd,2) = account_id;
+		WFIFOSET(login_fd,6);
+	}
 }
 
 static int char_db_setoffline(DBKey key, void* data, va_list ap) {
@@ -1674,18 +1676,10 @@ int count_users(void) {
 int mmo_char_send006b(int fd, struct char_session_data *sd) {
 	int i, j, found_num = 0;
 	struct mmo_charstatus *p = NULL;
-// hehe. commented other. anyway there's no need to use older version.
-// if use older packet version just uncomment that!
-//#ifdef NEW_006b
 	const int offset = 24;
-//#else
-//	int offset = 4;
-//#endif
-
-//	ShowDebug("mmo_char_send006b start.. (account:%d)\n",sd->account_id);
-//	printf("offset -> %d...\n",offset);
-
-    set_char_online(-1, 99,sd->account_id);
+	WFIFOHEAD(fd, offset +9*106);
+    
+	set_char_online(-1, 99,sd->account_id);
 
 	//search char.
 	sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id` = '%d'",char_db, sd->account_id);
@@ -1705,8 +1699,6 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
 		mysql_free_result(sql_res);
 	}
 
-//	printf("char fetching end (total: %d)....\n", found_num);
-
 	for(i = found_num; i < 9; i++)
 		sd->found_char[i] = -1;
 
@@ -1776,7 +1768,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, int data);
 int parse_tologin(int fd) {
 	int i;
 	struct char_session_data *sd;
-
+	RFIFOHEAD(fd);
 	// only login-server can have an access to here.
 	// so, if it isn't the login-server, we disconnect the session.
 	//session eof check!
@@ -1831,6 +1823,7 @@ int parse_tologin(int fd) {
 				return 0;
 			for(i = 0; i < fd_max; i++) {
 				if (session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
+					WFIFOHEAD(i,3);
 					if (RFIFOB(fd,6) != 0) {
 						WFIFOW(i,0) = 0x6c;
 						WFIFOB(i,2) = 0x42;
@@ -2160,6 +2153,7 @@ int parse_tologin(int fd) {
 						for(i = 0; i < fd_max; i++) {
 							if (session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid)
 							{
+								WFIFOHEAD(i,3);
 								WFIFOW(i,0) = 0x81;
 								WFIFOB(i,2) = 2;
 								WFIFOSET(i,3);
@@ -2192,6 +2186,7 @@ int parse_tologin(int fd) {
 			{	//Update ip.
 				char_ip = new_ip;
 				ShowInfo("Updating IP for [%s].\n",char_ip_str);
+				WFIFOHEAD(fd,6);
 				WFIFOW(fd,0) = 0x2736;
 				WFIFOL(fd,2) = char_ip;
 				WFIFOSET(fd,6);
@@ -2212,6 +2207,7 @@ int parse_tologin(int fd) {
 
 int request_accreg2(int account_id, int char_id) {
 	if (login_fd > 0) {
+		WFIFOHEAD(login_fd, 10);
 		WFIFOW(login_fd, 0) = 0x272e;
 		WFIFOL(login_fd, 2) = account_id;
 		WFIFOL(login_fd, 6) = char_id;
@@ -2368,7 +2364,7 @@ int char_loadName(int char_id, char* name)
 int parse_frommap(int fd) {
 	int i = 0, j = 0;
 	int id;
-//	int auth_fifo_flag=0;
+	RFIFOHEAD(fd);
 
 	// Sometimes fd=0, and it will cause server crash. Don't know why. :(
 	if (fd <= 0) {
@@ -2411,8 +2407,6 @@ int parse_frommap(int fd) {
 	}
 
 	while(RFIFOREST(fd) >= 2 && !session[fd]->eof) {
-	//ShowDebug("Received packet 0x%4x (%d bytes) from map-server (connection %d)\n", RFIFOW(fd, 0), RFIFOREST(fd), fd);
-
 		switch(RFIFOW(fd, 0)) {
 
 		// map-server alive packet
@@ -2426,6 +2420,7 @@ int parse_frommap(int fd) {
 				read_gm_account();
 			//Send to login request to reload gm accounts.
 			else if (login_fd > 0) { // don't send request if no login-server
+				WFIFOHEAD(login_fd, 2);
 				WFIFOW(login_fd,0) = 0x2709;
 				WFIFOSET(login_fd, 2);
 			}
@@ -2435,61 +2430,64 @@ int parse_frommap(int fd) {
 		case 0x2afa:
 			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 				return 0;
+		{
+			unsigned char *p = (unsigned char *)&server[id].ip;
+			unsigned char buf[16384];
+			int x;
+			WFIFOHEAD(fd,3+NAME_LENGTH);
+
 			memset(server[id].map, 0, sizeof(server[id].map));
 			j = 0;
 			for(i = 4; i < RFIFOW(fd,2); i += 4) {
 				server[id].map[j] = RFIFOW(fd,i);
-//				printf("set map %d.%d : %s\n", id, j, server[id].map[j]);
 				j++;
 			}
-			i = server[id].ip;
-			{
-				unsigned char *p = (unsigned char *)&server[id].ip;
-				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 (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]
-			}
+
+			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 (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]
+
 			WFIFOW(fd,0) = 0x2afb;
 			WFIFOB(fd,2) = 0;
-			memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH); // name for wisp to player
+			// name for wisp to player
+			memcpy(WFIFOP(fd,3), wisp_server_name, NAME_LENGTH);
 			WFIFOSET(fd,3+NAME_LENGTH);
+
 			char_send_fame_list(fd); //Send fame list.
-			//WFIFOSET(fd,27);
-			{
-				unsigned char buf[16384];
-				int x;
-				if (j == 0) {
-					ShowWarning("Map-Server %d have NO maps.\n", id);
+
+			if (j == 0)
+				ShowWarning("Map-Server %d have NO maps.\n", id);
+			else {
 				// Transmitting maps information to the other map-servers
-				} else {
-					WBUFW(buf,0) = 0x2b04;
-					WBUFW(buf,2) = j * 4 + 10;
-					WBUFL(buf,4) = server[id].ip;
-					WBUFW(buf,8) = server[id].port;
-					memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
-					mapif_sendallwos(fd, buf, WBUFW(buf,2));
-				}
-				// Transmitting the maps of the other map-servers to the new map-server
-				for(x = 0; x < MAX_MAP_SERVERS; x++) {
-					if (server_fd[x] > 0 && x != id) {
-						WFIFOW(fd,0) = 0x2b04;
-						WFIFOL(fd,4) = server[x].ip;
-						WFIFOW(fd,8) = server[x].port;
-						j = 0;
-						for(i = 0; i < MAX_MAP_PER_SERVER; i++)
-							if (server[x].map[i])
-								WFIFOW(fd,10+(j++)*4) = server[x].map[i];
-						if (j > 0) {
-							WFIFOW(fd,2) = j * 4 + 10;
-							WFIFOSET(fd,WFIFOW(fd,2));
-						}
+				WBUFW(buf,0) = 0x2b04;
+				WBUFW(buf,2) = j * 4 + 10;
+				WBUFL(buf,4) = server[id].ip;
+				WBUFW(buf,8) = server[id].port;
+				memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 4);
+				mapif_sendallwos(fd, buf, WBUFW(buf,2));
+			}
+			// Transmitting the maps of the other map-servers to the new map-server
+			for(x = 0; x < MAX_MAP_SERVERS; x++) {
+				if (server_fd[x] > 0 && x != id) {
+					WFIFOHEAD(fd, 10 +4*MAX_MAP_PER_SERVER);
+					WFIFOW(fd,0) = 0x2b04;
+					WFIFOL(fd,4) = server[x].ip;
+					WFIFOW(fd,8) = server[x].port;
+					j = 0;
+					for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+						if (server[x].map[i])
+							WFIFOW(fd,10+(j++)*4) = server[x].map[i];
+					if (j > 0) {
+						WFIFOW(fd,2) = j * 4 + 10;
+						WFIFOSET(fd,WFIFOW(fd,2));
 					}
 				}
 			}
 			RFIFOSKIP(fd,RFIFOW(fd,2));
+		}
 			break;
 		//Packet command is now used for sc_data request. [Skotlex]
 		case 0x2afc:
@@ -2512,10 +2510,11 @@ int parse_frommap(int fd) {
 			if (sql_res) {
 				struct status_change_data data;
 				int count = 0;
+				WFIFOHEAD(fd, 14+50*sizeof(struct status_change_data));
 				WFIFOW(fd, 0) = 0x2b1d;
 				WFIFOL(fd, 4) = aid;
 				WFIFOL(fd, 8) = cid;
-				while((sql_row = mysql_fetch_row(sql_res)))
+				while((sql_row = mysql_fetch_row(sql_res)) && count < 50)
 				{
 					data.type = atoi(sql_row[0]);
 					data.tick = atoi(sql_row[1]);
@@ -2526,6 +2525,8 @@ int parse_frommap(int fd) {
 					memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &data, sizeof(struct status_change_data));
 					count++;
 				}
+				if (count >= 50)
+					ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid);
 				mysql_free_result(sql_res);
 				if (count > 0)
 				{
@@ -2610,6 +2611,7 @@ int parse_frommap(int fd) {
 			if (RFIFOB(fd,12))
 		  	{ //Flag? Set character offline after saving [Skotlex]
 				set_char_offline(cid, aid);
+				WFIFOHEAD(fd, 10);
 				WFIFOW(fd, 0) = 0x2b21; //Save ack only needed on final save.
 				WFIFOL(fd, 2) = aid;
 				WFIFOL(fd, 6) = cid;
@@ -2635,12 +2637,13 @@ int parse_frommap(int fd) {
 			auth_fifo[auth_fifo_pos].connect_until_time = 0; // unlimited/unknown time by default (not display in map-server)
 			auth_fifo[auth_fifo_pos].ip = RFIFOL(fd,14);
 			auth_fifo_pos++;
-
+		{
+			WFIFOHEAD(fd, 7);
 			WFIFOW(fd, 0) = 0x2b03;
 			WFIFOL(fd, 2) = RFIFOL(fd, 2);
 			WFIFOB(fd, 6) = 0;
 			WFIFOSET(fd, 7);
-
+		}
 			RFIFOSKIP(fd, 18);
 			break;
 
@@ -2653,8 +2656,6 @@ int parse_frommap(int fd) {
 				int map_id, map_fd = -1;
 				struct online_char_data* data;
 				struct mmo_charstatus* char_data;
-
-
 				name = RFIFOW(fd,18);
 				map_id = search_mapserver(name, RFIFOL(fd,24), RFIFOW(fd,28)); //Locate mapserver by ip and port.
 				if (map_id >= 0)
@@ -2670,6 +2671,8 @@ int parse_frommap(int fd) {
 				if (map_fd>=0 && session[map_fd] && char_data) 
 				{	//Send the map server the auth of this player.
 					//Update the "last map" as this is where the player must be spawned on the new map server.
+					WFIFOHEAD(fd, 30);
+					WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
 					char_data->last_point.map = RFIFOW(fd,18);
 					char_data->last_point.x = RFIFOW(fd,20);
 					char_data->last_point.y = RFIFOW(fd,22);
@@ -2692,6 +2695,7 @@ int parse_frommap(int fd) {
 					memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
 					WFIFOSET(fd, 30);
 				} else { //Reply with nak
+					WFIFOHEAD(fd, 30);
 					WFIFOW(fd, 0) = 0x2b06;
 					memcpy(WFIFOP(fd,2), RFIFOP(fd,2), 28);
 					WFIFOL(fd, 6) = 0; //Set login1 to 0.
@@ -2707,6 +2711,7 @@ int parse_frommap(int fd) {
 				return 0;
 			{
 				char name[NAME_LENGTH];
+				WFIFOHEAD(fd,30);
 				char_loadName((int)RFIFOL(fd,2), name);
 				WFIFOW(fd,0) = 0x2b09;
 				WFIFOL(fd,2) = RFIFOL(fd,2);
@@ -2737,6 +2742,7 @@ int parse_frommap(int fd) {
 			if (RFIFOREST(fd) < 86)
 				return 0;
 			if (login_fd > 0) { // don't send request if no login-server
+				WFIFOHEAD(login_fd, 86);
 				memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0), 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
 				WFIFOW(login_fd,0) = 0x2722;
 				WFIFOSET(login_fd, 86);
@@ -2751,6 +2757,7 @@ int parse_frommap(int fd) {
 		  {
 			char character_name[NAME_LENGTH], t_name[NAME_LENGTH*2];
 			int acc = RFIFOL(fd,2); // account_id of who ask (-1 if nobody)
+			WFIFOHEAD(fd, 34);
 			memcpy(character_name, RFIFOP(fd,6), NAME_LENGTH);
 			character_name[NAME_LENGTH-1] = '\0';
 			jstrescapecpy(t_name, character_name); //Escape string for sql use... [Skotlex]
@@ -2776,6 +2783,7 @@ int parse_frommap(int fd) {
 					case 1: // block
 						if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
 							if (login_fd > 0) { // don't send request if no login-server
+								WFIFOHEAD(login_fd, 10);
 								WFIFOW(login_fd,0) = 0x2724;
 								WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
 								WFIFOL(login_fd,6) = 5; // status of the account
@@ -2788,6 +2796,7 @@ int parse_frommap(int fd) {
 					case 2: // ban
 						if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
 							if (login_fd > 0) { // don't send request if no login-server
+								WFIFOHEAD(login_fd, 18);
 								WFIFOW(login_fd, 0) = 0x2725;
 								WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
 								WFIFOW(login_fd, 6) = RFIFOW(fd,32); // year
@@ -2805,6 +2814,7 @@ int parse_frommap(int fd) {
 					case 3: // unblock
 						if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
 							if (login_fd > 0) { // don't send request if no login-server
+								WFIFOHEAD(login_fd, 10);
 								WFIFOW(login_fd,0) = 0x2724;
 								WFIFOL(login_fd,2) = atoi(sql_row[0]); // account value
 								WFIFOL(login_fd,6) = 0; // status of the account
@@ -2817,6 +2827,7 @@ int parse_frommap(int fd) {
 					case 4: // unban
 						if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
 							if (login_fd > 0) { // don't send request if no login-server
+								WFIFOHEAD(login_fd, 6);
 								WFIFOW(login_fd, 0) = 0x272a;
 								WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
 								WFIFOSET(login_fd, 6);
@@ -2828,6 +2839,7 @@ int parse_frommap(int fd) {
 					case 5: // changesex
 						if (acc == -1 || isGM(acc) >= isGM(atoi(sql_row[0]))) {
 							if (login_fd > 0) { // don't send request if no login-server
+								WFIFOHEAD(login_fd, 6);
 								WFIFOW(login_fd, 0) = 0x2727;
 								WFIFOL(login_fd, 2) = atoi(sql_row[0]); // account value
 								WFIFOSET(login_fd, 6);
@@ -3086,6 +3098,7 @@ int parse_char(int fd) {
 	struct char_session_data *sd;
 	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
 	long subnet_map_ip;
+	RFIFOHEAD(fd);
 
 	sd = (struct char_session_data*)session[fd]->session_data;
 
@@ -3134,17 +3147,17 @@ int parse_char(int fd) {
 			if (RFIFOREST(fd) < 17)
 				return 0;
 		{
-			if (sd == NULL) {
-				CREATE(session[fd]->session_data, struct char_session_data, 1);
-				sd = (struct char_session_data*)session[fd]->session_data;
-				sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
-			} else {
+			WFIFOHEAD(fd, 4);
+
+			if (sd) {
 				//Received again auth packet for already authentified account?? Discard it.
 				//TODO: Perhaps log this as a hack attempt?
 				RFIFOSKIP(fd,17);
 				break;
 			}
-
+			CREATE(session[fd]->session_data, struct char_session_data, 1);
+			sd = (struct char_session_data*)session[fd]->session_data;
+			sd->connect_until_time = 0; // unknow or illimited (not displaying on map-server)
 			sd->account_id = RFIFOL(fd, 2);
 			sd->login_id1 = RFIFOL(fd, 6);
 			sd->login_id2 = RFIFOL(fd, 10);
@@ -3203,6 +3216,7 @@ int parse_char(int fd) {
 				if (max_connect_user == 0 || count_users() < max_connect_user) {
 					if (login_fd > 0) { // don't send request if no login-server
 						// request to login-server to obtain e-mail/time limit
+						WFIFOHEAD(login_fd, 6);
 						WFIFOW(login_fd,0) = 0x2716;
 						WFIFOL(login_fd,2) = sd->account_id;
 						WFIFOSET(login_fd,6);
@@ -3221,6 +3235,7 @@ int parse_char(int fd) {
 			}
 			if (i == AUTH_FIFO_SIZE) {
 				if (login_fd > 0) { // don't send request if no login-server
+					WFIFOHEAD(login_fd,19);
 					WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
 					WFIFOL(login_fd,2) = sd->account_id;
 					WFIFOL(login_fd,6) = sd->login_id1;
@@ -3229,6 +3244,7 @@ int parse_char(int fd) {
 					WFIFOL(login_fd,15) = session[fd]->client_addr.sin_addr.s_addr;
 					WFIFOSET(login_fd,19);
 				} else { // if no login-server, we must refuse connection
+					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x6c;
 					WFIFOB(fd,2) = 0;
 					WFIFOSET(fd,3);
@@ -3311,6 +3327,7 @@ int parse_char(int fd) {
 					char_dat.last_point.y = 103;
 				} else {
 					ShowInfo("Connection Closed. No map server available that has a major city, and unable to find map-server for '%s'.\n", mapindex_id2name(char_dat.last_point.map));
+					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x81;
 					WFIFOB(fd,2) = 1; // 01 = Server closed
 					WFIFOSET(fd,3);
@@ -3319,18 +3336,21 @@ int parse_char(int fd) {
 				ShowWarning("Unable to find map-server for '%s', sending to major city '%s'.\n", mapindex_id2name(char_dat.last_point.map), mapindex_id2name(j));
 				char_dat.last_point.map = j;
 			}
-			WFIFOW(fd, 0) =0x71;
-			WFIFOL(fd, 2) =char_dat.char_id;
-			memcpy(WFIFOP(fd,6), mapindex_id2name(char_dat.last_point.map), MAP_NAME_LENGTH);
-
-			// Andvanced subnet check [LuzZza]
-			if((subnet_map_ip = lan_subnetcheck((long *)p)))
-				WFIFOL(fd,22) = subnet_map_ip;
-			else
-				WFIFOL(fd,22) = server[i].ip;
-
-			WFIFOW(fd,26) = server[i].port;
-			WFIFOSET(fd,28);
+			{	//Send player to map.
+				WFIFOHEAD(fd,28);
+				WFIFOW(fd, 0) =0x71;
+				WFIFOL(fd, 2) =char_dat.char_id;
+				memcpy(WFIFOP(fd,6), mapindex_id2name(char_dat.last_point.map), MAP_NAME_LENGTH);
+
+				// Advanced subnet check [LuzZza]
+				if((subnet_map_ip = lan_subnetcheck((long *)p)))
+					WFIFOL(fd,22) = subnet_map_ip;
+				else
+					WFIFOL(fd,22) = server[i].ip;
+
+				WFIFOW(fd,26) = server[i].port;
+				WFIFOSET(fd,28);
+			}
 			if (auth_fifo_pos >= AUTH_FIFO_SIZE) {
 				auth_fifo_pos = 0;
 			}
@@ -3352,15 +3372,17 @@ int parse_char(int fd) {
 				memset(&server[i], 0, sizeof(struct mmo_map_server));
 				break;
 			}	
-
-			WFIFOW(map_fd,0) = 0x2afd;
-			WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
-			WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id;
-			WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1;
-			WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2;
-			WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time;
-			memcpy(WFIFOP(map_fd,20), &char_dat, sizeof(struct mmo_charstatus));
-			WFIFOSET(map_fd, WFIFOW(map_fd,2));
+			{ //Send auth ok to map server
+				WFIFOHEAD(map_fd, 20 + sizeof(struct mmo_charstatus));
+				WFIFOW(map_fd,0) = 0x2afd;
+				WFIFOW(map_fd,2) = 20 + sizeof(struct mmo_charstatus);
+				WFIFOL(map_fd,4) = auth_fifo[auth_fifo_pos].account_id;
+				WFIFOL(map_fd,8) = auth_fifo[auth_fifo_pos].login_id1;
+				WFIFOL(map_fd,16) = auth_fifo[auth_fifo_pos].login_id2;
+				WFIFOL(map_fd,12) = (unsigned long)auth_fifo[auth_fifo_pos].connect_until_time;
+				memcpy(WFIFOP(map_fd,20), &char_dat, sizeof(struct mmo_charstatus));
+				WFIFOSET(map_fd, WFIFOW(map_fd,2));
+			}
 
 			set_char_online(i, auth_fifo[auth_fifo_pos].char_id, auth_fifo[auth_fifo_pos].account_id);
 			//Checks to see if the even share setting of the party must be broken.
@@ -3376,38 +3398,23 @@ int parse_char(int fd) {
 			else
 				i = make_new_char_sql(fd, RFIFOP(fd, 2));
 
-			//if (i < 0) {
-			//	WFIFOW(fd, 0) = 0x6e;
-			//	WFIFOB(fd, 2) = 0x00;
-			//	WFIFOSET(fd, 3);
-			//	RFIFOSKIP(fd, 37);
-			//	break;
-			//}
-			//Changed that we can support 'Charname already exists' (-1) amd 'Char creation denied' (-2)
+			//'Charname already exists' (-1), 'Char creation denied' (-2)
 			//And 'You are underaged' (-3) (XD) [Sirius]
-			if(i == -1){
-                       //already exists
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x00;
-                            WFIFOSET(fd, 3);
-                            RFIFOSKIP(fd, 37);
-                            break;
-			}else if(i == -2){
-                        //denied
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x02;
-                            WFIFOSET(fd, 3);
-                            RFIFOSKIP(fd, 37);
-                            break;
-			}else if(i == -3){
-                        //underaged XD
-                            WFIFOW(fd, 0) = 0x6e;
-                            WFIFOB(fd, 2) = 0x01;
-                            WFIFOSET(fd, 3);
-                            RFIFOSKIP(fd, 37);
-                            break;
+			if (i < 0)
+			{
+				WFIFOHEAD(fd, 3);
+				WFIFOW(fd, 0) = 0x6e;
+				switch (i) {
+				case -1: WFIFOB(fd, 2) = 0x00; break;
+				case -2: WFIFOB(fd, 2) = 0x02; break;
+				case -3: WFIFOB(fd, 2) = 0x01; break;
+				}
+				WFIFOSET(fd, 3);
+				RFIFOSKIP(fd, 37);
+				break;
 			}
-
+		{	//Send data.
+			WFIFOHEAD(fd, 108);
 			WFIFOW(fd, 0) = 0x6d;
 			memset(WFIFOP(fd, 2), 0x00, 106);
 
@@ -3450,7 +3457,7 @@ int parse_char(int fd) {
 
 			WFIFOSET(fd, 108);
 			RFIFOSKIP(fd, 37);
-			
+		}	
 			//to do
 			for(ch = 0; ch < 9; ch++) {
 				if (sd->found_char[ch] == -1) {
@@ -3463,6 +3470,7 @@ int parse_char(int fd) {
 			FIFOSD_CHECK(46);
 		{
 			int cid = RFIFOL(fd,2);
+			WFIFOHEAD(fd, 46);
 			ShowInfo(CL_RED" Request Char Deletion:"CL_GREEN"%d (%d)"CL_RESET"\n", sd->account_id, cid);
 			memcpy(email, RFIFOP(fd,6), 40);
 			
@@ -3556,12 +3564,21 @@ int parse_char(int fd) {
 		case 0x2af8: // login as map-server
 			if (RFIFOREST(fd) < 60)
 				return 0;
+		{
+			char *l_userid = RFIFOP(fd,2);
+			char *l_password = RFIFOP(fd,26);
+			WFIFOHEAD(fd, 4+5*GM_num); 
+
+			l_userid[23] = '\0';
+			l_password[23] = '\0';
 			WFIFOW(fd, 0) = 0x2af9;
 			for(i = 0; i < MAX_MAP_SERVERS; i++) {
 				if (server_fd[i] <= 0)
 					break;
 			}
-			if (i == MAX_MAP_SERVERS || strcmp((const char*)RFIFOP(fd,2), userid) || strcmp((const char*)RFIFOP(fd,26), passwd)) {
+			if (i == MAX_MAP_SERVERS ||
+				strcmp(l_userid, userid) ||
+				strcmp(l_password, passwd)) {
 				WFIFOB(fd,2) = 3;
 				WFIFOSET(fd, 3);
 			} else {
@@ -3589,7 +3606,7 @@ int parse_char(int fd) {
 			}
 			RFIFOSKIP(fd,60);
 			break;
-
+		}
 		case 0x187:	// Alive?
 			if (RFIFOREST(fd) < 6) {
 				return 0;
@@ -3598,6 +3615,8 @@ int parse_char(int fd) {
 			break;
 
 		case 0x7530:	// Athena info get
+		{
+			WFIFOHEAD(fd, 10);
 			WFIFOW(fd, 0) = 0x7531;
 			WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
 			WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
@@ -3609,7 +3628,7 @@ int parse_char(int fd) {
 			WFIFOSET(fd, 10);
 			RFIFOSKIP(fd, 2);
 			return 0;
-
+		}
 		case 0x7532:	// disconnect(default also disconnect)
 		default:
 			session[fd]->eof = 1;
@@ -3653,6 +3672,8 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
 	c = 0;
 	for(i = 0; i < MAX_MAP_SERVERS; i++) {
 		if ((fd = server_fd[i]) > 0) { //0 Should not be a valid server_fd [Skotlex]
+			WFIFOHEAD(fd,len);
+#if 0 //This seems to have been fixed long long ago.
 			if (session[fd] == NULL)
 			{	//Could this be the crash's source? [Skotlex]
 				ShowError("mapif_sendall: Attempting to write to invalid session %d! Map Server #%d disconnected.\n", fd, i);
@@ -3660,8 +3681,7 @@ int mapif_sendall(unsigned char *buf, unsigned int len) {
 				memset(&server[i], 0, sizeof(struct mmo_map_server));
 				continue;
 			}
-			if (WFIFOSPACE(fd) < len) //Increase buffer size.
-				realloc_writefifo(fd, len);
+#endif
 			memcpy(WFIFOP(fd,0), buf, len);
 			WFIFOSET(fd,len);
 			c++;
@@ -3678,8 +3698,7 @@ int mapif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
 	c = 0;
 	for(i=0, c=0;i<MAX_MAP_SERVERS;i++){
 		if ((fd = server_fd[i]) > 0 && fd != sfd) {
-			if (WFIFOSPACE(fd) < len) //Increase buffer size.
-				realloc_writefifo(fd, len);
+			WFIFOHEAD(fd, len);
 			memcpy(WFIFOP(fd,0), buf, len);
 			WFIFOSET(fd, len);
 			c++;
@@ -3695,8 +3714,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) {
 	if (fd >= 0) {
 		for(i = 0; i < MAX_MAP_SERVERS; i++) {
 			if (fd == server_fd[i]) {
-				if (WFIFOSPACE(fd) < len) //Increase buffer size.
-					realloc_writefifo(fd, len);
+				WFIFOHEAD(fd,len);
 				memcpy(WFIFOP(fd,0), buf, len);
 				WFIFOSET(fd,len);
 				return 1;
@@ -3712,6 +3730,7 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data) {
 
 	if (login_fd > 0 && session[login_fd]) {
 		// send number of user to login server
+		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x2714;
 		WFIFOL(login_fd,2) = users;
 		WFIFOSET(login_fd,6);
@@ -3767,6 +3786,8 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
 	}
 	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);
@@ -3776,10 +3797,9 @@ int check_connect_login_server(int tid, unsigned int tick, int id, int data) {
 	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;
 }
 

+ 4 - 1
src/char_sql/int_guild.c

@@ -987,6 +987,7 @@ int guild_calcinfo(struct guild *g)
 
 int mapif_guild_created(int fd,int account_id,struct guild *g)
 {
+	WFIFOHEAD(fd, 10);
 	WFIFOW(fd,0)=0x3830;
 	WFIFOL(fd,2)=account_id;
 	if(g != NULL)
@@ -1031,6 +1032,7 @@ int mapif_guild_info(int fd,struct guild *g)
 // ACK member add
 int mapif_guild_memberadded(int fd,int guild_id,int account_id,int char_id,int flag)
 {
+	WFIFOHEAD(fd, 15);
 	WFIFOW(fd,0)=0x3832;
 	WFIFOL(fd,2)=guild_id;
 	WFIFOL(fd,6)=account_id;
@@ -1232,7 +1234,7 @@ int mapif_guild_castle_datasave(int castle_id,int index,int value)      // <Agit
 int mapif_guild_castle_alldataload(int fd) {
 	struct guild_castle* gc = (struct guild_castle *)aMalloc(sizeof(struct guild_castle));
 	int i, len = 4;
-
+	WFIFOHEAD(fd, len + MAX_GUILDCASTLE*sizeof(struct guild_castle));
 	WFIFOW(fd,0) = 0x3842;
 	sprintf(tmp_sql,"SELECT * FROM `%s` ORDER BY `castle_id`", guild_castle_db);
 	if(mysql_query(&mysql_handle, tmp_sql) ) {
@@ -2060,6 +2062,7 @@ int mapif_parse_GuildCheck(int fd,int guild_id,int account_id,int char_id)
 // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない
 int inter_guild_parse_frommap(int fd)
 {
+	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
 	case 0x3030: mapif_parse_CreateGuild(fd,RFIFOL(fd,4),(char*)RFIFOP(fd,8),(struct guild_member *)RFIFOP(fd,32)); break;
 	case 0x3031: mapif_parse_GuildInfo(fd,RFIFOL(fd,2)); break;

+ 9 - 5
src/char_sql/int_homun.c

@@ -34,6 +34,7 @@ void inter_homunculus_sql_final(void){
 
 int mapif_saved_homunculus(int fd, int account_id, unsigned char flag)
 {
+	WFIFOHEAD(fd, 7);
 	WFIFOW(fd,0) = 0x3892;
 	WFIFOL(fd,2) = account_id;
 	WFIFOB(fd,6) = flag;
@@ -42,6 +43,7 @@ int mapif_saved_homunculus(int fd, int account_id, unsigned char flag)
 }
 int mapif_info_homunculus(int fd, int account_id, struct s_homunculus *hd)
 {
+	WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
 	WFIFOW(fd,0) = 0x3891;
 	WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
 	WFIFOL(fd,4) = account_id;
@@ -54,6 +56,7 @@ int mapif_info_homunculus(int fd, int account_id, struct s_homunculus *hd)
 
 int mapif_homunculus_deleted(int fd, int flag)
 {
+	WFIFOHEAD(fd, 3);
 	WFIFOW(fd, 0) = 0x3893;
 	WFIFOB(fd,2) = flag; //Flag 1 = success
 	WFIFOSET(fd, 3);
@@ -140,6 +143,7 @@ int mapif_save_homunculus(int fd, int account_id, struct s_homunculus *hd)
 // Load an homunculus
 int mapif_load_homunculus(int fd){
 	int i;
+	RFIFOHEAD(fd);
 	memset(homun_pt, 0, sizeof(struct s_homunculus));
 
 	sprintf(tmp_sql,"SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%lu'", RFIFOL(fd,6));
@@ -214,6 +218,7 @@ int mapif_load_homunculus(int fd){
 
 int mapif_delete_homunculus(int fd)
 {
+	RFIFOHEAD(fd);
 	sprintf(tmp_sql, "DELETE FROM `homunculus` WHERE `homun_id` = '%lu'", RFIFOL(fd,2));
 	if(mysql_query(&mysql_handle, tmp_sql))
 	{
@@ -233,6 +238,7 @@ int mapif_delete_homunculus(int fd)
 }
 
 int mapif_rename_homun_ack(int fd, int account_id, int char_id, unsigned char flag, char *name){
+	WFIFOHEAD(fd, NAME_LENGTH+12);
 	WFIFOW(fd, 0) =0x3894;
 	WFIFOL(fd, 2) =account_id;
 	WFIFOL(fd, 6) =char_id;
@@ -267,18 +273,16 @@ int mapif_rename_homun(int fd, int account_id, int char_id, char *name){
 
 int mapif_parse_CreateHomunculus(int fd)
 {
+	RFIFOHEAD(fd);
 	memcpy(homun_pt, RFIFOP(fd,8), sizeof(struct s_homunculus));
 	// Save in sql db
 	if(mapif_save_homunculus(fd,RFIFOL(fd,4), homun_pt))
 		return mapif_homunculus_created(fd, RFIFOL(fd,4), homun_pt, 1); // send homun_id
-	else
-		return mapif_homunculus_created(fd, RFIFOL(fd,4), homun_pt, 0); // fail
+	return mapif_homunculus_created(fd, RFIFOL(fd,4), homun_pt, 0); // fail
 }
 
-
-
-
 int inter_homunculus_parse_frommap(int fd){
+	RFIFOHEAD(fd);
 	switch(RFIFOW(fd, 0)){
 	case 0x3090: mapif_parse_CreateHomunculus(fd); break;
 	case 0x3091: mapif_load_homunculus(fd); break;

+ 2 - 0
src/char_sql/int_party.c

@@ -382,6 +382,7 @@ int party_check_conflict(int party_id,int account_id,int char_id)
 // パーティ作成可否
 int mapif_party_created(int fd,int account_id,int char_id,struct party *p)
 {
+	WFIFOHEAD(fd, 39);
 	WFIFOW(fd,0)=0x3820;
 	WFIFOL(fd,2)=account_id;
 	WFIFOL(fd,6)=char_id;
@@ -403,6 +404,7 @@ int mapif_party_created(int fd,int account_id,int char_id,struct party *p)
 // パーティ情報見つからず
 int mapif_party_noinfo(int fd,int party_id)
 {
+	WFIFOHEAD(fd,8);
 	WFIFOW(fd,0)=0x3821;
 	WFIFOW(fd,2)=8;
 	WFIFOL(fd,4)=party_id;

+ 15 - 1
src/char_sql/int_pet.c

@@ -141,6 +141,7 @@ int inter_pet_delete(int pet_id){
 //------------------------------------------------------
 int mapif_pet_created(int fd, int account_id, struct s_pet *p)
 {
+	WFIFOHEAD(fd, 11);
 	WFIFOW(fd, 0) =0x3880;
 	WFIFOL(fd, 2) =account_id;
 	if(p!=NULL){
@@ -157,6 +158,7 @@ int mapif_pet_created(int fd, int account_id, struct s_pet *p)
 }
 
 int mapif_pet_info(int fd, int account_id, struct s_pet *p){
+	WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
 	WFIFOW(fd, 0) =0x3881;
 	WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
 	WFIFOL(fd, 4) =account_id;
@@ -168,6 +170,7 @@ int mapif_pet_info(int fd, int account_id, struct s_pet *p){
 }
 
 int mapif_pet_noinfo(int fd, int account_id){
+	WFIFOHEAD(fd, sizeof(struct s_pet) + 9);
 	WFIFOW(fd, 0) =0x3881;
 	WFIFOW(fd, 2) =sizeof(struct s_pet) + 9;
 	WFIFOL(fd, 4) =account_id;
@@ -179,6 +182,7 @@ int mapif_pet_noinfo(int fd, int account_id){
 }
 
 int mapif_save_pet_ack(int fd, int account_id, int flag){
+	WFIFOHEAD(fd, 7);
 	WFIFOW(fd, 0) =0x3882;
 	WFIFOL(fd, 2) =account_id;
 	WFIFOB(fd, 6) =flag;
@@ -188,6 +192,7 @@ int mapif_save_pet_ack(int fd, int account_id, int flag){
 }
 
 int mapif_delete_pet_ack(int fd, int flag){
+	WFIFOHEAD(fd, 3);
 	WFIFOW(fd, 0) =0x3883;
 	WFIFOB(fd, 2) =flag;
 	WFIFOSET(fd, 3);
@@ -196,6 +201,7 @@ int mapif_delete_pet_ack(int fd, int flag){
 }
 
 int mapif_rename_pet_ack(int fd, int account_id, int char_id, int flag, char *name){
+	WFIFOHEAD(fd, NAME_LENGTH+12);
 	WFIFOW(fd, 0) =0x3884;
 	WFIFOL(fd, 2) =account_id;
 	WFIFOL(fd, 6) =char_id;
@@ -268,7 +274,9 @@ int mapif_load_pet(int fd, int account_id, int char_id, int pet_id){
 
 int mapif_save_pet(int fd, int account_id, struct s_pet *data) {
 	//here process pet save request.
-	int len=RFIFOW(fd, 2);
+	int len;
+	RFIFOHEAD(fd);
+	len=RFIFOW(fd, 2);
 	if(sizeof(struct s_pet)!=len-8) {
 		ShowError("inter pet: data size error %d %d\n", sizeof(struct s_pet), len-8);
 	}
@@ -318,32 +326,38 @@ int mapif_rename_pet(int fd, int account_id, int char_id, char *name){
 }
 
 int mapif_parse_CreatePet(int fd){
+	RFIFOHEAD(fd);
 	mapif_create_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOW(fd, 10), RFIFOW(fd, 12), RFIFOW(fd, 14), RFIFOW(fd, 16), RFIFOW(fd, 18),
 		RFIFOW(fd, 20), RFIFOB(fd, 22), RFIFOB(fd, 23), (char*)RFIFOP(fd, 24));
 	return 0;
 }
 
 int mapif_parse_LoadPet(int fd){
+	RFIFOHEAD(fd);
 	mapif_load_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
 	return 0;
 }
 
 int mapif_parse_SavePet(int fd){
+	RFIFOHEAD(fd);
 	mapif_save_pet(fd, RFIFOL(fd, 4), (struct s_pet *) RFIFOP(fd, 8));
 	return 0;
 }
 
 int mapif_parse_DeletePet(int fd){
+	RFIFOHEAD(fd);
 	mapif_delete_pet(fd, RFIFOL(fd, 2));
 	return 0;
 }
 
 int mapif_parse_RenamePet(int fd){
+	RFIFOHEAD(fd);
 	mapif_rename_pet(fd, RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOP(fd, 10));
 	return 0;
 }
 
 int inter_pet_parse_frommap(int fd){
+	RFIFOHEAD(fd);
 	switch(RFIFOW(fd, 0)){
 	case 0x3080: mapif_parse_CreatePet(fd); break;
 	case 0x3081: mapif_parse_LoadPet(fd); break;

+ 17 - 5
src/char_sql/int_storage.c

@@ -223,6 +223,7 @@ int inter_guild_storage_delete(int guild_id)
 // recive packet about storage data
 int mapif_load_storage(int fd,int account_id){
 	//load from DB
+	WFIFOHEAD(fd, sizeof(struct storage)+8);
 	storage_fromsql(account_id, storage_pt);
 	WFIFOW(fd,0)=0x3810;
 	WFIFOW(fd,2)=sizeof(struct storage)+8;
@@ -233,6 +234,7 @@ int mapif_load_storage(int fd,int account_id){
 }
 // send ack to map server which is "storage data save ok."
 int mapif_save_storage_ack(int fd,int account_id){
+	WFIFOHEAD(fd, 7);
 	WFIFOW(fd,0)=0x3811;
 	WFIFOL(fd,2)=account_id;
 	WFIFOB(fd,6)=0;
@@ -243,6 +245,7 @@ int mapif_save_storage_ack(int fd,int account_id){
 int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 {
 	int guild_exist=1;
+	WFIFOHEAD(fd, sizeof(struct guild_storage)+12);
 	WFIFOW(fd,0)=0x3818;
 
 #if 0	// innodb guilds should render this check unnecessary [Aru]
@@ -279,6 +282,7 @@ int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 }
 int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 {
+	WFIFOHEAD(fd,11);
 	WFIFOW(fd,0)=0x3819;
 	WFIFOL(fd,2)=account_id;
 	WFIFOL(fd,6)=guild_id;
@@ -292,14 +296,17 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 
 // recive request about storage data
 int mapif_parse_LoadStorage(int fd){
+	RFIFOHEAD(fd);
 	mapif_load_storage(fd,RFIFOL(fd,2));
 	return 0;
 }
 // storage data recive and save
 int mapif_parse_SaveStorage(int fd){
-	int account_id=RFIFOL(fd,4);
-	int len=RFIFOW(fd,2);
-
+	int account_id;
+	int len;
+	RFIFOHEAD(fd);
+	account_id=RFIFOL(fd,4);
+	len=RFIFOW(fd,2);
 	if(sizeof(struct storage)!=len-8){
 		ShowError("inter storage: data size error %d %d\n",sizeof(struct storage),len-8);
 	}else{
@@ -312,6 +319,7 @@ int mapif_parse_SaveStorage(int fd){
 
 int mapif_parse_LoadGuildStorage(int fd)
 {
+	RFIFOHEAD(fd);
 	mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6));
 	return 0;
 }
@@ -319,8 +327,11 @@ int mapif_parse_LoadGuildStorage(int fd)
 int mapif_parse_SaveGuildStorage(int fd)
 {
 	int guild_exist=1;
-	int guild_id=RFIFOL(fd,8);
-	int len=RFIFOW(fd,2);
+	int guild_id;
+	int len;
+	RFIFOHEAD(fd);
+	guild_id=RFIFOL(fd,8);
+	len=RFIFOW(fd,2);
 	if(sizeof(struct guild_storage)!=len-12){
 		ShowError("inter storage: data size error %d %d\n",sizeof(struct guild_storage),len-12);
 	}
@@ -354,6 +365,7 @@ int mapif_parse_SaveGuildStorage(int fd)
 
 
 int inter_storage_parse_frommap(int fd){
+	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
 	case 0x3010: mapif_parse_LoadStorage(fd); break;
 	case 0x3011: mapif_parse_SaveStorage(fd); break;

+ 29 - 18
src/char_sql/inter.c

@@ -493,8 +493,9 @@ int mapif_account_reg(int fd,unsigned char *src)
 int mapif_account_reg_reply(int fd,int account_id,int char_id, int type)
 {
 	struct accreg *reg=accreg_pt;
+	WFIFOHEAD(fd, 13 + 5000);
 	inter_accreg_fromsql(account_id,char_id,reg,type);
-
+	
 	WFIFOW(fd,0)=0x3804;
 	WFIFOL(fd,4)=account_id;
 	WFIFOL(fd,8)=char_id;
@@ -503,11 +504,13 @@ int mapif_account_reg_reply(int fd,int account_id,int char_id, int type)
 		WFIFOW(fd,2)=13;
 	}else{
 		int i,p;
-		for (p=13,i = 0; i < reg->reg_num; i++) {
+		for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) {
 			p+= sprintf(WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
 			p+= sprintf(WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
 		}
 		WFIFOW(fd,2)=p;
+		if (p>= 5000)
+			ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id);
 	}
 	WFIFOSET(fd,WFIFOW(fd,2));
 	return 0;
@@ -547,14 +550,16 @@ void mapif_send_maxid(int account_id, int char_id)
 //Request to kick char from a certain map server. [Skotlex]
 int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason)
 {
-	if (fd < 0)
-		return -1;
-	
-	WFIFOW(fd,0) = 0x2b1f;
-	WFIFOL(fd,2) = account_id;
-	WFIFOB(fd,6) = reason;
-	WFIFOSET(fd,7);
-	return 0;
+	if (fd >= 0)
+	{
+		WFIFOHEAD(fd,7);
+		WFIFOW(fd,0) = 0x2b1f;
+		WFIFOL(fd,2) = account_id;
+		WFIFOB(fd,6) = reason;
+		WFIFOSET(fd,7);
+		return 0;
+	}
+	return -1;
 }
 
 //--------------------------------------------------------
@@ -595,6 +600,7 @@ int check_ttl_wisdata(void) {
 // GM message sending
 int mapif_parse_GMmessage(int fd)
 {
+	RFIFOHEAD(fd);
 	mapif_GMmessage(RFIFOP(fd, 8), RFIFOW(fd, 2), RFIFOL(fd, 4), fd);
 	return 0;
 }
@@ -605,7 +611,7 @@ int mapif_parse_WisRequest(int fd) {
 	struct WisData* wd;
 	static int wisid = 0;
 	char name[NAME_LENGTH], t_name[NAME_LENGTH*2]; //Needs space to allocate names with escaped chars [Skotlex]
-
+	RFIFOHEAD(fd);
 	if ( fd <= 0 ) {return 0;} // check if we have a valid fd
 
 	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
@@ -675,9 +681,12 @@ int mapif_parse_WisRequest(int fd) {
 
 // Wisp/page transmission result
 int mapif_parse_WisReply(int fd) {
-	int id = RFIFOL(fd,2), flag = RFIFOB(fd,6);
-	struct WisData *wd = idb_get(wis_db, id);
-
+	int id, flag;
+	struct WisData *wd;
+	RFIFOHEAD(fd);
+	id = RFIFOL(fd,2);
+	flag = RFIFOB(fd,6);
+	wd = idb_get(wis_db, id);
 	if (wd == NULL)
 		return 0;	// This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
 
@@ -692,7 +701,7 @@ int mapif_parse_WisReply(int fd) {
 // Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers)
 int mapif_parse_WisToGM(int fd) {
 	unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
-
+	RFIFOHEAD(fd);
 	ShowDebug("Sent packet back!\n");
 	memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
 	WBUFW(buf, 0) = 0x3803;
@@ -706,7 +715,7 @@ int mapif_parse_Registry(int fd)
 {
 	int j,p,len, max;
 	struct accreg *reg=accreg_pt;
-	
+	RFIFOHEAD(fd);	
 	memset(accreg_pt,0,sizeof(struct accreg));
 	switch (RFIFOB(fd, 12)) {
 	case 3: //Character registry
@@ -754,9 +763,10 @@ int mapif_parse_RegistryRequest(int fd)
 //--------------------------------------------------------
 int inter_parse_frommap(int fd)
 {
-	int cmd=RFIFOW(fd,0);
+	int cmd;
 	int len=0;
-
+	RFIFOHEAD(fd);
+	cmd=RFIFOW(fd,0);
 	// interŽIŠÇŠ�‚©‚𒲂ׂ
 	if(cmd < 0x3000 || cmd >= 0x3000 + (sizeof(inter_recv_packet_length)/
 		sizeof(inter_recv_packet_length[0]) ) )
@@ -797,6 +807,7 @@ int inter_parse_frommap(int fd)
 // RFIFO check
 int inter_check_length(int fd, int length)
 {
+	RFIFOHEAD(fd);
 	if(length==-1){	// v-len packet
 		if(RFIFOREST(fd)<4)	// packet not yet
 			return 0;

+ 0 - 1
src/common/socket.c

@@ -877,7 +877,6 @@ int do_parsepacket(void)
 				continue;
 			}
 		}
-  		RFIFOHEAD(i);
 		RFIFOFLUSH(i);
 	}
 	return 0;

+ 4 - 4
src/common/socket.h

@@ -26,8 +26,8 @@ extern time_t stall_time;
 
 #define RFIFOSPACE(fd) (session[fd]->max_rdata-session[fd]->rdata_size)
 #ifdef TURBO
-#define RFIFOHEAD(fd) char *rbPtr = session[fd]->rdata+session[fd]->rdata_pos
-#define RFIFOP(fd,pos) (&rbPtr[pos])
+#define RFIFOHEAD(fd) char *rbPtr ## fd = session[fd]->rdata+session[fd]->rdata_pos
+#define RFIFOP(fd,pos) (&rbPtr ## fd[pos])
 #else
 //Make it a comment so it does not disrupts the rest of code.
 #define RFIFOHEAD(fd) //
@@ -55,8 +55,8 @@ extern time_t stall_time;
 
 #define WFIFOSPACE(fd) (session[fd]->max_wdata-session[fd]->wdata_size)
 #ifdef TURBO
-#define WFIFOHEAD(fd, x) char *wbPtr = session[fd]->wdata+session[fd]->wdata_size;
-#define WFIFOP(fd,pos) (&wbPtr[pos])
+#define WFIFOHEAD(fd, x) char *wbPtr ## fd = fd?(session[fd]->wdata+session[fd]->wdata_size):0;
+#define WFIFOP(fd,pos) (&wbPtr ## fd[pos])
 #else
 #define WFIFOHEAD(fd, size) { if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); }
 

+ 2 - 2
src/login/login.c

@@ -3278,6 +3278,7 @@ int parse_login(int fd) {
 			{
 				int GM_value, len;
 				char* server_name;
+ 				WFIFOHEAD(fd, 3);
 				memcpy(account.userid,RFIFOP(fd,2),NAME_LENGTH);
 				account.userid[23] = '\0';
 				remove_control_chars((unsigned char *)account.userid);
@@ -3286,7 +3287,7 @@ int parse_login(int fd) {
 				remove_control_chars((unsigned char *)account.passwd);
 				account.passwdenc = 0;
 				server_name = (char*)RFIFOP(fd,60);
-				server_name[19] = '\0';
+				server_name[20] = '\0';
 				remove_control_chars((unsigned char *)server_name);
 				login_log("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)" RETCODE,
 				          server_name, RFIFOB(fd,54), RFIFOB(fd,55), RFIFOB(fd,56), RFIFOB(fd,57), RFIFOW(fd,58), ip);
@@ -3303,7 +3304,6 @@ int parse_login(int fd) {
 					server[account.account_id].maintenance = RFIFOW(fd,82);
 					server[account.account_id].new_ = RFIFOW(fd,84);
 					server_fd[account.account_id] = fd;
-                                        WFIFOHEAD(fd, 3);
 					WFIFOW(fd,0) = 0x2711;
 					WFIFOB(fd,2) = 0;
 					WFIFOSET(fd,3);

+ 50 - 22
src/login_sql/login.c

@@ -268,8 +268,9 @@ void send_GM_accounts(int fd) {
 			charif_sendallwos(-1, buf, len);
 		else
 		{
+			WFIFOHEAD(fd, len);
 			memcpy(WFIFOP(fd,0), buf, len);
-			WFIFOSET(fd,len);
+			WFIFOSET(fd, len);
 		}
 		return;
 }
@@ -548,6 +549,7 @@ int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
 	c = 0;
 	for(i = 0; i < MAX_SERVERS; i++) {
 		if ((fd = server_fd[i]) > 0 && fd != sfd) {
+			WFIFOHEAD(fd,len);
 			if (WFIFOSPACE(fd) < len) //Increase buffer size.
 				realloc_writefifo(fd, len);
 			memcpy(WFIFOP(fd,0), buf, len);
@@ -898,6 +900,7 @@ int parse_fromchar(int fd){
 	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
 	unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
 	char ip[16];
+	RFIFOHEAD(fd);
 
 	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
 
@@ -949,6 +952,7 @@ int parse_fromchar(int fd){
 				return 0;
 		{
 			int account_id;
+			WFIFOHEAD(fd,51);
 			account_id = RFIFOL(fd,2); // speed up
 			for(i=0;i<AUTH_FIFO_SIZE;i++){
 				if (auth_fifo[i].account_id == account_id &&
@@ -1016,11 +1020,11 @@ int parse_fromchar(int fd){
 					ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
 				}
 			}
-
-			// send some answer
+		{	// send some answer
+			WFIFOHEAD(fd,6);
 			WFIFOW(fd,0) = 0x2718;
 			WFIFOSET(fd,2);
-
+		}
 			RFIFOSKIP(fd,6);
 			break;
 
@@ -1032,6 +1036,7 @@ int parse_fromchar(int fd){
 			int account_id;
 			time_t connect_until_time = 0;
 			char email[40] = "";
+			WFIFOHEAD(fd,50);
 			account_id=RFIFOL(fd,2);
 			sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
 			if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1065,10 +1070,13 @@ int parse_fromchar(int fd){
 			ShowError("change GM error 0 %s\n", RFIFOP(fd, 8));
 
 			RFIFOSKIP(fd, RFIFOW(fd, 2));
+		{
+			WFIFOHEAD(fd, 10);
 			WFIFOW(fd, 0) = 0x2721;
 			WFIFOL(fd, 2) = RFIFOL(fd,4); // oldacc;
 			WFIFOL(fd, 6) = 0; // newacc;
 			WFIFOSET(fd, 10);
+		}
 			return 0;
 
 		// Map server send information to change an email of an account via char-server
@@ -1359,6 +1367,7 @@ int parse_fromchar(int fd){
 				int account_id = RFIFOL(fd, 2);
 				int char_id = RFIFOL(fd, 6);
 				int p;
+				WFIFOHEAD(fd,10000);
 				RFIFOSKIP(fd,10);
 				sprintf(tmpsql, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'",reg_db, account_id);
 				if (mysql_query(&mysql_handle, tmpsql)) {
@@ -1374,12 +1383,14 @@ int parse_fromchar(int fd){
 				WFIFOL(fd,4) = account_id;
 				WFIFOL(fd,8) = char_id;
 				WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
-				for(p = 13; (sql_row = mysql_fetch_row(sql_res));){
+				for(p = 13; (sql_row = mysql_fetch_row(sql_res)) && p < 9000;){
 					if (sql_row[0][0]) {
 						p+= sprintf(WFIFOP(fd,p), "%s", sql_row[0])+1; //We add 1 to consider the '\0' in place.
 						p+= sprintf(WFIFOP(fd,p), "%s", sql_row[1])+1;
 					}
 				}
+				if (p >= 9000)
+					ShowWarning("Too many account2 registries for AID %d. Some registries were not sent.\n", account_id);
 				WFIFOW(fd,2) = p;
 				WFIFOSET(fd,WFIFOW(fd,2));
 				mysql_free_result(sql_res);
@@ -1499,6 +1510,7 @@ int parse_login(int fd) {
 	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
 	unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
 	char ip[16];
+	RFIFOHEAD(fd);
 
 	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
 
@@ -1579,11 +1591,12 @@ int parse_login(int fd) {
 				//		    int gm_level = isGM(account.account_id); // removed by [zzo]
 
 				if (min_level_to_connect > account.level) {
+					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x81;
 					WFIFOB(fd,2) = 1; // 01 = Server closed
 					WFIFOSET(fd,3);
 				} else {
-
+					WFIFOHEAD(fd,47+32*MAX_SERVERS);
 					if (p[0] != 127 && log_login) {
 						sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, (unsigned int)ntohl(ipl), t_uid);
 						//query
@@ -1641,6 +1654,7 @@ int parse_login(int fd) {
 			} else {
 				char tmp_sql[512];
 				char error[64];
+				WFIFOHEAD(fd,23);
 				if (log_login)
 				{
 					sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %%s')", loginlog_db, (unsigned int)ntohl(ipl), t_uid, result);
@@ -1817,12 +1831,16 @@ int parse_login(int fd) {
 				session[fd]->eof = 1;
 				return 0;
 			}
-			ShowDebug("Request Password key -%s\n",md5key);
-			RFIFOSKIP(fd,2);
+		{
+			WFIFOHEAD(fd,4+md5keylen);
 			WFIFOW(fd,0)=0x01dc;
 			WFIFOW(fd,2)=4+md5keylen;
 			memcpy(WFIFOP(fd,4),md5key,md5keylen);
 			WFIFOSET(fd,WFIFOW(fd,2));
+
+			ShowDebug("Request Password key -%s\n",md5key);
+			RFIFOSKIP(fd,2);
+		}
 			break;
 
 		case 0x2710:	// request Char-server connection
@@ -1830,9 +1848,27 @@ int parse_login(int fd) {
 				return 0;
 			{
 				unsigned char* server_name;
+				WFIFOHEAD(fd, 3);
+				memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH);
+				account.userid[23] = '\0';
+				memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH);
+				account.passwd[23] = '\0';
+				account.passwdenc = 0;
+				server_name = RFIFOP(fd,60);
+				server_name[20] = '\0';
+				ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
+					server_name, RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
+					p[0], p[1], p[2], p[3]);
+				jstrescapecpy(t_uid,server_name);
 				if (log_login)
 				{
-					sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, (unsigned int)ntohl(ipl), RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
+					char t_login[50];
+					jstrescapecpy(t_login,account.userid);
+					sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')",
+						loginlog_db, (unsigned int)ntohl(ipl),
+						t_login, t_uid, t_uid,
+						RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57),
+						RFIFOW(fd, 58));
 
 					//query
 					if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1840,15 +1876,6 @@ int parse_login(int fd) {
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
 					}
 				}
-				ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
-					RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
-					p[0], p[1], p[2], p[3]);
-				memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH);
-				account.userid[23] = '\0';
-				memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH);
-				account.passwd[23] = '\0';
-				account.passwdenc = 0;
-				server_name = RFIFOP(fd,60);
 				result = mmo_auth(&account, fd);
 				//printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
 
@@ -1857,7 +1884,7 @@ int parse_login(int fd) {
 					memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
 					server[account.account_id].ip=RFIFOL(fd,54);
 					server[account.account_id].port=RFIFOW(fd,58);
-					memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
+					memcpy(server[account.account_id].name,server_name,20);
 					server[account.account_id].users=0;
 					server[account.account_id].maintenance=RFIFOW(fd,82);
 					server[account.account_id].new_=RFIFOW(fd,84);
@@ -1869,9 +1896,8 @@ int parse_login(int fd) {
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
 					}
 
-					jstrescapecpy(t_uid,server[account.account_id].name);
 					sprintf(tmpsql,"INSERT INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
-						account.account_id, server[account.account_id].name,0);
+						account.account_id, t_uid,0);
 					//query
 					if(mysql_query(&mysql_handle, tmpsql)) {
 						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
@@ -1894,6 +1920,8 @@ int parse_login(int fd) {
 			return 0;
 
 		case 0x7530:	// request Athena information
+		{
+			WFIFOHEAD(fd,10);
 			WFIFOW(fd,0)=0x7531;
 			WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
 			WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
@@ -1906,7 +1934,7 @@ int parse_login(int fd) {
 			RFIFOSKIP(fd,2);
 			ShowInfo ("Athena version check...\n");
 			break;
-
+		}
 		case 0x7532:
 			ShowStatus ("End of connection (ip: %s)" RETCODE, ip);
 			session[fd]->eof = 1;

+ 97 - 115
src/map/clif.c

@@ -275,13 +275,14 @@ int clif_send_sub(struct block_list *bl, va_list ap)
 	struct block_list *src_bl;
 	struct map_session_data *sd;
 	unsigned char *buf;
-	int len, type;
+	int len, type, fd;
 
 	nullpo_retr(0, bl);
 	nullpo_retr(0, ap);
 	nullpo_retr(0, sd = (struct map_session_data *)bl);
 
-	if (!sd->fd) //Avoid attempting to send to disconnected chars (may prevent buffer overrun errors?) [Skotlex]
+	fd = sd->fd;
+	if (!fd) //Don't send to disconnected clients.
 		return 0;
 
 	buf = va_arg(ap,unsigned char*);
@@ -307,29 +308,29 @@ int clif_send_sub(struct block_list *bl, va_list ap)
 		break;
 	}
 
-	if (session[sd->fd] != NULL) {
-		WFIFOHEAD(sd->fd, len);
-		if (WFIFOP(sd->fd,0) == buf) {
+	if (session[fd] != NULL) {
+		WFIFOHEAD(fd, len);
+		if (WFIFOP(fd,0) == buf) {
 			printf("WARNING: Invalid use of clif_send function\n");
 			printf("         Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0));
 			printf("         Please correct your code.\n");
 			// don't send to not move the pointer of the packet for next sessions in the loop
 		} else {
 			if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-				memcpy(WFIFOP(sd->fd,0), buf, len);
+				memcpy(WFIFOP(fd,0), buf, len);
 				//Check if hidden, better to modify the char's buffer than the
 				//given buffer to prevent intravision affecting the packet as 
 				//it's being received by everyone. [Skotlex]
 				/* New implementation... not quite correct yet as the client no longer
 				 * displays correctly the SI_INTRAVISION effect.
 				if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 )
-						&& bl != src_bl && WFIFOW(sd->fd,0) == 0x0196)
+						&& bl != src_bl && WFIFOW(fd,0) == 0x0196)
 				{	//New intravision method, just modify the status change/start packet. [Skotlex]
-					switch (WFIFOW(sd->fd,2)) {
+					switch (WFIFOW(fd,2)) {
 						case SI_HIDING:
 						case SI_CLOAKING:
 						case SI_CHASEWALK:
-							WFIFOW(sd->fd,2) = SI_INTRAVISION;
+							WFIFOW(fd,2) = SI_INTRAVISION;
 					}
 				}
 				*/
@@ -344,17 +345,17 @@ int clif_send_sub(struct block_list *bl, va_list ap)
 						{
 #if PACKETVER > 6
 							case 0x229:
-								WFIFOL(sd->fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK);
+								WFIFOL(fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK);
 								break;
 							case 0x22a:
 							case 0x22b:
 							case 0x22c:
-								WFIFOL(sd->fd,12) &=~(OPTION_HIDE|OPTION_CLOAK);
+								WFIFOL(fd,12) &=~(OPTION_HIDE|OPTION_CLOAK);
 								break;
 #endif
 #if PACKETVER > 3
 							case 0x119:
-								WFIFOW(sd->fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK);
+								WFIFOW(fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK);
 								break;
 							case 0x1d8:
 							case 0x1d9:
@@ -365,12 +366,12 @@ int clif_send_sub(struct block_list *bl, va_list ap)
 							case 0x7a:
 							case 0x7b:
 							case 0x7c:
-								WFIFOW(sd->fd,12) &=~(OPTION_HIDE|OPTION_CLOAK);
+								WFIFOW(fd,12) &=~(OPTION_HIDE|OPTION_CLOAK);
 								break;
 						}
 					}
 				}
-				WFIFOSET(sd->fd,len);
+				WFIFOSET(fd,len);
 			}
 		}
 	}
@@ -387,7 +388,7 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 	struct map_session_data *sd = NULL;
 	struct party_data *p = NULL;
 	struct guild *g = NULL;
-	int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
+	int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
 
 	if (type != ALL_CLIENT &&
 		type != CHAT_MAINCHAT) {
@@ -452,11 +453,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 				if (type == CHAT_WOS && cd->usersd[i] == sd)
 					continue;
 				if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-					if (cd->usersd[i]->fd >0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
+					if ((fd=cd->usersd[i]->fd) >0 && session[fd]) // Added check to see if session exists [PoW]
 					{
-						WFIFOHEAD(cd->usersd[i]->fd,len);
-						memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
-						WFIFOSET(cd->usersd[i]->fd,len);
+						WFIFOHEAD(fd,len);
+						memcpy(WFIFOP(fd,0), buf, len);
+						WFIFOSET(fd,len);
 					}
 				}
 			}
@@ -466,10 +467,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 		for(i=1; i<fd_max; i++) {
 			if (session[i] && session[i]->func_parse == clif_parse &&
 				(sd = (struct map_session_data*)session[i]->session_data) != NULL &&
-				sd->state.mainchat && sd->fd) {
-					WFIFOHEAD(sd->fd, len);								
-					memcpy(WFIFOP(sd->fd,0), buf, len);
-					WFIFOSET(sd->fd, len);								
+				sd->state.mainchat && (fd=sd->fd))
+			{
+				WFIFOHEAD(fd, len);								
+				memcpy(WFIFOP(fd,0), buf, len);
+				WFIFOSET(fd, len);								
 			}
 		}
 		break;
@@ -490,8 +492,8 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			for(i=0;i<MAX_PARTY;i++){
 				if ((sd = p->data[i].sd) == NULL)
 					continue;
-				if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0
-					|| session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
+				if (!(fd=sd->fd) || session[fd] == NULL || sd->state.auth == 0
+					|| session[fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
 					continue;
 				
 				if (sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS))
@@ -505,9 +507,9 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 					continue;
 				
 				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-					WFIFOHEAD(sd->fd,len);
-					memcpy(WFIFOP(sd->fd,0), buf, len);
-					WFIFOSET(sd->fd,len);
+					WFIFOHEAD(fd,len);
+					memcpy(WFIFOP(fd,0), buf, len);
+					WFIFOSET(fd,len);
 				}
 			}
 			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
@@ -516,12 +518,12 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 
 				if (session[i] && session[i]->func_parse == clif_parse &&
 					(sd = (struct map_session_data*)session[i]->session_data) != NULL &&
-				  	sd->state.auth && sd->fd && sd->partyspy == p->party.party_id)
+				  	sd->state.auth && (fd=sd->fd) && sd->partyspy == p->party.party_id)
 		  		{
-					if (sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-						WFIFOHEAD(sd->fd,len);
-						memcpy(WFIFOP(sd->fd,0), buf, len);
-						WFIFOSET(sd->fd,len);
+					if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+						WFIFOHEAD(fd,len);
+						memcpy(WFIFOP(fd,0), buf, len);
+						WFIFOSET(fd,len);
 					}
 				}
 			}
@@ -547,10 +549,10 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 		}
 		break;
 	case SELF:
-		if (sd && sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-			WFIFOHEAD(sd->fd,len);
-			memcpy(WFIFOP(sd->fd,0), buf, len);
-			WFIFOSET(sd->fd,len);
+		if (sd && (fd=sd->fd) && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
+			WFIFOHEAD(fd,len);
+			memcpy(WFIFOP(fd,0), buf, len);
+			WFIFOSET(fd,len);
 		}
 		break;
 
@@ -571,8 +573,8 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 		if (g) {
 			for(i = 0; i < g->max_member; i++) {
 				if ((sd = g->member[i].sd) != NULL) {
-					if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0
-						|| session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
+					if (!(fd=sd->fd) || session[fd] == NULL || sd->state.auth == 0
+						|| session[fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
 						continue;
 					
 					if (sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS))
@@ -586,9 +588,9 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 						continue;
 
 					if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-						WFIFOHEAD(sd->fd,len);
-						memcpy(WFIFOP(sd->fd,0), buf, len);
-						WFIFOSET(sd->fd,len);
+						WFIFOHEAD(fd,len);
+						memcpy(WFIFOP(fd,0), buf, len);
+						WFIFOSET(fd,len);
 					}
 				}
 			}
@@ -597,11 +599,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			for (i = 1; i < fd_max; i++){ // guildspy [Syrus22]
 				if (session[i] && session[i]->func_parse == clif_parse &&
 					(sd = (struct map_session_data*)session[i]->session_data) != NULL &&
-				  	sd->state.auth && sd->fd && sd->guildspy == g->guild_id) {
+				  	sd->state.auth && (fd=sd->fd) && sd->guildspy == g->guild_id) {
 					if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
-						WFIFOHEAD(sd->fd,len);
-						memcpy(WFIFOP(sd->fd,0), buf, len);
-						WFIFOSET(sd->fd,len);
+						WFIFOHEAD(fd,len);
+						memcpy(WFIFOP(fd,0), buf, len);
+						WFIFOSET(fd,len);
 					}
 				}
 			}
@@ -1590,12 +1592,11 @@ int clif_homskillinfoblock(struct map_session_data *sd) {	//[orn]
 
 void clif_homskillup(struct map_session_data *sd, int skill_num) {	//[orn]
 	struct homun_data *hd;
-	int fd,skillid;
-	WFIFOHEAD(sd->fd, packet_len_table[0x239]);
+	int fd=sd->fd, skillid;
+	WFIFOHEAD(fd, packet_len_table[0x239]);
 	nullpo_retv(sd);
 	skillid = skill_num - HM_SKILLBASE - 1;
 
-	fd=sd->fd;
 	hd=sd->hd;
 
 	WFIFOW(fd,0) = 0x239;
@@ -1685,12 +1686,8 @@ void clif_parse_HomMenu(int fd, struct map_session_data *sd) {	//[orn]
 
 int clif_hom_food(struct map_session_data *sd,int foodid,int fail)	//[orn]
 {
-	int fd;
-	WFIFOHEAD(sd->fd,packet_len_table[0x22f]);
-
-	nullpo_retr(0, sd);
-
-	fd=sd->fd;
+	int fd=sd->fd;
+	WFIFOHEAD(fd,packet_len_table[0x22f]);
 	WFIFOW(fd,0)=0x22f;
 	WFIFOB(fd,2)=fail;
 	WFIFOW(fd,3)=foodid;
@@ -1705,12 +1702,8 @@ int clif_hom_food(struct map_session_data *sd,int foodid,int fail)	//[orn]
  */
 int clif_walkok(struct map_session_data *sd)
 {
-	int fd;
-	WFIFOHEAD(sd->fd, packet_len_table[0x87]);
-
-	nullpo_retr(0, sd);
-
-	fd=sd->fd;
+	int fd=sd->fd;
+	WFIFOHEAD(fd, packet_len_table[0x87]);
 	WFIFOW(fd,0)=0x87;
 	WFIFOL(fd,2)=gettick();
 	WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y);
@@ -3922,7 +3915,7 @@ void clif_getareachar_char(struct map_session_data* sd,struct block_list *bl)
 {
 	struct unit_data *ud;
 	struct view_data *vd;
-	int len;
+	int len, fd = sd->fd;
 	
 	vd = status_get_viewdata(bl);
 
@@ -3933,24 +3926,24 @@ void clif_getareachar_char(struct map_session_data* sd,struct block_list *bl)
 	if (ud && ud->walktimer != -1)
 	{
 #if PACKETVER > 6
-		WFIFOHEAD(sd->fd, packet_len_table[0x22c]);
+		WFIFOHEAD(fd, packet_len_table[0x22c]);
 #elif PACKETVER > 3
-		WFIFOHEAD(sd->fd, packet_len_table[0x1da]);
+		WFIFOHEAD(fd, packet_len_table[0x1da]);
 #else
-		WFIFOHEAD(sd->fd, packet_len_table[0x7b]);
+		WFIFOHEAD(fd, packet_len_table[0x7b]);
 #endif
-		len = clif_set007b(bl,vd,ud,WFIFOP(sd->fd,0));
-		WFIFOSET(sd->fd,len);
+		len = clif_set007b(bl,vd,ud,WFIFOP(fd,0));
+		WFIFOSET(fd,len);
 	} else {
 #if PACKETVER > 6
-		WFIFOHEAD(sd->fd,packet_len_table[0x22a]);
+		WFIFOHEAD(fd,packet_len_table[0x22a]);
 #elif PACKETVER > 3
-		WFIFOHEAD(sd->fd,packet_len_table[0x1d8]);
+		WFIFOHEAD(fd,packet_len_table[0x1d8]);
 #else
-		WFIFOHEAD(sd->fd,packet_len_table[0x78]);
+		WFIFOHEAD(fd,packet_len_table[0x78]);
 #endif
-		len = clif_set0078(bl,vd,WFIFOP(sd->fd,0));
-		WFIFOSET(sd->fd,len);
+		len = clif_set0078(bl,vd,WFIFOP(fd,0));
+		WFIFOSET(fd,len);
 	}
 
 	if (vd->cloth_color)
@@ -4980,13 +4973,8 @@ int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst)
 //		The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex]
 //		WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_fix(NULL,dst,100,i+1,status->def_ele, status->ele_lv))<0?0:fix);
 
-	if(sd->status.party_id>0)
-		clif_send(buf,packet_len_table[0x18c],&sd->bl,PARTY_SAMEMAP);
-	else{
-		WFIFOHEAD(sd->fd,packet_len_table[0x18c]);
-		memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x18c]);
-		WFIFOSET(sd->fd,packet_len_table[0x18c]);
-	}
+	clif_send(buf,packet_len_table[0x18c],&sd->bl,
+		sd->status.party_id>0?PARTY_SAMEMAP:SELF);
 	return 0;
 }
 /*==========================================
@@ -7636,23 +7624,19 @@ void clif_parse_QuitGame(int fd,struct map_session_data *sd);
 
 int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type)
 {
-	nullpo_retr(0, tsd);
-
+	int fd = tsd->fd;
+	WFIFOHEAD(fd,packet_len_table[0x18b]);
 	if(type)
 		clif_GM_kickack(sd,tsd->status.account_id);
-	WFIFOHEAD(tsd->fd,packet_len_table[0x18b]);
-	WFIFOW(tsd->fd,0) = 0x18b;
-	WFIFOW(tsd->fd,2) = 0;
-	WFIFOSET(tsd->fd,packet_len_table[0x18b]);
-
-	if (tsd->fd)
-	{
-		ShowDebug("clif_GM_kick: Disconnecting session #%d\n", tsd->fd);
-		clif_setwaitclose(tsd->fd);
-	} else { //Player has no session attached, delete it right away. [Skotlex]
+	if (!fd) {
 		map_quit(tsd);
+		return 0;
 	}
 
+	WFIFOW(fd,0) = 0x18b;
+	WFIFOW(fd,2) = 0;
+	WFIFOSET(fd,packet_len_table[0x18b]);
+	clif_setwaitclose(fd);
 	return 0;
 }
 
@@ -9650,7 +9634,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
 	struct map_session_data *t_sd;
 	
 	RFIFOHEAD(fd);	
-	t_sd = map_id2sd(RFIFOL(sd->fd,2));
+	t_sd = map_id2sd(RFIFOL(fd,2));
 
 	if(!sd->chatID && clif_cant_act(sd))
 		return; //You can trade while in a chatroom.
@@ -9678,7 +9662,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
 void clif_parse_TradeAck(int fd,struct map_session_data *sd)
 {
 	RFIFOHEAD(fd);
-	trade_tradeack(sd,RFIFOB(sd->fd,2));
+	trade_tradeack(sd,RFIFOB(fd,2));
 }
 
 /*==========================================
@@ -9688,7 +9672,7 @@ void clif_parse_TradeAck(int fd,struct map_session_data *sd)
 void clif_parse_TradeAddItem(int fd,struct map_session_data *sd)
 {
 	RFIFOHEAD(fd);
-	trade_tradeadditem(sd,RFIFOW(sd->fd,2),RFIFOL(sd->fd,4));
+	trade_tradeadditem(sd,RFIFOW(fd,2),RFIFOL(fd,4));
 }
 
 /*==========================================
@@ -10431,7 +10415,7 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) {
 		return;
 	}
 
-	t_sd = map_id2sd(RFIFOL(sd->fd,2));
+	t_sd = map_id2sd(RFIFOL(fd,2));
 
 	// @noask [LuzZza]
 	if(t_sd && t_sd->state.noask) {
@@ -10698,7 +10682,7 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd) {
 		return;
 	}
 
-	t_sd = map_id2sd(RFIFOL(sd->fd,2));
+	t_sd = map_id2sd(RFIFOL(fd,2));
 
 	// @noask [LuzZza]
 	if(t_sd && t_sd->state.noask) {
@@ -10789,7 +10773,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) {
 		return;
 	}
 
-	t_sd = map_id2sd(RFIFOL(sd->fd,2));
+	t_sd = map_id2sd(RFIFOL(fd,2));
 
 	// @noask [LuzZza]
 	if(t_sd && t_sd->state.noask) {
@@ -10830,7 +10814,6 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) {
 void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) {
 	
 	struct map_session_data *t_sd;
-	
 	RFIFOHEAD(fd);	
 
 	if(map[sd->bl.m].flag.guildlock)
@@ -10839,7 +10822,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) {
 		return;
 	}
 
-	t_sd = map_id2sd(RFIFOL(sd->fd,2));
+	t_sd = map_id2sd(RFIFOL(fd,2));
 
 	// @noask [LuzZza]
 	if(t_sd && t_sd->state.noask) {
@@ -11296,7 +11279,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
  */
 void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int char_id, int online)
 {	//Toggles a single friend online/offline [Skotlex]
-	int i;
+	int i, fd = sd->fd;
 
 	//Seek friend.
 	for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id &&
@@ -11305,13 +11288,12 @@ void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int cha
 	if(i == MAX_FRIENDS || sd->status.friends[i].char_id == 0)
 		return; //Not found
 
-	WFIFOHEAD(sd->fd,packet_len_table[0x206]);
-	WFIFOW(sd->fd, 0) = 0x206;
-	WFIFOL(sd->fd, 2) = sd->status.friends[i].account_id;
-	WFIFOL(sd->fd, 6) = sd->status.friends[i].char_id;
-	WFIFOB(sd->fd,10) = !online; //Yeah, a 1 here means "logged off", go figure... 
-	
-	WFIFOSET(sd->fd, packet_len_table[0x206]);
+	WFIFOHEAD(fd,packet_len_table[0x206]);
+	WFIFOW(fd, 0) = 0x206;
+	WFIFOL(fd, 2) = sd->status.friends[i].account_id;
+	WFIFOL(fd, 6) = sd->status.friends[i].char_id;
+	WFIFOB(fd,10) = !online; //Yeah, a 1 here means "logged off", go figure... 
+	WFIFOSET(fd, packet_len_table[0x206]);
 }
 
 //Subfunction called from clif_foreachclient to toggle friends on/off [Skotlex]
@@ -11327,21 +11309,21 @@ int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap)
 
 //For sending the whole friends list.
 void clif_friendslist_send(struct map_session_data *sd) {
-	int i = 0, n;
+	int i = 0, n, fd = sd->fd;
 	
 	// Send friends list
-	WFIFOHEAD(sd->fd, MAX_FRIENDS * 32 + 4);
-	WFIFOW(sd->fd, 0) = 0x201;
+	WFIFOHEAD(fd, MAX_FRIENDS * 32 + 4);
+	WFIFOW(fd, 0) = 0x201;
 	for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++)
 	{
-		WFIFOL(sd->fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
-		WFIFOL(sd->fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
-		memcpy(WFIFOP(sd->fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
+		WFIFOL(fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
+		WFIFOL(fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
+		memcpy(WFIFOP(fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
 	}
 
 	if (i) {
-		WFIFOW(sd->fd,2) = 4 + 32 * i;
-		WFIFOSET(sd->fd, WFIFOW(sd->fd,2));
+		WFIFOW(fd,2) = 4 + 32 * i;
+		WFIFOSET(fd, WFIFOW(fd,2));
 	}
 	
 	for (n = 0; n < i; n++)

+ 5 - 3
src/map/mercenary.c

@@ -186,9 +186,11 @@ void merc_hom_skillup(struct homun_data *hd,int skillnum)
 			hd->homunculus.hskill[i].lv++ ;
 			hd->homunculus.skillpts-- ;
 			status_calc_homunculus(hd,0) ;
-			clif_homskillup(hd->master, skillnum) ;
-			clif_hominfo(hd->master,hd,0) ;
-			clif_homskillinfoblock(hd->master) ;
+			if (hd->master) {
+				clif_homskillup(hd->master, skillnum);
+				clif_hominfo(hd->master,hd,0);
+				clif_homskillinfoblock(hd->master);
+			}
 		}
 	}
 }

+ 1 - 1
src/map/mob.c

@@ -134,7 +134,7 @@ int mobdb_checkid(const int id)
  * Returns the view data associated to this mob class.
  *------------------------------------------
  */
-struct view_data * mob_get_viewdata(class_) 
+struct view_data * mob_get_viewdata(int class_) 
 {
 	if (mob_db(class_) == mob_dummy)
 		return 0;