forked from mirrors/NBTExplorer
Missed updates
This commit is contained in:
parent
3c2b29e9f0
commit
24774776a2
4 changed files with 1415 additions and 0 deletions
480
NBToolkit/NBToolkit/Map/NBT/NBT.cs
Normal file
480
NBToolkit/NBToolkit/Map/NBT/NBT.cs
Normal file
|
@ -0,0 +1,480 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace NBToolkit.NBT
|
||||
{
|
||||
|
||||
public class NBT_Tree
|
||||
{
|
||||
private Stream _stream = null;
|
||||
private NBT_Compound _root = null;
|
||||
|
||||
private static NBT_Null _nulltag = new NBT_Null();
|
||||
|
||||
public NBT_Compound Root
|
||||
{
|
||||
get { return _root; }
|
||||
}
|
||||
|
||||
public NBT_Tree ()
|
||||
{
|
||||
_root = new NBT_Compound();
|
||||
}
|
||||
|
||||
public NBT_Tree (Stream s)
|
||||
{
|
||||
ReadFrom(s);
|
||||
}
|
||||
|
||||
public void ReadFrom (Stream s)
|
||||
{
|
||||
if (s != null) {
|
||||
_stream = s;
|
||||
_root = ReadRoot();
|
||||
_stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteTo (Stream s)
|
||||
{
|
||||
if (s != null) {
|
||||
_stream = s;
|
||||
|
||||
if (_root != null) {
|
||||
WriteTag("", _root);
|
||||
}
|
||||
|
||||
_stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
private NBT_Value ReadValue (NBT_Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case NBT_Type.TAG_END:
|
||||
return null;
|
||||
|
||||
case NBT_Type.TAG_BYTE:
|
||||
return ReadByte();
|
||||
|
||||
case NBT_Type.TAG_SHORT:
|
||||
return ReadShort();
|
||||
|
||||
case NBT_Type.TAG_INT:
|
||||
return ReadInt();
|
||||
|
||||
case NBT_Type.TAG_LONG:
|
||||
return ReadLong();
|
||||
|
||||
case NBT_Type.TAG_FLOAT:
|
||||
return ReadFloat();
|
||||
|
||||
case NBT_Type.TAG_DOUBLE:
|
||||
return ReadDouble();
|
||||
|
||||
case NBT_Type.TAG_BYTE_ARRAY:
|
||||
return ReadByteArray();
|
||||
|
||||
case NBT_Type.TAG_STRING:
|
||||
return ReadString();
|
||||
|
||||
case NBT_Type.TAG_LIST:
|
||||
return ReadList();
|
||||
|
||||
case NBT_Type.TAG_COMPOUND:
|
||||
return ReadCompound();
|
||||
}
|
||||
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
private NBT_Value ReadByte ()
|
||||
{
|
||||
int gzByte = _stream.ReadByte();
|
||||
if (gzByte == -1) {
|
||||
throw new NBTException(NBTException.MSG_GZIP_ENDOFSTREAM);
|
||||
}
|
||||
|
||||
NBT_Byte val = new NBT_Byte((byte)gzByte);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadShort ()
|
||||
{
|
||||
byte[] gzBytes = new byte[2];
|
||||
_stream.Read(gzBytes, 0, 2);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
NBT_Short val = new NBT_Short(BitConverter.ToInt16(gzBytes, 0));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadInt ()
|
||||
{
|
||||
byte[] gzBytes = new byte[4];
|
||||
_stream.Read(gzBytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
NBT_Int val = new NBT_Int(BitConverter.ToInt32(gzBytes, 0));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadLong ()
|
||||
{
|
||||
byte[] gzBytes = new byte[8];
|
||||
_stream.Read(gzBytes, 0, 8);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
NBT_Long val = new NBT_Long(BitConverter.ToInt64(gzBytes, 0));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadFloat ()
|
||||
{
|
||||
byte[] gzBytes = new byte[4];
|
||||
_stream.Read(gzBytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
NBT_Float val = new NBT_Float(BitConverter.ToSingle(gzBytes, 0));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadDouble ()
|
||||
{
|
||||
byte[] gzBytes = new byte[8];
|
||||
_stream.Read(gzBytes, 0, 8);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
NBT_Double val = new NBT_Double(BitConverter.ToDouble(gzBytes, 0));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadByteArray ()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
byte[] data = new byte[length];
|
||||
_stream.Read(data, 0, length);
|
||||
|
||||
NBT_ByteArray val = new NBT_ByteArray(data);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadString ()
|
||||
{
|
||||
byte[] lenBytes = new byte[2];
|
||||
_stream.Read(lenBytes, 0, 2);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(lenBytes);
|
||||
}
|
||||
|
||||
short len = BitConverter.ToInt16(lenBytes, 0);
|
||||
if (len < 0) {
|
||||
throw new NBTException(NBTException.MSG_READ_NEG);
|
||||
}
|
||||
|
||||
byte[] strBytes = new byte[len];
|
||||
_stream.Read(strBytes, 0, len);
|
||||
|
||||
System.Text.Encoding str = Encoding.GetEncoding(28591);
|
||||
|
||||
NBT_String val = new NBT_String(str.GetString(strBytes));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadList ()
|
||||
{
|
||||
int gzByte = _stream.ReadByte();
|
||||
if (gzByte == -1) {
|
||||
throw new NBTException(NBTException.MSG_GZIP_ENDOFSTREAM);
|
||||
}
|
||||
|
||||
NBT_List val = new NBT_List((NBT_Type)gzByte);
|
||||
if (val.ValueType > (NBT_Type)Enum.GetValues(typeof(NBT_Type)).GetUpperBound(0)) {
|
||||
throw new NBTException(NBTException.MSG_READ_TYPE);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
val.Add(ReadValue(val.ValueType));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Value ReadCompound ()
|
||||
{
|
||||
NBT_Compound val = new NBT_Compound();
|
||||
|
||||
while (ReadTag(val)) ;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private NBT_Compound ReadRoot ()
|
||||
{
|
||||
NBT_Type type = (NBT_Type)_stream.ReadByte();
|
||||
if (type == NBT_Type.TAG_COMPOUND) {
|
||||
string name = ReadString().ToNBTString().Data;
|
||||
return ReadValue(type) as NBT_Compound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool ReadTag (NBT_Compound parent)
|
||||
{
|
||||
//NBT_Tag tag = new NBT_Tag();
|
||||
|
||||
NBT_Type type = (NBT_Type)_stream.ReadByte();
|
||||
if (type != NBT_Type.TAG_END) {
|
||||
string name = ReadString().ToNBTString().Data;
|
||||
parent[name] = ReadValue(type);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
//tag.Value = ReadValue(type);
|
||||
|
||||
//return tag;
|
||||
}
|
||||
|
||||
private void WriteValue (NBT_Value val)
|
||||
{
|
||||
switch (val.GetNBTType()) {
|
||||
case NBT_Type.TAG_END:
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_BYTE:
|
||||
WriteByte(val.ToNBTByte());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_SHORT:
|
||||
WriteShort(val.ToNBTShort());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_INT:
|
||||
WriteInt(val.ToNBTInt());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_LONG:
|
||||
WriteLong(val.ToNBTLong());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_FLOAT:
|
||||
WriteFloat(val.ToNBTFloat());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_DOUBLE:
|
||||
WriteDouble(val.ToNBTDouble());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_BYTE_ARRAY:
|
||||
WriteByteArray(val.ToNBTByteArray());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_STRING:
|
||||
WriteString(val.ToNBTString());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_LIST:
|
||||
WriteList(val.ToNBTList());
|
||||
break;
|
||||
|
||||
case NBT_Type.TAG_COMPOUND:
|
||||
WriteCompound(val.ToNBTCompound());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteByte (NBT_Byte val)
|
||||
{
|
||||
_stream.WriteByte(val.Data);
|
||||
}
|
||||
|
||||
private void WriteShort (NBT_Short val)
|
||||
{
|
||||
byte[] gzBytes = BitConverter.GetBytes(val.Data);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
_stream.Write(gzBytes, 0, 2);
|
||||
}
|
||||
|
||||
private void WriteInt (NBT_Int val)
|
||||
{
|
||||
byte[] gzBytes = BitConverter.GetBytes(val.Data);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
_stream.Write(gzBytes, 0, 4);
|
||||
}
|
||||
|
||||
private void WriteLong (NBT_Long val)
|
||||
{
|
||||
byte[] gzBytes = BitConverter.GetBytes(val.Data);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
_stream.Write(gzBytes, 0, 8);
|
||||
}
|
||||
|
||||
private void WriteFloat (NBT_Float val)
|
||||
{
|
||||
byte[] gzBytes = BitConverter.GetBytes(val.Data);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
_stream.Write(gzBytes, 0, 4);
|
||||
}
|
||||
|
||||
private void WriteDouble (NBT_Double val)
|
||||
{
|
||||
byte[] gzBytes = BitConverter.GetBytes(val.Data);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(gzBytes);
|
||||
}
|
||||
|
||||
_stream.Write(gzBytes, 0, 8);
|
||||
}
|
||||
|
||||
private void WriteByteArray (NBT_ByteArray val)
|
||||
{
|
||||
byte[] lenBytes = BitConverter.GetBytes(val.Length);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(lenBytes);
|
||||
}
|
||||
|
||||
_stream.Write(lenBytes, 0, 4);
|
||||
_stream.Write(val.Data, 0, val.Length);
|
||||
}
|
||||
|
||||
private void WriteString (NBT_String val)
|
||||
{
|
||||
byte[] lenBytes = BitConverter.GetBytes((short)val.Length);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(lenBytes);
|
||||
}
|
||||
|
||||
_stream.Write(lenBytes, 0, 2);
|
||||
|
||||
System.Text.Encoding str = Encoding.GetEncoding(28591);
|
||||
byte[] gzBytes = str.GetBytes(val.Data);
|
||||
|
||||
_stream.Write(gzBytes, 0, gzBytes.Length);
|
||||
}
|
||||
|
||||
private void WriteList (NBT_List val)
|
||||
{
|
||||
byte[] lenBytes = BitConverter.GetBytes(val.Count);
|
||||
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
Array.Reverse(lenBytes);
|
||||
}
|
||||
|
||||
_stream.WriteByte((byte)val.ValueType);
|
||||
_stream.Write(lenBytes, 0, 4);
|
||||
|
||||
foreach (NBT_Value v in val) {
|
||||
WriteValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteCompound (NBT_Compound val)
|
||||
{
|
||||
foreach (KeyValuePair<string, NBT_Value> item in val) {
|
||||
WriteTag(item.Key, item.Value);
|
||||
}
|
||||
|
||||
WriteTag(null, _nulltag);
|
||||
}
|
||||
|
||||
private void WriteTag (string name, NBT_Value val)
|
||||
{
|
||||
_stream.WriteByte((byte)val.GetNBTType());
|
||||
|
||||
if (val.GetNBTType() != NBT_Type.TAG_END) {
|
||||
WriteString(name);
|
||||
WriteValue(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTException : Exception
|
||||
{
|
||||
public const String MSG_GZIP_ENDOFSTREAM = "Gzip Error: Unexpected end of stream";
|
||||
|
||||
public const String MSG_READ_NEG = "Read Error: Negative length";
|
||||
public const String MSG_READ_TYPE = "Read Error: Invalid value type";
|
||||
|
||||
public NBTException () { }
|
||||
|
||||
public NBTException (String msg) : base(msg) { }
|
||||
|
||||
public NBTException (String msg, Exception innerException) : base(msg, innerException) { }
|
||||
}
|
||||
|
||||
public class InvalidTagException : Exception { }
|
||||
|
||||
public class InvalidValueException : Exception { }
|
||||
}
|
172
NBToolkit/NBToolkit/Map/NBT/NBTSchema.cs
Normal file
172
NBToolkit/NBToolkit/Map/NBT/NBTSchema.cs
Normal file
|
@ -0,0 +1,172 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NBToolkit.NBT
|
||||
{
|
||||
public abstract class NBTSchemaNode
|
||||
{
|
||||
private string _name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
public NBTSchemaNode (string name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTScalerNode : NBTSchemaNode
|
||||
{
|
||||
private NBT_Type _type;
|
||||
|
||||
public NBT_Type Type
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
|
||||
public NBTScalerNode (string name, NBT_Type type)
|
||||
: base(name)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTArrayNode : NBTSchemaNode
|
||||
{
|
||||
private int _length;
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return _length; }
|
||||
}
|
||||
|
||||
public NBTArrayNode (string name)
|
||||
: base(name)
|
||||
{
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
public NBTArrayNode (string name, int length)
|
||||
: base(name)
|
||||
{
|
||||
_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTListNode : NBTSchemaNode
|
||||
{
|
||||
private NBT_Type _type;
|
||||
private int _length;
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return _length; }
|
||||
}
|
||||
|
||||
public NBT_Type Type
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
|
||||
public NBTListNode (string name, NBT_Type type)
|
||||
: base(name)
|
||||
{
|
||||
_type = type;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
public NBTListNode (string name, NBT_Type type, int length)
|
||||
: base(name)
|
||||
{
|
||||
_type = type;
|
||||
_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTCompoundNode : NBTSchemaNode, ICollection<NBTSchemaNode>
|
||||
{
|
||||
private List<NBTSchemaNode> _subnodes;
|
||||
|
||||
#region ICollection<NBTSchemaNode> Members
|
||||
|
||||
public void Add (NBTSchemaNode item)
|
||||
{
|
||||
_subnodes.Add(item);
|
||||
}
|
||||
|
||||
public void Clear ()
|
||||
{
|
||||
_subnodes.Clear();
|
||||
}
|
||||
|
||||
public bool Contains (NBTSchemaNode item)
|
||||
{
|
||||
return _subnodes.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo (NBTSchemaNode[] array, int arrayIndex)
|
||||
{
|
||||
_subnodes.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _subnodes.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool Remove (NBTSchemaNode item)
|
||||
{
|
||||
return _subnodes.Remove(item);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<NBTSchemaNode> Members
|
||||
|
||||
public IEnumerator<NBTSchemaNode> GetEnumerator ()
|
||||
{
|
||||
return _subnodes.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return _subnodes.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public NBTCompoundNode ()
|
||||
: base("")
|
||||
{
|
||||
_subnodes = new List<NBTSchemaNode>();
|
||||
}
|
||||
|
||||
public NBTCompoundNode (string name)
|
||||
: base(name)
|
||||
{
|
||||
_subnodes = new List<NBTSchemaNode>();
|
||||
}
|
||||
|
||||
public NBTCompoundNode MergeInto (NBTCompoundNode tree)
|
||||
{
|
||||
foreach (NBTSchemaNode node in _subnodes) {
|
||||
tree.Add(node);
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
}
|
557
NBToolkit/NBToolkit/Map/NBT/NBTValues.cs
Normal file
557
NBToolkit/NBToolkit/Map/NBT/NBTValues.cs
Normal file
|
@ -0,0 +1,557 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NBToolkit.NBT {
|
||||
|
||||
/// <summary>
|
||||
/// Describes the type of value held by an NBT_Tag
|
||||
/// </summary>
|
||||
public enum NBT_Type
|
||||
{
|
||||
TAG_END = 0,
|
||||
TAG_BYTE = 1, // 8 bits signed
|
||||
TAG_SHORT = 2, // 16 bits signed
|
||||
TAG_INT = 3, // 32 bits signed
|
||||
TAG_LONG = 4, // 64 bits signed
|
||||
TAG_FLOAT = 5,
|
||||
TAG_DOUBLE = 6,
|
||||
TAG_BYTE_ARRAY = 7,
|
||||
TAG_STRING = 8,
|
||||
TAG_LIST = 9,
|
||||
TAG_COMPOUND = 10
|
||||
}
|
||||
|
||||
public abstract class NBT_Value
|
||||
{
|
||||
virtual public NBT_Null ToNBTNull () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Byte ToNBTByte () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Short ToNBTShort () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Int ToNBTInt () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Long ToNBTLong () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Float ToNBTFloat () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Double ToNBTDouble () { throw new InvalidCastException(); }
|
||||
virtual public NBT_ByteArray ToNBTByteArray () { throw new InvalidCastException(); }
|
||||
virtual public NBT_String ToNBTString () { throw new InvalidCastException(); }
|
||||
virtual public NBT_List ToNBTList () { throw new InvalidCastException(); }
|
||||
virtual public NBT_Compound ToNBTCompound () { throw new InvalidCastException(); }
|
||||
|
||||
virtual public NBT_Type GetNBTType () { return NBT_Type.TAG_END; }
|
||||
}
|
||||
|
||||
public class NBT_Null : NBT_Value
|
||||
{
|
||||
override public NBT_Null ToNBTNull () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_END; }
|
||||
}
|
||||
|
||||
public class NBT_Byte : NBT_Value
|
||||
{
|
||||
private byte _data = 0;
|
||||
|
||||
override public NBT_Byte ToNBTByte () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_BYTE; }
|
||||
|
||||
public byte Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Byte () { }
|
||||
|
||||
public NBT_Byte (byte d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Byte (byte b)
|
||||
{
|
||||
return new NBT_Byte(b);
|
||||
}
|
||||
|
||||
public static implicit operator byte (NBT_Byte b)
|
||||
{
|
||||
return b._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_Short : NBT_Value
|
||||
{
|
||||
private short _data = 0;
|
||||
|
||||
override public NBT_Short ToNBTShort () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_SHORT; }
|
||||
|
||||
public short Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Short () { }
|
||||
|
||||
public NBT_Short (short d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Short (short s)
|
||||
{
|
||||
return new NBT_Short(s);
|
||||
}
|
||||
|
||||
public static implicit operator short (NBT_Short s)
|
||||
{
|
||||
return s._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_Int : NBT_Value
|
||||
{
|
||||
private int _data = 0;
|
||||
|
||||
override public NBT_Int ToNBTInt () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_INT; }
|
||||
|
||||
public int Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Int () { }
|
||||
|
||||
public NBT_Int (int d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Int (int i)
|
||||
{
|
||||
return new NBT_Int(i);
|
||||
}
|
||||
|
||||
public static implicit operator int (NBT_Int i)
|
||||
{
|
||||
return i._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_Long : NBT_Value
|
||||
{
|
||||
private long _data = 0;
|
||||
|
||||
override public NBT_Long ToNBTLong () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_LONG; }
|
||||
|
||||
public long Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Long () { }
|
||||
|
||||
public NBT_Long (long d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Long (long l)
|
||||
{
|
||||
return new NBT_Long(l);
|
||||
}
|
||||
|
||||
public static implicit operator long (NBT_Long l)
|
||||
{
|
||||
return l._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_Float : NBT_Value
|
||||
{
|
||||
private float _data = 0;
|
||||
|
||||
override public NBT_Float ToNBTFloat () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_FLOAT; }
|
||||
|
||||
public float Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Float () { }
|
||||
|
||||
public NBT_Float (float d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Float (float f)
|
||||
{
|
||||
return new NBT_Float(f);
|
||||
}
|
||||
|
||||
public static implicit operator float (NBT_Float f)
|
||||
{
|
||||
return f._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_Double : NBT_Value
|
||||
{
|
||||
private double _data = 0;
|
||||
|
||||
override public NBT_Double ToNBTDouble () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_DOUBLE; }
|
||||
|
||||
public double Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public NBT_Double () { }
|
||||
|
||||
public NBT_Double (double d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_Double (double d)
|
||||
{
|
||||
return new NBT_Double(d);
|
||||
}
|
||||
|
||||
public static implicit operator double (NBT_Double d)
|
||||
{
|
||||
return d._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_ByteArray : NBT_Value
|
||||
{
|
||||
private byte[] _data = null;
|
||||
|
||||
override public NBT_ByteArray ToNBTByteArray () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_BYTE_ARRAY; }
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return _data.Length; }
|
||||
}
|
||||
|
||||
public NBT_ByteArray () { }
|
||||
|
||||
public NBT_ByteArray (byte[] d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public byte this [int index] {
|
||||
get { return _data[index]; }
|
||||
set { _data[index] = value; }
|
||||
}
|
||||
|
||||
public static implicit operator NBT_ByteArray (byte[] b)
|
||||
{
|
||||
return new NBT_ByteArray(b);
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_String : NBT_Value
|
||||
{
|
||||
private string _data = null;
|
||||
|
||||
override public NBT_String ToNBTString () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_STRING; }
|
||||
|
||||
public string Data
|
||||
{
|
||||
get { return _data; }
|
||||
set { _data = value; }
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return _data.Length; }
|
||||
}
|
||||
|
||||
public NBT_String () { }
|
||||
|
||||
public NBT_String (string d)
|
||||
{
|
||||
_data = d;
|
||||
}
|
||||
|
||||
public static implicit operator NBT_String (string s)
|
||||
{
|
||||
return new NBT_String(s);
|
||||
}
|
||||
|
||||
public static implicit operator string (NBT_String s)
|
||||
{
|
||||
return s._data;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBT_List : NBT_Value, IList<NBT_Value>
|
||||
{
|
||||
private NBT_Type _type = NBT_Type.TAG_END;
|
||||
|
||||
private List<NBT_Value> _items = null;
|
||||
|
||||
override public NBT_List ToNBTList () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_LIST; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _items.Count; }
|
||||
}
|
||||
|
||||
public NBT_Type ValueType
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
|
||||
public NBT_List (NBT_Type type)
|
||||
{
|
||||
_type = type;
|
||||
_items = new List<NBT_Value>();
|
||||
}
|
||||
|
||||
public NBT_List (NBT_Type type, List<NBT_Value> items)
|
||||
{
|
||||
_type = type;
|
||||
_items = items;
|
||||
}
|
||||
|
||||
#region IList<NBT_Value> Members
|
||||
|
||||
public int IndexOf (NBT_Value item)
|
||||
{
|
||||
return _items.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert (int index, NBT_Value item)
|
||||
{
|
||||
_items.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
_items.RemoveAt(index);
|
||||
}
|
||||
|
||||
public NBT_Value this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _items[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_items[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection<NBT_Value> Members
|
||||
|
||||
public void Add (NBT_Value item)
|
||||
{
|
||||
_items.Add(item);
|
||||
}
|
||||
|
||||
public void Clear ()
|
||||
{
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
public bool Contains (NBT_Value item)
|
||||
{
|
||||
return _items.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo (NBT_Value[] array, int arrayIndex)
|
||||
{
|
||||
_items.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool Remove (NBT_Value item)
|
||||
{
|
||||
return _items.Remove(item);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<NBT_Value> Members
|
||||
|
||||
public IEnumerator<NBT_Value> GetEnumerator ()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class NBT_Compound : NBT_Value, IDictionary<string, NBT_Value>
|
||||
{
|
||||
private Dictionary<string, NBT_Value> _tags;
|
||||
|
||||
override public NBT_Compound ToNBTCompound () { return this; }
|
||||
override public NBT_Type GetNBTType () { return NBT_Type.TAG_COMPOUND; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _tags.Count; }
|
||||
}
|
||||
|
||||
public NBT_Compound ()
|
||||
{
|
||||
_tags = new Dictionary<string, NBT_Value>();
|
||||
}
|
||||
|
||||
#region IDictionary<string,NBT_Value> Members
|
||||
|
||||
public void Add (string key, NBT_Value value)
|
||||
{
|
||||
_tags.Add(key, value);
|
||||
}
|
||||
|
||||
public bool ContainsKey (string key)
|
||||
{
|
||||
return _tags.ContainsKey(key);
|
||||
}
|
||||
|
||||
public ICollection<string> Keys
|
||||
{
|
||||
get { return _tags.Keys; }
|
||||
}
|
||||
|
||||
public bool Remove (string key)
|
||||
{
|
||||
return _tags.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue (string key, out NBT_Value value)
|
||||
{
|
||||
return _tags.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public ICollection<NBT_Value> Values
|
||||
{
|
||||
get { return _tags.Values; }
|
||||
}
|
||||
|
||||
public NBT_Value this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tags[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
_tags[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection<KeyValuePair<string,NBT_Value>> Members
|
||||
|
||||
public void Add (KeyValuePair<string, NBT_Value> item)
|
||||
{
|
||||
_tags.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
public void Clear ()
|
||||
{
|
||||
_tags.Clear();
|
||||
}
|
||||
|
||||
public bool Contains (KeyValuePair<string, NBT_Value> item)
|
||||
{
|
||||
NBT_Value value;
|
||||
if (!_tags.TryGetValue(item.Key, out value)) {
|
||||
return false;
|
||||
}
|
||||
return value == item.Value;
|
||||
}
|
||||
|
||||
public void CopyTo (KeyValuePair<string, NBT_Value>[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
if (arrayIndex < 0) {
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
if (array.Length - arrayIndex < _tags.Count) {
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, NBT_Value> item in _tags) {
|
||||
array[arrayIndex] = item;
|
||||
arrayIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool Remove (KeyValuePair<string, NBT_Value> item)
|
||||
{
|
||||
if (Contains(item)) {
|
||||
_tags.Remove(item.Key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<KeyValuePair<string,NBT_Value>> Members
|
||||
|
||||
public IEnumerator<KeyValuePair<string, NBT_Value>> GetEnumerator ()
|
||||
{
|
||||
return _tags.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return _tags.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
206
NBToolkit/NBToolkit/Map/NBT/NBTVerifier.cs
Normal file
206
NBToolkit/NBToolkit/Map/NBT/NBTVerifier.cs
Normal file
|
@ -0,0 +1,206 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace NBToolkit.NBT
|
||||
{
|
||||
public delegate void MissingTagHandler (Object o, TagEventArgs e);
|
||||
public delegate void InvalidTagTypeHandler (Object o, TagEventArgs e);
|
||||
public delegate void InvalidTagValueHandler (Object o, TagEventArgs e);
|
||||
|
||||
public interface INBTVerifier
|
||||
{
|
||||
event MissingTagHandler MissingTag;
|
||||
event InvalidTagTypeHandler InvalidTagType;
|
||||
event InvalidTagValueHandler InvalidTagValue;
|
||||
|
||||
bool Verify ();
|
||||
}
|
||||
|
||||
public class TagEventArgs : EventArgs
|
||||
{
|
||||
protected string _tagName;
|
||||
protected NBT_Value _tag;
|
||||
protected NBTSchemaNode _schema;
|
||||
|
||||
public string TagName
|
||||
{
|
||||
get { return _tagName; }
|
||||
}
|
||||
|
||||
/* public NBT_Tag Tag
|
||||
{
|
||||
get { return _tag; }
|
||||
}*/
|
||||
|
||||
public TagEventArgs (string tagName)
|
||||
: base()
|
||||
{
|
||||
_tagName = tagName;
|
||||
}
|
||||
|
||||
public TagEventArgs (string tagName, NBT_Value tag)
|
||||
: base()
|
||||
{
|
||||
_tag = tag;
|
||||
_tagName = tagName;
|
||||
}
|
||||
|
||||
public TagEventArgs (NBTSchemaNode schema, NBT_Value tag)
|
||||
: base()
|
||||
{
|
||||
_tag = tag;
|
||||
_schema = schema;
|
||||
}
|
||||
}
|
||||
|
||||
public class NBTVerifier : INBTVerifier
|
||||
{
|
||||
private NBT_Compound _root;
|
||||
private NBTSchemaNode _schema;
|
||||
|
||||
public event MissingTagHandler MissingTag;
|
||||
public event InvalidTagTypeHandler InvalidTagType;
|
||||
public event InvalidTagValueHandler InvalidTagValue;
|
||||
|
||||
public NBTVerifier () { }
|
||||
|
||||
public NBTVerifier (NBT_Compound root, NBTSchemaNode schema)
|
||||
{
|
||||
_root = root;
|
||||
_schema = schema;
|
||||
}
|
||||
|
||||
public bool Verify ()
|
||||
{
|
||||
return Verify(_root, _schema);
|
||||
}
|
||||
|
||||
static NBTCompoundNode inventorySchema = new NBTCompoundNode("")
|
||||
{
|
||||
new NBTScalerNode("id", NBT_Type.TAG_SHORT),
|
||||
new NBTScalerNode("Damage", NBT_Type.TAG_SHORT),
|
||||
new NBTScalerNode("Count", NBT_Type.TAG_BYTE),
|
||||
new NBTScalerNode("Slot", NBT_Type.TAG_BYTE),
|
||||
};
|
||||
|
||||
private bool Verify (NBT_Value tag, NBTSchemaNode schema)
|
||||
{
|
||||
if (tag == null) {
|
||||
OnMissingTag(new TagEventArgs(schema.Name));
|
||||
return false;
|
||||
}
|
||||
|
||||
NBTScalerNode scaler = schema as NBTScalerNode;
|
||||
if (scaler != null) {
|
||||
return VerifyScaler(tag, scaler);
|
||||
}
|
||||
|
||||
NBTArrayNode array = schema as NBTArrayNode;
|
||||
if (array != null) {
|
||||
return VerifyArray(tag, array);
|
||||
}
|
||||
|
||||
NBTListNode list = schema as NBTListNode;
|
||||
if (list != null) {
|
||||
return VerifyList(tag, list);
|
||||
}
|
||||
|
||||
NBTCompoundNode compound = schema as NBTCompoundNode;
|
||||
if (compound != null) {
|
||||
return VerifyCompound(tag, compound);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool VerifyScaler (NBT_Value tag, NBTScalerNode schema)
|
||||
{
|
||||
if (tag.GetNBTType() != schema.Type) {
|
||||
OnInvalidTagType(new TagEventArgs(schema.Name, tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool VerifyArray (NBT_Value tag, NBTArrayNode schema)
|
||||
{
|
||||
NBT_ByteArray atag = tag as NBT_ByteArray;
|
||||
if (atag == null) {
|
||||
OnInvalidTagType(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
if (schema.Length > 0 && atag.Length != schema.Length) {
|
||||
OnInvalidTagValue(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool VerifyList (NBT_Value tag, NBTListNode schema)
|
||||
{
|
||||
NBT_List ltag = tag as NBT_List;
|
||||
if (ltag == null) {
|
||||
OnInvalidTagType(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
if (ltag.Count > 0 && ltag.ValueType != schema.Type) {
|
||||
OnInvalidTagValue(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
if (schema.Length > 0 && ltag.Count != schema.Length) {
|
||||
OnInvalidTagValue(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool VerifyCompound (NBT_Value tag, NBTCompoundNode schema)
|
||||
{
|
||||
NBT_Compound ctag = tag as NBT_Compound;
|
||||
if (ctag == null) {
|
||||
OnInvalidTagType(new TagEventArgs(schema, tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pass = true;
|
||||
|
||||
foreach (NBTSchemaNode node in schema) {
|
||||
NBT_Value value;
|
||||
ctag.TryGetValue(node.Name, out value);
|
||||
|
||||
pass = Verify(value, node) && pass;
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
protected void OnMissingTag (TagEventArgs e)
|
||||
{
|
||||
if (MissingTag != null) {
|
||||
MissingTag(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnInvalidTagType (TagEventArgs e)
|
||||
{
|
||||
if (InvalidTagType != null) {
|
||||
InvalidTagType(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnInvalidTagValue (TagEventArgs e)
|
||||
{
|
||||
if (InvalidTagValue != null) {
|
||||
InvalidTagValue(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue