merge IManifest interfaces into new project (#532)

This commit is contained in:
Jesse Plamondon-Willard 2018-06-24 21:51:51 -04:00
parent 316242eeb2
commit b08e27d13a
17 changed files with 68 additions and 254 deletions

View File

@ -7,9 +7,9 @@ using Newtonsoft.Json;
using NUnit.Framework;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.ModData;
using StardewModdingAPI.Framework.Models;
using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Models;
namespace StardewModdingAPI.Tests.Core
{
@ -472,17 +472,18 @@ namespace StardewModdingAPI.Tests.Core
/// <param name="dependencies">The <see cref="IManifest.Dependencies"/> value.</param>
private Manifest GetManifest(string id = null, string name = null, string version = null, string entryDll = null, string contentPackForID = null, string minimumApiVersion = null, IManifestDependency[] dependencies = null)
{
return new Manifest(
uniqueID: id ?? $"{Sample.String()}.{Sample.String()}",
name: name ?? id ?? Sample.String(),
author: Sample.String(),
description: Sample.String(),
version: version != null ? new SemanticVersion(version) : new SemanticVersion(Sample.Int(), Sample.Int(), Sample.Int(), Sample.String()),
entryDll: entryDll ?? $"{Sample.String()}.dll",
contentPackFor: contentPackForID != null ? new ManifestContentPackFor(contentPackForID) : null,
minimumApiVersion: minimumApiVersion != null ? new SemanticVersion(minimumApiVersion) : null,
dependencies: dependencies
);
return new Manifest
{
UniqueID = id ?? $"{Sample.String()}.{Sample.String()}",
Name = name ?? id ?? Sample.String(),
Author = Sample.String(),
Description = Sample.String(),
Version = version != null ? new SemanticVersion(version) : new SemanticVersion(Sample.Int(), Sample.Int(), Sample.Int(), Sample.String()),
EntryDll = entryDll ?? $"{Sample.String()}.dll",
ContentPackFor = contentPackForID != null ? new ManifestContentPackFor { UniqueID = contentPackForID } : null,
MinimumApiVersion = minimumApiVersion != null ? new SemanticVersion(minimumApiVersion) : null,
Dependencies = dependencies
};
}
/// <summary>Get a randomised basic manifest.</summary>

View File

@ -4,8 +4,8 @@ using System.IO;
using System.Linq;
using StardewModdingAPI.Events;
using StardewModdingAPI.Framework.Input;
using StardewModdingAPI.Framework.Models;
using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Models;
using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Framework.ModHelpers
@ -185,7 +185,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
author: author,
description: description,
version: version,
contentPackFor: new ManifestContentPackFor(this.ModID)
contentPackFor: this.ModID
);
// create content pack

View File

@ -4,10 +4,9 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using StardewModdingAPI.Framework.ModData;
using StardewModdingAPI.Framework.Models;
using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Models;
using StardewModdingAPI.Toolkit.Utilities;
using ToolkitManifest = StardewModdingAPI.Toolkit.Serialisation.Models.Manifest;
namespace StardewModdingAPI.Framework.ModLoading
{
@ -33,15 +32,13 @@ namespace StardewModdingAPI.Framework.ModLoading
string path = Path.Combine(modDir.FullName, "manifest.json");
try
{
ToolkitManifest rawManifest = jsonHelper.ReadJsonFile<ToolkitManifest>(path);
if (rawManifest == null)
manifest = jsonHelper.ReadJsonFile<Manifest>(path);
if (manifest == null)
{
error = File.Exists(path)
? "its manifest is invalid."
: "it doesn't have a manifest.";
}
else
manifest = new Manifest(rawManifest);
}
catch (SParseException ex)
{

View File

@ -1,97 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace StardewModdingAPI.Framework.Models
{
/// <summary>A manifest which describes a mod for SMAPI.</summary>
internal class Manifest : IManifest
{
/*********
** Accessors
*********/
/// <summary>The mod name.</summary>
public string Name { get; }
/// <summary>A brief description of the mod.</summary>
public string Description { get; }
/// <summary>The mod author's name.</summary>
public string Author { get; }
/// <summary>The mod version.</summary>
public ISemanticVersion Version { get; }
/// <summary>The minimum SMAPI version required by this mod, if any.</summary>
public ISemanticVersion MinimumApiVersion { get; }
/// <summary>The name of the DLL in the directory that has the <see cref="IMod.Entry"/> method. Mutually exclusive with <see cref="ContentPackFor"/>.</summary>
public string EntryDll { get; }
/// <summary>The mod which will read this as a content pack. Mutually exclusive with <see cref="IManifest.EntryDll"/>.</summary>
public IManifestContentPackFor ContentPackFor { get; }
/// <summary>The other mods that must be loaded before this mod.</summary>
public IManifestDependency[] Dependencies { get; }
/// <summary>The namespaced mod IDs to query for updates (like <c>Nexus:541</c>).</summary>
public string[] UpdateKeys { get; set; }
/// <summary>The unique mod ID.</summary>
public string UniqueID { get; }
/// <summary>Any manifest fields which didn't match a valid field.</summary>
[JsonExtensionData]
public IDictionary<string, object> ExtraFields { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="manifest">The toolkit manifest.</param>
public Manifest(Toolkit.Serialisation.Models.Manifest manifest)
: this(
uniqueID: manifest.UniqueID,
name: manifest.Name,
author: manifest.Author,
description: manifest.Description,
version: manifest.Version != null ? new SemanticVersion(manifest.Version) : null,
entryDll: manifest.EntryDll,
minimumApiVersion: manifest.MinimumApiVersion != null ? new SemanticVersion(manifest.MinimumApiVersion) : null,
contentPackFor: manifest.ContentPackFor != null ? new ManifestContentPackFor(manifest.ContentPackFor) : null,
dependencies: manifest.Dependencies?.Select(p => p != null ? (IManifestDependency)new ManifestDependency(p) : null).ToArray(),
updateKeys: manifest.UpdateKeys,
extraFields: manifest.ExtraFields
)
{ }
/// <summary>Construct an instance for a transitional content pack.</summary>
/// <param name="uniqueID">The unique mod ID.</param>
/// <param name="name">The mod name.</param>
/// <param name="author">The mod author's name.</param>
/// <param name="description">A brief description of the mod.</param>
/// <param name="version">The mod version.</param>
/// <param name="entryDll">The name of the DLL in the directory that has the <see cref="IMod.Entry"/> method. Mutually exclusive with <paramref name="contentPackFor"/>.</param>
/// <param name="minimumApiVersion">The minimum SMAPI version required by this mod, if any.</param>
/// <param name="contentPackFor">The modID which will read this as a content pack. Mutually exclusive with <paramref name="entryDll"/>.</param>
/// <param name="dependencies">The other mods that must be loaded before this mod.</param>
/// <param name="updateKeys">The namespaced mod IDs to query for updates (like <c>Nexus:541</c>).</param>
/// <param name="extraFields">Any manifest fields which didn't match a valid field.</param>
public Manifest(string uniqueID, string name, string author, string description, ISemanticVersion version, string entryDll = null, ISemanticVersion minimumApiVersion = null, IManifestContentPackFor contentPackFor = null, IManifestDependency[] dependencies = null, string[] updateKeys = null, IDictionary<string, object> extraFields = null)
{
this.Name = name;
this.Author = author;
this.Description = description;
this.Version = version;
this.UniqueID = uniqueID;
this.UpdateKeys = new string[0];
this.EntryDll = entryDll;
this.ContentPackFor = contentPackFor;
this.MinimumApiVersion = minimumApiVersion;
this.Dependencies = dependencies ?? new IManifestDependency[0];
this.UpdateKeys = updateKeys ?? new string[0];
this.ExtraFields = extraFields;
}
}
}

View File

@ -1,36 +0,0 @@
namespace StardewModdingAPI.Framework.Models
{
/// <summary>Indicates which mod can read the content pack represented by the containing manifest.</summary>
internal class ManifestContentPackFor : IManifestContentPackFor
{
/*********
** Accessors
*********/
/// <summary>The unique ID of the mod which can read this content pack.</summary>
public string UniqueID { get; }
/// <summary>The minimum required version (if any).</summary>
public ISemanticVersion MinimumVersion { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="contentPackFor">The toolkit instance.</param>
public ManifestContentPackFor(Toolkit.Serialisation.Models.ManifestContentPackFor contentPackFor)
{
this.UniqueID = contentPackFor.UniqueID;
this.MinimumVersion = contentPackFor.MinimumVersion != null ? new SemanticVersion(contentPackFor.MinimumVersion) : null;
}
/// <summary>Construct an instance.</summary>
/// <param name="uniqueID">The unique ID of the mod which can read this content pack.</param>
/// <param name="minimumVersion">The minimum required version (if any).</param>
public ManifestContentPackFor(string uniqueID, ISemanticVersion minimumVersion = null)
{
this.UniqueID = uniqueID;
this.MinimumVersion = minimumVersion;
}
}
}

View File

@ -1,40 +0,0 @@
namespace StardewModdingAPI.Framework.Models
{
/// <summary>A mod dependency listed in a mod manifest.</summary>
internal class ManifestDependency : IManifestDependency
{
/*********
** Accessors
*********/
/// <summary>The unique mod ID to require.</summary>
public string UniqueID { get; }
/// <summary>The minimum required version (if any).</summary>
public ISemanticVersion MinimumVersion { get; }
/// <summary>Whether the dependency must be installed to use the mod.</summary>
public bool IsRequired { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="dependency">The toolkit instance.</param>
public ManifestDependency(Toolkit.Serialisation.Models.ManifestDependency dependency)
: this(dependency.UniqueID, dependency.MinimumVersion?.ToString(), dependency.IsRequired) { }
/// <summary>Construct an instance.</summary>
/// <param name="uniqueID">The unique mod ID to require.</param>
/// <param name="minimumVersion">The minimum required version (if any).</param>
/// <param name="required">Whether the dependency must be installed to use the mod.</param>
public ManifestDependency(string uniqueID, string minimumVersion, bool required = true)
{
this.UniqueID = uniqueID;
this.MinimumVersion = !string.IsNullOrWhiteSpace(minimumVersion)
? new SemanticVersion(minimumVersion)
: null;
this.IsRequired = required;
}
}
}

View File

@ -1,40 +0,0 @@
using Newtonsoft.Json.Linq;
using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Converters;
namespace StardewModdingAPI.Framework.Serialisation
{
/// <summary>Handles deserialisation of <see cref="ISemanticVersion"/>.</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.ValueIgnoreCase<int>("MajorVersion");
int minor = obj.ValueIgnoreCase<int>("MinorVersion");
int patch = obj.ValueIgnoreCase<int>("PatchVersion");
string build = obj.ValueIgnoreCase<string>("Build");
if (build == "0")
build = null; // '0' from incorrect examples in old SMAPI documentation
return new SemanticVersion(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;
}
}
}

View File

@ -37,8 +37,11 @@ namespace StardewModdingAPI.Metadata
// rewrite for SMAPI 2.0
new VirtualEntryCallRemover(),
// rewrite for SMAPI 2.6
new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), type => type.Scope.Name == "StardewModdingAPI"), // moved to SMAPI.Toolkit.CoreInterfaces
// rewrite for SMAPI 2.6 (types moved into SMAPI.Toolkit.CoreInterfaces)
new TypeReferenceRewriter("StardewModdingAPI.IManifest", typeof(IManifest), type => type.Scope.Name == "StardewModdingAPI"),
new TypeReferenceRewriter("StardewModdingAPI.IManifestContentPackFor", typeof(IManifestContentPackFor), type => type.Scope.Name == "StardewModdingAPI"),
new TypeReferenceRewriter("StardewModdingAPI.IManifestDependency", typeof(IManifestDependency), type => type.Scope.Name == "StardewModdingAPI"),
new TypeReferenceRewriter("StardewModdingAPI.ISemanticVersion", typeof(ISemanticVersion), type => type.Scope.Name == "StardewModdingAPI"),
// rewrite for Stardew Valley 1.3
new StaticFieldToConstantRewriter<int>(typeof(Game1), "tileSize", Game1.tileSize),

View File

@ -201,8 +201,7 @@ namespace StardewModdingAPI
new StringEnumConverter<SButton>(),
new ColorConverter(),
new PointConverter(),
new RectangleConverter(),
new Framework.Serialisation.SemanticVersionConverter()
new RectangleConverter()
};
foreach (JsonConverter converter in converters)
this.JsonHelper.JsonSettings.Converters.Add(converter);

View File

@ -126,11 +126,7 @@
<Compile Include="Framework\Events\ModEvents.cs" />
<Compile Include="Framework\Events\ModInputEvents.cs" />
<Compile Include="Framework\Input\GamePadStateBuilder.cs" />
<Compile Include="Framework\Models\Manifest.cs" />
<Compile Include="Framework\Models\ManifestContentPackFor.cs" />
<Compile Include="Framework\Models\ManifestDependency.cs" />
<Compile Include="Framework\ModHelpers\InputHelper.cs" />
<Compile Include="Framework\Serialisation\SemanticVersionConverter.cs" />
<Compile Include="Framework\StateTracking\Comparers\GenericEqualsComparer.cs" />
<Compile Include="Framework\WatcherCore.cs" />
<Compile Include="IInputHelper.cs" />
@ -186,7 +182,6 @@
<Compile Include="Framework\StateTracking\PlayerTracker.cs" />
<Compile Include="Framework\Utilities\ContextHash.cs" />
<Compile Include="IContentPack.cs" />
<Compile Include="IManifestContentPackFor.cs" />
<Compile Include="IMultiplayerHelper.cs" />
<Compile Include="IReflectedField.cs" />
<Compile Include="IReflectedMethod.cs" />
@ -258,7 +253,6 @@
<Compile Include="IAssetDataForDictionary.cs" />
<Compile Include="IAssetDataForImage.cs" />
<Compile Include="IContentHelper.cs" />
<Compile Include="IManifestDependency.cs" />
<Compile Include="IModRegistry.cs" />
<Compile Include="Events\LocationEvents.cs" />
<Compile Include="Events\MenuEvents.cs" />
@ -275,7 +269,6 @@
<Compile Include="Framework\Reflection\ReflectedField.cs" />
<Compile Include="Framework\Reflection\ReflectedMethod.cs" />
<Compile Include="Framework\Reflection\Reflector.cs" />
<Compile Include="IManifest.cs" />
<Compile Include="IMod.cs" />
<Compile Include="IModHelper.cs" />
<Compile Include="IModLinked.cs" />

View File

@ -1,5 +1,4 @@
using Newtonsoft.Json.Linq;
using StardewModdingAPI.Toolkit.Serialisation.Models;
namespace StardewModdingAPI.Toolkit.Serialisation.Converters
{

View File

@ -5,7 +5,7 @@ using StardewModdingAPI.Toolkit.Serialisation.Converters;
namespace StardewModdingAPI.Toolkit.Serialisation.Models
{
/// <summary>A manifest which describes a mod for SMAPI.</summary>
public class Manifest
public class Manifest : IManifest
{
/*********
** Accessors
@ -20,21 +20,23 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models
public string Author { get; set; }
/// <summary>The mod version.</summary>
public SemanticVersion Version { get; set; }
[JsonConverter(typeof(SemanticVersionConverter))]
public ISemanticVersion Version { get; set; }
/// <summary>The minimum SMAPI version required by this mod, if any.</summary>
public SemanticVersion MinimumApiVersion { get; set; }
[JsonConverter(typeof(SemanticVersionConverter))]
public ISemanticVersion MinimumApiVersion { get; set; }
/// <summary>The name of the DLL in the directory that has the <c>Entry</c> method. Mutually exclusive with <see cref="ContentPackFor"/>.</summary>
public string EntryDll { get; set; }
/// <summary>The mod which will read this as a content pack. Mutually exclusive with <see cref="Manifest.EntryDll"/>.</summary>
[JsonConverter(typeof(ManifestContentPackForConverter))]
public ManifestContentPackFor ContentPackFor { get; set; }
public IManifestContentPackFor ContentPackFor { get; set; }
/// <summary>The other mods that must be loaded before this mod.</summary>
[JsonConverter(typeof(ManifestDependencyArrayConverter))]
public ManifestDependency[] Dependencies { get; set; }
public IManifestDependency[] Dependencies { get; set; }
/// <summary>The namespaced mod IDs to query for updates (like <c>Nexus:541</c>).</summary>
public string[] UpdateKeys { get; set; }
@ -45,5 +47,30 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models
/// <summary>Any manifest fields which didn't match a valid field.</summary>
[JsonExtensionData]
public IDictionary<string, object> ExtraFields { get; set; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
public Manifest() { }
/// <summary>Construct an instance for a transitional content pack.</summary>
/// <param name="uniqueID">The unique mod ID.</param>
/// <param name="name">The mod name.</param>
/// <param name="author">The mod author's name.</param>
/// <param name="description">A brief description of the mod.</param>
/// <param name="version">The mod version.</param>
/// <param name="contentPackFor">The modID which will read this as a content pack.</param>
public Manifest(string uniqueID, string name, string author, string description, ISemanticVersion version, string contentPackFor = null)
{
this.Name = name;
this.Author = author;
this.Description = description;
this.Version = version;
this.UniqueID = uniqueID;
this.UpdateKeys = new string[0];
this.ContentPackFor = new ManifestContentPackFor { UniqueID = contentPackFor };
}
}
}

View File

@ -1,7 +1,10 @@
using Newtonsoft.Json;
using StardewModdingAPI.Toolkit.Serialisation.Converters;
namespace StardewModdingAPI.Toolkit.Serialisation.Models
{
/// <summary>Indicates which mod can read the content pack represented by the containing manifest.</summary>
public class ManifestContentPackFor
public class ManifestContentPackFor : IManifestContentPackFor
{
/*********
** Accessors
@ -10,6 +13,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models
public string UniqueID { get; set; }
/// <summary>The minimum required version (if any).</summary>
public SemanticVersion MinimumVersion { get; set; }
[JsonConverter(typeof(SemanticVersionConverter))]
public ISemanticVersion MinimumVersion { get; set; }
}
}

View File

@ -1,7 +1,10 @@
using Newtonsoft.Json;
using StardewModdingAPI.Toolkit.Serialisation.Converters;
namespace StardewModdingAPI.Toolkit.Serialisation.Models
{
/// <summary>A mod dependency listed in a mod manifest.</summary>
public class ManifestDependency
public class ManifestDependency : IManifestDependency
{
/*********
** Accessors
@ -10,7 +13,8 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Models
public string UniqueID { get; set; }
/// <summary>The minimum required version (if any).</summary>
public SemanticVersion MinimumVersion { get; set; }
[JsonConverter(typeof(SemanticVersionConverter))]
public ISemanticVersion MinimumVersion { get; set; }
/// <summary>Whether the dependency must be installed to use the mod.</summary>
public bool IsRequired { get; set; }