using System; using Microsoft.Xna.Framework; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; namespace StardewModdingAPI.Framework.Serialisation { /// Handles deserialisation of for crossplatform compatibility. internal class PointConverter : JsonConverter { /********* ** Accessors *********/ /// Whether this converter can write JSON. public override bool CanWrite => false; /********* ** Public methods *********/ /// Get whether this instance can convert the specified object type. /// The object type. public override bool CanConvert(Type objectType) { return objectType == typeof(Point); } /// Reads the JSON representation of the object. /// The JSON reader. /// The object type. /// The object being read. /// The calling serializer. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // point // Linux/Mac: { "X": 1, "Y": 2 } // Windows: "1, 2" JToken token = JToken.Load(reader); switch (token.Type) { case JTokenType.Object: { JObject obj = (JObject)token; int x = obj.Value(nameof(Point.X)); int y = obj.Value(nameof(Point.Y)); return new Point(x, y); } case JTokenType.String: { string str = token.Value(); if (string.IsNullOrWhiteSpace(str)) return null; string[] parts = str.Split(','); if (parts.Length != 2) throw new SParseException($"Can't parse {typeof(Point).Name} from {token.Path}, invalid value '{str}'."); int x = Convert.ToInt32(parts[0]); int y = Convert.ToInt32(parts[1]); return new Point(x, y); } default: throw new SParseException($"Can't parse {typeof(Point).Name} from {token.Path}, must be an object or string."); } } /// Writes the JSON representation of the object. /// The JSON writer. /// The value. /// The calling serializer. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new InvalidOperationException("This converter does not write JSON."); } } }