Core/Spells: Added additional validation to loading spell_linked_spell to prevent infinite loops
Port From (https://github.com/TrinityCore/TrinityCore/commit/badb55bfd97c16fecfb8cd73ba99e39ecb6b622d)
This commit is contained in:
@@ -39,10 +39,10 @@ namespace Framework.Constants
|
||||
|
||||
public enum SpellLinkedType
|
||||
{
|
||||
Cast = 0, // +: cast; -: remove
|
||||
Hit = 1 * 200000,
|
||||
Aura = 2 * 200000, // +: aura; -: immune
|
||||
Remove = 0
|
||||
Cast = 0, // +: cast; -: remove
|
||||
Hit = 1,
|
||||
Aura = 2, // +: aura; -: immune
|
||||
Remove = 3
|
||||
}
|
||||
|
||||
//Spell targets used by SelectSpell
|
||||
|
||||
@@ -1238,7 +1238,7 @@ namespace Game.Spells
|
||||
// apply linked auras
|
||||
if (apply)
|
||||
{
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked((int)GetId() + (int)SpellLinkedType.Aura);
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Aura, GetId());
|
||||
if (spellTriggered != null)
|
||||
{
|
||||
foreach (var spell in spellTriggered)
|
||||
@@ -1253,7 +1253,7 @@ namespace Game.Spells
|
||||
else
|
||||
{
|
||||
// remove linked auras
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(-(int)GetId());
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Remove, GetId());
|
||||
if (spellTriggered != null)
|
||||
{
|
||||
foreach (var spell in spellTriggered)
|
||||
@@ -1266,7 +1266,7 @@ namespace Game.Spells
|
||||
.SetOriginalCastId(GetCastId()));
|
||||
}
|
||||
}
|
||||
spellTriggered = Global.SpellMgr.GetSpellLinked((int)GetId() + (int)SpellLinkedType.Aura);
|
||||
spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Aura, GetId());
|
||||
if (spellTriggered != null)
|
||||
{
|
||||
foreach (var id in spellTriggered)
|
||||
@@ -1282,7 +1282,7 @@ namespace Game.Spells
|
||||
else if (apply)
|
||||
{
|
||||
// modify stack amount of linked auras
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked((int)GetId() + (int)SpellLinkedType.Aura);
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Aura, GetId());
|
||||
if (spellTriggered != null)
|
||||
{
|
||||
foreach (var id in spellTriggered)
|
||||
|
||||
@@ -2312,7 +2312,7 @@ namespace Game.Spells
|
||||
|
||||
// trigger linked auras remove/apply
|
||||
// @todo remove/cleanup this, as this table is not documented and people are doing stupid things with it
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked((int)m_spellInfo.Id + (int)SpellLinkedType.Hit);
|
||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Hit, m_spellInfo.Id);
|
||||
if (spellTriggered != null)
|
||||
{
|
||||
foreach (var id in spellTriggered)
|
||||
@@ -2894,7 +2894,7 @@ namespace Game.Spells
|
||||
|
||||
CallScriptAfterCastHandlers();
|
||||
|
||||
var spell_triggered = Global.SpellMgr.GetSpellLinked((int)m_spellInfo.Id);
|
||||
var spell_triggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Cast, m_spellInfo.Id);
|
||||
if (spell_triggered != null)
|
||||
{
|
||||
foreach (var spellId in spell_triggered)
|
||||
|
||||
@@ -562,9 +562,9 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<int> GetSpellLinked(int spell_id)
|
||||
public List<int> GetSpellLinked(SpellLinkedType type, uint spellId)
|
||||
{
|
||||
return mSpellLinkedMap.LookupByKey(spell_id);
|
||||
return mSpellLinkedMap.LookupByKey((type, spellId));
|
||||
}
|
||||
|
||||
public MultiMap<uint, uint> GetPetLevelupSpellList(CreatureFamily petFamily)
|
||||
@@ -1730,7 +1730,7 @@ namespace Game.Entities
|
||||
{
|
||||
int trigger = result.Read<int>(0);
|
||||
int effect = result.Read<int>(1);
|
||||
int type = result.Read<int>(2);
|
||||
SpellLinkedType type = (SpellLinkedType)result.Read<byte>(2);
|
||||
|
||||
SpellInfo spellInfo = GetSpellInfo((uint)Math.Abs(trigger), Difficulty.None);
|
||||
if (spellInfo == null)
|
||||
@@ -1754,14 +1754,32 @@ namespace Game.Entities
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type != 0) //we will find a better way when more types are needed
|
||||
if (type < SpellLinkedType.Cast || type > SpellLinkedType.Remove)
|
||||
{
|
||||
if (trigger > 0)
|
||||
trigger += 200000 * type;
|
||||
else
|
||||
trigger -= 200000 * type;
|
||||
Log.outError(LogFilter.Sql, $"The spell trigger {trigger}, effect {effect} listed in `spell_linked_spell` has invalid link type {type}, skipped.");
|
||||
continue;
|
||||
}
|
||||
mSpellLinkedMap.Add(trigger, effect);
|
||||
|
||||
if (trigger < 0)
|
||||
{
|
||||
if (type != SpellLinkedType.Cast)
|
||||
Log.outError(LogFilter.Sql, $"The spell trigger {trigger} listed in `spell_linked_spell` has invalid link type {type}, changed to 0.");
|
||||
|
||||
trigger = -trigger;
|
||||
type = SpellLinkedType.Remove;
|
||||
}
|
||||
|
||||
|
||||
if (type != SpellLinkedType.Aura)
|
||||
{
|
||||
if (trigger == effect)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"The spell trigger {trigger}, effect {effect} listed in `spell_linked_spell` triggers itself (infinite loop), skipped.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
mSpellLinkedMap.Add((type, (uint)trigger), effect);
|
||||
|
||||
++count;
|
||||
} while (result.NextRow());
|
||||
@@ -4729,7 +4747,7 @@ namespace Game.Entities
|
||||
Dictionary<(uint id, Difficulty difficulty), SpellProcEntry> mSpellProcMap = new();
|
||||
Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new();
|
||||
Dictionary<uint, PetAura> mSpellPetAuraMap = new();
|
||||
MultiMap<int, int> mSpellLinkedMap = new();
|
||||
MultiMap<(SpellLinkedType, uint), int> mSpellLinkedMap = new();
|
||||
Dictionary<uint, SpellEnchantProcEntry> mSpellEnchantProcEventMap = new();
|
||||
MultiMap<uint, SpellArea> mSpellAreaMap = new();
|
||||
MultiMap<uint, SpellArea> mSpellAreaForQuestMap = new();
|
||||
|
||||
Reference in New Issue
Block a user