TrinityCore
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
26{
29}
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 if (NextGroupId >= 0xFFFFFFFE)
89 {
90 TC_LOG_ERROR("misc", "Group guid overflow!! Can't continue, shutting down server. ");
92 }
93 return NextGroupId++;
94}
95
97{
98 static GroupMgr instance;
99 return &instance;
100}
101
103{
104 GroupContainer::const_iterator itr = GroupStore.find(groupId.GetCounter());
105 if (itr != GroupStore.end())
106 return itr->second;
107
108 return nullptr;
109}
110
112{
113 for (std::pair<ObjectGuid::LowType const, Group*> const& group : GroupStore)
114 group.second->Update(diff);
115}
116
118{
119 GroupStore[group->GetGUID().GetCounter()] = group;
120}
121
123{
124 GroupStore.erase(group->GetGUID().GetCounter());
125}
126
128{
129 {
130 uint32 oldMSTime = getMSTime();
131
132 // Delete all members that does not exist
133 CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)");
134 // Delete all groups whose leader does not exist
135 CharacterDatabase.DirectExecute("DELETE FROM `groups` WHERE leaderGuid NOT IN (SELECT guid FROM characters)");
136 // Delete all groups with less than 2 members
137 CharacterDatabase.DirectExecute("DELETE FROM `groups` WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)");
138 // Delete all rows from group_member with no group
139 CharacterDatabase.DirectExecute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM `groups`)");
140
141 // 0 1 2 3 4 5 6 7 8 9
142 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"
143 // 10 11 12 13 14 15 16 17 18 19
144 ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.legacyRaidDifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM `groups` g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
145 if (!result)
146 {
147 TC_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `groups` is empty!");
148 return;
149 }
150
151 uint32 count = 0;
152 do
153 {
154 Field* fields = result->Fetch();
155 Group* group = new Group;
156 group->LoadGroupFromDB(fields);
157 AddGroup(group);
158
159 // Get the ID used for storing the group in the database and register it in the pool.
160 uint32 storageId = group->GetDbStoreId();
161
162 RegisterGroupDbStoreId(storageId, group);
163
164 // Increase the next available storage ID
165 if (storageId == NextGroupDbStoreId)
167
168 ++count;
169 }
170 while (result->NextRow());
171
172 TC_LOG_INFO("server.loading", ">> Loaded {} group definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
173 }
174
175 TC_LOG_INFO("server.loading", "Loading Group members...");
176 {
177 uint32 oldMSTime = getMSTime();
178
179 // 0 1 2 3 4
180 QueryResult result = CharacterDatabase.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid");
181 if (!result)
182 {
183 TC_LOG_INFO("server.loading", ">> Loaded 0 group members. DB table `group_member` is empty!");
184 return;
185 }
186
187 uint32 count = 0;
188
189 do
190 {
191 Field* fields = result->Fetch();
192 Group* group = GetGroupByDbStoreId(fields[0].GetUInt32());
193
194 if (group)
195 group->LoadMemberFromDB(fields[1].GetUInt64(), fields[2].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt8());
196 else
197 TC_LOG_ERROR("misc", "GroupMgr::LoadGroups: Consistency failed, can't find group (storage id: {})", fields[0].GetUInt32());
198
199 ++count;
200 }
201 while (result->NextRow());
202
203 TC_LOG_INFO("server.loading", ">> Loaded {} group members in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
204 }
205}
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
#define UI64LIT(N)
Definition: Define.h:127
uint32_t uint32
Definition: Define.h:142
#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
static Summons Group[]
Definition: boss_urom.cpp:83
Class used to access individual fields of database query result.
Definition: Field.h:90
static GroupMgr * instance()
Definition: GroupMgr.cpp:96
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:102
void RemoveGroup(Group *group)
Definition: GroupMgr.cpp:122
GroupMgr()
Definition: GroupMgr.cpp:25
ObjectGuid::LowType NextGroupId
Definition: GroupMgr.h:55
void Update(uint32 diff)
Definition: GroupMgr.cpp:111
GroupDbContainer GroupDbStore
Definition: GroupMgr.h:58
uint32 NextGroupDbStoreId
Definition: GroupMgr.h:56
void LoadGroups()
Definition: GroupMgr.cpp:127
void AddGroup(Group *group)
Definition: GroupMgr.cpp:117
~GroupMgr()
Definition: GroupMgr.cpp:31
ObjectGuid::LowType GenerateGroupId()
Definition: GroupMgr.cpp:86
void RegisterGroupDbStoreId(uint32 storageId, Group *group)
Definition: GroupMgr.cpp:59
GroupContainer GroupStore
Definition: GroupMgr.h:57
Definition: Group.h:197
void LoadGroupFromDB(Field *field)
Definition: Group.cpp:216
ObjectGuid GetGUID() const
Definition: Group.cpp:1663
void LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
Definition: Group.cpp:250
uint32 GetDbStoreId() const
Definition: Group.h:304
LowType GetCounter() const
Definition: ObjectGuid.h:293
uint64 LowType
Definition: ObjectGuid.h:278
static void StopNow(uint8 exitcode)
Definition: World.h:670
@ ERROR_EXIT_CODE
Definition: World.h:75