diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-06-27 00:05:53 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-06-27 00:05:53 -0400 |
commit | 5f19e4f2035c36f9c6c882da3767d6f29409db1c (patch) | |
tree | b4b04714dd65ae3d6e487c346977dcba3536e0d6 /src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs | |
parent | 9f0cfee55632663473ee06c0586035cc47abe397 (diff) | |
download | SMAPI-5f19e4f2035c36f9c6c882da3767d6f29409db1c.tar.gz SMAPI-5f19e4f2035c36f9c6c882da3767d6f29409db1c.tar.bz2 SMAPI-5f19e4f2035c36f9c6c882da3767d6f29409db1c.zip |
move mod DB parsing into toolkit (#532)
Diffstat (limited to 'src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs')
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs new file mode 100644 index 00000000..c60d2bcb --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDatabase.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Toolkit.Framework.ModData +{ + /// <summary>Handles access to SMAPI's internal mod metadata list.</summary> + public class ModDatabase + { + /********* + ** Properties + *********/ + /// <summary>The underlying mod data records indexed by default display name.</summary> + private readonly IDictionary<string, ModDataRecord> Records; + + /// <summary>Get an update URL for an update key (if valid).</summary> + private readonly Func<string, string> GetUpdateUrl; + + + /********* + ** Public methods + *********/ + /// <summary>Construct an empty instance.</summary> + public ModDatabase() + : this(new Dictionary<string, ModDataRecord>(), 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) + { + this.Records = records; + 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) + { + // 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 + : null; + } + + /// <summary>Get the mod page URL for a mod (if available).</summary> + /// <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); + 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; + } + } +} |