diff --git a/src/char/inter.cpp b/src/char/inter.cpp index f783405ad0..7c4997e371 100644 --- a/src/char/inter.cpp +++ b/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); } diff --git a/src/map/clif.cpp b/src/map/clif.cpp index a95efaeb95..d48262c413 100644 --- a/src/map/clif.cpp +++ b/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 .W .24B .?B /// 0097 .W .24B .L .?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); } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index f6ce01e1f5..3993cb7bba 100644 --- a/src/map/clif.hpp +++ b/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); diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 291ea0358f..4da47d8a67 100644 --- a/src/map/intif.cpp +++ b/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); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index f08fd66440..e07802e1dd 100755 --- a/src/map/pc.cpp +++ b/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); }