aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2020-05-16 09:06:03 +0000
committerGitHub <noreply@github.com>2020-05-16 11:06:03 +0200
commitbd2d60c2676a1d7e843a2a5673b8216bad0768c7 (patch)
treedbbd0a226df2e7166a86b71269bfe4fa9f0a2171 /src/server/game/Entities/Unit
parent8ad0ab362ee3e8ff5563d0ea3383d3d32969d27e (diff)
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
Diffstat (limited to 'src/server/game/Entities/Unit')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0001af2fc13..e2f509721ed 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4130,7 +4130,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();)
@@ -4139,6 +4139,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;
+ }
}
}