TrinityCore
Loading...
Searching...
No Matches
ChatHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "AccountMgr.h"
20#include "Channel.h"
21#include "ChannelMgr.h"
22#include "Chat.h"
23#include "ChatPackets.h"
24#include "Common.h"
25#include "CreatureAI.h"
26#include "DB2Stores.h"
27#include "GameTime.h"
28#include "GridNotifiersImpl.h"
29#include "Group.h"
30#include "Guild.h"
31#include "GuildMgr.h"
32#include "Language.h"
33#include "LanguageMgr.h"
34#include "Log.h"
35#include "ObjectAccessor.h"
36#include "ObjectMgr.h"
37#include "Opcodes.h"
38#include "Player.h"
39#include "ScriptMgr.h"
40#include "SpellAuraEffects.h"
41#include "Util.h"
42#include "World.h"
43#include <algorithm>
44
46{
47 CanWhisper = 0,
49 Offline = 2,
50 WrongFaction = 3
51};
52
53inline bool isNasty(uint8 c)
54{
55 if (c == '\t')
56 return false;
57 if (c <= '\037') // ASCII control block
58 return true;
59 return false;
60}
61
62inline bool ValidateMessage(Player const* player, std::string& msg)
63{
64 // cut at the first newline or carriage return
65 std::string::size_type pos = msg.find_first_of("\n\r");
66 if (pos == 0)
67 return false;
68 else if (pos != std::string::npos)
69 msg.erase(pos);
70
71 // abort on any sort of nasty character
72 for (uint8 c : msg)
73 {
74 if (isNasty(c))
75 {
76 TC_LOG_ERROR("network", "Player {} {} sent a message containing invalid character {} - blocked", player->GetName(),
77 player->GetGUID().ToString(), uint32(c));
78 return false;
79 }
80 }
81
82 // collapse multiple spaces into one
84 {
85 auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); });
86 msg.erase(end, msg.end());
87 }
88
89 return true;
90}
91
93{
94 ChatMsg type;
95
96 switch (chatMessage.GetOpcode())
97 {
99 type = CHAT_MSG_SAY;
100 break;
102 type = CHAT_MSG_YELL;
103 break;
105 type = CHAT_MSG_GUILD;
106 break;
108 type = CHAT_MSG_OFFICER;
109 break;
111 type = CHAT_MSG_PARTY;
112 break;
114 type = CHAT_MSG_RAID;
115 break;
118 break;
121 break;
122 default:
123 TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode ({})", chatMessage.GetOpcode());
124 return;
125 }
126
127 HandleChatMessage(type, Language(chatMessage.Language), chatMessage.Text);
128}
129
131{
132 HandleChatMessage(CHAT_MSG_WHISPER, Language(chatMessageWhisper.Language), chatMessageWhisper.Text, chatMessageWhisper.Target, chatMessageWhisper.TargetGUID);
133}
134
136{
137 HandleChatMessage(CHAT_MSG_CHANNEL, Language(chatMessageChannel.Language), chatMessageChannel.Text, chatMessageChannel.Target, chatMessageChannel.ChannelGUID);
138}
139
144
145ChatMessageResult WorldSession::HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target /*= ""*/, Optional<ObjectGuid> targetGuid /*= {}*/)
146{
147 Player* sender = GetPlayer();
148
149 if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE && type != CHAT_MSG_GUILD && type != CHAT_MSG_OFFICER)
150 {
151 TC_LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
154 }
155
156 // prevent talking at unknown language (cheating)
157 auto languageData = sLanguageMgr->GetLanguageDescById(lang);
158 if (languageData.begin() == languageData.end())
159 {
162 }
163
164 if (std::none_of(languageData.begin(), languageData.end(),
165 [sender](std::pair<uint32 const, LanguageDesc> const& langDesc) { return langDesc.second.SkillId == 0 || sender->HasSkill(langDesc.second.SkillId); }))
166 {
167 // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
169 {
172 }
173 }
174
175 // send in universal language if player in .gm on mode (ignore spell effects)
176 if (sender->IsGameMaster())
177 lang = LANG_UNIVERSAL;
178 else
179 {
180 // send in universal language in two side iteration allowed mode
182 lang = LANG_UNIVERSAL;
183 else
184 {
185 switch (type)
186 {
187 case CHAT_MSG_PARTY:
188 case CHAT_MSG_RAID:
190 // allow two side chat at group channel if two side group allowed
192 lang = LANG_UNIVERSAL;
193 break;
194 case CHAT_MSG_GUILD:
195 case CHAT_MSG_OFFICER:
196 // allow two side chat at guild channel if two side guild allowed
198 lang = LANG_UNIVERSAL;
199 break;
200 default:
201 break;
202 }
203 }
204
205 // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
207 if (!ModLangAuras.empty())
208 lang = Language(ModLangAuras.front()->GetMiscValue());
209 }
210
211 if (!CanSpeak())
212 {
213 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
216 }
217
218 if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
220
221 if (sender->HasAura(GM_SILENCE_AURA) && type != CHAT_MSG_WHISPER)
222 {
225 }
226
227 if (msg.size() > 511)
229
230 if (msg.empty())
232
233 if (ChatHandler(this).ParseCommands(msg.c_str()))
235
236 // do message validity checks
237 if (!ValidateMessage(GetPlayer(), msg))
239
240 // validate hyperlinks
243
244 switch (type)
245 {
246 case CHAT_MSG_SAY:
247 {
248 // Prevent cheating
249 if (!sender->IsAlive())
251
252 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
253 {
256 }
257
258 sender->Say(msg, lang);
259 break;
260 }
261 case CHAT_MSG_EMOTE:
262 {
263 // Prevent cheating
264 if (!sender->IsAlive())
266
267 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ))
268 {
271 }
272
273 sender->TextEmote(msg);
274 break;
275 }
276 case CHAT_MSG_YELL:
277 {
278 // Prevent cheating
279 if (!sender->IsAlive())
281
282 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ))
283 {
286 }
287
288 sender->Yell(msg, lang);
289 break;
290 }
291 case CHAT_MSG_WHISPER:
292 {
294 Player* receiver = nullptr;
295 if (targetGuid && !targetGuid->IsEmpty())
296 {
297 receiver = ObjectAccessor::FindConnectedPlayer(*targetGuid);
298 }
299 else
300 {
302
303 if (!normalizePlayerName(extName.Name))
304 {
306 break;
307 }
308
310 }
311 if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
312 {
315 }
316
317 // Apply checks only if receiver is not already in whitelist and if receiver is not a GM with ".whisper on"
318 if (!receiver->IsInWhisperWhiteList(sender->GetGUID()) && !receiver->IsGameMasterAcceptingWhispers())
319 {
320 if (!sender->IsGameMaster() && sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
321 {
324 }
325
326 if (GetPlayer()->GetEffectiveTeam() != receiver->GetEffectiveTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
327 {
330 }
331 }
332
333 if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
334 {
337 }
338
339 // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
340 // We also do that if a player is under the required level for whispers.
341 if (receiver->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
343 sender->AddWhisperWhiteList(receiver->GetGUID());
344
345 GetPlayer()->Whisper(msg, lang, receiver);
346 break;
347 }
348 case CHAT_MSG_PARTY:
349 {
350 // if player is in battleground, he cannot say to battleground members by /p
351 Group* group = GetPlayer()->GetOriginalGroup();
352 if (!group)
353 {
354 group = sender->GetGroup();
355 if (!group || group->isBGGroup())
357 }
358
359 if (group->IsLeader(GetPlayer()->GetGUID()))
361
362 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
363
365 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
366 group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID()));
367 break;
368 }
369 case CHAT_MSG_GUILD:
370 {
371 if (GetPlayer()->GetGuildId())
372 {
373 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
374 {
375 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
376
377 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
378 }
379 }
380 break;
381 }
382 case CHAT_MSG_OFFICER:
383 {
384 if (GetPlayer()->GetGuildId())
385 {
386 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
387 {
388 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
389
390 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
391 }
392 }
393 break;
394 }
395 case CHAT_MSG_RAID:
396 {
397 Group* group = GetPlayer()->GetGroup();
398 if (!group || !group->isRaidGroup() || group->isBGGroup())
400
401 if (group->IsLeader(GetPlayer()->GetGUID()))
403
404 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
405
407 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
408 group->BroadcastPacket(packet.Write(), false);
409 break;
410 }
412 {
413 Group* group = GetPlayer()->GetGroup();
414 if (!group)
416
417 if (group->isRaidGroup())
418 {
419 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
421 }
422 else if (!sWorld->getBoolConfig(CONFIG_CHAT_PARTY_RAID_WARNINGS))
424
425 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
426
428 //in battleground, raid warning is sent only to players in battleground - code is ok
429 packet.Initialize(CHAT_MSG_RAID_WARNING, lang, sender, nullptr, msg);
430 group->BroadcastPacket(packet.Write(), false);
431 break;
432 }
433 case CHAT_MSG_CHANNEL:
434 {
436 {
437 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
438 {
441 }
442 }
443
444 Channel* chn = targetGuid
445 ? ChannelMgr::GetChannelForPlayerByGuid(*targetGuid, sender)
447 if (chn)
448 {
449 if (ChatChannelsEntry const* chatChannel = sChatChannelsStore.LookupEntry(chn->GetChannelId()))
450 if (chatChannel->GetFlags().HasFlag(ChatChannelFlags::ReadOnly))
452
453 sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
454 chn->Say(sender->GetGUID(), msg, lang);
455 }
456 break;
457 }
459 {
460 Group* group = GetPlayer()->GetGroup();
461 if (!group)
463
464 if (group->IsLeader(GetPlayer()->GetGUID()))
466
467 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
468
470 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
471 group->BroadcastPacket(packet.Write(), false);
472 break;
473 }
474 default:
475 TC_LOG_ERROR("network", "CHAT: unknown message type {}, lang: {}", type, lang);
476 break;
477 }
478
480}
481
483{
484 HandleChatAddonMessage(chatAddonMessage.Params.Type, chatAddonMessage.Params.Prefix, chatAddonMessage.Params.Text, chatAddonMessage.Params.IsLogged);
485}
486
488{
489 switch (chatAddonMessageTargeted.Params.Type)
490 {
491 case CHAT_MSG_WHISPER:
492 HandleChatAddonMessage(chatAddonMessageTargeted.Params.Type, chatAddonMessageTargeted.Params.Prefix, chatAddonMessageTargeted.Params.Text,
493 chatAddonMessageTargeted.Params.IsLogged, chatAddonMessageTargeted.PlayerName, chatAddonMessageTargeted.PlayerGUID);
494 break;
495 case CHAT_MSG_CHANNEL:
496 HandleChatAddonMessage(chatAddonMessageTargeted.Params.Type, chatAddonMessageTargeted.Params.Prefix, chatAddonMessageTargeted.Params.Text,
497 chatAddonMessageTargeted.Params.IsLogged, chatAddonMessageTargeted.ChannelName, chatAddonMessageTargeted.ChannelGUID);
498 break;
499 default:
500 TC_LOG_ERROR("misc", "HandleChatAddonMessageTargetedOpcode: unknown addon message type {}", chatAddonMessageTargeted.Params.Type);
501 break;
502 }
503}
504
505void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, bool isLogged, std::string target /*= ""*/, Optional<ObjectGuid> targetGuid /*= {}*/)
506{
507 Player* sender = GetPlayer();
508
509 if (prefix.empty() || prefix.length() > 16)
510 return;
511
512 // Disabled addon channel?
513 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
514 return;
515
516 if (!CanSpeak())
517 return;
518
520
521 if (prefix == AddonChannelCommandHandler::PREFIX && AddonChannelCommandHandler(this).ParseCommands(text.c_str()))
522 return;
523
524 if (text.length() > 255)
525 return;
526
527 switch (type)
528 {
529 case CHAT_MSG_GUILD:
530 case CHAT_MSG_OFFICER:
531 {
532 if (sender->GetGuildId())
533 if (Guild* guild = sGuildMgr->GetGuildById(sender->GetGuildId()))
534 guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, text, prefix, isLogged);
535 break;
536 }
537 case CHAT_MSG_WHISPER:
538 {
540 Player* receiver = nullptr;
541 if (targetGuid && !targetGuid->IsEmpty())
542 {
543 receiver = ObjectAccessor::FindConnectedPlayer(*targetGuid);
544 }
545 else
546 {
548
549 if (!normalizePlayerName(extName.Name))
550 break;
551
553 }
554 if (!receiver)
555 break;
556
557 sender->WhisperAddon(text, prefix, isLogged, receiver);
558 break;
559 }
560 // Messages sent to "RAID" while in a party will get delivered to "PARTY"
561 case CHAT_MSG_PARTY:
562 case CHAT_MSG_RAID:
564 {
565 Group* group = nullptr;
566 int32 subGroup = -1;
567 if (type != CHAT_MSG_INSTANCE_CHAT)
568 group = sender->GetOriginalGroup();
569
570 if (!group)
571 {
572 group = sender->GetGroup();
573 if (!group)
574 break;
575
576 if (type == CHAT_MSG_PARTY)
577 subGroup = sender->GetSubGroup();
578 }
579
581 packet.Initialize(type, isLogged ? LANG_ADDON_LOGGED : LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix);
582 group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, subGroup, sender->GetGUID());
583 break;
584 }
585 case CHAT_MSG_CHANNEL:
586 {
587 Channel* chn = targetGuid
588 ? ChannelMgr::GetChannelForPlayerByGuid(*targetGuid, sender)
590 if (chn)
591 chn->AddonSay(sender->GetGUID(), prefix, text.c_str(), isLogged);
592 break;
593 }
594 default:
595 {
596 TC_LOG_ERROR("misc", "HandleAddonMessagechatOpcode: unknown addon message type {}", type);
597 break;
598 }
599 }
600}
601
603{
604 Player* sender = GetPlayer();
605
606 if (sender->IsInCombat())
607 return;
608
609 if (chatMessageAFK.Text.length() > 511)
610 return;
611
612 // do message validity checks
613 if (!ValidateMessage(sender, chatMessageAFK.Text))
614 return;
615
616 if (!ValidateHyperlinksAndMaybeKick(chatMessageAFK.Text))
617 return;
618
619 if (sender->HasAura(GM_SILENCE_AURA))
620 {
622 return;
623 }
624
625 if (sender->isAFK()) // Already AFK
626 {
627 if (chatMessageAFK.Text.empty())
628 sender->ToggleAFK(); // Remove AFK
629 else
630 sender->autoReplyMsg = chatMessageAFK.Text; // Update message
631 }
632 else // New AFK mode
633 {
634 sender->autoReplyMsg = chatMessageAFK.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : chatMessageAFK.Text;
635
636 if (sender->isDND())
637 sender->ToggleDND();
638
639 sender->ToggleAFK();
640 }
641
642 if (Guild* guild = sender->GetGuild())
643 guild->SendEventAwayChanged(sender->GetGUID(), sender->isAFK(), sender->isDND());
644
645 sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, chatMessageAFK.Text);
646}
647
649{
650 Player* sender = GetPlayer();
651
652 if (sender->IsInCombat())
653 return;
654
655 if (chatMessageDND.Text.length() > 511)
656 return;
657
658 // do message validity checks
659 if (!ValidateMessage(sender, chatMessageDND.Text))
660 return;
661
662 if (!ValidateHyperlinksAndMaybeKick(chatMessageDND.Text))
663 return;
664
665 if (sender->HasAura(GM_SILENCE_AURA))
666 {
668 return;
669 }
670
671 if (sender->isDND()) // Already DND
672 {
673 if (chatMessageDND.Text.empty())
674 sender->ToggleDND(); // Remove DND
675 else
676 sender->autoReplyMsg = chatMessageDND.Text; // Update message
677 }
678 else // New DND mode
679 {
680 sender->autoReplyMsg = chatMessageDND.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : chatMessageDND.Text;
681
682 if (sender->isAFK())
683 sender->ToggleAFK();
684
685 sender->ToggleDND();
686 }
687
688 if (Guild* guild = sender->GetGuild())
689 guild->SendEventAwayChanged(sender->GetGUID(), sender->isAFK(), sender->isDND());
690
691 sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, chatMessageDND.Text);
692}
693
695{
696 if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
697 return;
698
699 sScriptMgr->OnPlayerClearEmote(GetPlayer());
700
702}
703
705{
706 if (!_player->IsAlive())
707 return;
708
709 if (!CanSpeak())
710 {
711 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
713 return;
714 }
715
716 sScriptMgr->OnPlayerTextEmote(_player, packet.SoundIndex, packet.EmoteID, packet.Target);
717
718 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(packet.EmoteID);
719 if (!em)
720 return;
721
722 Emote emote = static_cast<Emote>(em->EmoteID);
723
724 switch (emote)
725 {
727 case EMOTE_STATE_SIT:
730 break;
732 case EMOTE_STATE_READ:
733 case EMOTE_STATE_LEAN:
734 _player->SetEmoteState(emote);
735 break;
736 default:
737 // Only allow text-emotes for "dead" entities (feign death included)
739 break;
740 _player->HandleEmoteCommand(emote, nullptr, { packet.SpellVisualKitIDs.data(), packet.SpellVisualKitIDs.data() + packet.SpellVisualKitIDs.size() }, packet.SequenceVariation);
741 break;
742 }
743
745 textEmote.SourceGUID = _player->GetGUID();
746 textEmote.SourceAccountGUID = GetAccountGUID();
747 textEmote.TargetGUID = packet.Target;
748 textEmote.EmoteID = packet.EmoteID;
749 textEmote.SoundIndex = packet.SoundIndex;
750 _player->SendMessageToSetInRange(textEmote.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
751
752 Unit* unit = ObjectAccessor::GetUnit(*_player, packet.Target);
753
755
756 // Send scripted event call
757 if (unit)
758 if (Creature* creature = unit->ToCreature())
759 creature->AI()->ReceiveEmote(_player, packet.EmoteID);
760
761 if (emote != EMOTE_ONESHOT_NONE)
763}
764
766{
767 Player* player = ObjectAccessor::FindConnectedPlayer(chatReportIgnored.IgnoredGUID);
768 if (!player || !player->GetSession())
769 return;
770
773 player->SendDirectMessage(packet.Write());
774}
775
777{
779}
780
781void WorldSession::SendPlayerAmbiguousNotice(std::string const& name)
782{
784}
785
787{
789 packet.Reason = restriction;
790 SendPacket(packet.Write());
791}
792
794{
795 ChatWhisperTargetStatus status = [&]
796 {
797 Player* sender = GetPlayer();
798 Player* receiver = ObjectAccessor::FindConnectedPlayer(canLocalWhisperTargetRequest.WhisperTarget);
799 if (!receiver || (!receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
801
802 if (!receiver->IsInWhisperWhiteList(sender->GetGUID()) && !receiver->IsGameMasterAcceptingWhispers())
803 if (GetPlayer()->GetEffectiveTeam() != receiver->GetEffectiveTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
805
807 }();
808
809 WorldPackets::Chat::CanLocalWhisperTargetResponse canLocalWhisperTargetResponse;
810 canLocalWhisperTargetResponse.WhisperTarget = canLocalWhisperTargetRequest.WhisperTarget;
811 canLocalWhisperTargetResponse.Status = status;
812 SendPacket(canLocalWhisperTargetResponse.Write());
813}
814
816{
817 // disabling chat not supported
818 // send Sueccess and force chat disabled to false instead of sending that change failed
819 // this makes client change the cvar back to false instead of just printing error message in console
821 response.Success = true;
822 response.ChatDisabled = false;
823 SendPacket(response.Write());
824}
ChatWhisperTargetStatus
bool ValidateMessage(Player const *player, std::string &msg)
bool isNasty(uint8 c)
#define DEFAULT_LOCALE
Definition Common.h:69
DB2Storage< EmotesTextEntry > sEmotesTextStore("EmotesText.db2", &EmotesTextLoadInfo::Instance)
DB2Storage< ChatChannelsEntry > sChatChannelsStore("ChatChannels.db2", &ChatChannelsLoadInfo::Instance)
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define sGuildMgr
Definition GuildMgr.h:76
#define sLanguageMgr
Definition LanguageMgr.h:97
@ LANG_SAY_REQ
Definition Language.h:1167
@ LANG_GM_SILENCE
Definition Language.h:1182
@ LANG_UNKNOWN_LANGUAGE
Definition Language.h:760
@ LANG_NOT_LEARNED_LANGUAGE
Definition Language.h:761
@ LANG_WHISPER_REQ
Definition Language.h:1168
@ LANG_WAIT_BEFORE_SPEAKING
Definition Language.h:697
@ LANG_PLAYER_AFK_DEFAULT
Definition Language.h:702
@ LANG_PLAYER_DND_DEFAULT
Definition Language.h:701
@ LANG_CHANNEL_REQ
Definition Language.h:1169
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
ExtendedPlayerName ExtractExtendedPlayerName(std::string const &name)
bool normalizePlayerName(std::string &name)
@ CMSG_CHAT_MESSAGE_YELL
Definition Opcodes.h:228
@ CMSG_CHAT_MESSAGE_GUILD
Definition Opcodes.h:220
@ CMSG_CHAT_MESSAGE_INSTANCE_CHAT
Definition Opcodes.h:221
@ CMSG_CHAT_MESSAGE_RAID_WARNING
Definition Opcodes.h:225
@ CMSG_CHAT_MESSAGE_SAY
Definition Opcodes.h:226
@ CMSG_CHAT_MESSAGE_RAID
Definition Opcodes.h:224
@ CMSG_CHAT_MESSAGE_OFFICER
Definition Opcodes.h:222
@ CMSG_CHAT_MESSAGE_PARTY
Definition Opcodes.h:223
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
#define sScriptMgr
Definition ScriptMgr.h:1449
Language
@ LANG_ADDON_LOGGED
@ LANG_UNIVERSAL
@ LANG_ADDON
ChatMessageResult
@ EMOTE_STATE_LEAN
@ EMOTE_STATE_SLEEP
@ EMOTE_STATE_SIT
@ EMOTE_STATE_READ
@ EMOTE_STATE_KNEEL
@ EMOTE_STATE_DANCE
@ EMOTE_ONESHOT_NONE
#define GM_SILENCE_AURA
ChatMsg
@ CHAT_MSG_RAID_WARNING
@ CHAT_MSG_IGNORED
@ CHAT_MSG_RAID
@ CHAT_MSG_SAY
@ CHAT_MSG_INSTANCE_CHAT_LEADER
@ CHAT_MSG_PARTY_LEADER
@ CHAT_MSG_RAID_LEADER
@ CHAT_MSG_DND
@ CHAT_MSG_INSTANCE_CHAT
@ CHAT_MSG_YELL
@ CHAT_MSG_PARTY
@ CHAT_MSG_WHISPER
@ CHAT_MSG_EMOTE
@ CHAT_MSG_GUILD
@ CHAT_MSG_OFFICER
@ CHAT_MSG_AFK
@ CHAT_MSG_CHANNEL
@ SPELL_AURA_COMPREHEND_LANGUAGE
@ SPELL_AURA_MOD_LANGUAGE
@ UNIT_STATE_DIED
Definition Unit.h:261
std::string secsToTimeString(uint64 timeInSecs, TimeFormat timeFormat, bool hoursOnly)
Definition Util.cpp:116
ChatRestrictionType
static std::string const PREFIX
Definition Chat.h:162
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
static Channel * GetChannelForPlayerByNamePart(std::string const &namePart, Player *playerSearcher)
static Channel * GetChannelForPlayerByGuid(ObjectGuid channelGuid, Player *playerSearcher)
uint32 GetChannelId() const
Definition Channel.h:174
void AddonSay(ObjectGuid const &guid, std::string const &prefix, std::string const &what, bool isLogged) const
Definition Channel.cpp:733
void Say(ObjectGuid const &guid, std::string const &what, uint32 lang) const
Definition Channel.cpp:681
Definition Group.h:205
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:1733
bool IsAssistant(ObjectGuid guid) const
Definition Group.h:319
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:1690
void BroadcastAddonMessagePacket(WorldPacket const *packet, const std::string &prefix, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty) const
Definition Group.cpp:960
bool isBGGroup() const
Definition Group.cpp:1633
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignoredPlayer=ObjectGuid::Empty) const
Definition Group.cpp:973
bool isRaidGroup() const
Definition Group.cpp:1628
Definition Guild.h:329
std::string ToString() const
Creature * ToCreature()
Definition Object.h:121
void SendMessageToSetInRange(WorldPacket const *data, float dist, bool self) const override
Definition Player.cpp:6251
bool IsGameMasterAcceptingWhispers() const
Definition Player.h:1310
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition Player.cpp:30140
std::string autoReplyMsg
Definition Player.h:1286
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
Group * GetOriginalGroup() const
Definition Player.h:2815
Guild * GetGuild()
Definition Player.cpp:30511
WorldSession * GetSession() const
Definition Player.h:2272
void WhisperAddon(std::string const &text, std::string const &prefix, bool isLogged, Player *receiver)
Definition Player.cpp:22361
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
Definition Player.cpp:27588
ObjectGuid::LowType GetGuildId() const
Definition Player.h:2164
bool IsGameMaster() const
Definition Player.h:1309
void ToggleAFK()
Definition Player.cpp:1188
bool isDND() const
Definition Player.h:1284
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition Player.cpp:21777
void AddWhisperWhiteList(ObjectGuid guid)
Definition Player.h:2868
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
uint8 GetSubGroup() const
Definition Player.h:2802
bool isAFK() const
Definition Player.h:1283
bool isAcceptWhispers() const
Definition Player.h:1307
void Yell(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles yelled message in regular chat based on declared language and in config pre-defined Range.
Definition Player.cpp:22338
void Say(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles said message in regular chat based on declared language and in config pre-defined Range.
Definition Player.cpp:22312
void TextEmote(std::string_view text, WorldObject const *=nullptr, bool=false) override
Outputs an universal text which is supposed to be an action.
Definition Player.cpp:22351
Team GetEffectiveTeam() const
Definition Player.h:2427
void Whisper(std::string_view text, Language language, Player *receiver, bool=false) override
Handles whispers from Addons and players based on sender, receiver's guid and language.
Definition Player.cpp:22379
void ToggleDND()
Definition Player.cpp:1200
Definition Unit.h:635
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1342
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
Definition Unit.cpp:4827
std::forward_list< AuraEffect * > AuraEffectList
Definition Unit.h:652
bool IsAlive() const
Definition Unit.h:1185
void SetEmoteState(Emote emote)
Definition Unit.h:865
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4241
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1657
uint8 GetLevel() const
Definition Unit.h:757
bool IsInCombat() const
Definition Unit.h:1058
std::string const & GetName() const
Definition Object.h:342
size_type size() const
Array< int32, 2 > SpellVisualKitIDs
WorldPacket const * Write() override
void Initialize(ChatMsg chatType, Language language, WorldObject const *sender, WorldObject const *receiver, std::string_view message, uint32 achievementId=0, std::string_view channelName="", LocaleConstant locale=DEFAULT_LOCALE, std::string_view addonPrefix="")
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
OpcodeClient GetOpcode() const
Definition Packet.h:68
char const * GetTrinityString(uint32 entry) const
void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote &chatMessageEmote)
void SendNotification(char const *format,...) ATTR_PRINTF(2
void HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, bool isLogged, std::string target="", Optional< ObjectGuid > targetGuid={})
void HandleEmoteOpcode(WorldPackets::Chat::EmoteClient &packet)
void HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK &chatMessageAFK)
ObjectGuid GetAccountGUID() const
std::string GetPlayerInfo() const
Player * GetPlayer() const
void HandleChatCanLocalWhisperTargetRequest(WorldPackets::Chat::CanLocalWhisperTargetRequest const &canLocalWhisperTargetRequest)
void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel &chatMessageChannel)
ChatMessageResult HandleChatMessage(ChatMsg type, Language lang, std::string msg, std::string target="", Optional< ObjectGuid > targetGuid={})
void SendChatRestricted(ChatRestrictionType restriction)
void SendChatPlayerNotfoundNotice(std::string const &name)
bool CanSpeak() const
void SendPlayerAmbiguousNotice(std::string const &name)
bool HasPermission(uint32 permissionId)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote &packet)
Player * _player
void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper &chatMessageWhisper)
void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage &chatMessage)
void HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND &chatMessageDND)
void HandleChatAddonMessageTargetedOpcode(WorldPackets::Chat::ChatAddonMessageTargeted &chatAddonMessageTargeted)
void HandleChatUpdateAADCStatus(WorldPackets::Chat::UpdateAADCStatus const &updateAADCStatus)
bool ValidateHyperlinksAndMaybeKick(std::string const &str)
void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage &chatAddonMessage)
void HandleChatIgnoredOpcode(WorldPackets::Chat::ChatReportIgnored &chatReportIgnored)
#define sWorld
Definition World.h:916
@ CONFIG_CHAT_CHANNEL_LEVEL_REQ
Definition World.h:319
@ CONFIG_CHAT_YELL_LEVEL_REQ
Definition World.h:323
@ CONFIG_CHAT_WHISPER_LEVEL_REQ
Definition World.h:320
@ CONFIG_CHAT_EMOTE_LEVEL_REQ
Definition World.h:321
@ CONFIG_CHAT_SAY_LEVEL_REQ
Definition World.h:322
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition World.h:210
@ CONFIG_CHAT_PARTY_RAID_WARNINGS
Definition World.h:127
@ CONFIG_CHAT_FAKE_MESSAGE_PREVENTING
Definition World.h:130
@ CONFIG_ADDON_CHANNEL
Definition World.h:106
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition World.h:112
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition World.h:113
time_t GetGameTime()
Definition GameTime.cpp:52
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Player * FindConnectedPlayerByName(std::string_view name)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
@ RBAC_PERM_TWO_SIDE_INTERACTION_CHAT
Definition RBAC.h:78
@ RBAC_PERM_CAN_FILTER_WHISPERS
Definition RBAC.h:89
@ RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ
Definition RBAC.h:72
std::string Name
Definition ObjectMgr.h:899