TrinityCore
Loading...
Searching...
No Matches
ChannelMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ChannelMgr.h"
19#include "Channel.h"
20#include "ChannelPackets.h"
21#include "DatabaseEnv.h"
22#include "DB2Stores.h"
23#include "Log.h"
24#include "Player.h"
25#include "RealmList.h"
26#include "World.h"
27#include "WorldSession.h"
28
30
31ChannelMgr::ChannelMgr(Team team) : _team(team), _guidGenerator(HighGuid::ChatChannel)
32{
33}
34
36{
37 for (auto itr = _channels.begin(); itr != _channels.end(); ++itr)
38 delete itr->second;
39
40 for (auto itr = _customChannels.begin(); itr != _customChannels.end(); ++itr)
41 delete itr->second;
42}
43
44/*static*/ void ChannelMgr::LoadFromDB()
45{
46 SpecialLinkedArea = sAreaTableStore.AssertEntry(3459);
48
49 if (!sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
50 {
51 TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. Custom channel saving is disabled.");
52 return;
53 }
54
55 uint32 oldMSTime = getMSTime();
57 {
59 stmt->setUInt32(0, days * DAY);
60 CharacterDatabase.Execute(stmt);
61 }
62
63 QueryResult result = CharacterDatabase.Query("SELECT name, team, announce, ownership, password, bannedList FROM channels");
64 if (!result)
65 {
66 TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. DB table `channels` is empty.");
67 return;
68 }
69
70 std::vector<std::pair<std::string, uint32>> toDelete;
71 uint32 count = 0;
72 do
73 {
74 Field* fields = result->Fetch();
75 std::string dbName = fields[0].GetString();
76 Team team = Team(fields[1].GetUInt32());
77 bool dbAnnounce = fields[2].GetBool();
78 bool dbOwnership = fields[3].GetBool();
79 std::string dbPass = fields[4].GetString();
80 std::string dbBanned = fields[5].GetString();
81
82 std::wstring channelName;
83 if (!Utf8toWStr(dbName, channelName))
84 {
85 TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '{}' from database - invalid utf8 sequence? Deleted.", dbName);
86 toDelete.push_back({ dbName, team });
87 continue;
88 }
89
90 ChannelMgr* mgr = ForTeam(team);
91 if (!mgr)
92 {
93 TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '{}' from database - invalid team {}. Deleted.", dbName, team);
94 toDelete.push_back({ dbName, team });
95 continue;
96 }
97
98 Channel* channel = new Channel(mgr->CreateCustomChannelGuid(), dbName, team, dbBanned);
99 channel->SetAnnounce(dbAnnounce);
100 channel->SetOwnership(dbOwnership);
101 channel->SetPassword(dbPass);
102 mgr->_customChannels.emplace(channelName, channel);
103
104 ++count;
105 } while (result->NextRow());
106
107 for (std::pair<std::string, uint32> const& pair : toDelete)
108 {
110 stmt->setString(0, pair.first);
111 stmt->setUInt32(1, pair.second);
112 CharacterDatabase.Execute(stmt);
113 }
114
115 TC_LOG_INFO("server.loading", ">> Loaded {} custom chat channels in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
116}
117
119{
120 static ChannelMgr allianceChannelMgr(ALLIANCE);
121 static ChannelMgr hordeChannelMgr(HORDE);
122 static ChannelMgr neutralChannelMgr(PANDARIA_NEUTRAL);
123
125 return &neutralChannelMgr; // cross-faction
126
127 switch (team)
128 {
129 case HORDE:
130 return &hordeChannelMgr;
131 case ALLIANCE:
132 return &allianceChannelMgr;
133 case PANDARIA_NEUTRAL:
134 return &neutralChannelMgr;
135 default:
136 break;
137 }
138
139 return nullptr;
140}
141
142Channel* ChannelMgr::GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher)
143{
144 std::wstring channelNamePart;
145 if (!Utf8toWStr(namePart, channelNamePart))
146 return nullptr;
147
148 wstrToLower(channelNamePart);
149 for (Channel* channel : playerSearcher->GetJoinedChannels())
150 {
151 std::string chanName = channel->GetName(playerSearcher->GetSession()->GetSessionDbcLocale());
152
153 std::wstring channelNameW;
154 if (!Utf8toWStr(chanName, channelNameW))
155 continue;
156
157 wstrToLower(channelNameW);
158 if (!channelNameW.compare(0, channelNamePart.size(), channelNamePart))
159 return channel;
160 }
161
162 return nullptr;
163}
164
166{
167 for (auto pair : _customChannels)
168 pair.second->UpdateChannelInDB();
169}
170
172{
173 for (Channel* channel : playerSearcher->GetJoinedChannels())
174 if (channel->GetGUID() == channelGuid)
175 return channel;
176
177 return nullptr;
178}
179
180Channel* ChannelMgr::GetSystemChannel(uint32 channelId, AreaTableEntry const* zoneEntry /* = nullptr */)
181{
182 ObjectGuid channelGuid = CreateBuiltinChannelGuid(channelId, zoneEntry);
183 auto itr = _channels.find(channelGuid);
184 if (itr != _channels.end())
185 return itr->second;
186
187 Channel* newChannel = new Channel(channelGuid, channelId, _team, zoneEntry);
188 _channels[channelGuid] = newChannel;
189 return newChannel;
190}
191
193{
194 std::wstring channelName;
195 if (!Utf8toWStr(name, channelName))
196 return nullptr;
197
198 wstrToLower(channelName);
199
200 Channel*& c = _customChannels[channelName];
201 if (c)
202 return nullptr;
203
204 Channel* newChannel = new Channel(CreateCustomChannelGuid(), name, _team);
205 newChannel->SetDirty();
206
207 c = newChannel;
208 return newChannel;
209}
210
211Channel* ChannelMgr::GetCustomChannel(std::string const& name) const
212{
213 std::wstring channelName;
214 if (!Utf8toWStr(name, channelName))
215 return nullptr;
216
217 wstrToLower(channelName);
218 auto itr = _customChannels.find(channelName);
219 if (itr != _customChannels.end())
220 return itr->second;
221
222 return nullptr;
223}
224
225Channel* ChannelMgr::GetChannel(uint32 channelId, std::string const& name, Player* player, bool notify /*= true*/, AreaTableEntry const* zoneEntry /*= nullptr*/) const
226{
227 Channel* result = nullptr;
228 if (channelId) // builtin
229 {
230 auto itr = _channels.find(CreateBuiltinChannelGuid(channelId, zoneEntry));
231 if (itr != _channels.end())
232 result = itr->second;
233 }
234 else // custom
235 {
236 std::wstring channelName;
237 if (!Utf8toWStr(name, channelName))
238 return nullptr;
239
240 wstrToLower(channelName);
241
242 auto itr = _customChannels.find(channelName);
243 if (itr != _customChannels.end())
244 result = itr->second;
245 }
246
247 if (!result && notify)
248 {
249 std::string channelName = name;
250 Channel::GetChannelName(channelName, channelId, player->GetSession()->GetSessionDbcLocale(), zoneEntry);
251
252 SendNotOnChannelNotify(player, channelName);
253 }
254
255 return result;
256}
257
258void ChannelMgr::LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry)
259{
260 auto itr = _channels.find(CreateBuiltinChannelGuid(channelId, zoneEntry));
261 if (itr == _channels.end())
262 return;
263
264 Channel* channel = itr->second;
265 if (!channel->GetNumPlayers())
266 {
267 _channels.erase(itr);
268 delete channel;
269 }
270}
271
272void ChannelMgr::SendNotOnChannelNotify(Player const* player, std::string const& name)
273{
276 notify._Channel = name;
277 player->SendDirectMessage(notify.Write());
278}
279
281{
282 return ObjectGuid::Create<HighGuid::ChatChannel>(false, false, 0, _team == ALLIANCE ? 3 : 5, _guidGenerator.Generate());
283}
284
285ObjectGuid ChannelMgr::CreateBuiltinChannelGuid(uint32 channelId, AreaTableEntry const* zoneEntry /*= nullptr*/) const
286{
287 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
288 uint32 zoneId = 0;
289 if (zoneEntry && channelEntry->GetFlags().HasFlag(ChatChannelFlags::ZoneBased) && !channelEntry->GetFlags().HasFlag(ChatChannelFlags::LinkedChannel))
290 zoneId = zoneEntry->ID;
291
292 if (channelEntry->GetFlags().HasFlag(ChatChannelFlags::GlobalForTournament))
293 if (std::shared_ptr<Realm const> currentRealm = sRealmList->GetCurrentRealm())
294 if (Cfg_CategoriesEntry const* category = sCfgCategoriesStore.LookupEntry(currentRealm->Timezone))
295 if (category->GetFlags().HasFlag(CfgCategoriesFlags::Tournament))
296 zoneId = 0;
297
298 return ObjectGuid::Create<HighGuid::ChatChannel>(true, channelEntry->GetFlags().HasFlag(ChatChannelFlags::LinkedChannel), zoneId, _team == ALLIANCE ? 3 : 5, channelId);
299}
@ CHAT_NOT_MEMBER_NOTICE
Definition Channel.h:48
@ CHAR_DEL_CHANNEL
@ CHAR_DEL_OLD_CHANNELS
@ DAY
Definition Common.h:34
DB2Storage< Cfg_CategoriesEntry > sCfgCategoriesStore("Cfg_Categories.db2", &CfgCategoriesLoadInfo::Instance)
DB2Storage< ChatChannelsEntry > sChatChannelsStore("ChatChannels.db2", &ChatChannelsLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
@ LinkedChatSpecialArea
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint32_t uint32
Definition Define.h:154
#define ASSERT
Definition Errors.h:80
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
HighGuid
Definition ObjectGuid.h:109
#define sRealmList
Definition RealmList.h:93
@ PANDARIA_NEUTRAL
@ ALLIANCE
@ HORDE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
void wstrToLower(std::wstring &str)
Definition Util.cpp:433
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition Util.cpp:336
Channel * CreateCustomChannel(std::string const &name)
ObjectGuid CreateBuiltinChannelGuid(uint32 channelId, AreaTableEntry const *zoneEntry=nullptr) const
Channel * GetCustomChannel(std::string const &name) const
static void LoadFromDB()
void LeftChannel(uint32 channelId, AreaTableEntry const *zoneEntry)
CustomChannelContainer _customChannels
Definition ChannelMgr.h:60
static AreaTableEntry const * SpecialLinkedArea
Definition ChannelMgr.h:50
ChannelMgr(Team team)
Team const _team
Definition ChannelMgr.h:62
static ChannelMgr * ForTeam(Team team)
Channel * GetSystemChannel(uint32 channelId, AreaTableEntry const *zoneEntry=nullptr)
ObjectGuidGenerator _guidGenerator
Definition ChannelMgr.h:63
Channel * GetChannel(uint32 channelId, std::string const &name, Player *player, bool notify=true, AreaTableEntry const *zoneEntry=nullptr) const
ObjectGuid CreateCustomChannelGuid()
void SaveToDB()
static Channel * GetChannelForPlayerByNamePart(std::string const &namePart, Player *playerSearcher)
static Channel * GetChannelForPlayerByGuid(ObjectGuid channelGuid, Player *playerSearcher)
BuiltinChannelContainer _channels
Definition ChannelMgr.h:61
static void SendNotOnChannelNotify(Player const *player, std::string const &name)
void SetDirty()
Definition Channel.h:185
void SetPassword(std::string const &password)
Definition Channel.h:188
static void GetChannelName(std::string &channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const *zoneEntry)
Definition Channel.cpp:99
void SetAnnounce(bool announce)
Definition Channel.h:182
void SetOwnership(bool ownership)
Definition Channel.h:229
uint32 GetNumPlayers() const
Definition Channel.h:191
Class used to access individual fields of database query result.
Definition Field.h:94
bool GetBool() const noexcept
Definition Field.h:102
std::string GetString() const noexcept
Definition Field.cpp:113
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
WorldSession * GetSession() const
Definition Player.h:2272
JoinedChannelsList const & GetJoinedChannels() const
Definition Player.h:2365
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
std::string _Channel
Channel Name.
WorldPacket const * Write() override
LocaleConstant GetSessionDbcLocale() const
#define sWorld
Definition World.h:916
@ CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION
Definition World.h:374
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
Definition World.h:111
@ CONFIG_PRESERVE_CUSTOM_CHANNELS
Definition World.h:162
EnumFlag< AreaFlags > GetFlags() const
EnumFlag< ChatChannelFlags > GetFlags() const