public static object Serialize(object value) { var type = value.GetType(); TagSerializer serializer; if (TagSerializer.TryGetSerializer(type, out serializer)) { return(serializer.Serialize(value)); } //does a base level typecheck with throw if (GetPayloadId(type) != 9) { return(value); } var elemType = type.GetGenericArguments()[0]; if (TagSerializer.TryGetSerializer(elemType, out serializer)) { return(serializer.SerializeList((IList)value)); } if (GetPayloadId(elemType) != 9) { return(value); //already a valid NBT list type } //list of lists conversion var list = value as IList <IList> ?? ((IList)value).Cast <IList>().ToList(); for (int i = 0; i < list.Count; i++) { list[i] = (IList)Serialize(list[i]); } return(list); }
public static object Deserialize(Type type, object tag) { if (type.IsInstanceOfType(tag)) { return(tag); } TagSerializer serializer; if (TagSerializer.TryGetSerializer(type, out serializer)) { if (tag == null) { tag = Deserialize(serializer.TagType, null); } return(serializer.Deserialize(tag)); } //normal nbt type with missing value if (tag == null) { if (type.GetGenericArguments().Length == 0) { return(GetHandler(GetPayloadId(type)).Default()); } if (type.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(null); } } //list conversion required if ((tag == null || tag is IList) && type.GetGenericArguments().Length == 1) { var elemType = type.GetGenericArguments()[0]; var newListType = typeof(List <>).MakeGenericType(elemType); if (type.IsAssignableFrom(newListType)) //if the desired type is a superclass of List<elemType> { if (tag == null) { return(newListType.GetConstructor(new Type[0]).Invoke(new object[0])); } if (TagSerializer.TryGetSerializer(elemType, out serializer)) { return(serializer.DeserializeList((IList)tag)); } //create a strongly typed nested list var oldList = (IList)tag; var newList = (IList)newListType.GetConstructor(new[] { typeof(int) }).Invoke(new object[] { oldList.Count }); foreach (var elem in oldList) { newList.Add(Deserialize(elemType, elem)); } return(newList); } } if (tag == null) //unable to create an empty list subclassing the desired type { throw new IOException($"Invalid NBT payload type '{type}'"); } throw new InvalidCastException($"Unable to cast object of type '{tag.GetType()}' to type '{type}'"); }