diff --git a/src/Core.cs b/src/Core.cs index bc00d39..2c8ec0c 100644 --- a/src/Core.cs +++ b/src/Core.cs @@ -6,6 +6,19 @@ namespace D2SLib { public class Core { + private static TXT _TXT = null; + public static TXT TXT + { + get + { + return _TXT ?? ResourceFilesTXT.Instance.TXT; + } + set + { + _TXT = value; + } + } + public static D2S ReadD2S(string path) { return D2S.Read(File.ReadAllBytes(path)); diff --git a/src/D2SLib.csproj b/src/D2SLib.csproj index c04ea08..8d15a12 100644 --- a/src/D2SLib.csproj +++ b/src/D2SLib.csproj @@ -8,6 +8,9 @@ d2s d2i diablo-ii diablo2 d2r Read and write saves from Diablo 2. Supports versions 1.10 through Diablo II: Resurrected (1.15). Supports both d2s (player saves) and d2i (shared stash). true + https://github.com/dschu012/D2SLib + git + 1.0.1 diff --git a/src/Model/Save/Attributes.cs b/src/Model/Save/Attributes.cs index 164bdcf..43ac123 100644 --- a/src/Model/Save/Attributes.cs +++ b/src/Model/Save/Attributes.cs @@ -14,7 +14,7 @@ public class Attributes public static Attributes Read(BitReader reader) { - ItemStatCostTXT itemStatCost = ResourceFilesTXT.Instance.TXT.ItemStatCost; + ItemStatCostTXT itemStatCost = Core.TXT.ItemStatCostTXT; Attributes attributes = new Attributes(); attributes.Header = reader.ReadUInt16(); UInt16 id = reader.ReadUInt16(9); @@ -37,7 +37,7 @@ public static byte[] Write(Attributes attributes) { using (BitWriter writer = new BitWriter()) { - ItemStatCostTXT itemStatCost = ResourceFilesTXT.Instance.TXT.ItemStatCost; + ItemStatCostTXT itemStatCost = Core.TXT.ItemStatCostTXT; writer.WriteUInt16(attributes.Header ?? (UInt16)0x6667); foreach (var entry in attributes.Stats) { diff --git a/src/Model/Save/Items.cs b/src/Model/Save/Items.cs index c70818e..bb730a6 100644 --- a/src/Model/Save/Items.cs +++ b/src/Model/Save/Items.cs @@ -238,7 +238,7 @@ protected static void ReadCompact(BitReader reader, Item item, UInt32 version) { for(int i = 0; i < 4; i++) { - item.Code += ResourceFilesTXT.Instance.TXT.ItemsTXT.ItemCodeTree.DecodeChar(reader); + item.Code += Core.TXT.ItemsTXT.ItemCodeTree.DecodeChar(reader); } } item.NumberOfSocketedItems = reader.ReadByte(item.IsCompact ? 1 : 3); @@ -295,7 +295,7 @@ protected static void WriteCompact(BitWriter writer, Item item, UInt32 version) { for (int i = 0; i < 4; i++) { - BitArray bits = ResourceFilesTXT.Instance.TXT.ItemsTXT.ItemCodeTree.EncodeChar((char)code[i]); + BitArray bits = Core.TXT.ItemsTXT.ItemCodeTree.EncodeChar((char)code[i]); foreach (var bit in bits.Cast()) { writer.WriteBit(bit); @@ -374,10 +374,10 @@ protected static void ReadComplete(BitReader reader, Item item, UInt32 version) { reader.ReadBits(96); } - ItemStatCostTXT itemStatCostTXT = ResourceFilesTXT.Instance.TXT.ItemStatCost; - TXTRow row = ResourceFilesTXT.Instance.TXT.ItemsTXT.GetByCode(item.Code); - bool isArmor = ResourceFilesTXT.Instance.TXT.ItemsTXT.IsArmor(item.Code); - bool isWeapon = ResourceFilesTXT.Instance.TXT.ItemsTXT.IsWeapon(item.Code); + ItemStatCostTXT itemStatCostTXT = Core.TXT.ItemStatCostTXT; + TXTRow row = Core.TXT.ItemsTXT.GetByCode(item.Code); + bool isArmor = Core.TXT.ItemsTXT.IsArmor(item.Code); + bool isWeapon = Core.TXT.ItemsTXT.IsWeapon(item.Code); bool isStackable = row["stackable"].ToBool(); if (isArmor) { @@ -492,10 +492,10 @@ protected static void WriteComplete(BitWriter writer, Item item, UInt32 version) { //todo 96 bits } - ItemStatCostTXT itemStatCostTXT = ResourceFilesTXT.Instance.TXT.ItemStatCost; - TXTRow row = ResourceFilesTXT.Instance.TXT.ItemsTXT.GetByCode(item.Code); - bool isArmor = ResourceFilesTXT.Instance.TXT.ItemsTXT.IsArmor(item.Code); - bool isWeapon = ResourceFilesTXT.Instance.TXT.ItemsTXT.IsWeapon(item.Code); + ItemStatCostTXT itemStatCostTXT = Core.TXT.ItemStatCostTXT; + TXTRow row = Core.TXT.ItemsTXT.GetByCode(item.Code); + bool isArmor = Core.TXT.ItemsTXT.IsArmor(item.Code); + bool isWeapon = Core.TXT.ItemsTXT.IsWeapon(item.Code); bool isStackable = row["stackable"].ToBool(); if (isArmor) { @@ -614,7 +614,7 @@ public class ItemStat public static ItemStat Read(BitReader reader, UInt16 id) { ItemStat itemStat = new ItemStat(); - TXTRow property = ResourceFilesTXT.Instance.TXT.ItemStatCost[id]; + TXTRow property = Core.TXT.ItemStatCostTXT[id]; if (property == null) { throw new Exception($"No ItemStatCost record found for id: {id} at bit {reader.Position - 9}"); @@ -728,11 +728,11 @@ public static TXTRow GetStatRow(ItemStat stat) { if (stat.Id != null) { - return ResourceFilesTXT.Instance.TXT.ItemStatCost[(UInt16)stat.Id]; + return Core.TXT.ItemStatCostTXT[(UInt16)stat.Id]; } else { - return ResourceFilesTXT.Instance.TXT.ItemStatCost[(string)stat.Stat]; + return Core.TXT.ItemStatCostTXT[(string)stat.Stat]; } } diff --git a/src/Model/TXT/ItemsTXT.cs b/src/Model/TXT/ItemsTXT.cs index c884fa1..83648b8 100644 --- a/src/Model/TXT/ItemsTXT.cs +++ b/src/Model/TXT/ItemsTXT.cs @@ -14,7 +14,23 @@ public class ItemsTXT public ArmorTXT ArmorTXT {get; set;} public WeaponsTXT WeaponsTXT { get; set; } public MiscTXT MiscTXT { get; set; } - public HuffmanTree ItemCodeTree { get; set; } + + private HuffmanTree _ItemCodeTree = null; + public HuffmanTree ItemCodeTree + { + get + { + if(_ItemCodeTree == null) + { + _ItemCodeTree = InitializeHuffmanTree(); + } + return _ItemCodeTree; + } + set + { + _ItemCodeTree = value; + } + } public TXTRow this[string i] => this.GetByCode(i); @@ -40,7 +56,7 @@ public bool IsMisc(string code) return MiscTXT[code] != null; } - public void InitializeHuffmanTree() + private HuffmanTree InitializeHuffmanTree() { /* List items = new List(); @@ -57,8 +73,9 @@ public void InitializeHuffmanTree() items.Add(row["code"]); } */ - ItemCodeTree = new HuffmanTree(); - ItemCodeTree.Build(new List()); + var itemCodeTree = new HuffmanTree(); + itemCodeTree.Build(new List()); + return itemCodeTree; } } diff --git a/src/ResourceFilesTXT.cs b/src/ResourceFilesTXT.cs index bfb2c64..e45552d 100644 --- a/src/ResourceFilesTXT.cs +++ b/src/ResourceFilesTXT.cs @@ -19,9 +19,8 @@ private static ResourceFilesTXT Init() ResourceFilesTXT resourceFilesTXT = new ResourceFilesTXT(); resourceFilesTXT.TXT = new TXT(); using(Stream s = GetResource("ItemStatCost.txt")) { - resourceFilesTXT.TXT.ItemStatCost = ItemStatCostTXT.Read(s); + resourceFilesTXT.TXT.ItemStatCostTXT = ItemStatCostTXT.Read(s); } - resourceFilesTXT.TXT.ItemsTXT = new ItemsTXT(); using (Stream s = GetResource("Armor.txt")) { resourceFilesTXT.TXT.ItemsTXT.ArmorTXT = ArmorTXT.Read(s); @@ -34,8 +33,6 @@ private static ResourceFilesTXT Init() { resourceFilesTXT.TXT.ItemsTXT.MiscTXT = MiscTXT.Read(s); } - resourceFilesTXT.TXT.ItemsTXT.InitializeHuffmanTree(); - return resourceFilesTXT; } diff --git a/src/TXT.cs b/src/TXT.cs index 64e3fd5..a6e0ec9 100644 --- a/src/TXT.cs +++ b/src/TXT.cs @@ -7,7 +7,22 @@ namespace D2SLib { public class TXT { - public ItemStatCostTXT ItemStatCost { get; set; } - public ItemsTXT ItemsTXT { get; set; } + public ItemStatCostTXT ItemStatCostTXT { get; set; } + private ItemsTXT _ItemsTXT = null; + public ItemsTXT ItemsTXT + { + get + { + if(_ItemsTXT == null) + { + _ItemsTXT = new ItemsTXT(); + } + return _ItemsTXT; + } + set + { + _ItemsTXT = value; + } + } } } diff --git a/test/D2STest.cs b/test/D2STest.cs index bd0fc0f..7252439 100644 --- a/test/D2STest.cs +++ b/test/D2STest.cs @@ -1,5 +1,6 @@ using D2SLib; using D2SLib.Model.Save; +using D2SLib.Model.TXT; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.IO; @@ -22,7 +23,6 @@ public void VerifyCanReadSimple115Save() public void VerifyCanReadComplex115Save() { D2S character = Core.ReadD2S(File.ReadAllBytes(@"Resources\D2S\1.15\DannyIsGreat.d2s")); - character.ClassSkills.Skills.ForEach(skill => skill.Points = 20); Assert.IsTrue(character.Name == "DannyIsGreat"); Assert.IsTrue(character.ClassId == 0x1); /* @@ -44,5 +44,6 @@ public void VerifyCanWriteComplex115Save() //File.WriteAllBytes(Environment.ExpandEnvironmentVariables($"%userprofile%/Saved Games/Diablo II Resurrected Tech Alpha/{character.Name}.d2s"), ret); Assert.IsTrue(input.Length == ret.Length); } + } }