diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Tests/Core/ModResolverTests.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/IModMetadata.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModMetadata.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModResolver.cs | 4 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/MetadataModel.cs (renamed from src/StardewModdingAPI.Toolkit/Framework/ModData/SMetadata.cs) | 4 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataModel.cs | 129 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs | 152 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecordVersionedFields.cs (renamed from src/StardewModdingAPI.Toolkit/Framework/ModData/ParsedModDataRecord.cs) | 4 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs | 103 | ||||
-rw-r--r-- | src/StardewModdingAPI.Toolkit/ModToolkit.cs | 6 |
10 files changed, 220 insertions, 192 deletions
diff --git a/src/SMAPI.Tests/Core/ModResolverTests.cs b/src/SMAPI.Tests/Core/ModResolverTests.cs index e63057b3..9e91b993 100644 --- a/src/SMAPI.Tests/Core/ModResolverTests.cs +++ b/src/SMAPI.Tests/Core/ModResolverTests.cs @@ -142,7 +142,7 @@ namespace StardewModdingAPI.Tests.Core { // arrange Mock<IModMetadata> mock = this.GetMetadata("Mod A", new string[0], allowStatusChange: true); - this.SetupMetadataForValidation(mock, new ParsedModDataRecord + this.SetupMetadataForValidation(mock, new ModDataRecordVersionedFields { Status = ModStatus.AssumeBroken, AlternativeUrl = "http://example.org" @@ -526,7 +526,7 @@ namespace StardewModdingAPI.Tests.Core /// <summary>Set up a mock mod metadata for <see cref="ModResolver.ValidateManifests"/>.</summary> /// <param name="mod">The mock mod metadata.</param> /// <param name="modRecord">The extra metadata about the mod from SMAPI's internal data (if any).</param> - private void SetupMetadataForValidation(Mock<IModMetadata> mod, ParsedModDataRecord modRecord = null) + private void SetupMetadataForValidation(Mock<IModMetadata> mod, ModDataRecordVersionedFields modRecord = null) { mod.Setup(p => p.Status).Returns(ModMetadataStatus.Found); mod.Setup(p => p.DataRecord).Returns(() => null); diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs index 5a8689de..2145105b 100644 --- a/src/SMAPI/Framework/IModMetadata.cs +++ b/src/SMAPI/Framework/IModMetadata.cs @@ -20,7 +20,7 @@ namespace StardewModdingAPI.Framework IManifest Manifest { get; } /// <summary>Metadata about the mod from SMAPI's internal data (if any).</summary> - ParsedModDataRecord DataRecord { get; } + ModDataRecordVersionedFields DataRecord { get; } /// <summary>The metadata resolution status.</summary> ModMetadataStatus Status { get; } diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 4db25932..585debb4 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -21,7 +21,7 @@ namespace StardewModdingAPI.Framework.ModLoading public IManifest Manifest { get; } /// <summary>Metadata about the mod from SMAPI's internal data (if any).</summary> - public ParsedModDataRecord DataRecord { get; } + public ModDataRecordVersionedFields DataRecord { get; } /// <summary>The metadata resolution status.</summary> public ModMetadataStatus Status { get; private set; } @@ -59,7 +59,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// <param name="directoryPath">The mod's full directory path.</param> /// <param name="manifest">The mod manifest.</param> /// <param name="dataRecord">Metadata about the mod from SMAPI's internal data (if any).</param> - public ModMetadata(string displayName, string directoryPath, IManifest manifest, ParsedModDataRecord dataRecord) + public ModMetadata(string displayName, string directoryPath, IManifest manifest, ModDataRecordVersionedFields dataRecord) { this.DisplayName = displayName; this.DirectoryPath = directoryPath; diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index c1bc51ec..174820a1 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -51,7 +51,7 @@ namespace StardewModdingAPI.Framework.ModLoading } // parse internal data record (if any) - ParsedModDataRecord dataRecord = modDatabase.GetParsed(manifest); + ModDataRecordVersionedFields dataRecord = modDatabase.Get(manifest?.UniqueID)?.GetVersionedFields(manifest); // get display name string displayName = manifest?.Name; @@ -301,7 +301,7 @@ namespace StardewModdingAPI.Framework.ModLoading string[] failedModNames = ( from entry in dependencies where entry.IsRequired && entry.Mod == null - let displayName = modDatabase.GetDisplayNameFor(entry.ID) ?? entry.ID + let displayName = modDatabase.Get(entry.ID)?.DisplayName ?? entry.ID let modUrl = modDatabase.GetModPageUrlFor(entry.ID) orderby displayName select modUrl != null diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/SMetadata.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/MetadataModel.cs index 9553cca9..ef6d4dd9 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModData/SMetadata.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/MetadataModel.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; namespace StardewModdingAPI.Toolkit.Framework.ModData { /// <summary>The SMAPI predefined metadata.</summary> - internal class SMetadata + internal class MetadataModel { /******** ** Accessors ********/ /// <summary>Extra metadata about mods.</summary> - public IDictionary<string, ModDataRecord> ModData { get; set; } + public IDictionary<string, ModDataModel> ModData { get; set; } } } diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataModel.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataModel.cs new file mode 100644 index 00000000..e2b3ec1d --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataModel.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace StardewModdingAPI.Toolkit.Framework.ModData +{ + /// <summary>The raw mod metadata from SMAPI's internal mod list.</summary> + internal class ModDataModel + { + /********* + ** Accessors + *********/ + /// <summary>The mod's current unique ID.</summary> + public string ID { get; set; } + + /// <summary>The former mod IDs (if any).</summary> + /// <remarks> + /// This uses a custom format which uniquely identifies a mod across multiple versions and + /// supports matching other fields if no ID was specified. This doesn't include the latest + /// ID, if any. Format rules: + /// 1. If the mod's ID changed over time, multiple variants can be separated by the + /// <c>|</c> character. + /// 2. Each variant can take one of two forms: + /// - A simple string matching the mod's UniqueID value. + /// - A JSON structure containing any of four manifest fields (ID, Name, Author, and + /// EntryDll) to match. + /// </remarks> + public string FormerIDs { get; set; } + + /// <summary>Maps local versions to a semantic version for update checks.</summary> + public IDictionary<string, string> MapLocalVersions { get; set; } = new Dictionary<string, string>(); + + /// <summary>Maps remote versions to a semantic version for update checks.</summary> + public IDictionary<string, string> MapRemoteVersions { get; set; } = new Dictionary<string, string>(); + + /// <summary>This field stores properties that aren't mapped to another field before they're parsed into <see cref="Fields"/>.</summary> + [JsonExtensionData] + public IDictionary<string, JToken> ExtensionData { get; set; } + + /// <summary>The versioned field data.</summary> + /// <remarks> + /// This maps field names to values. This should be accessed via <see cref="GetFields"/>. + /// Format notes: + /// - Each key consists of a field name prefixed with any combination of version range + /// and <c>Default</c>, separated by pipes (whitespace trimmed). For example, <c>Name</c> + /// will always override the name, <c>Default | Name</c> will only override a blank + /// name, and <c>~1.1 | Default | Name</c> will override blank names up to version 1.1. + /// - The version format is <c>min~max</c> (where either side can be blank for unbounded), or + /// a single version number. + /// - The field name itself corresponds to a <see cref="ModDataFieldKey"/> value. + /// </remarks> + public IDictionary<string, string> Fields { get; set; } = new Dictionary<string, string>(); + + + /********* + ** Public methods + *********/ + /// <summary>Get a parsed representation of the <see cref="Fields"/>.</summary> + public IEnumerable<ModDataField> GetFields() + { + foreach (KeyValuePair<string, string> pair in this.Fields) + { + // init fields + string packedKey = pair.Key; + string value = pair.Value; + bool isDefault = false; + ISemanticVersion lowerVersion = null; + ISemanticVersion upperVersion = null; + + // parse + string[] parts = packedKey.Split('|').Select(p => p.Trim()).ToArray(); + ModDataFieldKey fieldKey = (ModDataFieldKey)Enum.Parse(typeof(ModDataFieldKey), parts.Last(), ignoreCase: true); + foreach (string part in parts.Take(parts.Length - 1)) + { + // 'default' + if (part.Equals("Default", StringComparison.InvariantCultureIgnoreCase)) + { + isDefault = true; + continue; + } + + // version range + if (part.Contains("~")) + { + string[] versionParts = part.Split(new[] { '~' }, 2); + lowerVersion = versionParts[0] != "" ? new SemanticVersion(versionParts[0]) : null; + upperVersion = versionParts[1] != "" ? new SemanticVersion(versionParts[1]) : null; + continue; + } + + // single version + lowerVersion = new SemanticVersion(part); + upperVersion = new SemanticVersion(part); + } + + yield return new ModDataField(fieldKey, value, isDefault, lowerVersion, upperVersion); + } + } + + /// <summary>Get the former mod IDs.</summary> + public IEnumerable<string> GetFormerIDs() + { + if (this.FormerIDs != null) + { + foreach (string id in this.FormerIDs.Split('|')) + yield return id.Trim(); + } + } + + + /********* + ** Private methods + *********/ + /// <summary>The method invoked after JSON deserialisation.</summary> + /// <param name="context">The deserialisation context.</param> + [OnDeserialized] + private void OnDeserialized(StreamingContext context) + { + if (this.ExtensionData != null) + { + this.Fields = this.ExtensionData.ToDictionary(p => p.Key, p => p.Value.ToString()); + this.ExtensionData = null; + } + } + } +} diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs index 97ad0ca4..21c9cfca 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs @@ -1,107 +1,66 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace StardewModdingAPI.Toolkit.Framework.ModData { - /// <summary>Raw mod metadata from SMAPI's internal mod list.</summary> + /// <summary>The parsed mod metadata from SMAPI's internal mod list.</summary> public class ModDataRecord { /********* - ** Properties - *********/ - /// <summary>This field stores properties that aren't mapped to another field before they're parsed into <see cref="Fields"/>.</summary> - [JsonExtensionData] - private IDictionary<string, JToken> ExtensionData; - - - /********* ** Accessors *********/ + /// <summary>The mod's default display name.</summary> + public string DisplayName { get; } + /// <summary>The mod's current unique ID.</summary> - public string ID { get; set; } + public string ID { get; } /// <summary>The former mod IDs (if any).</summary> - /// <remarks> - /// This uses a custom format which uniquely identifies a mod across multiple versions and - /// supports matching other fields if no ID was specified. This doesn't include the latest - /// ID, if any. Format rules: - /// 1. If the mod's ID changed over time, multiple variants can be separated by the - /// <c>|</c> character. - /// 2. Each variant can take one of two forms: - /// - A simple string matching the mod's UniqueID value. - /// - A JSON structure containing any of four manifest fields (ID, Name, Author, and - /// EntryDll) to match. - /// </remarks> - public string FormerIDs { get; set; } + public string[] FormerIDs { get; } /// <summary>Maps local versions to a semantic version for update checks.</summary> - public IDictionary<string, string> MapLocalVersions { get; set; } = new Dictionary<string, string>(); + public IDictionary<string, string> MapLocalVersions { get; } /// <summary>Maps remote versions to a semantic version for update checks.</summary> - public IDictionary<string, string> MapRemoteVersions { get; set; } = new Dictionary<string, string>(); + public IDictionary<string, string> MapRemoteVersions { get; } /// <summary>The versioned field data.</summary> - /// <remarks> - /// This maps field names to values. This should be accessed via <see cref="GetFields"/>. - /// Format notes: - /// - Each key consists of a field name prefixed with any combination of version range - /// and <c>Default</c>, separated by pipes (whitespace trimmed). For example, <c>Name</c> - /// will always override the name, <c>Default | Name</c> will only override a blank - /// name, and <c>~1.1 | Default | Name</c> will override blank names up to version 1.1. - /// - The version format is <c>min~max</c> (where either side can be blank for unbounded), or - /// a single version number. - /// - The field name itself corresponds to a <see cref="ModDataFieldKey"/> value. - /// </remarks> - public IDictionary<string, string> Fields { get; set; } = new Dictionary<string, string>(); + public ModDataField[] Fields { get; } /********* ** Public methods *********/ - /// <summary>Get a parsed representation of the <see cref="Fields"/>.</summary> - public IEnumerable<ModDataField> GetFields() + /// <summary>Construct an instance.</summary> + /// <param name="displayName">The mod's default display name.</param> + /// <param name="model">The raw data model.</param> + internal ModDataRecord(string displayName, ModDataModel model) { - foreach (KeyValuePair<string, string> pair in this.Fields) - { - // init fields - string packedKey = pair.Key; - string value = pair.Value; - bool isDefault = false; - ISemanticVersion lowerVersion = null; - ISemanticVersion upperVersion = null; - - // parse - string[] parts = packedKey.Split('|').Select(p => p.Trim()).ToArray(); - ModDataFieldKey fieldKey = (ModDataFieldKey)Enum.Parse(typeof(ModDataFieldKey), parts.Last(), ignoreCase: true); - foreach (string part in parts.Take(parts.Length - 1)) - { - // 'default' - if (part.Equals("Default", StringComparison.InvariantCultureIgnoreCase)) - { - isDefault = true; - continue; - } - - // version range - if (part.Contains("~")) - { - string[] versionParts = part.Split(new[] { '~' }, 2); - lowerVersion = versionParts[0] != "" ? new SemanticVersion(versionParts[0]) : null; - upperVersion = versionParts[1] != "" ? new SemanticVersion(versionParts[1]) : null; - continue; - } - - // single version - lowerVersion = new SemanticVersion(part); - upperVersion = new SemanticVersion(part); - } + this.DisplayName = displayName; + this.ID = model.ID; + this.FormerIDs = model.GetFormerIDs().ToArray(); + this.MapLocalVersions = new Dictionary<string, string>(model.MapLocalVersions, StringComparer.InvariantCultureIgnoreCase); + this.MapRemoteVersions = new Dictionary<string, string>(model.MapRemoteVersions, StringComparer.InvariantCultureIgnoreCase); + this.Fields = model.GetFields().ToArray(); + } - yield return new ModDataField(fieldKey, value, isDefault, lowerVersion, upperVersion); + /// <summary>Get whether the mod has (or previously had) the given ID.</summary> + /// <param name="id">The mod ID.</param> + public bool HasID(string id) + { + // try main ID + if (this.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase)) + return true; + + // try former IDs + foreach (string formerID in this.FormerIDs) + { + if (formerID.Equals(id, StringComparison.InvariantCultureIgnoreCase)) + return true; } + + return false; } /// <summary>Get a semantic local version for update checks.</summary> @@ -127,20 +86,39 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData : version; } - - /********* - ** Private methods - *********/ - /// <summary>The method invoked after JSON deserialisation.</summary> - /// <param name="context">The deserialisation context.</param> - [OnDeserialized] - private void OnDeserialized(StreamingContext context) + /// <summary>Get a parsed representation of the <see cref="ModDataRecord.Fields"/> which match a given manifest.</summary> + /// <param name="manifest">The manifest to match.</param> + public ModDataRecordVersionedFields GetVersionedFields(IManifest manifest) { - if (this.ExtensionData != null) + ModDataRecordVersionedFields parsed = new ModDataRecordVersionedFields { DisplayName = this.DisplayName, DataRecord = this }; + foreach (ModDataField field in this.Fields.Where(field => field.IsMatch(manifest))) { - this.Fields = this.ExtensionData.ToDictionary(p => p.Key, p => p.Value.ToString()); - this.ExtensionData = null; + switch (field.Key) + { + // update key + case ModDataFieldKey.UpdateKey: + parsed.UpdateKey = field.Value; + break; + + // alternative URL + case ModDataFieldKey.AlternativeUrl: + parsed.AlternativeUrl = field.Value; + break; + + // status + case ModDataFieldKey.Status: + parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true); + parsed.StatusUpperVersion = field.UpperVersion; + break; + + // status reason phrase + case ModDataFieldKey.StatusReasonPhrase: + parsed.StatusReasonPhrase = field.Value; + break; + } } + + return parsed; } } } diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ParsedModDataRecord.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecordVersionedFields.cs index 74f11ea5..3601fc53 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModData/ParsedModDataRecord.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecordVersionedFields.cs @@ -1,7 +1,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData { - /// <summary>A parsed representation of the fields from a <see cref="ModDataRecord"/> for a specific manifest.</summary> - public class ParsedModDataRecord + /// <summary>The versioned fields from a <see cref="ModDataRecord"/> for a specific manifest.</summary> + public class ModDataRecordVersionedFields { /********* ** Accessors diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs index c60d2bcb..a12e3c67 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs @@ -11,7 +11,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData ** Properties *********/ /// <summary>The underlying mod data records indexed by default display name.</summary> - private readonly IDictionary<string, ModDataRecord> Records; + private readonly ModDataRecord[] Records; /// <summary>Get an update URL for an update key (if valid).</summary> private readonly Func<string, string> GetUpdateUrl; @@ -22,63 +22,23 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData *********/ /// <summary>Construct an empty instance.</summary> public ModDatabase() - : this(new Dictionary<string, ModDataRecord>(), key => null) { } + : this(new ModDataRecord[0], key => null) { } /// <summary>Construct an instance.</summary> /// <param name="records">The underlying mod data records indexed by default display name.</param> /// <param name="getUpdateUrl">Get an update URL for an update key (if valid).</param> - public ModDatabase(IDictionary<string, ModDataRecord> records, Func<string, string> getUpdateUrl) + public ModDatabase(IEnumerable<ModDataRecord> records, Func<string, string> getUpdateUrl) { - this.Records = records; + this.Records = records.ToArray(); this.GetUpdateUrl = getUpdateUrl; } - /// <summary>Get a parsed representation of the <see cref="ModDataRecord.Fields"/> which match a given manifest.</summary> - /// <param name="manifest">The manifest to match.</param> - public ParsedModDataRecord GetParsed(IManifest manifest) + /// <summary>Get a mod data record.</summary> + /// <param name="modID">The unique mod ID.</param> + public ModDataRecord Get(string modID) { - // get raw record - if (!this.TryGetRaw(manifest?.UniqueID, out string displayName, out ModDataRecord record)) - return null; - - // parse fields - ParsedModDataRecord parsed = new ParsedModDataRecord { DisplayName = displayName, DataRecord = record }; - foreach (ModDataField field in record.GetFields().Where(field => field.IsMatch(manifest))) - { - switch (field.Key) - { - // update key - case ModDataFieldKey.UpdateKey: - parsed.UpdateKey = field.Value; - break; - - // alternative URL - case ModDataFieldKey.AlternativeUrl: - parsed.AlternativeUrl = field.Value; - break; - - // status - case ModDataFieldKey.Status: - parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true); - parsed.StatusUpperVersion = field.UpperVersion; - break; - - // status reason phrase - case ModDataFieldKey.StatusReasonPhrase: - parsed.StatusReasonPhrase = field.Value; - break; - } - } - - return parsed; - } - - /// <summary>Get the display name for a given mod ID (if available).</summary> - /// <param name="id">The unique mod ID.</param> - public string GetDisplayNameFor(string id) - { - return this.TryGetRaw(id, out string displayName, out ModDataRecord _) - ? displayName + return !string.IsNullOrWhiteSpace(modID) + ? this.Records.FirstOrDefault(p => p.HasID(modID)) : null; } @@ -86,55 +46,14 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData /// <param name="id">The unique mod ID.</param> public string GetModPageUrlFor(string id) { - // get raw record - if (!this.TryGetRaw(id, out string _, out ModDataRecord record)) - return null; - // get update key - ModDataField updateKeyField = record.GetFields().FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey); + ModDataRecord record = this.Get(id); + ModDataField updateKeyField = record?.Fields.FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey); if (updateKeyField == null) return null; // get update URL return this.GetUpdateUrl(updateKeyField.Value); } - - - /********* - ** Private models - *********/ - /// <summary>Get a raw data record.</summary> - /// <param name="id">The mod ID to match.</param> - /// <param name="displayName">The mod's default display name.</param> - /// <param name="record">The raw mod record.</param> - private bool TryGetRaw(string id, out string displayName, out ModDataRecord record) - { - if (!string.IsNullOrWhiteSpace(id)) - { - foreach (var entry in this.Records) - { - displayName = entry.Key; - record = entry.Value; - - // try main ID - if (record.ID != null && record.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase)) - return true; - - // try former IDs - if (record.FormerIDs != null) - { - foreach (string part in record.FormerIDs.Split('|')) - { - if (part.Trim().Equals(id, StringComparison.InvariantCultureIgnoreCase)) - return true; - } - } - } - } - - displayName = null; - record = null; - return false; - } } } diff --git a/src/StardewModdingAPI.Toolkit/ModToolkit.cs b/src/StardewModdingAPI.Toolkit/ModToolkit.cs index 1723991e..7b678f3d 100644 --- a/src/StardewModdingAPI.Toolkit/ModToolkit.cs +++ b/src/StardewModdingAPI.Toolkit/ModToolkit.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; @@ -48,8 +49,9 @@ namespace StardewModdingAPI.Toolkit /// <param name="getUpdateUrl">Get an update URL for an update key (if valid).</param> public ModDatabase GetModDatabase(string metadataPath, Func<string, string> getUpdateUrl) { - SMetadata metadata = JsonConvert.DeserializeObject<SMetadata>(File.ReadAllText(metadataPath)); - return new ModDatabase(metadata.ModData, getUpdateUrl); + MetadataModel metadata = JsonConvert.DeserializeObject<MetadataModel>(File.ReadAllText(metadataPath)); + ModDataRecord[] records = metadata.ModData.Select(pair => new ModDataRecord(pair.Key, pair.Value)).ToArray(); + return new ModDatabase(records, getUpdateUrl); } /// <summary>Get an update URL for an update key (if valid).</summary> |