2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef __InstanceSaveMgr_H
20 #define __InstanceSaveMgr_H
22 #include "Platform/Define.h"
23 #include "Policies/Singleton.h"
24 #include "ace/Thread_Mutex.h"
27 #include "Utilities/UnorderedMap.h"
28 #include "Database/DatabaseEnv.h"
30 #include "ObjectGuid.h"
32 struct InstanceTemplate
;
38 Holds the information necessary for creating a new map for an existing instance
39 Is referenced in three cases:
40 - player-instance binds for solo players (not in group)
41 - player-instance binds for permanent heroic/raid saves
42 - group-instance binds (both solo and permanent) cache the player binds for the group leader
46 friend class InstanceSaveManager
;
48 /* Created either when:
49 - any new instance is being generated
50 - the first time a player bound to InstanceId logs in
51 - when a group bound to the instance is loaded */
52 InstanceSave(uint16 MapId
, uint32 InstanceId
, Difficulty difficulty
, time_t resetTime
, bool canReset
);
54 /* Unloaded when m_playerList and m_groupList become empty
55 or when the instance is reset */
58 uint8
GetPlayerCount() { return m_playerList
.size(); }
59 uint8
GetGroupCount() { return m_groupList
.size(); }
61 /* A map corresponding to the InstanceId/MapId does not always exist.
62 InstanceSave objects may be created on player logon but the maps are
63 created and loaded only when a player actually enters the instance. */
64 uint32
GetInstanceId() { return m_instanceid
; }
65 uint32
GetMapId() { return m_mapid
; }
67 /* Saved when the instance is generated for the first time */
69 /* When the instance is being reset (permanently deleted) */
72 /* for normal instances this corresponds to max(creature respawn time) + X hours
73 for raid/heroic instances this caches the global respawn time for the map */
74 time_t GetResetTime() { return m_resetTime
; }
75 void SetResetTime(time_t resetTime
) { m_resetTime
= resetTime
; }
76 time_t GetResetTimeForDB();
78 InstanceTemplate
const* GetTemplate();
79 MapEntry
const* GetMapEntry();
81 /* online players bound to the instance (perm/solo)
82 does not include the members of the group unless they have permanent saves */
83 void AddPlayer(Player
*player
) { m_playerList
.push_back(player
); }
84 bool RemovePlayer(Player
*player
) { m_playerList
.remove(player
); return UnloadIfEmpty(); }
85 /* all groups bound to the instance */
86 void AddGroup(Group
*group
) { m_groupList
.push_back(group
); }
87 bool RemoveGroup(Group
*group
) { m_groupList
.remove(group
); return UnloadIfEmpty(); }
89 /* instances cannot be reset (except at the global reset time)
90 if there are players permanently bound to it
91 this is cached for the case when those players are offline */
92 bool CanReset() { return m_canReset
; }
93 void SetCanReset(bool canReset
) { m_canReset
= canReset
; }
95 /* currently it is possible to omit this information from this structure
96 but that would depend on a lot of things that can easily change in future */
97 Difficulty
GetDifficulty() { return m_difficulty
; }
99 typedef std::list
<Player
*> PlayerListType
;
100 typedef std::list
<Group
*> GroupListType
;
102 bool UnloadIfEmpty();
103 /* the only reason the instSave-object links are kept is because
104 the object-instSave links need to be broken at reset time
105 TODO: maybe it's enough to just store the number of players/groups */
106 PlayerListType m_playerList
;
107 GroupListType m_groupList
;
111 Difficulty m_difficulty
;
115 class MANGOS_DLL_DECL InstanceSaveManager
: public MaNGOS::Singleton
<InstanceSaveManager
, MaNGOS::ClassLevelLockable
<InstanceSaveManager
, ACE_Thread_Mutex
> >
117 friend class InstanceSave
;
119 InstanceSaveManager();
120 ~InstanceSaveManager();
122 typedef UNORDERED_MAP
<uint32
/*InstanceId*/, InstanceSave
*> InstanceSaveHashMap
;
123 typedef UNORDERED_MAP
<uint32
/*mapId*/, InstanceSaveHashMap
> InstanceSaveMapMap
;
125 /* resetTime is a global propery of each (raid/heroic) map
126 all instances of that map reset at the same time */
127 struct InstResetEvent
130 Difficulty difficulty
:8;
134 InstResetEvent() : type(0), difficulty(DUNGEON_DIFFICULTY_NORMAL
), mapid(0), instanceId(0) {}
135 InstResetEvent(uint8 t
, uint32 _mapid
, Difficulty d
, uint16 _instanceid
)
136 : type(t
), difficulty(d
), mapid(_mapid
), instanceId(_instanceid
) {}
137 bool operator == (const InstResetEvent
& e
) { return e
.instanceId
== instanceId
; }
139 typedef std::multimap
<time_t /*resetTime*/, InstResetEvent
> ResetTimeQueue
;
140 typedef UNORDERED_MAP
<uint32
/*PAIR32(map,difficulty)*/,time_t /*resetTime*/> ResetTimeByMapDifficultyMap
;
142 void CleanupInstances();
143 void PackInstances();
145 void LoadResetTimes();
146 time_t GetResetTimeFor(uint32 mapid
, Difficulty d
) const
148 ResetTimeByMapDifficultyMap::const_iterator itr
= m_resetTimeByMapDifficulty
.find(MAKE_PAIR32(mapid
,d
));
149 return itr
!= m_resetTimeByMapDifficulty
.end() ? itr
->second
: 0;
151 void SetResetTimeFor(uint32 mapid
, Difficulty d
, time_t t
)
153 m_resetTimeByMapDifficulty
[MAKE_PAIR32(mapid
,d
)] = t
;
155 void ScheduleReset(bool add
, time_t time
, InstResetEvent event
);
159 InstanceSave
* AddInstanceSave(uint32 mapId
, uint32 instanceId
, Difficulty difficulty
, time_t resetTime
, bool canReset
, bool load
= false);
160 void RemoveInstanceSave(uint32 InstanceId
);
161 static void DeleteInstanceFromDB(uint32 instanceid
);
163 InstanceSave
*GetInstanceSave(uint32 InstanceId
);
166 uint32
GetNumInstanceSaves() { return m_instanceSaveById
.size(); }
167 uint32
GetNumBoundPlayersTotal();
168 uint32
GetNumBoundGroupsTotal();
171 void _ResetOrWarnAll(uint32 mapid
, Difficulty difficulty
, bool warn
, uint32 timeleft
);
172 void _ResetInstance(uint32 mapid
, uint32 instanceId
);
173 void _ResetSave(InstanceSaveHashMap::iterator
&itr
);
174 void _DelHelper(DatabaseType
&db
, const char *fields
, const char *table
, const char *queryTail
,...);
175 // used during global instance resets
177 // fast lookup by instance id
178 InstanceSaveHashMap m_instanceSaveById
;
179 // fast lookup for reset times (always use existed functions for access/set)
180 ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
;
181 ResetTimeQueue m_resetTimeQueue
;
184 #define sInstanceSaveMgr MaNGOS::Singleton<InstanceSaveManager>::Instance()