TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
InstanceSaveManager Class Reference

#include <InstanceSaveMgr.h>

Classes

struct  InstResetEvent
 

Public Types

typedef std::unordered_map
< uint32, InstanceSave * > 
InstanceSaveHashMap
 
typedef std::multimap< time_t,
InstResetEvent
ResetTimeQueue
 

Public Member Functions

void Unload ()
 
void LoadInstances ()
 
void LoadResetTimes ()
 
time_t GetResetTimeFor (uint32 mapid, Difficulty d) const
 
time_t GetSubsequentResetTime (uint32 mapid, Difficulty difficulty, time_t resetTime) const
 
void InitializeResetTimeFor (uint32 mapid, Difficulty d, time_t t)
 
void SetResetTimeFor (uint32 mapid, Difficulty d, time_t t)
 
ResetTimeByMapDifficultyMap constGetResetTimeMap () const
 
void ScheduleReset (bool add, time_t time, InstResetEvent event)
 
void ForceGlobalReset (uint32 mapId, Difficulty difficulty)
 
void Update ()
 
InstanceSaveAddInstanceSave (uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load=false)
 
void RemoveInstanceSave (uint32 InstanceId)
 
void UnloadInstanceSave (uint32 InstanceId)
 
InstanceSaveGetInstanceSave (uint32 InstanceId)
 
uint32 GetNumInstanceSaves () const
 
uint32 GetNumBoundPlayersTotal () const
 
uint32 GetNumBoundGroupsTotal () const
 

Static Public Member Functions

static InstanceSaveManagerinstance ()
 
static void DeleteInstanceFromDB (uint32 instanceid)
 

Static Protected Attributes

static uint16 ResetTimeDelay [] = {3600, 900, 300, 60}
 

Private Member Functions

 InstanceSaveManager ()
 
 ~InstanceSaveManager ()
 
void _ResetOrWarnAll (uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime)
 
void _ResetInstance (uint32 mapid, uint32 instanceId)
 
void _ResetSave (InstanceSaveHashMap::iterator &itr)
 

Private Attributes

bool lock_instLists
 
InstanceSaveHashMap m_instanceSaveById
 
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
 
ResetTimeQueue m_resetTimeQueue
 

Friends

class InstanceSave
 

Member Typedef Documentation

typedef std::multimap<time_t , InstResetEvent> InstanceSaveManager::ResetTimeQueue

Constructor & Destructor Documentation

InstanceSaveManager::InstanceSaveManager ( )
inlineprivate
155 : lock_instLists(false) { };
bool lock_instLists
Definition: InstanceSaveMgr.h:235
InstanceSaveManager::~InstanceSaveManager ( )
private
38 {
39 }

Member Function Documentation

void InstanceSaveManager::_ResetInstance ( uint32  mapid,
uint32  instanceId 
)
private
595 {
596  TC_LOG_DEBUG("maps", "InstanceSaveMgr::_ResetInstance %u, %u", mapid, instanceId);
597  Map const* map = sMapMgr->CreateBaseMap(mapid);
598  if (!map->Instanceable())
599  return;
600 
601  InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(instanceId);
602  if (itr != m_instanceSaveById.end())
603  _ResetSave(itr);
604 
605  DeleteInstanceFromDB(instanceId); // even if save not loaded
606 
607  Map* iMap = ((MapInstanced*)map)->FindInstanceMap(instanceId);
608 
609  if (iMap && iMap->IsDungeon())
610  ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
611 
612  if (iMap)
613  {
614  iMap->DeleteRespawnTimes();
615  iMap->DeleteCorpseData();
616  }
617  else
618  Map::DeleteRespawnTimesInDB(mapid, instanceId);
619 
620  // Free up the instance id and allow it to be reused
621  sMapMgr->FreeInstanceId(instanceId);
622 }
Definition: MapInstanced.h:28
bool IsDungeon() const
Definition: Map.h:395
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
void _ResetSave(InstanceSaveHashMap::iterator &itr)
Definition: InstanceSaveMgr.cpp:547
Definition: Map.h:758
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId)
Definition: Map.cpp:3671
void DeleteRespawnTimes()
Definition: Map.cpp:3663
Definition: Map.h:259
#define sMapMgr
Definition: MapManager.h:194
bool Instanceable() const
Definition: Map.h:394
Definition: Map.h:755
void DeleteCorpseData()
Definition: Map.cpp:3760
static void DeleteInstanceFromDB(uint32 instanceid)
Definition: InstanceSaveMgr.cpp:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void InstanceSaveManager::_ResetOrWarnAll ( uint32  mapid,
Difficulty  difficulty,
bool  warn,
time_t  resetTime 
)
private
Todo:
delete creature/gameobject respawn times even if the maps are not loaded
625 {
626  // global reset for all instances of the given map
627  MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
628  if (!mapEntry->Instanceable())
629  return;
630  TC_LOG_DEBUG("misc", "InstanceSaveManager::ResetOrWarnAll: Processing map %s (%u) on difficulty %u (warn? %u)", mapEntry->MapName_lang, mapid, uint8(difficulty), warn);
631 
632  time_t now = time(NULL);
633 
634  if (!warn)
635  {
636  // calculate the next reset time
637  time_t next_reset = GetSubsequentResetTime(mapid, difficulty, resetTime);
638  if (!next_reset)
639  return;
640 
641  // delete/promote instance binds from the DB, even if not loaded
643 
645  stmt->setUInt16(0, uint16(mapid));
646  stmt->setUInt8(1, uint8(difficulty));
647  trans->Append(stmt);
648 
650  stmt->setUInt16(0, uint16(mapid));
651  stmt->setUInt8(1, uint8(difficulty));
652  trans->Append(stmt);
653 
655  stmt->setUInt16(0, uint16(mapid));
656  stmt->setUInt8(1, uint8(difficulty));
657  trans->Append(stmt);
658 
660  stmt->setUInt16(0, uint16(mapid));
661  stmt->setUInt8(1, uint8(difficulty));
662  trans->Append(stmt);
663 
665 
666  // promote loaded binds to instances of the given map
667  for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();)
668  {
669  if (itr->second->GetMapId() == mapid && itr->second->GetDifficultyID() == difficulty)
670  _ResetSave(itr);
671  else
672  ++itr;
673  }
674 
675  SetResetTimeFor(mapid, difficulty, next_reset);
676  ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0));
677 
678  // Update it in the DB
680 
681  stmt->setUInt32(0, next_reset);
682  stmt->setUInt16(1, uint16(mapid));
683  stmt->setUInt8(2, uint8(difficulty));
684 
686  }
687 
688  // note: this isn't fast but it's meant to be executed very rarely
689  Map const* map = sMapMgr->CreateBaseMap(mapid); // _not_ include difficulty
690  MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps();
691  MapInstanced::InstancedMaps::iterator mitr;
692  uint32 timeLeft;
693 
694  for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr)
695  {
696  Map* map2 = mitr->second;
697  if (!map2->IsDungeon())
698  continue;
699 
700  if (warn)
701  {
702  if (now >= resetTime)
703  timeLeft = 0;
704  else
705  timeLeft = uint32(resetTime - now);
706 
707  ((InstanceMap*)map2)->SendResetWarnings(timeLeft);
708  }
709  else
710  ((InstanceMap*)map2)->Reset(INSTANCE_RESET_GLOBAL);
711  }
712 
714 }
Definition: MapInstanced.h:28
void Execute(const char *sql)
Definition: DatabaseWorkerPool.h:87
void ScheduleReset(bool add, time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:465
Definition: Map.h:752
Definition: CharacterDatabase.h:355
bool Instanceable() const
Definition: DBCStructure.h:859
void setUInt8(const uint8 index, const uint8 value)
Definition: PreparedStatement.cpp:97
SQLTransaction BeginTransaction()
Begins an automanaged transaction pointer that will automatically rollback if not commited...
Definition: DatabaseWorkerPool.h:221
Definition: DBCStructure.h:830
arena_t NULL
Definition: jemalloc_internal.h:624
bool IsDungeon() const
Definition: Map.h:395
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
void _ResetSave(InstanceSaveHashMap::iterator &itr)
Definition: InstanceSaveMgr.cpp:547
time_t GetSubsequentResetTime(uint32 mapid, Difficulty difficulty, time_t resetTime) const
Definition: InstanceSaveMgr.cpp:448
uint16_t uint16
Definition: g3dmath.h:166
Definition: PreparedStatement.h:74
std::unordered_map< uint32, Map * > InstancedMaps
Definition: MapInstanced.h:32
void CommitTransaction(SQLTransaction transaction)
Definition: DatabaseWorkerPool.cpp:179
void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
Definition: InstanceSaveMgr.h:198
Definition: Map.h:758
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
void setUInt16(const uint8 index, const uint16 value)
Definition: PreparedStatement.cpp:106
uint32_t uint32
Definition: Define.h:150
Definition: CharacterDatabase.h:421
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
Definition: Map.h:259
void setUInt32(const uint8 index, const uint32 value)
Definition: PreparedStatement.cpp:115
uint8_t uint8
Definition: g3dmath.h:164
Definition: CharacterDatabase.h:424
DBCStorage< MapEntry > sMapStore(Mapfmt)
#define sMapMgr
Definition: MapManager.h:194
uint8_t uint8
Definition: Define.h:152
Definition: CharacterDatabase.h:423
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
char * MapName_lang
Definition: DBCStructure.h:838
uint32_t uint32
Definition: g3dmath.h:168
Definition: CharacterDatabase.h:422
std::shared_ptr< Transaction > SQLTransaction
Definition: Transaction.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void InstanceSaveManager::_ResetSave ( InstanceSaveHashMap::iterator &  itr)
private
548 {
549  // unbind all players bound to the instance
550  // do not allow UnbindInstance to automatically unload the InstanceSaves
551  lock_instLists = true;
552 
553  bool shouldDelete = true;
554  InstanceSave::PlayerListType &pList = itr->second->m_playerList;
555  std::vector<Player*> temp; // list of expired binds that should be unbound
556  for (Player* player : pList)
557  {
558  if (InstancePlayerBind* bind = player->GetBoundInstance(itr->second->GetMapId(), itr->second->GetDifficultyID()))
559  {
560  ASSERT(bind->save == itr->second);
561  if (bind->perm && bind->extendState) // permanent and not already expired
562  {
563  // actual promotion in DB already happened in caller
564  bind->extendState = bind->extendState == EXTEND_STATE_EXTENDED ? EXTEND_STATE_NORMAL : EXTEND_STATE_EXPIRED;
565  shouldDelete = false;
566  continue;
567  }
568  }
569  temp.push_back(player);
570  }
571  for (Player* player : temp)
572  {
573  player->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficultyID(), true);
574  }
575 
576  InstanceSave::GroupListType &gList = itr->second->m_groupList;
577  while (!gList.empty())
578  {
579  Group* group = *(gList.begin());
580  group->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficultyID(), true);
581  }
582 
583  if (shouldDelete)
584  {
585  delete itr->second;
586  itr = m_instanceSaveById.erase(itr);
587  }
588  else
589  ++itr;
590 
591  lock_instLists = false;
592 }
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
std::list< Group * > GroupListType
Definition: InstanceSaveMgr.h:130
std::list< Player * > PlayerListType
Definition: InstanceSaveMgr.h:129
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload=false)
Definition: Group.cpp:2257
bool lock_instLists
Definition: InstanceSaveMgr.h:235
#define ASSERT
Definition: Errors.h:55
Definition: Group.h:191

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

InstanceSave * InstanceSaveManager::AddInstanceSave ( uint32  mapId,
uint32  instanceId,
Difficulty  difficulty,
time_t  resetTime,
bool  canReset,
bool  load = false 
)
75 {
76  if (InstanceSave* old_save = GetInstanceSave(instanceId))
77  return old_save;
78 
79  const MapEntry* entry = sMapStore.LookupEntry(mapId);
80  if (!entry)
81  {
82  TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: wrong mapid = %d, instanceid = %d!", mapId, instanceId);
83  return NULL;
84  }
85 
86  if (instanceId == 0)
87  {
88  TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d!", mapId, instanceId);
89  return NULL;
90  }
91 
92  DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
93  if (!difficultyEntry || difficultyEntry->InstanceType != entry->InstanceType)
94  {
95  TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty);
96  return NULL;
97  }
98 
99  if (!resetTime)
100  {
101  // initialize reset time
102  // for normal instances if no creatures are killed the instance will reset in two hours
103  if (entry->IsRaid() || difficulty > DIFFICULTY_NORMAL)
104  resetTime = GetResetTimeFor(mapId, difficulty);
105  else
106  {
107  resetTime = time(NULL) + 2 * HOUR;
108  // normally this will be removed soon after in InstanceMap::Add, prevent error
109  ScheduleReset(true, resetTime, InstResetEvent(0, mapId, difficulty, instanceId));
110  }
111  }
112 
113  TC_LOG_DEBUG("maps", "InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d", mapId, instanceId);
114 
115  InstanceSave* save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset);
116  if (!load)
117  save->SaveToDB();
118 
119  m_instanceSaveById[instanceId] = save;
120  return save;
121 }
void ScheduleReset(bool add, time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:465
Definition: Common.h:98
time_t GetResetTimeFor(uint32 mapid, Difficulty d) const
Definition: InstanceSaveMgr.h:184
Definition: DBCStructure.h:830
arena_t NULL
Definition: jemalloc_internal.h:624
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
friend class InstanceSave
Definition: InstanceSaveMgr.h:152
void SaveToDB()
Definition: InstanceSaveMgr.cpp:189
uint32 InstanceType
Definition: DBCStructure.h:834
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
uint32 InstanceType
Definition: DBCStructure.h:342
Definition: InstanceSaveMgr.h:44
bool IsRaid() const
Definition: DBCStructure.h:860
DBCStorage< MapEntry > sMapStore(Mapfmt)
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
InstanceSave * GetInstanceSave(uint32 InstanceId)
Definition: InstanceSaveMgr.cpp:123
DBCStorage< DifficultyEntry > sDifficultyStore(DifficultyFmt)
Definition: DBCEnums.h:405
Definition: DBCStructure.h:338

+ Here is the call graph for this function:

void InstanceSaveManager::DeleteInstanceFromDB ( uint32  instanceid)
static
130 {
132 
134  stmt->setUInt32(0, instanceid);
135  trans->Append(stmt);
136 
138  stmt->setUInt32(0, instanceid);
139  trans->Append(stmt);
140 
142  stmt->setUInt32(0, instanceid);
143  trans->Append(stmt);
144 
146  // Respawn times should be deleted only when the map gets unloaded
147 }
Definition: CharacterDatabase.h:419
Definition: CharacterDatabase.h:420
SQLTransaction BeginTransaction()
Begins an automanaged transaction pointer that will automatically rollback if not commited...
Definition: DatabaseWorkerPool.h:221
Definition: PreparedStatement.h:74
void CommitTransaction(SQLTransaction transaction)
Definition: DatabaseWorkerPool.cpp:179
Definition: CharacterDatabase.h:351
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
void setUInt32(const uint8 index, const uint32 value)
Definition: PreparedStatement.cpp:115
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
std::shared_ptr< Transaction > SQLTransaction
Definition: Transaction.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void InstanceSaveManager::ForceGlobalReset ( uint32  mapId,
Difficulty  difficulty 
)
503 {
504  if (!GetDownscaledMapDifficultyData(mapId, difficulty))
505  return;
506  // remove currently scheduled reset times
507  ScheduleReset(false, 0, InstResetEvent(1, mapId, difficulty, 0));
508  ScheduleReset(false, 0, InstResetEvent(4, mapId, difficulty, 0));
509  // force global reset on the instance
510  _ResetOrWarnAll(mapId, difficulty, false, time(nullptr));
511 }
void ScheduleReset(bool add, time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:465
MapDifficultyEntry const * GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty)
Definition: DBCStores.cpp:737
void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime)
Definition: InstanceSaveMgr.cpp:624

+ Here is the call graph for this function:

InstanceSave * InstanceSaveManager::GetInstanceSave ( uint32  InstanceId)
124 {
125  InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(InstanceId);
126  return itr != m_instanceSaveById.end() ? itr->second : NULL;
127 }
arena_t NULL
Definition: jemalloc_internal.h:624
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237

+ Here is the caller graph for this function:

uint32 InstanceSaveManager::GetNumBoundGroupsTotal ( ) const
726 {
727  uint32 ret = 0;
728  for (InstanceSaveHashMap::const_iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr)
729  ret += itr->second->GetGroupCount();
730 
731  return ret;
732 }
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
uint32_t uint32
Definition: Define.h:150
uint32 InstanceSaveManager::GetNumBoundPlayersTotal ( ) const
717 {
718  uint32 ret = 0;
719  for (InstanceSaveHashMap::const_iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr)
720  ret += itr->second->GetPlayerCount();
721 
722  return ret;
723 }
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
uint32_t uint32
Definition: Define.h:150
uint32 InstanceSaveManager::GetNumInstanceSaves ( ) const
inline
223 { return uint32(m_instanceSaveById.size()); }
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
uint32_t uint32
Definition: g3dmath.h:168
time_t InstanceSaveManager::GetResetTimeFor ( uint32  mapid,
Difficulty  d 
) const
inline
185  {
186  ResetTimeByMapDifficultyMap::const_iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR64(mapid, d));
187  return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0;
188  }
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
Definition: InstanceSaveMgr.h:239
uint64 MAKE_PAIR64(uint32 l, uint32 h)
Definition: ObjectDefines.h:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ResetTimeByMapDifficultyMap const& InstanceSaveManager::GetResetTimeMap ( ) const
inline
206  {
208  }
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
Definition: InstanceSaveMgr.h:239
time_t InstanceSaveManager::GetSubsequentResetTime ( uint32  mapid,
Difficulty  difficulty,
time_t  resetTime 
) const
449 {
450  MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapid, difficulty);
451  if (!mapDiff || !mapDiff->RaidDuration)
452  {
453  TC_LOG_ERROR("misc", "InstanceSaveManager::GetSubsequentResetTime: not valid difficulty or no reset delay for map %u", mapid);
454  return 0;
455  }
456 
457  time_t diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
458  time_t period = uint32(((mapDiff->RaidDuration * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
459  if (period < DAY)
460  period = DAY;
461 
462  return ((resetTime + MINUTE) / DAY * DAY) + period + diff;
463 }
MapDifficultyEntry const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:724
Definition: World.h:254
Definition: Common.h:98
uint32 RaidDuration
Definition: DBCStructure.h:891
#define sWorld
Definition: World.h:887
Definition: Common.h:97
Definition: Common.h:99
Definition: DBCStructure.h:885
Definition: World.h:438
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void InstanceSaveManager::InitializeResetTimeFor ( uint32  mapid,
Difficulty  d,
time_t  t 
)
inline
193  {
195  }
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
Definition: InstanceSaveMgr.h:239
uint64 MAKE_PAIR64(uint32 l, uint32 h)
Definition: ObjectDefines.h:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

InstanceSaveManager * InstanceSaveManager::instance ( )
static
42 {
44  return &instance;
45 }
static InstanceSaveManager * instance()
Definition: InstanceSaveMgr.cpp:41
Definition: InstanceSaveMgr.h:150

+ Here is the caller graph for this function:

void InstanceSaveManager::LoadInstances ( )
262 {
263  uint32 oldMSTime = getMSTime();
264 
265  // Delete expired instances (Instance related spawns are removed in the following cleanup queries)
266  CharacterDatabase.DirectExecute("DELETE i FROM instance i LEFT JOIN instance_reset ir ON mapid = map AND i.difficulty = ir.difficulty "
267  "WHERE (i.resettime > 0 AND i.resettime < UNIX_TIMESTAMP()) OR (ir.resettime IS NOT NULL AND ir.resettime < UNIX_TIMESTAMP())");
268 
269  // Delete invalid character_instance and group_instance references
270  CharacterDatabase.DirectExecute("DELETE ci.* FROM character_instance AS ci LEFT JOIN characters AS c ON ci.guid = c.guid WHERE c.guid IS NULL");
271  CharacterDatabase.DirectExecute("DELETE gi.* FROM group_instance AS gi LEFT JOIN groups AS g ON gi.guid = g.guid WHERE g.guid IS NULL");
272 
273  // Delete invalid instance references
274  CharacterDatabase.DirectExecute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance LEFT JOIN group_instance AS gi ON i.id = gi.instance WHERE ci.guid IS NULL AND gi.guid IS NULL");
275 
276  // Delete invalid references to instance
277  CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
278  CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
279  CharacterDatabase.DirectExecute("DELETE tmp.* FROM character_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL");
280  CharacterDatabase.DirectExecute("DELETE tmp.* FROM group_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL");
281 
282  // Clean invalid references to instance
283  CharacterDatabase.DirectExecute("UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
284  CharacterDatabase.DirectExecute("UPDATE characters AS tmp LEFT JOIN instance ON tmp.instance_id = instance.id SET tmp.instance_id = 0 WHERE tmp.instance_id > 0 AND instance.id IS NULL");
285 
286  // Initialize instance id storage (Needs to be done after the trash has been clean out)
287  sMapMgr->InitInstanceIds();
288 
289  // Load reset times and clean expired instances
290  sInstanceSaveMgr->LoadResetTimes();
291 
292  TC_LOG_INFO("server.loading", ">> Loaded instances in %u ms", GetMSTimeDiffToNow(oldMSTime));
293 
294 }
uint32 getMSTime()
Definition: Timer.h:24
uint32_t uint32
Definition: Define.h:150
#define sInstanceSaveMgr
Definition: InstanceSaveMgr.h:243
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:42
#define sMapMgr
Definition: MapManager.h:194
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
void DirectExecute(const char *sql)
Definition: DatabaseWorkerPool.h:121

+ Here is the call graph for this function:

void InstanceSaveManager::LoadResetTimes ( )
297 {
298  time_t now = time(NULL);
299  time_t today = (now / DAY) * DAY;
300 
301  // NOTE: Use DirectPExecute for tables that will be queried later
302 
303  // get the current reset times for normal instances (these may need to be updated)
304  // these are only kept in memory for InstanceSaves that are loaded later
305  // resettime = 0 in the DB for raid/heroic instances so those are skipped
306  typedef std::pair<uint32 /*PAIR32(map, difficulty)*/, time_t> ResetTimeMapDiffType;
307  typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType;
308  InstResetTimeMapDiffType instResetTime;
309 
310  // index instance ids by map/difficulty pairs for fast reset warning send
311  typedef std::multimap<uint32 /*PAIR32(map, difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances;
312  typedef std::pair<ResetTimeMapDiffInstances::const_iterator, ResetTimeMapDiffInstances::const_iterator> ResetTimeMapDiffInstancesBounds;
313  ResetTimeMapDiffInstances mapDiffResetInstances;
314 
315  QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC");
316  if (result)
317  {
318  do
319  {
320  Field* fields = result->Fetch();
321 
322  uint32 instanceId = fields[0].GetUInt32();
323 
324  // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1,
325  // so if the instance id is used, increment until we find the first unused one for a potential new instance
326  if (sMapMgr->GetNextInstanceId() == instanceId)
327  sMapMgr->SetNextInstanceId(instanceId + 1);
328 
329  // Mark instance id as being used
330  sMapMgr->RegisterInstanceId(instanceId);
331 
332  if (time_t resettime = time_t(fields[3].GetUInt32()))
333  {
334  uint32 mapid = fields[1].GetUInt16();
335  uint32 difficulty = fields[2].GetUInt8();
336 
337  instResetTime[instanceId] = ResetTimeMapDiffType(MAKE_PAIR32(mapid, difficulty), resettime);
338  mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid, difficulty), instanceId));
339  }
340  }
341  while (result->NextRow());
342 
343  // update reset time for normal instances with the max creature respawn time + X hours
345  {
346  do
347  {
348  Field* fields = result2->Fetch();
349  uint32 instance = fields[1].GetUInt32();
350  time_t resettime = time_t(fields[0].GetUInt32() + 2 * HOUR);
351  InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance);
352  if (itr != instResetTime.end() && itr->second.second != resettime)
353  {
354  CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '" UI64FMTD "' WHERE id = '%u'", uint64(resettime), instance);
355  itr->second.second = resettime;
356  }
357  }
358  while (result->NextRow());
359  }
360 
361  // schedule the reset times
362  for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr)
363  if (itr->second.second > now)
364  ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first), Difficulty(PAIR32_HIPART(itr->second.first)), itr->first));
365  }
366 
367  // load the global respawn times for raid/heroic instances
368  uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
369  result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset");
370  if (result)
371  {
372  do
373  {
374  Field* fields = result->Fetch();
375  uint32 mapid = fields[0].GetUInt16();
376  Difficulty difficulty = Difficulty(fields[1].GetUInt8());
377  uint64 oldresettime = fields[2].GetUInt32();
378 
379  MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapid, difficulty);
380  if (!mapDiff)
381  {
382  TC_LOG_ERROR("misc", "InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty);
383  CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid, difficulty);
384  continue;
385  }
386 
387  // update the reset time if the hour in the configs changes
388  uint64 newresettime = (oldresettime / DAY) * DAY + diff;
389  if (oldresettime != newresettime)
390  CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty);
391 
392  InitializeResetTimeFor(mapid, difficulty, newresettime);
393  } while (result->NextRow());
394  }
395 
396  // calculate new global reset times for expired instances and those that have never been reset yet
397  // add the global reset times to the priority queue
398  for (auto& mapDifficultyPair : sMapDifficultyMap)
399  {
400  uint32 mapid = mapDifficultyPair.first;
401 
402  for (auto& difficultyPair : mapDifficultyPair.second)
403  {
404  Difficulty difficulty = Difficulty(difficultyPair.first);
405  MapDifficultyEntry const* mapDiff = difficultyPair.second;
406  if (!mapDiff->RaidDuration)
407  continue;
408 
409  // the reset_delay must be at least one day
410  uint32 period = uint32(((mapDiff->RaidDuration * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
411  if (period < DAY)
412  period = DAY;
413 
414  time_t t = GetResetTimeFor(mapid, difficulty);
415  if (!t)
416  {
417  // initialize the reset time
418  t = today + period + diff;
419  CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, difficulty, (uint32)t);
420  }
421 
422  if (t < now)
423  {
424  // assume that expired instances have already been cleaned
425  // calculate the next reset time
426  t = (t / DAY) * DAY;
427  t += ((today - t) / period + 1) * period + diff;
428  CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
429  }
430 
431  InitializeResetTimeFor(mapid, difficulty, t);
432 
433  // schedule the global reset/warning
434  uint8 type;
435  for (type = 1; type < 4; ++type)
436  if (t - ResetTimeDelay[type - 1] > now)
437  break;
438 
439  ScheduleReset(true, t - ResetTimeDelay[type - 1], InstResetEvent(type, mapid, difficulty, 0));
440 
441  ResetTimeMapDiffInstancesBounds range = mapDiffResetInstances.equal_range(MAKE_PAIR32(mapid, difficulty));
442  for (; range.first != range.second; ++range.first)
443  ScheduleReset(true, t - ResetTimeDelay[type - 1], InstResetEvent(type, mapid, difficulty, range.first->second));
444  }
445  }
446 }
Difficulty
Definition: DBCEnums.h:402
MapDifficultyEntry const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:724
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: QueryResult.h:107
void ScheduleReset(bool add, time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:465
Definition: World.h:254
Definition: Common.h:98
MapDifficultyMap sMapDifficultyMap
Definition: DBCStores.cpp:115
Class used to access individual fields of database query result.
Definition: Field.h:56
time_t GetResetTimeFor(uint32 mapid, Difficulty d) const
Definition: InstanceSaveMgr.h:184
static InstanceSaveManager * instance()
Definition: InstanceSaveMgr.cpp:41
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 RaidDuration
Definition: DBCStructure.h:891
uint64_t uint64
Definition: g3dmath.h:170
#define sWorld
Definition: World.h:887
uint8 GetUInt8() const
Definition: Field.h:70
void DirectPExecute(Format &&sql, Args &&...args)
Definition: DatabaseWorkerPool.h:134
uint16 PAIR32_LOPART(uint32 x)
Definition: ObjectDefines.h:64
Definition: Common.h:99
#define UI64FMTD
Definition: Define.h:137
Definition: CharacterDatabase.h:293
uint32_t uint32
Definition: Define.h:150
uint64_t uint64
Definition: Define.h:149
std::shared_ptr< ResultSet > QueryResult
Definition: QueryResult.h:61
uint16 GetUInt16() const
Definition: Field.h:108
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
Definition: DBCStructure.h:885
void InitializeResetTimeFor(uint32 mapid, Difficulty d, time_t t)
Definition: InstanceSaveMgr.h:192
Definition: World.h:438
#define sMapMgr
Definition: MapManager.h:194
uint32 GetUInt32() const
Definition: Field.h:146
uint8_t uint8
Definition: Define.h:152
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
uint32_t uint32
Definition: g3dmath.h:168
uint16 PAIR32_HIPART(uint32 x)
Definition: ObjectDefines.h:59
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition: ObjectDefines.h:54
static uint16 ResetTimeDelay[]
Definition: InstanceSaveMgr.h:228

+ Here is the call graph for this function:

void InstanceSaveManager::RemoveInstanceSave ( uint32  InstanceId)
150 {
151  InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(InstanceId);
152  if (itr != m_instanceSaveById.end())
153  {
154  // save the resettime for normal instances only when they get unloaded
155  if (time_t resettime = itr->second->GetResetTimeForDB())
156  {
158 
159  stmt->setUInt32(0, uint32(resettime));
160  stmt->setUInt32(1, InstanceId);
161 
163  }
164 
165  itr->second->SetToDelete(true);
166  m_instanceSaveById.erase(itr);
167  }
168 }
void Execute(const char *sql)
Definition: DatabaseWorkerPool.h:87
Definition: PreparedStatement.h:74
Definition: CharacterDatabase.h:354
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
void setUInt32(const uint8 index, const uint32 value)
Definition: PreparedStatement.cpp:115
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the call graph for this function:

void InstanceSaveManager::ScheduleReset ( bool  add,
time_t  time,
InstResetEvent  event 
)
466 {
467  if (!add)
468  {
469  // find the event in the queue and remove it
470  ResetTimeQueue::iterator itr;
471  std::pair<ResetTimeQueue::iterator, ResetTimeQueue::iterator> range;
472  range = m_resetTimeQueue.equal_range(time);
473  for (itr = range.first; itr != range.second; ++itr)
474  {
475  if (itr->second == event)
476  {
477  m_resetTimeQueue.erase(itr);
478  return;
479  }
480  }
481 
482  // in case the reset time changed (should happen very rarely), we search the whole queue
483  if (itr == range.second)
484  {
485  for (itr = m_resetTimeQueue.begin(); itr != m_resetTimeQueue.end(); ++itr)
486  {
487  if (itr->second == event)
488  {
489  m_resetTimeQueue.erase(itr);
490  return;
491  }
492  }
493 
494  if (itr == m_resetTimeQueue.end())
495  TC_LOG_ERROR("misc", "InstanceSaveManager::ScheduleReset: cannot cancel the reset, the event(%d, %d, %d) was not found!", event.type, event.mapid, event.instanceId);
496  }
497  }
498  else
499  m_resetTimeQueue.insert(std::pair<time_t, InstResetEvent>(time, event));
500 }
ResetTimeQueue m_resetTimeQueue
Definition: InstanceSaveMgr.h:240
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the caller graph for this function:

void InstanceSaveManager::SetResetTimeFor ( uint32  mapid,
Difficulty  d,
time_t  t 
)
inline
199  {
200  ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR64(mapid, d));
201  ASSERT(itr != m_resetTimeByMapDifficulty.end());
202  itr->second = t;
203  }
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
Definition: InstanceSaveMgr.h:239
uint64 MAKE_PAIR64(uint32 l, uint32 h)
Definition: ObjectDefines.h:34
#define ASSERT
Definition: Errors.h:55

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void InstanceSaveManager::Unload ( )
48 {
49  lock_instLists = true;
50  for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr)
51  {
52  InstanceSave* save = itr->second;
53 
54  for (InstanceSave::PlayerListType::iterator itr2 = save->m_playerList.begin(), next = itr2; itr2 != save->m_playerList.end(); itr2 = next)
55  {
56  ++next;
57  (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true);
58  }
59 
60  for (InstanceSave::GroupListType::iterator itr2 = save->m_groupList.begin(), next = itr2; itr2 != save->m_groupList.end(); itr2 = next)
61  {
62  ++next;
63  (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true);
64  }
65 
66  delete save;
67  }
68 }
PlayerListType m_playerList
Definition: InstanceSaveMgr.h:136
int next(int i, int n)
Definition: RecastContour.cpp:469
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:237
Definition: InstanceSaveMgr.h:44
uint32 GetMapId() const
Definition: InstanceSaveMgr.h:65
Difficulty GetDifficultyID() const
Definition: InstanceSaveMgr.h:121
bool lock_instLists
Definition: InstanceSaveMgr.h:235
GroupListType m_groupList
Definition: InstanceSaveMgr.h:137

+ Here is the call graph for this function:

void InstanceSaveManager::UnloadInstanceSave ( uint32  InstanceId)
171 {
172  if (InstanceSave* save = GetInstanceSave(InstanceId))
173  save->UnloadIfEmpty();
174 }
Definition: InstanceSaveMgr.h:44
InstanceSave * GetInstanceSave(uint32 InstanceId)
Definition: InstanceSaveMgr.cpp:123

+ Here is the call graph for this function:

void InstanceSaveManager::Update ( )
514 {
515  time_t now = time(NULL);
516  time_t t;
517 
518  while (!m_resetTimeQueue.empty())
519  {
520  t = m_resetTimeQueue.begin()->first;
521  if (t >= now)
522  break;
523 
524  InstResetEvent &event = m_resetTimeQueue.begin()->second;
525  if (event.type == 0)
526  {
527  // for individual normal instances, max creature respawn + X hours
528  _ResetInstance(event.mapid, event.instanceId);
529  m_resetTimeQueue.erase(m_resetTimeQueue.begin());
530  }
531  else
532  {
533  // global reset/warning for a certain map
534  time_t resetTime = GetResetTimeFor(event.mapid, event.difficulty);
535  _ResetOrWarnAll(event.mapid, event.difficulty, event.type != 4, resetTime);
536  if (event.type != 4)
537  {
538  // schedule the next warning/reset
539  ++event.type;
540  ScheduleReset(true, resetTime - ResetTimeDelay[event.type-1], event);
541  }
542  m_resetTimeQueue.erase(m_resetTimeQueue.begin());
543  }
544  }
545 }
void ScheduleReset(bool add, time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:465
time_t GetResetTimeFor(uint32 mapid, Difficulty d) const
Definition: InstanceSaveMgr.h:184
arena_t NULL
Definition: jemalloc_internal.h:624
ResetTimeQueue m_resetTimeQueue
Definition: InstanceSaveMgr.h:240
void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime)
Definition: InstanceSaveMgr.cpp:624
void _ResetInstance(uint32 mapid, uint32 instanceId)
Definition: InstanceSaveMgr.cpp:594
static uint16 ResetTimeDelay[]
Definition: InstanceSaveMgr.h:228

+ Here is the call graph for this function:

Friends And Related Function Documentation

friend class InstanceSave
friend

Member Data Documentation

bool InstanceSaveManager::lock_instLists
private
InstanceSaveHashMap InstanceSaveManager::m_instanceSaveById
private
ResetTimeByMapDifficultyMap InstanceSaveManager::m_resetTimeByMapDifficulty
private
ResetTimeQueue InstanceSaveManager::m_resetTimeQueue
private
uint16 InstanceSaveManager::ResetTimeDelay = {3600, 900, 300, 60}
staticprotected

The documentation for this class was generated from the following files: