AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
InstanceSaveMgr Class Reference

#include "InstanceSaveMgr.h"

Classes

struct  InstResetEvent
 

Public Types

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

Public Member Functions

void LoadInstances ()
 
void LoadResetTimes ()
 
void LoadInstanceSaves ()
 
void LoadCharacterBinds ()
 
time_t GetResetTimeFor (uint32 mapid, Difficulty d) const
 
time_t GetExtendedResetTimeFor (uint32 mapid, Difficulty d) const
 
void SetResetTimeFor (uint32 mapid, Difficulty d, time_t t)
 
void SetExtendedResetTimeFor (uint32 mapid, Difficulty d, time_t t)
 
ResetTimeByMapDifficultyMap const & GetResetTimeMap () const
 
void ScheduleReset (time_t time, InstResetEvent event)
 
void Update ()
 
InstanceSaveAddInstanceSave (uint32 mapId, uint32 instanceId, Difficulty difficulty, bool startup=false)
 
bool DeleteInstanceSaveIfNeeded (uint32 InstanceId, bool skipMapCheck)
 
bool DeleteInstanceSaveIfNeeded (InstanceSave *save, bool skipMapCheck, bool deleteSave=true)
 
InstanceSaveGetInstanceSave (uint32 InstanceId)
 
InstancePlayerBindPlayerBindToInstance (ObjectGuid guid, InstanceSave *save, bool permanent, Player *player=nullptr)
 
void PlayerUnbindInstance (ObjectGuid guid, uint32 mapid, Difficulty difficulty, bool deleteFromDB, Player *player=nullptr)
 
void PlayerUnbindInstanceNotExtended (ObjectGuid guid, uint32 mapid, Difficulty difficulty, Player *player=nullptr)
 
InstancePlayerBindPlayerGetBoundInstance (ObjectGuid guid, uint32 mapid, Difficulty difficulty)
 
bool PlayerIsPermBoundToInstance (ObjectGuid guid, uint32 mapid, Difficulty difficulty)
 
BoundInstancesMap const & PlayerGetBoundInstances (ObjectGuid guid, Difficulty difficulty)
 
void PlayerCreateBoundInstancesMaps (ObjectGuid guid)
 
InstanceSavePlayerGetInstanceSave (ObjectGuid guid, uint32 mapid, Difficulty difficulty)
 
uint32 PlayerGetDestinationInstanceId (Player *player, uint32 mapid, Difficulty difficulty)
 
void CopyBinds (ObjectGuid from, ObjectGuid to, Player *toPlr=nullptr)
 
void UnbindAllFor (InstanceSave *save)
 
void SanitizeInstanceSavedData ()
 
void DeleteInstanceSavedData (uint32 instanceId)
 

Static Public Member Functions

static InstanceSaveMgrinstance ()
 

Static Protected Attributes

static uint16 ResetTimeDelay [] = {3600, 900, 300, 60, 0}
 
static PlayerBindStorage playerBindStorage
 
static BoundInstancesMap emptyBoundInstancesMap
 

Private Member Functions

 InstanceSaveMgr ()=default
 
 ~InstanceSaveMgr ()
 
void _ResetOrWarnAll (uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime)
 
void _ResetSave (InstanceSaveHashMap::iterator &itr)
 

Private Attributes

bool lock_instLists {false}
 
InstanceSaveHashMap m_instanceSaveById
 
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
 
ResetTimeByMapDifficultyMap m_resetExtendedTimeByMapDifficulty
 
ResetTimeQueue m_resetTimeQueue
 

Friends

class InstanceSave
 

Detailed Description

Member Typedef Documentation

◆ InstanceSaveHashMap

◆ ResetTimeQueue

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

Constructor & Destructor Documentation

◆ InstanceSaveMgr()

InstanceSaveMgr::InstanceSaveMgr ( )
privatedefault

◆ ~InstanceSaveMgr()

InstanceSaveMgr::~InstanceSaveMgr ( )
private
41{
42 lock_instLists = true;
43 // pussywizard: crashes on calling function in destructor (PlayerUnbindInstance), completely not needed anyway
44 /*for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr)
45 {
46 InstanceSave* save = itr->second;
47
48 InstanceSave::PlayerListType &pList = save->m_playerList;
49 while (!pList.empty())
50 PlayerUnbindInstance(*(pList.begin()), save->GetMapId(), save->GetDifficulty(), false);
51
52 delete save;
53 }*/
54}
bool lock_instLists
Definition: InstanceSaveMgr.h:195

References lock_instLists.

Member Function Documentation

◆ _ResetOrWarnAll()

void InstanceSaveMgr::_ResetOrWarnAll ( uint32  mapid,
Difficulty  difficulty,
bool  warn,
time_t  resetTime 
)
private
559{
560 // global reset for all instances of the given map
561 MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
562 if (!mapEntry->Instanceable())
563 return;
564
565 time_t now = GameTime::GetGameTime().count();
566
567 if (!warn)
568 {
569 MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty);
570 if (!mapDiff || !mapDiff->resetTime)
571 {
572 LOG_ERROR("instance.save", "InstanceSaveMgr::ResetOrWarnAll: not valid difficulty or no reset delay for map {}", mapid);
573 return;
574 }
575
576 // calculate the next reset time
577 uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
578
579 uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
580 if (period < DAY)
581 period = DAY;
582
583 uint32 next_reset = uint32(((resetTime + MINUTE) / DAY * DAY) + period + diff);
584 SetResetTimeFor(mapid, difficulty, next_reset);
585 SetExtendedResetTimeFor(mapid, difficulty, next_reset + period);
586 ScheduleReset(time_t(next_reset - 3600), InstResetEvent(1, mapid, difficulty));
587
588 // update it in the DB
590 stmt->SetData(0, next_reset);
591 stmt->SetData(1, uint16(mapid));
592 stmt->SetData(2, uint8(difficulty));
593 CharacterDatabase.Execute(stmt);
594
595 // remove all binds to instances of the given map and delete from db (delete per instance id, no mass deletion!)
596 // do this after new reset time is calculated
597 for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(), itr2; itr != m_instanceSaveById.end(); )
598 {
599 itr2 = itr++;
600 if (itr2->second->GetMapId() == mapid && itr2->second->GetDifficulty() == difficulty)
601 _ResetSave(itr2);
602 }
603 }
604
605 // now loop all existing maps to warn / reset
606 Map const* map = sMapMgr->CreateBaseMap(mapid);
607 MapInstanced::InstancedMaps& instMaps = ((MapInstanced*)map)->GetInstancedMaps();
608 MapInstanced::InstancedMaps::iterator mitr;
609 uint32 timeLeft;
610
611 for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr)
612 {
613 Map* map2 = mitr->second;
614 if (!map2->IsDungeon() || map2->GetDifficulty() != difficulty)
615 continue;
616
617 if (warn)
618 {
619 if (now >= resetTime)
620 timeLeft = 0;
621 else
622 timeLeft = uint32(resetTime - now);
623
624 map2->ToInstanceMap()->SendResetWarnings(timeLeft);
625 }
626 else
627 {
629 map2->ToInstanceMap()->Reset(INSTANCE_RESET_GLOBAL, (save ? & (save->m_playerList) : nullptr));
630 }
631 }
632}
constexpr auto DAY
Definition: Common.h:51
constexpr auto HOUR
Definition: Common.h:50
constexpr auto MINUTE
Definition: Common.h:49
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
std::uint16_t uint16
Definition: Define.h:109
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
@ CHAR_UPD_GLOBAL_INSTANCE_RESETTIME
Definition: CharacterDatabase.h:301
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:757
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
@ INSTANCE_RESET_GLOBAL
Definition: Map.h:812
#define sMapMgr
Definition: MapMgr.h:221
@ CONFIG_INSTANCE_RESET_TIME_HOUR
Definition: IWorld.h:249
@ RATE_INSTANCE_RESET_TIME
Definition: IWorld.h:509
#define sWorld
Definition: World.h:447
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: PreparedStatement.h:158
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition: PreparedStatement.h:78
Definition: InstanceSaveMgr.h:56
GuidList m_playerList
Definition: InstanceSaveMgr.h:91
InstanceSave * GetInstanceSave(uint32 InstanceId)
Definition: InstanceSaveMgr.cpp:107
void ScheduleReset(time_t time, InstResetEvent event)
Definition: InstanceSaveMgr.cpp:456
void _ResetSave(InstanceSaveHashMap::iterator &itr)
Definition: InstanceSaveMgr.cpp:506
void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t)
Definition: InstanceSaveMgr.h:148
InstanceSaveHashMap m_instanceSaveById
Definition: InstanceSaveMgr.h:196
void SetExtendedResetTimeFor(uint32 mapid, Difficulty d, time_t t)
Definition: InstanceSaveMgr.h:153
Definition: Map.h:313
bool IsDungeon() const
Definition: Map.h:448
InstanceMap * ToInstanceMap()
Definition: Map.h:545
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetInstanceId() const
Definition: Map.h:419
void SendResetWarnings(uint32 timeLeft) const
Definition: Map.cpp:3196
bool Reset(uint8 method, GuidList *globalSkipList=nullptr)
Definition: Map.cpp:3098
Definition: MapInstanced.h:26
std::unordered_map< uint32, Map * > InstancedMaps
Definition: MapInstanced.h:29
Definition: DBCStructure.h:1323
bool Instanceable() const
Definition: DBCStructure.h:1351
Definition: DBCStructure.h:2220
uint32 resetTime
Definition: DBCStructure.h:2224

References _ResetSave(), CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, CharacterDatabase, CONFIG_INSTANCE_RESET_TIME_HOUR, DAY, Map::GetDifficulty(), GameTime::GetGameTime(), Map::GetInstanceId(), GetInstanceSave(), GetMapDifficultyData(), HOUR, INSTANCE_RESET_GLOBAL, MapEntry::Instanceable(), Map::IsDungeon(), LOG_ERROR, m_instanceSaveById, InstanceSave::m_playerList, MINUTE, RATE_INSTANCE_RESET_TIME, InstanceMap::Reset(), MapDifficulty::resetTime, ScheduleReset(), InstanceMap::SendResetWarnings(), PreparedStatementBase::SetData(), SetExtendedResetTimeFor(), SetResetTimeFor(), sMapMgr, sMapStore, sWorld, and Map::ToInstanceMap().

Referenced by Update().

◆ _ResetSave()

void InstanceSaveMgr::_ResetSave ( InstanceSaveHashMap::iterator &  itr)
private
507{
508 lock_instLists = true;
509
510 GuidList& pList = itr->second->m_playerList;
511 for (GuidList::iterator iter = pList.begin(), iter2; iter != pList.end(); )
512 {
513 iter2 = iter++;
514 PlayerUnbindInstanceNotExtended(*iter2, itr->second->GetMapId(), itr->second->GetDifficulty(), ObjectAccessor::FindConnectedPlayer(*iter2));
515 }
516
517 // delete stuff if no players left (noone extended id)
518 if (pList.empty())
519 {
520 // delete character_instance per id, delete instance per id
522 stmt->SetData(0, itr->second->GetInstanceId());
523 CharacterDatabase.Execute(stmt);
524 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_INSTANCE);
525 stmt->SetData(0, itr->second->GetInstanceId());
526 CharacterDatabase.Execute(stmt);
527 DeleteInstanceSavedData(itr->second->GetInstanceId());
528
529 // clear respawn times if the map is already unloaded and won't do it by itself
530 if (!sMapMgr->FindMap(itr->second->GetMapId(), itr->second->GetInstanceId()))
531 Map::DeleteRespawnTimesInDB(itr->second->GetMapId(), itr->second->GetInstanceId());
532
533 sScriptMgr->OnInstanceIdRemoved(itr->second->GetInstanceId());
534
535 delete itr->second;
536 m_instanceSaveById.erase(itr);
537 }
538 else
539 {
540 // delete character_instance per id where extended = 0, transtaction with set extended = 0, transaction is used to avoid mysql thread races
541 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
543 stmt->SetData(0, itr->second->GetInstanceId());
544 trans->Append(stmt);
546 stmt->SetData(0, itr->second->GetInstanceId());
547 trans->Append(stmt);
548 CharacterDatabase.CommitTransaction(trans);
549
550 // update reset time and extended reset time for instance save
551 itr->second->SetResetTime(GetResetTimeFor(itr->second->GetMapId(), itr->second->GetDifficulty()));
552 itr->second->SetExtendedResetTime(GetExtendedResetTimeFor(itr->second->GetMapId(), itr->second->GetDifficulty()));
553 }
554
555 lock_instLists = false;
556}
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition: DatabaseEnvFwd.h:70
@ CHAR_UPD_CHAR_INSTANCE_SET_NOT_EXTENDED
Definition: CharacterDatabase.h:308
@ CHAR_DEL_INSTANCE_BY_INSTANCE
Definition: CharacterDatabase.h:376
@ CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_NOT_EXTENDED
Definition: CharacterDatabase.h:307
@ CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE
Definition: CharacterDatabase.h:306
std::list< ObjectGuid > GuidList
Definition: ObjectGuid.h:256
#define sScriptMgr
Definition: ScriptMgr.h:698
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:260
void DeleteInstanceSavedData(uint32 instanceId)
Definition: InstanceSaveMgr.cpp:249
time_t GetResetTimeFor(uint32 mapid, Difficulty d) const
Definition: InstanceSaveMgr.h:136
time_t GetExtendedResetTimeFor(uint32 mapid, Difficulty d) const
Definition: InstanceSaveMgr.h:142
void PlayerUnbindInstanceNotExtended(ObjectGuid guid, uint32 mapid, Difficulty difficulty, Player *player=nullptr)
Definition: InstanceSaveMgr.cpp:729
static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId)
Definition: Map.cpp:3451

References CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE, CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_NOT_EXTENDED, CHAR_DEL_INSTANCE_BY_INSTANCE, CHAR_UPD_CHAR_INSTANCE_SET_NOT_EXTENDED, CharacterDatabase, DeleteInstanceSavedData(), Map::DeleteRespawnTimesInDB(), ObjectAccessor::FindConnectedPlayer(), GetExtendedResetTimeFor(), GetResetTimeFor(), lock_instLists, m_instanceSaveById, PlayerUnbindInstanceNotExtended(), PreparedStatementBase::SetData(), sMapMgr, and sScriptMgr.

Referenced by _ResetOrWarnAll().

◆ AddInstanceSave()

InstanceSave * InstanceSaveMgr::AddInstanceSave ( uint32  mapId,
uint32  instanceId,
Difficulty  difficulty,
bool  startup = false 
)
66{
67 ASSERT(!GetInstanceSave(instanceId));
68
69 MapEntry const* entry = sMapStore.LookupEntry(mapId);
70 if (!entry)
71 {
72 LOG_ERROR("instance.save", "InstanceSaveMgr::AddInstanceSave: wrong mapid = {}, instanceid = {}!", mapId, instanceId);
73 return nullptr;
74 }
75
76 if (instanceId == 0)
77 {
78 LOG_ERROR("instance.save", "InstanceSaveMgr::AddInstanceSave: mapid = {}, wrong instanceid = {}!", mapId, instanceId);
79 return nullptr;
80 }
81
82 if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
83 {
84 LOG_ERROR("instance.save", "InstanceSaveMgr::AddInstanceSave: mapid = {}, instanceid = {}, wrong dificalty {}!", mapId, instanceId, difficulty);
85 return nullptr;
86 }
87
88 time_t resetTime, extendedResetTime;
89 if (entry->map_type == MAP_RAID || difficulty > DUNGEON_DIFFICULTY_NORMAL)
90 {
91 resetTime = GetResetTimeFor(mapId, difficulty);
92 extendedResetTime = GetExtendedResetTimeFor(mapId, difficulty);
93 }
94 else
95 {
96 resetTime = GameTime::GetGameTime().count() + static_cast<long long>(3) * DAY; // normals expire after 3 days even if someone is still bound to them, cleared on startup
97 extendedResetTime = 0;
98 }
99 InstanceSave* save = new InstanceSave(mapId, instanceId, difficulty, resetTime, extendedResetTime);
100 if (!startup)
101 save->InsertToDB();
102
103 m_instanceSaveById[instanceId] = save;
104 return save;
105}
#define ASSERT
Definition: Errors.h:68
#define MAX_RAID_DIFFICULTY
Definition: DBCEnums.h:290
@ MAP_RAID
Definition: DBCEnums.h:356
@ DUNGEON_DIFFICULTY_NORMAL
Definition: DBCEnums.h:277
#define MAX_DUNGEON_DIFFICULTY
Definition: DBCEnums.h:289
void InsertToDB()
Definition: InstanceSaveMgr.cpp:164
friend class InstanceSave
Definition: InstanceSaveMgr.h:108
bool IsRaid() const
Definition: DBCStructure.h:1352
uint32 map_type
Definition: DBCStructure.h:1326

References ASSERT, DAY, DUNGEON_DIFFICULTY_NORMAL, GetExtendedResetTimeFor(), GameTime::GetGameTime(), GetInstanceSave(), GetResetTimeFor(), InstanceSave::InsertToDB(), InstanceSave, MapEntry::IsRaid(), LOG_ERROR, m_instanceSaveById, MAP_RAID, MapEntry::map_type, MAX_DUNGEON_DIFFICULTY, MAX_RAID_DIFFICULTY, and sMapStore.

Referenced by LoadInstanceSaves().

◆ CopyBinds()

void InstanceSaveMgr::CopyBinds ( ObjectGuid  from,
ObjectGuid  to,
Player toPlr = nullptr 
)
817{
818 if (from == to)
819 return;
820
821 for (uint8 d = 0; d < MAX_DIFFICULTY; ++d)
822 {
824 for (BoundInstancesMap::const_iterator itr = bi.begin(); itr != bi.end(); ++itr)
825 if (!PlayerGetBoundInstance(to, itr->first, Difficulty(d)))
826 PlayerBindToInstance(to, itr->second.save, false, toPlr);
827 }
828}
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition: InstanceSaveMgr.h:46
Difficulty
Definition: DBCEnums.h:274
#define MAX_DIFFICULTY
Definition: DBCEnums.h:291
InstancePlayerBind * PlayerBindToInstance(ObjectGuid guid, InstanceSave *save, bool permanent, Player *player=nullptr)
Definition: InstanceSaveMgr.cpp:634
BoundInstancesMap const & PlayerGetBoundInstances(ObjectGuid guid, Difficulty difficulty)
Definition: InstanceSaveMgr.cpp:779
InstancePlayerBind * PlayerGetBoundInstance(ObjectGuid guid, uint32 mapid, Difficulty difficulty)
Definition: InstanceSaveMgr.cpp:749

References MAX_DIFFICULTY, PlayerBindToInstance(), PlayerGetBoundInstance(), and PlayerGetBoundInstances().

◆ DeleteInstanceSavedData()

void InstanceSaveMgr::DeleteInstanceSavedData ( uint32  instanceId)
250{
251 if (instanceId)
252 {
254 stmt->SetData(0, instanceId);
255 CharacterDatabase.Execute(stmt);
256 }
257}
@ CHAR_DELETE_INSTANCE_SAVED_DATA
Definition: CharacterDatabase.h:522

References CHAR_DELETE_INSTANCE_SAVED_DATA, CharacterDatabase, and PreparedStatementBase::SetData().

Referenced by _ResetSave(), and DeleteInstanceSaveIfNeeded().

◆ DeleteInstanceSaveIfNeeded() [1/2]

bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded ( InstanceSave save,
bool  skipMapCheck,
bool  deleteSave = true 
)
119{
120 // pussywizard: save is removed only when there are no more players bound AND the map doesn't exist
121 // pussywizard: this function is called when unbinding a player and when unloading a map
122 if (!lock_instLists && save && save->m_playerList.empty() && (skipMapCheck || !sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId())))
123 {
124 // delete save from storage:
125 InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(save->GetInstanceId());
126 ASSERT(itr != m_instanceSaveById.end() && itr->second == save);
127 m_instanceSaveById.erase(itr);
128
129 // delete save from db:
130 // character_instance is deleted when unbinding a certain player
132 stmt->SetData(0, save->GetInstanceId());
133 CharacterDatabase.Execute(stmt);
135
136 // clear respawn times (if map is loaded do it just to be sure, if already unloaded it won't do it by itself)
138
139 sScriptMgr->OnInstanceIdRemoved(save->GetInstanceId());
140
141 if (deleteSave)
142 {
143 delete save;
144 }
145
146 return true;
147 }
148 return false;
149}
uint32 GetInstanceId() const
Definition: InstanceSaveMgr.h:61
uint32 GetMapId() const
Definition: InstanceSaveMgr.h:62

References ASSERT, CHAR_DEL_INSTANCE_BY_INSTANCE, CharacterDatabase, DeleteInstanceSavedData(), Map::DeleteRespawnTimesInDB(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), lock_instLists, m_instanceSaveById, InstanceSave::m_playerList, PreparedStatementBase::SetData(), sMapMgr, and sScriptMgr.

◆ DeleteInstanceSaveIfNeeded() [2/2]

bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded ( uint32  InstanceId,
bool  skipMapCheck 
)
114{
115 return DeleteInstanceSaveIfNeeded(GetInstanceSave(InstanceId), skipMapCheck);
116}
bool DeleteInstanceSaveIfNeeded(uint32 InstanceId, bool skipMapCheck)
Definition: InstanceSaveMgr.cpp:113

References DeleteInstanceSaveIfNeeded(), and GetInstanceSave().

Referenced by DeleteInstanceSaveIfNeeded(), and InstanceSave::RemovePlayer().

◆ GetExtendedResetTimeFor()

time_t InstanceSaveMgr::GetExtendedResetTimeFor ( uint32  mapid,
Difficulty  d 
) const
inline
143 {
144 ResetTimeByMapDifficultyMap::const_iterator itr = m_resetExtendedTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d));
145 return itr != m_resetExtendedTimeByMapDifficulty.end() ? itr->second : 0;
146 }
uint32 MAKE_PAIR32(uint16 l, uint16 h)
Definition: ObjectDefines.h:87
ResetTimeByMapDifficultyMap m_resetExtendedTimeByMapDifficulty
Definition: InstanceSaveMgr.h:198

References m_resetExtendedTimeByMapDifficulty, and MAKE_PAIR32().

Referenced by _ResetSave(), and AddInstanceSave().

◆ GetInstanceSave()

InstanceSave * InstanceSaveMgr::GetInstanceSave ( uint32  InstanceId)
108{
109 InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(InstanceId);
110 return itr != m_instanceSaveById.end() ? itr->second : nullptr;
111}

References m_instanceSaveById.

Referenced by _ResetOrWarnAll(), AddInstanceSave(), DeleteInstanceSaveIfNeeded(), and LoadCharacterBinds().

◆ GetResetTimeFor()

time_t InstanceSaveMgr::GetResetTimeFor ( uint32  mapid,
Difficulty  d 
) const
inline
137 {
138 ResetTimeByMapDifficultyMap::const_iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d));
139 return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0;
140 }
ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty
Definition: InstanceSaveMgr.h:197

References m_resetTimeByMapDifficulty, and MAKE_PAIR32().

Referenced by _ResetSave(), AddInstanceSave(), LoadResetTimes(), and Update().

◆ GetResetTimeMap()

ResetTimeByMapDifficultyMap const & InstanceSaveMgr::GetResetTimeMap ( ) const
inline
159 {
161 }

References m_resetTimeByMapDifficulty.

◆ instance()

InstanceSaveMgr * InstanceSaveMgr::instance ( )
static
57{
59 return &instance;
60}
Definition: InstanceSaveMgr.h:107
static InstanceSaveMgr * instance()
Definition: InstanceSaveMgr.cpp:56

References instance().

Referenced by instance().

◆ LoadCharacterBinds()

void InstanceSaveMgr::LoadCharacterBinds ( )
405{
406 lock_instLists = true;
407
408 QueryResult result = CharacterDatabase.Query("SELECT guid, instance, permanent, extended FROM character_instance");
409 if (result)
410 {
411 do
412 {
413 Field* fields = result->Fetch();
414
415 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>(fields[0].Get<uint32>());
416 uint32 instanceId = fields[1].Get<uint32>();
417 bool perm = fields[2].Get<bool>();
418 bool extended = fields[3].Get<bool>();
419
420 if (InstanceSave* save = GetInstanceSave(instanceId))
421 {
423 InstancePlayerBind& bind = playerBindStorage[guid]->m[save->GetDifficulty()][save->GetMapId()];
424 if (bind.save) // pussywizard: another bind for the same map and difficulty! may happen because of mysql thread races
425 {
426 if (bind.perm) // already loaded perm -> delete currently checked one from db
427 {
429 stmt->SetData(0, guid.GetCounter());
430 stmt->SetData(1, instanceId);
431 CharacterDatabase.Execute(stmt);
432 continue;
433 }
434 else // override temp bind by newest one
435 {
437 stmt->SetData(0, guid.GetCounter());
438 stmt->SetData(1, bind.save->GetInstanceId());
439 CharacterDatabase.Execute(stmt);
440 bind.save->RemovePlayer(guid, this);
441 }
442 }
443 bind.save = save;
444 bind.perm = perm;
445 bind.extended = extended;
446 save->AddPlayer(guid);
447 if (perm)
448 save->SetCanReset(false);
449 }
450 } while (result->NextRow());
451 }
452
453 lock_instLists = false;
454}
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
@ CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID
Definition: CharacterDatabase.h:309
Class used to access individual fields of database query result.
Definition: Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
Definition: ObjectGuid.h:120
LowType GetCounter() const
Definition: ObjectGuid.h:147
Definition: InstanceSaveMgr.h:39
InstanceSave * save
Definition: InstanceSaveMgr.h:40
bool extended
Definition: InstanceSaveMgr.h:42
bool perm
Definition: InstanceSaveMgr.h:41
bool RemovePlayer(ObjectGuid guid, InstanceSaveMgr *ism)
Definition: InstanceSaveMgr.cpp:223
void PlayerCreateBoundInstancesMaps(ObjectGuid guid)
Definition: InstanceSaveMgr.cpp:787
static PlayerBindStorage playerBindStorage
Definition: InstanceSaveMgr.h:189

References CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, CharacterDatabase, InstancePlayerBind::extended, Field::Get(), ObjectGuid::GetCounter(), InstanceSave::GetInstanceId(), GetInstanceSave(), lock_instLists, InstancePlayerBind::perm, playerBindStorage, PlayerCreateBoundInstancesMaps(), InstanceSave::RemovePlayer(), InstancePlayerBind::save, and PreparedStatementBase::SetData().

Referenced by LoadInstances().

◆ LoadInstances()

void InstanceSaveMgr::LoadInstances ( )
260{
261 uint32 oldMSTime = getMSTime();
262
263 // Delete character_instance for non-existent character
264 CharacterDatabase.DirectExecute("DELETE ci.* FROM character_instance AS ci LEFT JOIN characters AS c ON ci.guid = c.guid WHERE c.guid IS NULL");
265
266 // Delete expired normal instances (normals expire after 3 days even if someone is still bound to them, cleared on startup)
267 CharacterDatabase.DirectExecute("DELETE FROM instance WHERE resettime > 0 AND resettime < UNIX_TIMESTAMP()");
268
269 // Delete instance with no binds
270 CharacterDatabase.DirectExecute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance WHERE ci.guid IS NULL");
271
272 // Delete creature_respawn, gameobject_respawn and creature_instance for non-existent instance
273 CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
274 CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
275 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");
276
277 // Clean invalid references to instance
278 CharacterDatabase.DirectExecute("UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)");
279 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");
280
281 // Initialize instance id storage (Needs to be done after the trash has been clean out)
282 sMapMgr->InitInstanceIds();
283
284 // Load reset times and clean expired instances
286
287 // pussywizard
290
291 // Sanitize pending rows on Instance_saved_data for data that wasn't deleted properly
293
294 LOG_INFO("server.loading", ">> Loaded Instances And Binds in {} ms", GetMSTimeDiffToNow(oldMSTime));
295 LOG_INFO("server.loading", " ");
296}
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
void LoadCharacterBinds()
Definition: InstanceSaveMgr.cpp:404
void LoadInstanceSaves()
Definition: InstanceSaveMgr.cpp:373
void LoadResetTimes()
Definition: InstanceSaveMgr.cpp:298
void SanitizeInstanceSavedData()
Definition: InstanceSaveMgr.cpp:243

References CharacterDatabase, getMSTime(), GetMSTimeDiffToNow(), LoadCharacterBinds(), LoadInstanceSaves(), LoadResetTimes(), LOG_INFO, SanitizeInstanceSavedData(), and sMapMgr.

◆ LoadInstanceSaves()

void InstanceSaveMgr::LoadInstanceSaves ( )
374{
375 QueryResult result = CharacterDatabase.Query("SELECT id, map, resettime, difficulty, completedEncounters, data FROM instance ORDER BY id ASC");
376 if (result)
377 {
378 do
379 {
380 Field* fields = result->Fetch();
381
382 uint32 instanceId = fields[0].Get<uint32>();
383 uint32 mapId = fields[1].Get<uint16>();
384 time_t resettime = time_t(fields[2].Get<uint32>());
385 uint8 difficulty = fields[3].Get<uint8>();
386 uint32 completedEncounters = fields[4].Get<uint32>();
387 std::string instanceData = fields[5].Get<std::string>();
388
389 // Mark instance id as being used
390 sMapMgr->RegisterInstanceId(instanceId);
391
392 InstanceSave* save = AddInstanceSave(mapId, instanceId, Difficulty(difficulty), true);
393 if (save)
394 {
395 save->SetCompletedEncounterMask(completedEncounters);
396 save->SetInstanceData(instanceData);
397 if (resettime > 0)
398 save->SetResetTime(resettime);
399 }
400 } while (result->NextRow());
401 }
402}
void SetResetTime(time_t resetTime)
Definition: InstanceSaveMgr.h:78
void SetInstanceData(std::string str)
Definition: InstanceSaveMgr.h:70
void SetCompletedEncounterMask(uint32 mask)
Definition: InstanceSaveMgr.h:72
InstanceSave * AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, bool startup=false)
Definition: InstanceSaveMgr.cpp:65

References AddInstanceSave(), CharacterDatabase, Field::Get(), InstanceSave::SetCompletedEncounterMask(), InstanceSave::SetInstanceData(), InstanceSave::SetResetTime(), and sMapMgr.

Referenced by LoadInstances().

◆ LoadResetTimes()

void InstanceSaveMgr::LoadResetTimes ( )
299{
300 time_t now = GameTime::GetGameTime().count();
301 time_t today = (now / DAY) * DAY;
302
303 // load the global respawn times for raid/heroic instances
304 uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
305 QueryResult result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset");
306 if (result)
307 {
308 do
309 {
310 Field* fields = result->Fetch();
311 uint32 mapid = fields[0].Get<uint16>();
312 Difficulty difficulty = Difficulty(fields[1].Get<uint8>());
313 uint64 resettime = fields[2].Get<uint32>();
314
315 MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty);
316 if (!mapDiff)
317 {
318 LOG_ERROR("instance.save", "InstanceSaveMgr::LoadResetTimes: invalid mapid({})/difficulty({}) pair in instance_reset!", mapid, difficulty);
319 CharacterDatabase.DirectExecute("DELETE FROM instance_reset WHERE mapid = '{}' AND difficulty = '{}'", mapid, difficulty);
320 continue;
321 }
322
323 SetResetTimeFor(mapid, difficulty, resettime);
324 } while (result->NextRow());
325 }
326
327 // calculate new global reset times for expired instances and those that have never been reset yet
328 // add the global reset times to the priority queue
329 for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr)
330 {
331 uint32 map_diff_pair = itr->first;
332 uint32 mapid = PAIR32_LOPART(map_diff_pair);
333 Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair));
334 MapDifficulty const* mapDiff = &itr->second;
335 if (!mapDiff->resetTime)
336 continue;
337
338 // the reset_delay must be at least one day
339 uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
340 if (period < DAY)
341 period = DAY;
342
343 time_t t = GetResetTimeFor(mapid, difficulty);
344 if (!t)
345 {
346 // initialize the reset time
347 t = today + period + diff;
348 SetResetTimeFor(mapid, difficulty, t);
349 CharacterDatabase.DirectExecute("INSERT INTO instance_reset VALUES ('{}', '{}', '{}')", mapid, difficulty, (uint32)t);
350 }
351
352 if (t < now)
353 {
354 // assume that expired instances have already been cleaned
355 // calculate the next reset time
356 t = (t * DAY) / DAY;
357 t += ((today - t) / period + 1) * period + diff;
358 CharacterDatabase.DirectExecute("UPDATE instance_reset SET resettime = '{}' WHERE mapid = '{}' AND difficulty = '{}'", (uint32)t, mapid, difficulty);
359 }
360
361 SetExtendedResetTimeFor(mapid, difficulty, t);
362
363 // schedule the global reset/warning
364 uint8 type;
365 for (type = 1; type < 5; ++type)
366 if (now + ResetTimeDelay[type - 1] < t)
367 break;
368
369 ScheduleReset(t - ResetTimeDelay[type - 1], InstResetEvent(type, mapid, difficulty));
370 }
371}
std::uint64_t uint64
Definition: Define.h:107
MapDifficultyMap sMapDifficultyMap
Definition: DBCStores.cpp:121
uint16 PAIR32_HIPART(uint32 x)
Definition: ObjectDefines.h:92
uint16 PAIR32_LOPART(uint32 x)
Definition: ObjectDefines.h:97
static uint16 ResetTimeDelay[]
Definition: InstanceSaveMgr.h:188

References CharacterDatabase, CONFIG_INSTANCE_RESET_TIME_HOUR, DAY, Field::Get(), GameTime::GetGameTime(), GetMapDifficultyData(), GetResetTimeFor(), HOUR, LOG_ERROR, PAIR32_HIPART(), PAIR32_LOPART(), RATE_INSTANCE_RESET_TIME, MapDifficulty::resetTime, ResetTimeDelay, ScheduleReset(), SetExtendedResetTimeFor(), SetResetTimeFor(), sMapDifficultyMap, and sWorld.

Referenced by LoadInstances().

◆ PlayerBindToInstance()

InstancePlayerBind * InstanceSaveMgr::PlayerBindToInstance ( ObjectGuid  guid,
InstanceSave save,
bool  permanent,
Player player = nullptr 
)
635{
636 InstancePlayerBind& bind = playerBindStorage[guid]->m[save->GetDifficulty()][save->GetMapId()];
637 ASSERT(!bind.perm || permanent); // ensure there's no changing permanent to temporary, this can be done only by unbinding
638
639 if (bind.save)
640 {
641 if (save != bind.save || permanent != bind.perm)
642 {
643 bind.extended = false;
644
646 stmt->SetData(0, save->GetInstanceId());
647 stmt->SetData(1, permanent);
648 stmt->SetData(2, guid.GetCounter());
649 stmt->SetData(3, bind.save->GetInstanceId());
650 CharacterDatabase.Execute(stmt);
651 }
652 }
653 else
654 {
655 // pussywizard: protect against mysql thread races!
656 // pussywizard: CHANGED MY MIND! DON'T SLOW DOWN THIS QUERY! HANDLE ONLY DURING LOADING FROM DB!
657 // example: enter instance -> bind -> update old id to new id -> exit -> delete new id
658 // if delete by new id is executed before update, then we end up with in db
659 /*CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
660 // ensure any for that map+difficulty is deleted!
661 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_GUID_MAP_DIFF); // DELETE ci FROM character_instance ci JOIN instance i ON ci.instance = i.id WHERE ci.guid = ? AND i.map = ? AND i.difficulty = ?
662 stmt->SetData(0, guidLow);
663 stmt->SetData(1, uint16(save->GetMapId()));
664 stmt->SetData(2, uint8(save->GetDifficulty()));
665 trans->Append(stmt);
666 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_INSTANCE);
667 stmt->SetData(0, guidLow);
668 stmt->SetData(1, save->GetInstanceId());
669 stmt->SetData(2, permanent);
670 trans->Append(stmt);
671 CharacterDatabase.CommitTransaction(trans);*/
672
674 stmt->SetData(0, guid.GetCounter());
675 stmt->SetData(1, save->GetInstanceId());
676 stmt->SetData(2, permanent);
677 CharacterDatabase.Execute(stmt);
678
679 if (player)
681 }
682
683 if (bind.save != save)
684 {
685 if (bind.save)
686 bind.save->RemovePlayer(guid, this);
687 save->AddPlayer(guid);
688 }
689
690 if (permanent)
691 {
692 save->SetCanReset(false);
693 if (!bind.perm && player) // temporary changing to permanent
694 player->GetSession()->SendCalendarRaidLockout(save, true);
695 }
696
697 bind.save = save;
698 bind.perm = permanent;
699
700 if (player)
701 sScriptMgr->OnPlayerBindToInstance(player, save->GetDifficulty(), save->GetMapId(), permanent);
702
703 return &bind;
704}
@ CHAR_INS_CHAR_INSTANCE
Definition: CharacterDatabase.h:312
@ CHAR_UPD_CHAR_INSTANCE
Definition: CharacterDatabase.h:310
@ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID
Definition: DBCEnums.h:144
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2131
WorldSession * GetSession() const
Definition: Player.h:1961
void AddPlayer(ObjectGuid guid)
Definition: InstanceSaveMgr.cpp:217
void SetCanReset(bool canReset)
Definition: InstanceSaveMgr.h:82
Difficulty GetDifficulty() const
Definition: InstanceSaveMgr.h:63
void SendCalendarRaidLockout(InstanceSave const *save, bool add)
Definition: CalendarHandler.cpp:818

References ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID, InstanceSave::AddPlayer(), ASSERT, CHAR_INS_CHAR_INSTANCE, CHAR_UPD_CHAR_INSTANCE, CharacterDatabase, InstancePlayerBind::extended, ObjectGuid::GetCounter(), InstanceSave::GetDifficulty(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), Player::GetSession(), InstancePlayerBind::perm, playerBindStorage, InstanceSave::RemovePlayer(), InstancePlayerBind::save, WorldSession::SendCalendarRaidLockout(), InstanceSave::SetCanReset(), PreparedStatementBase::SetData(), sScriptMgr, and Player::UpdateAchievementCriteria().

Referenced by CopyBinds().

◆ PlayerCreateBoundInstancesMaps()

void InstanceSaveMgr::PlayerCreateBoundInstancesMaps ( ObjectGuid  guid)
788{
789 if (playerBindStorage.find(guid) == playerBindStorage.end())
791}
Definition: InstanceSaveMgr.h:49

References playerBindStorage.

Referenced by LoadCharacterBinds().

◆ PlayerGetBoundInstance()

InstancePlayerBind * InstanceSaveMgr::PlayerGetBoundInstance ( ObjectGuid  guid,
uint32  mapid,
Difficulty  difficulty 
)
750{
751 Difficulty difficulty_fixed = ( IsSharedDifficultyMap(mapid) ? Difficulty(difficulty % 2) : difficulty);
752
753 MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(mapid, difficulty_fixed);
754 if (!mapDiff)
755 return nullptr;
756
757 BoundInstancesMapWrapper* w = nullptr;
758 PlayerBindStorage::const_iterator itr = playerBindStorage.find(guid);
759 if (itr != playerBindStorage.end())
760 w = itr->second;
761 else
762 return nullptr;
763
764 BoundInstancesMap::iterator itr2 = w->m[difficulty_fixed].find(mapid);
765 if (itr2 != w->m[difficulty_fixed].end())
766 return &itr2->second;
767 else
768 return nullptr;
769}
MapDifficulty const * GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty)
Definition: DBCStores.cpp:763
bool IsSharedDifficultyMap(uint32 mapid)
Definition: DBCStores.cpp:825
BoundInstancesMap m[MAX_DIFFICULTY]
Definition: InstanceSaveMgr.h:50

References GetDownscaledMapDifficultyData(), IsSharedDifficultyMap(), BoundInstancesMapWrapper::m, and playerBindStorage.

Referenced by CopyBinds(), PlayerGetDestinationInstanceId(), PlayerGetInstanceSave(), and PlayerIsPermBoundToInstance().

◆ PlayerGetBoundInstances()

BoundInstancesMap const & InstanceSaveMgr::PlayerGetBoundInstances ( ObjectGuid  guid,
Difficulty  difficulty 
)
780{
781 PlayerBindStorage::iterator itr = playerBindStorage.find(guid);
782 if (itr != playerBindStorage.end())
783 return itr->second->m[difficulty];
785}
static BoundInstancesMap emptyBoundInstancesMap
Definition: InstanceSaveMgr.h:190

References emptyBoundInstancesMap, and playerBindStorage.

Referenced by CopyBinds().

◆ PlayerGetDestinationInstanceId()

uint32 InstanceSaveMgr::PlayerGetDestinationInstanceId ( Player player,
uint32  mapid,
Difficulty  difficulty 
)
800{
801 // returning 0 means a new instance will be created
802 // non-zero implicates that InstanceSave exists
803
804 InstancePlayerBind* ipb = PlayerGetBoundInstance(player->GetGUID(), mapid, difficulty);
805 if (ipb && ipb->perm) // 1. self perm
806 return ipb->save->GetInstanceId();
807 if (Group* g = player->GetGroup())
808 {
809 if (InstancePlayerBind* ilb = PlayerGetBoundInstance(g->GetLeaderGUID(), mapid, difficulty)) // 2. leader temp/perm
810 return ilb->save->GetInstanceId();
811 return 0; // 3. in group, no leader bind
812 }
813 return ipb ? ipb->save->GetInstanceId() : 0; // 4. self temp
814}
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Group * GetGroup()
Definition: Player.h:2431
Definition: Group.h:169

References Player::GetGroup(), Object::GetGUID(), InstanceSave::GetInstanceId(), InstancePlayerBind::perm, PlayerGetBoundInstance(), and InstancePlayerBind::save.

◆ PlayerGetInstanceSave()

InstanceSave * InstanceSaveMgr::PlayerGetInstanceSave ( ObjectGuid  guid,
uint32  mapid,
Difficulty  difficulty 
)
794{
795 InstancePlayerBind* pBind = PlayerGetBoundInstance(guid, mapid, difficulty);
796 return (pBind ? pBind->save : nullptr);
797}

References PlayerGetBoundInstance(), and InstancePlayerBind::save.

◆ PlayerIsPermBoundToInstance()

bool InstanceSaveMgr::PlayerIsPermBoundToInstance ( ObjectGuid  guid,
uint32  mapid,
Difficulty  difficulty 
)
772{
773 if (InstancePlayerBind* bind = PlayerGetBoundInstance(guid, mapid, difficulty))
774 if (bind->perm)
775 return true;
776 return false;
777}

References PlayerGetBoundInstance().

◆ PlayerUnbindInstance()

void InstanceSaveMgr::PlayerUnbindInstance ( ObjectGuid  guid,
uint32  mapid,
Difficulty  difficulty,
bool  deleteFromDB,
Player player = nullptr 
)
707{
709 BoundInstancesMap::iterator itr = w->m[difficulty].find(mapid);
710 if (itr != w->m[difficulty].end())
711 {
712 if (deleteFromDB)
713 {
715 stmt->SetData(0, guid.GetCounter());
716 stmt->SetData(1, itr->second.save->GetInstanceId());
717 CharacterDatabase.Execute(stmt);
718 }
719
720 if (itr->second.perm && player)
721 player->GetSession()->SendCalendarRaidLockout(itr->second.save, false);
722
723 InstanceSave* tmp = itr->second.save;
724 w->m[difficulty].erase(itr);
725 tmp->RemovePlayer(guid, this);
726 }
727}

References CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, CharacterDatabase, ObjectGuid::GetCounter(), Player::GetSession(), BoundInstancesMapWrapper::m, playerBindStorage, InstanceSave::RemovePlayer(), WorldSession::SendCalendarRaidLockout(), and PreparedStatementBase::SetData().

Referenced by UnbindAllFor().

◆ PlayerUnbindInstanceNotExtended()

void InstanceSaveMgr::PlayerUnbindInstanceNotExtended ( ObjectGuid  guid,
uint32  mapid,
Difficulty  difficulty,
Player player = nullptr 
)
730{
732 BoundInstancesMap::iterator itr = w->m[difficulty].find(mapid);
733 if (itr != w->m[difficulty].end())
734 {
735 if (itr->second.extended)
736 itr->second.extended = false;
737 else
738 {
739 if (itr->second.perm && player)
740 player->GetSession()->SendCalendarRaidLockout(itr->second.save, false);
741
742 InstanceSave* tmp = itr->second.save;
743 w->m[difficulty].erase(itr);
744 tmp->RemovePlayer(guid, this);
745 }
746 }
747}

References Player::GetSession(), BoundInstancesMapWrapper::m, playerBindStorage, InstanceSave::RemovePlayer(), and WorldSession::SendCalendarRaidLockout().

Referenced by _ResetSave().

◆ SanitizeInstanceSavedData()

void InstanceSaveMgr::SanitizeInstanceSavedData ( )
244{
246 CharacterDatabase.Execute(stmt);
247}
@ CHAR_SANITIZE_INSTANCE_SAVED_DATA
Definition: CharacterDatabase.h:523

References CHAR_SANITIZE_INSTANCE_SAVED_DATA, and CharacterDatabase.

Referenced by LoadInstances().

◆ ScheduleReset()

void InstanceSaveMgr::ScheduleReset ( time_t  time,
InstResetEvent  event 
)
457{
458 m_resetTimeQueue.insert(std::pair<time_t, InstResetEvent>(time, event));
459}
ResetTimeQueue m_resetTimeQueue
Definition: InstanceSaveMgr.h:199

References m_resetTimeQueue.

Referenced by _ResetOrWarnAll(), LoadResetTimes(), and Update().

◆ SetExtendedResetTimeFor()

void InstanceSaveMgr::SetExtendedResetTimeFor ( uint32  mapid,
Difficulty  d,
time_t  t 
)
inline

◆ SetResetTimeFor()

void InstanceSaveMgr::SetResetTimeFor ( uint32  mapid,
Difficulty  d,
time_t  t 
)
inline
149 {
151 }

References m_resetTimeByMapDifficulty, and MAKE_PAIR32().

Referenced by _ResetOrWarnAll(), and LoadResetTimes().

◆ UnbindAllFor()

void InstanceSaveMgr::UnbindAllFor ( InstanceSave save)
831{
832 uint32 mapId = save->GetMapId();
833 Difficulty difficulty = save->GetDifficulty();
834 GuidList players = save->m_playerList;
835
836 for (ObjectGuid const& guid : players)
837 {
838 PlayerUnbindInstance(guid, mapId, difficulty, true, ObjectAccessor::FindConnectedPlayer(guid));
839 }
840}
void PlayerUnbindInstance(ObjectGuid guid, uint32 mapid, Difficulty difficulty, bool deleteFromDB, Player *player=nullptr)
Definition: InstanceSaveMgr.cpp:706

References ObjectAccessor::FindConnectedPlayer(), InstanceSave::GetDifficulty(), InstanceSave::GetMapId(), InstanceSave::m_playerList, and PlayerUnbindInstance().

◆ Update()

void InstanceSaveMgr::Update ( )
462{
463 time_t now = GameTime::GetGameTime().count();
464 time_t t;
465 bool resetOccurred = false;
466
467 while (!m_resetTimeQueue.empty())
468 {
469 t = m_resetTimeQueue.begin()->first;
470 if (t >= now)
471 break;
472
473 InstResetEvent& event = m_resetTimeQueue.begin()->second;
474 if (event.type)
475 {
476 // global reset/warning for a certain map
477 time_t resetTime = GetResetTimeFor(event.mapid, event.difficulty);
478 bool warn = event.type < 5;
479 _ResetOrWarnAll(event.mapid, event.difficulty, warn, resetTime);
480 if (warn)
481 {
482 // schedule the next warning/reset
483 ++event.type;
484 ScheduleReset(resetTime - ResetTimeDelay[event.type - 1], event);
485 }
486 else
487 resetOccurred = true;
488 }
489 m_resetTimeQueue.erase(m_resetTimeQueue.begin());
490 }
491
492 // pussywizard: send updated calendar and raid info
493 if (resetOccurred)
494 {
495 LOG_INFO("instance.save", "Instance ID reset occurred, sending updated calendar and raid info to all players!");
496 WorldPacket dummy;
497 for (SessionMap::const_iterator itr = sWorld->GetAllSessions().begin(); itr != sWorld->GetAllSessions().end(); ++itr)
498 if (Player* plr = itr->second->GetPlayer())
499 {
500 itr->second->HandleCalendarGetCalendar(dummy);
501 plr->SendRaidInfo();
502 }
503 }
504}
Definition: Player.h:1056
void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, time_t resetTime)
Definition: InstanceSaveMgr.cpp:558
Definition: WorldPacket.h:27

References _ResetOrWarnAll(), GameTime::GetGameTime(), GetResetTimeFor(), LOG_INFO, m_resetTimeQueue, ResetTimeDelay, ScheduleReset(), and sWorld.

Friends And Related Function Documentation

◆ InstanceSave

friend class InstanceSave
friend

Referenced by AddInstanceSave().

Member Data Documentation

◆ emptyBoundInstancesMap

BoundInstancesMap InstanceSaveMgr::emptyBoundInstancesMap
staticprotected

Referenced by PlayerGetBoundInstances().

◆ lock_instLists

bool InstanceSaveMgr::lock_instLists {false}
private

◆ m_instanceSaveById

InstanceSaveHashMap InstanceSaveMgr::m_instanceSaveById
private

◆ m_resetExtendedTimeByMapDifficulty

ResetTimeByMapDifficultyMap InstanceSaveMgr::m_resetExtendedTimeByMapDifficulty
private

◆ m_resetTimeByMapDifficulty

ResetTimeByMapDifficultyMap InstanceSaveMgr::m_resetTimeByMapDifficulty
private

◆ m_resetTimeQueue

ResetTimeQueue InstanceSaveMgr::m_resetTimeQueue
private

Referenced by ScheduleReset(), and Update().

◆ playerBindStorage

◆ ResetTimeDelay

uint16 InstanceSaveMgr::ResetTimeDelay = {3600, 900, 300, 60, 0}
staticprotected

Referenced by LoadResetTimes(), and Update().