root/trunk/src/game/InstanceSaveMgr.h @ 13

Revision 2, 7.1 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#ifndef __InstanceSaveMgr_H
20#define __InstanceSaveMgr_H
21
22#include "Platform/Define.h"
23#include "Policies/Singleton.h"
24#include "zthread/Mutex.h"
25#include <list>
26#include <map>
27#include "Utilities/HashMap.h"
28#include "Database/DatabaseEnv.h"
29
30struct InstanceTemplate;
31struct MapEntry;
32class Player;
33class Group;
34
35/*
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
41*/
42class InstanceSave
43{
44    friend class InstanceSaveManager;
45    public:
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);
51
52        /* Unloaded when m_playerList and m_groupList become empty
53           or when the instance is reset */
54        ~InstanceSave();
55
56        uint8 GetPlayerCount() { return m_playerList.size(); }
57        uint8 GetGroupCount() { return m_groupList.size(); }
58
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; }
64
65        /* Saved when the instance is generated for the first time */
66        void SaveToDB();
67        /* When the instance is being reset (permanently deleted) */
68        void DeleteFromDB();
69
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();
75
76        InstanceTemplate const* GetTemplate();
77        MapEntry const* GetMapEntry();
78
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(); }
86
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; }
92
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; }
96
97        typedef std::list<Player*> PlayerListType;
98        typedef std::list<Group*> GroupListType;
99    private:
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;
106        time_t m_resetTime;
107        uint32 m_instanceid;
108        uint16 m_mapid;
109        uint8 m_difficulty;
110        bool m_canReset;
111};
112
113class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSaveManager, MaNGOS::ClassLevelLockable<InstanceSaveManager, ZThread::Mutex> >
114{
115    friend class InstanceSave;
116    public:
117        InstanceSaveManager();
118        ~InstanceSaveManager();
119
120        typedef std::map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveMap;
121        typedef HM_NAMESPACE::hash_map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap;
122        typedef std::map<uint32 /*mapId*/, InstanceSaveMap> InstanceSaveMapMap;
123
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
127        {
128            uint8 type;
129            uint16 mapid;
130            uint16 instanceId;
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; }
133        };
134        typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue;
135        typedef std::vector<time_t /*resetTime*/> ResetTimeVector;
136
137        void CleanupInstances();
138        void PackInstances();
139
140        void LoadResetTimes();
141        time_t GetResetTimeFor(uint32 mapid) { return m_resetTimeByMapId[mapid]; }
142        void ScheduleReset(bool add, time_t time, InstResetEvent event);
143
144        void Update();
145
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);
149
150        InstanceSave *GetInstanceSave(uint32 InstanceId);
151
152        /* statistics */
153        uint32 GetNumInstanceSaves() { return m_instanceSaveById.size(); }
154        uint32 GetNumBoundPlayersTotal();
155        uint32 GetNumBoundGroupsTotal();
156
157    private:
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
163        bool lock_instLists;
164        // fast lookup by instance id
165        InstanceSaveHashMap m_instanceSaveById;
166        // fast lookup for reset times
167        ResetTimeVector m_resetTimeByMapId;
168        ResetTimeQueue m_resetTimeQueue;
169};
170
171#define sInstanceSaveManager MaNGOS::Singleton<InstanceSaveManager>::Instance()
172#endif
Note: See TracBrowser for help on using the browser.