mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Fixes/3.3.5 aura infinite loop (#24631)
* 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
* Fix build warnings
* Fix more build warnings
(cherry picked from commit bd2d60c267)
This commit is contained in:
@@ -4035,7 +4035,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 (int counter = 0; !m_appliedAuras.empty() || !m_ownedAuras.empty(); counter++)
|
||||
{
|
||||
AuraApplicationMap::iterator aurAppIter;
|
||||
for (aurAppIter = m_appliedAuras.begin(); aurAppIter != m_appliedAuras.end();)
|
||||
@@ -4044,6 +4044,37 @@ 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. Details:" << "\n";
|
||||
sstr << GetDebugInfo() << "\n";
|
||||
|
||||
if (!m_appliedAuras.empty())
|
||||
{
|
||||
sstr << "m_appliedAuras:" << "\n";
|
||||
|
||||
for (std::pair<uint32 const, AuraApplication*>& auraAppPair : m_appliedAuras)
|
||||
sstr << auraAppPair.second->GetDebugInfo() << "\n";
|
||||
}
|
||||
|
||||
if (!m_ownedAuras.empty())
|
||||
{
|
||||
sstr << "m_ownedAuras:" << "\n";
|
||||
|
||||
for (std::pair<uint32 const, Aura*>& auraPair : m_ownedAuras)
|
||||
sstr << auraPair.second->GetDebugInfo() << "\n";
|
||||
}
|
||||
|
||||
TC_LOG_ERROR("entities.unit", "%s", sstr.str().c_str());
|
||||
ABORT_MSG("%s", sstr.str().c_str());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1406,8 +1406,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
|
||||
@@ -1457,13 +1458,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
|
||||
@@ -1487,8 +1490,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
|
||||
@@ -1522,13 +1526,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
|
||||
@@ -1544,8 +1550,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
|
||||
@@ -1604,7 +1611,7 @@ void AuraEffect::HandleSpiritOfRedemption(AuraApplication const* aurApp, uint8 m
|
||||
}
|
||||
// die at aura end
|
||||
else if (target->IsAlive())
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// call functions which may have additional effects after changing state of unit
|
||||
target->setDeathState(JUST_DIED);
|
||||
}
|
||||
|
||||
@@ -2164,7 +2171,7 @@ void AuraEffect::HandleModUnattackable(AuraApplication const* aurApp, uint8 mode
|
||||
else
|
||||
target->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE_2);
|
||||
|
||||
// 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))
|
||||
{
|
||||
if (target->GetMap()->IsDungeon())
|
||||
@@ -2261,7 +2268,7 @@ void AuraEffect::HandleAuraModSilence(AuraApplication const* aurApp, uint8 mode,
|
||||
{
|
||||
target->AddUnitFlag(UNIT_FLAG_SILENCED);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// call functions which may have additional effects after changing state of unit
|
||||
// Stop cast only spells vs PreventionType & SPELL_PREVENTION_TYPE_SILENCE
|
||||
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
|
||||
if (Spell* spell = target->GetCurrentSpell(CurrentSpellTypes(i)))
|
||||
@@ -2409,8 +2416,9 @@ void AuraEffect::HandleAuraModStalked(AuraApplication const* aurApp, uint8 mode,
|
||||
target->RemoveDynamicFlag(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
|
||||
@@ -5051,8 +5059,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
|
||||
|
||||
@@ -291,6 +291,14 @@ void AuraApplication::ClientUpdate(bool remove)
|
||||
_target->SendMessageToSet(update.Write(), true);
|
||||
}
|
||||
|
||||
std::string AuraApplication::GetDebugInfo() const
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "Base: " << (GetBase() ? GetBase()->GetDebugInfo() : "NULL")
|
||||
<< "\nTarget: " << (GetTarget() ? GetTarget()->GetDebugInfo() : "NULL");
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availableEffectMask, WorldObject* owner)
|
||||
{
|
||||
ASSERT_NODEBUGINFO(spellProto);
|
||||
|
||||
@@ -92,6 +92,8 @@ class TC_GAME_API AuraApplication
|
||||
bool IsNeedClientUpdate() const { return _needClientUpdate; }
|
||||
void BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo, bool remove);
|
||||
void ClientUpdate(bool remove = false);
|
||||
|
||||
std::string GetDebugInfo() const;
|
||||
};
|
||||
|
||||
// Structure representing database aura primary key fields
|
||||
|
||||
Reference in New Issue
Block a user