aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp17
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp18
-rw-r--r--src/server/game/Chat/Channels/Channel.h6
-rw-r--r--src/server/game/Chat/Chat.cpp167
-rw-r--r--src/server/game/Chat/Chat.h10
-rw-r--r--src/server/game/Entities/Object/Object.cpp6
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp63
-rw-r--r--src/server/game/Entities/Player/Player.h25
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp13
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h5
-rw-r--r--src/server/game/Groups/Group.cpp6
-rw-r--r--src/server/game/Groups/Group.h6
-rw-r--r--src/server/game/Guilds/Guild.cpp15
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp277
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h12
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp55
-rw-r--r--src/server/game/Server/Packets/ChatPackets.h68
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp29
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h6
-rw-r--r--src/server/game/Server/WorldSession.h7
-rw-r--r--src/server/game/Texts/ChatTextBuilder.h15
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp15
-rw-r--r--src/server/game/Texts/CreatureTextMgr.h27
-rw-r--r--src/server/game/World/World.cpp18
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp8
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);
}
}