Browse Source

Cleaned up whisper code between map-servers (#2763)

Fixes #2760
Fixes #2762

Thanks to @LunarSHINING
Lemongrass3110 7 years ago
parent
commit
3a8c8a9da4
5 changed files with 77 additions and 67 deletions
  1. 37 40
      src/char/inter.cpp
  2. 15 6
      src/map/clif.cpp
  3. 1 1
      src/map/clif.hpp
  4. 23 19
      src/map/intif.cpp
  5. 1 1
      src/map/pc.cpp

+ 37 - 40
src/char/inter.cpp

@@ -66,9 +66,9 @@ int inter_recv_packet_length[] = {
 };
 
 struct WisData {
-	int id, fd, count, len;
+	int id, fd, count, len, gmlvl;
 	unsigned long tick;
-	unsigned char src[NAME_LENGTH], dst[NAME_LENGTH], msg[512];
+	char src[NAME_LENGTH], dst[NAME_LENGTH], msg[512];
 };
 static DBMap* wis_db = NULL; // int wis_id -> struct WisData*
 static int wis_dellist[WISDELLIST_MAX], wis_delnum;
@@ -1045,31 +1045,22 @@ int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short
 int mapif_wis_message(struct WisData *wd)
 {
 	unsigned char buf[2048];
-	if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex]
+	int headersize = 12 + 2 * NAME_LENGTH;
+
+	if (wd->len > 2047-headersize) wd->len = 2047-headersize; //Force it to fit to avoid crashes. [Skotlex]
 
 	WBUFW(buf, 0) = 0x3801;
-	WBUFW(buf, 2) = 56 +wd->len;
+	WBUFW(buf, 2) = headersize+wd->len;
 	WBUFL(buf, 4) = wd->id;
-	memcpy(WBUFP(buf, 8), wd->src, NAME_LENGTH);
-	memcpy(WBUFP(buf,32), wd->dst, NAME_LENGTH);
-	memcpy(WBUFP(buf,56), wd->msg, wd->len);
+	WBUFL(buf, 8) = wd->gmlvl;
+	safestrncpy(WBUFCP(buf,12), wd->src, NAME_LENGTH);
+	safestrncpy(WBUFCP(buf,12 + NAME_LENGTH), wd->dst, NAME_LENGTH);
+	safestrncpy(WBUFCP(buf,12 + 2*NAME_LENGTH), wd->msg, wd->len);
 	wd->count = chmapif_sendall(buf,WBUFW(buf,2));
 
 	return 0;
 }
 
-// Wis sending result
-int mapif_wis_end(struct WisData *wd, int flag)
-{
-	unsigned char buf[27];
-
-	WBUFW(buf, 0)=0x3802;
-	memcpy(WBUFP(buf, 2),wd->src,24);
-	WBUFB(buf,26)=flag;
-	chmapif_send(wd->fd,buf,27);
-	return 0;
-}
-
 // Send the requested account_reg
 int mapif_account_reg_reply(int fd, uint32 account_id, uint32 char_id, int type)
 {
@@ -1122,7 +1113,7 @@ int check_ttl_wisdata(void)
 			struct WisData *wd = (struct WisData*)idb_get(wis_db, wis_dellist[i]);
 			ShowWarning("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst);
 			// removed. not send information after a timeout. Just no answer for the player
-			//mapif_wis_end(wd, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+			//mapif_wis_reply(wd->fd, wd->src, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 			idb_remove(wis_db, wd->id);
 		}
 	} while(wis_delnum >= WISDELLIST_MAX);
@@ -1156,6 +1147,17 @@ int mapif_parse_broadcast_item(int fd) {
 	return 0;
 }
 
+// Wis sending result
+// flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+int mapif_wis_reply( int mapserver_fd, char* target, uint8 flag ){
+	unsigned char buf[27];
+
+	WBUFW(buf, 0) = 0x3802;
+	safestrncpy(WBUFCP(buf, 2), target, NAME_LENGTH);
+	WBUFB(buf,26) = flag;
+
+	return chmapif_send(mapserver_fd, buf, 27);
+}
 
 // Wisp/page request to send
 int mapif_parse_WisRequest(int fd)
@@ -1165,19 +1167,20 @@ int mapif_parse_WisRequest(int fd)
 	char esc_name[NAME_LENGTH*2+1];// escaped name
 	char* data;
 	size_t len;
+	int headersize = 8+2*NAME_LENGTH;
 
 
 	if ( fd <= 0 ) {return 0;} // check if we have a valid fd
 
-	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
+	if (RFIFOW(fd,2)-headersize >= sizeof(wd->msg)) {
 		ShowWarning("inter: Wis message size too long.\n");
 		return 0;
-	} else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
+	} else if (RFIFOW(fd,2)-headersize <= 0) { // normaly, impossible, but who knows...
 		ShowError("inter: Wis message doesn't exist.\n");
 		return 0;
 	}
 
-	safestrncpy(name, RFIFOCP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
+	safestrncpy(name, RFIFOCP(fd,8+NAME_LENGTH), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
 
 	Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
 	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", schema_config.char_db, esc_name) )
@@ -1186,11 +1189,7 @@ int mapif_parse_WisRequest(int fd)
 	// search if character exists before to ask all map-servers
 	if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
 	{
-		unsigned char buf[27];
-		WBUFW(buf, 0) = 0x3802;
-		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
-		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
-		chmapif_send(fd, buf, 27);
+		mapif_wis_reply(fd, RFIFOCP(fd, 8), 1);
 	}
 	else
 	{// Character exists. So, ask all map-servers
@@ -1199,13 +1198,9 @@ int mapif_parse_WisRequest(int fd)
 		memset(name, 0, NAME_LENGTH);
 		memcpy(name, data, zmin(len, NAME_LENGTH));
 		// if source is destination, don't ask other servers.
-		if( strncmp(RFIFOCP(fd,4), name, NAME_LENGTH) == 0 )
+		if( strncmp(RFIFOCP(fd,8), name, NAME_LENGTH) == 0 )
 		{
-			uint8 buf[27];
-			WBUFW(buf, 0) = 0x3802;
-			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
-			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
-			chmapif_send(fd, buf, 27);
+			mapif_wis_reply(fd, RFIFOCP(fd, 8), 1);
 		}
 		else
 		{
@@ -1218,10 +1213,11 @@ int mapif_parse_WisRequest(int fd)
 
 			wd->id = ++wisid;
 			wd->fd = fd;
-			wd->len= RFIFOW(fd,2)-52;
-			memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
-			memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
-			memcpy(wd->msg, RFIFOP(fd,52), wd->len);
+			wd->len= RFIFOW(fd,2)-headersize;
+			wd->gmlvl = RFIFOL(fd,4);
+			safestrncpy(wd->src, RFIFOCP(fd,8), NAME_LENGTH);
+			safestrncpy(wd->dst, RFIFOCP(fd,8+NAME_LENGTH), NAME_LENGTH);
+			safestrncpy(wd->msg, RFIFOCP(fd,8+2*NAME_LENGTH), wd->len);
 			wd->tick = gettick();
 			idb_put(wis_db, wd->id, wd);
 			mapif_wis_message(wd);
@@ -1236,7 +1232,8 @@ int mapif_parse_WisRequest(int fd)
 // Wisp/page transmission result
 int mapif_parse_WisReply(int fd)
 {
-	int id, flag;
+	int id;
+	uint8 flag;
 	struct WisData *wd;
 
 	id = RFIFOL(fd,2);
@@ -1246,7 +1243,7 @@ int mapif_parse_WisReply(int fd)
 		return 0;	// This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
 
 	if ((--wd->count) <= 0 || flag != 1) {
-		mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+		mapif_wis_reply(wd->fd, wd->src, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
 		idb_remove(wis_db, id);
 	}
 

+ 15 - 6
src/map/clif.cpp

@@ -6445,8 +6445,13 @@ void clif_upgrademessage(int fd, int result, unsigned short item_id)
 /// Whisper is transmitted to the destination player (ZC_WHISPER).
 /// 0097 <packet len>.W <nick>.24B <message>.?B
 /// 0097 <packet len>.W <nick>.24B <isAdmin>.L <message>.?B (PACKETVER >= 20091104)
-void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len)
-{
+void clif_wis_message(struct map_session_data* sd, const char* nick, const char* mes, int mes_len, int gmlvl){
+	int fd;
+
+	nullpo_retv(sd);
+
+	fd = sd->fd;
+
 #if PACKETVER < 20091104
 	WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4);
 	WFIFOW(fd,0) = 0x97;
@@ -6461,7 +6466,11 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len)
 	WFIFOW(fd,0) = 0x97;
 	WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8;
 	safestrncpy(WFIFOCP(fd,4), nick, NAME_LENGTH);
-	WFIFOL(fd,28) = (ssd && pc_get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char
+	// If it is not a message from the server or a player from another map-server
+	if( ssd ){
+		gmlvl = pc_get_group_level(ssd);
+	}
+	WFIFOL(fd, 28) = (gmlvl == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char
 	safestrncpy(WFIFOCP(fd,32), mes, mes_len);
 	WFIFOSET(fd,WFIFOW(fd,2));
 #endif
@@ -11222,7 +11231,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
 		// if there are 'Test' player on an other map-server and 'test' player on this map-server,
 		// and if we ask for 'Test', we must not contact 'test' player
 		// so, we send information to inter-server, which is the only one which decide (and copy correct name).
-		intif_wis_message(sd, target, message, strlen(message));
+		intif_wis_message(sd, target, message, strlen(message) + 1);
 		return;
 	}
 
@@ -11238,7 +11247,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
 	// if player is autotrading
 	if (dstsd->state.autotrade == 1){
 		safesnprintf(output,sizeof(output),"%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name);
-		clif_wis_message(fd, wisp_server_name, output, strlen(output) + 1);
+		clif_wis_message(sd, wisp_server_name, output, strlen(output) + 1, 0);
 		return;
 	}
 
@@ -11255,7 +11264,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
 	clif_wis_end(fd, 0); // 0: success to send wisper
 
 	// Normal message
-	clif_wis_message(dstsd->fd, sd->status.name, message, strlen(message)+1 );
+	clif_wis_message(dstsd, sd->status.name, message, strlen(message)+1, 0);
 }
 
 

+ 1 - 1
src/map/clif.hpp

@@ -688,7 +688,7 @@ void clif_status_change(struct block_list *bl, int type, int flag, int tick, int
 void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, int tick, int val1, int val2, int val3);
 void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target);
 
-void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len);
+void clif_wis_message(struct map_session_data* sd, const char* nick, const char* mes, int mes_len, int gmlvl);
 void clif_wis_end(int fd, int result);
 
 void clif_solved_charname(int fd, int charid, const char* name);

+ 23 - 19
src/map/intif.cpp

@@ -303,6 +303,8 @@ int intif_main_message(struct map_session_data* sd, const char* message)
  */
 int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len)
 {
+	int headersize = 8 + 2 * NAME_LENGTH;
+
 	nullpo_ret(sd);
 	if (CheckForCharServer())
 		return 0;
@@ -313,12 +315,13 @@ int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int me
 		return 0;
 	}
 
-	WFIFOHEAD(inter_fd,mes_len + 52);
+	WFIFOHEAD(inter_fd,mes_len + headersize);
 	WFIFOW(inter_fd,0) = 0x3001;
-	WFIFOW(inter_fd,2) = mes_len + 52;
-	memcpy(WFIFOP(inter_fd,4), sd->status.name, NAME_LENGTH);
-	memcpy(WFIFOP(inter_fd,4+NAME_LENGTH), nick, NAME_LENGTH);
-	memcpy(WFIFOP(inter_fd,4+2*NAME_LENGTH), mes, mes_len);
+	WFIFOW(inter_fd,2) = mes_len + headersize;
+	WFIFOL(inter_fd,4) = pc_get_group_level(sd);
+	safestrncpy(WFIFOCP(inter_fd,8), sd->status.name, NAME_LENGTH);
+	safestrncpy(WFIFOCP(inter_fd,8+NAME_LENGTH), nick, NAME_LENGTH);
+	safestrncpy(WFIFOCP(inter_fd,8+2*NAME_LENGTH), mes, mes_len);
 	WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
 
 	if (battle_config.etc_log)
@@ -333,7 +336,7 @@ int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int me
  * @param flag : 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  * @return 0=no char-serv connected, 1=msg sent
  */
-int intif_wis_replay(int id, int flag)
+int intif_wis_reply(int id, int flag)
 {
 	if (CheckForCharServer())
 		return 0;
@@ -344,7 +347,7 @@ int intif_wis_replay(int id, int flag)
 	WFIFOSET(inter_fd,7);
 
 	if (battle_config.etc_log)
-		ShowInfo("intif_wis_replay: id: %d, flag:%d\n", id, flag);
+		ShowInfo("intif_wis_reply: id: %d, flag:%d\n", id, flag);
 
 	return 1;
 }
@@ -365,9 +368,9 @@ int intif_wis_message_to_gm(char *wisp_name, int permission, char *mes)
 	WFIFOHEAD(inter_fd, mes_len + 8 + NAME_LENGTH);
 	WFIFOW(inter_fd,0) = 0x3003;
 	WFIFOW(inter_fd,2) = mes_len + 32;
-	memcpy(WFIFOP(inter_fd,4), wisp_name, NAME_LENGTH);
+	safestrncpy(WFIFOCP(inter_fd,4), wisp_name, NAME_LENGTH);
 	WFIFOL(inter_fd,4+NAME_LENGTH) = permission;
-	memcpy(WFIFOP(inter_fd,8+NAME_LENGTH), mes, mes_len);
+	safestrncpy(WFIFOCP(inter_fd,8+NAME_LENGTH), mes, mes_len);
 	WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
 
 	if (battle_config.etc_log)
@@ -1245,22 +1248,23 @@ int intif_parse_WisMessage(int fd)
 	struct map_session_data* sd;
 	char *wisp_source;
 	char name[NAME_LENGTH];
-	int id, i;
+	int id, i, gmlvl;
 
 	id=RFIFOL(fd,4);
+	gmlvl=RFIFOL(fd,8);
 
-	safestrncpy(name, RFIFOCP(fd,32), NAME_LENGTH);
+	safestrncpy(name, RFIFOCP(fd,12+NAME_LENGTH), NAME_LENGTH);
 	sd = map_nick2sd(name,false);
 	if(sd == NULL || strcmp(sd->status.name, name) != 0)
 	{	//Not found
-		intif_wis_replay(id,1);
+		intif_wis_reply(id,1);
 		return 0;
 	}
 	if(sd->state.ignoreAll) {
-		intif_wis_replay(id, 2);
+		intif_wis_reply(id, 2);
 		return 0;
 	}
-	wisp_source = RFIFOCP(fd,8); // speed up [Yor]
+	wisp_source = RFIFOCP(fd,12); // speed up [Yor]
 	for(i=0; i < MAX_IGNORE_LIST &&
 		sd->ignore[i].name[0] != '\0' &&
 		strcmp(sd->ignore[i].name, wisp_source) != 0
@@ -1268,12 +1272,12 @@ int intif_parse_WisMessage(int fd)
 
 	if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0')
 	{	//Ignored
-		intif_wis_replay(id, 2);
+		intif_wis_reply(id, 2);
 		return 0;
 	}
 	//Success to send whisper.
-	clif_wis_message(sd->fd, wisp_source, RFIFOCP(fd,56),RFIFOW(fd,2)-56);
-	intif_wis_replay(id,0);   // success
+	clif_wis_message(sd, wisp_source, RFIFOCP(fd,12+2*NAME_LENGTH),RFIFOW(fd,2)-12+2*NAME_LENGTH, gmlvl);
+	intif_wis_reply(id,0);   // success
 	return 1;
 }
 
@@ -1313,7 +1317,7 @@ static int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va)
 	wisp_name = va_arg(va, char*);
 	message = va_arg(va, char*);
 	len = va_arg(va, int);
-	clif_wis_message(sd->fd, wisp_name, message, len);
+	clif_wis_message(sd, wisp_name, message, len,0);
 	return 1;
 }
 
@@ -1334,8 +1338,8 @@ int mapif_parse_WisToGM(int fd)
 	mes_len =  RFIFOW(fd,2) - 8+NAME_LENGTH;
 	message = (char *) aMalloc(mes_len+1);
 
-	permission = RFIFOL(fd,4+NAME_LENGTH);
 	safestrncpy(Wisp_name, RFIFOCP(fd,4), NAME_LENGTH);
+	permission = RFIFOL(fd, 4 + NAME_LENGTH);
 	safestrncpy(message, RFIFOCP(fd,8+NAME_LENGTH), mes_len+1);
 	// information is sent to all online GM
 	map_foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len);

+ 1 - 1
src/map/pc.cpp

@@ -11678,7 +11678,7 @@ void pc_check_expiration(struct map_session_data *sd) {
 		char tmpstr[1024];
 
 		strftime(tmpstr,sizeof(tmpstr) - 1,msg_txt(sd,501),localtime(&exp_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S."
-		clif_wis_message(sd->fd,wisp_server_name,tmpstr,strlen(tmpstr) + 1);
+		clif_wis_message(sd,wisp_server_name,tmpstr,strlen(tmpstr) + 1,0);
 
 		pc_expire_check(sd);
 	}