Esempio n. 1
0
 /// <summary>
 /// Loads a level from the given level.dat file.
 /// </summary>
 public static Level Load(string file)
 {
     if (!Path.IsPathRooted(file))
         file = Path.Combine(Directory.GetCurrentDirectory(), file);
     var serializer = new NbtSerializer(typeof(Level));
     var nbtFile = new NbtFile(file);
     var level = (Level)serializer.Deserialize(nbtFile.RootTag["Data"]);
     level.DatFile = file;
     level.BaseDirectory = Path.GetDirectoryName(file);
     level.WorldGenerator = GetGenerator(level.GeneratorName);
     level.WorldGenerator.Initialize(level);
     var worlds = Directory.GetDirectories(level.BaseDirectory).Where(
         d => Directory.GetFiles(d).Any(f => f.EndsWith(".mca") || f.EndsWith(".mcr")));
     foreach (var world in worlds)
     {
         var w = World.LoadWorld(world);
         w.WorldGenerator = level.WorldGenerator;
         level.AddWorld(w);
     }
     return level;
 }
Esempio n. 2
0
 public static Chunk FromNbt(NbtFile nbt)
 {
     var serializer = new NbtSerializer(typeof(Chunk));
     var chunk = (Chunk)serializer.Deserialize(nbt.RootTag["Level"]);
     return chunk;
 }
Esempio n. 3
0
        public void Deserialize(NbtTag value)
        {
            var compound = value as NbtCompound;
            var chunk = (Chunk)Serializer.Deserialize(value, true);

            this._TileEntities = chunk._TileEntities;
            this.Biomes = chunk.Biomes;
            this.HeightMap = chunk.HeightMap;
            this.LastUpdate = chunk.LastUpdate;
            this.Sections = chunk.Sections;
            this.TerrainPopulated = chunk.TerrainPopulated;
            this.X = chunk.X;
            this.Z = chunk.Z;

            // Entities
            var entities = compound["Entities"] as NbtList;
            Entities = new List<IDiskEntity>();
            for (int i = 0; i < entities.Count; i++)
            {
                var id = entities[i]["id"].StringValue;
                IDiskEntity entity;
                if (EntityTypes.ContainsKey(id.ToUpper()))
                    entity = (IDiskEntity)Activator.CreateInstance(EntityTypes[id]);
                else
                    entity = new UnrecognizedEntity(id);
                entity.Deserialize(entities[i]);
                Entities.Add(entity);
            }
            var serializer = new NbtSerializer(typeof(Section));
            foreach (var section in compound["Sections"] as NbtList)
            {
                int index = section["Y"].IntValue;
                Sections[index] = (Section)serializer.Deserialize(section);
                Sections[index].ProcessSection();
            }
        }
Esempio n. 4
0
        public object Deserialize(NbtTag tag, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && typeof(INbtSerializable).IsAssignableFrom(Type)) {
                var instance = (INbtSerializable)Activator.CreateInstance(Type);
                instance.Deserialize(tag);
                return instance;
            }
            switch (tag.TagType) {
                case NbtTagType.List:
                    var list = (NbtList)tag;
                    Type type;
                    switch (list.ListType) {
                        case NbtTagType.Byte:
                            type = typeof(byte);
                            break;
                        case NbtTagType.ByteArray:
                            type = typeof(byte[]);
                            break;
                        case NbtTagType.List:
                            type = Type.GetElementType() ?? typeof(object);
                            break;
                        case NbtTagType.Double:
                            type = typeof(double);
                            break;
                        case NbtTagType.Float:
                            type = typeof(float);
                            break;
                        case NbtTagType.Int:
                            type = typeof(int);
                            break;
                        case NbtTagType.IntArray:
                            type = typeof(int[]);
                            break;
                        case NbtTagType.Long:
                            type = typeof(long);
                            break;
                        case NbtTagType.Short:
                            type = typeof(short);
                            break;
                        case NbtTagType.String:
                            type = typeof(string);
                            break;
                        default:
                            throw new NotSupportedException("The NBT list type '" + list.TagType +
                                                            "' is not supported.");
                    }
                    Array array = Array.CreateInstance(type, list.Count);
                    if (type.IsPrimitive || type.IsArray || type == typeof(string)) {
                        for (int i = 0; i < array.Length; i++) {
                            array.SetValue(DeserializeSimpleType(list[i]), i);
                        }
                    } else {
                        var innerSerializer = new NbtSerializer(type);
                        for (int i = 0; i < array.Length; i++) {
                            array.SetValue(innerSerializer.Deserialize(list[i]), i);
                        }
                    }
                    return array;

                case NbtTagType.Compound:
                    if (!propertyInfoRead) ReadPropertyInfo();
                    var compound = (NbtCompound)tag;

                    object resultObject = Activator.CreateInstance(Type);
                    foreach (PropertyInfo property in properties) {
                        if (!property.CanWrite) continue;
                        string name = propertyTagNames[property];

                        NbtTag node;
                        if (!compound.TryGet(name, out node)) 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;
                        }

                        if (property.PropertyType.IsInstanceOfType(data)) {
                            property.SetValue(resultObject, data, null);
                        } else {
                            property.SetValue(resultObject, Convert.ChangeType(data, property.PropertyType), null);
                        }
                    }

                    return resultObject;

                default:
                    return DeserializeSimpleType(tag);
            }
        }
Esempio n. 5
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.");
        }
Esempio n. 6
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.");
        }