diff options
Diffstat (limited to 'src/SMAPI.Toolkit/Framework')
-rw-r--r-- | src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs | 17 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs | 2 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs | 17 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs | 3 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs | 4 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs | 2 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/UpdateData/ModSiteKey.cs (renamed from src/SMAPI.Toolkit/Framework/UpdateData/ModRepositoryKey.cs) | 4 | ||||
-rw-r--r-- | src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs | 96 |
8 files changed, 95 insertions, 50 deletions
diff --git a/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs b/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs index f0a7c82a..2fb6ed20 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs @@ -62,16 +62,15 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi private TResult Post<TBody, TResult>(string url, TBody content) { // note: avoid HttpClient for Mac compatibility - using (WebClient client = new WebClient()) - { - Uri fullUrl = new Uri(this.BaseUrl, url); - string data = JsonConvert.SerializeObject(content); + using WebClient client = new WebClient(); - client.Headers["Content-Type"] = "application/json"; - client.Headers["User-Agent"] = $"SMAPI/{this.Version}"; - string response = client.UploadString(fullUrl, data); - return JsonConvert.DeserializeObject<TResult>(response, this.JsonSettings); - } + Uri fullUrl = new Uri(this.BaseUrl, url); + string data = JsonConvert.SerializeObject(content); + + client.Headers["Content-Type"] = "application/json"; + client.Headers["User-Agent"] = $"SMAPI/{this.Version}"; + string response = client.UploadString(fullUrl, data); + return JsonConvert.DeserializeObject<TResult>(response, this.JsonSettings); } } } 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<string, string> mapLocalVersions = this.GetAttributeAsVersionMapping(node, "data-map-local-versions"); IDictionary<string, string> 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/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 /// <summary>The compatibility status for a mod.</summary> public enum WikiCompatibilityStatus { + /// <summary>The status is unknown.</summary> + Unknown, + /// <summary>The mod is compatible.</summary> - Ok = 0, + Ok, /// <summary>The mod is compatible if you use an optional official download.</summary> - Optional = 1, + Optional, /// <summary>The mod is compatible if you use an unofficial update.</summary> - Unofficial = 2, + Unofficial, /// <summary>The mod isn't compatible, but the player can fix it or there's a good alternative.</summary> - Workaround = 3, + Workaround, /// <summary>The mod isn't compatible.</summary> - Broken = 4, + Broken, /// <summary>The mod is no longer maintained by the author, and an unofficial update or continuation is unlikely.</summary> - Abandoned = 5, + Abandoned, /// <summary>The mod is no longer needed and should be removed.</summary> - Obsolete = 6 + Obsolete } } 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 /// <summary>Special notes intended for developers who maintain unofficial updates or submit pull requests. </summary> public string DevNote { get; set; } + /// <summary>Update keys to add (optionally prefixed by '+') or remove (prefixed by '-').</summary> + public string[] ChangeUpdateKeys { get; set; } + /// <summary>Maps local versions to a semantic version for update checks.</summary> public IDictionary<string, string> MapLocalVersions { get; set; } diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index 212c70ef..4eec3424 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -124,8 +124,8 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning XElement root; try { - using (FileStream stream = file.OpenRead()) - root = XElement.Load(stream); + using FileStream stream = file.OpenRead(); + root = XElement.Load(stream); } catch { diff --git a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs index f11cc1a7..f4857c7d 100644 --- a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs +++ b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs @@ -22,7 +22,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning { // OS metadata files new Regex(@"^__folder_managed_by_vortex$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Vortex mod manager - new Regex(@"^(?:__MACOSX|\._\.DS_Store|\.DS_Store|mcs)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // MacOS + new Regex(@"(?:^\._|^\.DS_Store$|^__MACOSX$|^mcs$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), // MacOS new Regex(@"^(?:desktop\.ini|Thumbs\.db)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Windows new Regex(@"\.(?:url|lnk)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Windows shortcut files diff --git a/src/SMAPI.Toolkit/Framework/UpdateData/ModRepositoryKey.cs b/src/SMAPI.Toolkit/Framework/UpdateData/ModSiteKey.cs index 765ca334..47cd3f7e 100644 --- a/src/SMAPI.Toolkit/Framework/UpdateData/ModRepositoryKey.cs +++ b/src/SMAPI.Toolkit/Framework/UpdateData/ModSiteKey.cs @@ -1,7 +1,7 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData { - /// <summary>A mod repository which SMAPI can check for updates.</summary> - public enum ModRepositoryKey + /// <summary>A mod site which SMAPI can check for updates.</summary> + public enum ModSiteKey { /// <summary>An unknown or invalid mod repository.</summary> Unknown, diff --git a/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs b/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs index 3fc1759e..7e4d0220 100644 --- a/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs +++ b/src/SMAPI.Toolkit/Framework/UpdateData/UpdateKey.cs @@ -11,12 +11,15 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData /// <summary>The raw update key text.</summary> public string RawText { get; } - /// <summary>The mod repository containing the mod.</summary> - public ModRepositoryKey Repository { get; } + /// <summary>The mod site containing the mod.</summary> + public ModSiteKey Site { get; } /// <summary>The mod ID within the repository.</summary> public string ID { get; } + /// <summary>If specified, a substring in download names/descriptions to match.</summary> + public string Subkey { get; } + /// <summary>Whether the update key seems to be valid.</summary> public bool LooksValid { get; } @@ -26,53 +29,71 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData *********/ /// <summary>Construct an instance.</summary> /// <param name="rawText">The raw update key text.</param> - /// <param name="repository">The mod repository containing the mod.</param> - /// <param name="id">The mod ID within the repository.</param> - public UpdateKey(string rawText, ModRepositoryKey repository, string id) + /// <param name="site">The mod site containing the mod.</param> + /// <param name="id">The mod ID within the site.</param> + /// <param name="subkey">If specified, a substring in download names/descriptions to match.</param> + public UpdateKey(string rawText, ModSiteKey site, string id, string subkey) { - this.RawText = rawText; - this.Repository = repository; - this.ID = id; + this.RawText = rawText?.Trim(); + this.Site = site; + this.ID = id?.Trim(); + this.Subkey = subkey?.Trim(); this.LooksValid = - repository != ModRepositoryKey.Unknown + site != ModSiteKey.Unknown && !string.IsNullOrWhiteSpace(id); } /// <summary>Construct an instance.</summary> - /// <param name="repository">The mod repository containing the mod.</param> - /// <param name="id">The mod ID within the repository.</param> - public UpdateKey(ModRepositoryKey repository, string id) - : this($"{repository}:{id}", repository, id) { } + /// <param name="site">The mod site containing the mod.</param> + /// <param name="id">The mod ID within the site.</param> + /// <param name="subkey">If specified, a substring in download names/descriptions to match.</param> + public UpdateKey(ModSiteKey site, string id, string subkey) + : this(UpdateKey.GetString(site, id, subkey), site, id, subkey) { } /// <summary>Parse a raw update key.</summary> /// <param name="raw">The raw update key to parse.</param> public static UpdateKey Parse(string raw) { - // split parts - string[] parts = raw?.Split(':'); - if (parts == null || parts.Length != 2) - return new UpdateKey(raw, ModRepositoryKey.Unknown, null); - - // extract parts - string repositoryKey = parts[0].Trim(); - string id = parts[1].Trim(); + // extract site + ID + string rawSite; + string id; + { + string[] parts = raw?.Trim().Split(':'); + if (parts == null || parts.Length != 2) + return new UpdateKey(raw, ModSiteKey.Unknown, null, null); + + rawSite = parts[0].Trim(); + id = parts[1].Trim(); + } if (string.IsNullOrWhiteSpace(id)) id = null; + // extract subkey + string subkey = null; + if (id != null) + { + string[] parts = id.Split('@'); + if (parts.Length == 2) + { + id = parts[0].Trim(); + subkey = $"@{parts[1]}".Trim(); + } + } + // parse - if (!Enum.TryParse(repositoryKey, true, out ModRepositoryKey repository)) - return new UpdateKey(raw, ModRepositoryKey.Unknown, id); + if (!Enum.TryParse(rawSite, true, out ModSiteKey site)) + return new UpdateKey(raw, ModSiteKey.Unknown, id, subkey); if (id == null) - return new UpdateKey(raw, repository, null); + return new UpdateKey(raw, site, null, subkey); - return new UpdateKey(raw, repository, id); + return new UpdateKey(raw, site, id, subkey); } /// <summary>Get a string that represents the current object.</summary> public override string ToString() { return this.LooksValid - ? $"{this.Repository}:{this.ID}" + ? UpdateKey.GetString(this.Site, this.ID, this.Subkey) : this.RawText; } @@ -80,10 +101,18 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData /// <param name="other">An object to compare with this object.</param> public bool Equals(UpdateKey other) { + if (!this.LooksValid) + { + return + other?.LooksValid == false + && this.RawText.Equals(other.RawText, StringComparison.OrdinalIgnoreCase); + } + return other != null - && this.Repository == other.Repository - && string.Equals(this.ID, other.ID, StringComparison.InvariantCultureIgnoreCase); + && this.Site == other.Site + && string.Equals(this.ID, other.ID, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.Subkey, other.Subkey, StringComparison.OrdinalIgnoreCase); } /// <summary>Determines whether the specified object is equal to the current object.</summary> @@ -97,7 +126,16 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData /// <returns>A hash code for the current object.</returns> public override int GetHashCode() { - return $"{this.Repository}:{this.ID}".ToLower().GetHashCode(); + return this.ToString().ToLower().GetHashCode(); + } + + /// <summary>Get the string representation of an update key.</summary> + /// <param name="site">The mod site containing the mod.</param> + /// <param name="id">The mod ID within the repository.</param> + /// <param name="subkey">If specified, a substring in download names/descriptions to match.</param> + public static string GetString(ModSiteKey site, string id, string subkey = null) + { + return $"{site}:{id}{subkey}".Trim(); } } } |