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
|
public enum SpellLinkedType
|
||||||
{
|
{
|
||||||
Cast = 0, // +: cast; -: remove
|
Cast = 0, // +: cast; -: remove
|
||||||
Hit = 1 * 200000,
|
Hit = 1,
|
||||||
Aura = 2 * 200000, // +: aura; -: immune
|
Aura = 2, // +: aura; -: immune
|
||||||
Remove = 0
|
Remove = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
//Spell targets used by SelectSpell
|
//Spell targets used by SelectSpell
|
||||||
|
|||||||
@@ -1238,7 +1238,7 @@ namespace Game.Spells
|
|||||||
// apply linked auras
|
// apply linked auras
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
var spellTriggered = Global.SpellMgr.GetSpellLinked((int)GetId() + (int)SpellLinkedType.Aura);
|
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Aura, GetId());
|
||||||
if (spellTriggered != null)
|
if (spellTriggered != null)
|
||||||
{
|
{
|
||||||
foreach (var spell in spellTriggered)
|
foreach (var spell in spellTriggered)
|
||||||
@@ -1253,7 +1253,7 @@ namespace Game.Spells
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// remove linked auras
|
// remove linked auras
|
||||||
var spellTriggered = Global.SpellMgr.GetSpellLinked(-(int)GetId());
|
var spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Remove, GetId());
|
||||||
if (spellTriggered != null)
|
if (spellTriggered != null)
|
||||||
{
|
{
|
||||||
foreach (var spell in spellTriggered)
|
foreach (var spell in spellTriggered)
|
||||||
@@ -1266,7 +1266,7 @@ namespace Game.Spells
|
|||||||
.SetOriginalCastId(GetCastId()));
|
.SetOriginalCastId(GetCastId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spellTriggered = Global.SpellMgr.GetSpellLinked((int)GetId() + (int)SpellLinkedType.Aura);
|
spellTriggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Aura, GetId());
|
||||||
if (spellTriggered != null)
|
if (spellTriggered != null)
|
||||||
{
|
{
|
||||||
foreach (var id in spellTriggered)
|
foreach (var id in spellTriggered)
|
||||||
@@ -1282,7 +1282,7 @@ namespace Game.Spells
|
|||||||
else if (apply)
|
else if (apply)
|
||||||
{
|
{
|
||||||
// modify stack amount of linked auras
|
// 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)
|
if (spellTriggered != null)
|
||||||
{
|
{
|
||||||
foreach (var id in spellTriggered)
|
foreach (var id in spellTriggered)
|
||||||
|
|||||||
@@ -2312,7 +2312,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
// trigger linked auras remove/apply
|
// trigger linked auras remove/apply
|
||||||
// @todo remove/cleanup this, as this table is not documented and people are doing stupid things with it
|
// @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)
|
if (spellTriggered != null)
|
||||||
{
|
{
|
||||||
foreach (var id in spellTriggered)
|
foreach (var id in spellTriggered)
|
||||||
@@ -2894,7 +2894,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
CallScriptAfterCastHandlers();
|
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)
|
if (spell_triggered != null)
|
||||||
{
|
{
|
||||||
foreach (var spellId in spell_triggered)
|
foreach (var spellId in spell_triggered)
|
||||||
|
|||||||
@@ -562,9 +562,9 @@ namespace Game.Entities
|
|||||||
return false;
|
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)
|
public MultiMap<uint, uint> GetPetLevelupSpellList(CreatureFamily petFamily)
|
||||||
@@ -1730,7 +1730,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
int trigger = result.Read<int>(0);
|
int trigger = result.Read<int>(0);
|
||||||
int effect = result.Read<int>(1);
|
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);
|
SpellInfo spellInfo = GetSpellInfo((uint)Math.Abs(trigger), Difficulty.None);
|
||||||
if (spellInfo == null)
|
if (spellInfo == null)
|
||||||
@@ -1754,14 +1754,32 @@ namespace Game.Entities
|
|||||||
continue;
|
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)
|
Log.outError(LogFilter.Sql, $"The spell trigger {trigger}, effect {effect} listed in `spell_linked_spell` has invalid link type {type}, skipped.");
|
||||||
trigger += 200000 * type;
|
continue;
|
||||||
else
|
|
||||||
trigger -= 200000 * type;
|
|
||||||
}
|
}
|
||||||
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;
|
++count;
|
||||||
} while (result.NextRow());
|
} while (result.NextRow());
|
||||||
@@ -4729,7 +4747,7 @@ namespace Game.Entities
|
|||||||
Dictionary<(uint id, Difficulty difficulty), SpellProcEntry> mSpellProcMap = new();
|
Dictionary<(uint id, Difficulty difficulty), SpellProcEntry> mSpellProcMap = new();
|
||||||
Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new();
|
Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new();
|
||||||
Dictionary<uint, PetAura> mSpellPetAuraMap = new();
|
Dictionary<uint, PetAura> mSpellPetAuraMap = new();
|
||||||
MultiMap<int, int> mSpellLinkedMap = new();
|
MultiMap<(SpellLinkedType, uint), int> mSpellLinkedMap = new();
|
||||||
Dictionary<uint, SpellEnchantProcEntry> mSpellEnchantProcEventMap = new();
|
Dictionary<uint, SpellEnchantProcEntry> mSpellEnchantProcEventMap = new();
|
||||||
MultiMap<uint, SpellArea> mSpellAreaMap = new();
|
MultiMap<uint, SpellArea> mSpellAreaMap = new();
|
||||||
MultiMap<uint, SpellArea> mSpellAreaForQuestMap = new();
|
MultiMap<uint, SpellArea> mSpellAreaForQuestMap = new();
|
||||||
|
|||||||
Reference in New Issue
Block a user