Skip to content

Commit

Permalink
fix(Core): Crash related to reset instances (azerothcore#11003)
Browse files Browse the repository at this point in the history
  • Loading branch information
UltraNix committed Mar 18, 2022
1 parent 52427b4 commit 3c9e8d4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
38 changes: 29 additions & 9 deletions src/server/game/Instances/InstanceSaveMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded(uint32 InstanceId, bool skipMap
return DeleteInstanceSaveIfNeeded(GetInstanceSave(InstanceId), skipMapCheck);
}

bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMapCheck)
bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMapCheck, bool deleteSave /*= true*/)
{
// pussywizard: save is removed only when there are no more players bound AND the map doesn't exist
// pussywizard: this function is called when unbinding a player and when unloading a map
Expand All @@ -136,7 +136,11 @@ bool InstanceSaveMgr::DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMa
// clear respawn times (if map is loaded do it just to be sure, if already unloaded it won't do it by itself)
Map::DeleteRespawnTimesInDB(save->GetMapId(), save->GetInstanceId());

delete save;
if (deleteSave)
{
delete save;
}

return true;
}
return false;
Expand Down Expand Up @@ -216,11 +220,22 @@ void InstanceSave::AddPlayer(ObjectGuid guid)

bool InstanceSave::RemovePlayer(ObjectGuid guid, InstanceSaveMgr* ism)
{
std::lock_guard<std::mutex> guard(_lock);
m_playerList.remove(guid);
bool deleteSave = false;
{
std::lock_guard lg(_lock);
m_playerList.remove(guid);

// ism passed as an argument to avoid calling via singleton (might result in a deadlock)
deleteSave = ism->DeleteInstanceSaveIfNeeded(this, false, false);
}

// Delete save now (avoid mutex memory corruption)
if (deleteSave)
{
delete this;
}

// ism passed as an argument to avoid calling via singleton (might result in a deadlock)
return ism->DeleteInstanceSaveIfNeeded(this->GetInstanceId(), false);
return deleteSave;
}

void InstanceSaveMgr::LoadInstances()
Expand Down Expand Up @@ -787,7 +802,12 @@ void InstanceSaveMgr::CopyBinds(ObjectGuid from, ObjectGuid to, Player* toPlr)

void InstanceSaveMgr::UnbindAllFor(InstanceSave* save)
{
GuidList& pList = save->m_playerList;
while (!pList.empty())
PlayerUnbindInstance(*(pList.begin()), save->GetMapId(), save->GetDifficulty(), true, ObjectAccessor::FindConnectedPlayer(*(pList.begin())));
uint32 mapId = save->GetMapId();
Difficulty difficulty = save->GetDifficulty();
GuidList players = save->m_playerList;

for (ObjectGuid const& guid : players)
{
PlayerUnbindInstance(guid, mapId, difficulty, true, ObjectAccessor::FindConnectedPlayer(guid));
}
}
2 changes: 1 addition & 1 deletion src/server/game/Instances/InstanceSaveMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class InstanceSaveMgr

InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, bool startup = false);
bool DeleteInstanceSaveIfNeeded(uint32 InstanceId, bool skipMapCheck);
bool DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMapCheck);
bool DeleteInstanceSaveIfNeeded(InstanceSave* save, bool skipMapCheck, bool deleteSave = true);

InstanceSave* GetInstanceSave(uint32 InstanceId);

Expand Down
1 change: 1 addition & 0 deletions src/server/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2797,6 +2797,7 @@ InstanceMap::~InstanceMap()
{
delete instance_data;
instance_data = nullptr;
sInstanceSaveMgr->DeleteInstanceSaveIfNeeded(GetInstanceId(), true);
}

void InstanceMap::InitVisibilityDistance()
Expand Down

0 comments on commit 3c9e8d4

Please sign in to comment.