diff --git a/src/Model/Huffman/HuffmanTree.cs b/src/Model/Huffman/HuffmanTree.cs index 82e8bab..0f5c9b9 100644 --- a/src/Model/Huffman/HuffmanTree.cs +++ b/src/Model/Huffman/HuffmanTree.cs @@ -1,113 +1,112 @@ using D2SLib.IO; -using System; using System.Collections; -using System.Collections.Generic; -using System.Text; -namespace D2SLib.Model.Huffman +namespace D2SLib.Model.Huffman; + +//hardcoded.... +public class HuffmanTree { - //hardcoded.... - public class HuffmanTree - { - public Node Root { get; set; } + public Node? Root { get; set; } - public static Dictionary TABLE = new Dictionary - { - {'0', "11111011"}, - {' ', "10"}, - {'1', "1111100"}, - {'2', "001100"}, - {'3', "1101101"}, - {'4', "11111010"}, - {'5', "00010110"}, - {'6', "1101111"}, - {'7', "01111"}, - {'8', "000100"}, - {'9', "01110"}, - {'a', "11110"}, - {'b', "0101"}, - {'c', "01000"}, - {'d', "110001"}, - {'e', "110000"}, - {'f', "010011"}, - {'g', "11010"}, - {'h', "00011"}, - {'i', "1111110"}, - {'j', "000101110"}, - {'k', "010010"}, - {'l', "11101"}, - {'m', "01101"}, - {'n', "001101"}, - {'o', "1111111"}, - {'p', "11001"}, - {'q', "11011001"}, - {'r', "11100"}, - {'s', "0010"}, - {'t', "01100"}, - {'u', "00001"}, - {'v', "1101110"}, - {'w', "00000"}, - {'x', "00111"}, - {'y', "0001010"}, - {'z', "11011000"} - }; + public static readonly IReadOnlyDictionary TABLE = new Dictionary(38) + { + {'0', "11111011"}, + {' ', "10"}, + {'1', "1111100"}, + {'2', "001100"}, + {'3', "1101101"}, + {'4', "11111010"}, + {'5', "00010110"}, + {'6', "1101111"}, + {'7', "01111"}, + {'8', "000100"}, + {'9', "01110"}, + {'a', "11110"}, + {'b', "0101"}, + {'c', "01000"}, + {'d', "110001"}, + {'e', "110000"}, + {'f', "010011"}, + {'g', "11010"}, + {'h', "00011"}, + {'i', "1111110"}, + {'j', "000101110"}, + {'k', "010010"}, + {'l', "11101"}, + {'m', "01101"}, + {'n', "001101"}, + {'o', "1111111"}, + {'p', "11001"}, + {'q', "11011001"}, + {'r', "11100"}, + {'s', "0010"}, + {'t', "01100"}, + {'u', "00001"}, + {'v', "1101110"}, + {'w', "00000"}, + {'x', "00111"}, + {'y', "0001010"}, + {'z', "11011000"} + }; - //todo find a way to build this like d2? - public void Build(List items) + //todo find a way to build this like d2? + public void Build(List items) + { + Root = new Node(); + foreach (var entry in TABLE) { - Root = new Node(); - foreach(KeyValuePair entry in TABLE) + var current = Root; + foreach (char bit in entry.Value) { - var Current = Root; - foreach(char bit in entry.Value) + if (bit == '1') { - if(bit == '1') + if (current.Right == null) { - if(Current.Right == null) - { - Current.Right = new Node(); - } - Current = Current.Right; - } else if(bit == '0') + current.Right = new Node(); + } + current = current.Right; + } + else if (bit == '0') + { + if (current.Left == null) { - if (Current.Left == null) - { - Current.Left = new Node(); - } - Current = Current.Left; + current.Left = new Node(); } + current = current.Left; } - Current.Symbol = entry.Key; } + current.Symbol = entry.Key; } + } - public BitArray EncodeChar(char source) - { - List encodedSymbol = this.Root.Traverse(source, new List()); - return new BitArray(encodedSymbol.ToArray()); - } + public BitArray EncodeChar(char source) + { + var encodedSymbol = Root?.Traverse(source, new List()); + if (encodedSymbol is null) + throw new InvalidOperationException("Could not encode with an empty tree."); + return new BitArray(encodedSymbol.ToArray()); + } - public char DecodeChar(IBitReader reader) + public char DecodeChar(IBitReader reader) + { + var current = Root; + while (!(current?.IsLeaf() ?? true)) { - Node current = this.Root; - while(!current.IsLeaf()) + if (reader.ReadBit()) { - if (reader.ReadBit()) + if (current.Right is not null) { - if (current.Right != null) - { - current = current.Right; - } + current = current.Right; } - else + } + else + { + if (current.Left is not null) { - if (current.Left != null) - { - current = current.Left; - } + current = current.Left; } } - return current.Symbol; } + return current?.Symbol ?? '\0'; } } diff --git a/src/Model/Huffman/Node.cs b/src/Model/Huffman/Node.cs index e97abe3..018699e 100644 --- a/src/Model/Huffman/Node.cs +++ b/src/Model/Huffman/Node.cs @@ -1,66 +1,53 @@ -using System; -using System.Collections.Generic; -using System.Text; +namespace D2SLib.Model.Huffman; -namespace D2SLib.Model.Huffman +public class Node { - public class Node - { - public char Symbol { get; set; } - public int Frequency { get; set; } - public Node Right { get; set; } - public Node Left { get; set; } + public char Symbol { get; set; } + public int Frequency { get; set; } + public Node? Right { get; set; } + public Node? Left { get; set; } - public List Traverse(char symbol, List data) + public List? Traverse(char symbol, List data) + { + // Leaf + if (Right == null && Left == null) { - // Leaf - if (Right == null && Left == null) + if (symbol.Equals(Symbol)) { - if (symbol.Equals(this.Symbol)) - { - return data; - } - else - { - return null; - } + return data; } else { - List left = null; - List right = null; - - if (Left != null) - { - List leftPath = new List(); - leftPath.AddRange(data); - leftPath.Add(false); - - left = Left.Traverse(symbol, leftPath); - } + return null; + } + } + else + { + List? left = null; + List? right = null; - if (Right != null) - { - List rightPath = new List(); - rightPath.AddRange(data); - rightPath.Add(true); - right = Right.Traverse(symbol, rightPath); - } + if (Left is not null) + { + var leftPath = new List(data) { false }; + left = Left.Traverse(symbol, leftPath); + } - if (left != null) - { - return left; - } - else - { - return right; - } + if (Right is not null) + { + var rightPath = new List(data) { true }; + right = Right.Traverse(symbol, rightPath); } - } - public bool IsLeaf() - { - return (Left == null && Right == null); + if (left != null) + { + return left; + } + else + { + return right; + } } } + + public bool IsLeaf() => Left is null && Right is null; } diff --git a/src/Model/Save/Corpses.cs b/src/Model/Save/Corpses.cs index 9bbc095..35b518e 100644 --- a/src/Model/Save/Corpses.cs +++ b/src/Model/Save/Corpses.cs @@ -49,9 +49,13 @@ public static byte[] Write(CorpseList corpseList, uint version) public sealed class Corpse { -#nullable disable - private Corpse() { } -#nullable enable + private Corpse(IBitReader reader, uint version) + { + Unk0x0 = reader.ReadUInt32(); + X = reader.ReadUInt32(); + Y = reader.ReadUInt32(); + ItemList = ItemList.Read(reader, version); + } public uint? Unk0x0 { get; set; } public uint X { get; set; } @@ -68,13 +72,7 @@ public void Write(IBitWriter writer, uint version) public static Corpse Read(IBitReader reader, uint version) { - var corpse = new Corpse - { - Unk0x0 = reader.ReadUInt32(), - X = reader.ReadUInt32(), - Y = reader.ReadUInt32(), - ItemList = ItemList.Read(reader, version) - }; + var corpse = new Corpse(reader, version); return corpse; } diff --git a/src/Model/Save/Golem.cs b/src/Model/Save/Golem.cs index 0f5fea7..bdc4633 100644 --- a/src/Model/Save/Golem.cs +++ b/src/Model/Save/Golem.cs @@ -4,13 +4,19 @@ namespace D2SLib.Model.Save; public class Golem { -#nullable disable - private Golem() { } -#nullable enable + private Golem(IBitReader reader, uint version) + { + Header = reader.ReadUInt16(); + Exists = reader.ReadByte() == 1; + if (Exists) + { + Item = Item.Read(reader, version); + } + } public ushort? Header { get; set; } public bool Exists { get; set; } - public Item Item { get; set; } + public Item? Item { get; set; } public void Write(IBitWriter writer, uint version) { @@ -18,21 +24,13 @@ public void Write(IBitWriter writer, uint version) writer.WriteByte((byte)(Exists ? 1 : 0)); if (Exists) { - Item.Write(writer, version); + Item?.Write(writer, version); } } public static Golem Read(IBitReader reader, uint version) { - var golem = new Golem - { - Header = reader.ReadUInt16(), - Exists = reader.ReadByte() == 1 - }; - if (golem.Exists) - { - golem.Item = Item.Read(reader, version); - } + var golem = new Golem(reader, version); return golem; } diff --git a/src/Model/Save/Quests.cs b/src/Model/Save/Quests.cs index 58130f7..04ceae9 100644 --- a/src/Model/Save/Quests.cs +++ b/src/Model/Save/Quests.cs @@ -69,9 +69,14 @@ public static byte[] Write(QuestsSection questSection) public sealed class QuestsDifficulty { -#nullable disable - private QuestsDifficulty() { } -#nullable enable + private QuestsDifficulty(IBitReader reader) + { + ActI = ActIQuests.Read(reader); + ActII = ActIIQuests.Read(reader); + ActIII = ActIIIQuests.Read(reader); + ActIV = ActIVQuests.Read(reader); + ActV = ActVQuests.Read(reader); + } public ActIQuests ActI { get; set; } public ActIIQuests ActII { get; set; } @@ -90,15 +95,7 @@ public void Write(IBitWriter writer) public static QuestsDifficulty Read(IBitReader reader) { - var qd = new QuestsDifficulty - { - ActI = ActIQuests.Read(reader), - ActII = ActIIQuests.Read(reader), - ActIII = ActIIIQuests.Read(reader), - ActIV = ActIVQuests.Read(reader), - ActV = ActVQuests.Read(reader) - }; - + var qd = new QuestsDifficulty(reader); return qd; } diff --git a/src/Model/Save/Waypoints.cs b/src/Model/Save/Waypoints.cs index 46c8303..f580d91 100644 --- a/src/Model/Save/Waypoints.cs +++ b/src/Model/Save/Waypoints.cs @@ -63,9 +63,18 @@ public static byte[] Write(WaypointsSection waypointsSection) public class WaypointsDifficulty { -#nullable disable - private WaypointsDifficulty() { } -#nullable enable + private WaypointsDifficulty(IBitReader reader) + { + Header = reader.ReadUInt16(); + ActI = ActIWaypoints.Read(reader); + ActII = ActIIWaypoints.Read(reader); + ActIII = ActIIIWaypoints.Read(reader); + ActIV = ActIVWaypoints.Read(reader); + ActV = ActVWaypoints.Read(reader); + + reader.Align(); + reader.AdvanceBits(17 * 8); + } //[0x02, 0x01] public ushort? Header { get; set; } @@ -95,21 +104,7 @@ public void Write(IBitWriter writer) public static WaypointsDifficulty Read(IBitReader reader) { - ushort header = reader.ReadUInt16(); - - var waypointsDifficulty = new WaypointsDifficulty - { - Header = header, - ActI = ActIWaypoints.Read(reader), - ActII = ActIIWaypoints.Read(reader), - ActIII = ActIIIWaypoints.Read(reader), - ActIV = ActIVWaypoints.Read(reader), - ActV = ActVWaypoints.Read(reader) - }; - - reader.Align(); - reader.AdvanceBits(17 * 8); - + var waypointsDifficulty = new WaypointsDifficulty(reader); return waypointsDifficulty; }