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

Fixes #2760
Fixes #2762

Thanks to @LunarSHINING
This commit is contained in:
Lemongrass3110 2018-01-24 18:33:09 +01:00 committed by GitHub
parent c4a57c571c
commit 3a8c8a9da4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 67 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}