NBT support updated for Anvil.

This commit is contained in:
Justin Aquadro 2012-02-19 16:50:20 -05:00
parent 50b59bea25
commit 02691712f9
9 changed files with 298 additions and 10 deletions

View file

@ -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)]

View file

@ -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());

View file

@ -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;

View file

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Substrate.Nbt
{
/// <summary>
/// A concrete <see cref="SchemaNode"/> representing a <see cref="TagNodeIntArray"/>.
/// </summary>
public sealed class SchemaNodeIntArray : SchemaNode
{
private int _length;
/// <summary>
/// Gets the expected length of the corresponding int array.
/// </summary>
public int Length
{
get { return _length; }
}
/// <summary>
/// Indicates whether there is an expected length of the corresponding int array.
/// </summary>
public bool HasExpectedLength
{
get { return _length > 0; }
}
/// <summary>
/// Constructs a new <see cref="SchemaNodeIntArray"/> representing a <see cref="TagNodeIntArray"/> named <paramref name="name"/>.
/// </summary>
/// <param name="name">The name of the corresponding <see cref="TagNodeIntArray"/>.</param>
public SchemaNodeIntArray (string name)
: base(name)
{
_length = 0;
}
/// <summary>
/// Constructs a new <see cref="SchemaNodeIntArray"/> with additional options.
/// </summary>
/// <param name="name">The name of the corresponding <see cref="TagNodeIntArray"/>.</param>
/// <param name="options">One or more option flags modifying the processing of this node.</param>
public SchemaNodeIntArray (string name, SchemaOptions options)
: base(name, options)
{
_length = 0;
}
/// <summary>
/// Constructs a new <see cref="SchemaNodeIntArray"/> representing a <see cref="TagNodeIntArray"/> named <paramref name="name"/> with expected length <paramref name="length"/>.
/// </summary>
/// <param name="name">The name of the corresponding <see cref="TagNodeIntArray"/>.</param>
/// <param name="length">The expected length of corresponding byte array.</param>
public SchemaNodeIntArray (string name, int length)
: base(name)
{
_length = length;
}
/// <summary>
/// Constructs a new <see cref="SchemaNodeIntArray"/> with additional options.
/// </summary>
/// <param name="name">The name of the corresponding <see cref="TagNodeIntArray"/>.</param>
/// <param name="length">The expected length of corresponding byte array.</param>
/// <param name="options">One or more option flags modifying the processing of this node.</param>
public SchemaNodeIntArray (string name, int length, SchemaOptions options)
: base(name, options)
{
_length = length;
}
/// <summary>
/// Constructs a default <see cref="TagNodeIntArray"/> satisfying the constraints of this node.
/// </summary>
/// <returns>A <see cref="TagNodeString"/> with a sensible default value.</returns>
public override TagNode BuildDefaultTree ()
{
return new TagNodeIntArray(new int[_length]);
}
}
}

View file

@ -109,6 +109,15 @@ namespace Substrate.Nbt
throw new InvalidCastException();
}
/// <summary>
/// Conver this node to an int array tag type if supported.
/// </summary>
/// <returns>A new int array node.</returns>
public virtual TagNodeIntArray ToTagIntArray ()
{
throw new InvalidCastException();
}
/// <summary>
/// Gets the underlying tag type of the node.
/// </summary>

View file

@ -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;
/// <summary>
/// Converts the node to itself.
/// </summary>
/// <returns>A reference to itself.</returns>
public override TagNodeIntArray ToTagIntArray ()
{
return this;
}
/// <summary>
/// Gets the tag type of the node.
/// </summary>
/// <returns>The TAG_INT_ARRAY tag type.</returns>
public override TagType GetTagType ()
{
return TagType.TAG_INT_ARRAY;
}
/// <summary>
/// Gets or sets an int array of tag data.
/// </summary>
public int[] Data
{
get { return _data; }
set { _data = value; }
}
/// <summary>
/// Gets the length of the stored byte array.
/// </summary>
public int Length
{
get { return _data.Length; }
}
/// <summary>
/// Constructs a new byte array node with a null data value.
/// </summary>
public TagNodeIntArray () { }
/// <summary>
/// Constructs a new byte array node.
/// </summary>
/// <param name="d">The value to set the node's tag data value.</param>
public TagNodeIntArray (int[] d)
{
_data = d;
}
/// <summary>
/// Makes a deep copy of the node.
/// </summary>
/// <returns>A new int array node representing the same data.</returns>
public override TagNode Copy ()
{
int[] arr = new int[_data.Length];
_data.CopyTo(arr, 0);
return new TagNodeIntArray(arr);
}
/// <summary>
/// Gets a string representation of the node's data.
/// </summary>
/// <returns>String representation of the node's data.</returns>
public override string ToString ()
{
return _data.ToString();
}
/// <summary>
/// Gets or sets a single int at the specified index.
/// </summary>
/// <param name="index">Valid index within stored int array.</param>
/// <returns>The int value at the given index of the stored byte array.</returns>
public int this[int index]
{
get { return _data[index]; }
set { _data[index] = value; }
}
/// <summary>
/// Converts a system int array to a int array node representing the same data.
/// </summary>
/// <param name="i">A int array.</param>
/// <returns>A new int array node containing the given value.</returns>
public static implicit operator TagNodeIntArray (int[] i)
{
return new TagNodeIntArray(i);
}
/// <summary>
/// Converts an int array node to a system int array representing the same data.
/// </summary>
/// <param name="i">An int array node.</param>
/// <returns>A system int array set to the node's data.</returns>
public static implicit operator int[] (TagNodeIntArray i)
{
return i._data;
}
}
}

View file

@ -60,6 +60,11 @@ namespace Substrate.Nbt
/// <summary>
/// A tag containing a key-value store of tags, where each tag can be of any type.
/// </summary>
TAG_COMPOUND = 10
TAG_COMPOUND = 10,
/// <summary>
/// A tag containing an array of signed 32-bit values.
/// </summary>
TAG_INT_ARRAY = 11,
}
}

View file

@ -60,6 +60,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Source\AlphaWorld.cs" />
<Compile Include="Source\AnvilChunk.cs" />
<Compile Include="Source\BetaChunkManager.cs" />
<Compile Include="Source\BetaWorld.cs" />
<Compile Include="Source\Core\BlockTileTicks.cs" />
@ -122,6 +123,7 @@
<Compile Include="Source\NBT\SchemaNode.cs" />
<Compile Include="Source\NBT\SchemaNodeArray.cs" />
<Compile Include="Source\NBT\SchemaNodeCompound.cs" />
<Compile Include="Source\NBT\SchemaNodeIntArray.cs" />
<Compile Include="Source\NBT\SchemaNodeList.cs" />
<Compile Include="Source\NBT\SchemaNodeScaler.cs" />
<Compile Include="Source\NBT\SchemaNodeString.cs" />
@ -132,6 +134,7 @@
<Compile Include="Source\NBT\TagNodeDouble.cs" />
<Compile Include="Source\NBT\TagNodeFloat.cs" />
<Compile Include="Source\NBT\TagNodeInt.cs" />
<Compile Include="Source\NBT\TagNodeIntArray.cs" />
<Compile Include="Source\NBT\TagNodeList.cs" />
<Compile Include="Source\NBT\TagNodeLong.cs" />
<Compile Include="Source\NBT\TagNodeShort.cs" />

View file

@ -122,6 +122,7 @@
<Compile Include="Source\NBT\SchemaNode.cs" />
<Compile Include="Source\NBT\SchemaNodeArray.cs" />
<Compile Include="Source\NBT\SchemaNodeCompound.cs" />
<Compile Include="Source\NBT\SchemaNodeIntArray.cs" />
<Compile Include="Source\NBT\SchemaNodeList.cs" />
<Compile Include="Source\NBT\SchemaNodeScaler.cs" />
<Compile Include="Source\NBT\SchemaNodeString.cs" />
@ -132,6 +133,7 @@
<Compile Include="Source\NBT\TagNodeDouble.cs" />
<Compile Include="Source\NBT\TagNodeFloat.cs" />
<Compile Include="Source\NBT\TagNodeInt.cs" />
<Compile Include="Source\NBT\TagNodeIntArray.cs" />
<Compile Include="Source\NBT\TagNodeList.cs" />
<Compile Include="Source\NBT\TagNodeLong.cs" />
<Compile Include="Source\NBT\TagNodeShort.cs" />