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
This commit is contained in:
Giacomo Pozzoni authored and Ovahlord committed 2022-09-12 09:15:28 +02:00
1 parent eb181ca99f
commit 2b2237b7bc
2 files changed
+38 -15

No files matched your search

+15 -1
View File
@@ -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;
}
}
}
@@ -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