private void DumpTag(NbtTag tag, int level, StreamWriter writer)
        {
            for (var index = 0; index < level; index++)
                writer.Write("   ");
            writer.Write(tag.Name);
            writer.Write(" [");
            writer.Write(tag.GetType().Name);
            writer.Write("]: ");

            if (tag is NbtCompound)
            {
                writer.WriteLine("...");
                foreach (var name in ((NbtCompound)tag).Names)
                {
                    var value = tag[name];
                    this.DumpTag(value, level + 1, writer);
                }
            }
            else if (tag is NbtList)
            {
                writer.WriteLine("...");
                foreach (var item in (NbtList)tag)
                    this.DumpTag(item, level + 1, writer);
            }
            else
                writer.WriteLine(tag);
        }
Example #2
0
        public object Deserialize(NbtTag value)
        {
            if (value is NbtByte)
                return ((NbtByte)value).Value;
            else if (value is NbtByteArray)
                return ((NbtByteArray)value).Value;
            else if (value is NbtDouble)
                return ((NbtDouble)value).Value;
            else if (value is NbtFloat)
                return ((NbtFloat)value).Value;
            else if (value is NbtInt)
                return ((NbtInt)value).Value;
            else if (value is NbtIntArray)
                return ((NbtIntArray)value).Value;
            else if (value is NbtLong)
                return ((NbtLong)value).Value;
            else if (value is NbtShort)
                return ((NbtShort)value).Value;
            else if (value is NbtString)
                return ((NbtString)value).Value;
            else if(value is NbtCompound)
            {
                var compound = value as NbtCompound;
                var properties = Type.GetProperties().Where(p =>
                    !Attribute.GetCustomAttributes(p, typeof(NbtIgnoreAttribute)).Any());
                var resultObject = Activator.CreateInstance(Type);
                foreach (var property in properties)
                {
                    if (!property.CanWrite)
                        continue;
                    string name = property.Name;
                    var nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute));

                    if (nameAttributes.Length != 0)
                        name = ((TagNameAttribute)nameAttributes[0]).Name;
                    var node = compound.Tags.SingleOrDefault(a => a.Name == name);
                    if (node == null) continue;
                    var data = new NbtSerializer(property.PropertyType).Deserialize(node);

                    if (property.PropertyType == typeof(bool)
                        && data is byte)
                        data = (byte)data == 1;

                    property.SetValue(resultObject, data, null);
                }
                
                return resultObject;
            }
            
            throw new NotSupportedException("The node type '" + value.GetType() + "' is not supported.");
        }
Example #3
0
        public object Deserialize(NbtTag value, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && typeof(INbtSerializable).IsAssignableFrom(Type))
            {
                var instance = (INbtSerializable)Activator.CreateInstance(Type);
                instance.Deserialize(value);
                return instance;
            }
            if (value is NbtByte)
                return ((NbtByte)value).Value;
            else if (value is NbtByteArray)
                return ((NbtByteArray)value).Value;
            else if (value is NbtDouble)
                return ((NbtDouble)value).Value;
            else if (value is NbtFloat)
                return ((NbtFloat)value).Value;
            else if (value is NbtInt)
                return ((NbtInt)value).Value;
            else if (value is NbtIntArray)
                return ((NbtIntArray)value).Value;
            else if (value is NbtLong)
                return ((NbtLong)value).Value;
            else if (value is NbtShort)
                return ((NbtShort)value).Value;
            else if (value is NbtString)
                return ((NbtString)value).Value;
            else if (value is NbtList)
            {
                var list = (NbtList)value;
                var type = typeof(object);
                if (list.ListType == NbtTagType.Byte)
                    type = typeof(byte);
                else if (list.ListType == NbtTagType.ByteArray)
                    type = typeof(byte[]);
                else if (list.ListType == NbtTagType.Compound)
                {
                    if (Type.IsArray)
                        type = Type.GetElementType();
                    else
                        type = typeof(object);
                }
                else if (list.ListType == NbtTagType.Double)
                    type = typeof(double);
                else if (list.ListType == NbtTagType.Float)
                    type = typeof(float);
                else if (list.ListType == NbtTagType.Int)
                    type = typeof(int);
                else if (list.ListType == NbtTagType.IntArray)
                    type = typeof(int[]);
                else if (list.ListType == NbtTagType.Long)
                    type = typeof(long);
                else if (list.ListType == NbtTagType.Short)
                    type = typeof(short);
                else if (list.ListType == NbtTagType.String)
                    type = typeof(string);
                else
                    throw new NotSupportedException("The NBT list type '" + list.TagType + "' is not supported.");
                var array = Array.CreateInstance(type, list.Count);
                var innerSerializer = new NbtSerializer(type);
                for (int i = 0; i < array.Length; i++)
                    array.SetValue(innerSerializer.Deserialize(list[i]), i);
                return array;
            }
            else if(value is NbtCompound)
            {
                var compound = value as NbtCompound;
                var properties = Type.GetProperties().Where(p =>
                    !Attribute.GetCustomAttributes(p, typeof(NbtIgnoreAttribute)).Any());
                var resultObject = Activator.CreateInstance(Type);
                foreach (var property in properties)
                {
                    if (!property.CanWrite)
                        continue;
                    string name = property.Name;
                    var nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute));

                    if (nameAttributes.Length != 0)
                        name = ((TagNameAttribute)nameAttributes[0]).Name;
                    var node = compound.Tags.SingleOrDefault(a => a.Name == name);
                    if (node == null) continue;
                    object data;
                    if (typeof(INbtSerializable).IsAssignableFrom(property.PropertyType))
                    {
                        data = Activator.CreateInstance(property.PropertyType);
                        ((INbtSerializable)data).Deserialize(node);
                    }
                    else
                        data = new NbtSerializer(property.PropertyType).Deserialize(node);

                    // Some manual casting for edge cases
                    if (property.PropertyType == typeof(bool)
                        && data is byte)
                        data = (byte)data == 1;
                    if (property.PropertyType == typeof(sbyte) && data is byte)
                        data = (sbyte)(byte)data;

                    property.SetValue(resultObject, data, null);
                }

                return resultObject;
            }

            throw new NotSupportedException("The node type '" + value.GetType() + "' is not supported.");
        }