Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
GroupMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Common.h"
7#include "DBCStores.h"
8#include "GroupMgr.h"
9#include "InstanceSaveMgr.h"
10#include "World.h"
11
13{
14 for (GroupContainer::iterator itr = GroupStore.begin(); itr != GroupStore.end(); ++itr)
15 delete itr->second;
16}
17
19{
20 uint32 newStorageId = NextGroupDbStoreId;
21
22 for (uint32 i = ++NextGroupDbStoreId; i < 0xFFFFFFFF; ++i)
23 {
24 if ((i < GroupDbStore.size() && GroupDbStore[i] == NULL) || i >= GroupDbStore.size())
25 {
27 break;
28 }
29 }
30
31 if (newStorageId == NextGroupDbStoreId)
32 {
33 SF_LOG_ERROR("misc", "Group storage ID overflow!! Can't continue, shutting down server. ");
35 }
36
37 return newStorageId;
38}
39
41{
42 // Allocate space if necessary.
43 if (storageId >= uint32(GroupDbStore.size()))
44 GroupDbStore.resize(storageId + 1);
45
46 GroupDbStore[storageId] = group;
47}
48
50{
51 uint32 storageId = group->GetDbStoreId();
52
53 if (storageId < NextGroupDbStoreId)
54 NextGroupDbStoreId = storageId;
55
56 GroupDbStore[storageId] = NULL;
57}
58
60{
61 if (storageId < GroupDbStore.size())
62 return GroupDbStore[storageId];
63
64 return NULL;
65}
66
68{
69 if (NextGroupId >= 0xFFFFFFFE)
70 {
71 SF_LOG_ERROR("misc", "Group guid overflow!! Can't continue, shutting down server. ");
73 }
74 return NextGroupId++;
75}
76
78{
79 GroupContainer::const_iterator itr = GroupStore.find(groupId);
80 if (itr != GroupStore.end())
81 return itr->second;
82
83 return NULL;
84}
85
87{
88 GroupStore[group->GetLowGUID()] = group;
89}
90
92{
93 GroupStore.erase(group->GetLowGUID());
94}
95
97{
98 {
99 uint32 oldMSTime = getMSTime();
100
101 // Delete all groups whose leader does not exist
102 CharacterDatabase.DirectExecute("DELETE FROM parties WHERE leaderGuid NOT IN (SELECT guid FROM characters)");
103 // Delete all groups with less than 2 members
104 CharacterDatabase.DirectExecute("DELETE FROM parties WHERE guid NOT IN (SELECT guid FROM party_member GROUP BY guid HAVING COUNT(guid) > 1)");
105
106 // 0 1 2 3 4 5 6 7 8 9
107 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"
108 // 10 11 12 13 14 15 16 17
109 ", g.icon7, g.icon8, g.partyType, g.difficulty, g.raiddifficulty, g.guid, lfg.dungeon, lfg.state FROM parties g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
110 if (!result)
111 {
112 SF_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `parties` is empty!");
113 return;
114 }
115
116 uint32 count = 0;
117 do
118 {
119 Field* fields = result->Fetch();
120 Group* group = new Group;
121 group->LoadGroupFromDB(fields);
122 AddGroup(group);
123
124 // Get the ID used for storing the group in the database and register it in the pool.
125 uint32 storageId = group->GetDbStoreId();
126
127 RegisterGroupDbStoreId(storageId, group);
128
129 // Increase the next available storage ID
130 if (storageId == NextGroupDbStoreId)
132
133 ++count;
134 } while (result->NextRow());
135
136 SF_LOG_INFO("server.loading", ">> Loaded %u group definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
137 }
138
139 SF_LOG_INFO("server.loading", "Loading Group members...");
140 {
141 uint32 oldMSTime = getMSTime();
142
143 // Delete all rows from party_member and party_instance with no group
144 CharacterDatabase.DirectExecute("DELETE FROM party_member WHERE guid NOT IN (SELECT guid FROM parties)");
145 CharacterDatabase.DirectExecute("DELETE FROM party_instance WHERE guid NOT IN (SELECT guid FROM parties)");
146 // Delete all members that does not exist
147 CharacterDatabase.DirectExecute("DELETE FROM party_member WHERE memberGuid NOT IN (SELECT guid FROM characters)");
148
149 // 0 1 2 3 4
150 QueryResult result = CharacterDatabase.Query("SELECT guid, memberGuid, memberFlags, subparty, roles FROM party_member ORDER BY guid");
151 if (!result)
152 {
153 SF_LOG_INFO("server.loading", ">> Loaded 0 group members. DB table `party_member` is empty!");
154 return;
155 }
156
157 uint32 count = 0;
158
159 do
160 {
161 Field* fields = result->Fetch();
162 Group* group = GetGroupByDbStoreId(fields[0].GetUInt32());
163
164 if (group)
165 group->LoadMemberFromDB(fields[1].GetUInt32(), fields[2].GetUInt8(), fields[3].GetUInt8(), fields[4].GetUInt8());
166 else
167 SF_LOG_ERROR("misc", "GroupMgr::LoadGroups: Consistency failed, can't find group (storage id: %u)", fields[0].GetUInt32());
168
169 ++count;
170 } while (result->NextRow());
171
172 SF_LOG_INFO("server.loading", ">> Loaded %u group members in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
173 }
174
175 SF_LOG_INFO("server.loading", "Loading Group instance saves...");
176 {
177 uint32 oldMSTime = getMSTime();
178 // 0 1 2 3 4 5 6
179 QueryResult result = CharacterDatabase.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, COUNT(g.guid) "
180 "FROM party_instance gi INNER JOIN instance i ON gi.instance = i.id "
181 "LEFT JOIN character_instance ci LEFT JOIN parties g ON g.leaderGuid = ci.guid ON ci.instance = gi.instance AND ci.permanent = 1 GROUP BY gi.instance ORDER BY gi.guid");
182 if (!result)
183 {
184 SF_LOG_INFO("server.loading", ">> Loaded 0 group-instance saves. DB table `party_instance` is empty!");
185 return;
186 }
187
188 uint32 count = 0;
189 do
190 {
191 Field* fields = result->Fetch();
192 Group* group = GetGroupByDbStoreId(fields[0].GetUInt32());
193 // group will never be NULL (we have run consistency sql's before loading)
194
195 MapEntry const* mapEntry = sMapStore.LookupEntry(fields[1].GetUInt16());
196 if (!mapEntry || !mapEntry->IsInstance())
197 {
198 SF_LOG_ERROR("sql.sql", "Incorrect entry in party_instance table : no dungeon map %d", fields[1].GetUInt16());
199 continue;
200 }
201
202 uint32 diff = fields[4].GetUInt8();
203 DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(diff);
204 if (!difficultyEntry || difficultyEntry->maptype != mapEntry->map_type)
205 continue;
206
207 InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), DifficultyID(diff), time_t(fields[5].GetUInt32()), (bool)fields[6].GetUInt64(), true);
208 group->BindToInstance(save, fields[3].GetBool(), true);
209 ++count;
210 } while (result->NextRow());
211
212 SF_LOG_INFO("server.loading", ">> Loaded %u group-instance saves in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
213 }
214}
DifficultyID
Definition DBCEnums.h:330
DBCStorage< DifficultyEntry > sDifficultyStore(Difficultyfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
std::uint32_t uint32
Definition Define.h:77
#define sInstanceSaveMgr
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
Definition QueryResult.h:48
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
uint32 GetUInt32() const
Definition Field.h:105
Definition Group.h:147
void LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
Definition Group.cpp:177
InstanceGroupBind * BindToInstance(InstanceSave *save, bool permanent, bool load=false)
Definition Group.cpp:2426
void LoadGroupFromDB(Field *field)
Definition Group.cpp:149
uint32 GetLowGUID() const
Definition Group.cpp:2578
uint32 GetDbStoreId() const
Definition Group.h:206
Group * GetGroupByGUID(uint32 guid) const
Definition GroupMgr.cpp:77
uint32 GenerateGroupId()
Definition GroupMgr.cpp:67
void FreeGroupDbStoreId(Group *group)
Definition GroupMgr.cpp:49
Group * GetGroupByDbStoreId(uint32 storageId) const
Definition GroupMgr.cpp:59
uint32 GenerateNewGroupDbStoreId()
Definition GroupMgr.cpp:18
void RemoveGroup(Group *group)
Definition GroupMgr.cpp:91
uint32 NextGroupId
Definition GroupMgr.h:38
GroupDbContainer GroupDbStore
Definition GroupMgr.h:41
uint32 NextGroupDbStoreId
Definition GroupMgr.h:39
void LoadGroups()
Definition GroupMgr.cpp:96
void AddGroup(Group *group)
Definition GroupMgr.cpp:86
void RegisterGroupDbStoreId(uint32 storageId, Group *group)
Definition GroupMgr.cpp:40
GroupContainer GroupStore
Definition GroupMgr.h:40
static void StopNow(uint8 exitcode)
Definition World.h:674
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ ERROR_EXIT_CODE
Definition World.h:65
uint32 maptype
bool IsInstance() const
uint32 MapID
uint32 map_type