summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt3
-rw-r--r--src/char/char.c20
-rw-r--r--src/char/char.h2
-rw-r--r--src/char/inter.c118
4 files changed, 100 insertions, 43 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 2a10d0faf..9a218ffdf 100644
--- a/Changelog-Trunk.txt
+++ b/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
diff --git a/src/char/char.c b/src/char/char.c
index 2ae226ca1..50586a921 100644
--- a/src/char/char.c
+++ b/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));
diff --git a/src/char/char.h b/src/char/char.h
index feb5c1243..b6849f80f 100644
--- a/src/char/char.h
+++ b/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);
diff --git a/src/char/inter.c b/src/char/inter.c
index 094e67675..8127a60a4 100644
--- a/src/char/inter.c
+++ b/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