From 06c6c8afc727bf27336790dba2d96980308a0a5f Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 24 Jan 2023 23:08:20 -0500 Subject: [PATCH] Core/Auras: Fixed possible iterator invalidation crashes caused by calling UpdateTargetMap inside loops iterating m_appliedAuras Port From (https://github.com/TrinityCore/TrinityCore/commit/a1b2b86427ce6be2205db0643ad00f546fc076e4) --- Source/Game/Entities/Unit/Unit.Spells.cs | 6 +++++- Source/Game/Spells/SpellInfo.cs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 08082c9f2..8b9cef7ba 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -2928,6 +2928,7 @@ namespace Game.Entities public void RemoveAurasWithMechanic(ulong mechanicMaskToRemove, AuraRemoveMode removeMode = AuraRemoveMode.Default, uint exceptSpellId = 0, bool withEffectMechanics = false) { + List aurasToUpdateTargets = new(); RemoveAppliedAuras(aurApp => { Aura aura = aurApp.GetBase(); @@ -2943,9 +2944,12 @@ namespace Game.Entities return true; // effect mechanic matches required mask for removal - don't remove, only update targets - aura.UpdateTargetMap(aura.GetCaster()); + aurasToUpdateTargets.Add(aura); return false; }, removeMode); + + foreach (Aura aura in aurasToUpdateTargets) + aura.UpdateTargetMap(aura.GetCaster()); } public void RemoveAurasDueToSpellBySteal(uint spellId, ObjectGuid casterGUID, WorldObject stealer, int stolenCharges = 1) { diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index b881b8f54..861f7ee5e 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -2439,15 +2439,19 @@ namespace Game.Spells target.RemoveAurasWithMechanic(mechanicImmunity, AuraRemoveMode.Default, Id); else { + List aurasToUpdateTargets = new(); target.RemoveAppliedAuras(aurApp => { Aura aura = aurApp.GetBase(); if ((aura.GetSpellInfo().GetAllEffectsMechanicMask() & mechanicImmunity) != 0) - aura.UpdateTargetMap(aura.GetCaster()); + aurasToUpdateTargets.Add(aura); // only update targets, don't remove anything return false; }); + + foreach (Aura aura in aurasToUpdateTargets) + aura.UpdateTargetMap(aura.GetCaster()); } } }