OregonCore  revision fb2a440-git
Your Favourite TBC server
InstanceSaveMgr.h
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 #ifndef _INSTANCESAVEMGR_H
19 #define _INSTANCESAVEMGR_H
20 
21 #include "Platform/Define.h"
22 #include "Policies/Singleton.h"
23 #include "ace/Thread_Mutex.h"
24 #include <list>
25 #include <map>
26 #include "Utilities/UnorderedMap.h"
27 #include "Database/DatabaseEnv.h"
28 
29 struct InstanceTemplate;
30 struct MapEntry;
31 class Player;
32 class Group;
33 
34 /*
35  Holds the information necessary for creating a new map for an existing instance
36  Is referenced in three cases:
37  - player-instance binds for solo players (not in group)
38  - player-instance binds for permanent heroic/raid saves
39  - group-instance binds (both solo and permanent) cache the player binds for the group leader
40 */
42 {
43  friend class InstanceSaveManager;
44  public:
45  /* Created either when:
46  - any new instance is being generated
47  - the first time a player bound to InstanceId logs in
48  - when a group bound to the instance is loaded */
49  InstanceSave(uint16 MapId, uint32 InstanceId, DungeonDifficulty difficulty, time_t resetTime, bool canReset);
50 
51  /* Unloaded when m_playerList and m_groupList become empty
52  or when the instance is reset */
53  ~InstanceSave();
54 
56  {
57  return m_playerList.size();
58  }
60  {
61  return m_groupList.size();
62  }
63 
64  /* A map corresponding to the InstanceId/MapId does not always exist.
65  InstanceSave objects may be created on player logon but the maps are
66  created and loaded only when a player actually enters the instance. */
68  {
69  return m_instanceid;
70  }
72  {
73  return m_mapid;
74  }
75 
76  /* Saved when the instance is generated for the first time */
77  void SaveToDB();
78  /* When the instance is being reset (permanently deleted) */
79  void DeleteFromDB();
80 
81  /* for normal instances this corresponds to max(creature respawn time) + X hours
82  for raid/heroic instances this caches the global respawn time for the map */
83  time_t GetResetTime()
84  {
85  return m_resetTime;
86  }
87  void SetResetTime(time_t resetTime)
88  {
89  m_resetTime = resetTime;
90  }
91  time_t GetResetTimeForDB();
92 
94  MapEntry const* GetMapEntry();
95 
96  /* online players bound to the instance (perm/solo)
97  does not include the members of the group unless they have permanent saves */
98  void AddPlayer(Player* player)
99  {
100  m_playerList.push_back(player);
101  }
102  bool RemovePlayer(Player* player)
103  {
104  m_playerList.remove(player);
105  return UnloadIfEmpty();
106  }
107  /* all groups bound to the instance */
108  void AddGroup(Group* group)
109  {
110  m_groupList.push_back(group);
111  }
112  bool RemoveGroup(Group* group)
113  {
114  m_groupList.remove(group);
115  return UnloadIfEmpty();
116  }
117 
118  /* instances cannot be reset (except at the global reset time)
119  if there are players permanently bound to it
120  this is cached for the case when those players are offline */
121  bool CanReset()
122  {
123  return m_canReset;
124  }
125  void SetCanReset(bool canReset)
126  {
127  m_canReset = canReset;
128  }
129 
130  /* currently it is possible to omit this information from this structure
131  but that would depend on a lot of things that can easily change in future */
133  {
134  return m_difficulty;
135  }
136 
137  typedef std::list<Player*> PlayerListType;
138  typedef std::list<Group*> GroupListType;
139  private:
140  bool UnloadIfEmpty();
141  /* the only reason the instSave-object links are kept is because
142  the object-instSave links need to be broken at reset time
143  @todo maybe it's enough to just store the number of players/groups */
146  time_t m_resetTime;
149  PlayerListType m_playerList;
150  GroupListType m_groupList;
151 };
152 
153 class InstanceSaveManager : public Oregon::Singleton<InstanceSaveManager, Oregon::ClassLevelLockable<InstanceSaveManager, ACE_Thread_Mutex> >
154 {
155  friend class InstanceSave;
156  public:
159 
160  typedef std::map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveMap;
161  typedef UNORDERED_MAP<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap;
162  typedef std::map<uint32 /*mapId*/, InstanceSaveMap> InstanceSaveMapMap;
163 
164  /* resetTime is a global propery of each (raid/heroic) map
165  all instances of that map reset at the same time */
167  {
171  InstResetEvent(uint8 t = 0, uint16 m = 0, uint16 i = 0) : type(t), mapid(m), instanceId(i) {}
172  bool operator == (const InstResetEvent& e)
173  {
174  return e.instanceId == instanceId;
175  }
176  };
177  typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue;
178  typedef std::vector<time_t /*resetTime*/> ResetTimeVector;
179 
180  void CleanupInstances();
181  void PackInstances();
182 
183  void LoadResetTimes();
184  time_t GetResetTimeFor(uint32 mapid)
185  {
186  return m_resetTimeByMapId[mapid];
187  }
188  void ScheduleReset(bool add, time_t time, InstResetEvent event);
189 
190  void Update();
191 
192  InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, DungeonDifficulty difficulty, time_t resetTime, bool canReset, bool load = false);
193  void RemoveInstanceSave(uint32 InstanceId);
194  static void DeleteInstanceFromDB(uint32 instanceid);
195 
196  InstanceSave* GetInstanceSave(uint32 InstanceId);
197 
198  /* statistics */
200  {
201  return m_instanceSaveById.size();
202  }
203  uint32 GetNumBoundPlayersTotal();
204  uint32 GetNumBoundGroupsTotal();
205 
206  protected:
207  static uint16 ResetTimeDelay[];
208 
209  private:
210  void _ResetOrWarnAll(uint32 mapid, bool warn, time_t resetTime);
211  void _ResetInstance(uint32 mapid, uint32 instanceId);
212  void _ResetSave(InstanceSaveHashMap::iterator& itr);
213  void _DelHelper(DatabaseType& db, const char* fields, const char* table, const char* queryTail, ...);
214  // used during global instance resets
216  // fast lookup by instance id
217  InstanceSaveHashMap m_instanceSaveById;
218  // fast lookup for reset times
219  ResetTimeVector m_resetTimeByMapId;
220  ResetTimeQueue m_resetTimeQueue;
221 };
222 
223 #define sInstanceSaveMgr Oregon::Singleton<InstanceSaveManager>::Instance()
224 #endif
225 
PlayerListType m_playerList
std::map< uint32, InstanceSaveMap > InstanceSaveMapMap
std::vector< time_t > ResetTimeVector
uint8 GetPlayerCount()
friend class InstanceSaveManager
DungeonDifficulty GetDifficulty()
uint32 GetMapId()
std::map< uint32, InstanceSave * > InstanceSaveMap
uint8 GetGroupCount()
void SetResetTime(time_t resetTime)
DungeonDifficulty m_difficulty
time_t GetResetTimeFor(uint32 mapid)
DungeonDifficulty
void SetCanReset(bool canReset)
void AddGroup(Group *group)
InstanceTemplate const * GetTemplate()
ResetTimeQueue m_resetTimeQueue
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetInstanceId()
InstResetEvent(uint8 t=0, uint16 m=0, uint16 i=0)
InstanceSaveHashMap m_instanceSaveById
time_t GetResetTimeForDB()
const AuthHandler table[]
Definition: AuthSocket.cpp:149
#define UNORDERED_MAP
Definition: UnorderedMap.h:47
std::list< Group * > GroupListType
std::list< Player * > PlayerListType
time_t GetResetTime()
std::multimap< time_t, InstResetEvent > ResetTimeQueue
MapEntry const * GetMapEntry()
InstanceSave(uint16 MapId, uint32 InstanceId, DungeonDifficulty difficulty, time_t resetTime, bool canReset)
bool RemovePlayer(Player *player)
ResetTimeVector m_resetTimeByMapId
ACE_UINT16 uint16
Definition: Define.h:72
ACE_UINT32 uint32
Definition: Define.h:71
void AddPlayer(Player *player)
bool RemoveGroup(Group *group)
GroupListType m_groupList
Definition: Player.h:922
Definition: Group.h:154
UNORDERED_MAP< uint32, InstanceSave * > InstanceSaveHashMap