diff options
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 27 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 1 |
2 files changed, 16 insertions, 12 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 8b3946d22c5..0ed19a3642e 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -991,10 +991,7 @@ void GameObject::Update(uint32 diff) // If there is no restock timer, or if the restock timer passed, the chest becomes ready to loot m_restockTime = 0; m_lootState = GO_READY; - m_loot = nullptr; - m_personalLoot.clear(); - m_unique_users.clear(); - m_usetimes = 0; + ClearLoot(); UpdateDynamicFlagsForNearbyPlayers(); break; default: @@ -1223,10 +1220,7 @@ void GameObject::Update(uint32 diff) { m_restockTime = 0; m_lootState = GO_READY; - m_loot = nullptr; - m_personalLoot.clear(); - m_unique_users.clear(); - m_usetimes = 0; + ClearLoot(); UpdateDynamicFlagsForNearbyPlayers(); } break; @@ -1300,10 +1294,7 @@ void GameObject::Update(uint32 diff) return; } - m_loot = nullptr; - m_personalLoot.clear(); - m_unique_users.clear(); - m_usetimes = 0; + ClearLoot(); // Do not delete chests or goobers that are not consumed on loot, while still allowing them to despawn when they expire if summoned bool isSummonedAndExpired = (GetOwner() || GetSpellId()) && m_respawnTime == 0; @@ -3323,6 +3314,18 @@ void GameObject::SetLootState(LootState state, Unit* unit) } } +void GameObject::ClearLoot() +{ + // Unlink loot objects from this GameObject before destroying to avoid accessing freed memory from Loot destructor + std::unique_ptr<Loot> loot(std::move(m_loot)); + std::unordered_map<ObjectGuid, std::unique_ptr<Loot>> personalLoot(std::move(m_personalLoot)); + + loot.reset(); + personalLoot.clear(); + m_unique_users.clear(); + m_usetimes = 0; +} + bool GameObject::IsFullyLooted() const { if (m_loot && !m_loot->isLooted()) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 6800d3c9aed..170e5c18c2b 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -263,6 +263,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; } void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; } void ResetLootMode() { m_LootMode = LOOT_MODE_DEFAULT; } + void ClearLoot(); bool IsFullyLooted() const; void OnLootRelease(Player* looter); |