Esempio n. 1
0
 public NbtFile ToNbt()
 {
     var serializer = new NbtSerializer(typeof(Chunk));
     var compound = serializer.Serialize(this, "Level") as NbtCompound;
     var file = new NbtFile();
     file.RootTag.Add(compound);
     return file;
 }
Esempio n. 2
0
 /// <summary>
 /// Saves this level. This will not work with an in-memory world.
 /// </summary>
 public void Save()
 {
     if (DatFile == null)
         throw new InvalidOperationException("This level exists only in memory. Use Save(string).");
     LastPlayed = DateTime.UtcNow.Ticks;
     var serializer = new NbtSerializer(typeof(Level));
     var tag = serializer.Serialize(this, "Data") as NbtCompound;
     var file = new NbtFile();
     file.RootTag.Add(tag);
     file.SaveToFile(DatFile, NbtCompression.GZip);
     // Save worlds
     foreach (var world in Worlds)
     {
         if (world.BaseDirectory == null)
             world.Save(Path.Combine(BaseDirectory, world.Name));
         else
             world.Save();
     }
 }
Esempio n. 3
0
 public NbtTag Serialize(string tagName)
 {
     var chunk = (NbtCompound)Serializer.Serialize(this, tagName, true);
     var entities = new NbtList("Entities", NbtTagType.Compound);
     for (int i = 0; i < Entities.Count; i++)
         entities.Add(Entities[i].Serialize(string.Empty));
     chunk.Add(entities);
     var sections = new NbtList("Sections", NbtTagType.Compound);
     var serializer = new NbtSerializer(typeof(Section));
     for (int i = 0; i < Sections.Length; i++)
     {
         if (!Sections[i].IsAir)
             sections.Add(serializer.Serialize(Sections[i]));
     }
     chunk.Add(sections);
     return chunk;
 }
Esempio n. 4
0
        NbtTag SerializeList(string tagName, IList valueAsArray, Type elementType, NullPolicy elementNullPolicy)
        {
            NbtTagType listType;
            if (elementType == typeof(byte) || elementType == typeof(sbyte) || elementType == typeof(bool)) {
                listType = NbtTagType.Byte;
            } else if (elementType == typeof(byte[])) {
                listType = NbtTagType.ByteArray;
            } else if (elementType == typeof(double)) {
                listType = NbtTagType.Double;
            } else if (elementType == typeof(float)) {
                listType = NbtTagType.Float;
            } else if (elementType == typeof(int) || elementType == typeof(uint)) {
                listType = NbtTagType.Int;
            } else if (elementType == typeof(int[])) {
                listType = NbtTagType.IntArray;
            } else if (elementType == typeof(long) || elementType == typeof(ulong)) {
                listType = NbtTagType.Long;
            } else if (elementType == typeof(short) || elementType == typeof(ushort)) {
                listType = NbtTagType.Short;
            } else if (elementType == typeof(string)) {
                listType = NbtTagType.String;
            } else {
                listType = NbtTagType.Compound;
            }

            var list = new NbtList(tagName, listType);

            if (elementType.IsPrimitive) {
                // speedy serialization for basic types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    list.Add(SerializePrimitiveType(null, valueAsArray[i]));
                }
            } else if (SerializationUtil.IsDirectlyMappedType(elementType)) {
                // speedy serialization for directly-mapped types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.InsertDefault:
                                list.Add(Serialize(SerializationUtil.GetDefaultValue(elementType), true));
                                break;
                            case NullPolicy.Ignore:
                                continue;
                        }
                    } else {
                        list.Add(Serialize(valueAsArray[i], true));
                    }
                }
            } else {
                // serialize complex types
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.Ignore:
                                continue;
                            case NullPolicy.InsertDefault:
                                // TODO
                                break;
                        }
                    } else {
                        list.Add(innerSerializer.Serialize(valueAsArray[i], null));
                    }
                }
            }
            return list;
        }
Esempio n. 5
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false,
                                NullPolicy thisNullPolicy = NullPolicy.Error,
                                NullPolicy elementNullPolicy = NullPolicy.Error)
        {
            if (value == null) {
                return new NbtCompound(tagName);
            }

            Type realType = value.GetType();
            if (realType.IsPrimitive) {
                return SerializePrimitiveType(tagName, value);
            }

            var valueAsString = value as string;
            if (valueAsString != null) {
                return new NbtString(tagName, valueAsString);
            }

            // Serialize arrays
            var valueAsArray = value as Array;
            if (valueAsArray != null) {
                var valueAsByteArray = value as byte[];
                if (valueAsByteArray != null) {
                    return new NbtByteArray(tagName, valueAsByteArray);
                }

                var valueAsIntArray = value as int[];
                if (valueAsIntArray != null) {
                    return new NbtIntArray(tagName, valueAsIntArray);
                }

                Type elementType = realType.GetElementType();
                return SerializeList(tagName, valueAsArray, elementType, elementNullPolicy);
            }

            if (!skipInterfaceCheck && value is INbtSerializable) {
                return ((INbtSerializable)value).Serialize(tagName);
            }

            // Serialize ILists
            if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(List<>)) {
                Type listType = realType.GetGenericArguments()[0];
                return SerializeList(tagName, (IList)value, listType, elementNullPolicy);
            }

            // Skip serializing NbtTags and NbtFiles
            var valueAsTag = value as NbtTag;
            if (valueAsTag != null) {
                return valueAsTag;
            }
            var file = value as NbtFile;
            if (file != null) {
                return file.RootTag;
            }

            // Fallback for compound tags
            var compound = new NbtCompound(tagName);
            if (!propertyInfoRead) ReadPropertyInfo();

            foreach (PropertyInfo property in properties) {
                if (!property.CanRead) continue;
                Type propType = property.PropertyType;
                object propValue = property.GetValue(value, null);

                // Handle null property values
                if (propValue == null) {
                    NullPolicy selfNullPolicy = GetElementPolicy(property);
                    switch (selfNullPolicy) {
                        case NullPolicy.Ignore:
                            continue;
                        case NullPolicy.Error:
                            throw new NullReferenceException("Null values not allowed for property " + property.Name);
                        case NullPolicy.InsertDefault:
                            propValue = SerializationUtil.GetDefaultValue(propType);
                            break;
                    }
                }

                string propTagName = propertyTagNames[property];
                NbtTag tag;
                if (propType.IsPrimitive) {
                    tag = SerializePrimitiveType(propTagName, propValue);
                } else if (propType.IsArray || propType == typeof(string)) {
                    tag = Serialize(propValue, propTagName);
                } else {
                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    tag = innerSerializer.Serialize(propValue, propTagName);
                }
                compound.Add(tag);
            }

            return compound;
        }
Esempio n. 6
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && value is INbtSerializable)
            {
                return(((INbtSerializable)value).Serialize(tagName));
            }
            else if (value is NbtTag)
            {
                return((NbtTag)value);
            }
            else if (value is byte)
            {
                return(new NbtByte(tagName, (byte)value));
            }
            else if (value is sbyte)
            {
                return(new NbtByte(tagName, (byte)(sbyte)value));
            }
            else if (value is bool)
            {
                return(new NbtByte(tagName, (byte)((bool)value ? 1 : 0)));
            }
            else if (value is byte[])
            {
                return(new NbtByteArray(tagName, (byte[])value));
            }
            else if (value is double)
            {
                return(new NbtDouble(tagName, (double)value));
            }
            else if (value is float)
            {
                return(new NbtFloat(tagName, (float)value));
            }
            else if (value is int)
            {
                return(new NbtInt(tagName, (int)value));
            }
            else if (value is uint)
            {
                return(new NbtInt(tagName, (int)(uint)value));
            }
            else if (value is int[])
            {
                return(new NbtIntArray(tagName, (int[])value));
            }
            else if (value is long)
            {
                return(new NbtLong(tagName, (long)value));
            }
            else if (value is ulong)
            {
                return(new NbtLong(tagName, (long)(ulong)value));
            }
            else if (value is short)
            {
                return(new NbtShort(tagName, (short)value));
            }
            else if (value is ushort)
            {
                return(new NbtShort(tagName, (short)(ushort)value));
            }
            else if (value is string)
            {
                return(new NbtString(tagName, (string)value));
            }
            else if (value.GetType().IsArray)
            {
                var elementType = value.GetType().GetElementType();
                var array       = value as Array;
                var listType    = NbtTagType.Compound;
                if (elementType == typeof(byte) || elementType == typeof(sbyte))
                {
                    listType = NbtTagType.Byte;
                }
                else if (elementType == typeof(bool))
                {
                    listType = NbtTagType.Byte;
                }
                else if (elementType == typeof(byte[]))
                {
                    listType = NbtTagType.ByteArray;
                }
                else if (elementType == typeof(double))
                {
                    listType = NbtTagType.Double;
                }
                else if (elementType == typeof(float))
                {
                    listType = NbtTagType.Float;
                }
                else if (elementType == typeof(int) || elementType == typeof(uint))
                {
                    listType = NbtTagType.Int;
                }
                else if (elementType == typeof(int[]))
                {
                    listType = NbtTagType.IntArray;
                }
                else if (elementType == typeof(long) || elementType == typeof(ulong))
                {
                    listType = NbtTagType.Long;
                }
                else if (elementType == typeof(short) || elementType == typeof(ushort))
                {
                    listType = NbtTagType.Short;
                }
                else if (elementType == typeof(string))
                {
                    listType = NbtTagType.String;
                }
                var list            = new NbtList(tagName, listType);
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < array.Length; i++)
                {
                    list.Add(innerSerializer.Serialize(array.GetValue(i)));
                }
                return(list);
            }
            else if (value is NbtFile)
            {
                return(((NbtFile)value).RootTag);
            }
            else
            {
                var compound = new NbtCompound(tagName);

                if (value == null)
                {
                    return(compound);
                }
                var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof(TagNameAttribute));

                if (nameAttributes.Length > 0)
                {
                    compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name);
                }

                var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p,
                                                                                                typeof(NbtIgnoreAttribute)).Any());

                foreach (var property in properties)
                {
                    if (!property.CanRead)
                    {
                        continue;
                    }

                    NbtTag tag = null;

                    string name = property.Name;
                    nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute));
                    var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute));
                    if (nameAttributes.Length != 0)
                    {
                        name = ((TagNameAttribute)nameAttributes[0]).Name;
                    }

                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    var propValue       = property.GetValue(value, null);

                    if (propValue == null)
                    {
                        if (ignoreOnNullAttribute != null)
                        {
                            continue;
                        }
                        if (property.PropertyType.IsValueType)
                        {
                            propValue = Activator.CreateInstance(property.PropertyType);
                        }
                        else if (property.PropertyType == typeof(string))
                        {
                            propValue = "";
                        }
                    }

                    tag = innerSerializer.Serialize(propValue, name);
                    compound.Add(tag);
                }

                return(compound);
            }
        }
Esempio n. 7
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && value is INbtSerializable)
                return ((INbtSerializable)value).Serialize(tagName);
            else if (value is NbtTag)
                return (NbtTag)value;
            else if (value is byte)
                return new NbtByte(tagName, (byte)value);
            else if (value is sbyte)
                return new NbtByte(tagName, (byte)(sbyte)value);
            else if (value is bool)
                return new NbtByte(tagName, (byte)((bool)value ? 1 : 0));
            else if (value is byte[])
                return new NbtByteArray(tagName, (byte[])value);
            else if (value is double)
                return new NbtDouble(tagName, (double)value);
            else if (value is float)
                return new NbtFloat(tagName, (float)value);
            else if (value is int)
                return new NbtInt(tagName, (int)value);
            else if (value is uint)
                return new NbtInt(tagName, (int)(uint)value);
            else if (value is int[])
                return new NbtIntArray(tagName, (int[])value);
            else if (value is long)
                return new NbtLong(tagName, (long)value);
            else if (value is ulong)
                return new NbtLong(tagName, (long)(ulong)value);
            else if (value is short)
                return new NbtShort(tagName, (short)value);
            else if (value is ushort)
                return new NbtShort(tagName, (short)(ushort)value);
            else if (value is string)
                return new NbtString(tagName, (string)value);
            else if (value.GetType().IsArray)
            {
                var elementType = value.GetType().GetElementType();
                var array = value as Array;
                var listType = NbtTagType.Compound;
                if (elementType == typeof (byte) || elementType == typeof (sbyte))
                    listType = NbtTagType.Byte;
                else if (elementType == typeof (bool))
                    listType = NbtTagType.Byte;
                else if (elementType == typeof (byte[]))
                    listType = NbtTagType.ByteArray;
                else if (elementType == typeof (double))
                    listType = NbtTagType.Double;
                else if (elementType == typeof (float))
                    listType = NbtTagType.Float;
                else if (elementType == typeof (int) || elementType == typeof (uint))
                    listType = NbtTagType.Int;
                else if (elementType == typeof (int[]))
                    listType = NbtTagType.IntArray;
                else if (elementType == typeof (long) || elementType == typeof (ulong))
                    listType = NbtTagType.Long;
                else if (elementType == typeof (short) || elementType == typeof (ushort))
                    listType = NbtTagType.Short;
                else if (elementType == typeof (string))
                    listType = NbtTagType.String;
                var list = new NbtList(tagName, listType);
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < array.Length; i++)
                    list.Add(innerSerializer.Serialize(array.GetValue(i)));
                return list;
            }
            else if (value is NbtFile)
                return ((NbtFile)value).RootTag;
            else
            {
                var compound = new NbtCompound(tagName);

                if (value == null) return compound;
                var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof (TagNameAttribute));

                if (nameAttributes.Length > 0)
                    compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name);

                var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p,
                    typeof (NbtIgnoreAttribute)).Any());

                foreach (var property in properties)
                {
                    if (!property.CanRead)
                        continue;

                    NbtTag tag = null;

                    string name = property.Name;
                    nameAttributes = Attribute.GetCustomAttributes(property, typeof (TagNameAttribute));
                    var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute));
                    if (nameAttributes.Length != 0)
                        name = ((TagNameAttribute)nameAttributes[0]).Name;

                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    var propValue = property.GetValue(value, null);

                    if (propValue == null)
                    {
                        if (ignoreOnNullAttribute != null) continue;
                        if (property.PropertyType.IsValueType)
                        {
                            propValue = Activator.CreateInstance(property.PropertyType);
                        }
                        else if (property.PropertyType == typeof (string))
                            propValue = "";
                    }

                    tag = innerSerializer.Serialize(propValue, name);
                    compound.Add(tag);
                }

                return compound;
            }
        }