diff options
Diffstat (limited to 'src')
27 files changed, 611 insertions, 295 deletions
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 7f9359053a1..2f99bc0a6cc 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -70,7 +70,9 @@ namespace Trinity private: void do_helper(WorldPacket& data, char const* text) { - ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, text); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, text); + data = *packet.Write(); } ChatMsg _msgtype; @@ -94,7 +96,9 @@ namespace Trinity char str[2048]; snprintf(str, 2048, text, arg1str, arg2str); - ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, str); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, str); + data = *packet.Write(); } private: @@ -1693,11 +1697,12 @@ void Battleground::SendWarningToAll(uint32 entry, ...) if (!entry) return; - std::map<uint32, WorldPacket> localizedPackets; + std::map<uint32, WorldPackets::Chat::Chat> localizedPackets; for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) if (Player* player = _GetPlayer(itr, "SendWarningToAll")) { - if (localizedPackets.find(player->GetSession()->GetSessionDbLocaleIndex()) == localizedPackets.end()) + auto packetItr = localizedPackets.find(player->GetSession()->GetSessionDbLocaleIndex()); + if (packetItr == localizedPackets.end()) { char const* format = sObjectMgr->GetTrinityString(entry, player->GetSession()->GetSessionDbLocaleIndex()); @@ -1707,10 +1712,10 @@ void Battleground::SendWarningToAll(uint32 entry, ...) vsnprintf(str, 1024, format, ap); va_end(ap); - ChatHandler::BuildChatPacket(localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()], CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str); + ChatHandler::BuildChatPacket(&packetItr->second, CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str); } - player->SendDirectMessage(&localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()]); + player->SendDirectMessage(packetItr->second.Write()); } } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 65f07b625e1..7695ab45de0 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -622,13 +622,17 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) return; } - WorldPacket data; + WorldPackets::Chat::Chat packet; if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); else - ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name); + { + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), NULL, NULL, what, 0, _name); + packet.SenderGUID = guid; + packet.TargetGUID = guid; + } - SendToAll(&data, !playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty); + SendToAll(packet.Write(), !playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty); } void Channel::Invite(Player const* player, std::string const& newname) @@ -722,7 +726,7 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim) } } -void Channel::SendToAll(WorldPacket* data, ObjectGuid guid) +void Channel::SendToAll(WorldPacket const* data, ObjectGuid guid) { for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) @@ -730,7 +734,7 @@ void Channel::SendToAll(WorldPacket* data, ObjectGuid guid) player->GetSession()->SendPacket(data); } -void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who) +void Channel::SendToAllButOne(WorldPacket const* data, ObjectGuid who) { for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) if (i->first != who) @@ -738,7 +742,7 @@ void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who) player->GetSession()->SendPacket(data); } -void Channel::SendToOne(WorldPacket* data, ObjectGuid who) +void Channel::SendToOne(WorldPacket const* data, ObjectGuid who) { if (Player* player = ObjectAccessor::FindConnectedPlayer(who)) player->GetSession()->SendPacket(data); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 6489c8b47ad..f1f01e64f44 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -226,9 +226,9 @@ class Channel void MakeVoiceOn(WorldPacket* data, ObjectGuid guid); //+ 0x22 void MakeVoiceOff(WorldPacket* data, ObjectGuid guid); //+ 0x23 - void SendToAll(WorldPacket* data, ObjectGuid guid = ObjectGuid::Empty); - void SendToAllButOne(WorldPacket* data, ObjectGuid who); - void SendToOne(WorldPacket* data, ObjectGuid who); + void SendToAll(WorldPacket const* data, ObjectGuid guid = ObjectGuid::Empty); + void SendToAllButOne(WorldPacket const* data, ObjectGuid who); + void SendToOne(WorldPacket const* data, ObjectGuid who); bool IsOn(ObjectGuid who) const { return playersStore.find(who) != playersStore.end(); } bool IsBanned(ObjectGuid guid) const { return bannedStore.find(guid) != bannedStore.end(); } diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index ec3bc458066..fa89dca294c 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -35,6 +35,8 @@ #include "SpellMgr.h" #include "ScriptMgr.h" #include "ChatLink.h" +#include "Guild.h" +#include "Group.h" bool ChatHandler::load_command_table = true; @@ -202,7 +204,7 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part) void ChatHandler::SendSysMessage(const char *str) { - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -210,8 +212,8 @@ void ChatHandler::SendSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - m_session->SendPacket(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + m_session->SendPacket(packet.Write()); } free(buf); @@ -220,7 +222,7 @@ void ChatHandler::SendSysMessage(const char *str) void ChatHandler::SendGlobalSysMessage(const char *str) { // Chat output - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -228,8 +230,8 @@ void ChatHandler::SendGlobalSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - sWorld->SendGlobalMessage(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + sWorld->SendGlobalMessage(packet.Write()); } free(buf); @@ -238,7 +240,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str) void ChatHandler::SendGlobalGMSysMessage(const char *str) { // Chat output - WorldPacket data; + WorldPackets::Chat::Chat packet; // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); @@ -246,8 +248,8 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - sWorld->SendGlobalGMMessage(&data); + BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + sWorld->SendGlobalGMMessage(packet.Write()); } free(buf); @@ -628,132 +630,55 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd) return ShowHelpForSubCommands(table, "", cmd); } -size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag, - std::string const& senderName /*= ""*/, std::string const& receiverName /*= ""*/, - uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/, - std::string const& addonPrefix /*= ""*/) +void ChatHandler::BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, + uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/) { - size_t receiverGUIDPos = 0; - data.Initialize(!gmMessage ? SMSG_MESSAGECHAT : SMSG_GM_MESSAGECHAT); - data << uint8(chatType); - data << int32(language); - data << senderGUID; - data << uint32(0); // some flags - switch (chatType) - { - 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_EMOTE: - case CHAT_MSG_RAID_BOSS_WHISPER: - case CHAT_MSG_BATTLENET: - data << uint32(senderName.length() + 1); - data << senderName; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer() && !receiverGUID.IsPet()) - { - data << uint32(receiverName.length() + 1); - data << receiverName; - } - - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_WHISPER_FOREIGN: - data << uint32(senderName.length() + 1); - data << senderName; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_BG_SYSTEM_NEUTRAL: - case CHAT_MSG_BG_SYSTEM_ALLIANCE: - case CHAT_MSG_BG_SYSTEM_HORDE: - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer()) - { - data << uint32(receiverName.length() + 1); - data << receiverName; - } - - if (language == LANG_ADDON) - data << addonPrefix; - break; - case CHAT_MSG_ACHIEVEMENT: - case CHAT_MSG_GUILD_ACHIEVEMENT: - receiverGUIDPos = data.wpos(); - data << receiverGUID; - if (language == LANG_ADDON) - data << addonPrefix; - break; - default: - if (gmMessage) - { - data << uint32(senderName.length() + 1); - data << senderName; - } - - if (chatType == CHAT_MSG_CHANNEL) - { - ASSERT(channelName.length() > 0); - data << channelName; - } + // Clear everything because same packet can be used multiple times + packet->SenderGUID.Clear(); + packet->SenderAccountGUID.Clear(); + packet->SenderGuildGUID.Clear(); + packet->PartyGUID.Clear(); + packet->TargetGUID.Clear(); + packet->SenderName.clear(); + packet->TargetName.clear(); + packet->ChatFlags = CHAT_FLAG_NONE; + + packet->SlashCmd = chatType; + packet->Language = language; - receiverGUIDPos = data.wpos(); - data << receiverGUID; - - if (language == LANG_ADDON) - data << addonPrefix; - break; - } - - data << uint32(message.length() + 1); - data << message; - data << uint8(chatTag); - - if (chatType == CHAT_MSG_ACHIEVEMENT || chatType == CHAT_MSG_GUILD_ACHIEVEMENT) - data << uint32(achievementId); - else if (chatType == CHAT_MSG_RAID_BOSS_WHISPER || chatType == CHAT_MSG_RAID_BOSS_EMOTE) + if (sender) { - data << float(0.0f); // Display time in middle of the screen (in seconds), defaults to 10 if not set (cannot be below 1) - data << uint8(0); // Hide in chat frame (only shows in middle of the screen) - } + packet->SenderGUID = sender->GetGUID(); - return receiverGUIDPos; -} + if (Creature const* creatureSender = sender->ToCreature()) + packet->SenderName = creatureSender->GetNameForLocaleIdx(locale); -size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, - uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/) -{ - ObjectGuid senderGUID; - std::string senderName = ""; - uint8 chatTag = 0; - bool gmMessage = false; - ObjectGuid receiverGUID; - std::string receiverName = ""; - if (sender) - { - senderGUID = sender->GetGUID(); - senderName = sender->GetNameForLocaleIdx(locale); if (Player const* playerSender = sender->ToPlayer()) { - chatTag = playerSender->GetChatTag(); - gmMessage = playerSender->GetSession()->HasPermission(rbac::RBAC_PERM_COMMAND_GM_CHAT); + packet->SenderAccountGUID = ObjectGuid::Create<HighGuid::WowAccount>(playerSender->GetSession()->GetAccountId()); + packet->ChatFlags = playerSender->GetChatFlags(); + + if (Guild const* guild = playerSender->GetGuild()) + packet->SenderGuildGUID = guild->GetGUID(); + + if (Group const* group = playerSender->GetGroup()) + packet->PartyGUID = group->GetGUID(); } } if (receiver) { - receiverGUID = receiver->GetGUID(); - receiverName = receiver->GetNameForLocaleIdx(locale); + packet->TargetGUID = receiver->GetGUID(); + if (Creature const* creatureReceiver = receiver->ToCreature()) + packet->TargetName = creatureReceiver->GetNameForLocaleIdx(locale); } - return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName, addonPrefix); + packet->SenderVirtualAddress = GetVirtualRealmAddress(); + packet->TargetVirtualAddress = GetVirtualRealmAddress(); + packet->AchievementID = achievementId; + packet->Channel = channelName; + packet->Prefix = addonPrefix; + packet->ChatText = message; } Player* ChatHandler::getSelectedPlayer() diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 98c3bc3efbb..5db48db0fbe 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -22,6 +22,7 @@ #include "SharedDefines.h" #include "WorldSession.h" #include "RBAC.h" +#include "Packets/ChatPackets.h" #include <vector> @@ -53,14 +54,7 @@ class ChatHandler explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) { } virtual ~ChatHandler() { } - // 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, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag, - std::string const& senderName = "", std::string const& receiverName = "", - uint32 achievementId = 0, bool gmMessage = false, std::string const& channelName = "", - std::string const& addonPrefix = ""); - - // 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 const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = ""); + static void BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = ""); static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = NULL; return start; } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e482e0a449d..70612910797 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2359,19 +2359,19 @@ void Object::ForceValuesUpdateAtIndex(uint32 i) } } -void WorldObject::SendMessageToSet(WorldPacket* data, bool self) +void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self); } -void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/) +void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/) { Trinity::MessageDistDeliverer notifier(this, data, dist); VisitNearbyWorldObject(dist, notifier); } -void WorldObject::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) +void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) { Trinity::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr); VisitNearbyWorldObject(GetVisibilityRange(), notifier); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index bae3a8b07c1..d2dd0108d20 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -661,9 +661,9 @@ class WorldObject : public Object, public WorldLocation virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units - virtual void SendMessageToSet(WorldPacket* data, bool self); - virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self); - virtual void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); + virtual void SendMessageToSet(WorldPacket const* data, bool self); + virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self); + virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr); virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ae8f0191137..67f533f0833 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -87,6 +87,7 @@ #include "WorldSession.h" #include "WorldStatePackets.h" #include "MiscPackets.h" +#include "ChatPackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -1930,18 +1931,18 @@ void Player::ToggleDND() ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); } -uint8 Player::GetChatTag() const +uint8 Player::GetChatFlags() const { - uint8 tag = CHAT_TAG_NONE; + uint8 tag = CHAT_FLAG_NONE; if (isGMChat()) - tag |= CHAT_TAG_GM; + tag |= CHAT_FLAG_GM; if (isDND()) - tag |= CHAT_TAG_DND; + tag |= CHAT_FLAG_DND; if (isAFK()) - tag |= CHAT_TAG_AFK; + tag |= CHAT_FLAG_AFK; if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) - tag |= CHAT_TAG_DEV; + tag |= CHAT_FLAG_DEV; return tag; } @@ -6346,7 +6347,7 @@ void Player::SaveRecallPosition() m_recallO = GetOrientation(); } -void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self) +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) { if (self) GetSession()->SendPacket(data); @@ -6355,7 +6356,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self) VisitNearbyWorldObject(dist, notifier); } -void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only) +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only) { if (self) GetSession()->SendPacket(data); @@ -6364,7 +6365,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, b VisitNearbyWorldObject(dist, notifier); } -void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) +void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) { if (skipped_rcvr != this) GetSession()->SendPacket(data); @@ -6375,7 +6376,7 @@ void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) VisitNearbyWorldObject(GetVisibilityRange(), notifier); } -void Player::SendDirectMessage(WorldPacket const* data) +void Player::SendDirectMessage(WorldPacket const* data) const { m_session->SendPacket(data); } @@ -20416,9 +20417,9 @@ void Player::Say(std::string const& text, Language language, WorldObject const* std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SAY, language, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } void Player::Yell(std::string const& text, Language language, WorldObject const* /*= nullptr*/) @@ -20426,9 +20427,9 @@ void Player::Yell(std::string const& text, Language language, WorldObject const* std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_YELL, language, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); } void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/, bool /*= false*/) @@ -20436,9 +20437,9 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/ std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); + SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } void Player::WhisperAddon(std::string const& text, const std::string& prefix, Player* receiver) @@ -20449,9 +20450,9 @@ void Player::WhisperAddon(std::string const& text, const std::string& prefix, Pl if (!receiver->GetSession()->IsAddonRegistered(prefix)) return; - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); - receiver->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); + receiver->GetSession()->SendPacket(packet.Write()); } void Player::Whisper(std::string const& text, Language language, Player* target, bool /*= false*/) @@ -20466,16 +20467,16 @@ void Player::Whisper(std::string const& text, Language language, Player* target, std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target); - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text); - target->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, Language(language), this, this, _text); + target->GetSession()->SendPacket(packet.Write()); // rest stuff shouldn't happen in case of addon message if (isAddonMessage) return; - ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); - GetSession()->SendPacket(&data); + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); + GetSession()->SendPacket(packet.Write()); if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster()) { @@ -26742,7 +26743,13 @@ std::string Player::GetCoordsMapAreaAndZoneString() Guild* Player::GetGuild() { ObjectGuid::LowType guildId = GetGuildId(); - return guildId ? sGuildMgr->GetGuildById(guildId) : NULL; + return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; +} + +Guild const* Player::GetGuild() const +{ + ObjectGuid::LowType guildId = GetGuildId(); + return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; } Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 1dd993e5b5f..5f3eda1d69d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -858,18 +858,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 - CHAT_TAG_DEV = 0x10, - CHAT_TAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper - CHAT_TAG_MOBILE = 0x40 -}; - enum PlayedTimeIndex { PLAYED_TIME_TOTAL = 0, @@ -1314,7 +1302,7 @@ class Player : public Unit, public GridObject<Player> void ToggleDND(); bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); } bool isDND() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); } - uint8 GetChatTag() const; + uint8 GetChatFlags() const; std::string autoReplyMsg; uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL); @@ -1968,6 +1956,7 @@ class Player : public Unit, public GridObject<Player> void SetGuildIdInvited(ObjectGuid::LowType GuildId) { m_GuildIdInvited = GuildId; } ObjectGuid::LowType GetGuildId() const { return GetUInt64Value(OBJECT_FIELD_DATA); /* return only lower part */ } Guild* GetGuild(); + Guild const* GetGuild() const; static ObjectGuid::LowType GetGuildIdFromDB(ObjectGuid guid); static uint8 GetRankFromDB(ObjectGuid guid); ObjectGuid::LowType GetGuildIdInvited() { return m_GuildIdInvited; } @@ -2089,10 +2078,10 @@ class Player : public Unit, public GridObject<Player> bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } void UpdateUnderwaterState(Map* m, float x, float y, float z) override; - void SendMessageToSet(WorldPacket* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet - void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange - void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only); - void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) override; + void SendMessageToSet(WorldPacket const* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet + void SendMessageToSetInRange(WorldPacket const* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange + void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only); + void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) override; Corpse* GetCorpse() const; void SpawnCorpseBones(); @@ -2245,7 +2234,7 @@ class Player : public Unit, public GridObject<Player> void SendInitWorldStates(uint32 zone, uint32 area); void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false); - void SendDirectMessage(WorldPacket const* data); + void SendDirectMessage(WorldPacket const* data) const; void SendBGWeekendWorldStates(); void SendBattlefieldWorldStates(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 89ded594990..b7cefedec87 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -62,6 +62,7 @@ #include "WorldPacket.h" #include "MovementStructures.h" #include "WorldSession.h" +#include "ChatPackets.h" #include <cmath> @@ -16766,9 +16767,9 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b return; LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket data; - ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); - target->SendDirectMessage(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); + target->SendDirectMessage(packet.Write()); } void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target) @@ -16813,7 +16814,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ } LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket data; - ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); - target->SendDirectMessage(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); + target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index ae3bef5a8df..b693d2e13ac 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -33,6 +33,7 @@ #include "CreatureAI.h" #include "Spell.h" #include "WorldSession.h" +#include "Packets/ChatPackets.h" class Player; //class Map; @@ -125,11 +126,11 @@ namespace Trinity struct MessageDistDeliverer { WorldObject* i_source; - WorldPacket* i_message; + WorldPacket const* i_message; float i_distSq; uint32 team; Player const* skipped_receiver; - MessageDistDeliverer(WorldObject* src, WorldPacket* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) + MessageDistDeliverer(WorldObject* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) : i_source(src), i_message(msg), i_distSq(dist * dist) , team(0) , skipped_receiver(skipped) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c4e4b6f21ae..85e78071d01 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1623,7 +1623,7 @@ void Group::UpdatePlayerOutOfRange(Player* player) } } -void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/) +void Group::BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1638,7 +1638,7 @@ void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& } } -void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer) +void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -1651,7 +1651,7 @@ void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int } } -void Group::BroadcastReadyCheck(WorldPacket* packet) +void Group::BroadcastReadyCheck(WorldPacket const* packet) { for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 0bdfbf24a71..6216b7323b0 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -288,9 +288,9 @@ class Group worker(itr->GetSource()); } - void BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); - void BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); - void BroadcastReadyCheck(WorldPacket* packet); + void BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); + void BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); + void BroadcastReadyCheck(WorldPacket const* packet); void OfflineReadyCheck(); /*********************************************************/ diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4fb361209c1..b99ac0496e6 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -30,6 +30,7 @@ #include "ScriptMgr.h" #include "SocialMgr.h" #include "Opcodes.h" +#include "ChatPackets.h" #define MAX_GUILD_BANK_TAB_TEXT_LEN 500 #define EMBLEM_PRICE 10 * GOLD @@ -2593,13 +2594,14 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg); + WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindConnectedPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID())) - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(data); } } @@ -2607,14 +2609,15 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: { if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix); + WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID()) && player->GetSession()->IsAddonRegistered(prefix)) - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(data); } } diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index a2fc248bb61..ce1f0f8ea2d 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -39,7 +39,260 @@ #include "Util.h" #include "ScriptMgr.h" #include "AccountMgr.h" +#include "ChatPackets.h" +void WorldSession::HandleMessagechatOpcode(WorldPackets::Chat::ChatMessage& packet) +{ + uint32 type = 0; + uint32 lang = packet.Language; + std::string msg = packet.Text; + + switch (packet.GetOpcode()) + { + case CMSG_MESSAGECHAT_SAY: + type = CHAT_MSG_SAY; + break; + case CMSG_MESSAGECHAT_YELL: + type = CHAT_MSG_YELL; + break; + case CMSG_MESSAGECHAT_GUILD: + type = CHAT_MSG_GUILD; + break; + case CMSG_MESSAGECHAT_OFFICER: + type = CHAT_MSG_OFFICER; + break; + case CMSG_MESSAGECHAT_PARTY: + type = CHAT_MSG_PARTY; + break; + case CMSG_MESSAGECHAT_RAID: + type = CHAT_MSG_RAID; + break; + case CMSG_MESSAGECHAT_RAID_WARNING: + type = CHAT_MSG_RAID_WARNING; + break; + default: + TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", packet.GetOpcode()); + return; + } + + Player* sender = GetPlayer(); + + if (packet.Language == LANG_UNIVERSAL) + { + TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); + SendNotification(LANG_UNKNOWN_LANGUAGE); + return; + } + + // prevent talking at unknown language (cheating) + LanguageDesc const* langDesc = GetLanguageDescByID(lang); + if (!langDesc) + { + SendNotification(LANG_UNKNOWN_LANGUAGE); + return; + } + + if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) + { + // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) + Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); + bool foundAura = false; + for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) + { + if ((*i)->GetMiscValue() == int32(lang)) + { + foundAura = true; + break; + } + } + if (!foundAura) + { + SendNotification(LANG_NOT_LEARNED_LANGUAGE); + return; + } + } + + // send in universal language if player in .gm on mode (ignore spell effects) + if (sender->IsGameMaster()) + lang = LANG_UNIVERSAL; + else + { + // send in universal language in two side iteration allowed mode + if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) + lang = LANG_UNIVERSAL; + else + { + switch (type) + { + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + case CHAT_MSG_RAID_WARNING: + // allow two side chat at group channel if two side group allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) + lang = LANG_UNIVERSAL; + break; + case CHAT_MSG_GUILD: + case CHAT_MSG_OFFICER: + // allow two side chat at guild channel if two side guild allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) + lang = LANG_UNIVERSAL; + break; + } + } + + // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) + Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); + if (!ModLangAuras.empty()) + lang = ModLangAuras.front()->GetMiscValue(); + } + + if (!sender->CanSpeak()) + { + std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); + return; + } + + if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) + { + SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); + return; + } + + if (msg.empty()) + return; + + if (ChatHandler(this).ParseCommands(msg.c_str())) + return; + + // Strip invisible characters for non-addon messages + if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + stripLineInvisibleChars(msg); + + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) + { + TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), + GetPlayer()->GetGUID().ToString().c_str(), msg.c_str()); + + if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) + KickPlayer(); + + return; + } + + switch (type) + { + case CHAT_MSG_SAY: + case CHAT_MSG_YELL: + { + // Prevent cheating + if (!sender->IsAlive()) + return; + + if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) + { + SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); + return; + } + + if (type == CHAT_MSG_SAY) + sender->Say(msg, Language(lang)); + else if (type == CHAT_MSG_EMOTE) + sender->TextEmote(msg); + else if (type == CHAT_MSG_YELL) + sender->Yell(msg, Language(lang)); + break; + } + case CHAT_MSG_PARTY: + { + // if player is in battleground, he cannot say to battleground members by /p + Group* group = GetPlayer()->GetOriginalGroup(); + if (!group) + { + group = sender->GetGroup(); + if (!group || group->isBGGroup()) + return; + } + + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_PARTY_LEADER; + + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); + + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID())); + break; + } + case CHAT_MSG_GUILD: + { + if (GetPlayer()->GetGuildId()) + { + if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) + { + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); + + guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); + } + } + break; + } + case CHAT_MSG_OFFICER: + { + if (GetPlayer()->GetGuildId()) + { + if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) + { + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); + + guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); + } + } + break; + } + case CHAT_MSG_RAID: + { + // if player is in battleground, he cannot say to battleground members by /ra + Group* group = GetPlayer()->GetOriginalGroup(); + if (!group) + { + group = GetPlayer()->GetGroup(); + if (!group || group->isBGGroup() || !group->isRaidGroup()) + return; + } + + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_RAID_LEADER; + + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); + + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false); + break; + } + case CHAT_MSG_RAID_WARNING: + { + Group* group = GetPlayer()->GetGroup(); + if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) + return; + + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); + + WorldPackets::Chat::Chat packet; + //in battleground, raid warning is sent only to players in battleground - code is ok + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); + group->BroadcastPacket(packet.Write(), false); + break; + } + default: + TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); + break; + } +} + + +/** Left in here until all chat messages are moved to new packets void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { uint32 type = 0; @@ -47,7 +300,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) switch (recvData.GetOpcode()) { - /* case CMSG_MESSAGECHAT_SAY: type = CHAT_MSG_SAY; break; @@ -87,7 +339,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) case CMSG_MESSAGECHAT_RAID_WARNING: type = CHAT_MSG_RAID_WARNING; break; - */ default: TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", recvData.GetOpcode()); recvData.hexlike(); @@ -535,7 +786,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } -} +}*/ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) { @@ -627,9 +878,9 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) if (!group || !group->isBGGroup()) return; - WorldPacket data; - ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); - group->BroadcastAddonMessagePacket(&data, prefix, false); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); + group->BroadcastAddonMessagePacket(packet.Write(), prefix, false); break; } case CHAT_MSG_GUILD: @@ -660,9 +911,9 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) if (!group || group->isBGGroup()) break; - WorldPacket data; - ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); - group->BroadcastAddonMessagePacket(&data, prefix, true, -1, sender->GetGUID()); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix); + group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, -1, sender->GetGUID()); break; } default: @@ -718,6 +969,7 @@ namespace Trinity void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) { + /* if (!GetPlayer()->IsAlive()) return; @@ -780,6 +1032,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) //Send scripted event call if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote); + */ } void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) @@ -811,9 +1064,9 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) if (!player || !player->GetSession()) return; - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); - player->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); + player->GetSession()->SendPacket(packet.Write()); } void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 4c44a4f94a1..2b5c2e9e052 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -4131,6 +4131,18 @@ enum ChatMsg #define MAX_CHAT_MSG_TYPE 0x41 +enum ChatFlags +{ + CHAT_FLAG_NONE = 0x00, + CHAT_FLAG_AFK = 0x01, + CHAT_FLAG_DND = 0x02, + CHAT_FLAG_GM = 0x04, + CHAT_FLAG_COM = 0x08, // Commentator + CHAT_FLAG_DEV = 0x10, + CHAT_FLAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper + CHAT_FLAG_MOBILE = 0x40 +}; + enum ChatLinkColors { CHAT_LINK_COLOR_TRADE = 0xffffd000, // orange diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp new file mode 100644 index 00000000000..6b544480a71 --- /dev/null +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ChatPackets.h" + +void WorldPackets::Chat::ChatMessage::Read() +{ + _worldPacket >> Language; + uint32 len = _worldPacket.ReadBits(8); + Text = _worldPacket.ReadString(len); +} + +WorldPacket const* WorldPackets::Chat::Chat::Write() +{ + _worldPacket << SlashCmd; + _worldPacket << Language; + _worldPacket << SenderGUID; + _worldPacket << SenderGuildGUID; + _worldPacket << SenderAccountGUID; + _worldPacket << TargetGUID; + _worldPacket << TargetVirtualAddress; + _worldPacket << SenderVirtualAddress; + _worldPacket << PartyGUID; + _worldPacket << AchievementID; + _worldPacket << DisplayTime; + _worldPacket.WriteBits(SenderName.length(), 11); + _worldPacket.WriteBits(TargetName.length(), 11); + _worldPacket.WriteBits(Prefix.length(), 5); + _worldPacket.WriteBits(Channel.length(), 7); + _worldPacket.WriteBits(ChatText.length(), 12); + _worldPacket.WriteBits(ChatFlags, 10); + _worldPacket.WriteBit(HideChatLog); + _worldPacket.WriteBit(FakeSenderName); + _worldPacket.WriteString(SenderName); + _worldPacket.WriteString(TargetName); + _worldPacket.WriteString(Prefix); + _worldPacket.WriteString(Channel); + _worldPacket.WriteString(ChatText); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h new file mode 100644 index 00000000000..4aa49312daf --- /dev/null +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ChatPackets_h__ +#define ChatPackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Chat + { + class ChatMessage final : public ClientPacket + { + public: + ChatMessage(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + std::string Text; + int32 Language = LANG_UNIVERSAL; + }; + + class Chat final : public ServerPacket + { + public: + Chat() : ServerPacket(SMSG_MESSAGECHAT, 1+1+8+8+8+8+8+4+4+4+1+4+20) { } + + WorldPacket const* Write() override; + + uint8 SlashCmd = 0; + uint8 Language = LANG_UNIVERSAL; + ObjectGuid SenderGUID; + ObjectGuid SenderGuildGUID; + ObjectGuid SenderAccountGUID; // Not in JAM messages but appears in packet? + ObjectGuid TargetGUID; + ObjectGuid PartyGUID; + uint32 SenderVirtualAddress; + uint32 TargetVirtualAddress; + std::string SenderName; + std::string TargetName; + std::string Prefix; + std::string Channel; + std::string ChatText; + uint32 AchievementID = 0; + uint8 ChatFlags = 0; + float DisplayTime = 0.0f; + bool HideChatLog = false; + bool FakeSenderName = false; + }; + } +} + +#endif // ChatPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 84efecae188..9699d519fd3 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -19,6 +19,7 @@ #include "Opcodes.h" #include "WorldSession.h" #include "Packets/CharacterPackets.h" +#include "Packets/ChatPackets.h" #include "Packets/ClientConfigPackets.h" #include "Packets/CombatPackets.h" #include "Packets/GuildPackets.h" @@ -409,19 +410,19 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_DND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_OFFICER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_SAY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_YELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_DND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_MESSAGECHAT_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_SAY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_HANDLER(CMSG_MESSAGECHAT_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleMessagechatOpcode); + DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIGAME_MOVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode ); @@ -1072,7 +1073,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_UNHANDLED); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index aeb5bada68c..1fd3250d8ca 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -366,10 +366,10 @@ enum OpcodeClient : uint32 CMSG_MESSAGECHAT_DND = 0x0AAB, CMSG_MESSAGECHAT_EMOTE = 0x113C, CMSG_MESSAGECHAT_GUILD = 0x0B1B, - CMSG_MESSAGECHAT_OFFICER = 0xBADD, + CMSG_MESSAGECHAT_OFFICER = 0x0114, CMSG_MESSAGECHAT_PARTY = 0x0134, - CMSG_MESSAGECHAT_RAID = 0xBADD, - CMSG_MESSAGECHAT_RAID_WARNING = 0xBADD, + CMSG_MESSAGECHAT_RAID = 0x0B33, + CMSG_MESSAGECHAT_RAID_WARNING = 0x0313, CMSG_MESSAGECHAT_SAY = 0x1884, CMSG_MESSAGECHAT_WHISPER = 0x1829, CMSG_MESSAGECHAT_YELL = 0x1161, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index b508acb604e..3eaf30bd779 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -102,6 +102,11 @@ namespace WorldPackets class UserClientUpdateAccountData; } + namespace Chat + { + class ChatMessage; + } + namespace Combat { class AttackSwing; @@ -815,7 +820,7 @@ class WorldSession void HandlePushQuestToParty(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket); - void HandleMessagechatOpcode(WorldPacket& recvPacket); + void HandleMessagechatOpcode(WorldPackets::Chat::ChatMessage& packet); void HandleAddonMessagechatOpcode(WorldPacket& recvPacket); void SendPlayerNotFoundNotice(std::string const& name); void SendPlayerAmbiguousNotice(std::string const& name); diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index 72f80bb07a3..a4834d555d3 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -20,6 +20,7 @@ #include "Chat.h" #include "ObjectMgr.h" +#include "Packets/ChatPackets.h" namespace Trinity { @@ -32,13 +33,9 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); - } - - size_t operator()(WorldPacket* data, LocaleConstant locale) const - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); + data = *packet.Write(); } private: @@ -57,7 +54,9 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { - ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, _language, _source, _target, _text, 0, "", locale); + data = *packet.Write(); } private: diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 77819b87ec0..07d0bd53629 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -24,6 +24,7 @@ #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CreatureTextMgr.h" +#include "ChatPackets.h" class CreatureTextBuilder { @@ -31,11 +32,12 @@ class CreatureTextBuilder CreatureTextBuilder(WorldObject const* obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) : _source(obj), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } - size_t operator()(WorldPacket* data, LocaleConstant locale) const + void operator()(WorldPacket& data, LocaleConstant locale) const { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); - - return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _source, _target, text, 0, "", locale); + data = *packet.Write(); } private: @@ -54,11 +56,12 @@ class PlayerTextBuilder PlayerTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) : _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } - size_t operator()(WorldPacket* data, LocaleConstant locale) const + void operator()(WorldPacket& data, LocaleConstant locale) const { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); - - return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _talker, _target, text, 0, "", locale); + WorldPackets::Chat::Chat packet; + return ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _talker, _target, text, 0, "", locale); + data = *packet.Write(); } private: diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index 06efadb1dc7..647d8249e68 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -24,6 +24,7 @@ #include "SharedDefines.h" #include "Opcodes.h" #include "Group.h" +#include "Packets/ChatPackets.h" enum CreatureTextRange { @@ -133,50 +134,38 @@ class CreatureTextLocalizer ~CreatureTextLocalizer() { for (size_t i = 0; i < _packetCache.size(); ++i) - { - if (_packetCache[i]) - delete _packetCache[i]->first; delete _packetCache[i]; - } } void operator()(Player* player) { LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket* messageTemplate; - size_t whisperGUIDpos; + WorldPackets::Chat::Chat* messageTemplate; // create if not cached yet if (!_packetCache[loc_idx]) { - messageTemplate = new WorldPacket(); - whisperGUIDpos = _builder(messageTemplate, loc_idx); - ASSERT(messageTemplate->GetOpcode() != NULL_OPCODE); - _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos); + messageTemplate = new WorldPackets::Chat::Chat(); + _packetCache[loc_idx] = messageTemplate; } else - { - messageTemplate = _packetCache[loc_idx]->first; - whisperGUIDpos = _packetCache[loc_idx]->second; - } + messageTemplate = _packetCache[loc_idx]; - WorldPacket data(*messageTemplate); switch (_msgType) { case CHAT_MSG_MONSTER_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: - // TODO: Fix this. GUIDs are now always written packed and can have different packed lengths - //data.put<uint64>(whisperGUIDpos, player->GetGUID().GetRawValue()); + messageTemplate->TargetGUID = player->GetGUID(); break; default: break; } - player->SendDirectMessage(&data); + player->SendDirectMessage(messageTemplate->Write()); } private: - std::vector<std::pair<WorldPacket*, size_t>* > _packetCache; + std::vector<WorldPackets::Chat::Chat*> _packetCache; Builder const& _builder; ChatMsg _msgType; }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 098181c76a1..a7a5a8ae7bb 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -64,6 +64,7 @@ #include "WaypointMovementGenerator.h" #include "WeatherMgr.h" #include "WorldSession.h" +#include "ChatPackets.h" #include <boost/algorithm/string.hpp> @@ -2287,7 +2288,9 @@ namespace Trinity while (char* line = lineFromMessage(pos)) { WorldPacket* data = new WorldPacket(); - ChatHandler::BuildChatPacket(*data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + *data = *packet.Write(); data_list.push_back(data); } } @@ -2345,16 +2348,15 @@ void World::SendGMText(uint32 string_id, ...) /// DEPRECATED, only for debug purpose. Send a System Message to all players (except self if mentioned) void World::SendGlobalText(const char* text, WorldSession* self) { - WorldPacket data; - // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(text); char* pos = buf; while (char* line = ChatHandler::LineFromMessage(pos)) { - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); - SendGlobalMessage(&data, self); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + SendGlobalMessage(packet.Write(), self); } free(buf); @@ -2386,9 +2388,9 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession /// Send a System Message to all players in the zone (except self if mentioned) void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team) { - WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text); - SendZoneMessage(zone, &data, self, team); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text); + SendZoneMessage(zone, packet.Write(), self, team); } /// Kick (and save) all players diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 0c37b1491c3..db8ebe62775 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -481,9 +481,9 @@ public: char const* msg = "testtest"; uint8 type = atoi(args); - WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); - handler->GetSession()->SendPacket(&data); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); + handler->GetSession()->SendPacket(packet.Write()); return true; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index 176c24f6707..bf28ccbb17e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -31,6 +31,7 @@ EndScriptData */ #include "WorldPacket.h" #include "Chat.h" #include "WorldSession.h" +#include "Packets/ChatPackets.h" /* Battle of Mount Hyjal encounters: 0 - Rage Winterchill event @@ -173,10 +174,9 @@ public: { if (Player* player = i->GetSource()) { - WorldPacket packet; - - ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS); - player->SendDirectMessage(&packet); + WorldPackets::Chat::Chat packet; + ChatHandler::BuildChatPacket(&packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS); + player->SendDirectMessage(packet.Write()); player->PlayDirectSound(10986, player); } } |