From 5b43e0b1e04cda7d327b6d74a7d7f1f39547558b Mon Sep 17 00:00:00 2001 From: Warpten Date: Fri, 5 Aug 2016 02:59:44 +0200 Subject: [PATCH] Reduce startup time (10 times faster on my i3-2310M). --- .gitignore | 246 ++++++++- SpellWork/DBC/DB2Reader.cs | 263 --------- SpellWork/DBC/DBC.cs | 512 +++++++++--------- SpellWork/DBC/DataStoreFileNameAttribute.cs | 15 - SpellWork/DBC/Structures/ItemSparseEntry.cs | 5 +- .../DBC/Structures/SpellEffectScalingEntry.cs | 2 +- SpellWork/DBC/Structures/SpellEntry.cs | 2 +- SpellWork/Forms/FormMain.cs | 4 +- SpellWork/Spell/ProcInfo.cs | 4 +- SpellWork/Spell/SpellInfo.cs | 16 +- SpellWork/Spell/SpellInfoHelper.cs | 4 +- SpellWork/SpellWork.csproj | 11 +- SpellWork/packages.config | 5 + 13 files changed, 546 insertions(+), 543 deletions(-) delete mode 100644 SpellWork/DBC/DB2Reader.cs delete mode 100644 SpellWork/DBC/DataStoreFileNameAttribute.cs create mode 100644 SpellWork/packages.config diff --git a/.gitignore b/.gitignore index 8d5f41cb..3a2238d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,245 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +# User-specific files *.suo *.user -SpellWork/obj/* -*.orig -*.rej -*.patch +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Xx]64/ +[Xx]86/ +[Bb]uild/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj *.log -_ReSharper* +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml + +# TODO: Un-comment the next line if you do not want to checkin +# your web deploy settings because they may include unencrypted +# passwords +#*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# LightSwitch generated files +GeneratedArtifacts/ +ModelManifest.xml + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ \ No newline at end of file diff --git a/SpellWork/DBC/DB2Reader.cs b/SpellWork/DBC/DB2Reader.cs deleted file mode 100644 index eb746aed..00000000 --- a/SpellWork/DBC/DB2Reader.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Text; - -namespace SpellWork.DBC -{ - public class DB2Reader : Dictionary where T : class, new() - { - public int RecordCount { get; private set; } - public int FieldCount { get; private set; } - public int Hash { get; private set; } - public int Build { get; private set; } - public bool HasOffsetMap { get; private set; } - public bool HasInlineStrings => HasOffsetMap; - public bool HasNonInlineIDs { get; private set; } - public int RecordSize { get; private set; } - - private Dictionary StringTable = new Dictionary(); - private FieldStructure[] FieldStructures; - - public string Filename { get; private set; } - - public T this[uint key] => this[(int) key]; - public bool ContainsKey(uint key) => ContainsKey((int) key); - - private T BuildEntry(byte[] byteRow) - { - var structure = new T(); - - var propertyIndex = 0; - try - { - foreach (var prop in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public)) - { - if (propertyIndex >= FieldCount) - return structure; - - object value; - if (prop.FieldType.IsArray) - value = BuildArrayField(byteRow, propertyIndex, prop); - else - value = BuildSimpleField(byteRow, propertyIndex, prop.FieldType, 0); - - ++propertyIndex; - prop.SetValue(structure, value); - } - } - catch (Exception e) - { - Console.WriteLine($"Possible error when loading record. {e}"); - return null; - } - - return structure; - } - - private object BuildArrayField(byte[] byteRow, int propertyIndex, FieldInfo prop) - { - var fieldStructure = FieldStructures[propertyIndex]; - var fieldPosition = (int)fieldStructure.Position; - var positionOffset = 0; - var nextMarker = propertyIndex + 1 == FieldCount - ? RecordSize - : FieldStructures[propertyIndex + 1].Position; - var arraySize = (nextMarker - fieldPosition) / fieldStructure.ByteSize; - - var elementType = prop.FieldType.GetElementType(); - var instanceValue = Array.CreateInstance(elementType, arraySize); - for (var i = 0; i < arraySize; ++i) - { - instanceValue.SetValue(BuildSimpleField(byteRow, propertyIndex, elementType, positionOffset), i); - positionOffset += fieldStructure.ByteSize; - } - - return instanceValue; - } - - private object BuildSimpleField(byte[] byteRow, int propertyIndex, Type fieldType, int positionOffset) - { - var fieldStructure = FieldStructures[propertyIndex]; - var fieldPosition = (int)fieldStructure.Position + positionOffset; - object instanceValue = null; - switch (Type.GetTypeCode(fieldType)) - { - case TypeCode.SByte: - instanceValue = (sbyte)byteRow[fieldPosition]; - break; - case TypeCode.Byte: - instanceValue = byteRow[fieldPosition]; - break; - case TypeCode.Int16: - instanceValue = BitConverter.ToInt16(byteRow, fieldPosition); - break; - case TypeCode.UInt16: - instanceValue = BitConverter.ToUInt16(byteRow, fieldPosition); - break; - case TypeCode.Int32: - { - var elementVal = 0; - for (var k = 0; k < fieldStructure.ByteSize; ++k) - elementVal |= byteRow[fieldPosition + k] << (8 * k); - instanceValue = elementVal; - break; - } - case TypeCode.UInt32: - { - var elementVal = 0u; - for (var k = 0; k < fieldStructure.ByteSize; ++k) - elementVal |= (uint)(byteRow[fieldPosition + k] << (8 * k)); - instanceValue = elementVal; - break; - } - case TypeCode.Int64: - instanceValue = BitConverter.ToInt64(byteRow, fieldPosition); - break; - case TypeCode.UInt64: - instanceValue = BitConverter.ToUInt64(byteRow, fieldPosition); - break; - case TypeCode.Single: - instanceValue = BitConverter.ToSingle(byteRow, fieldPosition); - break; - case TypeCode.String: - { - if (HasInlineStrings) - { - //! TODO 7.x Implement, only Item-Sparse has this - instanceValue = string.Empty; - } - else - { - var stringOffset = BitConverter.ToInt32(byteRow, fieldPosition); - if (StringTable.ContainsKey(stringOffset)) - instanceValue = StringTable[stringOffset]; - else - instanceValue = string.Empty; - } - break; - } - } - - return instanceValue; - } - - private class FieldStructure - { - // Size in bits: (32 - Size) / 8 - public ushort Size; - // Position of the field within the record, relative to the start of the record. - public ushort Position; - - public int ByteSize => 4 - Size / 8; - } - - public DB2Reader(string fileName) - { - Open(fileName); - } - - public DB2Reader() { } - - public void Open(string fileName) - { - Filename = fileName; - using (var reader = new BinaryReader(File.Open(fileName, FileMode.Open))) - Read(reader); - } - - public new void Clear() - { - base.Clear(); - StringTable.Clear(); - } - - private void Read(BinaryReader reader) - { - reader.ReadInt32(); // Signature - RecordCount = reader.ReadInt32(); - FieldCount = reader.ReadInt32(); // Arrays now count as 1 - RecordSize = reader.ReadInt32(); - var stringBlockSize = reader.ReadInt32(); - Hash = reader.ReadInt32(); - Build = reader.ReadInt32(); - var minId = reader.ReadInt32(); - var maxId = reader.ReadInt32(); - reader.ReadInt32(); // Locale - var copyTableSize = reader.ReadInt32(); - var flags = reader.ReadInt16(); - var indexField = reader.ReadInt16(); - HasOffsetMap = (flags & 0x01) != 0; - HasNonInlineIDs = (flags & 0x04) != 0; - - // var offsetMap = new Dictionary(maxId - minId + 1); - var nonInlineIDs = new int[RecordCount]; - var copyTable = new Dictionary(copyTableSize / 8); - - FieldStructures = new FieldStructure[FieldCount]; - for (var i = 0; i < FieldCount; ++i) - { - // ReSharper disable once UseObjectOrCollectionInitializer - FieldStructures[i] = new FieldStructure(); - FieldStructures[i].Size = reader.ReadUInt16(); - FieldStructures[i].Position = reader.ReadUInt16(); - } - - var recordOffset = reader.BaseStream.Position; - reader.BaseStream.Position += RecordSize * RecordCount; - - if (!HasOffsetMap) - { - var stringTable = reader.ReadBytes(stringBlockSize); - var stringLength = 0; - for (var i = 0; i < stringBlockSize; ++i) - { - if (stringTable[i] == '\0') - { - StringTable[i - stringLength] = Encoding.UTF8.GetString(stringTable, i - stringLength, - stringLength); - stringLength = 0; - continue; - } - ++stringLength; - } - } - else //! TODO: Read offset map ?!? - reader.BaseStream.Position += (4 + 2) * (maxId - minId + 1); - // for (var i = 0; i < maxId - minId + 1; ++i) - // offsetMap[reader.ReadInt32()] = reader.ReadInt16(); - - if (HasNonInlineIDs) - for (var i = 0; i < RecordCount; ++i) - nonInlineIDs[i] = reader.ReadInt32(); - - if (copyTableSize > 0) - for (var i = 0; i < copyTableSize / 8; ++i) - copyTable[reader.ReadInt32()] = reader.ReadInt32(); - - reader.BaseStream.Position = recordOffset; - - // Populate data storage now. - for (var i = 0; i < RecordCount; ++i) - { - byte[] rowBytes = reader.ReadBytes(RecordSize); - int id; - if (!HasNonInlineIDs) - { - var idBytes = new byte[4]; - Array.Copy(rowBytes, FieldStructures[indexField].Position, idBytes, 0, FieldStructures[indexField].ByteSize); - id = BitConverter.ToInt32(idBytes, 0); - } - else - id = nonInlineIDs[i]; - - Add(id, BuildEntry(rowBytes)); - } - - // Populate copy table - foreach (var kv in copyTable) - Add(kv.Key, this[kv.Value]); - } - } -} diff --git a/SpellWork/DBC/DBC.cs b/SpellWork/DBC/DBC.cs index e085d659..68b85d74 100644 --- a/SpellWork/DBC/DBC.cs +++ b/SpellWork/DBC/DBC.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.IO; using System.Reflection; +using DBFilesClient.NET; +using System.Threading.Tasks; namespace SpellWork.DBC { @@ -17,312 +19,338 @@ public static class DBC public const string Version = "SpellWork 7.0.3 (21796)"; public const uint MaxLevel = 110; - public static readonly DB2Reader AreaGroupMember = new DB2Reader(); - public static DB2Reader AreaTable = new DB2Reader(); - public static DB2Reader OverrideSpellData = new DB2Reader(); - public static DB2Reader ScreenEffect = new DB2Reader(); - public static DB2Reader Spell = new DB2Reader(); - private static DB2Reader SpellAuraOptions = new DB2Reader(); - private static DB2Reader SpellAuraRestrictions = new DB2Reader(); - private static DB2Reader SpellCastingRequirements = new DB2Reader(); - public static DB2Reader SpellCastTimes = new DB2Reader(); - private static DB2Reader SpellCategories = new DB2Reader(); - private static DB2Reader SpellClassOptions = new DB2Reader(); - private static DB2Reader SpellCooldowns = new DB2Reader(); - public static DB2Reader SpellDescriptionVariables = new DB2Reader(); - public static DB2Reader SpellDuration = new DB2Reader(); - private static DB2Reader SpellEffect = new DB2Reader(); - public static DB2Reader SpellEffectScaling = new DB2Reader(); - private static DB2Reader SpellMisc = new DB2Reader(); - private static DB2Reader SpellEquippedItems = new DB2Reader(); - private static DB2Reader SpellInterrupts = new DB2Reader(); - private static DB2Reader SpellLevels = new DB2Reader(); - public static DB2Reader SpellPower = new DB2Reader(); - public static DB2Reader SpellRadius = new DB2Reader(); - public static DB2Reader SpellRange = new DB2Reader(); - private static DB2Reader SpellScaling = new DB2Reader(); - private static DB2Reader SpellShapeshift = new DB2Reader(); - private static DB2Reader SpellTargetRestrictions = new DB2Reader(); - private static DB2Reader SpellTotems = new DB2Reader(); - private static DB2Reader SpellXSpellVisual = new DB2Reader(); - public static DB2Reader RandPropPoints = new DB2Reader(); - private static DB2Reader SpellProcsPerMinute = new DB2Reader(); - - public static DB2Reader Item = new DB2Reader(); - - private static DB2Reader SpellReagents = new DB2Reader(); - public static DB2Reader SpellMissile = new DB2Reader(); - // public static DB2Reader SpellMissileMotion = new DB2Reader(); - // public static DB2Reader SpellVisual = new DB2Reader(); - - //[DataStoreFileName("Item-sparse")] - //public static DB2Reader ItemSparse = new DB2Reader(); - - public static Dictionary SkilllLineAbilityStore = new Dictionary(); - public static Dictionary SkilllLineStore = new Dictionary(); + // ReSharper disable MemberCanBePrivate.Global + public static Storage AreaGroupMember { get; set; } + public static Storage AreaTable { get; set; } + public static Storage OverrideSpellData { get; set; } + public static Storage ScreenEffect { get; set; } + public static Storage Spell { get; set; } + public static Storage SpellAuraOptions { get; set; } + public static Storage SpellAuraRestrictions { get; set; } + public static Storage SpellCastingRequirements { get; set; } + public static Storage SpellCastTimes { get; set; } + public static Storage SpellCategories { get; set; } + public static Storage SpellClassOptions { get; set; } + public static Storage SpellCooldowns { get; set; } + public static Storage SpellDescriptionVariables { get; set; } + public static Storage SpellDuration { get; set; } + public static Storage SpellEffect { get; set; } + public static Storage SpellEffectScaling { get; set; } + public static Storage SpellMisc { get; set; } + public static Storage SpellEquippedItems { get; set; } + public static Storage SpellInterrupts { get; set; } + public static Storage SpellLevels { get; set; } + public static Storage SpellPower { get; set; } + public static Storage SpellRadius { get; set; } + public static Storage SpellRange { get; set; } + public static Storage SpellScaling { get; set; } + public static Storage SpellShapeshift { get; set; } + public static Storage SpellTargetRestrictions { get; set; } + public static Storage SpellTotems { get; set; } + public static Storage SpellXSpellVisual { get; set; } + public static Storage RandPropPoints { get; set; } + public static Storage SpellProcsPerMinute { get; set; } + + public static Storage SkillLineAbility { get; set; } + public static Storage SkillLine { get; set; } + + public static Storage Item { get; set; } + public static Storage ItemSparse { get; set; } + + public static Storage SpellReagents { get; set; } + public static Storage SpellMissile { get; set; } + // ReSharper restore MemberCanBePrivate.Global + + // public static Storage SpellMissileMotion { get; public set; } + // public static Storage SpellVisual { get; public set; } private static readonly IDictionary SpellInfoLoadData = new ConcurrentDictionary(); - public static readonly IDictionary> SpellTriggerStore = new Dictionary>(); + public static readonly IDictionary> SpellTriggerStore = new Dictionary>(); - public static void Load() + public static async void Load() { - foreach (var dbc in typeof(DBC).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) - { - if (!dbc.FieldType.IsGenericType || dbc.FieldType.GetGenericTypeDefinition() != typeof(DB2Reader<>)) - continue; - - var name = dbc.Name; - - var attributes = dbc.GetCustomAttributes(typeof(DataStoreFileNameAttribute), false) as DataStoreFileNameAttribute[]; - if (attributes != null && attributes.Length == 1) - name = attributes[0].FileName; - - try - { - dbc.FieldType.GetMethod("Open", new [] { typeof(string) }).Invoke(dbc.GetValue(null), new object[] { $@"{Settings.Default.DbcPath}\{name}.db2" }); - } - catch (DirectoryNotFoundException) - { - } - catch (TargetInvocationException tie) + Parallel.ForEach( + typeof (DBC).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), dbc => { - if (tie.InnerException is ArgumentException) - throw new ArgumentException($"Failed to load {dbc.Name}.db2: {tie.InnerException.Message}"); - - throw; - } - } - - // Open DBCs locally - // This is faster because it avoids a truckload of reflection code later (ProcInfo, i'm looking at you) - var skillLineAbility = new DB2Reader($@"{Settings.Default.DbcPath}\SkillLineAbility.db2"); - var skillLine = new DB2Reader($@"{Settings.Default.DbcPath}\SkillLine.db2"); - foreach (var kvp in skillLineAbility) - SkilllLineAbilityStore[kvp.Key] = kvp.Value; - - foreach (var kvp in skillLine) - SkilllLineStore[kvp.Key] = kvp.Value; - - skillLine.Clear(); - skillLineAbility.Clear(); + if (!dbc.PropertyType.IsGenericType || + dbc.PropertyType.GetGenericTypeDefinition() != typeof (Storage<>)) + return; + + var name = dbc.Name; + + var fileNameAttr = + dbc.PropertyType.GetGenericArguments()[0].GetCustomAttribute(); + if (fileNameAttr != null) + name = fileNameAttr.FileName; + + try + { + dbc.SetValue(dbc.GetValue(null), + Activator.CreateInstance(dbc.PropertyType, $@"{Settings.Default.DbcPath}\{name}.db2")); + } + catch (DirectoryNotFoundException) + { + } + catch (TargetInvocationException tie) + { + if (tie.InnerException is ArgumentException) + throw new ArgumentException($"Failed to load {name}.db2: {tie.InnerException.Message}"); + throw; + } + }); foreach (var spell in Spell) - SpellInfoLoadData[spell.Value.ID] = new SpellInfoLoadData() { Spell = spell.Value }; + SpellInfoLoadData[spell.Value.ID] = new SpellInfoLoadData {Spell = spell.Value}; - foreach (var effect in SpellInfoLoadData) + await Task.WhenAll(Task.Run(() => { - if (!SpellMisc.ContainsKey(effect.Value.Spell.MiscID)) + foreach (var effect in SpellInfoLoadData) { - Console.WriteLine($"Spell {effect.Key} is referencing unknown SpellMisc {effect.Value.Spell.MiscID}, ignoring!"); - continue; + if (!SpellMisc.ContainsKey(effect.Value.Spell.MiscID)) + { + Console.WriteLine( + $"Spell {effect.Key} is referencing unknown SpellMisc {effect.Value.Spell.MiscID}, ignoring!"); + continue; + } + + effect.Value.Misc = SpellMisc[effect.Value.Spell.MiscID]; } - - effect.Value.Misc = SpellMisc[(int) effect.Value.Spell.MiscID]; - } - - foreach (var effect in SpellEffect) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellEffect) { - Console.WriteLine($"Spell effect {effect.Value.ID} is referencing unknown spell {effect.Value.SpellID}, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"Spell effect {effect.Value.ID} is referencing unknown spell {effect.Value.SpellID}, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Effects.Add(effect.Value); + var triggerid = effect.Value.EffectTriggerSpell; + if (triggerid != 0) + { + if (SpellTriggerStore.ContainsKey((int) triggerid)) + SpellTriggerStore[(int) triggerid].Add((int) effect.Value.SpellID); + else + SpellTriggerStore.Add((int) triggerid, new SortedSet {(int) effect.Value.SpellID}); + } } - - SpellInfoLoadData[effect.Value.SpellID].Effects.Add(effect.Value); - var triggerid = effect.Value.EffectTriggerSpell; - if (triggerid != 0) - { - if (SpellTriggerStore.ContainsKey(triggerid)) - SpellTriggerStore[triggerid].Add(effect.Value.SpellID); - else - SpellTriggerStore.Add(triggerid, new SortedSet { effect.Value.SpellID }); - } - } - - foreach (var effect in SpellTargetRestrictions) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellTargetRestrictions) { - Console.WriteLine($"SpellTargetRestrictions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellTargetRestrictions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].TargetRestrictions.Add(effect.Value); } - - SpellInfoLoadData[effect.Value.SpellID].TargetRestrictions.Add(effect.Value); - } - - foreach (var effect in SpellXSpellVisual) + }), Task.Run(() => { - if (effect.Value.DifficultyID != 0 || effect.Value.PlayerConditionID != 0) - continue; - - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellXSpellVisual) { - Console.WriteLine($"SpellXSpellVisual: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; - } + if (effect.Value.DifficultyID != 0 || effect.Value.PlayerConditionID != 0) + continue; - SpellInfoLoadData[effect.Value.SpellID].SpellXSpellVisual = effect.Value; - } + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellXSpellVisual: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } - foreach (var effect in SpellScaling) + SpellInfoLoadData[effect.Value.SpellID].SpellXSpellVisual = effect.Value; + } + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellScaling) { - Console.WriteLine($"SpellScaling: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellScaling: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Scaling = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Scaling = effect.Value; - } - - foreach (var effect in SpellAuraOptions) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellAuraOptions) { - Console.WriteLine($"SpellAuraOptions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellAuraOptions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].AuraOptions = effect.Value; + if (effect.Value.SpellProcsPerMinuteID != 0) + SpellInfoLoadData[effect.Value.SpellID].ProcsPerMinute = + SpellProcsPerMinute[effect.Value.SpellProcsPerMinuteID]; } - - SpellInfoLoadData[effect.Value.SpellID].AuraOptions = effect.Value; - if (effect.Value.SpellProcsPerMinuteID != 0) - SpellInfoLoadData[effect.Value.SpellID].ProcsPerMinute = SpellProcsPerMinute[effect.Value.SpellProcsPerMinuteID]; - } - - foreach (var effect in SpellAuraRestrictions) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellAuraRestrictions) { - Console.WriteLine($"SpellAuraRestrictions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellAuraRestrictions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].AuraRestrictions = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].AuraRestrictions = effect.Value; - } - - foreach (var effect in SpellCategories) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellCategories) { - Console.WriteLine($"SpellCategories: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellCategories: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Categories = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Categories = effect.Value; - } - - foreach (var effect in SpellCastingRequirements) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellCastingRequirements) { - Console.WriteLine($"SpellCastingRequirements: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - return; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellCastingRequirements: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + return; + } + + SpellInfoLoadData[effect.Value.SpellID].CastingRequirements = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].CastingRequirements = effect.Value; - } - - foreach (var effect in SpellClassOptions) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellClassOptions) { - Console.WriteLine($"SpellClassOptions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellClassOptions: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].ClassOptions = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].ClassOptions = effect.Value; - } - - foreach (var effect in SpellCooldowns) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellCooldowns) { - Console.WriteLine($"SpellCooldowns: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellCooldowns: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Cooldowns = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Cooldowns = effect.Value; - } - - foreach (var effect in SpellEffectScaling) + }), Task.Run(() => { - if (!SpellEffect.ContainsKey((int)effect.Value.SpellEffectId)) + foreach (var effect in SpellEffectScaling) { - Console.WriteLine($"SpellEffectScaling: Unknown spell effect {effect.Value.SpellEffectId} referenced, ignoring!"); - continue; + if (!SpellEffect.ContainsKey(effect.Value.SpellEffectId)) + { + Console.WriteLine( + $"SpellEffectScaling: Unknown spell effect {effect.Value.SpellEffectId} referenced, ignoring!"); + continue; + } + + SpellEffect[effect.Value.SpellEffectId].SpellEffectScalingEntry = effect.Value; } - - SpellEffect[effect.Value.SpellEffectId].SpellEffectScalingEntry = effect.Value; - } - - foreach (var effect in SpellInterrupts) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellInterrupts) { - Console.WriteLine($"SpellInterrupts: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellInterrupts: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Interrupts = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Interrupts = effect.Value; - } - - foreach (var effect in SpellEquippedItems) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellEquippedItems) { - Console.WriteLine($"SpellEquippedItems: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellEquippedItems: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].EquippedItems = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].EquippedItems = effect.Value; - } - - foreach (var effect in SpellLevels) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellLevels) { - Console.WriteLine($"SpellLevels: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; - } + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine($"SpellLevels: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } - SpellInfoLoadData[effect.Value.SpellID].Levels = effect.Value; - } - - foreach (var effect in SpellReagents) + SpellInfoLoadData[effect.Value.SpellID].Levels = effect.Value; + } + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellReagents) { - Console.WriteLine($"SpellReagents: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellReagents: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Reagents = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Reagents = effect.Value; - } - - foreach (var effect in SpellShapeshift) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellShapeshift) { - Console.WriteLine($"SpellShapeshift: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine( + $"SpellShapeshift: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } + + SpellInfoLoadData[effect.Value.SpellID].Shapeshift = effect.Value; } - - SpellInfoLoadData[effect.Value.SpellID].Shapeshift = effect.Value; - } - - foreach (var effect in SpellTotems) + }), Task.Run(() => { - if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + foreach (var effect in SpellTotems) { - Console.WriteLine($"SpellTotems: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); - continue; - } - - SpellInfoLoadData[effect.Value.SpellID].Totems = effect.Value; - } + if (!SpellInfoLoadData.ContainsKey(effect.Value.SpellID)) + { + Console.WriteLine($"SpellTotems: Unknown spell {effect.Value.SpellID} referenced, ignoring!"); + continue; + } - /*OnLoadProgress?.Invoke($"Generating ItemTemplate store ..."); + SpellInfoLoadData[effect.Value.SpellID].Totems = effect.Value; + } + })); - foreach (var item in ItemSparse.Rows) + /*foreach (var item in ItemSparse.Rows) { ItemTemplate.Add(new Item { diff --git a/SpellWork/DBC/DataStoreFileNameAttribute.cs b/SpellWork/DBC/DataStoreFileNameAttribute.cs deleted file mode 100644 index 6d213ecb..00000000 --- a/SpellWork/DBC/DataStoreFileNameAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace SpellWork.DBC -{ - [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] - sealed class DataStoreFileNameAttribute : Attribute - { - public DataStoreFileNameAttribute(string filename) - { - FileName = filename; - } - - public string FileName { get; } - } -} diff --git a/SpellWork/DBC/Structures/ItemSparseEntry.cs b/SpellWork/DBC/Structures/ItemSparseEntry.cs index 4d702925..ca719579 100644 --- a/SpellWork/DBC/Structures/ItemSparseEntry.cs +++ b/SpellWork/DBC/Structures/ItemSparseEntry.cs @@ -1,5 +1,8 @@ -namespace SpellWork.DBC.Structures +using DBFilesClient.NET; + +namespace SpellWork.DBC.Structures { + [DBFileName("Item-sparse")] public sealed class ItemSparseEntry { public uint[] Flags; diff --git a/SpellWork/DBC/Structures/SpellEffectScalingEntry.cs b/SpellWork/DBC/Structures/SpellEffectScalingEntry.cs index 7a21bbdd..8c08aa00 100644 --- a/SpellWork/DBC/Structures/SpellEffectScalingEntry.cs +++ b/SpellWork/DBC/Structures/SpellEffectScalingEntry.cs @@ -5,6 +5,6 @@ public class SpellEffectScalingEntry public float Coefficient; public float Variance; public float ResourceCoefficient; - public uint SpellEffectId; + public int SpellEffectId; } } diff --git a/SpellWork/DBC/Structures/SpellEntry.cs b/SpellWork/DBC/Structures/SpellEntry.cs index f1223d40..0f8b6728 100644 --- a/SpellWork/DBC/Structures/SpellEntry.cs +++ b/SpellWork/DBC/Structures/SpellEntry.cs @@ -6,7 +6,7 @@ public sealed class SpellEntry public string NameSubtext; public string Description; public string AuraDescription; - public uint MiscID; + public int MiscID; public uint ID; public uint DescriptionVariablesID; diff --git a/SpellWork/Forms/FormMain.cs b/SpellWork/Forms/FormMain.cs index 93067e79..b56bdcc0 100644 --- a/SpellWork/Forms/FormMain.cs +++ b/SpellWork/Forms/FormMain.cs @@ -405,9 +405,9 @@ private void FamilyTreeAfterCheck(object sender, TreeViewEventArgs e) where spell.SpellFamilyName == ProcInfo.SpellProc.SpellFamilyName && spell.SpellFamilyFlags.ContainsElement(mask) - join sk in DBC.DBC.SkilllLineAbilityStore.Values on spell.ID equals sk.SpellID into temp1 + join sk in DBC.DBC.SkillLineAbility.Values on spell.ID equals sk.SpellID into temp1 from skill in temp1.DefaultIfEmpty(new SkillLineAbilityEntry()) - join skl in DBC.DBC.SkilllLineStore on skill.SkillLine equals skl.Key into temp2 + join skl in DBC.DBC.SkillLine on skill.SkillLine equals skl.Key into temp2 from SkillLine in temp2.DefaultIfEmpty() select new diff --git a/SpellWork/Spell/ProcInfo.cs b/SpellWork/Spell/ProcInfo.cs index fb112c5e..862cd2f3 100644 --- a/SpellWork/Spell/ProcInfo.cs +++ b/SpellWork/Spell/ProcInfo.cs @@ -18,9 +18,9 @@ public static void Fill(TreeView familyTree, SpellFamilyNames spellfamily) var spells = from spell in DBC.DBC.SpellInfoStore.Values where spell.SpellFamilyName == (uint)spellfamily - join sk in DBC.DBC.SkilllLineAbilityStore.Values on spell.ID equals sk.SpellID into temp1 + join sk in DBC.DBC.SkillLineAbility.Values on spell.ID equals sk.SpellID into temp1 from skill in temp1.DefaultIfEmpty(new SkillLineAbilityEntry()) - join skl in DBC.DBC.SkilllLineStore on skill.SkillLine equals skl.Key into temp2 + join skl in DBC.DBC.SkillLine on skill.SkillLine equals skl.Key into temp2 from skillLine in temp2 select new { diff --git a/SpellWork/Spell/SpellInfo.cs b/SpellWork/Spell/SpellInfo.cs index 95a2b873..9ce5d16c 100644 --- a/SpellWork/Spell/SpellInfo.cs +++ b/SpellWork/Spell/SpellInfo.cs @@ -2,6 +2,7 @@ using System.Drawing; using System.Linq; using System.Windows.Forms; +using SpellWork.Database; using SpellWork.DBC.Structures; using SpellWork.Extensions; using SpellWork.GameTables; @@ -43,9 +44,9 @@ private void ViewSpellInfo() _rtb.AppendFormatLine(_line); var addline = false; - if (DBC.DBC.SpellTriggerStore.ContainsKey(_spell.ID)) + if (DBC.DBC.SpellTriggerStore.ContainsKey((int)_spell.ID)) { - foreach (var procSpellId in DBC.DBC.SpellTriggerStore[_spell.ID]) + foreach (var procSpellId in DBC.DBC.SpellTriggerStore[(int)_spell.ID]) { var procname = "Spell Not Found"; if (DBC.DBC.Spell.ContainsKey(procSpellId)) @@ -319,12 +320,12 @@ private void AppendSpellVisualInfo() private void AppendSkillLine() { - var query = DBC.DBC.SkilllLineAbilityStore.Where(skl => skl.Value.SpellID == _spell.ID).ToArray(); + var query = DBC.DBC.SkillLineAbility.Where(skl => skl.Value.SpellID == _spell.ID).ToArray(); if (query.Length == 0) return; var skill = query.First().Value; - var line = DBC.DBC.SkilllLineStore[skill.SkillLine]; + var line = DBC.DBC.SkillLine[skill.SkillLine]; _rtb.AppendFormatLine("Skill (Id {0}) \"{1}\"", skill.SkillLine, line.DisplayName); _rtb.AppendFormat(" MinSkillLineRank {0}", skill.MinSkillLineRank); @@ -423,7 +424,7 @@ private void AppendSpellEffectInfo() var query = from spell in DBC.DBC.SpellInfoStore.Values where spell.SpellFamilyName == _spell.SpellFamilyName && spell.SpellFamilyFlags.ContainsElement(classMask) - join sk in DBC.DBC.SkilllLineAbilityStore.Values on spell.ID equals sk.SpellID into temp + join sk in DBC.DBC.SkillLineAbility.Values on spell.ID equals sk.SpellID into temp from skill in temp.DefaultIfEmpty(new SkillLineAbilityEntry()) select new { @@ -633,7 +634,8 @@ where item.SpellId.ContainsElement((int)_spell.ID) select item; // ReSharper disable once PossibleMultipleEnumeration - if (!items.Any()) + var enumerable = items as Item[] ?? items.ToArray(); + if (!enumerable.Any()) return; _rtb.AppendLine(_line); @@ -641,7 +643,7 @@ where item.SpellId.ContainsElement((int)_spell.ID) _rtb.AppendLine("Items using this spell:"); _rtb.SetDefaultStyle(); - foreach (var item in items) + foreach (var item in enumerable) { var name = string.IsNullOrEmpty(item.LocalesName) ? item.Name : item.LocalesName; var desc = string.IsNullOrEmpty(item.LocalesDescription) ? item.Description : item.LocalesDescription; diff --git a/SpellWork/Spell/SpellInfoHelper.cs b/SpellWork/Spell/SpellInfoHelper.cs index aec9446b..be192b40 100644 --- a/SpellWork/Spell/SpellInfoHelper.cs +++ b/SpellWork/Spell/SpellInfoHelper.cs @@ -169,10 +169,10 @@ public string Description if (!string.IsNullOrEmpty(_Description)) sb.AppendFormatLine("Description: {0}", _Description); - if (SpellDescriptionVariableID == 0 || !DBC.DBC.SpellDescriptionVariables.ContainsKey(SpellDescriptionVariableID)) + if (SpellDescriptionVariableID == 0 || !DBC.DBC.SpellDescriptionVariables.ContainsKey((int)SpellDescriptionVariableID)) return sb.ToString(); - var sdesc = DBC.DBC.SpellDescriptionVariables[SpellDescriptionVariableID]; + var sdesc = DBC.DBC.SpellDescriptionVariables[(int)SpellDescriptionVariableID]; sb.AppendFormatLine("Description variable Id: {0}", SpellDescriptionVariableID); sb.AppendFormatLine("Description variable: {0}", sdesc.Variables); return sb.ToString(); diff --git a/SpellWork/SpellWork.csproj b/SpellWork/SpellWork.csproj index a157eef3..79bc05aa 100644 --- a/SpellWork/SpellWork.csproj +++ b/SpellWork/SpellWork.csproj @@ -62,10 +62,18 @@ false + + ..\packages\DBFilesClient.NET.1.0.0.0\lib\net452\DBFilesClient.NET.dll + True + False libs\MySql.Data.dll + + ..\packages\Sigil.4.7.0\lib\net45\Sigil.dll + True + 3.5 @@ -88,8 +96,6 @@ Code - - @@ -205,6 +211,7 @@ PreserveNewest Designer + PublicSettingsSingleFileGenerator Settings.Designer.cs diff --git a/SpellWork/packages.config b/SpellWork/packages.config new file mode 100644 index 00000000..f4a3ca8d --- /dev/null +++ b/SpellWork/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file