Browse Source

- Fixed clif_parse not checking for func_parse before sending data to the connected clients. This in turn required various code-rewrites in:
- duel related messaging functions (added clif targets DUEL/DUEL_WOS).
- intif whisper to gm function
- day/night timers
- Rewrote the parse_console function to stop allocating/deallocating memory on every call.
- Modified chrif_charselectreq to receive the player's ip among the data.
- Added function clif_disp_message, which is the same as clif_disp_onlyself, except you can specify the targets (it sends a guild-chat packet)


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

skotlex 19 years ago
parent
commit
cd8587dc4d
10 changed files with 184 additions and 176 deletions
  1. 11 0
      Changelog-Trunk.txt
  2. 25 39
      src/map/atcommand.c
  3. 2 11
      src/map/chrif.c
  4. 1 1
      src/map/chrif.h
  5. 84 40
      src/map/clif.c
  6. 4 1
      src/map/clif.h
  7. 15 7
      src/map/intif.c
  8. 4 1
      src/map/mail.c
  9. 15 40
      src/map/map.c
  10. 23 36
      src/map/pc.c

+ 11 - 0
Changelog-Trunk.txt

@@ -4,6 +4,17 @@ 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/11
+	* Fixed clif_parse not checking for func_parse before sending data to the
+	  connected clients. This in turn required various code-rewrites in: [Skotlex]
+	- duel related messaging functions (added clif targets DUEL/DUEL_WOS).
+	- intif whisper to gm function
+	- day/night timers
+	- Rewrote the parse_console function to stop allocating/deallocating memory
+	  on every call.
+	- Modified chrif_charselectreq to receive the player's ip among the data.
+	* Added function clif_disp_message, which is the same as
+	  clif_disp_onlyself, except you can specify the targets (it sends a
+	  guild-chat packet) [Skotlex]
 	* Fixed the subele bonus (elemental reduction) being applied to the element
 	  of the attacker instead of the element of the attack. [Skotlex]
 	* mob skills now won't trigger on unit_stopwalking calls. [Skotlex]

+ 25 - 39
src/map/atcommand.c

@@ -978,21 +978,6 @@ int atcommand_config_read(const char *cfgName) {
  * Duel organizing functions [LuzZza]
  *------------------------------------------
  */
-void duel_msg_foreach_sameduel_wos(
-	const unsigned int did, struct map_session_data* sd, char *output)
-{
-	int i;
-	struct map_session_data* msg_sd;
-	
-	for(i=0; i<fd_max; i++)
-		if(session[i] && (msg_sd = (struct map_session_data *) session[i]->session_data) 
-		&& msg_sd->state.auth && msg_sd->duel_group == did && msg_sd != sd)
-
-			clif_disp_onlyself(msg_sd, output, strlen(output));
-
-	return;
-}
-
 void duel_savetime(struct map_session_data* sd) {
 
 	time_t timer;
@@ -1020,13 +1005,23 @@ int duel_checktime(struct map_session_data* sd) {
 	
 	return !(diff >= 0 && diff < battle_config.duel_time_interval);
 }
+static int duel_showinfo_sub(struct map_session_data* sd,va_list va) {
+	struct map_session_data *ssd = va_arg(va, struct map_session_data*);
+	int *p = va_arg(va, int*);
+	char output[256];
+
+	if (sd->duel_group != ssd->duel_group) return 0;
+	
+	sprintf(output, "      %d. %s", ++(*p), (unsigned char *)sd->status.name);
+	clif_disp_onlyself(ssd, output, strlen(output));
+	return 1;
+}
 
 int duel_showinfo(
 	const unsigned int did, struct map_session_data* sd)
 {
-	int i, p=0;
+	int p=0;
 	char output[256];
-	struct map_session_data* msg_sd;
 
 	if(duel_list[did].max_players_limit > 0)
 		sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
@@ -1041,15 +1036,7 @@ int duel_showinfo(
 			duel_list[did].members_count + duel_list[did].invites_count);
 
 	clif_disp_onlyself(sd, output, strlen(output));
-      
-	for(i=0; i<fd_max; i++)
-		if (session[i] && (msg_sd = (struct map_session_data *) session[i]->session_data) 
-			&& msg_sd->state.auth && msg_sd->duel_group == did) {
-
-			sprintf(output, "      %d. %s", ++p, (unsigned char *) msg_sd->status.name);
-			clif_disp_onlyself(sd, output, strlen(output));
-		}
-	    
+   clif_foreachclient(duel_showinfo_sub, sd, &p);
 	return 0;
 }
 
@@ -1085,7 +1072,7 @@ int duel_invite(
 	sprintf(output, msg_txt(373), // " -- Player %s invites %s to duel --"
 		(unsigned char *)sd->status.name, (unsigned char *)target_sd->status.name);
 
-	duel_msg_foreach_sameduel_wos(did, sd, output);
+	clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
 
 	target_sd->duel_invite = did;
 	duel_list[did].invites_count++;
@@ -1096,27 +1083,26 @@ int duel_invite(
 	return 0;
 }
 
+static int duel_leave_sub(struct map_session_data* sd,va_list va) {
+	int did = va_arg(va, int);
+	if (sd->duel_invite == did)
+		sd->duel_invite = 0;
+	return 0;
+}
+
 int duel_leave(
 	const unsigned int did, struct map_session_data* sd)
 {
-	int i;
 	char output[256];
-	struct map_session_data* msg_sd;
 	
 	// " <- Player %s has left duel --"
 	sprintf(output, msg_txt(375), (unsigned char *)sd->status.name);
-	duel_msg_foreach_sameduel_wos(did, sd, output);
+	clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
 	
 	duel_list[did].members_count--;
 	
 	if(duel_list[did].members_count == 0) {
-		for (i=0; i<fd_max; i++)
-			if (session[i] && (msg_sd = (struct map_session_data *) session[i]->session_data) 
-				&& msg_sd->state.auth && msg_sd->duel_invite == did && msg_sd != sd) {
-				
-				msg_sd->duel_invite = 0;
-			}
-			
+		clif_foreachclient(duel_leave_sub, did); 
 		duel_count--;
 	}
 	
@@ -1133,7 +1119,7 @@ int duel_accept(
 	
 	// " -> Player %s has accepted duel --"
 	sprintf(output, msg_txt(376), (unsigned char *)sd->status.name);
-	duel_msg_foreach_sameduel_wos(did, sd, output);
+	clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
 	
 	duel_list[did].members_count++;
 	sd->duel_group = sd->duel_invite;
@@ -1152,7 +1138,7 @@ int duel_reject(
 	
 	// " -- Player %s has rejected duel --"
 	sprintf(output, msg_txt(377), (unsigned char *)sd->status.name);
-	duel_msg_foreach_sameduel_wos(did, sd, output);
+	clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
 	
 	duel_list[did].invites_count--;
 	sd->duel_invite = 0;

+ 2 - 11
src/map/chrif.c

@@ -568,24 +568,15 @@ int auth_db_cleanup(int tid, unsigned int tick, int id, int data) {
  *
  *------------------------------------------
  */
-int chrif_charselectreq(struct map_session_data *sd)
+int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
 {
-	int i, s_ip;
-
 	nullpo_retr(-1, sd);
 
 	if( !sd || !sd->bl.id || !sd->login_id1 )
 		return -1;
 	chrif_check(-1);
 
-	s_ip = 0;
-	for(i = 0; i < fd_max; i++)
-		if (session[i] && session[i]->session_data == sd) {
-			s_ip = session[i]->client_addr.sin_addr.s_addr;
-			break;
-		}
-
-        WFIFOHEAD(char_fd, 18);
+	WFIFOHEAD(char_fd, 18);
 	WFIFOW(char_fd, 0) = 0x2b02;
 	WFIFOL(char_fd, 2) = sd->bl.id;
 	WFIFOL(char_fd, 6) = sd->login_id1;

+ 1 - 1
src/map/chrif.h

@@ -26,7 +26,7 @@ extern int other_mapserver_count;
 void chrif_authreq(struct map_session_data *);
 void chrif_authok(int fd);
 int chrif_save(struct map_session_data*, int flag);
-int chrif_charselectreq(struct map_session_data *);
+int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip);
 void check_fake_id(int fd, struct map_session_data *sd, int target_id);
 int chrif_changemapserver(struct map_session_data *sd,short map,int x,int y,int ip,short port);
 

+ 84 - 40
src/map/clif.c

@@ -232,8 +232,9 @@ int clif_countusers(void)
 	struct map_session_data *sd;
 
 	for(i = 0; i < fd_max; i++) {
-		if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth &&
-				!(battle_config.hide_GM_session && pc_isGM(sd)))
+		if (session[i] && session[i]->func_parse == clif_parse &&
+			(sd = (struct map_session_data*)session[i]->session_data) &&
+		  	sd->state.auth && !(battle_config.hide_GM_session && pc_isGM(sd)))
 			users++;
 	}
 	return users;
@@ -253,10 +254,9 @@ int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...) //rec
 	va_start(ap,func);
 
 	for(i = 0; i < fd_max; i++) {
-		if ( session[i] ) {
+		if ( session[i] && session[i]->func_parse == clif_parse) {
 			sd = (struct map_session_data*)session[i]->session_data;
-			if ( sd && session[i]->func_parse == clif_parse &&
-					sd->state.auth && !sd->state.waitingdisconnect )
+			if ( sd && sd->state.auth && !sd->state.waitingdisconnect )
 				func(sd, ap);
 		}
 	}
@@ -394,9 +394,11 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 	}
 
 	switch(type) {
-	case ALL_CLIENT: // 全クライアントに送信
+	case ALL_CLIENT: //All player clients.
 		for (i = 0; i < fd_max; i++) {
-			if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL && sd->state.auth) {
+			if (session[i] && session[i]->func_parse == clif_parse &&
+				(sd = (struct map_session_data *)session[i]->session_data) != NULL&&
+				sd->state.auth) {
 				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
 					WFIFOHEAD(i, len);
 					memcpy(WFIFOP(i,0), buf, len);
@@ -405,9 +407,10 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			}
 		}
 		break;
-	case ALL_SAMEMAP: // 同じマップの全クライアントに送信
+	case ALL_SAMEMAP: //All players on the same map
 		for(i = 0; i < fd_max; i++) {
-			if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
+			if (session[i] && session[i]->func_parse == clif_parse &&
+				(sd = (struct map_session_data*)session[i]->session_data) != NULL &&
 				sd->state.auth && sd->bl.m == bl->m) {
 				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
 					WFIFOHEAD(i,len);
@@ -457,7 +460,8 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 		break;
 	case CHAT_MAINCHAT: //[LuzZza]
 		for(i=1; i<fd_max; i++) {
-			if(session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
+			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);
@@ -465,16 +469,16 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			}
 		}
 		break;
-	case PARTY_AREA:		// 同じ画面内の全パーティーメンバに送信
-	case PARTY_AREA_WOS:	// 自分以外の同じ画面内の全パーティーメンバに送信
+	case PARTY_AREA:
+	case PARTY_AREA_WOS:
 		x0 = bl->x - AREA_SIZE;
 		y0 = bl->y - AREA_SIZE;
 		x1 = bl->x + AREA_SIZE;
 		y1 = bl->y + AREA_SIZE;
-	case PARTY:				// 全パーティーメンバに送信
-	case PARTY_WOS:			// 自分以外の全パーティーメンバに送信
-	case PARTY_SAMEMAP:		// 同じマップの全パーティーメンバに送信
-	case PARTY_SAMEMAP_WOS:	// 自分以外の同じマップの全パーティーメンバに送信
+	case PARTY:
+	case PARTY_WOS:
+	case PARTY_SAMEMAP:
+	case PARTY_SAMEMAP_WOS:
 		if (sd && sd->status.party_id)
 			p = party_search(sd->status.party_id);
 			
@@ -505,18 +509,39 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
 				break;
 			for (i = 1; i < fd_max; i++){ // partyspy [Syrus22]
-				if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->partyspy) {
-					if (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 (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)
+		  		{
+					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);
 					}
 				}
 			}
 		}
 		break;
+	case DUEL:
+	case DUEL_WOS:
+		if (!sd || !sd->duel_group) break; //Invalid usage.
+
+		x0 = sd->duel_group; //Here we use x0 to store the duel group. [Skotlex]
+		for (i = 0; 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.auth && sd->duel_group == x0) {
+				if (type == DUEL_WOS && bl->id == sd->bl.id)
+					continue;
+				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { 
+					WFIFOHEAD(i, len);
+					memcpy(WFIFOP(i,0), buf, len);
+					WFIFOSET(i,len);
+				}
+			}
+		}
+		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);
@@ -566,13 +591,13 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
 			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
 				break;
 			for (i = 1; i < fd_max; i++){ // guildspy [Syrus22]
-				if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->guildspy) {
-					if (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);
-						}
+				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) {
+					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);
 					}
 				}
 			}
@@ -1324,7 +1349,9 @@ int clif_weather(int m) {
 	struct map_session_data *sd=NULL;
 
 	for(i = 0; i < fd_max; i++) {
-		if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == m) {
+		if (session[i] && session[i]->func_parse == clif_parse &&	
+			(sd = session[i]->session_data) != NULL &&
+		  	sd->state.auth && sd->bl.m == m) {
 			clif_weather_check(sd);
 		}
 	}
@@ -1696,7 +1723,8 @@ static int clif_delayquit(int tid, unsigned int tick, int id, int data) {
 void clif_quitsave(int fd,struct map_session_data *sd)
 {
 	if (sd->state.waitingdisconnect || //Was already waiting to be disconnected.
-		!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
+		!battle_config.prevent_logout ||
+	  	DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
 		map_quit(sd);
 	else if (sd->fd)
 	{	//Disassociate session from player (session is deleted after this function was called)
@@ -6069,7 +6097,9 @@ int clif_hpmeter(struct map_session_data *sd)
 		WBUFW(buf,8) = sd->battle_status.max_hp;
 	}
 	for (i = 0; i < fd_max; i++) {
-		if (session[i] && (sd2 = (struct map_session_data*)session[i]->session_data) &&  sd != sd2 && sd2->state.auth) {
+		if (session[i] && session[i]->func_parse == clif_parse &&	
+			(sd2 = (struct map_session_data*)session[i]->session_data) &&
+			sd != sd2 && sd2->state.auth) {
 			if (sd2->bl.m != sd->bl.m || 
 				sd2->bl.x < x0 || sd2->bl.y < y0 ||
 				sd2->bl.x > x1 || sd2->bl.y > y1 ||
@@ -7438,6 +7468,21 @@ int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
 	return 1;
 }
 
+/*==========================================
+ * Displays a message using the guild-chat colors to the specified targets. [Skotlex]
+ *------------------------------------------
+ */
+void clif_disp_message(struct block_list *src, char *mes, int len, int type)
+{
+	unsigned char buf[1024];
+	if (!len) return;
+	WBUFW(buf, 0) = 0x17f;
+	WBUFW(buf, 2) = len + 5;
+	memcpy(WBUFP(buf,4), mes, len);
+	clif_send(buf, WBUFW(buf,2), src, type);
+	return;
+}
+
 /*==========================================
  *
  *------------------------------------------
@@ -8020,10 +8065,10 @@ void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
 			//Check for characters with no connection (includes those that are using autotrade) [durf],[Skotlex]
 			if (old_sd->state.finalsave)
 				; //Ack has not arrived yet from char-server, be patient!
-			else if (!old_sd->fd)
-				map_quit(old_sd);
-			else 
+			else if (old_sd->fd)
 				clif_authfail_fd(old_sd->fd, 2); // same id
+			else 
+				map_quit(old_sd);
 			clif_authfail_fd(fd, 8); // still recognizes last connection
 		} else {
 			sd = (struct map_session_data*)aCalloc(1, sizeof(struct map_session_data));
@@ -8837,11 +8882,10 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
 	case 0x01:
 		/*	Rovert's Prevent logout option - Fixed [Valaris]	*/
 		if (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
-		{
-			//map_quit(sd);	//A clif_quitsave is sent inmediately after this, so no need to quit yet. [Skotlex]
-			chrif_charselectreq(sd);
+		{	//Send to char-server for character selection.
+			chrif_charselectreq(sd, session[fd]->client_addr.sin_addr.s_addr);
 		} else {
-                        WFIFOHEAD(fd,packet_len_table[0x18b]);
+			WFIFOHEAD(fd,packet_len_table[0x18b]);
 			WFIFOW(fd,0)=0x18b;
 			WFIFOW(fd,2)=1;
 

+ 4 - 1
src/map/clif.h

@@ -43,7 +43,9 @@ enum {
 	GUILD_SAMEMAP_WOS,
 	GUILD_AREA,
 	GUILD_AREA_WOS,	// end additions [Valaris]
-	SELF
+	SELF,
+	DUEL,
+	DUEL_WOS
 };
 
 extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
@@ -297,6 +299,7 @@ int clif_guild_xy_remove(struct map_session_data *sd);
 // atcommand
 int clif_displaymessage(const int fd,char* mes);
 int clif_disp_onlyself(struct map_session_data *sd,char *mes,int len);
+void clif_disp_message(struct block_list *src, char *mes, int len, int type);
 int clif_GMmessage(struct block_list *bl,char* mes,int len,int flag);
 void clif_MainChatMessage(char* message); //luzza
 int clif_announce(struct block_list *bl, char* mes, int len, unsigned long color, int flag);

+ 15 - 7
src/map/intif.c

@@ -831,10 +831,22 @@ int intif_parse_WisEnd(int fd) {
 	return 0;
 }
 
+static int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va) {
+	int min_gm_level = va_arg(va, int);
+	char *wisp_name;
+	char *message;
+	int len;
+	if (pc_isGM(sd) < min_gm_level) return 0;
+	clif_wis_message(sd->fd, wisp_name, message, len);
+	wisp_name = va_arg(va, char*);
+	message = va_arg(va, char*);
+	len = va_arg(va, int);
+	return 1;
+}
+
 // Received wisp message from map-server via char-server for ALL gm
 int mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
-	int i, min_gm_level, mes_len;
-	struct map_session_data *pl_sd;
+	int min_gm_level, mes_len;
 	char Wisp_name[NAME_LENGTH];
 	char mbuf[255];
 	char *message;
@@ -849,14 +861,10 @@ int mapif_parse_WisToGM(int fd) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B
 	memcpy(message, RFIFOP(fd,30), mes_len);
 	message[mes_len-1] = '\0';
 	// information is sended to all online GM
-	for (i = 0; i < fd_max; i++)
-		if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth)
-			if (pc_isGM(pl_sd) >= min_gm_level)
-				clif_wis_message(i, Wisp_name, message, strlen(message) + 1);
+	clif_foreachclient(mapif_parse_WisToGM_sub, min_gm_level, Wisp_name, message, mes_len);
 
 	if (message != mbuf)
 		aFree(message);
-
 	return 0;
 }
 

+ 4 - 1
src/map/mail.c

@@ -330,7 +330,10 @@ int mail_check_timer(int tid,unsigned int tick,int id,int data)
 
 		while ((mail_row = mysql_fetch_row(mail_res))) {
 			for (i = 0; i < fd_max; i++) {
-				if (session[i] && (sd = (struct map_session_data *) session[i]->session_data) && sd->state.auth){
+				if (session[i] && session[i]->func_parse == clif_parse &&	
+					(sd = (struct map_session_data *) session[i]->session_data) &&
+					sd->state.auth)
+				{
 					if(pc_isGM(sd) < 80 && sd->mail_counter > 0)
 						sd->mail_counter--;
 					if(sd->status.account_id==atoi(mail_row[0]))

+ 15 - 40
src/map/map.c

@@ -1693,11 +1693,10 @@ int map_quit(struct map_session_data *sd) {
 	}
 	if(sd->fd)
   	{	//Player will be free'd on save-ack. [Skotlex]
-		if (session[sd->fd] && session[sd->fd]->session_data == sd)
+		if (session[sd->fd])
 			session[sd->fd]->session_data = NULL;
 		sd->fd = 0;
 	}
-
 	return 0;
 }
 
@@ -3195,54 +3194,38 @@ static int char_ip_set = 0;
  *------------------------------------------
  */
 int parse_console(char *buf) {
-	char *type,*command,*map, *buf2;
+	char type[64],command[64],map[64], buf2[72];
 	int x = 0, y = 0;
 	int m, n;
-	struct map_session_data *sd;
-
-	sd = (struct map_session_data*)aCalloc(sizeof(struct map_session_data), 1);
-
-	sd->fd = 0;
-	strcpy( sd->status.name , "console");
+	struct map_session_data sd;
 
-	type = (char *)aCallocA(64,1);
-	command = (char *)aCallocA(64,1);
-	map = (char *)aCallocA(64,1);
-	buf2 = (char *)aCallocA(72,1);
+	memset(&sd, 0, sizeof(struct map_session_data));
+	strcpy( sd.status.name , "console");
 
 	if ( ( n = sscanf(buf, "%[^:]:%[^:]:%99s %d %d[^\n]", type , command , map , &x , &y )) < 5 )
 		if ( ( n = sscanf(buf, "%[^:]:%[^\n]", type , command )) < 2 )
 			n = sscanf(buf,"%[^\n]",type);
 
 	if ( n == 5 ) {
-		if (x <= 0) {
-			x = rand() % 399 + 1;
-			sd->bl.x = x;
-		} else {
-			sd->bl.x = x;
-		}
-
-		if (y <= 0) {
-			y = rand() % 399 + 1;
-			sd->bl.y = y;
-		} else {
-			sd->bl.y = y;
-		}
-
 		m = map_mapname2mapid(map);
-		if ( m >= 0 )
-			sd->bl.m = m;
-		else {
+		if ( m < 0 ) {
 			ShowWarning("Console: Unknown map\n");
-			goto end;
+			return 0;
 		}
+		sd.bl.m = m;
+		map_search_freecell(&sd.bl, m, &sd.bl.x, &sd.bl.y, -1, -1, 0); 
+		if (x > 0)
+			sd.bl.x = x;
+
+		if (y > 0)
+			sd.bl.y = y;
 	}
 
 	ShowInfo("Type of command: %s || Command: %s || Map: %s Coords: %d %d\n",type,command,map,x,y);
 
 	if ( strcmpi("admin",type) == 0 && n == 5 ) {
 		sprintf(buf2,"console: %s",command);
-		if( is_atcommand(sd->fd,sd,buf2,99) == AtCommand_None )
+		if( is_atcommand(sd.fd,&sd,buf2,99) == AtCommand_None )
 			printf("Console: not atcommand\n");
 	} else if ( strcmpi("server",type) == 0 && n == 2 ) {
 		if ( strcmpi("shutdown", command) == 0 || strcmpi("exit",command) == 0 || strcmpi("quit",command) == 0 ) {
@@ -3259,14 +3242,6 @@ int parse_console(char *buf) {
 		printf("server:shutdown\n");
 	}
 
-	end:
-	aFree(buf);
-	aFree(type);
-	aFree(command);
-	aFree(map);
-	aFree(buf2);
-	aFree(sd);
-
 	return 0;
 }
 

+ 23 - 36
src/map/pc.c

@@ -7105,7 +7105,16 @@ int pc_read_gm_account(int fd)
 	}
 	return GM_num;
 }
-
+static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
+{
+	if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled)
+  	{	//Night/day state does not match.
+		clif_status_load(&sd->bl, SI_NIGHT, night_flag); //New night effect by dynamix [Skotlex]
+		sd->state.night = night_flag;
+		return 1;
+	}
+	return 0;
+}
 /*================================================
  * timer to do the day [Yor]
  * data: 0 = called by timer, 1 = gmcommand/script
@@ -7114,29 +7123,17 @@ int pc_read_gm_account(int fd)
 int map_day_timer(int tid, unsigned int tick, int id, int data)
 {
 	char tmp_soutput[1024];
-	struct map_session_data *pl_sd;
 
 	if (data == 0 && battle_config.day_duration <= 0)	// if we want a day
 		return 0;
 	
-	if (night_flag != 0) {
-		int i;
-		night_flag = 0; // 0=day, 1=night [Yor]
-
-		for(i = 0; i < fd_max; i++) {
-			if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && pl_sd->fd)
-			{
-				if (pl_sd->state.night) {
-					clif_status_load(&pl_sd->bl, SI_NIGHT, 0); //New night effect by dynamix [Skotlex]
-					pl_sd->state.night = 0;
-				}
-			}
-		}
-
-		strcpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60)); // The day has arrived!
-		intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
-	}
-
+	if (!night_flag)
+		return 0; //Already day.
+	
+	night_flag = 0; // 0=day, 1=night [Yor]
+	clif_foreachclient(pc_daynight_timer_sub);
+	strcpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60)); // The day has arrived!
+	intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
 	return 0;
 }
 
@@ -7148,27 +7145,17 @@ int map_day_timer(int tid, unsigned int tick, int id, int data)
 int map_night_timer(int tid, unsigned int tick, int id, int data)
 {
 	char tmp_soutput[1024];
-	struct map_session_data *pl_sd;
 
 	if (data == 0 && battle_config.night_duration <= 0)	// if we want a night
 		return 0;
 	
-	if (night_flag == 0) {
-		int i;
-		night_flag = 1; // 0=day, 1=night [Yor]
-		for(i = 0; i < fd_max; i++) {
-			if (session[i] && (pl_sd = (struct map_session_data *) session[i]->session_data) && pl_sd->state.auth && pl_sd->fd)
-			{
-				if (!pl_sd->state.night && map[pl_sd->bl.m].flag.nightenabled) {
-					clif_status_load(&pl_sd->bl, SI_NIGHT, 1); //New night effect by dynamix [Skotlex]
-					pl_sd->state.night = 1;
-				}
-			}
-		}
-		strcpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59)); // The night has fallen...
-		intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
-	}
+	if (night_flag)
+		return 0; //Already nigth.
 
+	night_flag = 1; // 0=day, 1=night [Yor]
+	clif_foreachclient(pc_daynight_timer_sub);
+	strcpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59)); // The night has fallen...
+	intif_GMmessage(tmp_soutput, strlen(tmp_soutput) + 1, 0);
 	return 0;
 }