Files
TCPlayerbotCore/src/server/game/Chat/Channels/ChannelMgr.cpp
T
Treeston bd7aae928e Core/Chat: Properly reload saved channel settings from DB after 8c16f31.
(cherry picked from commit 2c1b87ca298bce37405329b3af0b5e375f4e53ef)
2021-12-16 21:20:38 +01:00

248 lines
7.7 KiB
C++

/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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 "ChannelMgr.h"
#include "Channel.h"
#include "ChannelPackets.h"
#include "DB2Stores.h"
#include "Player.h"
#include "Realm.h"
#include "World.h"
#include "WorldSession.h"
ChannelMgr::~ChannelMgr()
{
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(ALLIANCE);
static ChannelMgr hordeChannelMgr(HORDE);
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
return &allianceChannelMgr; // cross-faction
if (team == ALLIANCE)
return &allianceChannelMgr;
if (team == HORDE)
return &hordeChannelMgr;
return nullptr;
}
Channel* ChannelMgr::GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher)
{
std::wstring channelNamePart;
if (!Utf8toWStr(namePart, channelNamePart))
return nullptr;
wstrToLower(channelNamePart);
for (Channel* channel : playerSearcher->GetJoinedChannels())
{
std::string chanName = channel->GetName(playerSearcher->GetSession()->GetSessionDbcLocale());
std::wstring channelNameW;
if (!Utf8toWStr(chanName, channelNameW))
continue;
wstrToLower(channelNameW);
if (!channelNameW.compare(0, channelNamePart.size(), channelNamePart))
return channel;
}
return nullptr;
}
Channel* ChannelMgr::GetChannelForPlayerByGuid(ObjectGuid channelGuid, Player* playerSearcher)
{
for (Channel* channel : playerSearcher->GetJoinedChannels())
if (channel->GetGUID() == channelGuid)
return channel;
return nullptr;
}
Channel* ChannelMgr::GetSystemChannel(uint32 channelId, AreaTableEntry const* zoneEntry /* = nullptr */)
{
ObjectGuid channelGuid = CreateBuiltinChannelGuid(channelId, zoneEntry);
auto itr = _channels.find(channelGuid);
if (itr != _channels.end())
return itr->second;
Channel* newChannel = new Channel(channelGuid, channelId, _team, zoneEntry);
_channels[channelGuid] = newChannel;
return newChannel;
}
Channel* ChannelMgr::CreateCustomChannel(std::string const& name)
{
std::wstring channelName;
if (!Utf8toWStr(name, channelName))
return nullptr;
wstrToLower(channelName);
Channel*& c = _customChannels[channelName];
if (c)
return nullptr;
Channel* newChannel = new Channel(CreateCustomChannelGuid(), name, _team);
if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL);
stmt->setString(0, name);
stmt->setUInt32(1, _team);
CharacterDatabase.Execute(stmt);
TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str());
}
c = newChannel;
return newChannel;
}
Channel* ChannelMgr::GetCustomChannel(std::string const& name)
{
std::wstring channelName;
if (!Utf8toWStr(name, channelName))
return nullptr;
wstrToLower(channelName);
auto itr = _customChannels.find(channelName);
if (itr != _customChannels.end())
return itr->second;
else if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
stmt->setString(0, name);
stmt->setUInt32(1, _team);
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
{
Field* fields = result->Fetch();
std::string dbName = fields[0].GetString(); // may be different - channel names are case insensitive
bool dbAnnounce = fields[1].GetBool();
bool dbOwnership = fields[2].GetBool();
std::string dbPass = fields[3].GetString();
std::string dbBanned = fields[4].GetString();
Channel* channel = new Channel(CreateCustomChannelGuid(), dbName, _team, dbBanned);
channel->SetAnnounce(dbAnnounce);
channel->SetOwnership(dbOwnership);
channel->SetPassword(dbPass);
_customChannels.emplace(channelName, channel);
return channel;
}
}
return nullptr;
}
Channel* ChannelMgr::GetChannel(uint32 channelId, std::string const& name, Player* player, bool notify /*= true*/, AreaTableEntry const* zoneEntry /*= nullptr*/) const
{
Channel* result = nullptr;
if (channelId) // builtin
{
auto itr = _channels.find(CreateBuiltinChannelGuid(channelId, zoneEntry));
if (itr != _channels.end())
result = itr->second;
}
else // custom
{
std::wstring channelName;
if (!Utf8toWStr(name, channelName))
return nullptr;
wstrToLower(channelName);
auto itr = _customChannels.find(channelName);
if (itr != _customChannels.end())
result = itr->second;
}
if (!result && notify)
{
std::string channelName = name;
Channel::GetChannelName(channelName, channelId, player->GetSession()->GetSessionDbcLocale(), zoneEntry);
SendNotOnChannelNotify(player, channelName);
}
return result;
}
void ChannelMgr::LeftChannel(std::string const& name)
{
std::wstring channelName;
if (!Utf8toWStr(name, channelName))
return;
wstrToLower(channelName);
auto itr = _customChannels.find(channelName);
if (itr == _customChannels.end())
return;
Channel* channel = itr->second;
if (!channel->GetNumPlayers())
{
_customChannels.erase(itr);
delete channel;
}
}
void ChannelMgr::LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry)
{
auto itr = _channels.find(CreateBuiltinChannelGuid(channelId, zoneEntry));
if (itr == _channels.end())
return;
Channel* channel = itr->second;
if (!channel->GetNumPlayers())
{
_channels.erase(itr);
delete channel;
}
}
void ChannelMgr::SendNotOnChannelNotify(Player const* player, std::string const& name)
{
WorldPackets::Channel::ChannelNotify notify;
notify.Type = CHAT_NOT_MEMBER_NOTICE;
notify._Channel = name;
player->SendDirectMessage(notify.Write());
}
ObjectGuid ChannelMgr::CreateCustomChannelGuid()
{
return ObjectGuid::Create<HighGuid::ChatChannel>(false, false, 0, _team == ALLIANCE ? 3 : 5, _guidGenerator.Generate());
}
ObjectGuid ChannelMgr::CreateBuiltinChannelGuid(uint32 channelId, AreaTableEntry const* zoneEntry /*= nullptr*/) const
{
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;
return ObjectGuid::Create<HighGuid::ChatChannel>(true, (channelEntry->Flags & CHANNEL_DBC_FLAG_CITY_ONLY2) != 0, zoneId, _team == ALLIANCE ? 3 : 5, channelId);
}