diff --git a/SubstrateCS/Source/Nbt/NbtTree.cs b/SubstrateCS/Source/Nbt/NbtTree.cs index 6a884cb6..eff53ab6 100644 --- a/SubstrateCS/Source/Nbt/NbtTree.cs +++ b/SubstrateCS/Source/Nbt/NbtTree.cs @@ -145,6 +145,9 @@ private TagNode ReadValue (TagType type) case TagType.TAG_INT_ARRAY: return ReadIntArray(); + + case TagType.TAG_LONG_ARRAY: + return ReadLongArray(); case TagType.TAG_SHORT_ARRAY: return ReadShortArray(); @@ -353,6 +356,35 @@ private TagNode ReadIntArray () return val; } + private TagNode ReadLongArray () + { + 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); + } + + long[] data = new long[length]; + byte[] buffer = new byte[8]; + for (int i = 0; i < length; i++) { + _stream.Read(buffer, 0, 8); + if (BitConverter.IsLittleEndian) { + Array.Reverse(buffer); + } + data[i] = BitConverter.ToInt64(buffer, 0); + } + + TagNodeLongArray val = new TagNodeLongArray(data); + + return val; + } + private TagNode ReadShortArray () { byte[] lenBytes = new byte[4]; @@ -455,6 +487,10 @@ private void WriteValue (TagNode val) WriteIntArray(val.ToTagIntArray()); break; + case TagType.TAG_LONG_ARRAY: + WriteLongArray(val.ToTagLongArray()); + break; + case TagType.TAG_SHORT_ARRAY: WriteShortArray(val.ToTagShortArray()); break; @@ -596,6 +632,28 @@ private void WriteIntArray (TagNodeIntArray val) _stream.Write(data, 0, data.Length); } + private void WriteLongArray (TagNodeLongArray val) + { + byte[] lenBytes = BitConverter.GetBytes(val.Length); + + if (BitConverter.IsLittleEndian) { + Array.Reverse(lenBytes); + } + + _stream.Write(lenBytes, 0, 4); + + byte[] data = new byte[val.Length * 8]; + 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 * 8, 8); + } + + _stream.Write(data, 0, data.Length); + } + private void WriteShortArray (TagNodeShortArray val) { byte[] lenBytes = BitConverter.GetBytes(val.Length); diff --git a/SubstrateCS/Source/Nbt/NbtVerifier.cs b/SubstrateCS/Source/Nbt/NbtVerifier.cs index 40d30c4c..34067ef0 100644 --- a/SubstrateCS/Source/Nbt/NbtVerifier.cs +++ b/SubstrateCS/Source/Nbt/NbtVerifier.cs @@ -178,6 +178,11 @@ private bool Verify (TagNode parent, TagNode tag, SchemaNode schema) return VerifyIntArray(tag, intarray); } + SchemaNodeLongArray longarray = schema as SchemaNodeLongArray; + if (longarray != null) { + return VerifyLongArray(tag, longarray); + } + SchemaNodeShortArray shortarray = schema as SchemaNodeShortArray; if (shortarray != null) { return VerifyShortArray(tag, shortarray); @@ -264,6 +269,23 @@ private bool VerifyIntArray (TagNode tag, SchemaNodeIntArray schema) return true; } + private bool VerifyLongArray (TagNode tag, SchemaNodeLongArray schema) + { + TagNodeLongArray atag = tag as TagNodeLongArray; + 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 VerifyShortArray (TagNode tag, SchemaNodeShortArray schema) { TagNodeShortArray atag = tag as TagNodeShortArray; diff --git a/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs new file mode 100644 index 00000000..702bed1a --- /dev/null +++ b/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeLongArray : SchemaNode + { + private int _length; + + /// + /// Gets the expected length of the corresponding long 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 SchemaNodeLongArray (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 SchemaNodeLongArray (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 SchemaNodeLongArray (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 SchemaNodeLongArray (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 TagNodeLongArray(new long[_length]); + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagNode.cs b/SubstrateCS/Source/Nbt/TagNode.cs index 0e926e1e..6920b5ee 100644 --- a/SubstrateCS/Source/Nbt/TagNode.cs +++ b/SubstrateCS/Source/Nbt/TagNode.cs @@ -118,6 +118,15 @@ public virtual TagNodeIntArray ToTagIntArray () throw new InvalidCastException(); } + /// + /// Conver this node to a long array tag type if supported. + /// + /// A new long array node. + public virtual TagNodeLongArray ToTagLongArray () + { + throw new InvalidCastException(); + } + /// /// Conver this node to a short array tag type if supported. /// diff --git a/SubstrateCS/Source/Nbt/TagNodeLongArray.cs b/SubstrateCS/Source/Nbt/TagNodeLongArray.cs new file mode 100644 index 00000000..2f4758d5 --- /dev/null +++ b/SubstrateCS/Source/Nbt/TagNodeLongArray.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + public sealed class TagNodeLongArray : TagNode + { + private long[] _data = null; + + /// + /// Converts the node to itself. + /// + /// A reference to itself. + public override TagNodeLongArray ToTagLongArray () + { + return this; + } + + /// + /// Gets the tag type of the node. + /// + /// The TAG_LONG_ARRAY tag type. + public override TagType GetTagType () + { + return TagType.TAG_LONG_ARRAY; + } + + /// + /// Gets or sets an long array of tag data. + /// + public long[] 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 TagNodeLongArray() { } + + /// + /// Constructs a new byte array node. + /// + /// The value to set the node's tag data value. + public TagNodeLongArray(long[] d) + { + _data = d; + } + + /// + /// Makes a deep copy of the node. + /// + /// A new long array node representing the same data. + public override TagNode Copy () + { + long[] arr = new long[_data.Length]; + _data.CopyTo(arr, 0); + + return new TagNodeLongArray(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 long at the specified index. + /// + /// Valid index within stored long array. + /// The long value at the given index of the stored byte array. + public long this[int index] + { + get { return _data[index]; } + set { _data[index] = value; } + } + + /// + /// Converts a system long array to a long array node representing the same data. + /// + /// A long array. + /// A new long array node containing the given value. + public static implicit operator TagNodeLongArray(long[] i) + { + return new TagNodeLongArray(i); + } + + /// + /// Converts an long array node to a system long array representing the same data. + /// + /// An long array node. + /// A system long array set to the node's data. + public static implicit operator long[] (TagNodeLongArray i) + { + return i._data; + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagType.cs b/SubstrateCS/Source/Nbt/TagType.cs index 9b819bcb..272c32e9 100644 --- a/SubstrateCS/Source/Nbt/TagType.cs +++ b/SubstrateCS/Source/Nbt/TagType.cs @@ -67,10 +67,15 @@ public enum TagType /// TAG_INT_ARRAY = 11, + /// + /// A tag containing an array of signed 64-bit values. + /// + TAG_LONG_ARRAY = 12, + /// /// A tag containing an array of signed 16-bit values. NON-STANDARD NBT. /// This tag is included to support modded Minecraft and in anticipation that it may become standard in the future. /// - TAG_SHORT_ARRAY = 12, + TAG_SHORT_ARRAY = 13, } } \ No newline at end of file diff --git a/SubstrateCS/Substrate (NET2).csproj b/SubstrateCS/Substrate (NET2).csproj index 1faad19f..f96fd267 100644 --- a/SubstrateCS/Substrate (NET2).csproj +++ b/SubstrateCS/Substrate (NET2).csproj @@ -71,6 +71,8 @@ + + diff --git a/SubstrateCS/Substrate (NET4).csproj b/SubstrateCS/Substrate (NET4).csproj index 7dfa2541..f293012e 100644 --- a/SubstrateCS/Substrate (NET4).csproj +++ b/SubstrateCS/Substrate (NET4).csproj @@ -139,6 +139,8 @@ + +