using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; using StardewModdingAPI.Toolkit.Framework.ModData; namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi { /// Extended metadata about a mod. public class ModExtendedMetadataModel { /********* ** Accessors *********/ /**** ** Mod info ****/ /// The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates). public string[] ID { get; set; } = Array.Empty(); /// The mod's display name. public string? Name { get; set; } /// The mod ID on Nexus. public int? NexusID { get; set; } /// The mod ID in the Chucklefish mod repo. public int? ChucklefishID { get; set; } /// The mod ID in the CurseForge mod repo. public int? CurseForgeID { get; set; } /// The mod key in the CurseForge mod repo (used in mod page URLs). public string? CurseForgeKey { get; set; } /// The mod ID in the ModDrop mod repo. public int? ModDropID { get; set; } /// The GitHub repository in the form 'owner/repo'. public string? GitHubRepo { get; set; } /// The URL to a non-GitHub source repo. public string? CustomSourceUrl { get; set; } /// The custom mod page URL (if applicable). public string? CustomUrl { get; set; } /// The main version. public ModEntryVersionModel? Main { get; set; } /// The latest optional version, if newer than . public ModEntryVersionModel? Optional { get; set; } /// The latest unofficial version, if newer than and . public ModEntryVersionModel? Unofficial { get; set; } /// The latest unofficial version for the current Stardew Valley or SMAPI beta, if any. public ModEntryVersionModel? UnofficialForBeta { get; set; } /**** ** Stable compatibility ****/ /// The compatibility status. [JsonConverter(typeof(StringEnumConverter))] public WikiCompatibilityStatus? CompatibilityStatus { get; set; } /// The human-readable summary of the compatibility status or workaround, without HTML formatting. public string? CompatibilitySummary { get; set; } /// The game or SMAPI version which broke this mod, if applicable. public string? BrokeIn { get; set; } /**** ** Beta compatibility ****/ /// The compatibility status for the Stardew Valley beta (if any). [JsonConverter(typeof(StringEnumConverter))] public WikiCompatibilityStatus? BetaCompatibilityStatus { get; set; } /// The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatting. public string? BetaCompatibilitySummary { get; set; } /// The beta game or SMAPI version which broke this mod, if applicable. public string? BetaBrokeIn { get; set; } /**** ** Version mappings ****/ /// A serialized change descriptor to apply to the local version during update checks (see ). public string? ChangeLocalVersions { get; set; } /// A serialized change descriptor to apply to the remote version during update checks (see ). public string? ChangeRemoteVersions { get; set; } /// A serialized change descriptor to apply to the update keys during update checks (see ). public string? ChangeUpdateKeys { get; set; } /********* ** Public methods *********/ /// Construct an instance. public ModExtendedMetadataModel() { } /// Construct an instance. /// The mod metadata from the wiki (if available). /// The mod metadata from SMAPI's internal DB (if available). /// The main version. /// The latest optional version, if newer than . /// The latest unofficial version, if newer than and . /// The latest unofficial version for the current Stardew Valley or SMAPI beta, if any. public ModExtendedMetadataModel(WikiModEntry? wiki, ModDataRecord? db, ModEntryVersionModel? main, ModEntryVersionModel? optional, ModEntryVersionModel? unofficial, ModEntryVersionModel? unofficialForBeta) { // versions this.Main = main; this.Optional = optional; this.Unofficial = unofficial; this.UnofficialForBeta = unofficialForBeta; // wiki data if (wiki != null) { this.ID = wiki.ID; this.Name = wiki.Name.FirstOrDefault(); this.NexusID = wiki.NexusID; this.ChucklefishID = wiki.ChucklefishID; this.CurseForgeID = wiki.CurseForgeID; this.CurseForgeKey = wiki.CurseForgeKey; this.ModDropID = wiki.ModDropID; this.GitHubRepo = wiki.GitHubRepo; this.CustomSourceUrl = wiki.CustomSourceUrl; this.CustomUrl = wiki.CustomUrl; this.CompatibilityStatus = wiki.Compatibility.Status; this.CompatibilitySummary = wiki.Compatibility.Summary; this.BrokeIn = wiki.Compatibility.BrokeIn; this.BetaCompatibilityStatus = wiki.BetaCompatibility?.Status; this.BetaCompatibilitySummary = wiki.BetaCompatibility?.Summary; this.BetaBrokeIn = wiki.BetaCompatibility?.BrokeIn; this.ChangeLocalVersions = wiki.Overrides?.ChangeLocalVersions?.ToString(); this.ChangeRemoteVersions = wiki.Overrides?.ChangeRemoteVersions?.ToString(); this.ChangeUpdateKeys = wiki.Overrides?.ChangeUpdateKeys?.ToString(); } // internal DB data if (db != null) { this.ID = this.ID.Union(db.FormerIDs).ToArray(); this.Name ??= db.DisplayName; } } /// Get update keys based on the metadata. public IEnumerable GetUpdateKeys() { if (this.NexusID.HasValue) yield return $"Nexus:{this.NexusID}"; if (this.ChucklefishID.HasValue) yield return $"Chucklefish:{this.ChucklefishID}"; if (this.GitHubRepo != null) yield return $"GitHub:{this.GitHubRepo}"; } } }