TrinityCore
Loading...
Searching...
No Matches
GuildMgr.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 "GuildMgr.h"
19#include "DatabaseEnv.h"
20#include "Guild.h"
21#include "Log.h"
22#include "ObjectMgr.h"
23#include "Util.h"
24#include "World.h"
25
26GuildMgr::GuildMgr() : NextGuildId(1)
27{ }
28
29GuildMgr::~GuildMgr() = default;
30
32{
34 ptr.reset(guild);
35 guild->SetWeakPtr(ptr);
36}
37
39{
40 GuildStore.erase(guildId);
41}
42
44{
45 if (NextGuildId >= 0xFFFFFFFE)
46 {
47 TC_LOG_ERROR("guild", "Guild ids overflow!! Can't continue, shutting down server. ");
49 }
50 return NextGuildId++;
51}
52
53// Guild collection
55{
56 GuildContainer::const_iterator itr = GuildStore.find(guildId);
57 if (itr != GuildStore.end())
58 return itr->second.get();
59
60 return nullptr;
61}
62
63Guild* GuildMgr::GetGuildByName(std::string_view guildName) const
64{
65 for (auto const& [id, guild] : GuildStore)
66 if (StringEqualI(guild->GetName(), guildName))
67 return guild.get();
68
69 return nullptr;
70}
71
73{
74 if (Guild* guild = GetGuildById(guildId))
75 return guild->GetName();
76
77 return "";
78}
79
81{
82 static GuildMgr instance;
83 return &instance;
84}
85
87{
88 for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
89 if (itr->second->GetLeaderGUID() == guid)
90 return itr->second.get();
91
92 return nullptr;
93}
94
96{
97 // 1. Load all guilds
98 TC_LOG_INFO("server.loading", "Loading guilds definitions...");
99 {
100 uint32 oldMSTime = getMSTime();
101
102 // 0 1 2 3 4 5 6
103 QueryResult result = CharacterDatabase.Query("SELECT g.guildid, g.name, g.leaderguid, g.EmblemStyle, g.EmblemColor, g.BorderStyle, g.BorderColor, "
104 // 7 8 9 10 11 12
105 "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, COUNT(gbt.guildid) "
106 "FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");
107
108 if (!result)
109 {
110 TC_LOG_INFO("server.loading", ">> Loaded 0 guild definitions. DB table `guild` is empty.");
111 return;
112 }
113 else
114 {
115 uint32 count = 0;
116 do
117 {
118 Field* fields = result->Fetch();
119 Guild* guild = new Guild();
120
121 if (!guild->LoadFromDB(fields))
122 {
123 delete guild;
124 continue;
125 }
126
127 AddGuild(guild);
128
129 ++count;
130 }
131 while (result->NextRow());
132
133 TC_LOG_INFO("server.loading", ">> Loaded {} guild definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
134 }
135 }
136
137 // 2. Load all guild ranks
138 TC_LOG_INFO("server.loading", "Loading guild ranks...");
139 {
140 uint32 oldMSTime = getMSTime();
141
142 // Delete orphaned guild rank entries before loading the valid ones
143 CharacterDatabase.DirectExecute("DELETE gr FROM guild_rank gr LEFT JOIN guild g ON gr.guildId = g.guildId WHERE g.guildId IS NULL");
144
145 // 0 1 2 3 4
146 QueryResult result = CharacterDatabase.Query("SELECT guildid, rid, rname, rights, BankMoneyPerDay FROM guild_rank ORDER BY guildid ASC, rid ASC");
147
148 if (!result)
149 {
150 TC_LOG_INFO("server.loading", ">> Loaded 0 guild ranks. DB table `guild_rank` is empty.");
151 }
152 else
153 {
154 uint32 count = 0;
155 do
156 {
157 Field* fields = result->Fetch();
158 uint32 guildId = fields[0].GetUInt32();
159
160 if (Guild* guild = GetGuildById(guildId))
161 guild->LoadRankFromDB(fields);
162
163 ++count;
164 }
165 while (result->NextRow());
166
167 TC_LOG_INFO("server.loading", ">> Loaded {} guild ranks in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
168 }
169 }
170
171 // 3. Load all guild members
172 TC_LOG_INFO("server.loading", "Loading guild members...");
173 {
174 uint32 oldMSTime = getMSTime();
175
176 // Delete orphaned guild member entries before loading the valid ones
177 CharacterDatabase.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL");
178 CharacterDatabase.DirectExecute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL");
179
180 // 0 1 2 3 4 5 6 7 8 9 10
181 QueryResult result = CharacterDatabase.Query("SELECT guildid, gm.guid, `rank` , pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, "
182 // 11 12 13 14 15 16 17 18
183 "w.money, c.name, c.level, c.class, c.gender, c.zone, c.account, c.logout_time "
184 "FROM guild_member gm "
185 "LEFT JOIN guild_member_withdraw w ON gm.guid = w.guid "
186 "LEFT JOIN characters c ON c.guid = gm.guid ORDER BY guildid ASC");
187
188 if (!result)
189 TC_LOG_INFO("server.loading", ">> Loaded 0 guild members. DB table `guild_member` is empty.");
190 else
191 {
192 uint32 count = 0;
193
194 do
195 {
196 Field* fields = result->Fetch();
197 uint32 guildId = fields[0].GetUInt32();
198
199 if (Guild* guild = GetGuildById(guildId))
200 guild->LoadMemberFromDB(fields);
201
202 ++count;
203 }
204 while (result->NextRow());
205
206 TC_LOG_INFO("server.loading", ">> Loaded {} guild members in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
207 }
208 }
209
210 // 4. Load all guild bank tab rights
211 TC_LOG_INFO("server.loading", "Loading bank tab rights...");
212 {
213 uint32 oldMSTime = getMSTime();
214
215 // Delete orphaned guild bank right entries before loading the valid ones
216 CharacterDatabase.DirectExecute("DELETE gbr FROM guild_bank_right gbr LEFT JOIN guild g ON gbr.guildId = g.guildId WHERE g.guildId IS NULL");
217
218 // 0 1 2 3 4
219 QueryResult result = CharacterDatabase.Query("SELECT guildid, TabId, rid, gbright, SlotPerDay FROM guild_bank_right ORDER BY guildid ASC, TabId ASC");
220
221 if (!result)
222 {
223 TC_LOG_INFO("server.loading", ">> Loaded 0 guild bank tab rights. DB table `guild_bank_right` is empty.");
224 }
225 else
226 {
227 uint32 count = 0;
228 do
229 {
230 Field* fields = result->Fetch();
231 uint32 guildId = fields[0].GetUInt32();
232
233 if (Guild* guild = GetGuildById(guildId))
234 guild->LoadBankRightFromDB(fields);
235
236 ++count;
237 }
238 while (result->NextRow());
239
240 TC_LOG_INFO("server.loading", ">> Loaded {} bank tab rights in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
241 }
242 }
243
244 // 5. Load all event logs
245 TC_LOG_INFO("server.loading", "Loading guild event logs...");
246 {
247 uint32 oldMSTime = getMSTime();
248
249 CharacterDatabase.DirectPExecute("DELETE FROM guild_eventlog WHERE LogGuid > {}", sWorld->getIntConfig(CONFIG_GUILD_EVENT_LOG_COUNT));
250
251 // 0 1 2 3 4 5 6
252 QueryResult result = CharacterDatabase.Query("SELECT guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog ORDER BY TimeStamp DESC, LogGuid DESC");
253
254 if (!result)
255 {
256 TC_LOG_INFO("server.loading", ">> Loaded 0 guild event logs. DB table `guild_eventlog` is empty.");
257 }
258 else
259 {
260 uint32 count = 0;
261 do
262 {
263 Field* fields = result->Fetch();
264 uint32 guildId = fields[0].GetUInt32();
265
266 if (Guild* guild = GetGuildById(guildId))
267 guild->LoadEventLogFromDB(fields);
268
269 ++count;
270 }
271 while (result->NextRow());
272
273 TC_LOG_INFO("server.loading", ">> Loaded {} guild event logs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
274 }
275 }
276
277 // 6. Load all bank event logs
278 TC_LOG_INFO("server.loading", "Loading guild bank event logs...");
279 {
280 uint32 oldMSTime = getMSTime();
281
282 // Remove log entries that exceed the number of allowed entries per guild
283 CharacterDatabase.DirectPExecute("DELETE FROM guild_bank_eventlog WHERE LogGuid > {}", sWorld->getIntConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT));
284
285 // 0 1 2 3 4 5 6 7 8
286 QueryResult result = CharacterDatabase.Query("SELECT guildid, TabId, LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog ORDER BY TimeStamp DESC, LogGuid DESC");
287
288 if (!result)
289 {
290 TC_LOG_INFO("server.loading", ">> Loaded 0 guild bank event logs. DB table `guild_bank_eventlog` is empty.");
291 }
292 else
293 {
294 uint32 count = 0;
295 do
296 {
297 Field* fields = result->Fetch();
298 uint32 guildId = fields[0].GetUInt32();
299
300 if (Guild* guild = GetGuildById(guildId))
301 guild->LoadBankEventLogFromDB(fields);
302
303 ++count;
304 }
305 while (result->NextRow());
306
307 TC_LOG_INFO("server.loading", ">> Loaded {} guild bank event logs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
308 }
309 }
310
311 // 7. Load all guild bank tabs
312 TC_LOG_INFO("server.loading", "Loading guild bank tabs...");
313 {
314 uint32 oldMSTime = getMSTime();
315
316 // Delete orphaned guild bank tab entries before loading the valid ones
317 CharacterDatabase.DirectExecute("DELETE gbt FROM guild_bank_tab gbt LEFT JOIN guild g ON gbt.guildId = g.guildId WHERE g.guildId IS NULL");
318
319 // 0 1 2 3 4
320 QueryResult result = CharacterDatabase.Query("SELECT guildid, TabId, TabName, TabIcon, TabText FROM guild_bank_tab ORDER BY guildid ASC, TabId ASC");
321
322 if (!result)
323 {
324 TC_LOG_INFO("server.loading", ">> Loaded 0 guild bank tabs. DB table `guild_bank_tab` is empty.");
325 }
326 else
327 {
328 uint32 count = 0;
329 do
330 {
331 Field* fields = result->Fetch();
332 uint32 guildId = fields[0].GetUInt32();
333
334 if (Guild* guild = GetGuildById(guildId))
335 guild->LoadBankTabFromDB(fields);
336
337 ++count;
338 }
339 while (result->NextRow());
340
341 TC_LOG_INFO("server.loading", ">> Loaded {} guild bank tabs in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
342 }
343 }
344
345 // 8. Fill all guild bank tabs
346 TC_LOG_INFO("guild", "Filling bank tabs with items...");
347 {
348 uint32 oldMSTime = getMSTime();
349
350 // Delete orphan guild bank items
351 CharacterDatabase.DirectExecute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL");
352
353 // 0 1 2 3 4 5 6 7 8 9 10
354 QueryResult result = CharacterDatabase.Query("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, "
355 // 11 12 13 14 15
356 "guildid, TabId, SlotId, item_guid, itemEntry FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid");
357
358 if (!result)
359 {
360 TC_LOG_INFO("server.loading", ">> Loaded 0 guild bank tab items. DB table `guild_bank_item` or `item_instance` is empty.");
361 }
362 else
363 {
364 uint32 count = 0;
365 do
366 {
367 Field* fields = result->Fetch();
368 uint32 guildId = fields[11].GetUInt32();
369
370 if (Guild* guild = GetGuildById(guildId))
371 guild->LoadBankItemFromDB(fields);
372
373 ++count;
374 }
375 while (result->NextRow());
376
377 TC_LOG_INFO("server.loading", ">> Loaded {} guild bank tab items in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
378 }
379 }
380
381 // 9. Validate loaded guild data
382 TC_LOG_INFO("guild", "Validating data of loaded guilds...");
383 {
384 uint32 oldMSTime = getMSTime();
385
386 for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end();)
387 {
388 Guild* guild = itr->second.get();
389 ++itr;
390 if (guild)
391 guild->Validate();
392 }
393
394 TC_LOG_INFO("server.loading", ">> Validated data of loaded guilds in {} ms", GetMSTimeDiffToNow(oldMSTime));
395 }
396}
397
399{
400 for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
401 if (Guild* guild = itr->second.get())
402 guild->ResetTimes();
403
404 CharacterDatabase.DirectExecute("TRUNCATE guild_member_withdraw");
405}
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
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
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
bool StringEqualI(std::string_view a, std::string_view b)
Definition Util.cpp:706
Class used to access individual fields of database query result.
Definition Field.h:92
uint32 GetUInt32() const
Definition Field.cpp:61
std::string GetGuildNameById(ObjectGuid::LowType guildId) const
Definition GuildMgr.cpp:72
GuildContainer GuildStore
Definition GuildMgr.h:56
Guild * GetGuildById(ObjectGuid::LowType guildId) const
Definition GuildMgr.cpp:54
ObjectGuid::LowType NextGuildId
Definition GuildMgr.h:55
Guild * GetGuildByLeader(ObjectGuid guid) const
Definition GuildMgr.cpp:86
void AddGuild(Guild *guild)
Definition GuildMgr.cpp:31
ObjectGuid::LowType GenerateGuildId()
Definition GuildMgr.cpp:43
void LoadGuilds()
Definition GuildMgr.cpp:95
void ResetTimes()
Definition GuildMgr.cpp:398
void RemoveGuild(ObjectGuid::LowType guildId)
Definition GuildMgr.cpp:38
static GuildMgr * instance()
Definition GuildMgr.cpp:80
Guild * GetGuildByName(std::string_view guildName) const
Definition GuildMgr.cpp:63
Definition Guild.h:284
void SetWeakPtr(Trinity::unique_weak_ptr< Guild > weakRef)
Definition Guild.h:734
ObjectGuid::LowType GetId() const
Definition Guild.h:638
bool LoadFromDB(Field *fields)
Definition Guild.cpp:1916
std::string const & GetName() const
Definition Guild.h:640
bool Validate()
Definition Guild.cpp:2059
uint32 LowType
Definition ObjectGuid.h:142
Specialized variant of std::shared_ptr that enforces unique ownership and/or std::unique_ptr with std...
static void StopNow(uint8 exitcode)
Definition World.h:673
#define sWorld
Definition World.h:900
@ CONFIG_GUILD_EVENT_LOG_COUNT
Definition World.h:338
@ CONFIG_GUILD_BANK_EVENT_LOG_COUNT
Definition World.h:339
@ ERROR_EXIT_CODE
Definition World.h:64