diff options
Diffstat (limited to 'src')
13 files changed, 197 insertions, 140 deletions
diff --git a/src/SMAPI/Framework/Models/Manifest.cs b/src/SMAPI/Framework/Models/Manifest.cs index c362be9b..f9762406 100644 --- a/src/SMAPI/Framework/Models/Manifest.cs +++ b/src/SMAPI/Framework/Models/Manifest.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Models { @@ -21,18 +20,18 @@ namespace StardewModdingAPI.Framework.Models public string Author { get; set; } /// <summary>The mod version.</summary> - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion Version { get; set; } /// <summary>The minimum SMAPI version required by this mod, if any.</summary> - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(SemanticVersionConverter))] public ISemanticVersion MinimumApiVersion { get; set; } /// <summary>The name of the DLL in the directory that has the <see cref="IMod.Entry"/> method.</summary> public string EntryDll { get; set; } /// <summary>The other mods that must be loaded before this mod.</summary> - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ManifestDependencyArrayConverter))] public IManifestDependency[] Dependencies { get; set; } /// <summary>The namespaced mod IDs to query for updates (like <c>Nexus:541</c>).</summary> diff --git a/src/SMAPI/Framework/Models/ModDataRecord.cs b/src/SMAPI/Framework/Models/ModDataRecord.cs index fa6fc68d..580acb70 100644 --- a/src/SMAPI/Framework/Models/ModDataRecord.cs +++ b/src/SMAPI/Framework/Models/ModDataRecord.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Models { @@ -13,7 +12,7 @@ namespace StardewModdingAPI.Framework.Models ** Accessors *********/ /// <summary>The unique mod identifier.</summary> - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ModDataIdConverter))] public ModDataID ID { get; set; } /// <summary>A value to inject into <see cref="IManifest.UpdateKeys"/> field if it's not already set.</summary> @@ -23,7 +22,7 @@ namespace StardewModdingAPI.Framework.Models public string AlternativeUrl { get; set; } /// <summary>The compatibility of given mod versions (if any).</summary> - [JsonConverter(typeof(SFieldConverter))] + [JsonConverter(typeof(ModCompatibilityArrayConverter))] public ModCompatibility[] Compatibility { get; set; } = new ModCompatibility[0]; /// <summary>Map local versions to a semantic version for update checks.</summary> diff --git a/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs b/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs deleted file mode 100644 index 69353491..00000000 --- a/src/SMAPI/Framework/Serialisation/Converters/SFieldConverter.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using StardewModdingAPI.Framework.Exceptions; -using StardewModdingAPI.Framework.Models; - -namespace StardewModdingAPI.Framework.Serialisation.Converters -{ - /// <summary>Overrides how SMAPI reads and writes <see cref="ISemanticVersion"/> and <see cref="IManifestDependency"/> fields.</summary> - internal class SFieldConverter : JsonConverter - { - /********* - ** Accessors - *********/ - /// <summary>Whether this converter can write JSON.</summary> - public override bool CanWrite => false; - - - /********* - ** Public methods - *********/ - /// <summary>Get whether this instance can convert the specified object type.</summary> - /// <param name="objectType">The object type.</param> - public override bool CanConvert(Type objectType) - { - return - objectType == typeof(ISemanticVersion) - || objectType == typeof(IManifestDependency[]) - || objectType == typeof(ModDataID) - || objectType == typeof(ModCompatibility[]); - } - - /// <summary>Reads the JSON representation of the object.</summary> - /// <param name="reader">The JSON reader.</param> - /// <param name="objectType">The object type.</param> - /// <param name="existingValue">The object being read.</param> - /// <param name="serializer">The calling serializer.</param> - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - // semantic version - if (objectType == typeof(ISemanticVersion)) - { - JToken token = JToken.Load(reader); - switch (token.Type) - { - case JTokenType.Object: - { - JObject obj = (JObject)token; - int major = obj.Value<int>(nameof(ISemanticVersion.MajorVersion)); - int minor = obj.Value<int>(nameof(ISemanticVersion.MinorVersion)); - int patch = obj.Value<int>(nameof(ISemanticVersion.PatchVersion)); - string build = obj.Value<string>(nameof(ISemanticVersion.Build)); - return new LegacyManifestVersion(major, minor, patch, build); - } - - case JTokenType.String: - { - string str = token.Value<string>(); - if (string.IsNullOrWhiteSpace(str)) - return null; - if (!SemanticVersion.TryParse(str, out ISemanticVersion version)) - throw new SParseException($"Can't parse semantic version from invalid value '{str}', should be formatted like 1.2, 1.2.30, or 1.2.30-beta."); - return version; - } - - default: - throw new SParseException($"Can't parse semantic version from {token.Type}, must be an object or string."); - } - } - - // manifest dependencies - if (objectType == typeof(IManifestDependency[])) - { - List<IManifestDependency> result = new List<IManifestDependency>(); - foreach (JObject obj in JArray.Load(reader).Children<JObject>()) - { - string uniqueID = obj.Value<string>(nameof(IManifestDependency.UniqueID)); - string minVersion = obj.Value<string>(nameof(IManifestDependency.MinimumVersion)); - bool required = obj.Value<bool?>(nameof(IManifestDependency.IsRequired)) ?? true; - result.Add(new ManifestDependency(uniqueID, minVersion, required)); - } - return result.ToArray(); - } - - // mod data ID - if (objectType == typeof(ModDataID)) - { - JToken token = JToken.Load(reader); - return new ModDataID(token.Value<string>()); - } - - // mod compatibility records - if (objectType == typeof(ModCompatibility[])) - { - List<ModCompatibility> result = new List<ModCompatibility>(); - foreach (JProperty property in JObject.Load(reader).Properties()) - { - string range = property.Name; - ModStatus status = (ModStatus)Enum.Parse(typeof(ModStatus), property.Value.Value<string>(nameof(ModCompatibility.Status))); - string reasonPhrase = property.Value.Value<string>(nameof(ModCompatibility.ReasonPhrase)); - - result.Add(new ModCompatibility(range, status, reasonPhrase)); - } - return result.ToArray(); - } - - // unknown - throw new NotSupportedException($"Unknown type '{objectType?.FullName}'."); - } - - /// <summary>Writes the JSON representation of the object.</summary> - /// <param name="writer">The JSON writer.</param> - /// <param name="value">The value.</param> - /// <param name="serializer">The calling serializer.</param> - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new InvalidOperationException("This converter does not write JSON."); - } - } -} diff --git a/src/SMAPI/Framework/Serialisation/Converters/ColorConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/ColorConverter.cs index 7f830a0e..f4a2a26e 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/ColorConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/ColorConverter.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// <summary>Handles deserialisation of <see cref="Color"/> for crossplatform compatibility.</summary> /// <remarks> diff --git a/src/SMAPI/Framework/Serialisation/Converters/PointConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/PointConverter.cs index 87d0ff34..84c70989 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/PointConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/PointConverter.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// <summary>Handles deserialisation of <see cref="PointConverter"/> for crossplatform compatibility.</summary> /// <remarks> diff --git a/src/SMAPI/Framework/Serialisation/Converters/RectangleConverter.cs b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/RectangleConverter.cs index 7cf912a7..b89551e3 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/RectangleConverter.cs +++ b/src/SMAPI/Framework/Serialisation/CrossplatformConverters/RectangleConverter.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework; using Newtonsoft.Json.Linq; using StardewModdingAPI.Framework.Exceptions; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.CrossplatformConverters { /// <summary>Handles deserialisation of <see cref="Rectangle"/> for crossplatform compatibility.</summary> /// <remarks> diff --git a/src/SMAPI/Framework/Serialisation/JsonHelper.cs b/src/SMAPI/Framework/Serialisation/JsonHelper.cs index 1253f242..2e2a666e 100644 --- a/src/SMAPI/Framework/Serialisation/JsonHelper.cs +++ b/src/SMAPI/Framework/Serialisation/JsonHelper.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework.Input; using Newtonsoft.Json; -using StardewModdingAPI.Framework.Serialisation.Converters; +using StardewModdingAPI.Framework.Serialisation.CrossplatformConverters; +using StardewModdingAPI.Framework.Serialisation.SmapiConverters; namespace StardewModdingAPI.Framework.Serialisation { diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs new file mode 100644 index 00000000..6352e367 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ManifestDependencyArrayConverter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// <summary>Handles deserialisation of <see cref="IManifestDependency"/> arrays.</summary> + internal class ManifestDependencyArrayConverter : JsonConverter + { + /********* + ** Accessors + *********/ + /// <summary>Whether this converter can write JSON.</summary> + public override bool CanWrite => false; + + + /********* + ** Public methods + *********/ + /// <summary>Get whether this instance can convert the specified object type.</summary> + /// <param name="objectType">The object type.</param> + public override bool CanConvert(Type objectType) + { + return objectType == typeof(IManifestDependency[]); + } + + + /********* + ** Protected methods + *********/ + /// <summary>Read the JSON representation of the object.</summary> + /// <param name="reader">The JSON reader.</param> + /// <param name="objectType">The object type.</param> + /// <param name="existingValue">The object being read.</param> + /// <param name="serializer">The calling serializer.</param> + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List<IManifestDependency> result = new List<IManifestDependency>(); + foreach (JObject obj in JArray.Load(reader).Children<JObject>()) + { + string uniqueID = obj.Value<string>(nameof(IManifestDependency.UniqueID)); + string minVersion = obj.Value<string>(nameof(IManifestDependency.MinimumVersion)); + bool required = obj.Value<bool?>(nameof(IManifestDependency.IsRequired)) ?? true; + result.Add(new ManifestDependency(uniqueID, minVersion, required)); + } + return result.ToArray(); + } + + /// <summary>Writes the JSON representation of the object.</summary> + /// <param name="writer">The JSON writer.</param> + /// <param name="value">The value.</param> + /// <param name="serializer">The calling serializer.</param> + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new InvalidOperationException("This converter does not write JSON."); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs new file mode 100644 index 00000000..3232dde4 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModCompatibilityArrayConverter.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// <summary>Handles deserialisation of <see cref="ModCompatibility"/> arrays.</summary> + internal class ModCompatibilityArrayConverter : JsonConverter + { + /********* + ** Accessors + *********/ + /// <summary>Whether this converter can write JSON.</summary> + public override bool CanWrite => false; + + + /********* + ** Public methods + *********/ + /// <summary>Get whether this instance can convert the specified object type.</summary> + /// <param name="objectType">The object type.</param> + public override bool CanConvert(Type objectType) + { + return objectType == typeof(ModCompatibility[]); + } + + + /********* + ** Protected methods + *********/ + /// <summary>Read the JSON representation of the object.</summary> + /// <param name="reader">The JSON reader.</param> + /// <param name="objectType">The object type.</param> + /// <param name="existingValue">The object being read.</param> + /// <param name="serializer">The calling serializer.</param> + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List<ModCompatibility> result = new List<ModCompatibility>(); + foreach (JProperty property in JObject.Load(reader).Properties()) + { + string range = property.Name; + ModStatus status = (ModStatus)Enum.Parse(typeof(ModStatus), property.Value.Value<string>(nameof(ModCompatibility.Status))); + string reasonPhrase = property.Value.Value<string>(nameof(ModCompatibility.ReasonPhrase)); + + result.Add(new ModCompatibility(range, status, reasonPhrase)); + } + return result.ToArray(); + } + + /// <summary>Writes the JSON representation of the object.</summary> + /// <param name="writer">The JSON writer.</param> + /// <param name="value">The value.</param> + /// <param name="serializer">The calling serializer.</param> + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new InvalidOperationException("This converter does not write JSON."); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs new file mode 100644 index 00000000..8a10db47 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/ModDataIdConverter.cs @@ -0,0 +1,19 @@ +using StardewModdingAPI.Framework.Models; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// <summary>Handles deserialisation of <see cref="ModDataID"/>.</summary> + internal class ModDataIdConverter : SimpleReadOnlyConverter<ModDataID> + { + /********* + ** Protected methods + *********/ + /// <summary>Read a JSON string.</summary> + /// <param name="str">The JSON string value.</param> + /// <param name="path">The path to the current JSON node.</param> + protected override ModDataID ReadString(string str, string path) + { + return new ModDataID(str); + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs new file mode 100644 index 00000000..50181809 --- /dev/null +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/SemanticVersionConverter.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json.Linq; +using StardewModdingAPI.Framework.Exceptions; + +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters +{ + /// <summary>Handles deserialisation of <see cref="SemanticVersion"/>.</summary> + internal class SemanticVersionConverter : SimpleReadOnlyConverter<ISemanticVersion> + { + /********* + ** Protected methods + *********/ + /// <summary>Read a JSON object.</summary> + /// <param name="obj">The JSON object to read.</param> + /// <param name="path">The path to the current JSON node.</param> + protected override ISemanticVersion ReadObject(JObject obj, string path) + { + int major = obj.Value<int>(nameof(ISemanticVersion.MajorVersion)); + int minor = obj.Value<int>(nameof(ISemanticVersion.MinorVersion)); + int patch = obj.Value<int>(nameof(ISemanticVersion.PatchVersion)); + string build = obj.Value<string>(nameof(ISemanticVersion.Build)); + return new LegacyManifestVersion(major, minor, patch, build); + } + + /// <summary>Read a JSON string.</summary> + /// <param name="str">The JSON string value.</param> + /// <param name="path">The path to the current JSON node.</param> + protected override ISemanticVersion ReadString(string str, string path) + { + if (string.IsNullOrWhiteSpace(str)) + return null; + if (!SemanticVersion.TryParse(str, out ISemanticVersion version)) + throw new SParseException($"Can't parse semantic version from invalid value '{str}', should be formatted like 1.2, 1.2.30, or 1.2.30-beta (path: {path})."); + return version; + } + } +} diff --git a/src/SMAPI/Framework/Serialisation/Converters/StringEnumConverter.cs b/src/SMAPI/Framework/Serialisation/SmapiConverters/StringEnumConverter.cs index 0a612c74..c88ac834 100644 --- a/src/SMAPI/Framework/Serialisation/Converters/StringEnumConverter.cs +++ b/src/SMAPI/Framework/Serialisation/SmapiConverters/StringEnumConverter.cs @@ -1,7 +1,7 @@ using System; using Newtonsoft.Json.Converters; -namespace StardewModdingAPI.Framework.Serialisation.Converters +namespace StardewModdingAPI.Framework.Serialisation.SmapiConverters { /// <summary>A variant of <see cref="StringEnumConverter"/> which only converts a specified enum.</summary> /// <typeparam name="T">The enum type.</typeparam> diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index f5060e2d..ca05399d 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -110,10 +110,14 @@ <Compile Include="Framework\Exceptions\SAssemblyLoadFailedException.cs" /> <Compile Include="Framework\ModLoading\AssemblyLoadStatus.cs" /> <Compile Include="Framework\Reflection\InterfaceProxyBuilder.cs" /> + <Compile Include="Framework\Serialisation\SmapiConverters\ModCompatibilityArrayConverter.cs" /> + <Compile Include="Framework\Serialisation\SmapiConverters\ManifestDependencyArrayConverter.cs" /> + <Compile Include="Framework\Serialisation\SmapiConverters\ModDataIdConverter.cs" /> + <Compile Include="Framework\Serialisation\SmapiConverters\SemanticVersionConverter.cs" /> <Compile Include="Framework\Serialisation\SimpleReadOnlyConverter.cs" /> - <Compile Include="Framework\Serialisation\Converters\RectangleConverter.cs" /> - <Compile Include="Framework\Serialisation\Converters\ColorConverter.cs" /> - <Compile Include="Framework\Serialisation\Converters\PointConverter.cs" /> + <Compile Include="Framework\Serialisation\CrossplatformConverters\RectangleConverter.cs" /> + <Compile Include="Framework\Serialisation\CrossplatformConverters\ColorConverter.cs" /> + <Compile Include="Framework\Serialisation\CrossplatformConverters\PointConverter.cs" /> <Compile Include="Framework\Utilities\ContextHash.cs" /> <Compile Include="IReflectedField.cs" /> <Compile Include="IReflectedMethod.cs" /> @@ -181,8 +185,7 @@ <Compile Include="Framework\SContentManager.cs" /> <Compile Include="Framework\Exceptions\SParseException.cs" /> <Compile Include="Framework\Serialisation\JsonHelper.cs" /> - <Compile Include="Framework\Serialisation\Converters\StringEnumConverter.cs" /> - <Compile Include="Framework\Serialisation\Converters\SFieldConverter.cs" /> + <Compile Include="Framework\Serialisation\SmapiConverters\StringEnumConverter.cs" /> <Compile Include="IAssetEditor.cs" /> <Compile Include="IAssetInfo.cs" /> <Compile Include="IAssetLoader.cs" /> |