aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-07 00:59:56 -0300
committerGitHub <noreply@github.com>2016-10-07 00:59:56 -0300
commit66688a7855a8862666a39b9a958073aaa2489447 (patch)
treee9efaffe69a0299dc596c254a669ab6d39674688 /src
parentce45e1bf95a03be6b1f42c785e4c01dd55999d33 (diff)
Core/Channel: revamp channel system (#17980)
* Core/Channel: change the way channels are stored and sent to client. - Fixes multiple channels per zone when using different locales - Connected clients will receive locally the name of the channel for their apropiate locale (if available) - In other cases default locale name will be sent, so as to prevent breaking channel chat for those players Closes #8411
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp2
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp782
-rw-r--r--src/server/game/Chat/Channels/Channel.h95
-rw-r--r--src/server/game/Chat/Channels/ChannelAppenders.h476
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.cpp162
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.h28
-rw-r--r--src/server/game/Entities/Player/Player.cpp29
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Handlers/ChannelHandler.cpp132
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp10
-rw-r--r--src/server/scripts/Commands/cs_message.cpp43
11 files changed, 1090 insertions, 673 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 658827662ec..bbf03248ec2 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -226,7 +226,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
// Chat channel handling
- PrepareStatement(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHANNEL, "SELECT name, announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CHANNEL, "INSERT INTO channels(name, team, lastUsed) VALUES (?, ?, UNIX_TIMESTAMP())", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHANNEL, "UPDATE channels SET announce = ?, ownership = ?, password = ?, bannedList = ?, lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHANNEL_USAGE, "UPDATE channels SET lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC);
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 22601b711d1..85d03ef6b1f 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -17,93 +17,125 @@
*/
#include "Channel.h"
+#include "ChannelAppenders.h"
#include "Chat.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
#include "ObjectMgr.h"
+#include "Language.h"
#include "SocialMgr.h"
#include "World.h"
#include "DatabaseEnv.h"
#include "AccountMgr.h"
#include "Player.h"
-Channel::Channel(std::string const& name, uint32 channelId, uint32 team /*= 0*/):
- _announceEnabled(true),
- _ownershipEnabled(true),
+Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zoneEntry /*= nullptr*/) :
+ _announceEnabled(false), // no join/leave announces
+ _ownershipEnabled(false), // no ownership handout
_persistentChannel(false),
_isOwnerInvisible(false),
- _channelFlags(0),
+ _channelFlags(CHANNEL_FLAG_GENERAL), // for all built-in channels
_channelId(channelId),
_channelTeam(team),
_ownerGuid(),
- _channelName(name),
- _channelPassword()
+ _channelName(),
+ _channelPassword(),
+ _zoneEntry(zoneEntry)
{
- // set special flags if built-in channel
- if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channelId)) // check whether it's a built-in channel
- {
- _announceEnabled = false; // no join/leave announces
- _ownershipEnabled = false; // no ownership handout
+ ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
+ if (channelEntry->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
+ _channelFlags |= CHANNEL_FLAG_TRADE;
- _channelFlags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
+ if (channelEntry->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
+ _channelFlags |= CHANNEL_FLAG_CITY;
- if (ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
- _channelFlags |= CHANNEL_FLAG_TRADE;
+ if (channelEntry->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
+ _channelFlags |= CHANNEL_FLAG_LFG;
+ else // for all other channels
+ _channelFlags |= CHANNEL_FLAG_NOT_LFG;
+}
- if (ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
- _channelFlags |= CHANNEL_FLAG_CITY;
- if (ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
- _channelFlags |= CHANNEL_FLAG_LFG;
- else // for all other channels
- _channelFlags |= CHANNEL_FLAG_NOT_LFG;
- }
- else // it's custom channel
+Channel::Channel(std::string const& name, uint32 team /*= 0*/) :
+ _announceEnabled(true),
+ _ownershipEnabled(true),
+ _persistentChannel(false),
+ _isOwnerInvisible(false),
+ _channelFlags(CHANNEL_FLAG_CUSTOM),
+ _channelId(0),
+ _channelTeam(team),
+ _ownerGuid(),
+ _channelName(name),
+ _channelPassword(),
+ _zoneEntry(nullptr)
+{
+ // If storing custom channels in the db is enabled either load or save the channel
+ if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
{
- _channelFlags |= CHANNEL_FLAG_CUSTOM;
-
- // If storing custom channels in the db is enabled either load or save the channel
- if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
+ PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
+ stmt->setString(0, name);
+ stmt->setUInt32(1, _channelTeam);
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) // load
{
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _channelTeam);
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
-
- if (result) //load
+ Field* fields = result->Fetch();
+ _channelName = fields[0].GetString(); // re-get channel name. MySQL table collation is case insensitive
+ _announceEnabled = fields[1].GetBool();
+ _ownershipEnabled = fields[2].GetBool();
+ _channelPassword = fields[3].GetString();
+ std::string db_BannedList = fields[4].GetString();
+
+ if (!db_BannedList.empty())
{
- Field* fields = result->Fetch();
- _announceEnabled = fields[0].GetBool();
- _ownershipEnabled = fields[1].GetBool();
- _channelPassword = fields[2].GetString();
- char const* db_BannedList = fields[3].GetCString();
-
- if (db_BannedList)
+ Tokenizer tokens(db_BannedList, ' ');
+ for (auto const& token : tokens)
{
- Tokenizer tokens(db_BannedList, ' ');
- for (Tokenizer::const_iterator i = tokens.begin(); i != tokens.end(); ++i)
+ ObjectGuid banned_guid(uint64(atoull(token)));
+ if (banned_guid)
{
- ObjectGuid banned_guid(uint64(atoull(*i)));
- if (banned_guid)
- {
- TC_LOG_DEBUG("chat.system", "Channel(%s) loaded bannedStore %s", name.c_str(), banned_guid.ToString().c_str());
- _bannedStore.insert(banned_guid);
- }
+ TC_LOG_DEBUG("chat.system", "Channel(%s) loaded player %s into bannedStore", name.c_str(), banned_guid.ToString().c_str());
+ _bannedStore.insert(banned_guid);
}
}
}
- else // save
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _channelTeam);
- CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str());
- }
+ }
+ else // save
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL);
+ stmt->setString(0, name);
+ stmt->setUInt32(1, _channelTeam);
+ CharacterDatabase.Execute(stmt);
+ TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str());
+ }
+
+ _persistentChannel = true;
+ }
+}
- _persistentChannel = true;
+void Channel::GetChannelName(std::string& channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const* zoneEntry)
+{
+ if (channelId)
+ {
+ ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
+ if (!(channelEntry->flags & CHANNEL_DBC_FLAG_GLOBAL))
+ {
+ if (channelEntry->flags & CHANNEL_DBC_FLAG_CITY_ONLY)
+ channelName = Trinity::StringFormat(channelEntry->pattern[locale], sObjectMgr->GetTrinityString(LANG_CHANNEL_CITY, locale));
+ else
+ channelName = Trinity::StringFormat(channelEntry->pattern[locale], ASSERT_NOTNULL(zoneEntry)->area_name[locale]);
}
+ else
+ channelName = channelEntry->pattern[locale];
}
}
+std::string Channel::GetName(LocaleConstant locale /*= DEFAULT_LOCALE*/) const
+{
+ std::string result = _channelName;
+ Channel::GetChannelName(result, _channelId, locale, _zoneEntry);
+
+ return result;
+}
+
void Channel::UpdateChannelInDB() const
{
if (_persistentChannel)
@@ -155,26 +187,26 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
// Do not send error message for built-in channels
if (!IsConstant())
{
- WorldPacket data;
- MakePlayerAlreadyMember(&data, guid);
- SendToOne(&data, guid);
+ PlayerAlreadyMemberAppend appender(guid);
+ ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
}
return;
}
if (IsBanned(guid))
{
- WorldPacket data;
- MakeBanned(&data);
- SendToOne(&data, guid);
+ BannedAppend appender;
+ ChannelNameBuilder<BannedAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (!_channelPassword.empty() && pass != _channelPassword)
{
- WorldPacket data;
- MakeWrongPassword(&data);
- SendToOne(&data, guid);
+ WrongPasswordAppend appender;
+ ChannelNameBuilder<WrongPasswordAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -183,9 +215,9 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC
player->GetGroup())
{
- WorldPacket data;
- MakeNotInLfg(&data);
- SendToOne(&data, guid);
+ NotInLFGAppend appender;
+ ChannelNameBuilder<NotInLFGAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -193,9 +225,9 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
if (_announceEnabled && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakeJoined(&data, guid);
- SendToAll(&data);
+ JoinedAppend appender(guid);
+ ChannelNameBuilder<JoinedAppend> builder(this, appender);
+ SendToAll(builder);
}
bool newChannel = _playersStore.empty();
@@ -204,9 +236,9 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
pinfo.flags = MEMBER_FLAG_NONE;
pinfo.invisible = !player->isGMVisible();
- WorldPacket data;
- MakeYouJoined(&data);
- SendToOne(&data, guid);
+ YouJoinedAppend appender(this);
+ ChannelNameBuilder<YouJoinedAppend> builder(this, appender);
+ SendToOne(builder, guid);
JoinNotify(guid);
@@ -236,20 +268,20 @@ void Channel::LeaveChannel(Player* player, bool send)
{
if (send)
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
}
return;
}
if (send)
{
- WorldPacket data;
- MakeYouLeft(&data);
- SendToOne(&data, guid);
+ YouLeftAppend appender(this);
+ ChannelNameBuilder<YouLeftAppend> builder(this, appender);
+ SendToOne(builder, guid);
+
player->LeftChannel(this);
- data.clear();
}
PlayerInfo& info = _playersStore.at(guid);
@@ -258,9 +290,9 @@ void Channel::LeaveChannel(Player* player, bool send)
if (_announceEnabled && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakeLeft(&data, guid);
- SendToAll(&data);
+ LeftAppend appender(guid);
+ ChannelNameBuilder<LeftAppend> builder(this, appender);
+ SendToAll(builder);
}
LeaveNotify(guid);
@@ -302,18 +334,18 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
if (!IsOn(good))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, good);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
PlayerInfo& info = _playersStore.at(good);
if (!info.IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, good);
+ NotModeratorAppend appender;
+ ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
@@ -321,9 +353,9 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim))
{
- WorldPacket data;
- MakePlayerNotFound(&data, badname);
- SendToOne(&data, good);
+ PlayerNotFoundAppend appender(badname);
+ ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
@@ -331,9 +363,9 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGuid)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, good);
+ NotOwnerAppend appender;
+ ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
@@ -344,16 +376,16 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakePlayerBanned(&data, victim, good);
- SendToAll(&data);
+ PlayerBannedAppend appender(good, victim);
+ ChannelNameBuilder<PlayerBannedAppend> builder(this, appender);
+ SendToAll(builder);
}
}
else if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakePlayerKicked(&data, victim, good);
- SendToAll(&data);
+ PlayerKickedAppend appender(good, victim);
+ ChannelNameBuilder<PlayerKickedAppend> builder(this, appender);
+ SendToAll(builder);
}
_playersStore.erase(victim);
@@ -373,18 +405,18 @@ void Channel::UnBan(Player const* player, std::string const& badname)
if (!IsOn(good))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, good);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
PlayerInfo& info = _playersStore.at(good);
if (!info.IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, good);
+ NotModeratorAppend appender;
+ ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
@@ -393,17 +425,17 @@ void Channel::UnBan(Player const* player, std::string const& badname)
if (!victim || !IsBanned(victim))
{
- WorldPacket data;
- MakePlayerNotFound(&data, badname);
- SendToOne(&data, good);
+ PlayerNotFoundAppend appender(badname);
+ ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
+ SendToOne(builder, good);
return;
}
_bannedStore.erase(victim);
- WorldPacket data;
- MakePlayerUnbanned(&data, victim, good);
- SendToAll(&data);
+ PlayerUnbannedAppend appender(good, victim);
+ ChannelNameBuilder<PlayerUnbannedAppend> builder(this, appender);
+ SendToAll(builder);
UpdateChannelInDB();
}
@@ -415,26 +447,26 @@ void Channel::Password(Player const* player, std::string const& pass)
ChatHandler chat(player->GetSession());
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
PlayerInfo& info = _playersStore.at(guid);
if (!info.IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ NotModeratorAppend appender;
+ ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
_channelPassword = pass;
- WorldPacket data;
- MakePasswordChanged(&data, guid);
- SendToAll(&data);
+ PasswordChangedAppend appender(guid);
+ ChannelNameBuilder<PasswordChangedAppend> builder(this, appender);
+ SendToAll(builder);
UpdateChannelInDB();
}
@@ -445,18 +477,18 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
PlayerInfo& info = _playersStore.at(guid);
if (!info.IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ NotModeratorAppend appender;
+ ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -471,17 +503,17 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))
{
- WorldPacket data;
- MakePlayerNotFound(&data, p2n);
- SendToOne(&data, guid);
+ PlayerNotFoundAppend appender(p2n);
+ ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (_ownerGuid == victim && _ownerGuid != guid)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, guid);
+ NotOwnerAppend appender;
+ ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -504,23 +536,57 @@ void Channel::SetInvisible(Player const* player, bool on)
_isOwnerInvisible = on;
}
+void Channel::SetModerator(ObjectGuid guid, bool set)
+{
+ if (!IsOn(guid))
+ return;
+
+ PlayerInfo& playerInfo = _playersStore.at(guid);
+ if (playerInfo.IsModerator() != set)
+ {
+ uint8 oldFlag = GetPlayerFlags(guid);
+ playerInfo.SetModerator(set);
+
+ ModeChangeAppend appender(guid, oldFlag, GetPlayerFlags(guid));
+ ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
+ SendToAll(builder);
+ }
+}
+
+void Channel::SetMute(ObjectGuid guid, bool set)
+{
+ if (!IsOn(guid))
+ return;
+
+ PlayerInfo& playerInfo = _playersStore.at(guid);
+ if (playerInfo.IsMuted() != set)
+ {
+ uint8 oldFlag = GetPlayerFlags(guid);
+ playerInfo.SetMuted(set);
+
+ ModeChangeAppend appender(guid, oldFlag, GetPlayerFlags(guid));
+ ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
+ SendToAll(builder);
+ }
+}
+
void Channel::SetOwner(Player const* player, std::string const& newname)
{
ObjectGuid guid = player->GetGUID();
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGuid)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, guid);
+ NotOwnerAppend appender;
+ ChannelNameBuilder<NotOwnerAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -532,9 +598,9 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))
{
- WorldPacket data;
- MakePlayerNotFound(&data, newname);
- SendToOne(&data, guid);
+ PlayerNotFoundAppend appender(newname);
+ ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -545,12 +611,18 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
void Channel::SendWhoOwner(ObjectGuid guid)
{
- WorldPacket data;
if (IsOn(guid))
- MakeChannelOwner(&data);
+ {
+ ChannelOwnerAppend appender(this, _ownerGuid);
+ ChannelNameBuilder<ChannelOwnerAppend> builder(this, appender);
+ SendToOne(builder, guid);
+ }
else
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ {
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
+ }
}
void Channel::List(Player const* player) const
@@ -559,18 +631,19 @@ void Channel::List(Player const* player) const
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
+ std::string channelName = GetName(player->GetSession()->GetSessionDbcLocale());
TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST %s Channel: %s",
- player->GetSession()->GetPlayerInfo().c_str(), GetName().c_str());
+ player->GetSession()->GetPlayerInfo().c_str(), channelName.c_str());
- WorldPacket data(SMSG_CHANNEL_LIST, 1+(GetName().size()+1)+1+4+_playersStore.size()*(8+1));
+ WorldPacket data(SMSG_CHANNEL_LIST, 1 + (channelName.size() + 1) + 1 + 4 + _playersStore.size() * (8 + 1));
data << uint8(1); // channel type?
- data << GetName(); // channel name
+ data << channelName; // channel name
data << uint8(GetFlags()); // channel flags?
size_t pos = data.wpos();
@@ -597,8 +670,7 @@ void Channel::List(Player const* player) const
}
data.put<uint32>(pos, count);
-
- SendToOne(&data, guid);
+ player->SendDirectMessage(&data);
}
void Channel::Announce(Player const* player)
@@ -607,29 +679,35 @@ void Channel::Announce(Player const* player)
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
PlayerInfo& info = _playersStore.at(guid);
if (!info.IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ NotModeratorAppend appender;
+ ChannelNameBuilder<NotModeratorAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
_announceEnabled = !_announceEnabled;
- WorldPacket data;
if (_announceEnabled)
- MakeAnnouncementsOn(&data, guid);
+ {
+ AnnouncementsOnAppend appender(guid);
+ ChannelNameBuilder<AnnouncementsOnAppend> builder(this, appender);
+ SendToAll(builder);
+ }
else
- MakeAnnouncementsOff(&data, guid);
- SendToAll(&data);
+ {
+ AnnouncementsOffAppend appender(guid);
+ ChannelNameBuilder<AnnouncementsOffAppend> builder(this, appender);
+ SendToAll(builder);
+ }
UpdateChannelInDB();
}
@@ -645,28 +723,33 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) const
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
PlayerInfo const& info = _playersStore.at(guid);
if (info.IsMuted())
{
- WorldPacket data;
- MakeMuted(&data);
- SendToOne(&data, guid);
+ MutedAppend appender;
+ ChannelNameBuilder<MutedAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
- WorldPacket data;
- if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
- ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _channelName);
- else
- ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _channelName);
+ auto builder = [&](WorldPacket& data, LocaleConstant locale)
+ {
+ LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
+
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, GetName(localeIdx));
+ else
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, GetName(localeIdx));
+ };
+
+ SendToAll(builder, !info.IsModerator() ? guid : ObjectGuid::Empty);
- SendToAll(&data, !info.IsModerator() ? guid : ObjectGuid::Empty);
}
void Channel::Invite(Player const* player, std::string const& newname)
@@ -675,26 +758,26 @@ void Channel::Invite(Player const* player, std::string const& newname)
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ NotMemberAppend appender;
+ ChannelNameBuilder<NotMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
if (!newp || !newp->isGMVisible())
{
- WorldPacket data;
- MakePlayerNotFound(&data, newname);
- SendToOne(&data, guid);
+ PlayerNotFoundAppend appender(newname);
+ ChannelNameBuilder<PlayerNotFoundAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (IsBanned(newp->GetGUID()))
{
- WorldPacket data;
- MakePlayerInviteBanned(&data, newname);
- SendToOne(&data, guid);
+ PlayerInviteBannedAppend appender(newname);
+ ChannelNameBuilder<PlayerInviteBannedAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
@@ -702,31 +785,30 @@ void Channel::Invite(Player const* player, std::string const& newname)
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))
{
- WorldPacket data;
- MakeInviteWrongFaction(&data);
- SendToOne(&data, guid);
+ InviteWrongFactionAppend appender;
+ ChannelNameBuilder<InviteWrongFactionAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (IsOn(newp->GetGUID()))
{
- WorldPacket data;
- MakePlayerAlreadyMember(&data, newp->GetGUID());
- SendToOne(&data, guid);
+ PlayerAlreadyMemberAppend appender(newp->GetGUID());
+ ChannelNameBuilder<PlayerAlreadyMemberAppend> builder(this, appender);
+ SendToOne(builder, guid);
return;
}
if (!newp->GetSocial()->HasIgnore(guid.GetCounter()))
{
- WorldPacket data;
- MakeInvite(&data, guid);
- SendToOne(&data, newp->GetGUID());
- data.clear();
+ InviteAppend appender(guid);
+ ChannelNameBuilder<InviteAppend> builder(this, appender);
+ SendToOne(builder, newp->GetGUID());
}
- WorldPacket data;
- MakePlayerInvited(&data, newp->GetName());
- SendToOne(&data, guid);
+ PlayerInvitedAppend appender(newp->GetName());
+ ChannelNameBuilder<PlayerInvitedAppend> builder(this, appender);
+ SendToOne(builder, guid);
}
void Channel::SetOwner(ObjectGuid guid, bool exclaim)
@@ -749,42 +831,21 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim)
itr->second.SetModerator(true);
itr->second.SetOwner(true);
- WorldPacket data;
- MakeModeChange(&data, _ownerGuid, oldFlag);
- SendToAll(&data);
+ ModeChangeAppend appender(_ownerGuid, oldFlag, GetPlayerFlags(_ownerGuid));
+ ChannelNameBuilder<ModeChangeAppend> builder(this, appender);
+ SendToAll(builder);
if (exclaim)
{
- MakeOwnerChanged(&data, _ownerGuid);
- SendToAll(&data);
+ OwnerChangedAppend appender(_ownerGuid);
+ ChannelNameBuilder<OwnerChangedAppend> builder(this, appender);
+ SendToAll(builder);
}
UpdateChannelInDB();
}
}
-void Channel::SendToAll(WorldPacket* data, ObjectGuid guid) const
-{
- for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
- if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
- if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter()))
- player->GetSession()->SendPacket(data);
-}
-
-void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who) const
-{
- for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
- if (i->first != who)
- if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
- player->GetSession()->SendPacket(data);
-}
-
-void Channel::SendToOne(WorldPacket* data, ObjectGuid who) const
-{
- if (Player* player = ObjectAccessor::FindConnectedPlayer(who))
- player->GetSession()->SendPacket(data);
-}
-
void Channel::Voice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) const
{
@@ -795,245 +856,72 @@ void Channel::DeVoice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/) const
}
-void Channel::MakeNotifyPacket(WorldPacket* data, uint8 notify_type) const
-{
- data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + _channelName.size());
- *data << uint8(notify_type);
- *data << _channelName;
-}
-
-void Channel::MakeJoined(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_JOINED_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeLeft(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_LEFT_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeYouJoined(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_YOU_JOINED_NOTICE);
- *data << uint8(GetFlags());
- *data << uint32(GetChannelId());
- *data << uint32(0);
-}
-
-void Channel::MakeYouLeft(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE);
- *data << uint32(GetChannelId());
- *data << uint8(IsConstant());
-}
-
-void Channel::MakeWrongPassword(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE);
-}
-
-void Channel::MakeNotMember(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE);
-}
-
-void Channel::MakeNotModerator(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE);
-}
-
-void Channel::MakePasswordChanged(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeOwnerChanged(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakePlayerNotFound(WorldPacket* data, std::string const& name) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE);
- *data << name;
-}
-
-void Channel::MakeNotOwner(WorldPacket* data) const
+void Channel::JoinNotify(ObjectGuid guid) const
{
- MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE);
-}
+ auto builder = [&](WorldPacket& data, LocaleConstant locale)
+ {
+ LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
-void Channel::MakeChannelOwner(WorldPacket* data) const
-{
- std::string name;
+ data.Initialize(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + 30 /*channelName buffer*/);
+ data << uint64(guid);
+ data << uint8(GetPlayerFlags(guid));
+ data << uint8(GetFlags());
+ data << uint32(GetNumPlayers());
+ data << GetName(localeIdx);
+ };
- CharacterInfo const* cInfo = sWorld->GetCharacterInfo(_ownerGuid);
- if (!cInfo || cInfo->Name.empty())
- name = "PLAYER_NOT_FOUND";
+ if (IsConstant())
+ SendToAllButOne(builder, guid);
else
- name = cInfo->Name;
-
- MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE);
- *data << ((IsConstant() || !_ownerGuid) ? "Nobody" : name);
-}
-
-void Channel::MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags) const
-{
- MakeNotifyPacket(data, CHAT_MODE_CHANGE_NOTICE);
- *data << uint64(guid);
- *data << uint8(oldflags);
- *data << uint8(GetPlayerFlags(guid));
-}
-
-void Channel::MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeMuted(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_MUTED_NOTICE);
-}
-
-void Channel::MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_KICKED_NOTICE);
- *data << uint64(bad);
- *data << uint64(good);
-}
-
-void Channel::MakeBanned(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_BANNED_NOTICE);
-}
-
-void Channel::MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_BANNED_NOTICE);
- *data << uint64(bad);
- *data << uint64(good);
-}
-
-void Channel::MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_UNBANNED_NOTICE);
- *data << uint64(bad);
- *data << uint64(good);
-}
-
-void Channel::MakePlayerNotBanned(WorldPacket* data, const std::string &name) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE);
- *data << name;
+ SendToAll(builder);
}
-void Channel::MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeInvite(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_INVITE_NOTICE);
- *data << uint64(guid);
-}
-
-void Channel::MakeInviteWrongFaction(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE);
-}
-
-void Channel::MakeWrongFaction(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE);
-}
-
-void Channel::MakeInvalidName(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE);
-}
-
-void Channel::MakeNotModerated(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE);
-}
-
-void Channel::MakePlayerInvited(WorldPacket* data, std::string const& name) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE);
- *data << name;
-}
-
-void Channel::MakePlayerInviteBanned(WorldPacket* data, std::string const& name) const
-{
- MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE);
- *data << name;
-}
-
-void Channel::MakeThrottled(WorldPacket* data) const
+void Channel::LeaveNotify(ObjectGuid guid) const
{
- MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE);
-}
+ auto builder = [&](WorldPacket& data, LocaleConstant locale)
+ {
+ LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
-void Channel::MakeNotInArea(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE);
-}
+ data.Initialize(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + 30 /*channelName buffer*/);
+ data << uint64(guid);
+ data << uint8(GetFlags());
+ data << uint32(GetNumPlayers());
+ data << GetName(localeIdx);
+ };
-void Channel::MakeNotInLfg(WorldPacket* data) const
-{
- MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE);
+ if (IsConstant())
+ SendToAllButOne(builder, guid);
+ else
+ SendToAll(builder);
}
-void Channel::MakeVoiceOn(WorldPacket* data, ObjectGuid guid) const
+template<class Builder>
+void Channel::SendToAll(Builder& builder, ObjectGuid guid /*= ObjectGuid::Empty*/) const
{
- MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE);
- *data << uint64(guid);
-}
+ Trinity::LocalizedPacketDo<Builder> localizer(builder);
-void Channel::MakeVoiceOff(WorldPacket* data, ObjectGuid guid) const
-{
- MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE);
- *data << uint64(guid);
+ for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
+ if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter()))
+ localizer(player);
}
-void Channel::JoinNotify(ObjectGuid guid) const
+template<class Builder>
+void Channel::SendToAllButOne(Builder& builder, ObjectGuid who) const
{
- WorldPacket data(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + GetName().size());
- data << uint64(guid);
- data << uint8(GetPlayerFlags(guid));
- data << uint8(GetFlags());
- data << uint32(GetNumPlayers());
- data << GetName();
+ Trinity::LocalizedPacketDo<Builder> localizer(builder);
- if (IsConstant())
- SendToAllButOne(&data, guid);
- else
- SendToAll(&data);
+ for (PlayerContainer::const_iterator i = _playersStore.begin(); i != _playersStore.end(); ++i)
+ if (i->first != who)
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
+ localizer(player);
}
-void Channel::LeaveNotify(ObjectGuid guid) const
+template<class Builder>
+void Channel::SendToOne(Builder& builder, ObjectGuid who) const
{
- WorldPacket data(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + GetName().size());
- data << uint64(guid);
- data << uint8(GetFlags());
- data << uint32(GetNumPlayers());
- data << GetName();
+ Trinity::LocalizedPacketDo<Builder> localizer(builder);
- if (IsConstant())
- SendToAllButOne(&data, guid);
- else
- SendToAll(&data);
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(who))
+ localizer(player);
}
diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h
index 4859a984967..8c01a474854 100644
--- a/src/server/game/Chat/Channels/Channel.h
+++ b/src/server/game/Chat/Channels/Channel.h
@@ -150,9 +150,11 @@ class TC_GAME_API Channel
};
public:
- Channel(std::string const& name, uint32 channel_id, uint32 team = 0);
+ Channel(uint32 channelId, uint32 team = 0, AreaTableEntry const* zoneEntry = nullptr); // built-in channel ctor
+ Channel(std::string const& name, uint32 team = 0); // custom player channel ctor
- std::string const& GetName() const { return _channelName; }
+ static void GetChannelName(std::string& channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const* zoneEntry);
+ std::string GetName(LocaleConstant locale = DEFAULT_LOCALE) const;
uint32 GetChannelId() const { return _channelId; }
bool IsConstant() const { return _channelId != 0; }
@@ -169,6 +171,8 @@ class TC_GAME_API Channel
uint8 GetFlags() const { return _channelFlags; }
bool HasFlag(uint8 flag) const { return (_channelFlags & flag) != 0; }
+ AreaTableEntry const* GetZoneEntry() const { return _zoneEntry; }
+
void JoinChannel(Player* player, std::string const& pass);
void LeaveChannel(Player* player, bool send = true);
@@ -203,47 +207,15 @@ class TC_GAME_API Channel
static void CleanOldChannelsInDB();
private:
- // initial packet data (notify type and channel name)
- void MakeNotifyPacket(WorldPacket* data, uint8 notify_type) const;
- // type specific packet data
- void MakeJoined(WorldPacket* data, ObjectGuid guid) const; //+ 0x00
- void MakeLeft(WorldPacket* data, ObjectGuid guid) const; //+ 0x01
- void MakeYouJoined(WorldPacket* data) const; //+ 0x02
- void MakeYouLeft(WorldPacket* data) const; //+ 0x03
- void MakeWrongPassword(WorldPacket* data) const; //? 0x04
- void MakeNotMember(WorldPacket* data) const; //? 0x05
- void MakeNotModerator(WorldPacket* data) const; //? 0x06
- void MakePasswordChanged(WorldPacket* data, ObjectGuid guid) const; //+ 0x07
- void MakeOwnerChanged(WorldPacket* data, ObjectGuid guid) const; //? 0x08
- void MakePlayerNotFound(WorldPacket* data, std::string const& name) const; //+ 0x09
- void MakeNotOwner(WorldPacket* data) const; //? 0x0A
- void MakeChannelOwner(WorldPacket* data) const; //? 0x0B
- void MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags) const; //+ 0x0C
- void MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid) const; //+ 0x0D
- void MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid) const; //+ 0x0E
- void MakeMuted(WorldPacket* data) const; //? 0x11
- void MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const; //? 0x12
- void MakeBanned(WorldPacket* data) const; //? 0x13
- void MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const; //? 0x14
- void MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good) const; //? 0x15
- void MakePlayerNotBanned(WorldPacket* data, std::string const& name) const; //? 0x16
- void MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid) const; //+ 0x17
- void MakeInvite(WorldPacket* data, ObjectGuid guid) const; //? 0x18
- void MakeInviteWrongFaction(WorldPacket* data) const; //? 0x19
- void MakeWrongFaction(WorldPacket* data) const; //? 0x1A
- void MakeInvalidName(WorldPacket* data) const; //? 0x1B
- void MakeNotModerated(WorldPacket* data) const; //? 0x1C
- void MakePlayerInvited(WorldPacket* data, std::string const& name) const; //+ 0x1D
- void MakePlayerInviteBanned(WorldPacket* data, std::string const& name) const; //? 0x1E
- void MakeThrottled(WorldPacket* data) const; //? 0x1F
- void MakeNotInArea(WorldPacket* data) const; //? 0x20
- void MakeNotInLfg(WorldPacket* data) const; //? 0x21
- void MakeVoiceOn(WorldPacket* data, ObjectGuid guid) const; //+ 0x22
- void MakeVoiceOff(WorldPacket* data, ObjectGuid guid) const; //+ 0x23
-
- void SendToAll(WorldPacket* data, ObjectGuid guid = ObjectGuid::Empty) const;
- void SendToAllButOne(WorldPacket* data, ObjectGuid who) const;
- void SendToOne(WorldPacket* data, ObjectGuid who) const;
+
+ template<class Builder>
+ void SendToAll(Builder&, ObjectGuid guid = ObjectGuid::Empty) const;
+
+ template<class Builder>
+ void SendToAllButOne(Builder& builder, ObjectGuid who) const;
+
+ template<class Builder>
+ void SendToOne(Builder& builder, ObjectGuid who) const;
bool IsOn(ObjectGuid who) const { return _playersStore.count(who) != 0; }
bool IsBanned(ObjectGuid guid) const { return _bannedStore.count(guid) != 0; }
@@ -257,39 +229,8 @@ class TC_GAME_API Channel
return itr != _playersStore.end() ? itr->second.flags : 0;
}
- void SetModerator(ObjectGuid guid, bool set)
- {
- if (!IsOn(guid))
- return;
-
- PlayerInfo& playerInfo = _playersStore.at(guid);
- if (playerInfo.IsModerator() != set)
- {
- uint8 oldFlag = GetPlayerFlags(guid);
- playerInfo.SetModerator(set);
-
- WorldPacket data;
- MakeModeChange(&data, guid, oldFlag);
- SendToAll(&data);
- }
- }
-
- void SetMute(ObjectGuid guid, bool set)
- {
- if (!IsOn(guid))
- return;
-
- PlayerInfo& playerInfo = _playersStore.at(guid);
- if (playerInfo.IsMuted() != set)
- {
- uint8 oldFlag = GetPlayerFlags(guid);
- playerInfo.SetMuted(set);
-
- WorldPacket data;
- MakeModeChange(&data, guid, oldFlag);
- SendToAll(&data);
- }
- }
+ void SetModerator(ObjectGuid guid, bool set);
+ void SetMute(ObjectGuid guid, bool set);
typedef std::map<ObjectGuid, PlayerInfo> PlayerContainer;
typedef GuidUnorderedSet BannedContainer;
@@ -307,6 +248,8 @@ class TC_GAME_API Channel
std::string _channelPassword;
PlayerContainer _playersStore;
BannedContainer _bannedStore;
+
+ AreaTableEntry const* _zoneEntry;
};
#endif
diff --git a/src/server/game/Chat/Channels/ChannelAppenders.h b/src/server/game/Chat/Channels/ChannelAppenders.h
new file mode 100644
index 00000000000..3dfdc3f32cf
--- /dev/null
+++ b/src/server/game/Chat/Channels/ChannelAppenders.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2008-2016 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 _CHANNELAPPENDERS_H
+#define _CHANNELAPPENDERS_H
+
+#include "Channel.h"
+
+// initial packet data (notify type and channel name)
+template<class PacketModifier>
+class ChannelNameBuilder
+{
+ public:
+ ChannelNameBuilder(Channel const* source, PacketModifier const& modifier)
+ : _source(source), _modifier(modifier){ }
+
+ void operator()(WorldPacket& data, LocaleConstant locale) const
+ {
+ // LocalizedPacketDo sends client DBC locale, we need to get available to server locale
+ LocaleConstant localeIdx = sWorld->GetAvailableDbcLocale(locale);
+
+ data.Initialize(SMSG_CHANNEL_NOTIFY, 60); // guess size
+ data << uint8(_modifier.NotificationType);
+ data << _source->GetName(localeIdx);
+ _modifier.Append(data);
+ }
+
+ private:
+ Channel const* _source;
+ PacketModifier _modifier;
+};
+
+struct JoinedAppend
+{
+ explicit JoinedAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_JOINED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct LeftAppend
+{
+ explicit LeftAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_LEFT_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct YouJoinedAppend
+{
+ explicit YouJoinedAppend(Channel const* channel) : _channel(channel) { }
+
+ static uint8 const NotificationType = CHAT_YOU_JOINED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint8(_channel->GetFlags());
+ data << uint32(_channel->GetChannelId());
+ data << uint32(0);
+ }
+
+private:
+ Channel const* _channel;
+};
+
+struct YouLeftAppend
+{
+ explicit YouLeftAppend(Channel const* channel) : _channel(channel) { }
+
+ static uint8 const NotificationType = CHAT_YOU_LEFT_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint32(_channel->GetChannelId());
+ data << uint8(_channel->IsConstant());
+ }
+
+private:
+ Channel const* _channel;
+};
+
+struct WrongPasswordAppend
+{
+ static uint8 const NotificationType = CHAT_WRONG_PASSWORD_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct NotMemberAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_MEMBER_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct NotModeratorAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_MODERATOR_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct PasswordChangedAppend
+{
+ explicit PasswordChangedAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_PASSWORD_CHANGED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct OwnerChangedAppend
+{
+ explicit OwnerChangedAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_OWNER_CHANGED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct PlayerNotFoundAppend
+{
+ explicit PlayerNotFoundAppend(std::string const& playerName) : _playerName(playerName) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_NOT_FOUND_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << _playerName;
+ }
+
+private:
+ std::string _playerName;
+};
+
+struct NotOwnerAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_OWNER_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct ChannelOwnerAppend
+{
+ explicit ChannelOwnerAppend(Channel const* channel, ObjectGuid const& ownerGuid) : _channel(channel), _ownerGuid(ownerGuid)
+ {
+ CharacterInfo const* cInfo = sWorld->GetCharacterInfo(_ownerGuid);
+ if (!cInfo || cInfo->Name.empty())
+ _ownerName = "PLAYER_NOT_FOUND";
+ else
+ _ownerName = cInfo->Name;
+ }
+
+ static uint8 const NotificationType = CHAT_CHANNEL_OWNER_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << ((_channel->IsConstant() || !_ownerGuid) ? "Nobody" : _ownerName);
+ }
+
+private:
+ Channel const* _channel;
+ ObjectGuid _ownerGuid;
+
+ std::string _ownerName;
+};
+
+struct ModeChangeAppend
+{
+ explicit ModeChangeAppend(ObjectGuid const& guid, uint8 oldFlags, uint8 newFlags) : _guid(guid), _oldFlags(oldFlags), _newFlags(newFlags) { }
+
+ static uint8 const NotificationType = CHAT_MODE_CHANGE_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ data << uint8(_oldFlags);
+ data << uint8(_newFlags);
+ }
+
+private:
+ ObjectGuid _guid;
+ uint8 _oldFlags;
+ uint8 _newFlags;
+};
+
+struct AnnouncementsOnAppend
+{
+ explicit AnnouncementsOnAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_ANNOUNCEMENTS_ON_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct AnnouncementsOffAppend
+{
+ explicit AnnouncementsOffAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_ANNOUNCEMENTS_OFF_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct MutedAppend
+{
+ static uint8 const NotificationType = CHAT_MUTED_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct PlayerKickedAppend
+{
+ explicit PlayerKickedAppend(ObjectGuid const& kicker, ObjectGuid const& kickee) : _kicker(kicker), _kickee(kickee) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_KICKED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_kickee);
+ data << uint64(_kicker);
+ }
+
+private:
+ ObjectGuid _kicker;
+ ObjectGuid _kickee;
+};
+
+struct BannedAppend
+{
+ static uint8 const NotificationType = CHAT_BANNED_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct PlayerBannedAppend
+{
+ explicit PlayerBannedAppend(ObjectGuid const& moderator, ObjectGuid const& banned) : _moderator(moderator), _banned(banned) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_BANNED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_banned);
+ data << uint64(_moderator);
+ }
+
+private:
+ ObjectGuid _moderator;
+ ObjectGuid _banned;
+};
+
+struct PlayerUnbannedAppend
+{
+ explicit PlayerUnbannedAppend(ObjectGuid const& moderator, ObjectGuid const& unbanned) : _moderator(moderator), _unbanned(unbanned) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_UNBANNED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_unbanned);
+ data << uint64(_moderator);
+ }
+
+private:
+ ObjectGuid _moderator;
+ ObjectGuid _unbanned;
+};
+
+struct PlayerNotBannedAppend
+{
+ explicit PlayerNotBannedAppend(std::string const& playerName) : _playerName(playerName) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_NOT_BANNED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << _playerName;
+ }
+
+private:
+ std::string _playerName;
+};
+
+struct PlayerAlreadyMemberAppend
+{
+ explicit PlayerAlreadyMemberAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_ALREADY_MEMBER_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct InviteAppend
+{
+ explicit InviteAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_INVITE_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct InviteWrongFactionAppend
+{
+ static uint8 const NotificationType = CHAT_INVITE_WRONG_FACTION_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct WrongFactionAppend
+{
+ static uint8 const NotificationType = CHAT_WRONG_FACTION_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct InvalidNameAppend
+{
+ static uint8 const NotificationType = CHAT_INVALID_NAME_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct NotModeratedAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_MODERATED_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct PlayerInvitedAppend
+{
+ explicit PlayerInvitedAppend(std::string const& playerName) : _playerName(playerName) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_INVITED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << _playerName;
+ }
+
+private:
+ std::string _playerName;
+};
+
+struct PlayerInviteBannedAppend
+{
+ explicit PlayerInviteBannedAppend(std::string const& playerName) : _playerName(playerName) { }
+
+ static uint8 const NotificationType = CHAT_PLAYER_INVITE_BANNED_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << _playerName;
+ }
+
+private:
+ std::string _playerName;
+};
+
+struct ThrottledAppend
+{
+ static uint8 const NotificationType = CHAT_THROTTLED_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct NotInAreaAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_IN_AREA_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct NotInLFGAppend
+{
+ static uint8 const NotificationType = CHAT_NOT_IN_LFG_NOTICE;
+
+ void Append(WorldPacket& /*data*/) const { }
+};
+
+struct VoiceOnAppend
+{
+ explicit VoiceOnAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_VOICE_ON_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+struct VoiceOffAppend
+{
+ explicit VoiceOffAppend(ObjectGuid const& guid) : _guid(guid) { }
+
+ static uint8 const NotificationType = CHAT_VOICE_OFF_NOTICE;
+
+ void Append(WorldPacket& data) const
+ {
+ data << uint64(_guid);
+ }
+
+private:
+ ObjectGuid _guid;
+};
+
+#endif // _CHANNELAPPENDERS_H
diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp
index 043d4bdc2bc..ee1f463aae2 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.cpp
+++ b/src/server/game/Chat/Channels/ChannelMgr.cpp
@@ -16,20 +16,25 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "Channel.h"
#include "ChannelMgr.h"
#include "Player.h"
#include "World.h"
ChannelMgr::~ChannelMgr()
{
- for (ChannelMap::iterator itr = channels.begin(); itr != channels.end(); ++itr)
+ for (auto itr = _channels.begin(); itr != _channels.end(); ++itr)
+ delete itr->second;
+
+ for (auto itr = _customChannels.begin(); itr != _customChannels.end(); ++itr)
delete itr->second;
}
ChannelMgr* ChannelMgr::forTeam(uint32 team)
{
- static ChannelMgr allianceChannelMgr;
- static ChannelMgr hordeChannelMgr;
+ static ChannelMgr allianceChannelMgr(ALLIANCE);
+ static ChannelMgr hordeChannelMgr(HORDE);
+
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
return &allianceChannelMgr; // cross-faction
@@ -42,69 +47,148 @@ ChannelMgr* ChannelMgr::forTeam(uint32 team)
return nullptr;
}
-Channel* ChannelMgr::GetJoinChannel(std::string const& name, uint32 channelId)
+Channel* ChannelMgr::GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher)
{
- std::wstring wname;
- if (!Utf8toWStr(name, wname))
+ std::wstring channelNamePart;
+ if (!Utf8toWStr(namePart, channelNamePart))
return nullptr;
- wstrToLower(wname);
+ wstrToLower(channelNamePart);
+ for (Channel* channel : playerSearcher->GetJoinedChannels())
+ {
+ std::string chanName = channel->GetName(playerSearcher->GetSession()->GetSessionDbcLocale());
- ChannelMap::const_iterator i = channels.find(wname);
+ std::wstring channelNameW;
+ if (!Utf8toWStr(chanName, channelNameW))
+ continue;
- if (i == channels.end())
- {
- Channel* nchan = new Channel(name, channelId, team);
- channels[wname] = nchan;
- return nchan;
+ wstrToLower(channelNameW);
+ if (!channelNameW.compare(0, channelNamePart.size(), channelNamePart))
+ return channel;
}
- return i->second;
+ return nullptr;
}
-Channel* ChannelMgr::GetChannel(std::string const& name, Player* player, bool pkt)
+Channel* ChannelMgr::GetJoinChannel(uint32 channelId, std::string const& name, AreaTableEntry const* zoneEntry /*= nullptr*/)
{
- std::wstring wname;
- if (!Utf8toWStr(name, wname))
- return nullptr;
+ if (channelId) // builtin
+ {
+ ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
+ uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
+ if (channelEntry->flags & (CHANNEL_DBC_FLAG_GLOBAL | CHANNEL_DBC_FLAG_CITY_ONLY))
+ zoneId = 0;
- wstrToLower(wname);
+ std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
- ChannelMap::const_iterator i = channels.find(wname);
+ auto itr = _channels.find(key);
+ if (itr != _channels.end())
+ return itr->second;
- if (i == channels.end())
+ Channel* newChannel = new Channel(channelId, _team, zoneEntry);
+ _channels[key] = newChannel;
+ return newChannel;
+ }
+ else // custom
{
- if (pkt)
- {
- WorldPacket data;
- MakeNotOnPacket(&data, name);
- player->GetSession()->SendPacket(&data);
- }
+ std::wstring channelName;
+ if (!Utf8toWStr(name, channelName))
+ return nullptr;
+
+ wstrToLower(channelName);
+ auto itr = _customChannels.find(channelName);
+ if (itr != _customChannels.end())
+ return itr->second;
+
+ Channel* newChannel = new Channel(name, _team);
+ _customChannels[channelName] = newChannel;
+ return newChannel;
+ }
+}
- return nullptr;
+Channel* ChannelMgr::GetChannel(uint32 channelId, std::string const& name, Player* player, bool pkt /*= true*/, AreaTableEntry const* zoneEntry /*= nullptr*/) const
+{
+ Channel* ret = nullptr;
+ bool send = false;
+
+ if (channelId) // builtin
+ {
+ ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
+ uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
+ if (channelEntry->flags & (CHANNEL_DBC_FLAG_GLOBAL | CHANNEL_DBC_FLAG_CITY_ONLY))
+ zoneId = 0;
+
+ std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
+
+ auto itr = _channels.find(key);
+ if (itr != _channels.end())
+ ret = itr->second;
+ else
+ send = true;
}
+ else // custom
+ {
+ std::wstring channelName;
+ if (!Utf8toWStr(name, channelName))
+ return nullptr;
+
+ wstrToLower(channelName);
+ auto itr = _customChannels.find(channelName);
+ if (itr != _customChannels.end())
+ ret = itr->second;
+ else
+ send = true;
+ }
+
+ if (send && pkt)
+ {
+ std::string channelName = name;
+ Channel::GetChannelName(channelName, channelId, player->GetSession()->GetSessionDbcLocale(), zoneEntry);
- return i->second;
+ WorldPacket data;
+ ChannelMgr::MakeNotOnPacket(&data, channelName);
+ player->SendDirectMessage(&data);
+ }
+
+ return ret;
}
void ChannelMgr::LeftChannel(std::string const& name)
{
- std::wstring wname;
- if (!Utf8toWStr(name, wname))
+ std::wstring channelName;
+ if (!Utf8toWStr(name, channelName))
return;
- wstrToLower(wname);
+ wstrToLower(channelName);
+ auto itr = _customChannels.find(channelName);
+ if (itr == _customChannels.end())
+ return;
- ChannelMap::const_iterator i = channels.find(wname);
+ Channel* channel = itr->second;
+ if (!channel->GetNumPlayers())
+ {
+ _customChannels.erase(itr);
+ delete channel;
+ }
+}
- if (i == channels.end())
- return;
+void ChannelMgr::LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry)
+{
+ ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
+ uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
+ if (channelEntry->flags & (CHANNEL_DBC_FLAG_GLOBAL | CHANNEL_DBC_FLAG_CITY_ONLY))
+ zoneId = 0;
+
+ std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
- Channel* channel = i->second;
+ auto itr = _channels.find(key);
+ if (itr == _channels.end())
+ return;
- if (!channel->GetNumPlayers() && !channel->IsConstant())
+ Channel* channel = itr->second;
+ if (!channel->GetNumPlayers())
{
- channels.erase(wname);
+ _channels.erase(itr);
delete channel;
}
}
@@ -112,5 +196,5 @@ void ChannelMgr::LeftChannel(std::string const& name)
void ChannelMgr::MakeNotOnPacket(WorldPacket* data, std::string const& name)
{
data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + name.size());
- (*data) << uint8(5) << name;
+ (*data) << uint8(CHAT_NOT_MEMBER_NOTICE) << name;
}
diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h
index abe45690997..c9d85a99812 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.h
+++ b/src/server/game/Chat/Channels/ChannelMgr.h
@@ -19,36 +19,34 @@
#define __TRINITY_CHANNELMGR_H
#include "Common.h"
-#include "Channel.h"
-#include <map>
-#include <string>
-
-#include "World.h"
-
-#define MAX_CHANNEL_PASS_STR 31
+class Channel;
class TC_GAME_API ChannelMgr
{
- typedef std::map<std::wstring, Channel*> ChannelMap;
+ typedef std::unordered_map<std::wstring, Channel*> CustomChannelContainer; // custom channels only differ in name
+ typedef std::unordered_map<std::pair<uint32 /*channelId*/, uint32 /*zoneId*/>, Channel*> BuiltinChannelContainer; //identify builtin (DBC) channels by zoneId instead, since name changes by client locale
protected:
- ChannelMgr() : team(0) { }
+ explicit ChannelMgr(uint32 team) : _team(team) { }
~ChannelMgr();
public:
static ChannelMgr* forTeam(uint32 team);
- void setTeam(uint32 newTeam) { team = newTeam; }
+ static Channel* GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher);
- Channel* GetJoinChannel(std::string const& name, uint32 channel_id);
- Channel* GetChannel(std::string const& name, Player* p, bool pkt = true);
+ Channel* GetJoinChannel(uint32 channelId, std::string const& name, AreaTableEntry const* zoneEntry = nullptr);
+ Channel* GetChannel(uint32 channelId, std::string const& name, Player* player, bool pkt = true, AreaTableEntry const* zoneEntry = nullptr) const;
void LeftChannel(std::string const& name);
+ void LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry);
private:
- ChannelMap channels;
- uint32 team;
+ CustomChannelContainer _customChannels;
+ BuiltinChannelContainer _channels;
+ uint32 const _team;
- void MakeNotOnPacket(WorldPacket* data, std::string const& name);
+ static void MakeNotOnPacket(WorldPacket* data, std::string const& name);
+ ChannelMgr() = delete;
};
#endif
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index dff6f8c0478..e6681f27e51 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -5172,8 +5172,15 @@ void Player::CleanupChannels()
Channel* ch = *m_channels.begin();
m_channels.erase(m_channels.begin()); // remove from player's channel list
ch->LeaveChannel(this, false); // not send to client, not remove from player's channel list
+
+ // delete channel if empty
if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam()))
- cMgr->LeftChannel(ch->GetName()); // deleted channel if empty
+ {
+ if (ch->IsConstant())
+ cMgr->LeftChannel(ch->GetChannelId(), ch->GetZoneEntry());
+ else
+ cMgr->LeftChannel(ch->GetName());
+ }
}
TC_LOG_DEBUG("chat.system", "Player::CleanupChannels: Channels of player '%s' (%s) cleaned up.", GetName().c_str(), GetGUID().ToString().c_str());
}
@@ -5191,7 +5198,6 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (!cMgr)
return;
- std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()];
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
{
ChatChannelsEntry const* channelEntry = sChatChannelsStore.LookupEntry(i);
@@ -5219,14 +5225,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (channelEntry->flags & CHANNEL_DBC_FLAG_CITY_ONLY && usedChannel)
continue; // Already on the channel, as city channel names are not changing
- std::string currentNameExt;
- if (channelEntry->flags & CHANNEL_DBC_FLAG_CITY_ONLY)
- currentNameExt = sObjectMgr->GetTrinityStringForDBCLocale(LANG_CHANNEL_CITY);
- else
- currentNameExt = current_zone_name;
-
- std::string newChannelName = Trinity::StringFormat(channelEntry->pattern[m_session->GetSessionDbcLocale()], currentNameExt.c_str());
- joinChannel = cMgr->GetJoinChannel(newChannelName, channelEntry->ChannelID);
+ joinChannel = cMgr->GetJoinChannel(channelEntry->ChannelID, std::string(), current_zone);
if (usedChannel)
{
if (joinChannel != usedChannel)
@@ -5239,7 +5238,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
}
}
else
- joinChannel = cMgr->GetJoinChannel(channelEntry->pattern[m_session->GetSessionDbcLocale()], channelEntry->ChannelID);
+ joinChannel = cMgr->GetJoinChannel(channelEntry->ChannelID, std::string());
}
else
removeChannel = usedChannel;
@@ -5249,10 +5248,10 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (removeChannel)
{
- removeChannel->LeaveChannel(this, sendRemove); // Leave old channel
- std::string name = removeChannel->GetName(); // Store name, (*i)erase in LeftChannel
- LeftChannel(removeChannel); // Remove from player's channel list
- cMgr->LeftChannel(name); // Delete if empty
+ removeChannel->LeaveChannel(this, sendRemove); // Leave old channel
+
+ LeftChannel(removeChannel); // Remove from player's channel list
+ cMgr->LeftChannel(removeChannel->GetChannelId(), removeChannel->GetZoneEntry()); // Delete if empty
}
}
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 2f580908e2b..7c4bf2f9471 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1847,6 +1847,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void UpdateLocalChannels(uint32 newZone);
void LeaveLFGChannel();
+ typedef std::list<Channel*> JoinedChannelsList;
+ JoinedChannelsList const& GetJoinedChannels() const { return m_channels; }
+
void UpdateDefense();
void UpdateWeaponSkill (WeaponAttackType attType);
void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defense);
@@ -2454,7 +2457,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
WorldSession* m_session;
- typedef std::list<Channel*> JoinedChannelsList;
JoinedChannelsList m_channels;
uint8 m_cinematic;
diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp
index 9285f4247b2..71cdddcebf5 100644
--- a/src/server/game/Handlers/ChannelHandler.cpp
+++ b/src/server/game/Handlers/ChannelHandler.cpp
@@ -17,11 +17,15 @@
*/
#include "ObjectMgr.h" // for normalizePlayerName
+#include "Channel.h"
#include "ChannelMgr.h"
#include "Player.h"
+#include "WorldSession.h"
#include <cctype>
+static size_t const MAX_CHANNEL_PASS_STR = 31;
+
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
{
uint32 channelId;
@@ -33,13 +37,13 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL %s Channel: %u, unk1: %u, unk2: %u, channel: %s, password: %s",
GetPlayerInfo().c_str(), channelId, unknown1, unknown2, channelName.c_str(), password.c_str());
+ AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
if (channelId)
{
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
if (!channel)
return;
- AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
return;
}
@@ -51,30 +55,42 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
return;
if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- {
- cMgr->setTeam(GetPlayer()->GetTeam());
- if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
+ if (Channel* channel = cMgr->GetJoinChannel(channelId, channelName, zone))
channel->JoinChannel(GetPlayer(), password);
- }
}
void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
{
- uint32 unk;
+ uint32 channelId;
std::string channelName;
- recvPacket >> unk >> channelName;
+ recvPacket >> channelId >> channelName;
- TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s Channel: %s, unk1: %u",
- GetPlayerInfo().c_str(), channelName.c_str(), unk);
+ TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s Channel: %s, channelId: %u",
+ GetPlayerInfo().c_str(), channelName.c_str(), channelId);
- if (channelName.empty())
+ if (channelName.empty() && !channelId)
return;
+ AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
+ if (channelId)
+ {
+ ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
+ if (!channel)
+ return;
+
+ if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
+ return;
+ }
+
if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
{
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
+ if (Channel* channel = cMgr->GetChannel(channelId, channelName, GetPlayer(), true, zone))
channel->LeaveChannel(GetPlayer(), true);
- cMgr->LeftChannel(channelName);
+
+ if (channelId)
+ cMgr->LeftChannel(channelId, zone);
+ else
+ cMgr->LeftChannel(channelName);
}
}
@@ -87,9 +103,8 @@ void WorldSession::HandleChannelList(WorldPacket& recvPacket)
recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->List(GetPlayer());
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->List(GetPlayer());
}
void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
@@ -103,9 +118,8 @@ void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
if (password.length() > MAX_CHANNEL_PASS_STR)
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->Password(GetPlayer(), password);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->Password(GetPlayer(), password);
}
void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
@@ -119,9 +133,8 @@ void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->SetOwner(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->SetOwner(GetPlayer(), targetName);
}
void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
@@ -132,9 +145,8 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->SendWhoOwner(GetPlayer()->GetGUID());
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->SendWhoOwner(GetPlayer()->GetGUID());
}
void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
@@ -148,9 +160,8 @@ void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->SetModerator(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->SetModerator(GetPlayer(), targetName);
}
void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
@@ -164,9 +175,8 @@ void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->UnsetModerator(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->UnsetModerator(GetPlayer(), targetName);
}
void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
@@ -180,9 +190,8 @@ void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->SetMute(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->SetMute(GetPlayer(), targetName);
}
void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
@@ -196,9 +205,8 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->UnsetMute(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->UnsetMute(GetPlayer(), targetName);
}
void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
@@ -212,9 +220,8 @@ void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->Invite(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->Invite(GetPlayer(), targetName);
}
void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
@@ -228,9 +235,8 @@ void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->Kick(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->Kick(GetPlayer(), targetName);
}
void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
@@ -244,9 +250,8 @@ void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->Ban(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->Ban(GetPlayer(), targetName);
}
void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
@@ -260,9 +265,8 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->UnBan(GetPlayer(), targetName);
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->UnBan(GetPlayer(), targetName);
}
void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
@@ -273,9 +277,8 @@ void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->Announce(GetPlayer());
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->Announce(GetPlayer());
}
void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
@@ -292,19 +295,17 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
{
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- {
- TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT %s Channel: %s Count: %u",
- GetPlayerInfo().c_str(), channelName.c_str(), channel->GetNumPlayers());
-
- WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, channel->GetName().size() + 1 + 4);
- data << channel->GetName();
- data << uint8(channel->GetFlags());
- data << uint32(channel->GetNumPlayers());
- SendPacket(&data);
- }
+ TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT %s Channel: %s Count: %u",
+ GetPlayerInfo().c_str(), channelName.c_str(), channel->GetNumPlayers());
+
+ std::string name = channel->GetName(GetSessionDbcLocale());
+ WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, name.size() + 1 + 4);
+ data << name;
+ data << uint8(channel->GetFlags());
+ data << uint32(channel->GetNumPlayers());
+ SendPacket(&data);
}
}
@@ -317,8 +318,7 @@ void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket)
GetPlayerInfo().c_str(), channelName.c_str());
/*
- if (ChannelMgr* cMgr = channelMgr(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->JoinNotify(GetPlayer());
+ if (Channel* channel = ChannelMgr::GetChannelForPlayerByNamePart(channelName, GetPlayer()))
+ channel->JoinNotify(GetPlayer());
*/
}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 2b1660fef2b..ba5164f9be5 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -26,6 +26,7 @@
#include "DatabaseEnv.h"
#include "CellImpl.h"
#include "Chat.h"
+#include "Channel.h"
#include "ChannelMgr.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
@@ -461,13 +462,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
}
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam()))
+ if (Channel* chn = ChannelMgr::GetChannelForPlayerByNamePart(channel, sender))
{
- if (Channel* chn = cMgr->GetChannel(channel, sender))
- {
- sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
- chn->Say(sender->GetGUID(), msg.c_str(), lang);
- }
+ sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
+ chn->Say(sender->GetGUID(), msg.c_str(), lang);
}
break;
}
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index 69ff04ffb46..4b3caae686b 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -24,6 +24,7 @@ EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
+#include "Channel.h"
#include "ChannelMgr.h"
#include "Language.h"
#include "Player.h"
@@ -63,21 +64,49 @@ public:
if (!*args)
return false;
char const* channelStr = strtok((char*)args, " ");
- char const* argStr = strtok(NULL, "");
+ char const* argStr = strtok(nullptr, "");
if (!channelStr || !argStr)
return false;
+ uint32 channelId = 0;
+ for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
+ {
+ ChatChannelsEntry const* entry = sChatChannelsStore.LookupEntry(i);
+ if (!entry)
+ continue;
+
+ if (strstr(entry->pattern[handler->GetSessionDbcLocale()], channelStr))
+ {
+ channelId = i;
+ break;
+ }
+ }
+
+ AreaTableEntry const* zoneEntry = nullptr;
+ for (uint32 i = 0; i < sAreaTableStore.GetNumRows(); ++i)
+ {
+ AreaTableEntry const* entry = sAreaTableStore.LookupEntry(i);
+ if (!entry)
+ continue;
+
+ if (strstr(entry->area_name[handler->GetSessionDbcLocale()], channelStr))
+ {
+ zoneEntry = entry;
+ break;
+ }
+ }
+
Player* player = handler->GetSession()->GetPlayer();
- Channel* channcel = NULL;
+ Channel* channel = nullptr;
if (ChannelMgr* cMgr = ChannelMgr::forTeam(player->GetTeam()))
- channcel = cMgr->GetChannel(channelStr, player);
+ channel = cMgr->GetChannel(channelId, channelStr, player, false, zoneEntry);
if (strcmp(argStr, "on") == 0)
{
- if (channcel)
- channcel->SetOwnership(true);
+ if (channel)
+ channel->SetOwnership(true);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_OWNERSHIP);
stmt->setUInt8 (0, 1);
stmt->setString(1, channelStr);
@@ -86,8 +115,8 @@ public:
}
else if (strcmp(argStr, "off") == 0)
{
- if (channcel)
- channcel->SetOwnership(false);
+ if (channel)
+ channel->SetOwnership(false);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_OWNERSHIP);
stmt->setUInt8 (0, 0);
stmt->setString(1, channelStr);