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

Revision 102, 7.2 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed copyright notices to comply with GPL.

Original author: w12x
Date: 2008-10-23 03:29:52-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __InstanceSaveMgr_H
23#define __InstanceSaveMgr_H
24
25#include "Platform/Define.h"
26#include "Policies/Singleton.h"
27#include "zthread/Mutex.h"
28#include <list>
29#include <map>
30#include "Utilities/HashMap.h"
31#include "Database/DatabaseEnv.h"
32
33struct InstanceTemplate;
34struct MapEntry;
35class Player;
36class Group;
37
38/*
39    Holds the information necessary for creating a new map for an existing instance
40    Is referenced in three cases:
41    - player-instance binds for solo players (not in group)
42    - player-instance binds for permanent heroic/raid saves
43    - group-instance binds (both solo and permanent) cache the player binds for the group leader
44*/
45class InstanceSave
46{
47    friend class InstanceSaveManager;
48    public:
49        /* Created either when:
50           - any new instance is being generated
51           - the first time a player bound to InstanceId logs in
52           - when a group bound to the instance is loaded */
53        InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset);
54
55        /* Unloaded when m_playerList and m_groupList become empty
56           or when the instance is reset */
57        ~InstanceSave();
58
59        uint8 GetPlayerCount() { return m_playerList.size(); }
60        uint8 GetGroupCount() { return m_groupList.size(); }
61
62        /* A map corresponding to the InstanceId/MapId does not always exist.
63        InstanceSave objects may be created on player logon but the maps are
64        created and loaded only when a player actually enters the instance. */
65        uint32 GetInstanceId() { return m_instanceid; }
66        uint32 GetMapId() { return m_mapid; }
67
68        /* Saved when the instance is generated for the first time */
69        void SaveToDB();
70        /* When the instance is being reset (permanently deleted) */
71        void DeleteFromDB();
72
73        /* for normal instances this corresponds to max(creature respawn time) + X hours
74           for raid/heroic instances this caches the global respawn time for the map */
75        time_t GetResetTime() { return m_resetTime; }
76        void SetResetTime(time_t resetTime) { m_resetTime = resetTime; }
77        time_t GetResetTimeForDB();
78
79        InstanceTemplate const* GetTemplate();
80        MapEntry const* GetMapEntry();
81
82        /* online players bound to the instance (perm/solo)
83           does not include the members of the group unless they have permanent saves */
84        void AddPlayer(Player *player) { m_playerList.push_back(player); }
85        bool RemovePlayer(Player *player) { m_playerList.remove(player); return UnloadIfEmpty(); }
86        /* all groups bound to the instance */
87        void AddGroup(Group *group) { m_groupList.push_back(group); }
88        bool RemoveGroup(Group *group) { m_groupList.remove(group); return UnloadIfEmpty(); }
89
90        /* instances cannot be reset (except at the global reset time)
91           if there are players permanently bound to it
92           this is cached for the case when those players are offline */
93        bool CanReset() { return m_canReset; }
94        void SetCanReset(bool canReset) { m_canReset = canReset; }
95
96        /* currently it is possible to omit this information from this structure
97           but that would depend on a lot of things that can easily change in future */
98        uint8 GetDifficulty() { return m_difficulty; }
99
100        typedef std::list<Player*> PlayerListType;
101        typedef std::list<Group*> GroupListType;
102    private:
103        bool UnloadIfEmpty();
104        /* the only reason the instSave-object links are kept is because
105           the object-instSave links need to be broken at reset time
106           TODO: maybe it's enough to just store the number of players/groups */
107        PlayerListType m_playerList;
108        GroupListType m_groupList;
109        time_t m_resetTime;
110        uint32 m_instanceid;
111        uint16 m_mapid;
112        uint8 m_difficulty;
113        bool m_canReset;
114};
115
116class TRINITY_DLL_DECL InstanceSaveManager : public Trinity::Singleton<InstanceSaveManager, Trinity::ClassLevelLockable<InstanceSaveManager, ZThread::Mutex> >
117{
118    friend class InstanceSave;
119    public:
120        InstanceSaveManager();
121        ~InstanceSaveManager();
122
123        typedef std::map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveMap;
124        typedef HM_NAMESPACE::hash_map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap;
125        typedef std::map<uint32 /*mapId*/, InstanceSaveMap> InstanceSaveMapMap;
126
127        /* resetTime is a global propery of each (raid/heroic) map
128           all instances of that map reset at the same time */
129        struct InstResetEvent
130        {
131            uint8 type;
132            uint16 mapid;
133            uint16 instanceId;
134            InstResetEvent(uint8 t = 0, uint16 m = 0, uint16 i = 0) : type(t), mapid(m), instanceId(i) {}
135            bool operator == (const InstResetEvent& e) { return e.instanceId == instanceId; }
136        };
137        typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue;
138        typedef std::vector<time_t /*resetTime*/> ResetTimeVector;
139
140        void CleanupInstances();
141        void PackInstances();
142
143        void LoadResetTimes();
144        time_t GetResetTimeFor(uint32 mapid) { return m_resetTimeByMapId[mapid]; }
145        void ScheduleReset(bool add, time_t time, InstResetEvent event);
146
147        void Update();
148
149        InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load = false);
150        void RemoveInstanceSave(uint32 InstanceId);
151        static void DeleteInstanceFromDB(uint32 instanceid);
152
153        InstanceSave *GetInstanceSave(uint32 InstanceId);
154
155        /* statistics */
156        uint32 GetNumInstanceSaves() { return m_instanceSaveById.size(); }
157        uint32 GetNumBoundPlayersTotal();
158        uint32 GetNumBoundGroupsTotal();
159
160    private:
161        void _ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeleft);
162        void _ResetInstance(uint32 mapid, uint32 instanceId);
163        void _ResetSave(InstanceSaveHashMap::iterator &itr);
164        void _DelHelper(DatabaseType &db, const char *fields, const char *table, const char *queryTail,...);
165        // used during global instance resets
166        bool lock_instLists;
167        // fast lookup by instance id
168        InstanceSaveHashMap m_instanceSaveById;
169        // fast lookup for reset times
170        ResetTimeVector m_resetTimeByMapId;
171        ResetTimeQueue m_resetTimeQueue;
172};
173
174#define sInstanceSaveManager Trinity::Singleton<InstanceSaveManager>::Instance()
175#endif
Note: See TracBrowser for help on using the browser.