diff options
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/DungeonFinding/LFGMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.cpp | 29 | ||||
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Maps/MapManager.cpp | 2 |
5 files changed, 34 insertions, 15 deletions
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 046dbc11e95..9d990ff17f9 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1731,7 +1731,7 @@ LfgLockMap LFGMgr::GetLockedDungeons(ObjectGuid guid) return LFG_LOCKSTATUS_NOT_IN_SEASON; if (DisableMgr::IsDisabledFor(DISABLE_TYPE_LFG_MAP, dungeon->map, player)) return LFG_LOCKSTATUS_RAID_LOCKED; - if (dungeon->difficulty > DIFFICULTY_NORMAL && sInstanceLockMgr.FindActiveInstanceLock(guid, { dungeon->map, Difficulty(dungeon->difficulty) })) + if (sInstanceLockMgr.FindActiveInstanceLock(guid, { dungeon->map, Difficulty(dungeon->difficulty) })) return LFG_LOCKSTATUS_RAID_LOCKED; if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(dungeon->contentTuningId, player->m_playerData->CtrOptions->ContentTuningConditionMask)) { 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()); } diff --git a/src/server/game/Instances/InstanceLockMgr.h b/src/server/game/Instances/InstanceLockMgr.h index 84edcd90621..40fc27e05b3 100644 --- a/src/server/game/Instances/InstanceLockMgr.h +++ b/src/server/game/Instances/InstanceLockMgr.h @@ -115,6 +115,9 @@ public: bool IsInUse() const { return _isInUse; } void SetInUse(bool inUse) { _isInUse = inUse; } + bool IsNew() const { return _isNew; } + void SetIsNew(bool isNew) { _isNew = isNew; } + private: uint32 _mapId; Difficulty _difficultyId; @@ -123,6 +126,7 @@ private: bool _extended; InstanceLockData _data; bool _isInUse; + bool _isNew; }; struct SharedInstanceLockData : InstanceLockData diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index d215693c4cc..c5a44aefc51 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2860,7 +2860,7 @@ bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) player->AddInstanceEnterTime(GetInstanceId(), GameTime::GetGameTime()); MapDb2Entries entries{ GetEntry(), GetMapDifficulty() }; - if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && i_instanceLock->GetData()->CompletedEncountersMask) + if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && !i_instanceLock->IsNew()) { if (!entries.MapDifficulty->IsUsingEncounterLocks()) { @@ -2948,7 +2948,7 @@ void InstanceMap::CreateInstanceData() if (!i_data) return; - if (!i_instanceLock || !i_instanceLock->GetInstanceId()) + if (!i_instanceLock || i_instanceLock->IsNew()) { i_data->Create(); return; @@ -2985,7 +2985,7 @@ void InstanceMap::TrySetOwningGroup(Group* group) InstanceResetResult InstanceMap::Reset(InstanceResetMethod method) { // raids can be reset if no boss was killed - if (method != InstanceResetMethod::Expire && i_instanceLock && i_instanceLock->GetData()->CompletedEncountersMask) + if (method != InstanceResetMethod::Expire && i_instanceLock && !i_instanceLock->IsNew()) return InstanceResetResult::CannotReset; if (HavePlayers()) @@ -3075,7 +3075,7 @@ void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateS playerCompletedEncounters = playerLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit); } - bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired(); + bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired(); InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries, InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent), @@ -3121,7 +3121,7 @@ void InstanceMap::UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& update if (playerLock) oldData = &playerLock->GetData()->Data; - bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired(); + bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired(); InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries, InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent), @@ -3146,7 +3146,7 @@ void InstanceMap::CreateInstanceLockForPlayer(Player* player) MapDb2Entries entries{ GetEntry(), GetMapDifficulty() }; InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries); - bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired(); + bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired(); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index fe9c950cc49..0c2d686d10d 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -95,7 +95,7 @@ InstanceMap* MapManager::CreateInstance(uint32 mapId, uint32 instanceId, Instanc sDB2Manager.GetDownscaledMapDifficultyData(mapId, difficulty); TC_LOG_DEBUG("maps", "MapInstanced::CreateInstance: {}map instance {} for {} created with difficulty {}", - instanceLock && instanceLock->GetInstanceId() ? "" : "new ", instanceId, mapId, sDifficultyStore.AssertEntry(difficulty)->Name[sWorld->GetDefaultDbcLocale()]); + instanceLock && instanceLock->IsNew() ? "" : "new ", instanceId, mapId, sDifficultyStore.AssertEntry(difficulty)->Name[sWorld->GetDefaultDbcLocale()]); InstanceMap* map = new InstanceMap(mapId, i_gridCleanUpDelay, instanceId, difficulty, team, instanceLock); ASSERT(map->IsDungeon()); |