From d9c2d242b9457a6517ec348c945ae1a324582492 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 24 May 2020 16:39:56 -0400 Subject: add update key overrides --- .../Framework/Clients/Wiki/WikiClient.cs | 2 + .../Framework/Clients/Wiki/WikiModEntry.cs | 3 + src/SMAPI.Web/Controllers/ModsApiController.cs | 103 +++++++++++++-------- 3 files changed, 68 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs index c829c0f4..34e2e1b8 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs @@ -105,6 +105,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki string pullRequestUrl = this.GetAttribute(node, "data-pr"); IDictionary mapLocalVersions = this.GetAttributeAsVersionMapping(node, "data-map-local-versions"); IDictionary mapRemoteVersions = this.GetAttributeAsVersionMapping(node, "data-map-remote-versions"); + string[] changeUpdateKeys = this.GetAttributeAsCsv(node, "data-change-update-keys"); // parse stable compatibility WikiCompatibilityInfo compatibility = new WikiCompatibilityInfo @@ -153,6 +154,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki Warnings = warnings, PullRequestUrl = pullRequestUrl, DevNote = devNote, + ChangeUpdateKeys = changeUpdateKeys, MapLocalVersions = mapLocalVersions, MapRemoteVersions = mapRemoteVersions, Anchor = anchor diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs index 474dce3d..21466c6a 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs @@ -63,6 +63,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki /// Special notes intended for developers who maintain unofficial updates or submit pull requests. public string DevNote { get; set; } + /// Update keys to add (optionally prefixed by '+') or remove (prefixed by '-'). + public string[] ChangeUpdateKeys { get; set; } + /// Maps local versions to a semantic version for update checks. public IDictionary MapLocalVersions { get; set; } diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs index 028fc613..db669bf9 100644 --- a/src/SMAPI.Web/Controllers/ModsApiController.cs +++ b/src/SMAPI.Web/Controllers/ModsApiController.cs @@ -280,56 +280,79 @@ namespace StardewModdingAPI.Web.Controllers /// The mod's entry in the wiki list. private IEnumerable GetUpdateKeys(string[] specifiedKeys, ModDataRecord record, WikiModEntry entry) { - // get every update key (including duplicates) - IEnumerable GetRaw() + // get unique update keys + List updateKeys = this.GetUnfilteredUpdateKeys(specifiedKeys, record, entry) + .Select(UpdateKey.Parse) + .Distinct() + .ToList(); + + // apply remove overrides from wiki + { + var removeKeys = new HashSet( + from key in entry?.ChangeUpdateKeys ?? new string[0] + where key.StartsWith('-') + select UpdateKey.Parse(key.Substring(1)) + ); + if (removeKeys.Any()) + updateKeys.RemoveAll(removeKeys.Contains); + } + + // if the list has both an update key (like "Nexus:2400") and subkey (like "Nexus:2400@subkey") for the same page, the subkey takes priority { - // specified update keys - if (specifiedKeys != null) + var removeKeys = new HashSet(); + foreach (var key in updateKeys) { - foreach (string key in specifiedKeys) - { - if (!string.IsNullOrWhiteSpace(key)) - yield return key.Trim(); - } + if (key.Subkey != null) + removeKeys.Add(new UpdateKey(key.Site, key.ID, null)); } + if (removeKeys.Any()) + updateKeys.RemoveAll(removeKeys.Contains); + } + + return updateKeys; + } + + /// Get every available update key based on the available mod metadata, including duplicates and keys which should be filtered. + /// The specified update keys. + /// The mod's entry in SMAPI's internal database. + /// The mod's entry in the wiki list. + private IEnumerable GetUnfilteredUpdateKeys(string[] specifiedKeys, ModDataRecord record, WikiModEntry entry) + { + // specified update keys + foreach (string key in specifiedKeys ?? Array.Empty()) + { + if (!string.IsNullOrWhiteSpace(key)) + yield return key.Trim(); + } - // default update key + // default update key + { string defaultKey = record?.GetDefaultUpdateKey(); if (!string.IsNullOrWhiteSpace(defaultKey)) yield return defaultKey; - - // wiki metadata - if (entry != null) - { - if (entry.NexusID.HasValue) - yield return UpdateKey.GetString(ModSiteKey.Nexus, entry.NexusID.ToString()); - if (entry.ModDropID.HasValue) - yield return UpdateKey.GetString(ModSiteKey.ModDrop, entry.ModDropID.ToString()); - if (entry.CurseForgeID.HasValue) - yield return UpdateKey.GetString(ModSiteKey.CurseForge, entry.CurseForgeID.ToString()); - if (entry.ChucklefishID.HasValue) - yield return UpdateKey.GetString(ModSiteKey.Chucklefish, entry.ChucklefishID.ToString()); - } } - // get unique update keys - var subkeyRoots = new HashSet(); - List updateKeys = GetRaw() - .Select(raw => - { - var key = UpdateKey.Parse(raw); - if (key.Subkey != null) - subkeyRoots.Add(new UpdateKey(key.Site, key.ID, null)); - return key; - }) - .Distinct() - .ToList(); - - // if the list has both an update key (like "Nexus:2400") and subkey (like "Nexus:2400@subkey") for the same page, the subkey takes priority - if (subkeyRoots.Any()) - updateKeys.RemoveAll(subkeyRoots.Contains); + // wiki metadata + if (entry != null) + { + if (entry.NexusID.HasValue) + yield return UpdateKey.GetString(ModSiteKey.Nexus, entry.NexusID.ToString()); + if (entry.ModDropID.HasValue) + yield return UpdateKey.GetString(ModSiteKey.ModDrop, entry.ModDropID.ToString()); + if (entry.CurseForgeID.HasValue) + yield return UpdateKey.GetString(ModSiteKey.CurseForge, entry.CurseForgeID.ToString()); + if (entry.ChucklefishID.HasValue) + yield return UpdateKey.GetString(ModSiteKey.Chucklefish, entry.ChucklefishID.ToString()); + } - return updateKeys; + // overrides from wiki + foreach (string key in entry?.ChangeUpdateKeys ?? Array.Empty()) + { + if (key.StartsWith('+')) + yield return key.Substring(1); + else if (!key.StartsWith("-")) + yield return key; + } } } } -- cgit