diff --git a/Hashing.cs b/Hashing.cs
deleted file mode 100644
index 24d1d9a..0000000
--- a/Hashing.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-using LibAC.Serialization;
-using LibAC.Serialization.ACFile;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC
-{
- public class Hash : Serializable
- {
- public byte[] hashed;
- private readonly byte signature = 0x9f;
- public int passnum = 0;
-
- public Hash(int len)
- {
- hashed = new byte[len];
- //hashed[0] = signature;
-
- passnum = 0;
- }
-
- public byte get_sig_at_pass(int pass)
- {
- byte start = signature;
- for (int i = 0; i < pass; i++)
- {
- start = (byte)wrap_add((int)start, (int)signature);
- }
-
- return start;
- }
-
- public Hash(byte[] bs, int pass)
- {
- hashed = bs;
- passnum = pass;
- }
-
- public static Hash compute(int len, byte[] data)
- {
- if (len <= 0) throw new ArgumentOutOfRangeException();
- byte[] arr = new byte[len];
- int p = 0;//pointer to position in [arr]
-
- foreach (byte b in data)
- {
- //arr[p] += b;// treat as a number.
- int exist = arr[p];
- exist += b;
- while (exist > 255) exist -= 255;
-
- if (exist < 0) exist *= -1;
- arr[p] = (byte)exist;
-
- p++;
- if (p >= len)
- {
- p = 0;// reset the pointer
- }
- }
-
-
- return new Hash(arr, 1);
-
- }
-
- public static Hash operator +(Hash a, Hash b)
- {
- Hash ret = new Hash(a.hashed, a.passnum);
- int p = 2; // We do want to add the position signed bit. As that information is unique to a piece of source data
-
- for (p = 0; p < b.hashed.Length; p++)
- {
- int exist = a.hashed[p];
- exist = wrap_add(exist, b.hashed[p]);
-
- ret.hashed[p] = (byte)exist;
- }
-
- ret.passnum++;
-
-
- return ret;
- }
-
- ///
- /// Wrap adds, with a cap at 255
- ///
- ///
- ///
- /// Wrapped integer
- public static int wrap_add(int a, int b)
- {
- a = a + b;
- while (a > 255) a -= 255;
- if (a < 0) a *= -1;
- return a;
- }
- ///
- /// Wrap subtracts with a cap of 255
- ///
- ///
- ///
- /// Wrapped integer
- public static int wrap_sub(int a, int b)
- {
- int ret = a - b;
- if (ret < 0) ret += 255;
- return ret;
- }
-
- public static Hash operator -(Hash a, Hash b)
- {
- Hash ret = new Hash(a.hashed, a.passnum);
- int p = 1; // We do want to add the position signed bit. As that information is unique to a piece of source data
-
- for (p = 0; p < b.hashed.Length; p++)
- {
- int exist = a.hashed[p];
- exist = wrap_sub(exist, b.hashed[p]);
-
- ret.hashed[p] = (byte)exist;
- }
-
- ret.passnum--;
- /*
- if (ret.get_sig_at_pass(ret.passnum) == ret.hashed[0])
- {
- // success
- }
- else throw new Exception("Fatal error in pass. Validation failed");
- */
-
-
- return ret;
-
-
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- foreach (byte b in serialize())
- {
- sb.Append(b.ToString("X2"));
- }
-
- return sb.ToString();
- }
-
- public byte[] serialize()
- {
- MemoryStream ms = new MemoryStream();
- BinaryWriter bw = new BinaryWriter(ms);
- bw.Write(passnum);
- bw.Write(hashed.Length);
- bw.Write(hashed);
-
- return ms.ToArray();
- }
-
- public void deserialize(byte[] streams)
- {
- MemoryStream ms = new MemoryStream(streams);
- BinaryReader br = new BinaryReader(ms);
- passnum = br.ReadInt32();
- hashed = br.ReadBytes(br.ReadInt32());
-
- br.Close();
- }
-
- public override void save(Folder f)
- {
- f.Add(new IntTag("pass", passnum));
- f.Add(new ByteArrayTag("hash",hashed));
- }
-
- public override void load(Folder f)
- {
- passnum = f["pass"].IntValue;
- hashed = (f["hash"] as ByteArrayTag).Value;
- }
- }
-}
diff --git a/LibZNI.csproj b/LibZNI.csproj
index 32309d8..dd189fb 100644
--- a/LibZNI.csproj
+++ b/LibZNI.csproj
@@ -2,16 +2,16 @@
Library
- net7.0
+ net8.0
true
false
Debug;Release;DebPub;KVPBuild
-
-
-
+
+
+
diff --git a/NBT/API/ByteLayer.cs b/NBT/API/ByteLayer.cs
new file mode 100644
index 0000000..696c277
--- /dev/null
+++ b/NBT/API/ByteLayer.cs
@@ -0,0 +1,358 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Linq;
+using System.IO.Compression;
+using System.Collections.Generic;
+
+public class ByteLayer
+{
+ private byte[] _byteBuffer;
+ private int _position;
+
+ public ByteLayer()
+ {
+ _byteBuffer = new byte[0];
+ _position = 0;
+ }
+
+ public int Length => _byteBuffer.Length;
+
+ public int CurrentPosition => _position;
+
+ public byte[] Bytes => _byteBuffer.Take(_position).ToArray();
+
+ private void EnsureCapacity(int additionalBytes)
+ {
+ int requiredCapacity = _position + additionalBytes;
+ if (requiredCapacity > _byteBuffer.Length)
+ {
+ Array.Resize(ref _byteBuffer, requiredCapacity);
+ }
+ }
+
+ public void WriteInt(int value)
+ {
+ EnsureCapacity(4);
+ Array.Copy(BitConverter.GetBytes(value), 0, _byteBuffer, _position, 4);
+ if (BitConverter.IsLittleEndian)
+ Array.Reverse(_byteBuffer, _position, 4);
+ _position += 4;
+ }
+
+ public int ReadInt()
+ {
+ if (_position + 4 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = _byteBuffer.Skip(_position).Take(4).ToArray();
+ if (BitConverter.IsLittleEndian) Array.Reverse(value);
+ _position += 4;
+ return BitConverter.ToInt32(value, 0);
+ }
+
+ public void WriteDouble(double value)
+ {
+ EnsureCapacity(8);
+ var bytes = BitConverter.GetBytes(value);
+ if (BitConverter.IsLittleEndian)
+ Array.Reverse(bytes);
+ Array.Copy(bytes, 0, _byteBuffer, _position, 8);
+ _position += 8;
+ }
+
+ public double ReadDouble()
+ {
+ if (_position + 8 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = _byteBuffer.Skip(_position).Take(8).ToArray();
+ if (BitConverter.IsLittleEndian) Array.Reverse(value);
+ _position += 8;
+ return BitConverter.ToDouble(value, 0);
+ }
+
+ public void WriteFloat(float value)
+ {
+ EnsureCapacity(4);
+ var bytes = BitConverter.GetBytes(value);
+ if(BitConverter.IsLittleEndian)
+ Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, _byteBuffer, _position, 4);
+ _position += 4;
+ }
+
+ public float ReadFloat()
+ {
+ if (_position + 4 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = _byteBuffer.Skip(_position).Take(4).ToArray();
+ if (BitConverter.IsLittleEndian) Array.Reverse(value);
+ _position += 4;
+ return BitConverter.ToSingle(value, 0);
+ }
+
+ public void WriteString(string value)
+ {
+ var encoded = Encoding.UTF8.GetBytes(value);
+ WriteShort((short)encoded.Length);
+ EnsureCapacity(encoded.Length);
+ Array.Copy(encoded, 0, _byteBuffer, _position, encoded.Length);
+ _position += encoded.Length;
+ }
+
+ public string ReadString()
+ {
+ int length = ReadShort();
+ if (_position + length > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = Encoding.UTF8.GetString(_byteBuffer, _position, length);
+ _position += length;
+ return value;
+ }
+
+ public void WriteShort(short value)
+ {
+ EnsureCapacity(2);
+ var bytes = BitConverter.GetBytes((short)value);
+ if (BitConverter.IsLittleEndian)
+ Array.Reverse(bytes);
+ Array.Copy(bytes, 0, _byteBuffer, _position, 2);
+ _position += 2;
+ }
+
+ public short ReadShort()
+ {
+ if (_position + 2 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = _byteBuffer.Skip(_position).Take(2).ToArray();
+ if (BitConverter.IsLittleEndian) Array.Reverse(value);
+ _position += 2;
+ return BitConverter.ToInt16(value, 0);
+ }
+
+ public void WriteByte(byte value)
+ {
+ EnsureCapacity(1);
+ _byteBuffer[_position] = value;
+ _position++;
+ }
+
+ public void WriteBytes(List bytes)
+ {
+ EnsureCapacity(bytes.Count);
+ Array.Copy(bytes.ToArray(), 0, _byteBuffer, _position, bytes.Count);
+ _position += bytes.Count;
+ }
+
+ public byte ReadByte()
+ {
+ if (_position >= _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ return _byteBuffer[_position++];
+ }
+
+ public void ResetPosition() => _position = 0;
+
+ public void RestorePosition(int position)
+ {
+ if (position < 0 || position > _byteBuffer.Length)
+ throw new ArgumentOutOfRangeException(nameof(position));
+ _position = position;
+ }
+
+ public void Clear()
+ {
+ _position = 0;
+ _byteBuffer = new byte[0];
+ }
+
+ public void WriteToFile(string filePath)
+ {
+ File.WriteAllBytes(filePath, Bytes);
+ }
+
+ public void ReadFromFile(string filePath)
+ {
+ if (!File.Exists(filePath)) throw new FileNotFoundException("File does not exist.", filePath);
+ _byteBuffer = File.ReadAllBytes(filePath);
+ ResetPosition();
+ }
+
+ public void Compress()
+ {
+ using var memoryStream = new MemoryStream();
+ using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
+ {
+ gzipStream.Write(_byteBuffer, 0, _byteBuffer.Length);
+ }
+ _byteBuffer = memoryStream.ToArray();
+ _position = _byteBuffer.Length;
+ }
+
+ public void Decompress()
+ {
+ using var memoryStream = new MemoryStream(_byteBuffer);
+ using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress);
+ using var decompressedStream = new MemoryStream();
+ gzipStream.CopyTo(decompressedStream);
+ _byteBuffer = decompressedStream.ToArray();
+ _position = _byteBuffer.Length;
+ }
+
+ public void WriteVarInt(int value)
+ {
+ while ((value & ~0x7F) != 0)
+ {
+ WriteByte((byte)((value & 0x7F) | 0x80));
+ value >>= 7;
+ }
+ WriteByte((byte)(value & 0x7F));
+ }
+
+ public int ReadVarInt()
+ {
+ int result = 0;
+ int shift = 0;
+ int byteRead;
+ do
+ {
+ byteRead = ReadByte();
+ result |= (byteRead & 0x7F) << shift;
+ shift += 7;
+ } while ((byteRead & 0x80) != 0);
+ return result;
+ }
+
+ public void WriteVarIntNoZigZag(int value)
+ {
+ while ((value & ~0x7F) != 0)
+ {
+ WriteByte((byte)((value & 0x7F) | 0x80));
+ value >>= 7;
+ }
+ WriteByte((byte)(value & 0x7F));
+ }
+
+ public int ReadVarIntNoZigZag()
+ {
+ int result = 0;
+ int shift = 0;
+ int byteRead;
+ do
+ {
+ byteRead = ReadByte();
+ result |= (byteRead & 0x7F) << shift;
+ shift += 7;
+ } while ((byteRead & 0x80) != 0);
+ return result;
+ }
+
+ public void WriteLong(long value)
+ {
+ EnsureCapacity(8);
+ Array.Copy(BitConverter.GetBytes(value), 0, _byteBuffer, _position, 8);
+ if (BitConverter.IsLittleEndian)
+ Array.Reverse(_byteBuffer, _position, 8);
+ _position += 8;
+ }
+
+ public long ReadLong()
+ {
+ if (_position + 8 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow.");
+ var value = _byteBuffer.Skip(_position).Take(8).ToArray();
+ if (BitConverter.IsLittleEndian) Array.Reverse(value);
+ _position += 8;
+ return BitConverter.ToInt64(value, 0);
+ }
+
+ public void WriteVarLongZigZag(long value)
+ {
+ value = (value << 1) ^ (value >> 63);
+ WriteVarLongNoZigZag(value);
+ }
+
+ public void WriteVarLongNoZigZag(long value)
+ {
+ while ((value & ~0x7F) != 0)
+ {
+ WriteByte((byte)((value & 0x7F) | 0x80));
+ value >>= 7;
+ }
+ WriteByte((byte)(value & 0x7F));
+ }
+
+ public long ReadVarLongZigZag()
+ {
+ long result = ReadVarLongNoZigZag();
+ return (result >> 1) ^ -(result & 1);
+ }
+
+ public long ReadVarLongNoZigZag()
+ {
+ long result = 0;
+ int shift = 0;
+ int byteRead;
+ do
+ {
+ byteRead = ReadByte();
+ result |= (byteRead & 0x7F) << shift;
+ shift += 7;
+ } while ((byteRead & 0x80) != 0);
+ return result;
+ }
+
+ public void SetBit(int position, byte maskToSet)
+ {
+ if (position < _byteBuffer.Length)
+ {
+ Seek(position);
+ byte current = ReadByte();
+ Seek(position);
+ current |= maskToSet;
+ WriteByte(current);
+ }
+ }
+
+ public void ClearBit(int position, byte maskToClear)
+ {
+ if (position < _byteBuffer.Length)
+ {
+ Seek(position);
+ byte current = ReadByte();
+ current &= (byte)~maskToClear;
+ Seek(position);
+ WriteByte(current);
+ }
+ }
+
+ public bool CheckBit(int position, byte mask)
+ {
+ if (position < _byteBuffer.Length)
+ {
+ Seek(position);
+ byte current = ReadByte();
+ return (current & mask) == mask;
+ }
+ return false;
+ }
+
+ public byte GetBit(int position)
+ {
+ if (position < _byteBuffer.Length)
+ {
+ Seek(position);
+ return ReadByte();
+ }
+ return 0;
+ }
+
+ public void Seek(int position)
+ {
+ if (position < 0 || position > _byteBuffer.Length)
+ throw new ArgumentOutOfRangeException(nameof(position));
+ _position = position;
+ }
+
+ public void InsertRandomBytes(int count)
+ {
+ Random rng = new Random();
+ for (int i = 0; i < count; i++)
+ {
+ WriteByte((byte)rng.Next(256));
+ }
+ }
+}
diff --git a/NBT/API/InvalidNbtDataException.cs b/NBT/API/InvalidNbtDataException.cs
new file mode 100644
index 0000000..d8182ca
--- /dev/null
+++ b/NBT/API/InvalidNbtDataException.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace LibAC.NBT.API
+{
+ public class InvalidNbtDataException : Exception
+ {
+ }
+}
\ No newline at end of file
diff --git a/NBT/API/NBTAccountant.cs b/NBT/API/NBTAccountant.cs
new file mode 100644
index 0000000..3f61e41
--- /dev/null
+++ b/NBT/API/NBTAccountant.cs
@@ -0,0 +1,32 @@
+namespace LibAC.NBT.API;
+
+using System;
+
+public class NBTAccountant
+{
+ private static int _prettyIndex = 0;
+
+ public static void PrintRead(Tag tag)
+ {
+ tag.PrettyPrint(_prettyIndex, false);
+ }
+
+ public static void VisitTag()
+ {
+ _prettyIndex++;
+ }
+
+ public static void LeaveTag(Tag tag)
+ {
+ if (tag is CompoundTag ct)
+ {
+ ct.EndPrettyPrint(_prettyIndex);
+ }
+ else if (tag is ListTag lt)
+ {
+ lt.EndPrettyPrint(_prettyIndex);
+ }
+
+ _prettyIndex--;
+ }
+}
\ No newline at end of file
diff --git a/NBT/API/NbtIo.cs b/NBT/API/NbtIo.cs
new file mode 100644
index 0000000..76fd553
--- /dev/null
+++ b/NBT/API/NbtIo.cs
@@ -0,0 +1,132 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Linq;
+using LibAC.NBT;
+
+
+namespace LibAC.NBT.API
+{
+ public class NbtIo
+ {
+ private static ByteLayer _io = new ByteLayer();
+
+ private static void _Read(string file)
+ {
+ _io = new ByteLayer();
+ _io.ReadFromFile(file);
+ }
+
+ public static CompoundTag Read(string file)
+ {
+ _Read(file);
+ if (_io.ReadByte() == (byte)TagType.Compound)
+ {
+ _io.ResetPosition();
+ return (CompoundTag)Tag.ReadNamedTag(_io);
+ }
+ else
+ {
+ return ReadCompressed(file);
+ }
+ }
+
+ public static CompoundTag ReadCompressed(string file)
+ {
+ _io = new ByteLayer();
+ _io.ReadFromFile(file);
+ _io.Decompress();
+ _io.ResetPosition();
+ return (CompoundTag)Tag.ReadNamedTag(_io);
+ }
+
+ public static void Write(string file, CompoundTag tag)
+ {
+ _io = new ByteLayer();
+ Tag.WriteNamedTag(tag, _io);
+ _io.WriteToFile(file);
+ }
+
+ public static void WriteCompressedAsync(string file, CompoundTag tag)
+ {
+ _io = new ByteLayer();
+ Tag.WriteNamedTag(tag, _io);
+ _io.Compress();
+ _io.WriteToFile(file);
+ }
+
+ public static ByteLayer GetStream()
+ {
+ return _io;
+ }
+
+ public static string WriteBase64String(CompoundTag tag)
+ {
+ _io = new ByteLayer();
+ Tag.WriteNamedTag(tag, _io);
+ _io.Compress();
+ return Convert.ToBase64String(_io.Bytes);
+ }
+
+ public static CompoundTag ReadBase64String(string encoded)
+ {
+ _io = new ByteLayer();
+ byte[] bytes = Convert.FromBase64String(encoded);
+ foreach (byte b in bytes)
+ {
+ _io.WriteByte(b);
+ }
+ _io.Decompress();
+ _io.ResetPosition();
+ return (CompoundTag)Tag.ReadNamedTag(_io);
+ }
+
+ public static byte[] WriteToStreamCompressed(CompoundTag tag)
+ {
+ _io = new ByteLayer();
+ Tag.WriteNamedTag(tag, _io);
+ _io.Compress();
+ return _io.Bytes;
+ }
+
+ public static CompoundTag ReadFromStreamCompressed(byte[] list)
+ {
+ _io = new ByteLayer();
+ try
+ {
+ _io.WriteBytes(list.ToList());
+ _io.ResetPosition();
+ _io.Decompress();
+ _io.ResetPosition();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ return (CompoundTag)Tag.ReadNamedTag(_io);
+ }
+
+ public static async Task WriteToStreamAsync(CompoundTag tag)
+ {
+ _io = new ByteLayer();
+ Tag.WriteNamedTag(tag, _io);
+ return _io.Bytes;
+ }
+
+ public static CompoundTag ReadFromStream(byte[] list)
+ {
+ _io = new ByteLayer();
+ try
+ {
+ _io.WriteBytes(list.ToList());
+ _io.ResetPosition();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ return (CompoundTag)Tag.ReadNamedTag(_io);
+ }
+ }
+}
diff --git a/NBT/API/NbtUUID.cs b/NBT/API/NbtUUID.cs
new file mode 100644
index 0000000..58b4e0f
--- /dev/null
+++ b/NBT/API/NbtUUID.cs
@@ -0,0 +1,43 @@
+using System;
+using LibAC.Utilities;
+
+namespace LibAC.NBT.API
+{
+ public class NbtUUID
+ {
+ public long MSB { get; }
+ public long LSB { get; }
+
+ public static readonly NbtUUID ZERO = new NbtUUID(UUID.ZERO);
+
+ public NbtUUID(long msb, long lsb)
+ {
+ MSB = msb;
+ LSB = lsb;
+ }
+
+ public NbtUUID(UUID uuid)
+ {
+ byte[] uuidBytes = uuid.GetBytes();
+ MSB = BitConverter.ToInt64(uuidBytes, 0);
+ LSB = BitConverter.ToInt64(uuidBytes, 8);
+ }
+
+ public long GetMostSignificantBits() => MSB;
+
+ public long GetLeastSignificantBits() => LSB;
+
+ public UUID ToUUID()
+ {
+ byte[] bytes = new byte[16];
+ BitConverter.GetBytes(MSB).CopyTo(bytes, 0);
+ BitConverter.GetBytes(LSB).CopyTo(bytes, 8);
+ return new UUID(bytes);
+ }
+
+ public override string ToString()
+ {
+ return ToUUID().ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/API/NbtUtils.cs b/NBT/API/NbtUtils.cs
new file mode 100644
index 0000000..530f232
--- /dev/null
+++ b/NBT/API/NbtUtils.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using LibAC.NBT.API;
+using LibAC.Utilities;
+
+namespace LibAC.NBT.API
+{
+ public static class NbtUtils
+ {
+ public static void WriteBoolean(CompoundTag tag, string name, bool value)
+ {
+ tag.Put(name, ByteTag.ValueOf(value ? (byte)1 : (byte)0));
+ }
+
+ public static bool ReadBoolean(CompoundTag tag, string name)
+ {
+ if (tag.ContainsKey(name))
+ {
+ return tag.Get(name).AsByte() == 1;
+ }
+ return false;
+ }
+
+ public static void WriteVector2d(CompoundTag tag, string name, Vector2d pos)
+ {
+ var posTag = new ListTag();
+ posTag.Add(DoubleTag.ValueOf(pos.X));
+ posTag.Add(DoubleTag.ValueOf(pos.Z));
+ tag.Put(name, posTag);
+ }
+
+ public static Vector2d ReadVector2d(CompoundTag tag, string name)
+ {
+ if (tag.ContainsKey(name))
+ {
+ var listTag = (ListTag)tag.Get(name);
+ return new Vector2d(listTag.Get(0).AsDouble(), listTag.Get(1).AsDouble());
+ }
+ return Vector2d.ZERO;
+ }
+
+ public static void WriteVector2i(CompoundTag tag, string name, Vector2i pos)
+ {
+ var posTag = new ListTag();
+ posTag.Add(IntTag.ValueOf(pos.X));
+ posTag.Add(IntTag.ValueOf(pos.Z));
+ tag.Put(name, posTag);
+ }
+
+ public static Vector2i ReadVector2i(CompoundTag tag, string name)
+ {
+ if (tag.ContainsKey(name))
+ {
+ var listTag = (ListTag)tag.Get(name);
+ return new Vector2i(listTag.Get(0).AsInt(), listTag.Get(1).AsInt());
+ }
+ return Vector2i.ZERO;
+ }
+
+ public static void WriteVector3d(CompoundTag tag, string name, Vector3d pos)
+ {
+ var posTag = new ListTag();
+ posTag.Add(DoubleTag.ValueOf(pos.X));
+ posTag.Add(DoubleTag.ValueOf(pos.Y));
+ posTag.Add(DoubleTag.ValueOf(pos.Z));
+ tag.Put(name, posTag);
+ }
+
+ public static Vector3d ReadVector3d(CompoundTag tag, string name)
+ {
+ if (tag.ContainsKey(name))
+ {
+ var listTag = (ListTag)tag.Get(name);
+ return new Vector3d(
+ listTag.Get(0).AsDouble(),
+ listTag.Get(1).AsDouble(),
+ listTag.Get(2).AsDouble());
+ }
+ return Vector3d.ZERO;
+ }
+
+ public static void WriteVector3i(CompoundTag tag, string name, Vector3i pos)
+ {
+ var posTag = new ListTag();
+ posTag.Add(IntTag.ValueOf(pos.X));
+ posTag.Add(IntTag.ValueOf(pos.Y));
+ posTag.Add(IntTag.ValueOf(pos.Z));
+ tag.Put(name, posTag);
+ }
+
+ public static Vector3i ReadVector3i(CompoundTag tag, string name)
+ {
+ if (tag.ContainsKey(name))
+ {
+ var listTag = (ListTag)tag.Get(name);
+ return new Vector3i(
+ listTag.Get(0).AsInt(),
+ listTag.Get(1).AsInt(),
+ listTag.Get(2).AsInt());
+ }
+ return Vector3i.ZERO;
+ }
+
+ private static int[] MsbLsbToIntArray(long msb, long lsb)
+ {
+ return new[]
+ {
+ (int)(msb >> 32),
+ (int)msb,
+ (int)(lsb >> 32),
+ (int)lsb
+ };
+ }
+
+ private static int[] UuidToIntArray(NbtUUID id)
+ {
+ return MsbLsbToIntArray(id.GetMostSignificantBits(), id.GetLeastSignificantBits());
+ }
+
+ private static NbtUUID UuidFromIntArray(int[] values)
+ {
+ return new NbtUUID(
+ ((long)values[0] << 32) | (values[1] & 0xFFFFFFFFL),
+ ((long)values[2] << 32) | (values[3] & 0xFFFFFFFFL));
+ }
+
+ public static void WriteUUID(CompoundTag tag, string name, NbtUUID id)
+ {
+ tag.Put(name, IntArrayTag.ValueOf(UuidToIntArray(id).ToList()));
+ }
+
+ public static NbtUUID ReadUUID(CompoundTag tag, string name)
+ {
+ if (!tag.ContainsKey(name))
+ {
+ return NbtUUID.ZERO;
+ }
+ return UuidFromIntArray(tag.Get(name).AsIntArray().ToArray());
+ }
+ }
+}
diff --git a/NBT/API/SnbtIo.cs b/NBT/API/SnbtIo.cs
new file mode 100644
index 0000000..35ab451
--- /dev/null
+++ b/NBT/API/SnbtIo.cs
@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using System.Text;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT.API
+{
+ public static class SnbtIo
+ {
+ ///
+ /// Writes a CompoundTag to a file in SNBT format.
+ ///
+ /// The file path to write to.
+ /// The CompoundTag to write.
+ public static async Task WriteToFile(string file, CompoundTag tag)
+ {
+ var fileInfo = new FileInfo(file);
+
+ if (fileInfo.Exists)
+ {
+ fileInfo.Delete(); // Ensure the file is reset to 0 bytes.
+ }
+
+ var builder = new StringBuilder();
+ Tag.WriteStringifiedNamedTag(tag, builder, 0);
+
+ using (var writer = new StreamWriter(file))
+ {
+ await writer.WriteAsync(builder.ToString());
+ }
+ }
+
+ ///
+ /// Reads a tag from a file in SNBT format.
+ ///
+ /// The file path to read from.
+ /// A Task resolving to the read Tag.
+ public static async Task ReadFromFile(string file)
+ {
+ var fileInfo = new FileInfo(file);
+ if (!fileInfo.Exists)
+ {
+ throw new FileNotFoundException($"File not found: {file}");
+ }
+
+ string data;
+ using (var reader = new StreamReader(file))
+ {
+ data = await reader.ReadToEndAsync();
+ }
+
+ var stringReader = new StringReader(data);
+ Tag tag = new CompoundTag();
+
+ try
+ {
+ tag = Tag.ReadStringifiedNamedTag(stringReader);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"FATAL ERROR OCCURRED AT LOCATION:\n{stringReader.GetSnapshot()}");
+ Console.WriteLine(ex);
+ }
+
+ return tag;
+ }
+
+ ///
+ /// Converts a CompoundTag to its SNBT string representation.
+ ///
+ /// The CompoundTag to convert.
+ /// A string representing the CompoundTag in SNBT format.
+ public static string WriteToString(CompoundTag tag)
+ {
+ var builder = new StringBuilder();
+ Tag.WriteStringifiedNamedTag(tag, builder, 0);
+ return builder.ToString();
+ }
+
+ ///
+ /// Reads a Tag from an SNBT string.
+ ///
+ /// The SNBT string to read.
+ /// A Task resolving to the read Tag.
+ public static Task ReadFromString(string data)
+ {
+ var stringReader = new StringReader(data);
+ return Task.FromResult(Tag.ReadStringifiedNamedTag(stringReader));
+ }
+ }
+}
diff --git a/NBT/API/StringBuilder.cs b/NBT/API/StringBuilder.cs
new file mode 100644
index 0000000..b598571
--- /dev/null
+++ b/NBT/API/StringBuilder.cs
@@ -0,0 +1,32 @@
+using System.Text;
+
+namespace LibAC.NBT.API
+{
+ public class StringBuilder
+ {
+ private string _buffer = string.Empty;
+
+ public StringBuilder()
+ {
+ }
+
+ public bool IsEmpty => string.IsNullOrEmpty(_buffer);
+
+ public int Length => _buffer.Length;
+
+ public void Append(string value)
+ {
+ _buffer += value;
+ }
+
+ public void Clear()
+ {
+ _buffer = string.Empty;
+ }
+
+ public override string ToString()
+ {
+ return _buffer;
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/API/StringReader.cs b/NBT/API/StringReader.cs
new file mode 100644
index 0000000..e18e959
--- /dev/null
+++ b/NBT/API/StringReader.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Text;
+
+namespace LibAC.NBT.API
+{
+ public class StringReader
+ {
+ private readonly string _buffer;
+ private int _position = 0;
+ private int _lastPosition = 0;
+ private bool _quotedString = false;
+
+ public StringReader(string buffer)
+ {
+ _buffer = buffer;
+ }
+
+ // Check if there's more to read
+ public bool CanRead => _CanRead();
+
+ private bool _CanRead()
+ {
+ SkipWhitespace();
+ return _position < _buffer.Length;
+ }
+
+ // Get the number of chars seeked
+ public int Seeked => _lastPosition - _position;
+
+ // Read the next character
+ public char Next()
+ {
+ if (CanRead)
+ {
+ SkipWhitespace();
+ return _buffer[_position++];
+ }
+ else
+ {
+ throw new Exception("End of buffer reached");
+ }
+ }
+
+ // Generates a snapshot of the text location if applicable
+ public string GetSnapshot()
+ {
+ if (CanRead)
+ {
+ if (_position + 64 < _buffer.Length)
+ {
+ return _buffer.Substring(_position, 64);
+ }
+ else
+ {
+ return _buffer.Substring(_position);
+ }
+ }
+ else
+ {
+ return string.Empty;
+ }
+ }
+
+ // Peek the next character without advancing the position
+ public char Peek()
+ {
+ SkipWhitespace();
+ if (CanRead)
+ {
+ return _buffer[_position];
+ }
+ else
+ {
+ throw new Exception("End of buffer reached");
+ }
+ }
+
+ // Skip any whitespace characters
+ public void SkipWhitespace()
+ {
+ if (_quotedString) return; // We need whitespace for strings
+ while (_position < _buffer.Length && IsWhitespace(_buffer[_position]))
+ {
+ _position++;
+ }
+ }
+
+ // Check if a character is a whitespace
+ private bool IsWhitespace(char character)
+ {
+ return char.IsWhiteSpace(character);
+ }
+
+ // Read until a specific character is found
+ public string ReadUntil(char stopChar, int maxChars)
+ {
+ var result = new StringBuilder();
+ int index = 0;
+ while (CanRead && Peek() != stopChar && index < maxChars)
+ {
+ result.Append(Next().ToString());
+ index++;
+ }
+ return result.ToString();
+ }
+
+ // Read a string enclosed in double quotes
+ public string ReadQuotedString()
+ {
+ _quotedString = true;
+ if (Next() != '"')
+ {
+ throw new Exception("Expected double quotes at the start of a string");
+ }
+ var result = new StringBuilder();
+ while (CanRead)
+ {
+ char character = Next();
+ if (character == '"')
+ {
+ break;
+ }
+ result.Append(character.ToString());
+ }
+ _quotedString = false;
+ return result.ToString();
+ }
+
+ // Read a number (int or double)
+ public string ReadNumber()
+ {
+ var result = new StringBuilder();
+ while (CanRead && (IsDigit(Peek()) || Peek() == '.' || Peek() == '-'))
+ {
+ result.Append(Next().ToString());
+ }
+ return result.ToString();
+ }
+
+ // Check if a character is a digit
+ private bool IsDigit(char character)
+ {
+ return char.IsDigit(character);
+ }
+
+ // Read an unquoted string (used for keys in SNBT)
+ public string ReadUnquotedString()
+ {
+ var result = new StringBuilder();
+ while (CanRead &&
+ !IsWhitespace(Peek()) &&
+ Peek() != ':' &&
+ Peek() != ',' &&
+ Peek() != '{' &&
+ Peek() != '}' &&
+ Peek() != '[' &&
+ Peek() != ']')
+ {
+ result.Append(Next().ToString());
+ }
+ return result.ToString();
+ }
+
+ public string ReadString()
+ {
+ if (Peek() == '"')
+ {
+ return ReadQuotedString();
+ }
+ else
+ {
+ return ReadUnquotedString();
+ }
+ }
+
+ // Read a specific character and throw an exception if it's not found
+ public void Expect(char expectedChar)
+ {
+ if (char.ToLower(Next()) != char.ToLower(expectedChar))
+ {
+ throw new Exception($"Expected {expectedChar}");
+ }
+ }
+
+ public void StartSeek()
+ {
+ _lastPosition = _position;
+ }
+
+ public void EndSeek()
+ {
+ _position = _lastPosition;
+ _lastPosition = 0;
+ }
+ }
+}
diff --git a/NBT/API/Tag.cs b/NBT/API/Tag.cs
new file mode 100644
index 0000000..94fd0e0
--- /dev/null
+++ b/NBT/API/Tag.cs
@@ -0,0 +1,280 @@
+using System.Collections.Generic;
+
+namespace LibAC.NBT.API;
+
+using System;
+using System.Text;
+
+public abstract class Tag
+{
+ private TagType _parentTagType = TagType.End;
+ private Tag _parentTag;
+ private string _key;
+
+ public byte GetType()
+ {
+ return (byte)GetTagType();
+ }
+
+ public abstract TagType GetTagType();
+
+ public bool HasParent => _parentTag != null;
+
+ public void UpdateParent(Tag tag)
+ {
+ if (tag == null)
+ {
+ _parentTag = null;
+ SetParentTagType(TagType.End);
+ }
+ else
+ {
+ _parentTag = tag;
+ SetParentTagType(tag.GetTagType());
+ }
+ }
+
+ public Tag GetParent => _parentTag;
+
+ public TagType ParentTagType => _parentTagType;
+
+ public void SetParentTagType(TagType type)
+ {
+ _parentTagType = type;
+ }
+
+ public abstract void WriteValue(ByteLayer data);
+ public abstract void ReadValue(ByteLayer data);
+
+ public string GetKey()
+ {
+ return _key ?? string.Empty;
+ }
+
+ public void SetKey(string key)
+ {
+ _key = key;
+ }
+
+ public abstract dynamic GetValue();
+ public abstract void SetValue(dynamic val);
+
+ public static Tag ReadNamedTag(ByteLayer data)
+ {
+ var type = data.ReadByte();
+ if (type == 0)
+ {
+ return new EndTag();
+ }
+ else
+ {
+ Tag tag = MakeTagOfType(TagTypeExtensions.GetTagTypeFromByte(type));
+ tag._key = data.ReadString();
+ tag.ReadValue(data);
+
+ return tag;
+ }
+ }
+
+ public static void WriteNamedTag(Tag tag, ByteLayer data)
+ {
+ data.WriteByte(tag.GetType());
+ if (tag.GetType() != 0)
+ {
+ data.WriteString(tag.GetKey());
+ tag.WriteValue(data);
+ }
+ }
+
+ public static void WriteStringifiedNamedTag(Tag tag, StringBuilder builder, int indents)
+ {
+ if (tag.GetType() != 0)
+ {
+ if (builder.Length > 0)
+ {
+ if (string.IsNullOrEmpty(tag.GetKey()))
+ {
+ builder.Append(new string('\t', indents));
+ }
+ else
+ {
+ if (tag.ShouldQuoteName())
+ {
+ builder.Append(new string('\t', indents) + $"\"{tag.GetKey()}\": ");
+ }
+ else
+ {
+ builder.Append(new string('\t', indents) + $"{tag.GetKey()}: ");
+ }
+ }
+ }
+
+ tag.WriteStringifiedValue(builder, indents + 1, false);
+ }
+ }
+
+ public static Tag ReadStringifiedNamedTag(StringReader stringReader)
+ {
+ string name = stringReader.Peek() == '{' || stringReader.Peek() == '[' ? "" : stringReader.ReadString();
+ if (!string.IsNullOrEmpty(name)) stringReader.Expect(':');
+
+ TagType type = TagTypeExtensions.GetStringifiedTagType(stringReader);
+ Tag tag = MakeTagOfType(type);
+ tag._key = name;
+ tag.ReadStringifiedValue(stringReader);
+
+ return tag;
+ }
+
+ public bool ShouldQuoteName()
+ {
+ if (string.IsNullOrEmpty(GetKey()))
+ {
+ return false;
+ }
+ else
+ {
+ string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ foreach (char c in GetKey())
+ {
+ if (!letters.Contains(c.ToString())) return true;
+ }
+ return false;
+ }
+ }
+
+ public bool ShouldQuote(string value)
+ {
+ if (string.IsNullOrEmpty(value)) return true;
+
+ string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ foreach (char c in value)
+ {
+ if (!letters.Contains(c.ToString())) return true;
+ }
+ return false;
+ }
+
+ public abstract void WriteStringifiedValue(StringBuilder builder, int indent, bool isList);
+ public abstract void ReadStringifiedValue(StringReader reader);
+
+ public bool Equals(object obj)
+ {
+ if (obj == null || !(obj is Tag)) return false;
+
+ var tag = (Tag)obj;
+ if (tag.GetType() != GetType()) return false;
+ if (GetKey() != tag.GetKey()) return false;
+
+ return true;
+ }
+
+ public static Tag MakeTagOfType(TagType type)
+ {
+ switch (type)
+ {
+ case TagType.Byte: return new ByteTag();
+ case TagType.ByteArray: return new ByteArrayTag();
+ case TagType.Compound: return new CompoundTag();
+ case TagType.Double: return new DoubleTag();
+ case TagType.End: return new EndTag();
+ case TagType.Short: return new ShortTag();
+ case TagType.Int: return new IntTag();
+ case TagType.Long: return new LongTag();
+ case TagType.Float: return new FloatTag();
+ case TagType.IntArray: return new IntArrayTag();
+ case TagType.LongArray: return new LongArrayTag();
+ case TagType.List: return new ListTag();
+ case TagType.String: return new StringTag();
+ default: throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public int AsByte()
+ {
+ if (this is ByteTag byteTag) return byteTag.Value;
+ return 0;
+ }
+
+ public List AsByteArray()
+ {
+ if (this is ByteArrayTag byteArrayTag) return byteArrayTag.Value;
+ return new List();
+ }
+
+ public double AsDouble()
+ {
+ if (this is DoubleTag doubleTag) return doubleTag.Value;
+ return 0.0;
+ }
+
+ public double AsFloat()
+ {
+ if (this is FloatTag floatTag) return floatTag.value;
+ return 0.0;
+ }
+
+ public List AsIntArray()
+ {
+ if (this is IntArrayTag intArrayTag) return intArrayTag.Value;
+ return new List();
+ }
+
+ public int AsInt()
+ {
+ if (this is IntTag intTag) return intTag.Value;
+ return 0;
+ }
+
+ public List AsLongArray()
+ {
+ if (this is LongArrayTag longArrayTag) return longArrayTag.value;
+ return new List();
+ }
+
+ public long AsLong()
+ {
+ if (this is LongTag longTag) return longTag.value;
+ return 0;
+ }
+
+ public short AsShort()
+ {
+ if (this is ShortTag shortTag) return shortTag.value;
+ return 0;
+ }
+
+ public string AsString()
+ {
+ if (this is StringTag stringTag) return stringTag.value;
+ return string.Empty;
+ }
+
+ public CompoundTag AsCompoundTag()
+ {
+ return this is CompoundTag compoundTag ? compoundTag : new CompoundTag();
+ }
+
+ public abstract void PrettyPrint(int indent, bool recurse);
+
+ public static string GetCanonicalName(TagType type)
+ {
+ return type switch
+ {
+ TagType.String => "TAG_String",
+ TagType.List => "TAG_List",
+ TagType.LongArray => "TAG_LongArray",
+ TagType.Long => "TAG_Long",
+ TagType.IntArray => "TAG_IntArray",
+ TagType.Int => "TAG_Int",
+ TagType.Compound => "TAG_Compound",
+ TagType.ByteArray => "TAG_ByteArray",
+ TagType.Byte => "TAG_Byte",
+ TagType.Double => "TAG_Double",
+ TagType.Float => "TAG_Float",
+ TagType.Short => "TAG_Short",
+ TagType.End => "TAG_End",
+ _ => throw new ArgumentOutOfRangeException()
+ };
+ }
+}
diff --git a/NBT/API/TagType.cs b/NBT/API/TagType.cs
new file mode 100644
index 0000000..dc627b6
--- /dev/null
+++ b/NBT/API/TagType.cs
@@ -0,0 +1,18 @@
+namespace LibAC.NBT.API;
+
+public enum TagType
+{
+ End = 0,
+ Byte = 1,
+ Short = 2,
+ Int = 3,
+ Long = 4,
+ Float = 5,
+ Double = 6,
+ ByteArray = 7,
+ String = 8,
+ List = 9,
+ Compound = 10,
+ IntArray = 11,
+ LongArray = 12
+}
\ No newline at end of file
diff --git a/NBT/API/TagTypeExtensions.cs b/NBT/API/TagTypeExtensions.cs
new file mode 100644
index 0000000..78d83a3
--- /dev/null
+++ b/NBT/API/TagTypeExtensions.cs
@@ -0,0 +1,145 @@
+namespace LibAC.NBT.API;
+
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+
+public static class TagTypeExtensions
+{
+ private static readonly string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ public static TagType GetTagTypeFromByte(int byteValue)
+ {
+ return Enum.IsDefined(typeof(TagType), byteValue) ? (TagType)byteValue : TagType.End;
+ }
+
+ public static TagType GetStringifiedTagType(StringReader reader)
+ {
+ reader.StartSeek(); // Enter fake read mode
+ TagType ret = TagType.End;
+ bool isQuoted = false;
+ bool isNumeric = true; // Assume true until proven otherwise
+ bool isAlpha = true; // Assume true until proven otherwise
+ bool hasDecimalPoint = false;
+ StringBuilder buffer = new StringBuilder();
+
+ while (reader.CanRead)
+ {
+ var val = reader.Peek(); // Peek at the next character without consuming it
+
+ if (val == ',' || val == '\n' || val == ']' || val == '}')
+ {
+ break; // Stop at comma or newline
+ }
+
+ if (val == '"')
+ {
+ reader.Next(); // Consume the quote character
+ isQuoted = true; // Toggle quoted state
+ break;
+ }
+
+ if (val == '{')
+ {
+ ret = TagType.Compound; // Detected a CompoundTag
+ reader.Next(); // Consume '{'
+ reader.EndSeek(); // Restore the original stream position
+ return ret;
+ }
+
+ if (val == '[')
+ {
+ reader.Next(); // Consume '['
+ // Peek ahead to differentiate between List and Array
+ var prefix = reader.ReadUntil(';', 2).ToUpper();
+
+ switch (prefix)
+ {
+ case "B":
+ ret = TagType.ByteArray;
+ break;
+ case "I":
+ ret = TagType.IntArray;
+ break;
+ case "L":
+ ret = TagType.LongArray;
+ break;
+ default:
+ ret = TagType.List; // No type prefix, it's a List
+ break;
+ }
+
+ reader.EndSeek(); // Restore the original stream position
+ return ret;
+ }
+
+ // Adjusting numeric and alphabetic checks
+ var current = reader.Next(); // Consume the character
+
+ buffer.Append(current.ToString());
+
+ // Updated check to allow digits, decimal points, and numeric suffixes
+ if (!Regex.IsMatch(current.ToString(), @"^[0-9]$"))
+ {
+ if (current == '.' && !hasDecimalPoint)
+ {
+ hasDecimalPoint = true; // Allow only one decimal point
+ }
+ else if (!Regex.IsMatch(current.ToString(), @"^[sSbBiIlLfFdD]$"))
+ {
+ isNumeric = false; // Not purely numeric or allowed decimal/suffix
+ }
+ }
+
+ // Check if current character is purely alphabetical
+ if (!Regex.IsMatch(current.ToString(), @"^[A-Za-z]$"))
+ {
+ isAlpha = false; // Not purely alphabetical
+ }
+ }
+
+ var input = buffer.ToString().Trim();
+ reader.EndSeek(); // Restore the original stream position
+
+ if (string.IsNullOrEmpty(input))
+ {
+ return TagType.String; // No input detected
+ }
+
+ if (isQuoted)
+ {
+ return TagType.String; // Quoted string
+ }
+
+ if (isNumeric)
+ {
+ // Check the last character for type indicator (only for numeric input)
+ var lastChar = input.Substring(input.Length - 1).ToUpper();
+ switch (lastChar)
+ {
+ case "S":
+ return TagType.Short;
+ case "B":
+ return TagType.Byte;
+ case "I":
+ return TagType.Int;
+ case "F":
+ return TagType.Float;
+ case "D":
+ return TagType.Double;
+ case "L":
+ return TagType.Long;
+ default:
+ return TagType.Int; // Default to Int if purely numeric with no specific suffix
+ }
+ }
+ else if (isAlpha && !input.Contains(' '))
+ {
+ return TagType.String; // Unquoted purely alphabetical string
+ }
+ else
+ {
+ return TagType.String; // Unquoted string with mixed content or spaces
+ }
+ }
+}
diff --git a/NBT/ByteArrayTag.cs b/NBT/ByteArrayTag.cs
new file mode 100644
index 0000000..a3ead47
--- /dev/null
+++ b/NBT/ByteArrayTag.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class ByteArrayTag : Tag
+ {
+ public List Value { get; private set; } = new List();
+
+ public ByteArrayTag() { }
+
+ private ByteArrayTag(List value)
+ {
+ Value.AddRange(value);
+ }
+
+ public static ByteArrayTag ValueOf(List value)
+ {
+ return new ByteArrayTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ int len = data.ReadInt();
+ for (int i = 0; i < len; i++)
+ {
+ Value.Add(data.ReadByte());
+ }
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteInt(Value.Count);
+ foreach (byte i in Value)
+ {
+ data.WriteByte(i);
+ }
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.ByteArray;
+ }
+
+ public override dynamic GetValue()
+ {
+ return null; // Implementation-specific value retrieval
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ // Implementation-specific value setting
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ string array = string.Join(", ", Value);
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{array}]");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}[B; {string.Join("B, ", Value)}B]");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ reader.Expect('[');
+ reader.Expect('B');
+ reader.Expect(';');
+ while (reader.Peek() != ']')
+ {
+ Value.Add(byte.Parse(reader.ReadNumber()));
+ reader.Expect('b');
+
+ if (reader.Peek() == ',') reader.Next();
+ }
+ reader.Expect(']');
+ }
+ }
+}
diff --git a/NBT/ByteTag.cs b/NBT/ByteTag.cs
new file mode 100644
index 0000000..02a4d2e
--- /dev/null
+++ b/NBT/ByteTag.cs
@@ -0,0 +1,67 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class ByteTag : Tag
+ {
+ public byte Value { get; private set; } = 0;
+
+ public ByteTag() { }
+
+ private ByteTag(byte value)
+ {
+ Value = value;
+ }
+
+ public static ByteTag ValueOf(byte value)
+ {
+ return new ByteTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ Value = data.ReadByte();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteByte(Value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Byte;
+ }
+
+ public override dynamic GetValue()
+ {
+ return Value;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is byte)
+ {
+ Value = (byte)val;
+ }
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {Value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{Value}b");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ string val = reader.ReadNumber();
+ Value = byte.Parse(val);
+ reader.Expect('b');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/CompoundTag.cs b/NBT/CompoundTag.cs
new file mode 100644
index 0000000..bd3bc67
--- /dev/null
+++ b/NBT/CompoundTag.cs
@@ -0,0 +1,283 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class CompoundTag : Tag, IDictionary
+ {
+ private readonly Dictionary _value = new Dictionary();
+
+ public CompoundTag() { }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ _value.Clear();
+
+ while (true)
+ {
+ Tag tag = Tag.ReadNamedTag(data);
+ if (tag.GetType() == 0)
+ {
+ return;
+ }
+
+ tag.SetParentTagType(TagType.Compound);
+ this[tag.GetKey()] = tag;
+ }
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ foreach (var tag in _value.Values)
+ {
+ Tag.WriteNamedTag(tag, data);
+ }
+
+ data.WriteByte((byte)TagType.End);
+ }
+
+ public void Put(string name, Tag tag)
+ {
+ _value[name] = tag;
+ tag.SetKey(name);
+ tag.UpdateParent(this);
+ }
+
+ public Tag? Get(string name)
+ {
+ return ContainsKey(name) ? _value[name] : null;
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Compound;
+ }
+
+ public override object GetValue()
+ {
+ return null;
+ }
+
+ public override void SetValue(object val) { }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{_value.Count} entries]");
+ Console.WriteLine($"{new string('\t', indent)}");
+ if (recurse)
+ {
+ foreach (var tag in _value.Values)
+ {
+ tag.PrettyPrint(indent + 1, true);
+ }
+ }
+ }
+
+ public void EndPrettyPrint(int indent)
+ {
+ Console.WriteLine($"{new string('\t', indent)}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent - 1) : "")}{{\n");
+
+ bool firstEntry = true;
+ foreach (var tag in _value.Values)
+ {
+ if (!firstEntry)
+ {
+ builder.Append(",\n");
+ }
+ firstEntry = false;
+ Tag.WriteStringifiedNamedTag(tag, builder, indent);
+ }
+
+ builder.Append($"\n{new string('\t', indent - 1)}}}");
+ }
+
+ public bool TryGetValue(string key, out Tag value)
+ {
+ return _value.TryGetValue(key, out value);
+ }
+
+ public Tag? this[string key]
+ {
+ get => _value.ContainsKey(key) ? _value[key] : null;
+ set
+ {
+ if (value != null)
+ {
+ _value[key] = value;
+ value.UpdateParent(this);
+ }
+ }
+ }
+
+ public void Add(string key, Tag value)
+ {
+ _value.Add(key, value);
+ value.UpdateParent(this);
+ }
+
+ public void Add(KeyValuePair item)
+ {
+ _value.Add(item.Key, item.Value);
+ item.Value.UpdateParent(this);
+ }
+
+ public void Clear()
+ {
+ UnsetParent();
+ _value.Clear();
+ }
+
+ public bool Contains(KeyValuePair item)
+ {
+ return _value.ContainsKey(item.Key);
+ }
+
+ public void CopyTo(KeyValuePair[] array, int arrayIndex)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(KeyValuePair item)
+ {
+ return _value.Remove(item.Key);
+ }
+
+ public void UnsetParent()
+ {
+ foreach (var entry in _value)
+ {
+ entry.Value.SetParentTagType(TagType.End);
+ entry.Value.UpdateParent(null);
+ }
+ }
+
+ public bool ContainsKey(string key)
+ {
+ return _value.ContainsKey(key);
+ }
+
+ public bool ContainsValue(Tag value)
+ {
+ return _value.ContainsValue(value);
+ }
+
+ public void ForEach(Action action)
+ {
+ foreach (var entry in _value)
+ {
+ action(entry.Key, entry.Value);
+ }
+ }
+
+ public int Count => _value.Count;
+ public bool IsReadOnly { get; }
+
+ public bool IsEmpty => _value.Count == 0;
+
+ public bool IsNotEmpty => _value.Count > 0;
+
+ public ICollection Keys => _value.Keys;
+
+ public ICollection Values => _value.Values;
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ reader.Expect('{');
+
+ while (reader.Peek() != '}')
+ {
+ Tag tag = Tag.ReadStringifiedNamedTag(reader);
+ Put(tag.GetKey(), tag);
+
+ if (reader.Peek() == ',') reader.Next();
+ }
+
+ reader.Expect('}');
+ }
+
+ public void AddAll(IDictionary other)
+ {
+ foreach (var entry in other)
+ {
+ _value[entry.Key] = entry.Value;
+ entry.Value.UpdateParent(this);
+ }
+ }
+
+ public bool Remove(string key)
+ {
+ if (_value.ContainsKey(key))
+ {
+ _value[key].UpdateParent(null);
+ return _value.Remove(key);
+ }
+
+ return false;
+ }
+
+ public void RemoveWhere(Predicate> predicate)
+ {
+ var toRemove = new List();
+ foreach (var entry in _value)
+ {
+ if (predicate(entry))
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ foreach (var key in toRemove)
+ {
+ _value[key].UpdateParent(null);
+ _value.Remove(key);
+ }
+ }
+
+ public void UpdateAll(Action update)
+ {
+ foreach (var entry in _value)
+ {
+ update(entry.Key, entry.Value);
+ }
+ }
+
+ public Tag PutIfAbsent(string key, Func ifAbsent)
+ {
+ if (!_value.ContainsKey(key))
+ {
+ var tag = ifAbsent();
+ tag.UpdateParent(this);
+ _value[key] = tag;
+ return tag;
+ }
+
+ return _value[key];
+ }
+
+ public void AddEntries(IEnumerable> newEntries)
+ {
+ foreach (var entry in newEntries)
+ {
+ _value.Add(entry.Key, entry.Value);
+ entry.Value.UpdateParent(this);
+ }
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return _value.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _value.GetEnumerator();
+ }
+ }
+}
diff --git a/NBT/DoubleTag.cs b/NBT/DoubleTag.cs
new file mode 100644
index 0000000..8015eb7
--- /dev/null
+++ b/NBT/DoubleTag.cs
@@ -0,0 +1,67 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class DoubleTag : Tag
+ {
+ public double Value { get; private set; } = 0.0;
+
+ public DoubleTag() { }
+
+ private DoubleTag(double value)
+ {
+ Value = value;
+ }
+
+ public static DoubleTag ValueOf(double value)
+ {
+ return new DoubleTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ Value = data.ReadDouble();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteDouble(Value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Double;
+ }
+
+ public override dynamic GetValue()
+ {
+ return Value;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is double)
+ {
+ Value = (double)val;
+ }
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {Value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{Value}d");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ double val = double.Parse(reader.ReadNumber());
+ Value = val;
+ reader.Expect('d');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/EndTag.cs b/NBT/EndTag.cs
new file mode 100644
index 0000000..710c5bf
--- /dev/null
+++ b/NBT/EndTag.cs
@@ -0,0 +1,42 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT;
+
+public class EndTag : Tag
+{
+ public override TagType GetTagType()
+ {
+ return TagType.End;
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ }
+
+ public override dynamic GetValue()
+ {
+ return null;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{"".PadLeft(indent, '\t')}{Tag.GetCanonicalName(GetTagType())}");
+ }
+}
\ No newline at end of file
diff --git a/NBT/FloatTag.cs b/NBT/FloatTag.cs
new file mode 100644
index 0000000..d9a30b6
--- /dev/null
+++ b/NBT/FloatTag.cs
@@ -0,0 +1,66 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class FloatTag : Tag
+ {
+ public float value { get; private set; } = 0.0f;
+
+ public FloatTag() { }
+
+ private FloatTag(float value)
+ {
+ this.value = value;
+ }
+
+ public static FloatTag ValueOf(float value)
+ {
+ return new FloatTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ value = data.ReadFloat();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteFloat(value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Float;
+ }
+
+ public override object GetValue()
+ {
+ return value;
+ }
+
+ public override void SetValue(object val)
+ {
+ if (val is float)
+ {
+ value = (float)val;
+ }
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{value}f");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ value = float.Parse(reader.ReadNumber());
+ reader.Expect('f');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/IntArrayTag.cs b/NBT/IntArrayTag.cs
new file mode 100644
index 0000000..4eac559
--- /dev/null
+++ b/NBT/IntArrayTag.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class IntArrayTag : Tag
+ {
+ public List Value { get; private set; } = new List();
+
+ public IntArrayTag() { }
+
+ private IntArrayTag(List value)
+ {
+ this.Value.AddRange(value);
+ }
+
+ public static IntArrayTag ValueOf(List value)
+ {
+ return new IntArrayTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ int count = data.ReadInt();
+ for (int i = 0; i < count; i++)
+ {
+ Value.Add(data.ReadInt());
+ }
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteInt(Value.Count);
+ foreach (int i in Value)
+ {
+ data.WriteInt(i);
+ }
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.IntArray;
+ }
+
+ public override void SetValue(dynamic val) { }
+
+ public override dynamic GetValue() { return null; }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ string array = string.Join(", ", Value);
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{array}]");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}[I; {string.Join("I, ", Value)}I]");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ reader.Expect('[');
+ reader.Expect('I');
+ reader.Expect(';');
+ while (reader.Peek() != ']')
+ {
+ Value.Add(int.Parse(reader.ReadNumber()));
+
+ if (reader.Peek() == ',')
+ reader.Next();
+ }
+ reader.Expect('I');
+ }
+ }
+}
diff --git a/NBT/IntTag.cs b/NBT/IntTag.cs
new file mode 100644
index 0000000..40b7993
--- /dev/null
+++ b/NBT/IntTag.cs
@@ -0,0 +1,70 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class IntTag : Tag
+ {
+ public int Value { get; private set; } = 0;
+
+ public IntTag() { }
+
+ private IntTag(int value)
+ {
+ this.Value = value;
+ }
+
+ public static IntTag ValueOf(int value)
+ {
+ return new IntTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ Value = data.ReadInt();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteInt(Value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Int;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is int)
+ Value = val;
+ }
+
+ public override dynamic GetValue()
+ {
+ return Value;
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {Value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{Value}i");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ string val = reader.ReadNumber();
+ Value = int.Parse(val);
+
+ // Since a type indicator is optional for an int, check for a comma
+ if (reader.Peek() == ',')
+ return;
+ else
+ reader.Expect('i');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/ListTag.cs b/NBT/ListTag.cs
new file mode 100644
index 0000000..afe1f06
--- /dev/null
+++ b/NBT/ListTag.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class ListTag : Tag
+ {
+ private List value = new List();
+
+ public List GetList => new List(value);
+
+ public ListTag() { }
+
+ public TagType ListTagType
+ {
+ get
+ {
+ return value.Count == 0 ? TagType.End : value[0].GetTagType();
+ }
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ TagType type = TagTypeExtensions.GetTagTypeFromByte(data.ReadByte());
+ int size = data.ReadInt();
+
+ for (int i = 0; i < size; i++)
+ {
+ Tag tag = Tag.MakeTagOfType(type);
+ tag.ReadValue(data);
+ Add(tag);
+ }
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ TagType type = TagType.End;
+ if (Size() > 0)
+ {
+ type = value[0].GetTagType();
+ }
+
+ data.WriteByte((byte)type);
+ data.WriteInt(Size());
+ for (int i = 0; i < Size(); i++)
+ {
+ value[i].WriteValue(data);
+ }
+ }
+
+ public void Add(Tag tag)
+ {
+ TagType type = TagType.End;
+ if (Size() > 0)
+ {
+ type = value[0].GetTagType();
+ }
+ if (type == TagType.End || type == tag.GetTagType())
+ {
+ value.Add(tag);
+ tag.UpdateParent(this);
+ }
+ }
+
+ public Tag Get(int index)
+ {
+ if (Size() > index)
+ {
+ return value[index];
+ }
+ else
+ {
+ return new EndTag();
+ }
+ }
+
+ public void Remove(Tag tag)
+ {
+ value.Remove(tag);
+ tag.UpdateParent(null);
+ }
+
+ public void RemoveAt(int index)
+ {
+ value[index].UpdateParent(null);
+ value.RemoveAt(index);
+ }
+
+ public int IndexOf(Tag tag)
+ {
+ return value.IndexOf(tag);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.List;
+ }
+
+ public override void SetValue(dynamic val) { }
+
+ public override dynamic GetValue()
+ {
+ return null;
+ }
+
+ public int Size()
+ {
+ return value.Count;
+ }
+
+ public void Clear()
+ {
+ // Clear the list
+ foreach (var entry in value)
+ {
+ entry.UpdateParent(null);
+ entry.SetParentTagType(TagType.End);
+ }
+
+ value.Clear();
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{value.Count} entries]");
+ Console.WriteLine($"{new string('\t', indent)}[");
+ foreach (Tag tag in value)
+ {
+ tag.PrettyPrint(indent + 1, true);
+ }
+ }
+
+ public void EndPrettyPrint(int indent)
+ {
+ Console.WriteLine($"{new string('\t', indent)}]");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent - 1) : "")}[");
+
+ bool firstTag = true;
+ foreach (Tag tag in value)
+ {
+ if (!firstTag)
+ {
+ builder.Append(",");
+ }
+
+ firstTag = false;
+ tag.WriteStringifiedValue(builder, indent + 1, true);
+ }
+
+ builder.Append($"{new string('\t', indent - 1)}]");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ reader.Expect('[');
+ while (reader.Peek() != ']')
+ {
+ TagType type = TagTypeExtensions.GetStringifiedTagType(reader);
+ Tag newTag = Tag.MakeTagOfType(type);
+ newTag.ReadStringifiedValue(reader);
+ Add(newTag);
+
+ if (reader.Peek() == ',') reader.Next();
+ }
+ reader.Expect(']');
+ }
+ }
+}
diff --git a/NBT/LongArrayTag.cs b/NBT/LongArrayTag.cs
new file mode 100644
index 0000000..f71aa6c
--- /dev/null
+++ b/NBT/LongArrayTag.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class LongArrayTag : Tag
+ {
+ public List value { get; private set; } = new List();
+
+ public LongArrayTag() { }
+
+ public LongArrayTag(List lst)
+ {
+ value.AddRange(lst);
+ }
+
+ public static LongArrayTag ValueOf(List value)
+ {
+ return new LongArrayTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ int count = data.ReadInt();
+ for (int i = 0; i < count; i++)
+ {
+ value.Add(data.ReadLong());
+ }
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteInt(Size());
+ foreach (long val in value)
+ {
+ data.WriteLong(val);
+ }
+ }
+
+ public int Size()
+ {
+ return value.Count;
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.LongArray;
+ }
+
+ public override void SetValue(dynamic val) { }
+
+ public override dynamic GetValue()
+ {
+ return null;
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ string array = string.Join(", ", value);
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: [{array}]");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}[L; {string.Join("L, ", value)}L]");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ reader.Expect('[');
+ reader.Expect('L');
+ reader.Expect(';');
+ while (reader.Peek() != ']')
+ {
+ value.Add(long.Parse(reader.ReadNumber()));
+ reader.Expect('l');
+
+ if (reader.Peek() == ',') reader.Next();
+ }
+ reader.Expect(']');
+ }
+ }
+}
diff --git a/NBT/LongTag.cs b/NBT/LongTag.cs
new file mode 100644
index 0000000..26d846d
--- /dev/null
+++ b/NBT/LongTag.cs
@@ -0,0 +1,65 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class LongTag : Tag
+ {
+ public long value { get; private set; } = 0;
+
+ public LongTag() { }
+
+ public LongTag(long value)
+ {
+ this.value = value;
+ }
+
+ public static LongTag ValueOf(long value)
+ {
+ return new LongTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ value = data.ReadLong();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteLong(value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Long;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is long) value = val;
+ }
+
+ public override dynamic GetValue()
+ {
+ return value;
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{value}L");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ long val = long.Parse(reader.ReadNumber());
+ value = val;
+
+ reader.Expect('l');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/ShortTag.cs b/NBT/ShortTag.cs
new file mode 100644
index 0000000..f5150c4
--- /dev/null
+++ b/NBT/ShortTag.cs
@@ -0,0 +1,65 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class ShortTag : Tag
+ {
+ public short value { get; private set; }
+ = 0;
+ public ShortTag() { }
+
+ public ShortTag(short value)
+ {
+ this.value = value;
+ }
+
+ public static ShortTag ValueOf(short value)
+ {
+ return new ShortTag(value);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ value = data.ReadShort();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteShort(value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.Short;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is short) value = val;
+ }
+
+ public override dynamic GetValue()
+ {
+ return value;
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{value}S");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ short val = short.Parse(reader.ReadNumber());
+ value = val;
+
+ reader.Expect('s');
+ }
+ }
+}
\ No newline at end of file
diff --git a/NBT/StringTag.cs b/NBT/StringTag.cs
new file mode 100644
index 0000000..959ea35
--- /dev/null
+++ b/NBT/StringTag.cs
@@ -0,0 +1,73 @@
+using System;
+using LibAC.NBT.API;
+
+namespace LibAC.NBT
+{
+ public class StringTag : Tag
+ {
+ public string value { get; private set; } = "";
+
+ public StringTag() { }
+
+ public StringTag(string str)
+ {
+ value = str;
+ }
+
+ public static StringTag ValueOf(string str)
+ {
+ return new StringTag(str);
+ }
+
+ public override void ReadValue(ByteLayer data)
+ {
+ value = data.ReadString();
+ }
+
+ public override void WriteValue(ByteLayer data)
+ {
+ data.WriteString(value);
+ }
+
+ public override TagType GetTagType()
+ {
+ return TagType.String;
+ }
+
+ public override void SetValue(dynamic val)
+ {
+ if (val is string) value = val;
+ }
+
+ public override dynamic GetValue()
+ {
+ return value;
+ }
+
+ public override void PrettyPrint(int indent, bool recurse)
+ {
+ Console.WriteLine($"{new string('\t', indent)}{Tag.GetCanonicalName(GetTagType())}: {value}");
+ }
+
+ public override void WriteStringifiedValue(StringBuilder builder, int indent, bool isList)
+ {
+ if (ShouldQuote(value))
+ builder.Append($"{(isList ? new string('\t', indent) : "")}\"{value}\"");
+ else
+ builder.Append($"{(isList ? new string('\t', indent) : "")}{value}");
+ }
+
+ public override void ReadStringifiedValue(StringReader reader)
+ {
+ string str = reader.ReadString();
+ value = str;
+ }
+
+ // This method will need to be implemented for checking if a string should be quoted
+ private bool ShouldQuote(string str)
+ {
+ // Implement logic for determining if the string needs to be quoted
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Serialization/NBTReader.cs b/Serialization/NBTReader.cs
deleted file mode 100644
index 10bb6b1..0000000
--- a/Serialization/NBTReader.cs
+++ /dev/null
@@ -1,236 +0,0 @@
-// DISCLAIMER: Taken from fNBT to be altered to fit the needs of ZNI NBT
-// All credit for the implementation of this file should go to the fNBT Authors, unless stated otherwise by comment!
-
-
-using LibAC.Serialization.ACFile;
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Text;
-
-namespace LibAC.Serialization
-{
- /// BinaryReader wrapper that takes care of reading primitives from an NBT stream,
- /// while taking care of endianness, string encoding, and skipping.
- public sealed class NBTReader : BinaryReader
- {
- readonly byte[] buffer = new byte[sizeof(double)];
-
- byte[] seekBuffer;
- const int SeekBufferSize = 8 * 1024;
- readonly bool swapNeeded;
- readonly byte[] stringConversionBuffer = new byte[64];
-
-
- public NBTReader(Stream input, bool bigEndian)
- : base(input)
- {
- swapNeeded = (BitConverter.IsLittleEndian == bigEndian);
- }
-
-
- public TagType ReadTagType()
- {
- int type = ReadByte();
- if (type < 0)
- {
- throw new EndOfStreamException();
- }
- else if (type > (int)TagType.UUID) // ZNI: Other data types are supported
- {
- throw new Exception("NBT tag type out of range: " + type);
- }
- return (TagType)type;
- }
-
-
- public override short ReadInt16()
- {
- if (swapNeeded)
- {
- return Swap(base.ReadInt16());
- }
- else
- {
- return base.ReadInt16();
- }
- }
-
-
- public override int ReadInt32()
- {
- if (swapNeeded)
- {
- return Swap(base.ReadInt32());
- }
- else
- {
- return base.ReadInt32();
- }
- }
-
-
- public override long ReadInt64()
- {
- if (swapNeeded)
- {
- return Swap(base.ReadInt64());
- }
- else
- {
- return base.ReadInt64();
- }
- }
-
-
- public override float ReadSingle()
- {
- if (swapNeeded)
- {
- FillBuffer(sizeof(float));
- Array.Reverse(buffer, 0, sizeof(float));
- return BitConverter.ToSingle(buffer, 0);
- }
- else
- {
- return base.ReadSingle();
- }
- }
-
-
- public override double ReadDouble()
- {
- if (swapNeeded)
- {
- FillBuffer(sizeof(double));
- Array.Reverse(buffer);
- return BitConverter.ToDouble(buffer, 0);
- }
- return base.ReadDouble();
- }
-
-
- public override string ReadString()
- {
- short length = ReadInt16();
- if (length < 0)
- {
- throw new Exception("Negative string length given!");
- }
- if (length < stringConversionBuffer.Length)
- {
- int stringBytesRead = 0;
- while (stringBytesRead < length)
- {
- int bytesToRead = length - stringBytesRead;
- int bytesReadThisTime = BaseStream.Read(stringConversionBuffer, stringBytesRead, bytesToRead);
- if (bytesReadThisTime == 0)
- {
- throw new EndOfStreamException();
- }
- stringBytesRead += bytesReadThisTime;
- }
- return Encoding.UTF8.GetString(stringConversionBuffer, 0, length);
- }
- else
- {
- byte[] stringData = ReadBytes(length);
- if (stringData.Length < length)
- {
- throw new EndOfStreamException();
- }
- return Encoding.UTF8.GetString(stringData);
- }
- }
-
-
- public void Skip(int bytesToSkip)
- {
- if (bytesToSkip < 0)
- {
- throw new ArgumentOutOfRangeException("bytesToSkip");
- }
- else if (BaseStream.CanSeek)
- {
- BaseStream.Position += bytesToSkip;
- }
- else if (bytesToSkip != 0)
- {
- if (seekBuffer == null) seekBuffer = new byte[SeekBufferSize];
- int bytesSkipped = 0;
- while (bytesSkipped < bytesToSkip)
- {
- int bytesToRead = Math.Min(SeekBufferSize, bytesToSkip - bytesSkipped);
- int bytesReadThisTime = BaseStream.Read(seekBuffer, 0, bytesToRead);
- if (bytesReadThisTime == 0)
- {
- throw new EndOfStreamException();
- }
- bytesSkipped += bytesReadThisTime;
- }
- }
- }
-
-
- new void FillBuffer(int numBytes)
- {
- int offset = 0;
- do
- {
- int num = BaseStream.Read(buffer, offset, numBytes - offset);
- if (num == 0) throw new EndOfStreamException();
- offset += num;
- } while (offset < numBytes);
- }
-
-
- public void SkipString()
- {
- short length = ReadInt16();
- if (length < 0)
- {
- throw new Exception("Negative string length given!");
- }
- Skip(length);
- }
-
-
- [DebuggerStepThrough]
- static short Swap(short v)
- {
- unchecked
- {
- return (short)((v >> 8) & 0x00FF |
- (v << 8) & 0xFF00);
- }
- }
-
-
- [DebuggerStepThrough]
- static int Swap(int v)
- {
- unchecked
- {
- var v2 = (uint)v;
- return (int)((v2 >> 24) & 0x000000FF |
- (v2 >> 8) & 0x0000FF00 |
- (v2 << 8) & 0x00FF0000 |
- (v2 << 24) & 0xFF000000);
- }
- }
-
-
- [DebuggerStepThrough]
- static long Swap(long v)
- {
- unchecked
- {
- return (Swap((int)v) & uint.MaxValue) << 32 |
- Swap((int)(v >> 32)) & uint.MaxValue;
- }
- }
-
- // ZNI Removed selector. Not needed for the ZNI NBT implementation
- }
-}
diff --git a/Serialization/NBTWriter.cs b/Serialization/NBTWriter.cs
deleted file mode 100644
index 961cd1e..0000000
--- a/Serialization/NBTWriter.cs
+++ /dev/null
@@ -1,263 +0,0 @@
-// DISCLAIMER: Taken from fNBT to be altered to fit the needs of ZNI NBT
-// All credit for the implementation of this file should go to the fNBT Authors, unless stated otherwise by comment!
-
-using LibAC.Serialization.ACFile;
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Text;
-
-namespace LibAC.Serialization
-{
- /// BinaryWriter wrapper that writes NBT primitives to a stream,
- /// while taking care of endianness and string encoding, and counting bytes written.
- public sealed unsafe class NBTWriter
- {
- // Write at most 4 MiB at a time.
- public const int MaxWriteChunk = 4 * 1024 * 1024;
-
- // Encoding can be shared among all instances of NbtBinaryWriter, because it is stateless.
- static readonly UTF8Encoding Encoding = new UTF8Encoding(false, true);
-
- // Each instance has to have its own encoder, because it does maintain state.
- readonly Encoder encoder = Encoding.GetEncoder();
-
- public Stream BaseStream
- {
- get
- {
- stream.Flush();
- return stream;
- }
- }
-
- readonly Stream stream;
-
- // Buffer used for temporary conversion
- const int BufferSize = 256;
-
- // UTF8 characters use at most 4 bytes each.
- const int MaxBufferedStringLength = BufferSize / 4;
-
- // Each NbtBinaryWriter needs to have its own instance of the buffer.
- readonly byte[] buffer = new byte[BufferSize];
-
- // Swap is only needed if endianness of the runtime differs from desired NBT stream
- readonly bool swapNeeded;
-
-
- public NBTWriter( Stream input, bool bigEndian)
- {
- if (input == null) throw new ArgumentNullException("input");
- if (!input.CanWrite) throw new ArgumentException("Given stream must be writable", "input");
- stream = input;
- swapNeeded = (BitConverter.IsLittleEndian == bigEndian);
- }
-
-
- public void Write(byte value)
- {
- stream.WriteByte(value);
- }
-
-
- public void Write(TagType value)
- {
- stream.WriteByte((byte)value);
- }
-
-
- public void Write(short value)
- {
- unchecked
- {
- if (swapNeeded)
- {
- buffer[0] = (byte)(value >> 8);
- buffer[1] = (byte)value;
- }
- else
- {
- buffer[0] = (byte)value;
- buffer[1] = (byte)(value >> 8);
- }
- }
- stream.Write(buffer, 0, 2);
- }
-
-
- public void Write(int value)
- {
- unchecked
- {
- if (swapNeeded)
- {
- buffer[0] = (byte)(value >> 24);
- buffer[1] = (byte)(value >> 16);
- buffer[2] = (byte)(value >> 8);
- buffer[3] = (byte)value;
- }
- else
- {
- buffer[0] = (byte)value;
- buffer[1] = (byte)(value >> 8);
- buffer[2] = (byte)(value >> 16);
- buffer[3] = (byte)(value >> 24);
- }
- }
- stream.Write(buffer, 0, 4);
- }
-
-
- public void Write(long value)
- {
- unchecked
- {
- if (swapNeeded)
- {
- buffer[0] = (byte)(value >> 56);
- buffer[1] = (byte)(value >> 48);
- buffer[2] = (byte)(value >> 40);
- buffer[3] = (byte)(value >> 32);
- buffer[4] = (byte)(value >> 24);
- buffer[5] = (byte)(value >> 16);
- buffer[6] = (byte)(value >> 8);
- buffer[7] = (byte)value;
- }
- else
- {
- buffer[0] = (byte)value;
- buffer[1] = (byte)(value >> 8);
- buffer[2] = (byte)(value >> 16);
- buffer[3] = (byte)(value >> 24);
- buffer[4] = (byte)(value >> 32);
- buffer[5] = (byte)(value >> 40);
- buffer[6] = (byte)(value >> 48);
- buffer[7] = (byte)(value >> 56);
- }
- }
- stream.Write(buffer, 0, 8);
- }
-
-
- public void Write(float value)
- {
- ulong tmpValue = *(uint*)&value;
- unchecked
- {
- if (swapNeeded)
- {
- buffer[0] = (byte)(tmpValue >> 24);
- buffer[1] = (byte)(tmpValue >> 16);
- buffer[2] = (byte)(tmpValue >> 8);
- buffer[3] = (byte)tmpValue;
- }
- else
- {
- buffer[0] = (byte)tmpValue;
- buffer[1] = (byte)(tmpValue >> 8);
- buffer[2] = (byte)(tmpValue >> 16);
- buffer[3] = (byte)(tmpValue >> 24);
- }
- }
- stream.Write(buffer, 0, 4);
- }
-
-
- public void Write(double value)
- {
- ulong tmpValue = *(ulong*)&value;
- unchecked
- {
- if (swapNeeded)
- {
- buffer[0] = (byte)(tmpValue >> 56);
- buffer[1] = (byte)(tmpValue >> 48);
- buffer[2] = (byte)(tmpValue >> 40);
- buffer[3] = (byte)(tmpValue >> 32);
- buffer[4] = (byte)(tmpValue >> 24);
- buffer[5] = (byte)(tmpValue >> 16);
- buffer[6] = (byte)(tmpValue >> 8);
- buffer[7] = (byte)tmpValue;
- }
- else
- {
- buffer[0] = (byte)tmpValue;
- buffer[1] = (byte)(tmpValue >> 8);
- buffer[2] = (byte)(tmpValue >> 16);
- buffer[3] = (byte)(tmpValue >> 24);
- buffer[4] = (byte)(tmpValue >> 32);
- buffer[5] = (byte)(tmpValue >> 40);
- buffer[6] = (byte)(tmpValue >> 48);
- buffer[7] = (byte)(tmpValue >> 56);
- }
- }
- stream.Write(buffer, 0, 8);
- }
-
-
- // Based on BinaryWriter.Write(String)
- public void Write(string value)
- {
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
-
- // Write out string length (as number of bytes)
- int numBytes = Encoding.GetByteCount(value);
- Write((short)numBytes);
-
- if (numBytes <= BufferSize)
- {
- // If the string fits entirely in the buffer, encode and write it as one
- Encoding.GetBytes(value, 0, value.Length, buffer, 0);
- stream.Write(buffer, 0, numBytes);
- }
- else
- {
- // Aggressively try to not allocate memory in this loop for runtime performance reasons.
- // Use an Encoder to write out the string correctly (handling surrogates crossing buffer
- // boundaries properly).
- int charStart = 0;
- int numLeft = value.Length;
- while (numLeft > 0)
- {
- // Figure out how many chars to process this round.
- int charCount = (numLeft > MaxBufferedStringLength) ? MaxBufferedStringLength : numLeft;
- int byteLen;
- fixed (char* pChars = value)
- {
- fixed (byte* pBytes = buffer)
- {
- byteLen = encoder.GetBytes(pChars + charStart, charCount, pBytes, BufferSize,
- charCount == numLeft);
- }
- }
- stream.Write(buffer, 0, byteLen);
- charStart += charCount;
- numLeft -= charCount;
- }
- }
- }
-
-
- public void Write(byte[] data, int offset, int count)
- {
- int written = 0;
- while (written < count)
- {
- int toWrite = Math.Min(MaxWriteChunk, count - written);
- stream.Write(data, offset + written, toWrite);
- written += toWrite;
- }
- }
-
- // Aria : Added a NBT compatible shortcut method for writing a byte array with the length prefix
- public void Write(byte[] bytes)
- {
- this.Write(bytes.Length);
- this.Write(bytes, 0, bytes.Length);
- }
- }
-}
diff --git a/Serialization/Serializable.cs b/Serialization/Serializable.cs
deleted file mode 100644
index b25f565..0000000
--- a/Serialization/Serializable.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using LibAC.Serialization.ACFile;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization
-{
- public abstract class Serializable
- {
- public abstract void save(Folder f);
- public abstract void load(Folder f);
- }
-}
diff --git a/Serialization/SerializingHelper.cs b/Serialization/SerializingHelper.cs
deleted file mode 100644
index 6fe7b75..0000000
--- a/Serialization/SerializingHelper.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization
-{
- public static class SerializingHelper
- {
- private static int SEGMENT_BITS = 0x7F;
- private static int CONTINUE_BIT = 0x80;
- ///
- /// Adapted from code from wiki.vg
- ///
- ///
- ///
- public static void WriteVarInt(this BinaryWriter bw, int value)
- {
- while (true)
- {
- if ((value & ~SEGMENT_BITS) == 0)
- {
- bw.Write((byte)value);
- return;
- }
-
- byte b = (byte)((value & SEGMENT_BITS) | CONTINUE_BIT);
- bw.Write(b);
-
- value >>>= 7;
- }
- }
-
- public static int ReadVarInt(this BinaryReader br)
- {
- int value = 0;
- int position = 0;
- byte curByte;
-
- while (true)
- {
- curByte = br.ReadByte();
- value |= (curByte & SEGMENT_BITS) << position;
- if ((curByte & CONTINUE_BIT) == 0) break;
-
- position += 7;
-
- if (position >= 32) throw new VarIntSizeException("Too large");
- }
-
- return value;
- }
-
- public static void WriteVarLong(this BinaryWriter bw, long value)
- {
- while (true)
- {
- if ((value & ~((long)SEGMENT_BITS)) == 0)
- {
- byte bx = (byte)value;
- bw.Write(bx);
- return;
- }
- byte b = (byte)((value & SEGMENT_BITS) | CONTINUE_BIT);
- bw.Write(b);
- value >>>= 7;
- }
- }
-
- public static long ReadVarLong(this BinaryReader br)
- {
- long value = 0;
- int position = 0;
- byte curByte;
- while (true)
- {
- curByte = br.ReadByte();
- value |= (long)(curByte & SEGMENT_BITS) << position;
-
- if ((curByte & CONTINUE_BIT) == 0) break;
-
- position += 7;
-
- if (position >= 64) throw new VarLongSizeException("Too large");
- }
-
- return value;
- }
-
- ///
- /// Applies ZigZag Encoding to the integer
- ///
- ///
- ///
- public static int ZigZag(this int i)
- {
- return Math.Abs((i + i) + ((i < 0) ? 1 : 0));
- }
- ///
- /// Undoes the zigzag encoding on a integer
- ///
- ///
- ///
- public static int DeZigZag(this int i)
- {
- if ((i % 2) == 0)
- {
- // Even number. Divide by two
- return (i / 2);
- }
- else
- {
- int x = i - 1;
- x = -i;
- return x;
- }
- }
-
-
- ///
- /// Applies ZigZag Encoding to the integer
- ///
- ///
- ///
- public static long ZigZag(this long i)
- {
- return Math.Abs((i + i) + ((i < 0L) ? 1L : 0L));
- }
- ///
- /// Undoes the zigzag encoding on a integer
- ///
- ///
- ///
- public static long DeZigZag(this long i)
- {
- if ((i % 2) == 0)
- {
- // Even number. Divide by two
- return (i / 2L);
- }
- else
- {
- long x = i - 1L;
- x = -i;
- return x;
- }
- }
-
-
- }
-
- public class VarIntSizeException : Exception
- {
- public VarIntSizeException(string Message) : base(Message) { }
- }
- public class VarLongSizeException : Exception
- {
- public VarLongSizeException(string Message) : base(Message) { }
- }
-}
diff --git a/Serialization/TagIO.cs b/Serialization/TagIO.cs
deleted file mode 100644
index 0041033..0000000
--- a/Serialization/TagIO.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using LibAC.Serialization.ACFile;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization
-{
- ///
- /// This class contains helper functions for interacting with streams and files that are encoded using ZNIFile's structure
- /// Additionally, this provides a overlay as it interacts with the final data set, and can compress and or encrypt.
- ///
- public static class TagIO
- {
- public static void WriteOnStream(Stream s, Tag x)
- {
- NBTWriter bw = new NBTWriter(s, true);
- x.WriteTag(bw);
- x.WriteData(bw);
- }
-
- public static Folder ReadFromStream(Stream s)
- {
- try
- {
-
- Folder folder = new Folder();
- NBTReader br = new NBTReader(s,true);
- TagType type = (TagType)br.ReadByte();
- if (type == TagType.FOLDER)
- {
- // Read the file!
- folder.ReadTag(br);
- }
-
- return folder;
- }catch(Exception e)
- {
- return new Folder();
- }
- }
-
- public static void SaveToFile(string FileName, Tag x, bool gz=false)
- {
- if(File.Exists(FileName))File.Delete(FileName);
- Stream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
- if (gz){
- fs = new GZipStream(fs, CompressionLevel.SmallestSize);
- }
- WriteOnStream(fs, x);
- fs.Close();
- }
- public static Folder ReadFromFile(string FileName, bool gz = false)
- {
- Stream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
- if (gz)
- {
- fs = new GZipStream(fs, CompressionMode.Decompress);
- }
- Folder f = ReadFromStream(fs);
- fs.Close();
- return f;
- }
- }
-}
diff --git a/Serialization/ZNIFile/BoolTag.cs b/Serialization/ZNIFile/BoolTag.cs
deleted file mode 100644
index 067b9b4..0000000
--- a/Serialization/ZNIFile/BoolTag.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class BoolTag : Tag
- {
- private bool BoolVal;
- public bool Value
- {
- get
- {
- return BoolVal;
- }
- }
-
- public BoolTag(string _Name, bool val)
- {
- Name = _Name;
- BoolVal = val;
- }
- public BoolTag(bool boolVal) : this(null, boolVal)
- {
- }
- public BoolTag() : this(null, false) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.BOOL;
- }
- }
- public override bool ReadTag(NBTReader br)
- {
- throw new NotImplementedException();
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new BoolTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- Folder vFolder = new Folder(Name);
- vFolder.Add(new ByteTag("val", (byte)(Value ? 1 : 0)));
- vFolder.Add(new ByteTag("_virtcast_", (byte)Type));
- if(Parent != null)
- {
- if(Parent.Type == TagType.LIST)
- {
- vFolder.Add(new StringTag("name", Name));
- }
- }
- vFolder.WriteTag(bw);
- vFolder.WriteData(bw);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
-
- }
-
- public override object Clone()
- {
- return new BoolTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- if (!F.HasNamedTag("name"))
- Name = F.Name;
- else Name = F["name"].StringValue;
-
- int ret = F["val"].IntValue;
- if (ret == 1) BoolVal = true;
- else BoolVal = false;
-
-
- }
-
- }
-}
diff --git a/Serialization/ZNIFile/ByteArrayTag.cs b/Serialization/ZNIFile/ByteArrayTag.cs
deleted file mode 100644
index 8ffe556..0000000
--- a/Serialization/ZNIFile/ByteArrayTag.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class ByteArrayTag : Tag
- {
- private byte[] BArrVal;
- public byte[] Value
- {
- get
- {
- return BArrVal;
- }
- }
-
- public ByteArrayTag(string _Name, byte[] val)
- {
- Name = _Name;
- BArrVal = val;
- }
- public ByteArrayTag(byte[] boolVal) : this(null, boolVal)
- {
- }
- public ByteArrayTag() : this(null, new byte[] {}) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.BYTEARRAY;
- }
- }
- public override bool ReadTag(NBTReader br)
- {
- if(!(Parent!= null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- BArrVal = br.ReadBytes(br.ReadInt32());
-
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new ByteArrayTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
-
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
-
- }
-
- public override object Clone()
- {
- return new ByteArrayTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
-
- }
-}
diff --git a/Serialization/ZNIFile/ByteTag.cs b/Serialization/ZNIFile/ByteTag.cs
deleted file mode 100644
index 06cb0bb..0000000
--- a/Serialization/ZNIFile/ByteTag.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class ByteTag : Tag
- {
- private byte ByteVal;
- public byte Value
- {
- get
- {
- return ByteVal;
- }
- }
-
- public ByteTag(string _Name, byte val)
- {
- Name = _Name;
- ByteVal = val;
- }
- public ByteTag(byte _ByteVal) : this(null, _ByteVal)
- {
- }
- public ByteTag() : this(null, 0) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.BYTE;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
-
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- ByteVal = br.ReadByte();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new ByteTag().ReadTag(br);
- }
-
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
- }
-
- public override object Clone()
- {
- return new ByteTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
-
- }
-}
diff --git a/Serialization/ZNIFile/DoubleTag.cs b/Serialization/ZNIFile/DoubleTag.cs
deleted file mode 100644
index 1b30627..0000000
--- a/Serialization/ZNIFile/DoubleTag.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class DoubleTag : Tag
- {
- public override TagType Type
- {
- get
- {
- return TagType.DOUBLE;
- }
- }
-
- private double DoubleVal;
- public double Value
- {
- get
- {
- return DoubleVal;
- }
- }
-
- public DoubleTag() : this(null, 0) { }
- public DoubleTag(double Val) : this(null, Val) { }
- public DoubleTag(string DName, double val)
- {
- Name = DName;
- DoubleVal = val;
- }
-
- public override object Clone()
- {
- return new DoubleTag(Name, Value);
- }
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- DoubleVal = br.ReadDouble();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new DoubleTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/FloatTag.cs b/Serialization/ZNIFile/FloatTag.cs
deleted file mode 100644
index 7557c5b..0000000
--- a/Serialization/ZNIFile/FloatTag.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class FloatTag : Tag
- {
- private float FloatVal;
- public float Value
- {
- get
- {
- return FloatVal;
- }
- }
-
- public FloatTag(string _Name, float val)
- {
- Name = _Name;
- FloatVal = val;
- }
- public FloatTag(float _FloatVal) : this(null, _FloatVal)
- {
- }
- public FloatTag() : this(null, 0f) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.FLOAT;
- }
- }
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- FloatVal = br.ReadSingle();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new FloatTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
- }
-
- public override object Clone()
- {
- return new FloatTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/Folder.cs b/Serialization/ZNIFile/Folder.cs
deleted file mode 100644
index 81cd982..0000000
--- a/Serialization/ZNIFile/Folder.cs
+++ /dev/null
@@ -1,293 +0,0 @@
-using Microsoft.VisualBasic;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Reflection.Metadata.Ecma335;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class Folder : Tag, ICollection, ICollection
- {
- public Folder() { }
- public Folder(string name)
- {
- this.Name = name;
- }
- public Collection Tags { get; set; } = new Collection();
- public override TagType Type
- {
- get
- {
- return TagType.FOLDER;
- }
- }
-
- public int Count
- {
- get
- {
- return Tags.Count;
- }
- }
-
- public bool IsReadOnly
- {
- get
- {
- return false;
- }
- }
-
- public object SyncRoot
- {
- get
- {
- return (Tags as ICollection).SyncRoot;
- }
- }
-
- bool ICollection.IsSynchronized
- {
- get
- {
- return false;
- }
- }
-
- public void Add(Tag item)
- {
- if (item == null) throw new Exception("Bad item!");
-
- Tags.Add(item);
- item.Parent = this;
- }
-
- public override Tag this[int index]
- {
- get
- {
- return Tags.ElementAt(index);
- }
- set
- {
- try
- {
-
- string TagName = Tags.ElementAt(index).Name;
- this[TagName] = value;
- }
- catch(Exception e)
- {
- Tags.Add(value);
- }
-
- }
- }
- public override Tag this[string index]
- {
- get
- {
- return Tags.Where(x => x.Name == index).FirstOrDefault();
- }
- set
- {
- if(Tags.Select(x=>x.Name == index).Count() != 0)
- {
- Tags.RemoveAt(Tags.IndexOf(Tags.Where(x => x.Name == index).FirstOrDefault()));
- }
-
- Tags.Add(value);
- }
- }
-
- public void Clear()
- {
- foreach(Tag t in Tags)
- {
- t.Parent = null;
- }
- Tags = new Collection();
- }
-
- public bool Contains(Tag item)
- {
- return Tags.Contains(item);
- }
-
- public void CopyTo(Tag[] array, int arrayIndex)
- {
- Tags.CopyTo(array, arrayIndex);
- }
-
- public void CopyTo(Array array, int index)
- {
- CopyTo((Tag[])array, index);
- }
-
- public IEnumerator GetEnumerator()
- {
- return Tags.GetEnumerator();
- }
-
- public bool Remove(Tag item)
- {
- return Tags.Remove(item);
- }
-
-
- public override bool ReadTag(NBTReader br)
- {
- // Aria: Removed a return on parent not being null because that is how the ZNI Parsing system works.
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
-
-
- while (true)
- {
- TagType next = br.ReadTagType();
- Tag _next = null;
- switch (next)
- {
- case TagType.FOLDER:
- _next = new Folder();
- break;
- case TagType.BYTE:
- _next = new ByteTag();
- break;
- case TagType.DOUBLE:
- _next = new DoubleTag();
- break;
- case TagType.FLOAT:
- _next = new FloatTag();
- break;
- case TagType.INTEGER:
- _next = new IntTag();
- break;
- case TagType.LIST:
- _next = new ListTag();
- break;
- case TagType.LONG:
- _next = new LongTag();
- break;
- case TagType.STRING:
- _next = new StringTag();
- break;
- case TagType.BYTEARRAY:
- _next = new ByteArrayTag();
- break;
- case TagType.INTARRAY:
- _next = new IntArrayTag();
- break;
- case TagType.LONGARRAY:
- _next = new LongArrayTag();
- break;
- case TagType.END:
- return true;
-
- case TagType.SHORT:
- _next = new ShortTag();
- break;
- }
- _next.Parent = this;
-
- if (_next.ReadTag(br))
- {
- if (_next.Type == TagType.FOLDER)
- {
- Folder NextTag = _next as Folder;
- if (NextTag.HasNamedTag("_virtcast_"))
- {
- ByteTag bt = NextTag["_virtcast_"] as ByteTag;
- next = (TagType)bt.Value;
- Tag temp = null;
- switch (next)
- {
- case TagType.BOOL:
- temp = new BoolTag();
- temp.CastFrom(NextTag);
- break;
- case TagType.ULONG:
- temp = new uLongTag();
- temp.CastFrom(NextTag);
- break;
- case TagType.UUID:
- temp = new UUIDTag();
- temp.CastFrom(NextTag);
- break;
- }
- _next = temp;
- }
-
- }
- Tags.Add(_next);
- }
- }
- return true;
- }
-
- public bool HasNamedTag(string Name)
- {
- foreach(Tag t in Tags)
- {
- if(t.Name == Name) return true;
- }
- return false;
- }
-
-
- public override void SkipTag(NBTReader br)
- {
- _ = new Folder().ReadTag(br);
- }
-
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- foreach (Tag t in Tags)
- {
- t.WriteTag(bw);
- t.WriteData(bw);
- }
- bw.Write(TagType.END);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type); // Write int (0), folder
-
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- public override void Rename(string old, string newName)
- {
- // do nothing. The folder's collection will be automatically updated.
- }
-
- public override object Clone()
- {
- return new Folder(this);
- }
-
- public Folder(Folder existing)
- {
- Name = existing.Name;
- Tags = new Collection(Tags.ToArray());
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/IntArrayTag.cs b/Serialization/ZNIFile/IntArrayTag.cs
deleted file mode 100644
index e856eb1..0000000
--- a/Serialization/ZNIFile/IntArrayTag.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class IntArrayTag : Tag
- {
- private int[] BArrVal;
- public int[] Value
- {
- get
- {
- return BArrVal;
- }
- }
-
- public IntArrayTag(string _Name, int[] val)
- {
- Name = _Name;
- BArrVal = val;
- }
- public IntArrayTag(int[] boolVal) : this(null, boolVal)
- {
- }
- public IntArrayTag() : this(null, new int[] {}) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.INTARRAY;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
-
- int count = br.ReadInt32();
-
- BArrVal = new int[count];
- for (int i = 0; i < count; i++)
- {
- BArrVal[i] = br.ReadInt32();
- }
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new IntArrayTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
-
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value.Length);
-
- foreach (int i in Value)
- {
- bw.Write(i);
- }
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
- }
-
- public override object Clone()
- {
- return new IntArrayTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/IntTag.cs b/Serialization/ZNIFile/IntTag.cs
deleted file mode 100644
index b4ee5a8..0000000
--- a/Serialization/ZNIFile/IntTag.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class IntTag : Tag
- {
-
- public IntTag() : this(null, 0)
- { }
- public IntTag(int Value) : this(null, Value)
- {
- }
- public IntTag(string _Name, int Val)
- {
- this.Name = _Name;
- IntVal = Val;
- }
- private int IntVal;
- public int Value
- {
- get
- {
- return IntVal;
- }
- }
- public override TagType Type
- {
- get
- {
- return TagType.INTEGER;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
-
- IntVal = br.ReadInt32();
- return true;
- }
-
-
- public override void SkipTag(NBTReader br)
- {
- _ = new IntTag().ReadTag(br);
- }
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value);
- }
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override object Clone()
- {
- return new IntTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/ListTag.cs b/Serialization/ZNIFile/ListTag.cs
deleted file mode 100644
index a872962..0000000
--- a/Serialization/ZNIFile/ListTag.cs
+++ /dev/null
@@ -1,335 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using static System.Net.Mime.MediaTypeNames;
-
-namespace LibAC.Serialization.ACFile
-{
- public class ListTag : Tag, IList, IList
- {
- private TagType _subtype = TagType.INVALID;
- private List _tags;
- public List Value
- {
- get
- {
- return _tags;
- }
- }
-
- public ListTag() : this(TagType.STRING, null, new List())
- {
- }
- public ListTag(TagType sub) : this(sub, null, new List()) { }
- public ListTag(TagType sub, string name) : this(sub,name, new List()) { }
- public ListTag(TagType sub, string name, List tags)
- {
- _tags = tags;
- Name = name;
- setSubtype(sub);
- }
- public void setSubtype(TagType itemTypes)
- {
- _subtype = itemTypes;
- }
- public TagType getListType()
- {
- return _subtype;
- }
- public override TagType Type
- {
- get
- {
- return TagType.LIST;
- }
- }
-
- public bool IsFixedSize
- {
- get
- {
- return false;
- }
- }
-
- public bool IsReadOnly
- {
- get
- {
- return false;
- }
- }
-
- public int Count
- {
- get
- {
- return _tags.Count;
- }
- }
-
- public bool IsSynchronized
- {
- get
- {
- return false;
- }
- }
-
- public object SyncRoot
- {
- get
- {
- return ((IList)_tags).SyncRoot;
- }
- }
-
- object IList.this[int index]
- {
- get
- {
- return _tags[index];
- }
- set
- {
- if (_tags.Count >= index) _tags[index] = (Tag)value;
- else _tags.Add((Tag)value);
- }
- }
-
- public override object Clone()
- {
- throw new NotImplementedException();
- }
-
- public override bool ReadTag(NBTReader br)
- {
- //_subtype = (TagType)br.ReadInt32();
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- _subtype = br.ReadTagType();
- int count = br.ReadInt32();
- TagType next = _subtype;
- for (int i = 0; i < count; i++)
- {
- Tag _next = null;
- // read sub-tags
- switch (next)
- {
- case TagType.FOLDER:
- _next = new Folder();
- break;
- case TagType.BOOL:
- _next = new BoolTag();
- break;
- case TagType.BYTE:
- _next = new ByteTag();
- break;
- case TagType.DOUBLE:
- _next = new DoubleTag();
- break;
- case TagType.FLOAT:
- _next = new FloatTag();
- break;
- case TagType.INTEGER:
- _next = new IntTag();
- break;
- case TagType.LIST:
- _next = new ListTag();
- break;
- case TagType.LONG:
- _next = new LongTag();
- break;
- case TagType.STRING:
- _next = new StringTag();
- break;
- case TagType.BYTEARRAY:
- _next = new ByteArrayTag();
- break;
- case TagType.INTARRAY:
- _next = new IntArrayTag();
- break;
- case TagType.LONGARRAY:
- _next = new LongArrayTag();
- break;
- case TagType.SHORT:
- _next = new ShortTag();
- break;
- }
- _next.Parent = this;
- if (_next.ReadTag(br))
- {
- if (_next.Type == TagType.FOLDER)
- {
- Folder nxt = _next as Folder;
- if (nxt.HasNamedTag("_virtcast_"))
- {
- TagType tag = (TagType)nxt["_virtcast_"].ByteValue;
- Tag temp = null;
- switch (tag)
- {
- case TagType.BOOL:
- temp = new BoolTag();
- temp.CastFrom(nxt);
- break;
- case TagType.ULONG:
- temp = new uLongTag();
- temp.CastFrom(nxt);
- break;
- case TagType.UUID:
- temp = new UUIDTag();
- temp.CastFrom(nxt);
- break;
-
- }
- _next = temp;
- }
- }
- _tags.Add(_next);
- }
-
-
- }
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new ListTag(_subtype).ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
-
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(_subtype);
- bw.Write(_tags.Count);
-
- foreach (Tag x in _tags)
- {
- x.WriteData(bw);
- }
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
-
-
- //bw.Write(((int)TagType.END));
- }
-
- public int Add(object value)
- {
- if (value is Tag)
- {
- Tag tx = (Tag)value;
- Add(tx);
- return _tags.IndexOf(tx);
- }
- else return -1;
- }
-
- public void Clear()
- {
- foreach(Tag x in _tags)
- {
- x.Parent = null;
- }
- _tags.Clear();
- }
-
- public bool Contains(object value)
- {
- throw new NotImplementedException();
- }
-
- public int IndexOf(object value)
- {
- if (!(value is Tag)) return -1;
- return _tags.IndexOf((Tag)value);
- }
-
- public void Insert(int index, object value)
- {
- throw new NotImplementedException();
- }
-
- public void Remove(object value)
- {
- throw new NotImplementedException();
- }
-
- public void RemoveAt(int index)
- {
- throw new NotImplementedException();
- }
-
- public void CopyTo(Array array, int index)
- {
- throw new NotImplementedException();
- }
-
- public IEnumerator GetEnumerator()
- {
- return _tags.GetEnumerator();
- }
-
- public int IndexOf(Tag item)
- {
- return _tags.IndexOf(item);
- }
-
- public void Insert(int index, Tag item)
- {
- throw new NotImplementedException();
- }
-
- public void Add(Tag item)
- {
- item.Parent = this;
- _tags.Add(item);
- }
-
- public bool Contains(Tag item)
- {
- return _tags.Contains(item);
- }
-
- public void CopyTo(Tag[] array, int arrayIndex)
- {
- throw new NotImplementedException();
- }
-
- public bool Remove(Tag item)
- {
- if (Contains(item))
- {
- item.Parent = null;
- _tags.Remove(item);
- return true;
- }
- else return false;
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return _tags.GetEnumerator();
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/LongArrayTag.cs b/Serialization/ZNIFile/LongArrayTag.cs
deleted file mode 100644
index d0a580f..0000000
--- a/Serialization/ZNIFile/LongArrayTag.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class LongArrayTag : Tag
- {
- private long[] BArrVal;
- public long[] Value
- {
- get
- {
- return BArrVal;
- }
- }
-
- public LongArrayTag(string _Name, long[] val)
- {
- Name = _Name;
- BArrVal = val;
- }
- public LongArrayTag(long[] boolVal) : this(null, boolVal)
- {
- }
- public LongArrayTag() : this(null, new long[] {}) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.LONGARRAY;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- int count = br.ReadVarInt();
- BArrVal = new long[count];
- for(int i = 0; i < count; i++)
- {
- BArrVal[i] = br.ReadInt64();
- }
-
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new LongArrayTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
- bw.Write(Value.Length);
-
- foreach (long i in Value)
- {
- bw.Write(i);
- }
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
- }
-
- public override object Clone()
- {
- return new LongArrayTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/LongTag.cs b/Serialization/ZNIFile/LongTag.cs
deleted file mode 100644
index bd89fa2..0000000
--- a/Serialization/ZNIFile/LongTag.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class LongTag : Tag
- {
- private long LongVal;
- public long Value
- {
- get
- {
- return LongVal;
- }
- }
-
- public LongTag(string _Name, long val)
- {
- Name = _Name;
- LongVal = val;
- }
- public LongTag(long _LongVal) : this(null, _LongVal)
- {
- }
- public LongTag() : this(null, 0) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.LONG;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- LongVal = br.ReadInt64();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new LongTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
-
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
- }
-
- public override object Clone()
- {
- return new LongTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/ShortTag.cs b/Serialization/ZNIFile/ShortTag.cs
deleted file mode 100644
index c6a36d3..0000000
--- a/Serialization/ZNIFile/ShortTag.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class ShortTag : Tag
- {
- private short FloatVal;
- public short Value
- {
- get
- {
- return FloatVal;
- }
- }
-
- public ShortTag(string _Name, short val)
- {
- Name = _Name;
- FloatVal = val;
- }
- public ShortTag(short _FloatVal) : this(null, _FloatVal)
- {
- }
- public ShortTag() : this(null, 0) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.SHORT;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- FloatVal = br.ReadInt16();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new ShortTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
-
- bw.Write(Value);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
- }
-
- public override object Clone()
- {
- return new ShortTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/StringTag.cs b/Serialization/ZNIFile/StringTag.cs
deleted file mode 100644
index 8133a55..0000000
--- a/Serialization/ZNIFile/StringTag.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class StringTag : Tag
- {
- private string StrVal;
- public string Value
- {
- get
- {
- return StrVal;
- }
- }
-
- public override TagType Type
- {
- get
- {
- return TagType.STRING;
- }
- }
-
- public StringTag() : this(null, "")
- { }
- public StringTag(string Value) : this(null, Value)
- {
- }
- public StringTag(string _Name, string Val)
- {
- this.Name = _Name;
- StrVal = Val;
- }
-
- public override bool ReadTag(NBTReader br)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- Name = br.ReadString();
- StrVal = br.ReadString();
- return true;
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new StringTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- if (!(Parent != null && Parent.Type == TagType.LIST))
- bw.Write(Name);
-
- bw.Write(StrVal);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- bw.Write(Type);
- }
-
- public override object Clone()
- {
- return new StringTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/Serialization/ZNIFile/Tag.cs b/Serialization/ZNIFile/Tag.cs
deleted file mode 100644
index f379855..0000000
--- a/Serialization/ZNIFile/Tag.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public abstract class Tag : ICloneable, IComparable
- {
- public Tag Parent { get; internal set; }
- public abstract TagType Type { get; }
-
- public bool HasValue
- {
- get
- {
- switch(Type)
- {
- case TagType.FOLDER:
- case TagType.LIST:
- case TagType.END:
- case TagType.INVALID:
- return false;
- default:
- return true;
-
- }
- }
- }
-
- internal string _Name="";
- public string Name
- {
- get
- {
- return _Name;
- }
- set
- {
- if (_Name == value) return;
- if (value == null)
- {
- value = "";
- }
- Folder f = Parent as Folder;
- if(f != null)
- {
- f.Rename(_Name, value);
- }
- _Name = value;
- }
- }
-
- public abstract bool ReadTag(NBTReader br);
- public abstract void SkipTag(NBTReader br);
- public abstract void WriteTag(NBTWriter bw);
- public abstract void WriteData(NBTWriter bw);
-
- public abstract void CastFrom(Folder F);
-
- private string Error = "Invalid tag type";
- public virtual Tag this[int index]
- {
- get
- {
- throw new InvalidOperationException(Error);
- }
- set
- {
- throw new InvalidOperationException(Error);
- }
- }
-
- public virtual Tag this[string index]
- {
- get
- {
- throw new InvalidOperationException(Error);
- }
- set
- {
- throw new InvalidOperationException(Error);
- }
- }
-
- public static string GetCanonicalName(TagType type)
- {
- switch(type)
- {
- case TagType.FOLDER:
- {
- return "Folder";
- }
- case TagType.STRING:
- {
- return "String";
- }
- case TagType.INTEGER:
- {
- return "Integer";
- }
- case TagType.LIST:
- {
- return "List";
- }
- case TagType.BOOL:
- {
- return "Bool";
- }
- case TagType.DOUBLE:
- {
- return "Double";
- }
- case TagType.FLOAT:
- {
- return "Float";
- }
- case TagType.LONG:
- {
- return "Long";
- }
- case TagType.BYTE:
- {
- return "Invalid";
- }
- }
- return "Invalid";
- }
-
- public string StringValue
- {
- get
- {
- switch(Type)
- {
- case TagType.STRING:
- {
- return (this as StringTag).Value;
- }
- default:
- {
- throw new Exception("Invalid type");
- }
- }
- }
- }
-
- public int IntValue
- {
- get
- {
- switch (Type)
- {
- case TagType.INTEGER:
- return (this as IntTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
-
- public bool BoolValue
- {
- get
- {
- switch (Type)
- {
- case TagType.BOOL:
- return (this as BoolTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public double DoubleValue
- {
- get
- {
- switch (Type)
- {
- case TagType.DOUBLE:
- return (this as DoubleTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public float FloatValue
- {
- get
- {
- switch (Type)
- {
- case TagType.FLOAT:
- return (this as FloatTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public long LongValue
- {
- get
- {
- switch (Type)
- {
- case TagType.LONG:
- return (this as LongTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public byte ByteValue
- {
- get
- {
- switch (Type)
- {
- case TagType.BYTE:
- return (this as ByteTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public ulong uLongValue
- {
- get
- {
- switch (Type)
- {
- case TagType.ULONG:
- return (this as uLongTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
- public Guid UUIDValue
- {
- get
- {
- switch (Type)
- {
- case TagType.UUID:
- return (this as UUIDTag).Value;
- default:
- throw new Exception("Invalid type");
- }
- }
- }
-
- public abstract void Rename(string old, string newName);
-
- public abstract object Clone();
-
- public int CompareTo(Tag other)
- {
- if (ID == other.ID) return 0;
- else return 1;
- }
-
- private Guid ID { get; set; } = Guid.NewGuid();
- }
-}
diff --git a/Serialization/ZNIFile/TagType.cs b/Serialization/ZNIFile/TagType.cs
deleted file mode 100644
index 98f4e29..0000000
--- a/Serialization/ZNIFile/TagType.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- // Aria: Changed to a type of byte which keeps it to only one byte when writing out in serializing
- public enum TagType : byte
- {
- END = 0x00, // Present at the end of a folder
- BYTE = 0x01,
- SHORT = 0x02,
- INTEGER = 0x03,
- LONG = 0x04,
- FLOAT = 0x05,
- DOUBLE = 0x06,
- BYTEARRAY = 0x07,
- STRING = 0x08,
- LIST = 0x09, // List can be any valid Tag Type
- FOLDER = 0x0A,
- INTARRAY = 0x0B,
- LONGARRAY = 0x0C,
- BOOL = 0x0D,
- ULONG=0x0E,
- UUID=0x0F,
-
-
-
- INVALID=0xFF
- }
-}
diff --git a/Serialization/ZNIFile/UUIDTag.cs b/Serialization/ZNIFile/UUIDTag.cs
deleted file mode 100644
index b0ab1e2..0000000
--- a/Serialization/ZNIFile/UUIDTag.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class UUIDTag : Tag
- {
- private Guid LongVal;
- public Guid Value
- {
- get
- {
- return LongVal;
- }
- }
- public static UUIDTag Random(string sName)
- {
- UUIDTag rnd = new UUIDTag(sName, Guid.NewGuid());
-
- return rnd;
- }
-
- public static UUIDTag Empty(string sName)
- {
- UUIDTag z = new UUIDTag(sName, Guid.Empty);
- return z;
- }
-
- public UUIDTag(string _Name, Guid val)
- {
- Name = _Name;
- LongVal = val;
- }
- public UUIDTag(Guid _LongVal) : this(null, _LongVal)
- {
- }
- public UUIDTag() : this(null, Guid.Empty) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.UUID;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- throw new Exception("Must be virtcasted!");
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new UUIDTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- Folder vCast = new Folder(Name);
- vCast.Add(new ByteTag("_virtcast_", (byte)Type));
- vCast.Add(new ByteArrayTag("val", Value.ToByteArray()));
- if (Parent != null)
- {
- if (Parent.Type == TagType.LIST)
- {
- vCast.Add(new StringTag("name", Name));
- }
- }
- vCast.WriteTag(bw);
- vCast.WriteData(bw);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
- }
-
- public override object Clone()
- {
- return new UUIDTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- if (!F.HasNamedTag("name"))
- Name = F.Name;
- else Name = F["name"].StringValue;
- ByteArrayTag bat = F["val"] as ByteArrayTag;
- LongVal = new Guid(bat.Value);
- }
- }
-}
diff --git a/Serialization/ZNIFile/ulongTag.cs b/Serialization/ZNIFile/ulongTag.cs
deleted file mode 100644
index b6fa32a..0000000
--- a/Serialization/ZNIFile/ulongTag.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LibAC.Serialization.ACFile
-{
- public class uLongTag : Tag
- {
- private ulong LongVal;
- public ulong Value
- {
- get
- {
- return LongVal;
- }
- }
-
- public uLongTag(string _Name, ulong val)
- {
- Name = _Name;
- LongVal = val;
- }
- public uLongTag(ulong _LongVal) : this(null, _LongVal)
- {
- }
- public uLongTag() : this(null, 0) { }
-
- public override TagType Type
- {
- get
- {
- return TagType.ULONG;
- }
- }
-
- public override bool ReadTag(NBTReader br)
- {
- throw new Exception("Not allowed"); // This type must be virtual casted
- }
-
- public override void Rename(string old, string newName)
- {
- throw new NotImplementedException();
- }
-
- public override void SkipTag(NBTReader br)
- {
- _ = new uLongTag().ReadTag(br);
- }
-
- public override void WriteData(NBTWriter bw)
- {
- Folder vCast = new Folder(Name);
- vCast.Add(new ByteTag("_virtcast_", (byte)Type));
- vCast.Add(new StringTag("val", Value.ToString()));
- if (Parent != null)
- {
- if (Parent.Type == TagType.LIST)
- {
- vCast.Add(new StringTag("name", Name));
- }
- }
- vCast.WriteTag(bw);
- vCast.WriteData(bw);
- }
-
- public override void WriteTag(NBTWriter bw)
- {
-
- }
-
- public override object Clone()
- {
- return new uLongTag(Name, Value);
- }
-
- public override void CastFrom(Folder F)
- {
- if (!F.HasNamedTag("name"))
- Name = F.Name;
- else Name = F["name"].StringValue;
- LongVal = ulong.Parse(F["val"].StringValue);
- }
- }
-}
diff --git a/Utilities/UUID.cs b/Utilities/UUID.cs
new file mode 100644
index 0000000..c2f986b
--- /dev/null
+++ b/Utilities/UUID.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Text;
+using System.Security.Cryptography;
+using System.Linq;
+
+namespace LibAC.Utilities
+{
+ public class UUID
+ {
+ private readonly byte[] _bytes;
+
+ public static readonly UUID ZERO = UUID.Generate(0);
+
+ public UUID(byte[] bytes)
+ {
+ _bytes = bytes;
+ }
+
+ public static bool Validate(string uuid)
+ {
+ return uuid.Length == (16 * 2) + 4; // Basic length check
+ }
+
+ public static UUID Parse(string uuid)
+ {
+ if (Validate(uuid))
+ {
+ string[] segments = uuid.Split('-');
+ if (segments.Length != 5)
+ {
+ throw new FormatException("Invalid UUID format");
+ }
+
+ string msbString = string.Join("", segments.Take(3));
+ string lsbString = string.Join("", segments.Skip(3));
+
+ byte[] byteArray = new byte[16];
+ int i = 0;
+ for (i = 0; i < msbString.Length; i += 2)
+ {
+ byteArray[i / 2] = Convert.ToByte(msbString.Substring(i, 2), 16);
+ }
+
+ for (i = 0; i < lsbString.Length; i += 2)
+ {
+ byteArray[msbString.Length / 2 + i / 2] = Convert.ToByte(lsbString.Substring(i, 2), 16);
+ }
+
+ return new UUID(byteArray);
+ }
+ else
+ {
+ return ZERO;
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder hexBuilder = new StringBuilder();
+ foreach (byte b in _bytes)
+ {
+ hexBuilder.Append(b.ToString("x2"));
+ }
+
+ return $"{hexBuilder.ToString().Substring(0, 8)}-{hexBuilder.ToString().Substring(8, 4)}-{hexBuilder.ToString().Substring(12, 4)}-{hexBuilder.ToString().Substring(16, 4)}-{hexBuilder.ToString().Substring(20, 12)}";
+ }
+
+ public static UUID Generate(int version, params object[] parameters)
+ {
+ if (version != 4 && version != 0 && version != 3 && version != 5)
+ {
+ return Generate(4);
+ }
+
+ byte[] bytes0 = new byte[16];
+
+
+ switch (version)
+ {
+ case 0:
+ return new UUID(bytes0);
+ case 3:
+ if (parameters.Length != 2)
+ {
+ throw new ArgumentException("UUID v3 requires two parameters: [namespace, name]");
+ }
+
+ string namespaceStr = parameters[0] as string;
+ string nameStr = parameters[1] as string;
+
+ using (MD5 md5 = MD5.Create())
+ {
+ byte[] namespaceBytes = Encoding.UTF8.GetBytes(namespaceStr);
+ byte[] nameBytes = Encoding.UTF8.GetBytes(nameStr);
+ byte[] combined = namespaceBytes.Concat(nameBytes).ToArray();
+
+ byte[] hash = md5.ComputeHash(combined);
+
+ Array.Copy(hash, 0, bytes0, 0, 16);
+ bytes0[6] = (byte)(bytes0[6] & 0x0F | 0x30); // Set version to 3
+ bytes0[8] = (byte)(bytes0[8] & 0x3F | 0x80); // Set variant to RFC4122
+ return new UUID(bytes0);
+ }
+ case 4:
+ using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
+ {
+ byte[] bytes4 = new byte[16];
+ rng.GetBytes(bytes4);
+ bytes4[6] = (byte)(bytes4[6] & 0x0F | 0x40); // Set version to 4
+ bytes4[8] = (byte)(bytes4[8] & 0x3F | 0x80); // Set variant to RFC4122
+ return new UUID(bytes4);
+ }
+ case 5:
+ if (parameters.Length != 2)
+ {
+ throw new ArgumentException("UUID v5 requires two parameters: [namespace, name]");
+ }
+
+ string namespaceStr5 = parameters[0] as string;
+ string nameStr5 = parameters[1] as string;
+
+ using (SHA1 sha1 = SHA1.Create())
+ {
+ byte[] namespaceBytes5 = Encoding.UTF8.GetBytes(namespaceStr5);
+ byte[] nameBytes5 = Encoding.UTF8.GetBytes(nameStr5);
+ byte[] combined5 = namespaceBytes5.Concat(nameBytes5).ToArray();
+
+ byte[] hash = sha1.ComputeHash(combined5);
+
+ byte[] bytes5 = new byte[16];
+ Array.Copy(hash, 0, bytes5, 0, 16);
+ bytes5[6] = (byte)(bytes5[6] & 0x0F | 0x50); // Set version to 5
+ bytes5[8] = (byte)(bytes5[8] & 0x3F | 0x80); // Set variant to RFC4122
+ return new UUID(bytes5);
+ }
+ default:
+ throw new ArgumentException($"Unsupported UUID version: {version}");
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ return _bytes.Take(16).ToArray();
+ }
+ }
+}
diff --git a/Utilities/Vector2d.cs b/Utilities/Vector2d.cs
new file mode 100644
index 0000000..b628a5f
--- /dev/null
+++ b/Utilities/Vector2d.cs
@@ -0,0 +1,90 @@
+using System;
+
+namespace LibAC.Utilities
+{
+ public class Vector2d
+ {
+ public static readonly Vector2d ZERO = new Vector2d(0, 0);
+ public double X { get; set; }
+ public double Z { get; set; }
+
+ public Vector2d(double X = 0.0, double Z = 0.0)
+ {
+ this.X = X;
+ this.Z = Z;
+ }
+
+ public override bool Equals(object other)
+ {
+ if (other is Vector2d)
+ {
+ Vector2d otherVector = (Vector2d)other;
+ return X == otherVector.X && Z == otherVector.Z;
+ }
+ return false;
+ }
+
+ public static Vector2d operator +(Vector2d v1, Vector2d v2)
+ {
+ Vector2d result = v1.Clone();
+ result.X += v2.X;
+ result.Z += v2.Z;
+ return result;
+ }
+
+ public static Vector2d operator -(Vector2d v1, Vector2d v2)
+ {
+ Vector2d result = v1.Clone();
+ result.X -= v2.X;
+ result.Z -= v2.Z;
+ return result;
+ }
+
+ public static Vector2d operator *(Vector2d v1, Vector2d v2)
+ {
+ Vector2d result = v1.Clone();
+ result.X *= v2.X;
+ result.Z *= v2.Z;
+ return result;
+ }
+
+ public static Vector2d operator /(Vector2d v1, Vector2d v2)
+ {
+ Vector2d result = v1.Clone();
+ result.X /= v2.X;
+ result.Z /= v2.Z;
+ return result;
+ }
+
+ public static bool operator >(Vector2d v1, Vector2d v2)
+ {
+ return (v1.X > v2.X) || (v1.X > v2.Z);
+ }
+
+ public static bool operator <(Vector2d v1, Vector2d v2)
+ {
+ return (v1.X < v2.X) || (v1.X < v2.Z);
+ }
+
+ public Vector2d Clone()
+ {
+ return new Vector2d(X, Z);
+ }
+
+ public override string ToString()
+ {
+ return $"<{X}, {Z}>";
+ }
+
+ public bool Inside(Vector2d min, Vector2d max)
+ {
+ return (min.X <= X && max.X >= X) && (min.Z <= Z && max.Z >= Z);
+ }
+
+ // Override GetHashCode if you override Equals
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(X, Z);
+ }
+ }
+}
diff --git a/Utilities/Vector2i.cs b/Utilities/Vector2i.cs
new file mode 100644
index 0000000..a0f9679
--- /dev/null
+++ b/Utilities/Vector2i.cs
@@ -0,0 +1,90 @@
+using System;
+
+namespace LibAC.Utilities
+{
+ public class Vector2i
+ {
+ public static readonly Vector2i ZERO = new Vector2i(0, 0);
+ public int X { get; set; }
+ public int Z { get; set; }
+
+ public Vector2i(int X = 0, int Z = 0)
+ {
+ this.X = X;
+ this.Z = Z;
+ }
+
+ public override bool Equals(object other)
+ {
+ if (other is Vector2i)
+ {
+ Vector2i otherVector = (Vector2i)other;
+ return X == otherVector.X && Z == otherVector.Z;
+ }
+ return false;
+ }
+
+ public static Vector2i operator +(Vector2i v1, Vector2i v2)
+ {
+ Vector2i result = v1.Clone();
+ result.X += v2.X;
+ result.Z += v2.Z;
+ return result;
+ }
+
+ public static Vector2i operator -(Vector2i v1, Vector2i v2)
+ {
+ Vector2i result = v1.Clone();
+ result.X -= v2.X;
+ result.Z -= v2.Z;
+ return result;
+ }
+
+ public static Vector2i operator *(Vector2i v1, Vector2i v2)
+ {
+ Vector2i result = v1.Clone();
+ result.X *= v2.X;
+ result.Z *= v2.Z;
+ return result;
+ }
+
+ public static Vector2i operator /(Vector2i v1, Vector2i v2)
+ {
+ Vector2i result = v1.Clone();
+ result.X = (int)Math.Round((double)v1.X / v2.X);
+ result.Z = (int)Math.Round((double)v1.Z / v2.Z);
+ return result;
+ }
+
+ public static bool operator >(Vector2i v1, Vector2i v2)
+ {
+ return (v1.X > v2.X) || (v1.X > v2.Z);
+ }
+
+ public static bool operator <(Vector2i v1, Vector2i v2)
+ {
+ return (v1.X < v2.X) || (v1.X < v2.Z);
+ }
+
+ public Vector2i Clone()
+ {
+ return new Vector2i(X, Z);
+ }
+
+ public override string ToString()
+ {
+ return $"<{X}, {Z}>";
+ }
+
+ public bool Inside(Vector2i min, Vector2i max)
+ {
+ return (min.X <= X && max.X >= X) && (min.Z <= Z && max.Z >= Z);
+ }
+
+ // Override GetHashCode if you override Equals
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(X, Z);
+ }
+ }
+}
diff --git a/Utilities/Vector3d.cs b/Utilities/Vector3d.cs
new file mode 100644
index 0000000..6016db3
--- /dev/null
+++ b/Utilities/Vector3d.cs
@@ -0,0 +1,96 @@
+using System;
+
+namespace LibAC.Utilities
+{
+ public class Vector3d
+ {
+ public static readonly Vector3d ZERO = new Vector3d(0, 0, 0);
+ public double X { get; set; }
+ public double Y { get; set; }
+ public double Z { get; set; }
+
+ public Vector3d(double X = 0.0, double Y = 0.0, double Z = 0.0)
+ {
+ this.X = X;
+ this.Y = Y;
+ this.Z = Z;
+ }
+
+ public override bool Equals(object other)
+ {
+ if (other is Vector3d)
+ {
+ Vector3d otherVector = (Vector3d)other;
+ return X == otherVector.X && Y == otherVector.Y && Z == otherVector.Z;
+ }
+ return false;
+ }
+
+ public static Vector3d operator +(Vector3d v1, Vector3d v2)
+ {
+ Vector3d result = v1.Clone();
+ result.X += v2.X;
+ result.Y += v2.Y;
+ result.Z += v2.Z;
+ return result;
+ }
+
+ public static Vector3d operator -(Vector3d v1, Vector3d v2)
+ {
+ Vector3d result = v1.Clone();
+ result.X -= v2.X;
+ result.Y -= v2.Y;
+ result.Z -= v2.Z;
+ return result;
+ }
+
+ public static Vector3d operator *(Vector3d v1, Vector3d v2)
+ {
+ Vector3d result = v1.Clone();
+ result.X *= v2.X;
+ result.Y *= v2.Y;
+ result.Z *= v2.Z;
+ return result;
+ }
+
+ public static Vector3d operator /(Vector3d v1, Vector3d v2)
+ {
+ Vector3d result = v1.Clone();
+ result.X /= v2.X;
+ result.Y /= v2.Y;
+ result.Z /= v2.Z;
+ return result;
+ }
+
+ public static bool operator >(Vector3d v1, Vector3d v2)
+ {
+ return (v1.X > v2.X) || (v1.Y > v2.Y) || (v1.X > v2.Z);
+ }
+
+ public static bool operator <(Vector3d v1, Vector3d v2)
+ {
+ return (v1.X < v2.X) || (v1.Y < v2.Y) || (v1.X < v2.Z);
+ }
+
+ public Vector3d Clone()
+ {
+ return new Vector3d(X, Y, Z);
+ }
+
+ public override string ToString()
+ {
+ return $"<{X}, {Y}, {Z}>";
+ }
+
+ public bool Inside(Vector3d min, Vector3d max)
+ {
+ return (min.X <= X && max.X >= X) && (min.Y <= Y && max.Y >= Y) && (min.Z <= Z && max.Z >= Z);
+ }
+
+ // Override GetHashCode if you override Equals
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(X, Y, Z);
+ }
+ }
+}
diff --git a/Utilities/Vector3i.cs b/Utilities/Vector3i.cs
new file mode 100644
index 0000000..14cdfd5
--- /dev/null
+++ b/Utilities/Vector3i.cs
@@ -0,0 +1,96 @@
+using System;
+
+namespace LibAC.Utilities
+{
+ public class Vector3i
+ {
+ public static readonly Vector3i ZERO = new Vector3i(0, 0, 0);
+ public int X { get; set; }
+ public int Y { get; set; }
+ public int Z { get; set; }
+
+ public Vector3i(int X = 0, int Y = 0, int Z = 0)
+ {
+ this.X = X;
+ this.Y = Y;
+ this.Z = Z;
+ }
+
+ public override bool Equals(object other)
+ {
+ if (other is Vector3i)
+ {
+ Vector3i otherVector = (Vector3i)other;
+ return X == otherVector.X && Y == otherVector.Y && Z == otherVector.Z;
+ }
+ return false;
+ }
+
+ public static Vector3i operator +(Vector3i v1, Vector3i v2)
+ {
+ Vector3i result = v1.Clone();
+ result.X += v2.X;
+ result.Y += v2.Y;
+ result.Z += v2.Z;
+ return result;
+ }
+
+ public static Vector3i operator -(Vector3i v1, Vector3i v2)
+ {
+ Vector3i result = v1.Clone();
+ result.X -= v2.X;
+ result.Y -= v2.Y;
+ result.Z -= v2.Z;
+ return result;
+ }
+
+ public static Vector3i operator *(Vector3i v1, Vector3i v2)
+ {
+ Vector3i result = v1.Clone();
+ result.X *= v2.X;
+ result.Y *= v2.Y;
+ result.Z *= v2.Z;
+ return result;
+ }
+
+ public static Vector3i operator /(Vector3i v1, Vector3i v2)
+ {
+ Vector3i result = v1.Clone();
+ result.X = (int)Math.Round((double)result.X / v2.X);
+ result.Y = (int)Math.Round((double)result.Y / v2.Y);
+ result.Z = (int)Math.Round((double)result.Z / v2.Z);
+ return result;
+ }
+
+ public static bool operator >(Vector3i v1, Vector3i v2)
+ {
+ return (v1.X > v2.X) || (v1.Y > v2.Y) || (v1.X > v2.Z);
+ }
+
+ public static bool operator <(Vector3i v1, Vector3i v2)
+ {
+ return (v1.X < v2.X) || (v1.Y < v2.Y) || (v1.X < v2.Z);
+ }
+
+ public Vector3i Clone()
+ {
+ return new Vector3i(X, Y, Z);
+ }
+
+ public override string ToString()
+ {
+ return $"<{X}, {Y}, {Z}>";
+ }
+
+ public bool Inside(Vector3i min, Vector3i max)
+ {
+ return (min.X <= X && max.X >= X) && (min.Y <= Y && max.Y >= Y) && (min.Z <= Z && max.Z >= Z);
+ }
+
+ // Override GetHashCode if you override Equals
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(X, Y, Z);
+ }
+ }
+}
diff --git a/Versioning.cs b/Versioning.cs
index 4d8de02..2debf2b 100644
--- a/Versioning.cs
+++ b/Versioning.cs
@@ -1,11 +1,11 @@
-using LibAC.Serialization;
-using LibAC.Serialization.ACFile;
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading.Tasks;
+using LibAC.NBT;
+using LibAC.NBT.API;
namespace LibAC
{
@@ -16,7 +16,7 @@ namespace LibAC
{
}
}
- public class Version : Serializable
+ public class Version
{
public List ver { get; set; } = new List();
@@ -104,26 +104,28 @@ namespace LibAC
return $"{ver[0]}.{ver[1]}.{ver[2]}.{ver[3]}.{CYCLE}.{ver[5]}";
}
- public override void load(Folder f)
+ public void load(CompoundTag f)
{
ListTag lt = f["Version"] as ListTag;
ver = new List();
- foreach(Tag tag in lt)
+ foreach(Tag tag in lt.GetList)
{
IntTag it = tag as IntTag;
- ver.Add(it.IntValue);
+ ver.Add(it.Value);
}
}
- public override void save(Folder f)
+ public CompoundTag save()
{
- ListTag lt = new ListTag(TagType.INTEGER, "Version");
+ CompoundTag ct = new CompoundTag();
+ ListTag lt = new ListTag();
foreach(int v in ver)
{
- IntTag i = new IntTag(v);
+ IntTag i = IntTag.ValueOf(v);
lt.Add(i);
}
- f.Add(lt);
+ ct.Put("Version", lt);
+ return ct;
}
}
}