summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Web/Controllers/ModsApiController.cs47
-rw-r--r--src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs3
-rw-r--r--src/SMAPI.Web/appsettings.json4
-rw-r--r--src/SMAPI/Program.cs3
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs3
5 files changed, 57 insertions, 3 deletions
diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs
index c4f1023b..b9af17dc 100644
--- a/src/SMAPI.Web/Controllers/ModsApiController.cs
+++ b/src/SMAPI.Web/Controllers/ModsApiController.cs
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using StardewModdingAPI.Toolkit;
using StardewModdingAPI.Toolkit.Framework.Clients.WebApi;
+using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;
using StardewModdingAPI.Toolkit.Framework.ModData;
using StardewModdingAPI.Web.Framework.Clients.Chucklefish;
using StardewModdingAPI.Web.Framework.Clients.GitHub;
@@ -45,6 +46,9 @@ namespace StardewModdingAPI.Web.Controllers
/// <summary>The internal mod metadata list.</summary>
private readonly ModDatabase ModDatabase;
+ /// <summary>The web URL for the wiki compatibility list.</summary>
+ private readonly string WikiCompatibilityPageUrl;
+
/*********
** Public methods
@@ -60,6 +64,7 @@ namespace StardewModdingAPI.Web.Controllers
{
this.ModDatabase = new ModToolkit().GetModDatabase(Path.Combine(environment.WebRootPath, "StardewModdingAPI.metadata.json"));
ModUpdateCheckConfig config = configProvider.Value;
+ this.WikiCompatibilityPageUrl = config.WikiCompatibilityPageUrl;
this.Cache = cache;
this.SuccessCacheMinutes = config.SuccessCacheMinutes;
@@ -84,6 +89,9 @@ namespace StardewModdingAPI.Web.Controllers
ISemanticVersion apiVersion = this.GetApiVersion();
ModSearchEntryModel[] searchMods = this.GetSearchMods(model, apiVersion).ToArray();
+ // fetch wiki data
+ WikiCompatibilityEntry[] wikiData = await this.GetWikiDataAsync();
+
// perform checks
IDictionary<string, ModEntryModel> mods = new Dictionary<string, ModEntryModel>(StringComparer.CurrentCultureIgnoreCase);
foreach (ModSearchEntryModel mod in searchMods)
@@ -123,7 +131,7 @@ namespace StardewModdingAPI.Web.Controllers
continue;
}
- if (result.Main == null || result.Main.Version.IsOlderThan(version))
+ if (this.IsNewer(version, result.Main?.Version))
{
result.Name = data.Name;
result.Main = new ModEntryVersionModel(version, data.Url);
@@ -139,7 +147,7 @@ namespace StardewModdingAPI.Web.Controllers
continue;
}
- if (result.Optional == null || result.Optional.Version.IsOlderThan(version))
+ if (this.IsNewer(version, result.Optional?.Version))
{
result.Name = result.Name ?? data.Name;
result.Optional = new ModEntryVersionModel(version, data.Url);
@@ -147,6 +155,13 @@ namespace StardewModdingAPI.Web.Controllers
}
}
+ // get unofficial version
+ {
+ WikiCompatibilityEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(result.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));
+ if (wikiEntry?.UnofficialVersion != null && this.IsNewer(wikiEntry.UnofficialVersion, result.Main?.Version) && this.IsNewer(wikiEntry.UnofficialVersion, result.Optional?.Version))
+ result.Unofficial = new ModEntryVersionModel(wikiEntry.UnofficialVersion, this.WikiCompatibilityPageUrl);
+ }
+
// fallback to preview if latest is invalid
if (result.Main == null && result.Optional != null)
{
@@ -199,6 +214,14 @@ namespace StardewModdingAPI.Web.Controllers
return true;
}
+ /// <summary>Get whether a <paramref name="current"/> version is newer than an <paramref name="other"/> version.</summary>
+ /// <param name="current">The current version.</param>
+ /// <param name="other">The other version.</param>
+ private bool IsNewer(ISemanticVersion current, ISemanticVersion other)
+ {
+ return current != null && (other == null || other.IsOlderThan(current));
+ }
+
/// <summary>Get the mods for which the API should return data.</summary>
/// <param name="model">The search model.</param>
/// <param name="apiVersion">The requested API version.</param>
@@ -222,6 +245,26 @@ namespace StardewModdingAPI.Web.Controllers
}
}
+ /// <summary>Get mod data from the wiki compatibility list.</summary>
+ private async Task<WikiCompatibilityEntry[]> GetWikiDataAsync()
+ {
+ ModToolkit toolkit = new ModToolkit();
+ return await this.Cache.GetOrCreateAsync($"_wiki", async entry =>
+ {
+ try
+ {
+ WikiCompatibilityEntry[] entries = await toolkit.GetWikiCompatibilityListAsync();
+ entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.SuccessCacheMinutes);
+ return entries;
+ }
+ catch
+ {
+ entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.ErrorCacheMinutes);
+ return new WikiCompatibilityEntry[0];
+ }
+ });
+ }
+
/// <summary>Get the mod info for an update key.</summary>
/// <param name="updateKey">The namespaced update key.</param>
private async Task<ModInfoModel> GetInfoForUpdateKeyAsync(string updateKey)
diff --git a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
index fc3b7dc2..ce4f3cb5 100644
--- a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
+++ b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
@@ -24,5 +24,8 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels
/// <summary>The repository key for Nexus Mods.</summary>
public string NexusKey { get; set; }
+
+ /// <summary>The web URL for the wiki compatibility list.</summary>
+ public string WikiCompatibilityPageUrl { get; set; }
}
}
diff --git a/src/SMAPI.Web/appsettings.json b/src/SMAPI.Web/appsettings.json
index 2f87dbe5..837ba536 100644
--- a/src/SMAPI.Web/appsettings.json
+++ b/src/SMAPI.Web/appsettings.json
@@ -46,6 +46,8 @@
"ChucklefishKey": "Chucklefish",
"GitHubKey": "GitHub",
- "NexusKey": "Nexus"
+ "NexusKey": "Nexus",
+
+ "WikiCompatibilityPageUrl": "https://smapi.io/compat"
}
}
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index a1180474..d899e512 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -675,12 +675,15 @@ namespace StardewModdingAPI
ISemanticVersion localVersion = mod.DataRecord?.GetLocalVersionForUpdateChecks(mod.Manifest.Version) ?? mod.Manifest.Version;
ISemanticVersion latestVersion = mod.DataRecord?.GetRemoteVersionForUpdateChecks(result.Main?.Version) ?? result.Main?.Version;
ISemanticVersion optionalVersion = mod.DataRecord?.GetRemoteVersionForUpdateChecks(result.Optional?.Version) ?? result.Optional?.Version;
+ ISemanticVersion unofficialVersion = result.Unofficial?.Version;
// show update alerts
if (this.IsValidUpdate(localVersion, latestVersion, useBetaChannel: true))
updates.Add(Tuple.Create(mod, latestVersion, result.Main?.Url));
else if (this.IsValidUpdate(localVersion, optionalVersion, useBetaChannel: localVersion.IsPrerelease()))
updates.Add(Tuple.Create(mod, optionalVersion, result.Optional?.Url));
+ else if (this.IsValidUpdate(localVersion, unofficialVersion, useBetaChannel: mod.Status == ModMetadataStatus.Failed))
+ updates.Add(Tuple.Create(mod, unofficialVersion, result.Unofficial?.Url));
}
// show update errors
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs
index 581a524c..adfdfef9 100644
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/WebApi/ModEntryModel.cs
@@ -20,6 +20,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
/// <summary>The latest optional version, if newer than <see cref="Main"/>.</summary>
public ModEntryVersionModel Optional { get; set; }
+ /// <summary>The latest unofficial version, if newer than <see cref="Main"/> and <see cref="Optional"/>.</summary>
+ public ModEntryVersionModel Unofficial { get; set; }
+
/// <summary>The errors that occurred while fetching update data.</summary>
public string[] Errors { get; set; } = new string[0];