2 * Copyright (C) 2005,2006,2007 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 "zthread/Mutex.h"
27 #include "Utilities/UnorderedMap.h"
28 #include "Database/DatabaseEnv.h"
30 struct InstanceTemplate
;
36 Holds the information necessary for creating a new map for an existing instance
37 Is referenced in three cases:
38 - player-instance binds for solo players (not in group)
39 - player-instance binds for permanent heroic/raid saves
40 - group-instance binds (both solo and permanent) cache the player binds for the group leader
44 friend class InstanceSaveManager
;
46 /* Created either when:
47 - any new instance is being generated
48 - the first time a player bound to InstanceId logs in
49 - when a group bound to the instance is loaded */
50 InstanceSave(uint16 MapId
, uint32 InstanceId
, uint8 difficulty
, time_t resetTime
, bool canReset
);
52 /* Unloaded when m_playerList and m_groupList become empty
53 or when the instance is reset */
56 uint8
GetPlayerCount() { return m_playerList
.size(); }
57 uint8
GetGroupCount() { return m_groupList
.size(); }
59 /* A map corresponding to the InstanceId/MapId does not always exist.
60 InstanceSave objects may be created on player logon but the maps are
61 created and loaded only when a player actually enters the instance. */
62 uint32
GetInstanceId() { return m_instanceid
; }
63 uint32
GetMapId() { return m_mapid
; }
65 /* Saved when the instance is generated for the first time */
67 /* When the instance is being reset (permanently deleted) */
70 /* for normal instances this corresponds to max(creature respawn time) + X hours
71 for raid/heroic instances this caches the global respawn time for the map */
72 time_t GetResetTime() { return m_resetTime
; }
73 void SetResetTime(time_t resetTime
) { m_resetTime
= resetTime
; }
74 time_t GetResetTimeForDB();
76 InstanceTemplate
const* GetTemplate();
77 MapEntry
const* GetMapEntry();
79 /* online players bound to the instance (perm/solo)
80 does not include the members of the group unless they have permanent saves */
81 void AddPlayer(Player
*player
) { m_playerList
.push_back(player
); }
82 bool RemovePlayer(Player
*player
) { m_playerList
.remove(player
); return UnloadIfEmpty(); }
83 /* all groups bound to the instance */
84 void AddGroup(Group
*group
) { m_groupList
.push_back(group
); }
85 bool RemoveGroup(Group
*group
) { m_groupList
.remove(group
); return UnloadIfEmpty(); }
87 /* instances cannot be reset (except at the global reset time)
88 if there are players permanently bound to it
89 this is cached for the case when those players are offline */
90 bool CanReset() { return m_canReset
; }
91 void SetCanReset(bool canReset
) { m_canReset
= canReset
; }
93 /* currently it is possible to omit this information from this structure
94 but that would depend on a lot of things that can easily change in future */
95 uint8
GetDifficulty() { return m_difficulty
; }
97 typedef std::list
<Player
*> PlayerListType
;
98 typedef std::list
<Group
*> GroupListType
;
100 bool UnloadIfEmpty();
101 /* the only reason the instSave-object links are kept is because
102 the object-instSave links need to be broken at reset time
103 TODO: maybe it's enough to just store the number of players/groups */
104 PlayerListType m_playerList
;
105 GroupListType m_groupList
;
113 class MANGOS_DLL_DECL InstanceSaveManager
: public MaNGOS::Singleton
<InstanceSaveManager
, MaNGOS::ClassLevelLockable
<InstanceSaveManager
, ZThread::Mutex
> >
115 friend class InstanceSave
;
117 InstanceSaveManager();
118 ~InstanceSaveManager();
120 typedef std::map
<uint32
/*InstanceId*/, InstanceSave
*> InstanceSaveMap
;
121 typedef UNORDERED_MAP
<uint32
/*InstanceId*/, InstanceSave
*> InstanceSaveHashMap
;
122 typedef std::map
<uint32
/*mapId*/, InstanceSaveMap
> InstanceSaveMapMap
;
124 /* resetTime is a global propery of each (raid/heroic) map
125 all instances of that map reset at the same time */
126 struct InstResetEvent
131 InstResetEvent(uint8 t
= 0, uint16 m
= 0, uint16 i
= 0) : type(t
), mapid(m
), instanceId(i
) {}
132 bool operator == (const InstResetEvent
& e
) { return e
.instanceId
== instanceId
; }
134 typedef std::multimap
<time_t /*resetTime*/, InstResetEvent
> ResetTimeQueue
;
135 typedef std::vector
<time_t /*resetTime*/> ResetTimeVector
;
137 void CleanupInstances();
138 void PackInstances();
140 void LoadResetTimes();
141 time_t GetResetTimeFor(uint32 mapid
) { return m_resetTimeByMapId
[mapid
]; }
142 void ScheduleReset(bool add
, time_t time
, InstResetEvent event
);
146 InstanceSave
* AddInstanceSave(uint32 mapId
, uint32 instanceId
, uint8 difficulty
, time_t resetTime
, bool canReset
, bool load
= false);
147 void RemoveInstanceSave(uint32 InstanceId
);
148 static void DeleteInstanceFromDB(uint32 instanceid
);
150 InstanceSave
*GetInstanceSave(uint32 InstanceId
);
153 uint32
GetNumInstanceSaves() { return m_instanceSaveById
.size(); }
154 uint32
GetNumBoundPlayersTotal();
155 uint32
GetNumBoundGroupsTotal();
158 void _ResetOrWarnAll(uint32 mapid
, bool warn
, uint32 timeleft
);
159 void _ResetInstance(uint32 mapid
, uint32 instanceId
);
160 void _ResetSave(InstanceSaveHashMap::iterator
&itr
);
161 void _DelHelper(DatabaseType
&db
, const char *fields
, const char *table
, const char *queryTail
,...);
162 // used during global instance resets
164 // fast lookup by instance id
165 InstanceSaveHashMap m_instanceSaveById
;
166 // fast lookup for reset times
167 ResetTimeVector m_resetTimeByMapId
;
168 ResetTimeQueue m_resetTimeQueue
;
171 #define sInstanceSaveManager MaNGOS::Singleton<InstanceSaveManager>::Instance()