using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Decal.Interop.Core; using Decal.Interop.SpellFilter; namespace Decal.SpellFilter { [ComVisible(true)] [Guid("C2D43735-BE7E-4829-AF73-F2E7E820EB16")] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(_ISpellsEvents))] [ProgId("SpellFilter.Spells")] public class SpellsImpl : ISpells, IDecalService { private readonly Dictionary _spellsById = new Dictionary(); private readonly Dictionary _spellsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _componentsById = new Dictionary(); private readonly Dictionary _componentsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly HashSet _knownSpells = new HashSet(); private int _lastSpellId; private string _server = string.Empty; // COM events public event _ISpellsEvents_LoginEventHandler Login; public event _ISpellsEvents_Spellbook_AddEventHandler Spellbook_Add; public event _ISpellsEvents_Spellbook_DeleteEventHandler Spellbook_Delete; // ISpells parameterized properties - accessed via IDispatch public Spell SpellByID => null; public Spell SpellByName => null; public bool SpellKnown => false; public int LastSpellID => _lastSpellId; public string Server => _server; public Component ComponentByID => null; public Component ComponentByName => null; // Internal accessors for parameterized property dispatch internal SpellImpl GetSpellByID(int id) { _spellsById.TryGetValue(id, out var spell); return spell; } internal SpellImpl GetSpellByName(string name) { _spellsByName.TryGetValue(name, out var spell); return spell; } internal bool IsSpellKnown(int id) { return _knownSpells.Contains(id); } internal ComponentImpl GetComponentByID(int id) { _componentsById.TryGetValue(id, out var comp); return comp; } internal ComponentImpl GetComponentByName(string name) { _componentsByName.TryGetValue(name, out var comp); return comp; } // Registration methods internal void RegisterSpell(SpellImpl spell) { _spellsById[spell.SpellID] = spell; if (!string.IsNullOrEmpty(spell.Name)) _spellsByName[spell.Name] = spell; if (spell.SpellID > _lastSpellId) _lastSpellId = spell.SpellID; } internal void RegisterComponent(ComponentImpl component) { _componentsById[component.ComponentID] = component; if (!string.IsNullOrEmpty(component.Name)) _componentsByName[component.Name] = component; } internal void OnLogin(int characterId) { _knownSpells.Clear(); Login?.Invoke(characterId); } internal void OnSpellbookAdd(int spellId) { _knownSpells.Add(spellId); Spellbook_Add?.Invoke(spellId); } internal void OnSpellbookDelete(int spellId) { _knownSpells.Remove(spellId); Spellbook_Delete?.Invoke(spellId); } // IDecalService public void Initialize(DecalCore pDecal) { // Spell data would be loaded from the portal.dat via the DatService // The spell table is at file ID 0x0E00000E in portal.dat } public void BeforePlugins() { } public void AfterPlugins() { } public void Terminate() { _spellsById.Clear(); _spellsByName.Clear(); _componentsById.Clear(); _componentsByName.Clear(); _knownSpells.Clear(); } } }