From 2b2237b7bc829d4d2ae5dbca3150d653735f170e Mon Sep 17 00:00:00 2001 From: Giacomo Pozzoni Date: Sat, 3 Sep 2022 13:16:02 +0200 Subject: [PATCH] Fixes/3.3.5 aura infinite loop * Core/Auras: Attempt to fix infinite loop with aura 18950 on map unload * Core/Auras: Log a detailed error and assert when failing to remove all auras after a few tries * Code cleanup --- src/server/game/Entities/Unit/Unit.cpp | 16 +++++++- .../game/Spells/Auras/SpellAuraEffects.cpp | 37 ++++++++++++------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index db9541170f..b7f87f6d27 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3989,7 +3989,7 @@ void Unit::RemoveAllAuras() { // this may be a dead loop if some events on aura remove will continiously apply aura on remove // we want to have all auras removed, so use your brain when linking events - while (!m_appliedAuras.empty() || !m_ownedAuras.empty()) + for (uint32 counter = 0; !m_appliedAuras.empty() || !m_ownedAuras.empty(); counter++) { AuraApplicationMap::iterator aurAppIter; for (aurAppIter = m_appliedAuras.begin(); aurAppIter != m_appliedAuras.end();) @@ -3998,6 +3998,20 @@ void Unit::RemoveAllAuras() AuraMap::iterator aurIter; for (aurIter = m_ownedAuras.begin(); aurIter != m_ownedAuras.end();) RemoveOwnedAura(aurIter); + + const int maxIteration = 50; + // give this loop a few tries, if there are still auras then log as much information as possible + if (counter >= maxIteration) + { + std::stringstream sstr; + sstr << "Unit::RemoveAllAuras() iterated " << maxIteration << " times already but there are still " + << m_appliedAuras.size() << " m_appliedAuras and " << m_ownedAuras.size() << " m_ownedAuras.\n"; + + TC_LOG_ERROR("entities.unit", "%s", sstr.str().c_str()); + ASSERT(false, sstr.str().c_str()); + + break; + } } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index d958dcce1c..91dbe5041f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1501,8 +1501,9 @@ void AuraEffect::HandleModInvisibilityDetect(AuraApplication const* aurApp, uint target->m_invisibilityDetect.AddValue(type, -GetAmount()); } - // call functions which may have additional effects after chainging state of unit - target->UpdateObjectVisibility(); + // call functions which may have additional effects after changing state of unit + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModInvisibility(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1559,13 +1560,15 @@ void AuraEffect::HandleModInvisibility(AuraApplication const* aurApp, uint8 mode target->m_invisibility.AddValue(type, -GetAmount()); } - // call functions which may have additional effects after chainging state of unit + // call functions which may have additional effects after changing state of unit if (apply && (mode & AURA_EFFECT_HANDLE_REAL)) { // drop flag at invisibiliy in bg target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis); } - target->UpdateObjectVisibility(); + + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModStealthDetect(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1589,8 +1592,9 @@ void AuraEffect::HandleModStealthDetect(AuraApplication const* aurApp, uint8 mod target->m_stealthDetect.AddValue(type, -GetAmount()); } - // call functions which may have additional effects after chainging state of unit - target->UpdateObjectVisibility(); + // call functions which may have additional effects after changing state of unit + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModStealth(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1624,13 +1628,15 @@ void AuraEffect::HandleModStealth(AuraApplication const* aurApp, uint8 mode, boo } } - // call functions which may have additional effects after chainging state of unit + // call functions which may have additional effects after changing state of unit if (apply && (mode & AURA_EFFECT_HANDLE_REAL)) { // drop flag at stealth in bg target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis); } - target->UpdateObjectVisibility(); + + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleModStealthLevel(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1646,8 +1652,9 @@ void AuraEffect::HandleModStealthLevel(AuraApplication const* aurApp, uint8 mode else target->m_stealth.AddValue(type, -GetAmount()); - // call functions which may have additional effects after chainging state of unit - target->UpdateObjectVisibility(); + // call functions which may have additional effects after changing state of unit + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleDetectAmore(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -2653,8 +2660,9 @@ void AuraEffect::HandleAuraModStalked(AuraApplication const* aurApp, uint8 mode, target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT); } - // call functions which may have additional effects after chainging state of unit - target->UpdateObjectVisibility(); + // call functions which may have additional effects after changing state of unit + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleAuraUntrackable(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -5168,8 +5176,9 @@ void AuraEffect::HandleAuraModFakeInebriation(AuraApplication const* aurApp, uin target->m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK); } - // call functions which may have additional effects after chainging state of unit - target->UpdateObjectVisibility(); + // call functions which may have additional effects after changing state of unit + if (target->IsInWorld()) + target->UpdateObjectVisibility(); } void AuraEffect::HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 mode, bool apply) const