Merge pull request #1277 from rathena/cleanup/chat_messages
Cleaned and merged the chat functions * This addresses the issue that clients from late 2015 will not zero terminate most of their messages anymore. * Also fixes the problem with the unknown packets that were most likely caused by adding the zero termination directly into the packet buffer. Thanks to @Lemongrass3110!
This commit is contained in:
commit
a89ab2f123
311
src/map/clif.c
311
src/map/clif.c
@ -9747,88 +9747,99 @@ void clif_msg_skill(struct map_session_data* sd, uint16 skill_id, int msg_id)
|
|||||||
|
|
||||||
/// Validates one global/guild/party/whisper message packet and tries to recognize its components.
|
/// Validates one global/guild/party/whisper message packet and tries to recognize its components.
|
||||||
/// Returns true if the packet was parsed successfully.
|
/// Returns true if the packet was parsed successfully.
|
||||||
/// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00
|
/// Formats: false - <packet id>.w <packet len>.w (<name> : <message>).?B 00
|
||||||
/// 1 - <packet id>.w <packet len>.w <name>.24B <message>.?B 00
|
/// true - <packet id>.w <packet len>.w <name>.24B <message>.?B 00
|
||||||
static bool clif_process_message(struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_) {
|
static bool clif_process_message(struct map_session_data* sd, bool whisperFormat, char* out_name, char* out_message, char* out_full_message ){
|
||||||
char *text, *name, *message;
|
char* seperator = " : ";
|
||||||
unsigned int packetlen, textlen, namelen, messagelen;
|
int fd;
|
||||||
int fd = sd->fd;
|
struct s_packet_db* info;
|
||||||
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
uint16 packetLength, inputLength;
|
||||||
|
const char *input, *name, *message;
|
||||||
|
size_t nameLength, messageLength;
|
||||||
|
|
||||||
*name_ = NULL;
|
fd = sd->fd;
|
||||||
*namelen_ = 0;
|
|
||||||
*message_ = NULL;
|
|
||||||
*messagelen_ = 0;
|
|
||||||
|
|
||||||
packetlen = RFIFOW(fd,info->pos[0]);
|
info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
||||||
// basic structure checks
|
|
||||||
if( packetlen < 4 + 1 ) { // 4-byte header and at least an empty string is expected
|
packetLength = RFIFOW(fd,info->pos[0]);
|
||||||
|
input = (const char*)RFIFOP(fd,info->pos[1]);
|
||||||
|
|
||||||
|
// basic structure check for the 4-byte header
|
||||||
|
if( packetLength < 4 ){
|
||||||
ShowWarning("clif_process_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
|
ShowWarning("clif_process_message: Received malformed packet from player '%s' (no message data)!\n", sd->status.name);
|
||||||
return false;
|
return false;
|
||||||
|
}else{
|
||||||
|
inputLength = packetLength - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
text = (char*)RFIFOP(fd,info->pos[1]);
|
|
||||||
textlen = packetlen - 4;
|
|
||||||
|
|
||||||
// process <name> part of the packet
|
// process <name> part of the packet
|
||||||
if( format == 0 ) { // name and message are separated by ' : '
|
if( whisperFormat ) {
|
||||||
// validate name
|
|
||||||
name = text;
|
|
||||||
namelen = strnlen(sd->status.name, NAME_LENGTH-1); // name length (w/o zero byte)
|
|
||||||
|
|
||||||
if( strncmp(name, sd->status.name, namelen) || // the text must start with the speaker's name
|
|
||||||
name[namelen] != ' ' || name[namelen+1] != ':' || name[namelen+2] != ' ' ) // followed by ' : '
|
|
||||||
{
|
|
||||||
//Hacked message, or infamous "client desynch" issue where they pick one char while loading another.
|
|
||||||
ShowWarning("clif_process_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
|
|
||||||
set_eof(fd); // Just kick them out to correct it.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
message = name + namelen + 3;
|
|
||||||
messagelen = textlen - namelen - 3; // this should be the message length (w/ zero byte included)
|
|
||||||
} else {
|
|
||||||
// name has fixed width
|
// name has fixed width
|
||||||
if( textlen < NAME_LENGTH + 1 ) {
|
if( inputLength < NAME_LENGTH + 1 ) {
|
||||||
ShowWarning("clif_process_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
|
ShowWarning("clif_process_message: Received malformed packet from player '%s' (packet length is incorrect)!\n", sd->status.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = input;
|
||||||
|
|
||||||
// validate name
|
// validate name
|
||||||
name = text;
|
nameLength = strnlen( name, NAME_LENGTH - 1 );
|
||||||
namelen = strnlen(name, NAME_LENGTH-1); // name length (w/o zero byte)
|
|
||||||
|
|
||||||
// only restriction is that the name must be zero-terminated
|
// only restriction is that the name must be zero-terminated
|
||||||
if( name[namelen] != '\0' ) {
|
if( name[nameLength] != '\0' ) {
|
||||||
ShowWarning("clif_process_message: Player '%s' sent an unterminated name!\n", sd->status.name);
|
ShowWarning("clif_process_message: Player '%s' sent an unterminated name!\n", sd->status.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
message = name + NAME_LENGTH;
|
message = input + NAME_LENGTH;
|
||||||
messagelen = textlen - NAME_LENGTH; // this should be the message length (w/ zero byte included)
|
messageLength = inputLength - NAME_LENGTH;
|
||||||
|
}else{
|
||||||
|
// name and message are separated by ' : '
|
||||||
|
size_t seperatorLength = strnlen( seperator, NAME_LENGTH );
|
||||||
|
|
||||||
|
nameLength = strnlen( sd->status.name, NAME_LENGTH - 1 ); // name length (w/o zero byte)
|
||||||
|
|
||||||
|
// check if there's enough data provided
|
||||||
|
if( inputLength < nameLength + seperatorLength + 1 ){
|
||||||
|
ShowWarning("clif_process_message: Received malformed packet from player '%s' (no username data)!\n", sd->status.name);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PACKETVER >= 20151001
|
name = input;
|
||||||
if (message[messagelen-1] != '\0')
|
|
||||||
|
// validate name
|
||||||
|
if( strncmp( name, sd->status.name, nameLength ) || // the text must start with the speaker's name
|
||||||
|
strncmp( name + nameLength, seperator, seperatorLength ) ) // followed by the seperator
|
||||||
{
|
{
|
||||||
message[messagelen++] = '\0';
|
//Hacked message, or infamous "client desynch" issue where they pick one char while loading another.
|
||||||
|
ShowWarning("clif_process_message: Player '%s' sent a message using an incorrect name! Forcing a relog...\n", sd->status.name);
|
||||||
|
set_eof(sd->fd); // Just kick them out to correct it.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
message = input + nameLength + seperatorLength;
|
||||||
|
messageLength = inputLength - nameLength - seperatorLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PACKETVER < 20151001
|
||||||
// the declared length must match real length
|
// the declared length must match real length
|
||||||
if( messagelen != strnlen(message, messagelen)+1 ) {
|
if( messageLength != strnlen(message, messageLength)+1 ) {
|
||||||
ShowWarning("clif_process_message: Received malformed packet from player '%s' (length is incorrect)!\n", sd->status.name);
|
ShowWarning("clif_process_message: Received malformed packet from player '%s' (length is incorrect)!\n", sd->status.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify <message> part of the packet
|
// verify <message> part of the packet
|
||||||
if( message[messagelen-1] != '\0' ) { // message must be zero-terminated
|
if( message[messageLength-1] != '\0' ) { // message must be zero-terminated
|
||||||
ShowWarning("clif_process_message: Player '%s' sent an unterminated message string!\n", sd->status.name);
|
ShowWarning("clif_process_message: Player '%s' sent an unterminated message string!\n", sd->status.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// No zero termination anymore
|
||||||
|
messageLength += 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
// messages mustn't be too long
|
// messages mustn't be too long
|
||||||
if( messagelen > CHAT_SIZE_MAX-1 ) {
|
if( messageLength > CHAT_SIZE_MAX-1 ) {
|
||||||
// Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
|
// Normally you can only enter CHATBOX_SIZE-1 letters into the chat box, but Frost Joke / Dazzler's text can be longer.
|
||||||
// Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
|
// Also, the physical size of strings that use multibyte encoding can go multiple times over the chatbox capacity.
|
||||||
// Neither the official client nor server place any restriction on the length of the data in the packet,
|
// Neither the official client nor server place any restriction on the length of the data in the packet,
|
||||||
@ -9837,10 +9848,36 @@ static bool clif_process_message(struct map_session_data* sd, int format, char**
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*name_ = name;
|
// If it is not a whisper message, set the name to the fakename of the player
|
||||||
*namelen_ = namelen;
|
if( whisperFormat == false && sd->fakename[0] != '\0' ){
|
||||||
*message_ = message;
|
strcpy( out_name, sd->fakename );
|
||||||
*messagelen_ = messagelen;
|
}else{
|
||||||
|
safestrncpy( out_name, name, nameLength + 1 );
|
||||||
|
}
|
||||||
|
safestrncpy( out_message, message, messageLength );
|
||||||
|
|
||||||
|
if( whisperFormat ){
|
||||||
|
sprintf( out_full_message, "%-24s%s", out_name, out_message );
|
||||||
|
out_full_message[nameLength] = '\0';
|
||||||
|
}else{
|
||||||
|
sprintf( out_full_message, "%s%s%s", out_name, seperator, out_message );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( is_atcommand( fd, sd, out_message, 1 ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (sd->sc.cant.chat)
|
||||||
|
return false; //no "chatting" while muted.
|
||||||
|
|
||||||
|
if( battle_config.min_chat_delay ) { //[Skotlex]
|
||||||
|
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
|
||||||
|
return false;
|
||||||
|
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battle_config.idletime_option&IDLE_CHAT)
|
||||||
|
sd->idletime = last_tick;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10620,69 +10657,33 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd)
|
|||||||
/// There are various variants of this packet.
|
/// There are various variants of this packet.
|
||||||
void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
|
void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
|
||||||
{
|
{
|
||||||
|
char name[NAME_LENGTH], message[CHAT_SIZE_MAX], output[CHAT_SIZE_MAX+NAME_LENGTH*2];
|
||||||
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
size_t length;
|
||||||
int textlen = RFIFOW(fd,info->pos[0]) - 4;
|
|
||||||
const char* text = (char*)RFIFOP(fd,info->pos[1]);
|
|
||||||
|
|
||||||
char *name, *message, *fakename = NULL;
|
|
||||||
int namelen, messagelen;
|
|
||||||
|
|
||||||
bool is_fake;
|
|
||||||
|
|
||||||
// validate packet and retrieve name and message
|
// validate packet and retrieve name and message
|
||||||
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
|
if( !clif_process_message(sd, false, name, message, output ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( is_atcommand(fd, sd, message, 1) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sd->sc.cant.chat)
|
|
||||||
return; //no "chatting" while muted.
|
|
||||||
|
|
||||||
if( battle_config.min_chat_delay ) { //[Skotlex]
|
|
||||||
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
|
|
||||||
return;
|
|
||||||
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battle_config.idletime_option&IDLE_CHAT)
|
|
||||||
sd->idletime = last_tick;
|
|
||||||
|
|
||||||
if( sd->gcbind ) {
|
if( sd->gcbind ) {
|
||||||
channel_send(sd->gcbind,sd,message);
|
channel_send(sd->gcbind,sd,message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fake Name Design by FatalEror (bug report #9)
|
|
||||||
**/
|
|
||||||
if( ( is_fake = ( sd->fakename[0] ) ) ) {
|
|
||||||
fakename = (char*) aMalloc(strlen(sd->fakename)+messagelen+3);
|
|
||||||
strcpy(fakename, sd->fakename);
|
|
||||||
strcat(fakename, " : ");
|
|
||||||
strcat(fakename, message);
|
|
||||||
textlen = strlen(fakename) + 1;
|
|
||||||
}
|
|
||||||
// send message to others (using the send buffer for temp. storage)
|
// send message to others (using the send buffer for temp. storage)
|
||||||
clif_GlobalMessage(&sd->bl,is_fake ? fakename : text,sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
|
clif_GlobalMessage(&sd->bl,output,sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
|
||||||
|
|
||||||
|
length = strlen(output) + 1;
|
||||||
|
|
||||||
// send back message to the speaker
|
// send back message to the speaker
|
||||||
if( is_fake ) {
|
WFIFOHEAD(fd,4+length);
|
||||||
WFIFOHEAD(fd, textlen + 4);
|
|
||||||
WFIFOW(fd,0) = 0x8e;
|
WFIFOW(fd,0) = 0x8e;
|
||||||
WFIFOW(fd,2) = textlen + 4;
|
WFIFOW(fd,2) = 4+length;
|
||||||
safestrncpy((char*)WFIFOP(fd,4), fakename, textlen);
|
safestrncpy((char*)WFIFOP(fd,4), output, length );
|
||||||
aFree(fakename);
|
|
||||||
} else {
|
|
||||||
WFIFOHEAD(fd, RFIFOW(fd, info->pos[0]));
|
|
||||||
memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,info->pos[0]));
|
|
||||||
WFIFOW(fd,0) = 0x8e;
|
|
||||||
}
|
|
||||||
WFIFOSET(fd, WFIFOW(fd,2));
|
WFIFOSET(fd, WFIFOW(fd,2));
|
||||||
|
|
||||||
#ifdef PCRE_SUPPORT
|
#ifdef PCRE_SUPPORT
|
||||||
// trigger listening npcs
|
// trigger listening npcs
|
||||||
map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
|
map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, output, strlen(output), &sd->bl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Chat logging type 'O' / Global Chat
|
// Chat logging type 'O' / Global Chat
|
||||||
@ -10965,30 +10966,12 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
|
|||||||
{
|
{
|
||||||
struct map_session_data* dstsd;
|
struct map_session_data* dstsd;
|
||||||
int i;
|
int i;
|
||||||
|
char target[NAME_LENGTH], message[CHAT_SIZE_MAX], output[CHAT_SIZE_MAX+NAME_LENGTH*2];
|
||||||
char *target, *message;
|
|
||||||
int namelen, messagelen;
|
|
||||||
|
|
||||||
// validate packet and retrieve name and message
|
// validate packet and retrieve name and message
|
||||||
if( !clif_process_message(sd, 1, &target, &namelen, &message, &messagelen) )
|
if( !clif_process_message( sd, true, target, message, output ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( is_atcommand(fd, sd, message, 1) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sd->sc.cant.chat)
|
|
||||||
return; //no "chatting" while muted.
|
|
||||||
|
|
||||||
if (battle_config.min_chat_delay) { //[Skotlex]
|
|
||||||
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battle_config.idletime_option&IDLE_CHAT)
|
|
||||||
sd->idletime = last_tick;
|
|
||||||
|
|
||||||
// Chat logging type 'W' / Whisper
|
// Chat logging type 'W' / Whisper
|
||||||
log_chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
|
log_chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
|
||||||
|
|
||||||
@ -11059,7 +11042,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,
|
// 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
|
// 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).
|
// so, we send information to inter-server, which is the only one which decide (and copy correct name).
|
||||||
intif_wis_message(sd, target, message, messagelen);
|
intif_wis_message(sd, target, message, strlen(message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11074,7 +11057,6 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
|
|||||||
|
|
||||||
// if player is autotrading
|
// if player is autotrading
|
||||||
if (dstsd->state.autotrade == 1){
|
if (dstsd->state.autotrade == 1){
|
||||||
char output[256];
|
|
||||||
safesnprintf(output,sizeof(output),"%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name);
|
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(fd, wisp_server_name, output, strlen(output) + 1);
|
||||||
return;
|
return;
|
||||||
@ -11093,7 +11075,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
|
|||||||
clif_wis_end(fd, 0); // 0: success to send wisper
|
clif_wis_end(fd, 0); // 0: success to send wisper
|
||||||
|
|
||||||
// Normal message
|
// Normal message
|
||||||
clif_wis_message(dstsd->fd, sd->status.name, message, messagelen);
|
clif_wis_message(dstsd->fd, sd->status.name, message, strlen(message)+1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -12770,38 +12752,13 @@ void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd)
|
|||||||
/// Validates and processes party messages (CZ_REQUEST_CHAT_PARTY).
|
/// Validates and processes party messages (CZ_REQUEST_CHAT_PARTY).
|
||||||
/// 0108 <packet len>.W <text>.?B (<name> : <message>) 00
|
/// 0108 <packet len>.W <text>.?B (<name> : <message>) 00
|
||||||
void clif_parse_PartyMessage(int fd, struct map_session_data* sd){
|
void clif_parse_PartyMessage(int fd, struct map_session_data* sd){
|
||||||
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
char name[NAME_LENGTH], message[CHAT_SIZE_MAX], output[CHAT_SIZE_MAX+NAME_LENGTH*2];
|
||||||
int textlen = RFIFOW(fd,info->pos[0]) - 4;
|
|
||||||
const char* text = (char*)RFIFOP(fd,info->pos[1]);
|
|
||||||
|
|
||||||
char *name, *message;
|
|
||||||
int namelen, messagelen;
|
|
||||||
|
|
||||||
#if PACKETVER >= 20151001
|
|
||||||
textlen++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// validate packet and retrieve name and message
|
// validate packet and retrieve name and message
|
||||||
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
|
if( !clif_process_message( sd, false, name, message, output ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( is_atcommand(fd, sd, message, 1) )
|
party_send_message(sd, output, strlen(output) + 1 );
|
||||||
return;
|
|
||||||
|
|
||||||
if (sd->sc.cant.chat)
|
|
||||||
return; //no "chatting" while muted.
|
|
||||||
|
|
||||||
if( battle_config.min_chat_delay )
|
|
||||||
{ //[Skotlex]
|
|
||||||
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
|
|
||||||
return;
|
|
||||||
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battle_config.idletime_option&IDLE_CHAT)
|
|
||||||
sd->idletime = last_tick;
|
|
||||||
|
|
||||||
party_send_message(sd, text, textlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -13375,38 +13332,16 @@ void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd){
|
|||||||
/// Validates and processes guild messages (CZ_GUILD_CHAT).
|
/// Validates and processes guild messages (CZ_GUILD_CHAT).
|
||||||
/// 017e <packet len>.W <text>.?B (<name> : <message>) 00
|
/// 017e <packet len>.W <text>.?B (<name> : <message>) 00
|
||||||
void clif_parse_GuildMessage(int fd, struct map_session_data* sd){
|
void clif_parse_GuildMessage(int fd, struct map_session_data* sd){
|
||||||
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
char name[NAME_LENGTH], message[CHAT_SIZE_MAX], output[CHAT_SIZE_MAX+NAME_LENGTH*2];
|
||||||
int textlen = RFIFOW(fd,info->pos[0]) - 4;
|
|
||||||
const char* text = (char*)RFIFOP(fd,info->pos[1]);
|
|
||||||
|
|
||||||
|
|
||||||
char *name, *message;
|
|
||||||
int namelen, messagelen;
|
|
||||||
|
|
||||||
// validate packet and retrieve name and message
|
// validate packet and retrieve name and message
|
||||||
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
|
if( !clif_process_message( sd, false, name, message, output ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( is_atcommand(fd, sd, message, 1) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sd->sc.cant.chat)
|
|
||||||
return; //no "chatting" while muted.
|
|
||||||
|
|
||||||
if( battle_config.min_chat_delay )
|
|
||||||
{ //[Skotlex]
|
|
||||||
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
|
|
||||||
return;
|
|
||||||
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battle_config.idletime_option&IDLE_CHAT)
|
|
||||||
sd->idletime = last_tick;
|
|
||||||
|
|
||||||
if( sd->bg_id )
|
if( sd->bg_id )
|
||||||
bg_send_message(sd, text, textlen);
|
bg_send_message(sd, output, strlen(output) );
|
||||||
else
|
else
|
||||||
guild_send_message(sd, text, textlen);
|
guild_send_message(sd, output, strlen(output) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16484,32 +16419,12 @@ void clif_bg_message(struct battleground_data *bg, int src_id, const char *name,
|
|||||||
/// Validates and processes battlechat messages [pakpil] (CZ_BATTLEFIELD_CHAT).
|
/// Validates and processes battlechat messages [pakpil] (CZ_BATTLEFIELD_CHAT).
|
||||||
/// 0x2db <packet len>.W <text>.?B (<name> : <message>) 00
|
/// 0x2db <packet len>.W <text>.?B (<name> : <message>) 00
|
||||||
void clif_parse_BattleChat(int fd, struct map_session_data* sd){
|
void clif_parse_BattleChat(int fd, struct map_session_data* sd){
|
||||||
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
|
char name[NAME_LENGTH], message[CHAT_SIZE_MAX], output[CHAT_SIZE_MAX+NAME_LENGTH*2];
|
||||||
int textlen = RFIFOW(fd,info->pos[0]) - 4;
|
|
||||||
const char* text = (char*)RFIFOP(fd,info->pos[1]);
|
|
||||||
|
|
||||||
char *name, *message;
|
if( !clif_process_message( sd, false, name, message, output ) )
|
||||||
int namelen, messagelen;
|
|
||||||
|
|
||||||
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( is_atcommand(fd, sd, message, 1) )
|
bg_send_message(sd, output, strlen(output) );
|
||||||
return;
|
|
||||||
|
|
||||||
if (sd->sc.cant.chat)
|
|
||||||
return; //no "chatting" while muted.
|
|
||||||
|
|
||||||
if( battle_config.min_chat_delay ) {
|
|
||||||
if( DIFF_TICK(sd->cantalk_tick, gettick()) > 0 )
|
|
||||||
return;
|
|
||||||
sd->cantalk_tick = gettick() + battle_config.min_chat_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (battle_config.idletime_option&IDLE_CHAT)
|
|
||||||
sd->idletime = last_tick;
|
|
||||||
|
|
||||||
bg_send_message(sd, text, textlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1293,11 +1293,11 @@ int mapif_parse_WisToGM(int fd)
|
|||||||
char *message;
|
char *message;
|
||||||
|
|
||||||
mes_len = RFIFOW(fd,2) - 8+NAME_LENGTH;
|
mes_len = RFIFOW(fd,2) - 8+NAME_LENGTH;
|
||||||
message = (char *) aMalloc(mes_len);
|
message = (char *) aMalloc(mes_len+1);
|
||||||
|
|
||||||
permission = RFIFOL(fd,4+NAME_LENGTH);
|
permission = RFIFOL(fd,4+NAME_LENGTH);
|
||||||
safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
|
safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
|
||||||
safestrncpy(message, (char*)RFIFOP(fd,8+NAME_LENGTH), mes_len);
|
safestrncpy(message, (char*)RFIFOP(fd,8+NAME_LENGTH), mes_len+1);
|
||||||
// information is sent to all online GM
|
// information is sent to all online GM
|
||||||
map_foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len);
|
map_foreachpc(mapif_parse_WisToGM_sub, permission, Wisp_name, message, mes_len);
|
||||||
aFree(message);
|
aFree(message);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user