TrinityCore
Loading...
Searching...
No Matches
GroupMgr.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 "GroupMgr.h"
19#include "Common.h"
20#include "DatabaseEnv.h"
21#include "Group.h"
22#include "Log.h"
23#include "World.h"
24
30
32{
33 for (GroupContainer::iterator itr = GroupStore.begin(); itr != GroupStore.end(); ++itr)
34 delete itr->second;
35}
36
38{
39 uint32 newStorageId = NextGroupDbStoreId;
40
41 for (uint32 i = ++NextGroupDbStoreId; i < 0xFFFFFFFF; ++i)
42 {
43 if ((i < GroupDbStore.size() && GroupDbStore[i] == nullptr) || i >= GroupDbStore.size())
44 {
46 break;
47 }
48 }
49
50 if (newStorageId == NextGroupDbStoreId)
51 {
52 TC_LOG_ERROR("misc", "Group storage ID overflow!! Can't continue, shutting down server. ");
54 }
55
56 return newStorageId;
57}
58
60{
61 // Allocate space if necessary.
62 if (storageId >= uint32(GroupDbStore.size()))
63 GroupDbStore.resize(storageId + 1);
64
65 GroupDbStore[storageId] = group;
66}
67
69{
70 uint32 storageId = group->GetDbStoreId();
71
72 if (storageId < NextGroupDbStoreId)
73 NextGroupDbStoreId = storageId;
74
75 GroupDbStore[storageId] = nullptr;
76}
77
79{
80 if (storageId < GroupDbStore.size())
81 return GroupDbStore[storageId];
82
83 return nullptr;
84}
85
87{
88 GroupDbStore.resize(newSize);
89}
90
92{
93 if (NextGroupId >= 0xFFFFFFFE)
94 {
95 TC_LOG_ERROR("misc", "Group guid overflow!! Can't continue, shutting down server. ");
97 }
98 return NextGroupId++;
99}
100
102{
103 static GroupMgr instance;
104 return &instance;
105}
106
108{
109 GroupContainer::const_iterator itr = GroupStore.find(groupId.GetCounter());
110 if (itr != GroupStore.end())
111 return itr->second;
112
113 return nullptr;
114}
115
117{
118 for (std::pair<ObjectGuid::LowType const, Group*> const& group : GroupStore)
119 group.second->Update(diff);
120}
121
123{
124 GroupStore[group->GetGUID().GetCounter()] = group;
125}
126
128{
129 GroupStore.erase(group->GetGUID().GetCounter());
130}
131
133{
134 {
135 uint32 oldMSTime = getMSTime();
136
137 // Delete all members that does not exist
138 CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)");
139 // Delete all groups whose leader does not exist
140 CharacterDatabase.DirectExecute("DELETE FROM `groups` WHERE leaderGuid NOT IN (SELECT guid FROM characters)");
141 // Delete all groups with less than 2 members
142 CharacterDatabase.DirectExecute("DELETE FROM `groups` WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)");
143 // Delete all rows from group_member with no group
144 CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM `groups`)");
145
146 // 0 1 2 3 4 5 6 7 8 9
147 QueryResult result = CharacterDatabase.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6"
148 // 10 11 12 13 14 15 16 17 18 19 20
149 ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.legacyRaidDifficulty, g.masterLooterGuid, g.guid, g.pingRestriction, lfg.dungeon, lfg.state FROM `groups` g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
150 if (!result)
151 {
152 TC_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `groups` is empty!");
153 return;
154 }
155
156 uint32 count = 0;
157 do
158 {
159 Field* fields = result->Fetch();
160 Group* group = new Group;
161 group->LoadGroupFromDB(fields);
162 AddGroup(group);
163
164 // Get the ID used for storing the group in the database and register it in the pool.
165 uint32 storageId = group->GetDbStoreId();
166
167 RegisterGroupDbStoreId(storageId, group);
168
169 // Increase the next available storage ID
170 if (storageId == NextGroupDbStoreId)
172
173 ++count;
174 }
175 while (result->NextRow());
176
177 TC_LOG_INFO("server.loading", ">> Loaded {} group definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
178 }
179
180 TC_LOG_INFO("server.loading", "Loading Group members...");
181 {
182 uint32 oldMSTime = getMSTime();
183
184 // 0 1 2 3 4
185 QueryResult result = CharacterDatabase.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid");
186 if (!result)
187 {
188 TC_LOG_INFO("server.loading", ">> Loaded 0 group members. DB table `group_member` is empty!");
189 return;
190 }
191
192 uint32 count = 0;
193
194 do
195 {
196 Field* fields = result->Fetch();
197 Group* group = GetGroupByDbStoreId(fields[0].GetUInt32());
198
199 if (group)
200 group->LoadMemberFromDB(fields[1].GetUInt64(), fields[2].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt8());
201 else
202 TC_LOG_ERROR("misc", "GroupMgr::LoadGroups: Consistency failed, can't find group (storage id: {})", fields[0].GetUInt32());
203
204 ++count;
205 }
206 while (result->NextRow());
207
208 TC_LOG_INFO("server.loading", ">> Loaded {} group members in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
209 }
210}
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
#define UI64LIT(N)
Definition Define.h:139
uint32_t uint32
Definition Define.h:154
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
Class used to access individual fields of database query result.
Definition Field.h:94
static GroupMgr * instance()
Definition GroupMgr.cpp:101
void FreeGroupDbStoreId(Group *group)
Definition GroupMgr.cpp:68
Group * GetGroupByDbStoreId(uint32 storageId) const
Definition GroupMgr.cpp:78
uint32 GenerateNewGroupDbStoreId()
Definition GroupMgr.cpp:37
Group * GetGroupByGUID(ObjectGuid const &guid) const
Definition GroupMgr.cpp:107
void RemoveGroup(Group *group)
Definition GroupMgr.cpp:127
ObjectGuid::LowType NextGroupId
Definition GroupMgr.h:60
void Update(uint32 diff)
Definition GroupMgr.cpp:116
GroupDbContainer GroupDbStore
Definition GroupMgr.h:63
uint32 NextGroupDbStoreId
Definition GroupMgr.h:61
void SetGroupDbStoreSize(uint32 newSize)
Definition GroupMgr.cpp:86
void LoadGroups()
Definition GroupMgr.cpp:132
void AddGroup(Group *group)
Definition GroupMgr.cpp:122
ObjectGuid::LowType GenerateGroupId()
Definition GroupMgr.cpp:91
void RegisterGroupDbStoreId(uint32 storageId, Group *group)
Definition GroupMgr.cpp:59
GroupContainer GroupStore
Definition GroupMgr.h:62
Definition Group.h:205
void LoadGroupFromDB(Field *field)
Definition Group.cpp:211
ObjectGuid GetGUID() const
Definition Group.cpp:1653
void Update(uint32 diff)
Definition Group.cpp:90
void LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
Definition Group.cpp:248
uint32 GetDbStoreId() const
Definition Group.h:312
LowType GetCounter() const
Definition ObjectGuid.h:336
uint64 LowType
Definition ObjectGuid.h:321
static void StopNow(uint8 exitcode)
Definition World.h:667
@ ERROR_EXIT_CODE
Definition World.h:76