diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
commit | 60b41195778af33fd609eab66d9ae3f1d1165e8f (patch) | |
tree | 7128b906d40e94c56c34ed6058f27bc31c31a08b /src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs | |
parent | b9bc1a6d17cafa0a97b46ffecda432cfc2f23b51 (diff) | |
parent | 52cf953f685c65b2b6814e375ec9a5ffa03c440a (diff) | |
download | SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.gz SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.bz2 SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs')
-rw-r--r-- | src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs new file mode 100644 index 00000000..82ac8837 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Framework/ModData/ModDataRecord.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Toolkit.Framework.ModData +{ + /// <summary>The parsed mod metadata from SMAPI's internal mod list.</summary> + public class ModDataRecord + { + /********* + ** 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; } + + /// <summary>The former mod IDs (if any).</summary> + public string[] FormerIDs { get; } + + /// <summary>Maps local versions to a semantic version for update checks.</summary> + public IDictionary<string, string> MapLocalVersions { get; } + + /// <summary>Maps remote versions to a semantic version for update checks.</summary> + public IDictionary<string, string> MapRemoteVersions { get; } + + /// <summary>The versioned field data.</summary> + public ModDataField[] Fields { get; } + + + /********* + ** Public methods + *********/ + /// <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) + { + 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(); + } + + /// <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> + /// <param name="version">The remote version to normalise.</param> + public ISemanticVersion GetLocalVersionForUpdateChecks(ISemanticVersion version) + { + return this.MapLocalVersions != null && this.MapLocalVersions.TryGetValue(version.ToString(), out string newVersion) + ? new SemanticVersion(newVersion) + : version; + } + + /// <summary>Get a semantic remote version for update checks.</summary> + /// <param name="version">The remote version to normalise.</param> + public string GetRemoteVersionForUpdateChecks(string version) + { + // normalise version if possible + if (SemanticVersion.TryParse(version, out ISemanticVersion parsed)) + version = parsed.ToString(); + + // fetch remote version + return this.MapRemoteVersions != null && this.MapRemoteVersions.TryGetValue(version, out string newVersion) + ? newVersion + : version; + } + + /// <summary>Get the possible mod IDs.</summary> + public IEnumerable<string> GetIDs() + { + return this.FormerIDs + .Concat(new[] { this.ID }) + .Where(p => !string.IsNullOrWhiteSpace(p)) + .Select(p => p.Trim()) + .Distinct(); + } + + /// <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) + { + ModDataRecordVersionedFields parsed = new ModDataRecordVersionedFields { DisplayName = this.DisplayName, DataRecord = this }; + foreach (ModDataField field in this.Fields.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; + } + } +} |