Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
InstanceSaveMgr.h
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#ifndef SF_INSTANCESAVEMGR_H
7#define SF_INSTANCESAVEMGR_H
8
9#include "DatabaseEnv.h"
10#include "DBCEnums.h"
11#include "Define.h"
12#include "ObjectDefines.h"
13#include "Platform/Singleton.h"
14#include "UnorderedMap.h"
15#include <list>
16#include <map>
17#include <mutex>
18
19struct InstanceTemplate;
20struct MapEntry;
21class Player;
22class Group;
23
24/*
25 Holds the information necessary for creating a new map for an existing instance
26 Is referenced in three cases:
27 - player-instance binds for solo players (not in group)
28 - player-instance binds for permanent heroic/raid saves
29 - group-instance binds (both solo and permanent) cache the player binds for the group leader
30*/
32{
33 friend class InstanceSaveManager;
34public:
35 /* Created either when:
36 - any new instance is being generated
37 - the first time a player bound to InstanceId logs in
38 - when a group bound to the instance is loaded */
39 InstanceSave(uint16 MapId, uint32 InstanceId, DifficultyID difficulty, time_t resetTime, bool canReset);
40
41 /* Unloaded when m_playerList and m_groupList become empty
42 or when the instance is reset */
44
45 uint8 GetPlayerCount() const { return m_playerList.size(); }
46 uint8 GetGroupCount() const { return m_groupList.size(); }
47
48 /* A map corresponding to the InstanceId/MapId does not always exist.
49 InstanceSave objects may be created on player logon but the maps are
50 created and loaded only when a player actually enters the instance. */
51 uint32 GetInstanceId() const { return m_instanceid; }
52 uint32 GetMapId() const { return m_mapid; }
53
54 /* Saved when the instance is generated for the first time */
55 void SaveToDB();
56 /* When the instance is being reset (permanently deleted) */
57 void DeleteFromDB();
58
59 /* for normal instances this corresponds to max(creature respawn time) + X hours
60 for raid/heroic instances this caches the global respawn time for the map */
61 time_t GetResetTime() const { return m_resetTime; }
62 void SetResetTime(time_t resetTime) { m_resetTime = resetTime; }
63 time_t GetResetTimeForDB();
64
66 MapEntry const* GetMapEntry();
67
68 /* online players bound to the instance (perm/solo)
69 does not include the members of the group unless they have permanent saves */
70 void AddPlayer(Player* player) { std::lock_guard<std::mutex> guard(_lock); m_playerList.push_back(player); }
71 bool RemovePlayer(Player* player)
72 {
73 _lock.lock();
74 m_playerList.remove(player);
75 bool isStillValid = UnloadIfEmpty();
76 _lock.unlock();
77
78 //delete here if needed, after releasing the lock
79 if (m_toDelete)
80 delete this;
81
82 return isStillValid;
83 }
84 /* all groups bound to the instance */
85 void AddGroup(Group* group) { m_groupList.push_back(group); }
86 bool RemoveGroup(Group* group)
87 {
88 m_groupList.remove(group);
89 bool isStillValid = UnloadIfEmpty();
90 if (m_toDelete)
91 delete this;
92 return isStillValid;
93 }
94
95 /* instances cannot be reset (except at the global reset time)
96 if there are players permanently bound to it
97 this is cached for the case when those players are offline */
98 bool CanReset() const { return m_canReset; }
99 void SetCanReset(bool canReset) { m_canReset = canReset; }
100
101 /* currently it is possible to omit this information from this structure
102 but that would depend on a lot of things that can easily change in future */
104
105 /* used to flag the InstanceSave as to be deleted, so the caller can delete it */
106 void SetToDelete(bool toDelete)
107 {
108 m_toDelete = toDelete;
109 }
110
111 typedef std::list<Player*> PlayerListType;
112 typedef std::list<Group*> GroupListType;
113private:
114 bool UnloadIfEmpty();
115 /* the only reason the instSave-object links are kept is because
116 the object-instSave links need to be broken at reset time */
126
127 std::mutex _lock;
128};
129
130typedef UNORDERED_MAP<uint32 /*PAIR32(map, difficulty)*/, time_t /*resetTime*/> ResetTimeByMapDifficultyMap;
131
133{
134 friend class Skyfire::Singleton<InstanceSaveManager, Skyfire::Mutex>;
135 friend class InstanceSave;
136
137private:
140
141public:
143
144 /* resetTime is a global propery of each (raid/heroic) map
145 all instances of that map reset at the same time */
158 typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue;
159
160 void LoadInstances();
161
162 void LoadResetTimes();
163 time_t GetResetTimeFor(uint32 mapid, DifficultyID d) const
164 {
165 ResetTimeByMapDifficultyMap::const_iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d));
166 return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0;
167 }
168
169 void SetResetTimeFor(uint32 mapid, DifficultyID d, time_t t)
170 {
172 }
173
178 void ScheduleReset(bool add, time_t time, InstResetEvent event);
179
180 void Update();
181
182 InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, DifficultyID difficulty, time_t resetTime,
183 bool canReset, bool load = false);
184 void RemoveInstanceSave(uint32 InstanceId);
185 static void DeleteInstanceFromDB(uint32 instanceid);
186
188
189 /* statistics */
193
194protected:
195 static uint16 ResetTimeDelay[];
196
197private:
198 void _ResetOrWarnAll(uint32 mapid, DifficultyID difficulty, bool warn, time_t resetTime);
199 void _ResetInstance(uint32 mapid, uint32 instanceId);
200 void _ResetSave(InstanceSaveHashMap::iterator& itr);
201 // used during global instance resets
203 // fast lookup by instance id
205 // fast lookup for reset times (always use existed functions for access/set)
208};
209
210#define sInstanceSaveMgr Skyfire::Singleton<InstanceSaveManager, Skyfire::Mutex>::instance()
211#endif
DifficultyID
Definition DBCEnums.h:330
@ DIFFICULTY_NORMAL
Definition DBCEnums.h:332
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint16_t uint16
Definition Define.h:78
UNORDERED_MAP< uint32, time_t > ResetTimeByMapDifficultyMap
uint32 MAKE_PAIR32(uint16 l, uint16 h)
#define UNORDERED_MAP
Definition Group.h:147
std::mutex _lock
void AddPlayer(Player *player)
DifficultyID GetDifficulty() const
DifficultyID m_difficulty
InstanceTemplate const * GetTemplate()
bool RemovePlayer(Player *player)
uint8 GetPlayerCount() const
bool RemoveGroup(Group *group)
uint8 GetGroupCount() const
MapEntry const * GetMapEntry()
void SetCanReset(bool canReset)
time_t GetResetTimeForDB()
void SetResetTime(time_t resetTime)
uint32 GetInstanceId() const
std::list< Group * > GroupListType
uint32 GetMapId() const
void AddGroup(Group *group)
bool CanReset() const
PlayerListType m_playerList
friend class InstanceSaveManager
std::list< Player * > PlayerListType
InstanceSave(uint16 MapId, uint32 InstanceId, DifficultyID difficulty, time_t resetTime, bool canReset)
GroupListType m_groupList
time_t GetResetTime() const
void SetToDelete(bool toDelete)
InstanceSave * GetInstanceSave(uint32 InstanceId)
std::multimap< time_t, InstResetEvent > ResetTimeQueue
UNORDERED_MAP< uint32, InstanceSave * > InstanceSaveHashMap
static void DeleteInstanceFromDB(uint32 instanceid)
void SetResetTimeFor(uint32 mapid, DifficultyID d, time_t t)
void _ResetInstance(uint32 mapid, uint32 instanceId)
InstanceSaveHashMap m_instanceSaveById
static uint16 ResetTimeDelay[]
ResetTimeByMapDifficultyMap const & GetResetTimeMap() const
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
friend class InstanceSave
void RemoveInstanceSave(uint32 InstanceId)
void ScheduleReset(bool add, time_t time, InstResetEvent event)
void _ResetOrWarnAll(uint32 mapid, DifficultyID difficulty, bool warn, time_t resetTime)
InstanceSave * AddInstanceSave(uint32 mapId, uint32 instanceId, DifficultyID difficulty, time_t resetTime, bool canReset, bool load=false)
ResetTimeQueue m_resetTimeQueue
void _ResetSave(InstanceSaveHashMap::iterator &itr)
time_t GetResetTimeFor(uint32 mapid, DifficultyID d) const
bool operator==(const InstResetEvent &e) const
InstResetEvent(uint8 t, uint32 _mapid, DifficultyID d, uint16 _instanceid)