diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index 397b13a61..c4cc5a36e 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -41,6 +41,7 @@ public: Channel* GetJoinChannel(std::string const& name, uint32 channel_id); Channel* GetChannel(std::string const& name, Player* p, bool pkt = true); + const ChannelMap& GetChannels() const { return channels; } static void LoadChannels(); static void LoadChannelRights(); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index fcd405fa9..338e0665f 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -313,6 +313,78 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName); } +void ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg msgtype, std::string_view message, Language language /*= LANG_UNIVERSAL*/, PlayerChatTag chatTag /*= CHAT_TAG_NONE*/, + ObjectGuid const& senderGuid /*= ObjectGuid()*/, std::string_view senderName /*= nullptr*/, + ObjectGuid const& targetGuid /*= ObjectGuid()*/, std::string_view targetName /*= nullptr*/, + std::string_view channelName /*= nullptr*/, uint32 achievementId /*= 0*/) +{ + const bool isGM = (chatTag & CHAT_TAG_GM) != 0; + bool isAchievement = false; + + data.Initialize((isGM && language != LANG_ADDON) ? SMSG_GM_MESSAGECHAT : SMSG_MESSAGECHAT); + data << uint8(msgtype); + data << uint32(language); + data << ObjectGuid(senderGuid); + data << uint32(0); // 2.1.0 + + switch (msgtype) + { + case CHAT_MSG_MONSTER_SAY: + case CHAT_MSG_MONSTER_PARTY: + case CHAT_MSG_MONSTER_YELL: + case CHAT_MSG_MONSTER_WHISPER: + case CHAT_MSG_MONSTER_EMOTE: + case CHAT_MSG_RAID_BOSS_WHISPER: + case CHAT_MSG_RAID_BOSS_EMOTE: + case CHAT_MSG_BATTLENET: + case CHAT_MSG_WHISPER_FOREIGN: + data << uint32(senderName.size() + 1); + data << senderName; + data << ObjectGuid(targetGuid); // Unit Target + if (targetGuid && !targetGuid.IsPlayer() && !targetGuid.IsPet() && (msgtype != CHAT_MSG_WHISPER_FOREIGN)) + { + data << uint32(targetName.size() + 1); // target name length + data << targetName; // target name + } + break; + case CHAT_MSG_BG_SYSTEM_NEUTRAL: + case CHAT_MSG_BG_SYSTEM_ALLIANCE: + case CHAT_MSG_BG_SYSTEM_HORDE: + data << ObjectGuid(targetGuid); // Unit Target + if (targetGuid && !targetGuid.IsPlayer()) + { + data << uint32(targetName.size() + 1); // target name length + data << targetName; // target name + } + break; + case CHAT_MSG_ACHIEVEMENT: + case CHAT_MSG_GUILD_ACHIEVEMENT: + data << ObjectGuid(targetGuid); // Unit Target + isAchievement = true; + break; + default: + if (isGM) + { + data << uint32(senderName.size() + 1); + data << senderName; + } + + if (msgtype == CHAT_MSG_CHANNEL) + { + data << channelName; + } + data << ObjectGuid(targetGuid); + break; + } + data << uint32(message.size() + 1); + data << message; + data << uint8(chatTag); + + if (isAchievement) + data << uint32(achievementId); +} + + Player* ChatHandler::getSelectedPlayer() const { if (!m_session) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index acb6760db..348058e72 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -34,6 +34,17 @@ class WorldObject; struct GameTele; +enum PlayerChatTag +{ + CHAT_TAG_NONE = 0x00, + CHAT_TAG_AFK = 0x01, + CHAT_TAG_DND = 0x02, + CHAT_TAG_GM = 0x04, + CHAT_TAG_COM = 0x08, // Commentator + CHAT_TAG_DEV = 0x10, // Developer +}; +typedef uint32 ChatTagFlags; + class AC_GAME_API ChatHandler { public: @@ -48,6 +59,13 @@ public: // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string_view message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE); + // All in one chat message builder + static void BuildChatPacket( + WorldPacket& data, ChatMsg msgtype, std::string_view message, Language language = LANG_UNIVERSAL, PlayerChatTag chatTag = CHAT_TAG_NONE, + ObjectGuid const& senderGuid = ObjectGuid(), std::string_view senderName = nullptr, + ObjectGuid const& targetGuid = ObjectGuid(), std::string_view targetName = nullptr, + std::string_view channelName = nullptr, uint32 achievementId = 0); + static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = nullptr; return start; } // function with different implementation for chat/console diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 288c9392e..81b15fd42 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -839,16 +839,6 @@ enum EnviromentalDamage DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss }; -enum PlayerChatTag -{ - CHAT_TAG_NONE = 0x00, - CHAT_TAG_AFK = 0x01, - CHAT_TAG_DND = 0x02, - CHAT_TAG_GM = 0x04, - CHAT_TAG_COM = 0x08, // Commentator tag. Do not exist in clean client - CHAT_TAG_DEV = 0x10, -}; - enum PlayedTimeIndex { PLAYED_TIME_TOTAL = 0,