diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-03-21 12:07:54 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-03-21 12:07:54 +0100 |
commit | 2569dc8cfec7a5fd89f037579ea6081504b9223f (patch) | |
tree | faa1c70bb7d9f00081d3a70498efe1ab98cd5410 /src/server/game/Instances/InstanceLockMgr.cpp | |
parent | 5f642b78f04bbbc723d573362ff25f2ede24f5af (diff) |
Core/Instances: Fixed not being able to reenter instances that have no encounters completed
Closes #28737
Diffstat (limited to 'src/server/game/Instances/InstanceLockMgr.cpp')
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/server/game/Instances/InstanceLockMgr.cpp b/src/server/game/Instances/InstanceLockMgr.cpp index cddb94c8e7b..44aaeb145ea 100644 --- a/src/server/game/Instances/InstanceLockMgr.cpp +++ b/src/server/game/Instances/InstanceLockMgr.cpp @@ -29,7 +29,8 @@ InstanceLockData::InstanceLockData() = default; InstanceLockData::~InstanceLockData() = default; InstanceLock::InstanceLock(uint32 mapId, Difficulty difficultyId, InstanceResetTimePoint expiryTime, uint32 instanceId) - : _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false), _isInUse(false) + : _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false), + _isInUse(false), _isNew(false) { } @@ -149,7 +150,7 @@ void InstanceLockMgr::Load() } instanceLock = new SharedInstanceLock(mapId, difficulty, expiryTime, instanceId, sharedDataItr->second); - _instanceLockDataById[instanceId] = std::weak_ptr<SharedInstanceLockData>(sharedDataItr->second); + _instanceLockDataById[instanceId] = sharedDataItr->second; } else instanceLock = new InstanceLock(mapId, difficulty, expiryTime, instanceId); @@ -186,7 +187,7 @@ TransferAbortReason InstanceLockMgr::CanJoinInstanceLock(ObjectGuid const& playe return TRANSFER_ABORT_NONE; } - if (!entries.MapDifficulty->IsUsingEncounterLocks() && playerInstanceLock->GetInstanceId() && playerInstanceLock->GetInstanceId() != instanceLock->GetInstanceId()) + if (!entries.MapDifficulty->IsUsingEncounterLocks() && !playerInstanceLock->IsNew() && playerInstanceLock->GetInstanceId() != instanceLock->GetInstanceId()) return TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE; return TRANSFER_ABORT_NONE; @@ -256,11 +257,13 @@ InstanceLock* InstanceLockMgr::CreateInstanceLockForNewInstance(ObjectGuid const std::shared_ptr<SharedInstanceLockData> sharedData = std::make_shared<SharedInstanceLockData>(); _instanceLockDataById[instanceId] = sharedData; instanceLock = new SharedInstanceLock(entries.MapDifficulty->MapID, Difficulty(entries.MapDifficulty->DifficultyID), - GetNextResetTime(entries), 0, std::move(sharedData)); + GetNextResetTime(entries), instanceId, std::move(sharedData)); } else instanceLock = new InstanceLock(entries.MapDifficulty->MapID, Difficulty(entries.MapDifficulty->DifficultyID), - GetNextResetTime(entries), 0); + GetNextResetTime(entries), instanceId); + + instanceLock->SetIsNew(true); _temporaryInstanceLocksByPlayer[playerGuid][entries.GetKey()].reset(instanceLock); TC_LOG_DEBUG("instance.locks", "[{}-{} | {}-{}] Created new temporary instance lock for {} in instance {}", @@ -333,7 +336,7 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran { if (entries.IsInstanceIdBound()) { - ASSERT(!instanceLock->GetInstanceId() || instanceLock->GetInstanceId() == updateEvent.InstanceId); + ASSERT(instanceLock->GetInstanceId() == updateEvent.InstanceId); auto sharedDataItr = _instanceLockDataById.find(updateEvent.InstanceId); ASSERT(sharedDataItr != _instanceLockDataById.end()); ASSERT(sharedDataItr->second.lock().get() == static_cast<SharedInstanceLock*>(instanceLock)->GetSharedData()); @@ -342,6 +345,7 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran instanceLock->SetInstanceId(updateEvent.InstanceId); } + instanceLock->SetIsNew(false); instanceLock->GetData()->Data = std::move(updateEvent.NewData); if (updateEvent.CompletedEncounter) { @@ -428,7 +432,15 @@ void InstanceLockMgr::OnSharedInstanceLockDataDelete(uint32 instanceId) if (_unloading) return; - _instanceLockDataById.erase(instanceId); + auto itr = _instanceLockDataById.find(instanceId); + if (itr == _instanceLockDataById.end()) + return; + + // weak_ptr state must be checked as well, it might be pointing to a different and valid lock data + if (!itr->second.expired()) + return; + + _instanceLockDataById.erase(itr); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE); stmt->setUInt32(0, instanceId); CharacterDatabase.Execute(stmt); @@ -482,6 +494,9 @@ void InstanceLockMgr::ResetInstanceLocksForPlayer(ObjectGuid const& playerGuid, if (difficulty && *difficulty != playerLockPair.second->GetDifficultyId()) continue; + if (playerLockPair.second->IsExpired()) + continue; + locksReset->push_back(playerLockPair.second.get()); } |