Core/Spells: Protect against stack overflows in spell override handling

Port From (https://github.com/TrinityCore/TrinityCore/commit/723e638a84d2aebe8a41fc39ba94f1a04138797e)
This commit is contained in:
Hondacrx
2024-11-10 14:16:58 -05:00
parent b34ef7c6f7
commit daea912bdb
2 changed files with 36 additions and 10 deletions
+10 -6
View File
@@ -274,20 +274,23 @@ namespace Game.Entities
return false; return false;
} }
public override SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag) public override SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag, GetCastSpellInfoContext context)
{ {
var overrides = m_overrideSpells.LookupByKey(spellInfo.Id); var overrides = m_overrideSpells.LookupByKey(spellInfo.Id);
if (!overrides.Empty()) if (!overrides.Empty())
{ {
foreach (uint spellId in overrides) foreach (uint spellId in overrides)
{ {
SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID()); if (context.AddSpell(spellId))
if (newInfo != null) {
return GetCastSpellInfo(newInfo, triggerFlag); SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID());
if (newInfo != null)
return GetCastSpellInfo(newInfo, triggerFlag, context);
}
} }
} }
return base.GetCastSpellInfo(spellInfo, triggerFlag); return base.GetCastSpellInfo(spellInfo, triggerFlag, context);
} }
public void SetOverrideSpellsId(uint overrideSpellsId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideSpellsID), overrideSpellsId); } public void SetOverrideSpellsId(uint overrideSpellsId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideSpellsID), overrideSpellsId); }
@@ -3879,7 +3882,8 @@ namespace Game.Entities
} }
// Check possible spell cast overrides // Check possible spell cast overrides
spellInfo = castingUnit.GetCastSpellInfo(spellInfo, triggerFlag); GetCastSpellInfoContext overrideContext = new();
spellInfo = castingUnit.GetCastSpellInfo(spellInfo, triggerFlag, overrideContext);
if (spellInfo.IsPassive()) if (spellInfo.IsPassive())
{ {
CancelPendingCastRequest(); CancelPendingCastRequest();
+26 -4
View File
@@ -944,14 +944,14 @@ namespace Game.Entities
spell.Finish(result); spell.Finish(result);
} }
public virtual SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag) public virtual SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag, GetCastSpellInfoContext context)
{ {
SpellInfo findMatchingAuraEffectIn(AuraType type) SpellInfo findMatchingAuraEffectIn(AuraType type)
{ {
foreach (AuraEffect auraEffect in GetAuraEffectsByType(type)) foreach (AuraEffect auraEffect in GetAuraEffectsByType(type))
{ {
bool matches = auraEffect.GetMiscValue() != 0 ? auraEffect.GetMiscValue() == spellInfo.Id : auraEffect.IsAffectingSpell(spellInfo); bool matches = auraEffect.GetMiscValue() != 0 ? auraEffect.GetMiscValue() == spellInfo.Id : auraEffect.IsAffectingSpell(spellInfo);
if (matches) if (matches && context.AddSpell((uint)auraEffect.GetAmount()))
{ {
SpellInfo info = Global.SpellMgr.GetSpellInfo((uint)auraEffect.GetAmount(), GetMap().GetDifficultyID()); SpellInfo info = Global.SpellMgr.GetSpellInfo((uint)auraEffect.GetAmount(), GetMap().GetDifficultyID());
if (info != null) if (info != null)
@@ -979,14 +979,14 @@ namespace Game.Entities
if (newInfo != null) if (newInfo != null)
{ {
triggerFlag &= ~TriggerCastFlags.IgnoreCastTime; triggerFlag &= ~TriggerCastFlags.IgnoreCastTime;
return GetCastSpellInfo(newInfo, triggerFlag); return GetCastSpellInfo(newInfo, triggerFlag, context);
} }
newInfo = findMatchingAuraEffectIn(AuraType.OverrideActionbarSpellsTriggered); newInfo = findMatchingAuraEffectIn(AuraType.OverrideActionbarSpellsTriggered);
if (newInfo != null) if (newInfo != null)
{ {
triggerFlag |= TriggerCastFlags.IgnoreCastTime; triggerFlag |= TriggerCastFlags.IgnoreCastTime;
return GetCastSpellInfo(newInfo, triggerFlag); return GetCastSpellInfo(newInfo, triggerFlag, context);
} }
return spellInfo; return spellInfo;
@@ -4602,4 +4602,26 @@ namespace Game.Entities
public void SetVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Add(aurApp); } public void SetVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Add(aurApp); }
public void RemoveVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Remove(aurApp); } public void RemoveVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Remove(aurApp); }
} }
public class GetCastSpellInfoContext
{
uint[] VisitedSpells = new uint[5];
public bool AddSpell(uint spellId)
{
if (VisitedSpells.Contains(spellId))
return false; // already exists
for (int i = 0; i < VisitedSpells.Length; ++i)
{
if (VisitedSpells[i] != 0u)
continue;
VisitedSpells[i] = spellId;
return true;
}
return false;
}
}
} }