From 0b5fa6bf86d08cd2205dca3279d99795e68f5a12 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 9 May 2020 21:30:28 -0400 Subject: add new 'unknown' compatibility status (#711) --- .../Framework/Clients/Wiki/WikiCompatibilityStatus.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src/SMAPI.Toolkit/Framework/Clients/Wiki') diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs index a1d2dfae..5cdf489f 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs @@ -3,25 +3,28 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki /// The compatibility status for a mod. public enum WikiCompatibilityStatus { + /// The status is unknown. + Unknown, + /// The mod is compatible. - Ok = 0, + Ok, /// The mod is compatible if you use an optional official download. - Optional = 1, + Optional, /// The mod is compatible if you use an unofficial update. - Unofficial = 2, + Unofficial, /// The mod isn't compatible, but the player can fix it or there's a good alternative. - Workaround = 3, + Workaround, /// The mod isn't compatible. - Broken = 4, + Broken, /// The mod is no longer maintained by the author, and an unofficial update or continuation is unlikely. - Abandoned = 5, + Abandoned, /// The mod is no longer needed and should be removed. - Obsolete = 6 + Obsolete } } -- cgit 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 --- docs/release-notes.md | 1 + .../Framework/Clients/Wiki/WikiClient.cs | 2 + .../Framework/Clients/Wiki/WikiModEntry.cs | 3 + src/SMAPI.Web/Controllers/ModsApiController.cs | 103 +++++++++++++-------- 4 files changed, 69 insertions(+), 40 deletions(-) (limited to 'src/SMAPI.Toolkit/Framework/Clients/Wiki') diff --git a/docs/release-notes.md b/docs/release-notes.md index 5813298d..90835fa3 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -16,6 +16,7 @@ * Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info). * Added [update subkeys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Update_checks#Update_subkeys). * Added `Multiplayer.PeerConnected` event. + * Added ability to override update keys from the compatibility list. * Added `harmony_summary` console command which lists all current Harmony patches, optionally with a search filter. * Harmony mods which use the `[HarmonyPatch(type)]` attribute now work crossplatform. Previously SMAPI couldn't rewrite types in custom attributes for compatibility. * Improved mod rewriting for compatibility: 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