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 "DatabaseEnv.h"
21#include "DBCStores.h"
22#include "Log.h"
23#include "Player.h"
24#include "World.h"
25#include "WorldSession.h"
26
28{
29 for (auto itr = _channels.begin(); itr != _channels.end(); ++itr)
30 delete itr->second;
31
32 for (auto itr = _customChannels.begin(); itr != _customChannels.end(); ++itr)
33 delete itr->second;
34}
35
36/*static*/ void ChannelMgr::LoadFromDB()
37{
38 if (!sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
39 {
40 TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. Custom channel saving is disabled.");
41 return;
42 }
43
44 uint32 oldMSTime = getMSTime();
46 {
48 stmt->setUInt32(0, days * DAY);
49 CharacterDatabase.Execute(stmt);
50 }
51
52 QueryResult result = CharacterDatabase.Query("SELECT name, team, announce, ownership, password, bannedList FROM channels");
53 if (!result)
54 {
55 TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. DB table `channels` is empty.");
56 return;
57 }
58
59 std::vector<std::pair<std::string, uint32>> toDelete;
60 uint32 count = 0;
61 do
62 {
63 Field* fields = result->Fetch();
64 std::string dbName = fields[0].GetString();
65 uint32 team = fields[1].GetUInt32();
66 bool dbAnnounce = fields[2].GetBool();
67 bool dbOwnership = fields[3].GetBool();
68 std::string dbPass = fields[4].GetString();
69 std::string dbBanned = fields[5].GetString();
70
71 std::wstring channelName;
72 if (!Utf8toWStr(dbName, channelName))
73 {
74 TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '{}' from database - invalid utf8 sequence? Deleted.", dbName);
75 toDelete.push_back({ dbName, team });
76 continue;
77 }
78
79 ChannelMgr* mgr = forTeam(team);
80 if (!mgr)
81 {
82 TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '{}' from database - invalid team {}. Deleted.", dbName, team);
83 toDelete.push_back({ dbName, team });
84 continue;
85 }
86
87 Channel* channel = new Channel(dbName, team, dbBanned);
88 channel->SetAnnounce(dbAnnounce);
89 channel->SetOwnership(dbOwnership);
90 channel->SetPassword(dbPass);
91 mgr->_customChannels.emplace(channelName, channel);
92
93 ++count;
94 } while (result->NextRow());
95
96 for (auto pair : toDelete)
97 {
99 stmt->setString(0, pair.first);
100 stmt->setUInt32(1, pair.second);
101 CharacterDatabase.Execute(stmt);
102 }
103
104 TC_LOG_INFO("server.loading", ">> Loaded {} custom chat channels in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
105}
106
108{
109 static ChannelMgr allianceChannelMgr(ALLIANCE);
110 static ChannelMgr hordeChannelMgr(HORDE);
111
113 return &allianceChannelMgr; // cross-faction
114
115 if (team == ALLIANCE)
116 return &allianceChannelMgr;
117
118 if (team == HORDE)
119 return &hordeChannelMgr;
120
121 return nullptr;
122}
123
124Channel* ChannelMgr::GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher)
125{
126 std::wstring channelNamePart;
127 if (!Utf8toWStr(namePart, channelNamePart))
128 return nullptr;
129
130 wstrToLower(channelNamePart);
131 for (Channel* channel : playerSearcher->GetJoinedChannels())
132 {
133 std::string chanName = channel->GetName(playerSearcher->GetSession()->GetSessionDbcLocale());
134
135 std::wstring channelNameW;
136 if (!Utf8toWStr(chanName, channelNameW))
137 continue;
138
139 wstrToLower(channelNameW);
140 if (!channelNameW.compare(0, channelNamePart.size(), channelNamePart))
141 return channel;
142 }
143
144 return nullptr;
145}
146
148{
149 for (auto pair : _customChannels)
150 pair.second->UpdateChannelInDB();
151}
152
154{
155 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
156 uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
158 zoneId = 0;
159
160 std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
161
162 auto itr = _channels.find(key);
163 if (itr != _channels.end())
164 return itr->second;
165
166 Channel* newChannel = new Channel(channelId, _team, zoneEntry);
167 _channels[key] = newChannel;
168 return newChannel;
169}
170
172{
173 std::wstring channelName;
174 if (!Utf8toWStr(name, channelName))
175 return nullptr;
176
177 wstrToLower(channelName);
178
179 Channel*& c = _customChannels[channelName];
180 if (c)
181 return nullptr;
182
183 Channel* newChannel = new Channel(name, _team);
184 newChannel->SetDirty();
185
186 c = newChannel;
187 return newChannel;
188}
189
190Channel* ChannelMgr::GetCustomChannel(std::string const& name) const
191{
192 std::wstring channelName;
193 if (!Utf8toWStr(name, channelName))
194 return nullptr;
195
196 wstrToLower(channelName);
197 auto itr = _customChannels.find(channelName);
198 if (itr != _customChannels.end())
199 return itr->second;
200
201 return nullptr;
202}
203
204Channel* ChannelMgr::GetChannel(uint32 channelId, std::string const& name, Player* player, bool pkt /*= true*/, AreaTableEntry const* zoneEntry /*= nullptr*/) const
205{
206 Channel* ret = nullptr;
207 bool send = false;
208
209 if (channelId) // builtin
210 {
211 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
212 uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
214 zoneId = 0;
215
216 std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
217
218 auto itr = _channels.find(key);
219 if (itr != _channels.end())
220 ret = itr->second;
221 else
222 send = true;
223 }
224 else // custom
225 {
226 std::wstring channelName;
227 if (!Utf8toWStr(name, channelName))
228 return nullptr;
229
230 wstrToLower(channelName);
231 auto itr = _customChannels.find(channelName);
232 if (itr != _customChannels.end())
233 ret = itr->second;
234 else
235 send = true;
236 }
237
238 if (send && pkt)
239 {
240 std::string channelName = name;
241 Channel::GetChannelName(channelName, channelId, player->GetSession()->GetSessionDbcLocale(), zoneEntry);
242
243 WorldPacket data;
244 ChannelMgr::MakeNotOnPacket(&data, channelName);
245 player->SendDirectMessage(&data);
246 }
247
248 return ret;
249}
250
251void ChannelMgr::LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry)
252{
253 ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
254 uint32 zoneId = zoneEntry ? zoneEntry->ID : 0;
256 zoneId = 0;
257
258 std::pair<uint32, uint32> key = std::make_pair(channelId, zoneId);
259
260 auto itr = _channels.find(key);
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::MakeNotOnPacket(WorldPacket* data, std::string const& name)
273{
274 data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + name.size());
275 (*data) << uint8(CHAT_NOT_MEMBER_NOTICE) << name;
276}
@ CHANNEL_DBC_FLAG_CITY_ONLY
Definition Channel.h:98
@ CHANNEL_DBC_FLAG_GLOBAL
Definition Channel.h:96
@ CHAT_NOT_MEMBER_NOTICE
Definition Channel.h:40
@ CHAR_DEL_CHANNEL
@ CHAR_DEL_OLD_CHANNELS
@ DAY
Definition Common.h:31
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
@ ALLIANCE
@ HORDE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
void wstrToLower(std::wstring &str)
Definition Util.cpp:480
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition Util.cpp:383
Channel * CreateCustomChannel(std::string const &name)
Channel * GetCustomChannel(std::string const &name) const
static void LoadFromDB()
void LeftChannel(uint32 channelId, AreaTableEntry const *zoneEntry)
CustomChannelContainer _customChannels
Definition ChannelMgr.h:52
Channel * GetChannel(uint32 channelId, std::string const &name, Player *player, bool pkt=true, AreaTableEntry const *zoneEntry=nullptr) const
static ChannelMgr * forTeam(uint32 team)
Channel * GetSystemChannel(uint32 channelId, AreaTableEntry const *zoneEntry=nullptr)
uint32 const _team
Definition ChannelMgr.h:54
void SaveToDB()
static Channel * GetChannelForPlayerByNamePart(std::string const &namePart, Player *playerSearcher)
static void MakeNotOnPacket(WorldPacket *data, std::string const &name)
BuiltinChannelContainer _channels
Definition ChannelMgr.h:53
void SetDirty()
Definition Channel.h:176
void SetPassword(std::string const &password)
Definition Channel.h:179
static void GetChannelName(std::string &channelName, uint32 channelId, LocaleConstant locale, AreaTableEntry const *zoneEntry)
Definition Channel.cpp:91
void SetAnnounce(bool announce)
Definition Channel.h:173
void SetOwnership(bool ownership)
Definition Channel.h:219
uint32 GetNumPlayers() const
Definition Channel.h:182
Class used to access individual fields of database query result.
Definition Field.h:92
std::string GetString() const
Definition Field.cpp:125
bool GetBool() const
Definition Field.h:100
uint32 GetUInt32() const
Definition Field.cpp:61
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6161
WorldSession * GetSession() const
Definition Player.h:1719
JoinedChannelsList const & GetJoinedChannels() const
Definition Player.h:1788
void setUInt32(uint8 index, uint32 value)
void setString(uint8 index, std::string const &value)
void Initialize(uint16 opcode, size_t newres=200)
Definition WorldPacket.h:73
LocaleConstant GetSessionDbcLocale() const
@ SMSG_CHANNEL_NOTIFY
Definition Opcodes.h:182
#define sWorld
Definition World.h:900
@ CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION
Definition World.h:352
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL
Definition World.h:97
@ CONFIG_PRESERVE_CUSTOM_CHANNELS
Definition World.h:149