diff options
Diffstat (limited to 'src/StardewModdingAPI.Toolkit')
4 files changed, 100 insertions, 25 deletions
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs index 2aafe199..8a9c0a25 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs @@ -18,9 +18,15 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi /// <summary>The latest unofficial version, if newer than <see cref="Main"/> and <see cref="Optional"/>.</summary> public ModEntryVersionModel Unofficial { get; set; } + /// <summary>The latest unofficial version for the current Stardew Valley or SMAPI beta, if any (see <see cref="HasBetaInfo"/>).</summary> + public ModEntryVersionModel UnofficialForBeta { get; set; } + /// <summary>Optional extended data which isn't needed for update checks.</summary> public ModExtendedMetadataModel Metadata { get; set; } + /// <summary>Whether a Stardew Valley or SMAPI beta which affects mod compatibility is in progress. If this is true, <see cref="UnofficialForBeta"/> should be used for beta versions of SMAPI instead of <see cref="Unofficial"/>.</summary> + public bool HasBetaInfo { get; set; } + /// <summary>The errors that occurred while fetching update data.</summary> public string[] Errors { get; set; } = new string[0]; } diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs index 21376b36..0f3cb26f 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModExtendedMetadataModel.cs @@ -13,6 +13,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi /********* ** Accessors *********/ + /**** + ** Mod info + ****/ /// <summary>The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates).</summary> public string[] ID { get; set; } = new string[0]; @@ -34,6 +37,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi /// <summary>The custom mod page URL (if applicable).</summary> public string CustomUrl { get; set; } + /**** + ** Stable compatibility + ****/ /// <summary>The compatibility status.</summary> [JsonConverter(typeof(StringEnumConverter))] public WikiCompatibilityStatus? CompatibilityStatus { get; set; } @@ -42,6 +48,17 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi public string CompatibilitySummary { get; set; } + /**** + ** Beta compatibility + ****/ + /// <summary>The compatibility status for the Stardew Valley beta (if any).</summary> + [JsonConverter(typeof(StringEnumConverter))] + public WikiCompatibilityStatus? BetaCompatibilityStatus { get; set; } + + /// <summary>The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatitng.</summary> + public string BetaCompatibilitySummary { get; set; } + + /********* ** Public methods *********/ @@ -63,8 +80,12 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi this.GitHubRepo = wiki.GitHubRepo; this.CustomSourceUrl = wiki.CustomSourceUrl; this.CustomUrl = wiki.CustomUrl; + this.CompatibilityStatus = wiki.Status; this.CompatibilitySummary = wiki.Summary; + + this.BetaCompatibilityStatus = wiki.BetaStatus; + this.BetaCompatibilitySummary = wiki.BetaSummary; } // internal DB data diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs index d0da42df..929284c3 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs @@ -73,26 +73,8 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki { foreach (HtmlNode node in nodes) { - // parse status - WikiCompatibilityStatus status; - { - string rawStatus = node.GetAttributeValue("data-status", null); - if (rawStatus == null) - continue; // not a mod node? - if (!Enum.TryParse(rawStatus, true, out status)) - throw new InvalidOperationException($"Unknown status '{rawStatus}' when parsing compatibility list."); - } - - // parse unofficial version - ISemanticVersion unofficialVersion = null; - { - string rawUnofficialVersion = node.GetAttributeValue("data-unofficial-version", null); - SemanticVersion.TryParse(rawUnofficialVersion, out unofficialVersion); - } - - // parse other fields + // parse mod info string name = node.Descendants("td").FirstOrDefault()?.InnerText?.Trim(); - string summary = node.Descendants("td").FirstOrDefault(p => p.GetAttributeValue("class", null) == "summary")?.InnerText.Trim(); string[] ids = this.GetAttribute(node, "data-id")?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray() ?? new string[0]; int? nexusID = this.GetNullableIntAttribute(node, "data-nexus-id"); int? chucklefishID = this.GetNullableIntAttribute(node, "data-chucklefish-id"); @@ -100,23 +82,65 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki string customSourceUrl = this.GetAttribute(node, "data-custom-source"); string customUrl = this.GetAttribute(node, "data-custom-url"); + // parse stable compatibility + WikiCompatibilityStatus status = this.GetStatusAttribute(node, "data-status") ?? WikiCompatibilityStatus.Ok; + ISemanticVersion unofficialVersion = this.GetSemanticVersionAttribute(node, "data-unofficial-version"); + string summary = node.Descendants().FirstOrDefault(p => p.HasClass("data-summary"))?.InnerText.Trim(); + + // parse beta compatibility + WikiCompatibilityStatus? betaStatus = this.GetStatusAttribute(node, "data-beta-status"); + ISemanticVersion betaUnofficialVersion = betaStatus.HasValue ? this.GetSemanticVersionAttribute(node, "data-beta-unofficial-version") : null; + string betaSummary = betaStatus.HasValue ? node.Descendants().FirstOrDefault(p => p.HasClass("data-beta-summary"))?.InnerText.Trim() : null; + // yield model yield return new WikiCompatibilityEntry { + // mod info ID = ids, Name = name, - Status = status, NexusID = nexusID, ChucklefishID = chucklefishID, GitHubRepo = githubRepo, CustomSourceUrl = customSourceUrl, CustomUrl = customUrl, + + // stable compatibility + Status = status, + Summary = summary, UnofficialVersion = unofficialVersion, - Summary = summary + + // beta compatibility + BetaStatus = betaStatus, + BetaSummary = betaSummary, + BetaUnofficialVersion = betaUnofficialVersion }; } } + /// <summary>Get a compatibility status attribute value.</summary> + /// <param name="node">The HTML node.</param> + /// <param name="attributeName">The attribute name.</param> + private WikiCompatibilityStatus? GetStatusAttribute(HtmlNode node, string attributeName) + { + string raw = node.GetAttributeValue(attributeName, null); + if (raw == null) + return null; // not a mod node? + if (!Enum.TryParse(raw, true, out WikiCompatibilityStatus status)) + throw new InvalidOperationException($"Unknown status '{raw}' when parsing compatibility list."); + return status; + } + + /// <summary>Get a semantic version attribute value.</summary> + /// <param name="node">The HTML node.</param> + /// <param name="attributeName">The attribute name.</param> + private ISemanticVersion GetSemanticVersionAttribute(HtmlNode node, string attributeName) + { + string raw = node.GetAttributeValue(attributeName, null); + return SemanticVersion.TryParse(raw, out ISemanticVersion version) + ? version + : null; + } + /// <summary>Get a nullable integer attribute value.</summary> /// <param name="node">The HTML node.</param> /// <param name="attributeName">The attribute name.</param> diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs index 8bc66e20..3cb9c97c 100644 --- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs +++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs @@ -3,6 +3,12 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki /// <summary>An entry in the mod compatibility list.</summary> public class WikiCompatibilityEntry { + /********* + ** Accessors + *********/ + /**** + ** Mod info + ****/ /// <summary>The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates).</summary> public string[] ID { get; set; } @@ -24,13 +30,31 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki /// <summary>The custom mod page URL (if applicable).</summary> public string CustomUrl { get; set; } - /// <summary>The version of the latest unofficial update, if applicable.</summary> - public ISemanticVersion UnofficialVersion { get; set; } - + /**** + ** Stable compatibility + ****/ /// <summary>The compatibility status.</summary> public WikiCompatibilityStatus Status { get; set; } - /// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatitng.</summary> + /// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatting.</summary> public string Summary { get; set; } + + /// <summary>The version of the latest unofficial update, if applicable.</summary> + public ISemanticVersion UnofficialVersion { get; set; } + + /**** + ** Beta compatibility + ****/ + /// <summary>Whether a Stardew Valley or SMAPI beta which affects mod compatibility is in progress. If this is true, <see cref="BetaUnofficialVersion"/> should be used for beta versions of SMAPI instead of <see cref="UnofficialVersion"/>.</summary> + public bool HasBetaInfo => this.BetaStatus != null; + + /// <summary>The compatibility status for the Stardew Valley beta, if a beta is in progress.</summary> + public WikiCompatibilityStatus? BetaStatus { get; set; } + + /// <summary>The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatting.</summary> + public string BetaSummary { get; set; } + + /// <summary>The version of the latest unofficial update for the Stardew Valley beta (if any), if applicable.</summary> + public ISemanticVersion BetaUnofficialVersion { get; set; } } } |