void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
{
const char* text = (char*)RFIFOP(fd,4);
size_t textlen = RFIFOW(fd,2) - 4;
char *name, *message, *fakename = NULL;
size_t namelen, messagelen;
// unsigned long color1 = strtoul("0x000000",NULL,0); // DEFAULT: GREEN
// unsigned long color2;
// char *tmp = pc_readglobalreg_str(sd, "CHAT_COLOR$");
// if(tmp != NULL) { color2 = strtoul(tmp, NULL, 0); }
bool is_fake;
// validate packet and retrieve name and message
if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) )
return;
if( atcommand->exec(fd, sd, message, true) )
return;
if( !pc->can_talk(sd) )
return;
if( battle_config.min_chat_delay ) { //[Skotlex]
if (DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0)
return;
sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
if( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE ) {
unsigned int next = pc->nextbaseexp(sd);
if( next == 0 ) next = pc->thisbaseexp(sd);
if( next ) { // 0%, 10%, 20%, ...
int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. );
if( (battle_config.snovice_call_type || percent) && ( percent%100 ) == 0 ) {// 10.0%, 20.0%, ..., 90.0%
switch (sd->state.snovice_call_flag) {
case 0:
if( strstr(message, msg_txt(1479)) ) // "Dear angel, can you hear my voice?"
sd->state.snovice_call_flag = 1;
break;
case 1: {
char buf[256];
snprintf(buf, 256, msg_txt(1480), sd->status.name);
if( strstr(message, buf) ) // "I am %s Super Novice~"
sd->state.snovice_call_flag = 2;
}
break;
case 2:
if( strstr(message, msg_txt(1481)) ) // "Help me out~ Please~ T_T"
sd->state.snovice_call_flag = 3;
break;
case 3:
sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
sd->state.snovice_call_flag = 0;
break;
}
}
}
}
if( battle_config.idletime_criteria & BCIDLE_CHAT )
sd->idletime = sockt->last_tick;
if( sd->gcbind ) {
channel->send(sd->gcbind,sd,message);
return;
} else if ( sd->fontcolor && !sd->chatID ) {
char mout[200];
unsigned char mylen = 1;
if( sd->disguise == -1 ) {
sd->fontcolor_tid = timer->add(timer->gettick()+5000, clif->undisguise_timer, sd->bl.id, 0);
pc->disguise(sd,sd->status.class_);
if( pc_isdead(sd) )
clif->clearunit_single(-sd->bl.id, CLR_DEAD, sd->fd);
if( unit->is_walking(&sd->bl) )
clif->move(&sd->ud);
} else if ( sd->disguise == sd->status.class_ && sd->fontcolor_tid != INVALID_TIMER ) {
const struct TimerData *td;
if( (td = timer->get(sd->fontcolor_tid)) ) {
timer->settick(sd->fontcolor_tid, td->tick+5000);
}
}
mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
WFIFOHEAD(fd,mylen + 12);
WFIFOW(fd,0) = 0x2C1;
WFIFOW(fd,2) = mylen + 12;
WFIFOL(fd,4) = sd->bl.id;
WFIFOL(fd,8) = channel->config->colors[sd->fontcolor - 1];
// if(color2 != "") // if CHAT_COLOR != ""
// WFIFOL(fd,8) = (color2&0x0000FF) << 16 | (color2&0x00FF00) | (color2&0xFF0000) >> 16; // RGB -> BGR
// else // if CHAT_COLOR == ""
// WFIFOL(fd,8) = (color1&0x0000FF) << 16 | (color1&0x00FF00) | (color1&0xFF0000) >> 16; // RGB -> BGR
safestrncpy((char*)WFIFOP(fd,12), mout, mylen);
clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS);
WFIFOL(fd,4) = -sd->bl.id;
WFIFOSET(fd, mylen + 12);
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)
WFIFOHEAD(fd, 8 + textlen);
WFIFOW(fd,0) = 0x8d;
WFIFOW(fd,2) = 8 + textlen;
WFIFOL(fd,4) = sd->bl.id;
safestrncpy((char*)WFIFOP(fd,8), is_fake ? fakename : text, textlen);
//FIXME: chat has range of 9 only
clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);
// send back message to the speaker
if( is_fake ) {
WFIFOW(fd,0) = 0x8e;
WFIFOW(fd,2) = textlen + 4;
safestrncpy((char*)WFIFOP(fd,4), fakename, textlen);
aFree(fakename);
} else {
memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
WFIFOW(fd,0) = 0x8e;
}
WFIFOSET(fd, WFIFOW(fd,2));
// Chat logging type 'O' / Global Chat
logs->chat(LOG_CHAT_GLOBAL, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
#ifdef PCRE_SUPPORT
// trigger listening npcs
map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl);
#endif
}