/// <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; }
public static Chunk FromNbt(NbtFile nbt) { var serializer = new NbtSerializer(typeof(Chunk)); var chunk = (Chunk)serializer.Deserialize(nbt.RootTag["Level"]); return chunk; }
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(); } }
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); } }
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."); }
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."); }