Ver código fonte

- Modified the char-server TXT whisper system to use the online_db to know to which map server forward whispers, instead of just sending the whisper to every map server.
- Added char-server functions search_character_byname() and search_character_online() required for the previous update.


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

skotlex 18 anos atrás
pai
commit
c06808095d
4 arquivos alterados com 100 adições e 43 exclusões
  1. 3 0
      Changelog-Trunk.txt
  2. 20 0
      src/char/char.c
  3. 2 0
      src/char/char.h
  4. 75 43
      src/char/inter.c

+ 3 - 0
Changelog-Trunk.txt

@@ -4,6 +4,9 @@ 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/09/13
+	* Modified the char-server TXT whisper system to use the online_db to know
+	  to which map server forward whispers, instead of just sending the whisper
+	  to every map server. [Skotlex]
 	* Readded the setting TCP_NODELAY on socket.c to see if it fixes the
 	  walk-lag issue. [Skotlex]
 2006/09/12

+ 20 - 0
src/char/char.c

@@ -216,6 +216,13 @@ struct mmo_charstatus* search_character(int aid, int cid) {
 	return NULL;
 }
 	
+struct mmo_charstatus* search_character_byname(char* character_name)
+{
+	int i = search_character_index(character_name);
+	if (i == -1) return NULL;
+	return &char_dat[i].status;
+}
+
 //----------------------------------------------
 // Search an character id
 //   (return character index or -1 (if not found))
@@ -259,6 +266,19 @@ char * search_character_name(int index) {
 	return unknown_char_name;
 }
 
+// Searches if the given character is online, and returns the fd of the
+// map-server it is connected to.
+int search_character_online(int aid, int cid)
+{
+	//Look for online character.
+	struct online_char_data* character;
+	character = idb_get(online_char_db, aid);
+	if(character &&
+		character->char_id == cid &&
+		character->server > -1) 
+		return server_fd[character->server];
+	return -1;
+}
 static void * create_online_char_data(DBKey key, va_list args) {
 	struct online_char_data* character;
 	character = aCalloc(1, sizeof(struct online_char_data));

+ 2 - 0
src/char/char.h

@@ -24,8 +24,10 @@ struct mmo_map_server{
 };
 
 struct mmo_charstatus* search_character(int aid, int cid);
+struct mmo_charstatus* search_character_byname(char* character_name);
 int search_character_index(char* character_name);
 char * search_character_name(int index);
+int search_character_online(int aid, int cid);
 
 int mapif_sendall(unsigned char *buf, unsigned int len);
 int mapif_sendallwos(int fd,unsigned char *buf, unsigned int len);

+ 75 - 43
src/char/inter.c

@@ -325,6 +325,20 @@ int mapif_GMmessage(unsigned char *mes, int len, unsigned long color, int sfd) {
 	return 0;
 }
 
+// Wisp/page transmission to one map-server
+int mapif_wis_message2(struct WisData *wd, int fd) {
+	WFIFOHEAD(fd, 56+wd->len);
+	WFIFOW(fd, 0) = 0x3801;
+	WFIFOW(fd, 2) = 56 + wd->len;
+	WFIFOL(fd, 4) = wd->id;
+	memcpy(WFIFOP(fd, 8), wd->src, NAME_LENGTH);
+	memcpy(WFIFOP(fd,32), wd->dst, NAME_LENGTH);
+	memcpy(WFIFOP(fd,56), wd->msg, wd->len);
+	wd->count = 1;
+	WFIFOSET(fd,WFIFOW(fd,2));
+	return 1;
+}
+
 // Wisp/page transmission to all map-server
 int mapif_wis_message(struct WisData *wd) {
 	unsigned char buf[2048];
@@ -341,6 +355,16 @@ int mapif_wis_message(struct WisData *wd) {
 	return 0;
 }
 
+int mapif_wis_fail(int fd, char *src) {
+	unsigned char buf[27];
+	WBUFW(buf, 0) = 0x3802;
+	memcpy(WBUFP(buf, 2), src, NAME_LENGTH);
+	WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+	mapif_send(fd, buf, 27);
+	return 0;
+
+}
+
 // Wisp/page transmission result to map-server
 int mapif_wis_end(struct WisData *wd, int flag) {
 	unsigned char buf[27];
@@ -449,12 +473,31 @@ int mapif_parse_GMmessage(int fd) {
 	return 0;
 }
 
+static struct WisData* mapif_create_whisper(int fd, char* src, char* dst, char* mes, int meslen)
+{
+	static int wisid = 0;
+	struct WisData* wd = (struct WisData *)aCalloc(sizeof(struct WisData), 1);
+	if (wd == NULL){
+		ShowFatalError("inter: WisRequest: out of memory !\n");
+		return NULL;
+	}
+	wd->id = ++wisid;
+	wd->fd = fd;
+	wd->len= meslen;
+	memcpy(wd->src, src, NAME_LENGTH);
+	memcpy(wd->dst, dst, NAME_LENGTH);
+	memcpy(wd->msg, mes, meslen);
+	wd->tick = gettick();
+	return wd;
+}
+
 // Wisp/page request to send
 int mapif_parse_WisRequest(int fd) {
+	struct mmo_charstatus* char_status;
 	struct WisData* wd;
 	char name[NAME_LENGTH];
-	static int wisid = 0;
-	int index;
+	int fd2;
+
 	RFIFOHEAD(fd);
 
 	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
@@ -468,48 +511,37 @@ int mapif_parse_WisRequest(int fd) {
 	memcpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
 	name[NAME_LENGTH-1]= '\0';
 	// search if character exists before to ask all map-servers
-	if ((index = search_character_index(name)) == -1) {
-		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
-		mapif_send(fd, buf, 27);
-	// Character exists. So, ask all map-servers
-	} else {
-		// to be sure of the correct name, rewrite it
-		memset(name, 0, NAME_LENGTH);
-		strncpy(name, search_character_name(index), NAME_LENGTH);
-		// if source is destination, don't ask other servers.
-		if (strcmp((char*)RFIFOP(fd,4),name) == 0) {
-			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
-			mapif_send(fd, buf, 27);
-		} else {
-
-			wd = (struct WisData *)aCalloc(sizeof(struct WisData), 1);
-			if (wd == NULL){
-				ShowFatalError("inter: WisRequest: out of memory !\n");
-				return 0;
-			}
-
-			// Whether the failure of previous wisp/page transmission (timeout)
-			check_ttl_wisdata();
-
-			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->tick = gettick();
-			idb_put(wis_db, wd->id, wd);
-			mapif_wis_message(wd);
-		}
+	char_status = search_character_byname(name);
+	if (char_status == NULL)
+		return mapif_wis_fail(fd, RFIFOP(fd, 4));
+
+	// Character exists.
+	// to be sure of the correct name, rewrite it
+	memset(name, 0, NAME_LENGTH);
+	strncpy(name, char_status->name, NAME_LENGTH);
+	// if source is destination, don't ask other servers.
+	if (strcmp((char*)RFIFOP(fd,4),name) == 0)
+		return mapif_wis_fail(fd, RFIFOP(fd, 4));
+
+	//Look for online character.
+	fd2 = search_character_online(char_status->account_id, char_status->char_id);
+	if (fd2 >= 0) {	//Character online, send whisper.
+		wd = mapif_create_whisper(fd, RFIFOP(fd, 4), RFIFOP(fd,28), RFIFOP(fd,52), RFIFOW(fd,2)-52);
+		if (!wd) return 1;
+		idb_put(wis_db, wd->id, wd);
+		mapif_wis_message2(wd, fd2);
+		return 0;
 	}
-
+	//Not found.
+	return mapif_wis_fail(fd, RFIFOP(fd, 4));
+
+/* Scrapped since now we know where characters are online in. [Skotlex]
+	wd = mapif_create_whisper(fd, RFIFOP(fd, 4), RFIFOP(fd,28), RFIFOP(fd,52), RFIFOW(fd,2)-52);
+	if (!wd) return 0;
+	idb_put(wis_db, wd->id, wd);
+	mapif_wis_message(wd);
 	return 0;
+*/
 }
 
 // Wisp/page transmission result
@@ -522,7 +554,7 @@ int mapif_parse_WisReply(int fd) {
 	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
+		return 0;	// This wisp was probably suppress before, because it was timeout or 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