summaryrefslogtreecommitdiff
path: root/src/SMAPI.Toolkit
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Toolkit')
-rw-r--r--src/SMAPI.Toolkit/Framework/Clients/WebApi/WebApiClient.cs17
-rw-r--r--src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs2
-rw-r--r--src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs17
-rw-r--r--src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs3
-rw-r--r--src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs4
-rw-r--r--src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs2
-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.cs96
-rw-r--r--src/SMAPI.Toolkit/ModToolkit.cs3
-rw-r--r--src/SMAPI.Toolkit/Properties/AssemblyInfo.cs4
-rw-r--r--src/SMAPI.Toolkit/SMAPI.Toolkit.csproj9
-rw-r--r--src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs5
12 files changed, 102 insertions, 64 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();
}
}
}
diff --git a/src/SMAPI.Toolkit/ModToolkit.cs b/src/SMAPI.Toolkit/ModToolkit.cs
index 80b14659..08fe0fed 100644
--- a/src/SMAPI.Toolkit/ModToolkit.cs
+++ b/src/SMAPI.Toolkit/ModToolkit.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Newtonsoft.Json;
using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;
@@ -11,8 +10,6 @@ using StardewModdingAPI.Toolkit.Framework.ModData;
using StardewModdingAPI.Toolkit.Framework.ModScanning;
using StardewModdingAPI.Toolkit.Serialization;
-[assembly: InternalsVisibleTo("StardewModdingAPI")]
-[assembly: InternalsVisibleTo("SMAPI.Web")]
namespace StardewModdingAPI.Toolkit
{
/// <summary>A convenience wrapper for the various tools.</summary>
diff --git a/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..233e680b
--- /dev/null
+++ b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs
@@ -0,0 +1,4 @@
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("StardewModdingAPI")]
+[assembly: InternalsVisibleTo("SMAPI.Web")]
diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
index edb1d612..71ea0f12 100644
--- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
+++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
@@ -1,20 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
-
<PropertyGroup>
- <AssemblyName>SMAPI.Toolkit</AssemblyName>
<RootNamespace>StardewModdingAPI.Toolkit</RootNamespace>
<Description>A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods.</Description>
<TargetFrameworks>net4.5;netstandard2.0</TargetFrameworks>
- <LangVersion>latest</LangVersion>
- <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\SMAPI.Toolkit.xml</DocumentationFile>
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PlatformTarget Condition="'$(TargetFramework)' == 'net4.5'">x86</PlatformTarget>
- <RootNamespace>StardewModdingAPI.Toolkit</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
- <PackageReference Include="Pathoschild.Http.FluentClient" Version="3.3.1" />
+ <PackageReference Include="Pathoschild.Http.FluentClient" Version="4.0.0" />
<PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT' AND '$(TargetFramework)' == 'netstandard2.0'" />
</ItemGroup>
@@ -24,5 +20,4 @@
</ItemGroup>
<Import Project="..\..\build\common.targets" />
-
</Project>
diff --git a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs
index c45448f3..1e490448 100644
--- a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs
+++ b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs
@@ -30,10 +30,7 @@ namespace StardewModdingAPI.Toolkit.Utilities
/// <summary>Detect the current OS.</summary>
public static Platform DetectPlatform()
{
- if (EnvironmentUtility.CachedPlatform == null)
- EnvironmentUtility.CachedPlatform = EnvironmentUtility.DetectPlatformImpl();
-
- return EnvironmentUtility.CachedPlatform.Value;
+ return EnvironmentUtility.CachedPlatform ??= EnvironmentUtility.DetectPlatformImpl();
}