From 02691712f9ec7adc253c0816d26ffc2a44af996d Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sun, 19 Feb 2012 16:50:20 -0500 Subject: [PATCH] NBT support updated for Anvil. --- SubstrateCS/Properties/AssemblyInfo.cs | 6 +- SubstrateCS/Source/Nbt/NbtTree.cs | 64 ++++++++++- SubstrateCS/Source/Nbt/NbtVerifier.cs | 22 ++++ SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs | 83 ++++++++++++++ SubstrateCS/Source/Nbt/TagNode.cs | 9 ++ SubstrateCS/Source/Nbt/TagNodeIntArray.cs | 112 +++++++++++++++++++ SubstrateCS/Source/Nbt/TagType.cs | 7 +- SubstrateCS/Substrate (NET2).csproj | 3 + SubstrateCS/Substrate (NET4).csproj | 2 + 9 files changed, 298 insertions(+), 10 deletions(-) create mode 100644 SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs create mode 100644 SubstrateCS/Source/Nbt/TagNodeIntArray.cs diff --git a/SubstrateCS/Properties/AssemblyInfo.cs b/SubstrateCS/Properties/AssemblyInfo.cs index 25e35d6..e1e0f6e 100644 --- a/SubstrateCS/Properties/AssemblyInfo.cs +++ b/SubstrateCS/Properties/AssemblyInfo.cs @@ -11,7 +11,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Substrate")] -[assembly: AssemblyCopyright("2011 Justin Aquadro")] +[assembly: AssemblyCopyright("2011-2012 Justin Aquadro")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -30,8 +30,8 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] +[assembly: AssemblyVersion("1.1.1.0")] +[assembly: AssemblyFileVersion("1.1.1.0")] // This library is compatible with all CLS-compliant .NET programming languages. [assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/NbtTree.cs b/SubstrateCS/Source/Nbt/NbtTree.cs index 1758caf..fce56c0 100644 --- a/SubstrateCS/Source/Nbt/NbtTree.cs +++ b/SubstrateCS/Source/Nbt/NbtTree.cs @@ -142,6 +142,9 @@ namespace Substrate.Nbt case TagType.TAG_COMPOUND: return ReadCompound(); + + case TagType.TAG_INT_ARRAY: + return ReadIntArray(); } throw new Exception(); @@ -315,6 +318,35 @@ namespace Substrate.Nbt return val; } + private TagNode ReadIntArray () + { + byte[] lenBytes = new byte[4]; + _stream.Read(lenBytes, 0, 4); + + if (BitConverter.IsLittleEndian) { + Array.Reverse(lenBytes); + } + + int length = BitConverter.ToInt32(lenBytes, 0); + if (length < 0) { + throw new NBTException(NBTException.MSG_READ_NEG); + } + + int[] data = new int[length]; + byte[] buffer = new byte[4]; + for (int i = 0; i < length; i++) { + _stream.Read(buffer, 0, 4); + if (BitConverter.IsLittleEndian) { + Array.Reverse(buffer); + } + data[i] = BitConverter.ToInt32(buffer, 0); + } + + TagNodeIntArray val = new TagNodeIntArray(data); + + return val; + } + private TagNodeCompound ReadRoot () { TagType type = (TagType)_stream.ReadByte(); @@ -328,8 +360,6 @@ namespace Substrate.Nbt private bool ReadTag (TagNodeCompound parent) { - //NBT_Tag tag = new NBT_Tag(); - TagType type = (TagType)_stream.ReadByte(); if (type != TagType.TAG_END) { string name = ReadString().ToTagString().Data; @@ -338,10 +368,6 @@ namespace Substrate.Nbt } return false; - - //tag.Value = ReadValue(type); - - //return tag; } private void WriteValue (TagNode val) @@ -389,6 +415,10 @@ namespace Substrate.Nbt case TagType.TAG_COMPOUND: WriteCompound(val.ToTagCompound()); break; + + case TagType.TAG_INT_ARRAY: + WriteIntArray(val.ToTagIntArray()); + break; } } @@ -505,6 +535,28 @@ namespace Substrate.Nbt WriteTag(null, _nulltag); } + private void WriteIntArray (TagNodeIntArray val) + { + byte[] lenBytes = BitConverter.GetBytes(val.Length); + + if (BitConverter.IsLittleEndian) { + Array.Reverse(lenBytes); + } + + _stream.Write(lenBytes, 0, 4); + + byte[] data = new byte[val.Length * 4]; + for (int i = 0; i < val.Length; i++) { + byte[] buffer = BitConverter.GetBytes(val.Data[i]); + if (BitConverter.IsLittleEndian) { + Array.Reverse(buffer); + } + Array.Copy(buffer, 0, data, i * 4, 4); + } + + _stream.Write(data, 0, data.Length); + } + private void WriteTag (string name, TagNode val) { _stream.WriteByte((byte)val.GetTagType()); diff --git a/SubstrateCS/Source/Nbt/NbtVerifier.cs b/SubstrateCS/Source/Nbt/NbtVerifier.cs index 5e0cc33..52e066c 100644 --- a/SubstrateCS/Source/Nbt/NbtVerifier.cs +++ b/SubstrateCS/Source/Nbt/NbtVerifier.cs @@ -175,6 +175,11 @@ namespace Substrate.Nbt return VerifyArray(tag, array); } + SchemaNodeIntArray intarray = schema as SchemaNodeIntArray; + if (intarray != null) { + return VerifyIntArray(tag, intarray); + } + SchemaNodeList list = schema as SchemaNodeList; if (list != null) { return VerifyList(tag, list); @@ -239,6 +244,23 @@ namespace Substrate.Nbt return true; } + private bool VerifyIntArray (TagNode tag, SchemaNodeIntArray schema) + { + TagNodeIntArray atag = tag as TagNodeIntArray; + if (atag == null) { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + return false; + } + } + if (schema.Length > 0 && atag.Length != schema.Length) { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } + } + + return true; + } + private bool VerifyList (TagNode tag, SchemaNodeList schema) { TagNodeList ltag = tag as TagNodeList; diff --git a/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs new file mode 100644 index 0000000..086b67f --- /dev/null +++ b/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeIntArray : SchemaNode + { + private int _length; + + /// + /// Gets the expected length of the corresponding int array. + /// + public int Length + { + get { return _length; } + } + + /// + /// Indicates whether there is an expected length of the corresponding int array. + /// + public bool HasExpectedLength + { + get { return _length > 0; } + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + public SchemaNodeIntArray (string name) + : base(name) + { + _length = 0; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeIntArray (string name, SchemaOptions options) + : base(name, options) + { + _length = 0; + } + + /// + /// Constructs a new representing a named with expected length . + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + public SchemaNodeIntArray (string name, int length) + : base(name) + { + _length = length; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + /// One or more option flags modifying the processing of this node. + public SchemaNodeIntArray (string name, int length, SchemaOptions options) + : base(name, options) + { + _length = length; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. + public override TagNode BuildDefaultTree () + { + return new TagNodeIntArray(new int[_length]); + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagNode.cs b/SubstrateCS/Source/Nbt/TagNode.cs index 05471fc..ab3712f 100644 --- a/SubstrateCS/Source/Nbt/TagNode.cs +++ b/SubstrateCS/Source/Nbt/TagNode.cs @@ -109,6 +109,15 @@ namespace Substrate.Nbt throw new InvalidCastException(); } + /// + /// Conver this node to an int array tag type if supported. + /// + /// A new int array node. + public virtual TagNodeIntArray ToTagIntArray () + { + throw new InvalidCastException(); + } + /// /// Gets the underlying tag type of the node. /// diff --git a/SubstrateCS/Source/Nbt/TagNodeIntArray.cs b/SubstrateCS/Source/Nbt/TagNodeIntArray.cs new file mode 100644 index 0000000..c44c171 --- /dev/null +++ b/SubstrateCS/Source/Nbt/TagNodeIntArray.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + public sealed class TagNodeIntArray : TagNode + { + private int[] _data = null; + + /// + /// Converts the node to itself. + /// + /// A reference to itself. + public override TagNodeIntArray ToTagIntArray () + { + return this; + } + + /// + /// Gets the tag type of the node. + /// + /// The TAG_INT_ARRAY tag type. + public override TagType GetTagType () + { + return TagType.TAG_INT_ARRAY; + } + + /// + /// Gets or sets an int array of tag data. + /// + public int[] Data + { + get { return _data; } + set { _data = value; } + } + + /// + /// Gets the length of the stored byte array. + /// + public int Length + { + get { return _data.Length; } + } + + /// + /// Constructs a new byte array node with a null data value. + /// + public TagNodeIntArray () { } + + /// + /// Constructs a new byte array node. + /// + /// The value to set the node's tag data value. + public TagNodeIntArray (int[] d) + { + _data = d; + } + + /// + /// Makes a deep copy of the node. + /// + /// A new int array node representing the same data. + public override TagNode Copy () + { + int[] arr = new int[_data.Length]; + _data.CopyTo(arr, 0); + + return new TagNodeIntArray(arr); + } + + /// + /// Gets a string representation of the node's data. + /// + /// String representation of the node's data. + public override string ToString () + { + return _data.ToString(); + } + + /// + /// Gets or sets a single int at the specified index. + /// + /// Valid index within stored int array. + /// The int value at the given index of the stored byte array. + public int this[int index] + { + get { return _data[index]; } + set { _data[index] = value; } + } + + /// + /// Converts a system int array to a int array node representing the same data. + /// + /// A int array. + /// A new int array node containing the given value. + public static implicit operator TagNodeIntArray (int[] i) + { + return new TagNodeIntArray(i); + } + + /// + /// Converts an int array node to a system int array representing the same data. + /// + /// An int array node. + /// A system int array set to the node's data. + public static implicit operator int[] (TagNodeIntArray i) + { + return i._data; + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagType.cs b/SubstrateCS/Source/Nbt/TagType.cs index e48a0e6..4ae9138 100644 --- a/SubstrateCS/Source/Nbt/TagType.cs +++ b/SubstrateCS/Source/Nbt/TagType.cs @@ -60,6 +60,11 @@ namespace Substrate.Nbt /// /// A tag containing a key-value store of tags, where each tag can be of any type. /// - TAG_COMPOUND = 10 + TAG_COMPOUND = 10, + + /// + /// A tag containing an array of signed 32-bit values. + /// + TAG_INT_ARRAY = 11, } } \ No newline at end of file diff --git a/SubstrateCS/Substrate (NET2).csproj b/SubstrateCS/Substrate (NET2).csproj index 0209e0a..d307014 100644 --- a/SubstrateCS/Substrate (NET2).csproj +++ b/SubstrateCS/Substrate (NET2).csproj @@ -60,6 +60,7 @@ + @@ -122,6 +123,7 @@ + @@ -132,6 +134,7 @@ + diff --git a/SubstrateCS/Substrate (NET4).csproj b/SubstrateCS/Substrate (NET4).csproj index 817fddf..11775c5 100644 --- a/SubstrateCS/Substrate (NET4).csproj +++ b/SubstrateCS/Substrate (NET4).csproj @@ -122,6 +122,7 @@ + @@ -132,6 +133,7 @@ +