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 type = group->IsLeader(sender->GetGUID()) ? CHAT_MSG_PARTY_LEADER : CHAT_MSG_PARTY;
360
361 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
362
364 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
365 group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID()));
366 break;
367 }
368 case CHAT_MSG_GUILD:
369 {
370 if (GetPlayer()->GetGuildId())
371 {
372 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
373 {
374 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
375
376 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
377 }
378 }
379 break;
380 }
381 case CHAT_MSG_OFFICER:
382 {
383 if (GetPlayer()->GetGuildId())
384 {
385 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
386 {
387 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
388
389 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
390 }
391 }
392 break;
393 }
394 case CHAT_MSG_RAID:
395 {
396 Group* group = GetPlayer()->GetGroup();
397 if (!group || !group->isRaidGroup() || group->isBGGroup())
399
400 if (group->IsLeader(GetPlayer()->GetGUID()))
402
403 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
404
406 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
407 group->BroadcastPacket(packet.Write(), false);
408 break;
409 }
411 {
412 Group* group = GetPlayer()->GetGroup();
413 if (!group)
415
416 if (group->isRaidGroup())
417 {
418 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
420 }
421 else if (!sWorld->getBoolConfig(CONFIG_CHAT_PARTY_RAID_WARNINGS))
423
424 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
425
427 //in battleground, raid warning is sent only to players in battleground - code is ok
428 packet.Initialize(CHAT_MSG_RAID_WARNING, lang, sender, nullptr, msg);
429 group->BroadcastPacket(packet.Write(), false);
430 break;
431 }
432 case CHAT_MSG_CHANNEL:
433 {
435 {
436 if (sender->GetLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
437 {
440 }
441 }
442
443 Channel* chn = targetGuid
444 ? ChannelMgr::GetChannelForPlayerByGuid(*targetGuid, sender)
446 if (chn)
447 {
448 if (ChatChannelsEntry const* chatChannel = sChatChannelsStore.LookupEntry(chn->GetChannelId()))
449 if (chatChannel->GetFlags().HasFlag(ChatChannelFlags::ReadOnly))
451
452 sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
453 chn->Say(sender->GetGUID(), msg, lang);
454 }
455 break;
456 }
458 {
459 Group* group = GetPlayer()->GetGroup();
460 if (!group)
462
463 if (group->IsLeader(GetPlayer()->GetGUID()))
465
466 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
467
469 packet.Initialize(ChatMsg(type), lang, sender, nullptr, msg);
470 group->BroadcastPacket(packet.Write(), false);
471 break;
472 }
473 default:
474 TC_LOG_ERROR("network", "CHAT: unknown message type {}, lang: {}", type, lang);
475 break;
476 }
477
479}
480
482{
483 HandleChatAddonMessage(chatAddonMessage.Params.Type, chatAddonMessage.Params.Prefix, chatAddonMessage.Params.Text, chatAddonMessage.Params.IsLogged);
484}
485
487{
488 switch (chatAddonMessageTargeted.Params.Type)
489 {
490 case CHAT_MSG_WHISPER:
491 HandleChatAddonMessage(chatAddonMessageTargeted.Params.Type, chatAddonMessageTargeted.Params.Prefix, chatAddonMessageTargeted.Params.Text,
492 chatAddonMessageTargeted.Params.IsLogged, chatAddonMessageTargeted.PlayerName, chatAddonMessageTargeted.PlayerGUID);
493 break;
494 case CHAT_MSG_CHANNEL:
495 HandleChatAddonMessage(chatAddonMessageTargeted.Params.Type, chatAddonMessageTargeted.Params.Prefix, chatAddonMessageTargeted.Params.Text,
496 chatAddonMessageTargeted.Params.IsLogged, chatAddonMessageTargeted.ChannelName, chatAddonMessageTargeted.ChannelGUID);
497 break;
498 default:
499 TC_LOG_ERROR("misc", "HandleChatAddonMessageTargetedOpcode: unknown addon message type {}", chatAddonMessageTargeted.Params.Type);
500 break;
501 }
502}
503
504void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, bool isLogged, std::string target /*= ""*/, Optional<ObjectGuid> targetGuid /*= {}*/)
505{
506 Player* sender = GetPlayer();
507
508 if (prefix.empty() || prefix.length() > 16)
509 return;
510
511 // Disabled addon channel?
512 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
513 return;
514
515 if (!CanSpeak())
516 return;
517
519
520 if (prefix == AddonChannelCommandHandler::PREFIX && AddonChannelCommandHandler(this).ParseCommands(text.c_str()))
521 return;
522
523 if (text.length() > 255)
524 return;
525
526 switch (type)
527 {
528 case CHAT_MSG_GUILD:
529 case CHAT_MSG_OFFICER:
530 {
531 if (sender->GetGuildId())
532 if (Guild* guild = sGuildMgr->GetGuildById(sender->GetGuildId()))
533 guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, text, prefix, isLogged);
534 break;
535 }
536 case CHAT_MSG_WHISPER:
537 {
539 Player* receiver = nullptr;
540 if (targetGuid && !targetGuid->IsEmpty())
541 {
542 receiver = ObjectAccessor::FindConnectedPlayer(*targetGuid);
543 }
544 else
545 {
547
548 if (!normalizePlayerName(extName.Name))
549 break;
550
552 }
553 if (!receiver)
554 break;
555
556 sender->WhisperAddon(text, prefix, isLogged, receiver);
557 break;
558 }
559 // Messages sent to "RAID" while in a party will get delivered to "PARTY"
560 case CHAT_MSG_PARTY:
561 case CHAT_MSG_RAID:
563 {
564 Group* group = nullptr;
565 int32 subGroup = -1;
566 if (type != CHAT_MSG_INSTANCE_CHAT)
567 group = sender->GetOriginalGroup();
568
569 if (!group)
570 {
571 group = sender->GetGroup();
572 if (!group)
573 break;
574
575 if (type == CHAT_MSG_PARTY)
576 subGroup = sender->GetSubGroup();
577 }
578
580 packet.Initialize(type, isLogged ? LANG_ADDON_LOGGED : LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix);
581 group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, subGroup, sender->GetGUID());
582 break;
583 }
584 case CHAT_MSG_CHANNEL:
585 {
586 Channel* chn = targetGuid
587 ? ChannelMgr::GetChannelForPlayerByGuid(*targetGuid, sender)
589 if (chn)
590 chn->AddonSay(sender->GetGUID(), prefix, text.c_str(), isLogged);
591 break;
592 }
593 default:
594 {
595 TC_LOG_ERROR("misc", "HandleAddonMessagechatOpcode: unknown addon message type {}", type);
596 break;
597 }
598 }
599}
600
602{
603 Player* sender = GetPlayer();
604
605 if (sender->IsInCombat())
606 return;
607
608 if (chatMessageAFK.Text.length() > 511)
609 return;
610
611 // do message validity checks
612 if (!ValidateMessage(sender, chatMessageAFK.Text))
613 return;
614
615 if (!ValidateHyperlinksAndMaybeKick(chatMessageAFK.Text))
616 return;
617
618 if (sender->HasAura(GM_SILENCE_AURA))
619 {
621 return;
622 }
623
624 if (sender->isAFK()) // Already AFK
625 {
626 if (chatMessageAFK.Text.empty())
627 sender->ToggleAFK(); // Remove AFK
628 else
629 sender->autoReplyMsg = chatMessageAFK.Text; // Update message
630 }
631 else // New AFK mode
632 {
633 sender->autoReplyMsg = chatMessageAFK.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : chatMessageAFK.Text;
634
635 if (sender->isDND())
636 sender->ToggleDND();
637
638 sender->ToggleAFK();
639 }
640
641 if (Guild* guild = sender->GetGuild())
642 guild->SendEventAwayChanged(sender->GetGUID(), sender->isAFK(), sender->isDND());
643
644 sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, chatMessageAFK.Text);
645}
646
648{
649 Player* sender = GetPlayer();
650
651 if (sender->IsInCombat())
652 return;
653
654 if (chatMessageDND.Text.length() > 511)
655 return;
656
657 // do message validity checks
658 if (!ValidateMessage(sender, chatMessageDND.Text))
659 return;
660
661 if (!ValidateHyperlinksAndMaybeKick(chatMessageDND.Text))
662 return;
663
664 if (sender->HasAura(GM_SILENCE_AURA))
665 {
667 return;
668 }
669
670 if (sender->isDND()) // Already DND
671 {
672 if (chatMessageDND.Text.empty())
673 sender->ToggleDND(); // Remove DND
674 else
675 sender->autoReplyMsg = chatMessageDND.Text; // Update message
676 }
677 else // New DND mode
678 {
679 sender->autoReplyMsg = chatMessageDND.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : chatMessageDND.Text;
680
681 if (sender->isAFK())
682 sender->ToggleAFK();
683
684 sender->ToggleDND();
685 }
686
687 if (Guild* guild = sender->GetGuild())
688 guild->SendEventAwayChanged(sender->GetGUID(), sender->isAFK(), sender->isDND());
689
690 sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, chatMessageDND.Text);
691}
692
694{
695 if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
696 return;
697
698 sScriptMgr->OnPlayerClearEmote(GetPlayer());
699
701}
702
704{
705 if (!_player->IsAlive())
706 return;
707
708 if (!CanSpeak())
709 {
710 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
712 return;
713 }
714
715 sScriptMgr->OnPlayerTextEmote(_player, packet.EmoteID, packet.SoundIndex, packet.Target);
716
717 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(packet.EmoteID);
718 if (!em)
719 return;
720
721 Emote emote = static_cast<Emote>(em->EmoteID);
722
723 switch (emote)
724 {
726 case EMOTE_STATE_SIT:
729 break;
731 case EMOTE_STATE_READ:
732 case EMOTE_STATE_LEAN:
733 _player->SetEmoteState(emote);
734 break;
735 default:
736 // Only allow text-emotes for "dead" entities (feign death included)
738 break;
739 _player->HandleEmoteCommand(emote, nullptr, { packet.SpellVisualKitIDs.data(), packet.SpellVisualKitIDs.data() + packet.SpellVisualKitIDs.size() }, packet.SequenceVariation);
740 break;
741 }
742
744 textEmote.SourceGUID = _player->GetGUID();
745 textEmote.SourceAccountGUID = GetAccountGUID();
746 textEmote.TargetGUID = packet.Target;
747 textEmote.EmoteID = packet.EmoteID;
748 textEmote.SoundIndex = packet.SoundIndex;
749 _player->SendMessageToSetInRange(textEmote.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
750
751 Unit* unit = ObjectAccessor::GetUnit(*_player, packet.Target);
752
754
755 // Send scripted event call
756 if (Creature* creature = Object::ToCreature(unit))
757 creature->AI()->ReceiveEmote(_player, packet.EmoteID);
758
759 if (emote != EMOTE_ONESHOT_NONE)
761}
762
764{
765 Player* player = ObjectAccessor::FindConnectedPlayer(chatReportIgnored.IgnoredGUID);
766 if (!player || !player->GetSession())
767 return;
768
771 player->SendDirectMessage(packet.Write());
772}
773
775{
777}
778
779void WorldSession::SendPlayerAmbiguousNotice(std::string const& name)
780{
782}
783
785{
787 packet.Reason = restriction;
788 SendPacket(packet.Write());
789}
790
792{
793 ChatWhisperTargetStatus status = [&]
794 {
795 Player* sender = GetPlayer();
796 Player* receiver = ObjectAccessor::FindConnectedPlayer(canLocalWhisperTargetRequest.WhisperTarget);
797 if (!receiver || (!receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
799
800 if (!receiver->IsInWhisperWhiteList(sender->GetGUID()) && !receiver->IsGameMasterAcceptingWhispers())
801 if (GetPlayer()->GetEffectiveTeam() != receiver->GetEffectiveTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
803
805 }();
806
807 WorldPackets::Chat::CanLocalWhisperTargetResponse canLocalWhisperTargetResponse;
808 canLocalWhisperTargetResponse.WhisperTarget = canLocalWhisperTargetRequest.WhisperTarget;
809 canLocalWhisperTargetResponse.Status = status;
810 SendPacket(canLocalWhisperTargetResponse.Write());
811}
812
814{
815 // disabling chat not supported
816 // send Sueccess and force chat disabled to false instead of sending that change failed
817 // this makes client change the cvar back to false instead of just printing error message in console
819 response.Success = true;
820 response.ChatDisabled = false;
821 SendPacket(response.Write());
822}
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:182
ExtendedPlayerName ExtractExtendedPlayerName(std::string const &name)
bool normalizePlayerName(std::string &name)
@ CMSG_CHAT_MESSAGE_YELL
Definition Opcodes.h:229
@ CMSG_CHAT_MESSAGE_GUILD
Definition Opcodes.h:221
@ CMSG_CHAT_MESSAGE_INSTANCE_CHAT
Definition Opcodes.h:222
@ CMSG_CHAT_MESSAGE_RAID_WARNING
Definition Opcodes.h:226
@ CMSG_CHAT_MESSAGE_SAY
Definition Opcodes.h:227
@ CMSG_CHAT_MESSAGE_RAID
Definition Opcodes.h:225
@ CMSG_CHAT_MESSAGE_OFFICER
Definition Opcodes.h:223
@ CMSG_CHAT_MESSAGE_PARTY
Definition Opcodes.h:224
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:275
std::string secsToTimeString(uint64 timeInSecs, TimeFormat timeFormat, bool hoursOnly)
Definition Util.cpp:116
ChatRestrictionType
static std::string_view 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:166
void AddonSay(ObjectGuid const &guid, std::string const &prefix, std::string const &what, bool isLogged) const
Definition Channel.cpp:754
void Say(ObjectGuid const &guid, std::string const &what, uint32 lang) const
Definition Channel.cpp:702
Definition Group.h:209
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:1703
bool IsAssistant(ObjectGuid guid) const
Definition Group.h:323
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:1660
void BroadcastAddonMessagePacket(WorldPacket const *packet, const std::string &prefix, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty) const
Definition Group.cpp:945
bool isBGGroup() const
Definition Group.cpp:1603
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignoredPlayer=ObjectGuid::Empty) const
Definition Group.cpp:958
bool isRaidGroup() const
Definition Group.cpp:1598
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:6161
bool IsGameMasterAcceptingWhispers() const
Definition Player.h:1294
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition Player.cpp:30053
std::string autoReplyMsg
Definition Player.h:1270
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6193
Group * GetOriginalGroup() const
Definition Player.h:2800
Guild * GetGuild()
Definition Player.cpp:30428
WorldSession * GetSession() const
Definition Player.h:2256
void WhisperAddon(std::string const &text, std::string const &prefix, bool isLogged, Player *receiver)
Definition Player.cpp:22308
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
Definition Player.cpp:27532
ObjectGuid::LowType GetGuildId() const
Definition Player.h:2147
bool IsGameMaster() const
Definition Player.h:1293
void ToggleAFK()
Definition Player.cpp:1143
bool isDND() const
Definition Player.h:1268
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition Player.cpp:21724
void AddWhisperWhiteList(ObjectGuid guid)
Definition Player.h:2853
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2781
uint8 GetSubGroup() const
Definition Player.h:2787
bool isAFK() const
Definition Player.h:1267
bool isAcceptWhispers() const
Definition Player.h:1291
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:22285
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:22259
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:22298
Team GetEffectiveTeam() const
Definition Player.h:2410
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:22326
void ToggleDND()
Definition Player.cpp:1155
Definition Unit.h:647
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1362
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
Definition Unit.cpp:4845
std::forward_list< AuraEffect * > AuraEffectList
Definition Unit.h:664
bool IsAlive() const
Definition Unit.h:1205
void SetEmoteState(Emote emote)
Definition Unit.h:880
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4259
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1662
uint8 GetLevel() const
Definition Unit.h:769
bool IsInCombat() const
Definition Unit.h:1073
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:919
@ 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:211
@ 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:898