summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI.Tests/Core/ModResolverTests.cs14
-rw-r--r--src/SMAPI/Constants.cs33
-rw-r--r--src/SMAPI/Framework/ModLoading/ModResolver.cs16
-rw-r--r--src/SMAPI/Program.cs2
4 files changed, 38 insertions, 27 deletions
diff --git a/src/SMAPI.Tests/Core/ModResolverTests.cs b/src/SMAPI.Tests/Core/ModResolverTests.cs
index 900a6c4f..d63eb1a2 100644
--- a/src/SMAPI.Tests/Core/ModResolverTests.cs
+++ b/src/SMAPI.Tests/Core/ModResolverTests.cs
@@ -120,7 +120,7 @@ namespace StardewModdingAPI.Tests.Core
[Test(Description = "Assert that validation doesn't fail if there are no mods installed.")]
public void ValidateManifests_NoMods_DoesNothing()
{
- new ModResolver().ValidateManifests(new ModMetadata[0], apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new ModMetadata[0], apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
}
[Test(Description = "Assert that validation skips manifests that have already failed without calling any other properties.")]
@@ -131,7 +131,7 @@ namespace StardewModdingAPI.Tests.Core
mock.Setup(p => p.Status).Returns(ModMetadataStatus.Failed);
// act
- new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
mock.VerifyGet(p => p.Status, Times.Once, "The validation did not check the manifest status.");
@@ -149,7 +149,7 @@ namespace StardewModdingAPI.Tests.Core
});
// act
- new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata.");
@@ -164,7 +164,7 @@ namespace StardewModdingAPI.Tests.Core
this.SetupMetadataForValidation(mock);
// act
- new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata.");
@@ -178,7 +178,7 @@ namespace StardewModdingAPI.Tests.Core
this.SetupMetadataForValidation(mock);
// act
- new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata.");
@@ -195,7 +195,7 @@ namespace StardewModdingAPI.Tests.Core
this.SetupMetadataForValidation(mod);
// act
- new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
modA.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the first mod with a unique ID.");
@@ -221,7 +221,7 @@ namespace StardewModdingAPI.Tests.Core
mock.Setup(p => p.DirectoryPath).Returns(modFolder);
// act
- new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>());
+ new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null);
// assert
// if Moq doesn't throw a method-not-setup exception, the validation didn't override the status.
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index 515e9870..caee93e4 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -21,6 +21,14 @@ namespace StardewModdingAPI
/// <summary>Whether the directory containing the current save's data exists on disk.</summary>
private static bool SavePathReady => Context.IsSaveLoaded && Directory.Exists(Constants.RawSavePath);
+ /// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID). This doesn't affect update checks, which defer to the remote web API.</summary>
+ private static readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
+ {
+ ["Chucklefish"] = "https://community.playstarbound.com/resources/{0}",
+ ["Nexus"] = "http://nexusmods.com/stardewvalley/mods/{0}",
+ ["GitHub"] = "https://github.com/{0}/releases"
+ };
+
/*********
** Accessors
@@ -87,14 +95,6 @@ namespace StardewModdingAPI
Platform.Mono;
#endif
- /// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID) during mod compatibility checks. This doesn't affect update checks, which defer to the remote web API.</summary>
- internal static readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
- {
- ["Chucklefish"] = "https://community.playstarbound.com/resources/{0}",
- ["Nexus"] = "http://nexusmods.com/stardewvalley/mods/{0}",
- ["GitHub"] = "https://github.com/{0}/releases"
- };
-
/*********
** Internal methods
@@ -145,6 +145,23 @@ namespace StardewModdingAPI
return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences, targetAssemblies);
}
+ /// <summary>Get an update URL for an update key (if valid).</summary>
+ /// <param name="updateKey">The update key.</param>
+ internal static string GetUpdateUrl(string updateKey)
+ {
+ string[] parts = updateKey.Split(new[] { ':' }, 2);
+ if (parts.Length != 2)
+ return null;
+
+ string vendorKey = parts[0].Trim();
+ string modID = parts[1].Trim();
+
+ if (Constants.VendorModUrls.TryGetValue(vendorKey, out string urlTemplate))
+ return string.Format(urlTemplate, modID);
+
+ return null;
+ }
+
/*********
** Private methods
diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs
index 09a9299e..99d86bf8 100644
--- a/src/SMAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs
@@ -73,8 +73,8 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Validate manifest metadata.</summary>
/// <param name="mods">The mod manifests to validate.</param>
/// <param name="apiVersion">The current SMAPI version.</param>
- /// <param name="vendorModUrls">Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID).</param>
- public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion, IDictionary<string, string> vendorModUrls)
+ /// <param name="getUpdateUrl">Get an update URL for an update key (if valid).</param>
+ public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion, Func<string, string> getUpdateUrl)
{
mods = mods.ToArray();
@@ -101,15 +101,9 @@ namespace StardewModdingAPI.Framework.ModLoading
List<string> updateUrls = new List<string>();
foreach (string key in mod.Manifest.UpdateKeys ?? new string[0])
{
- string[] parts = key.Split(new[] { ':' }, 2);
- if (parts.Length != 2)
- continue;
-
- string vendorKey = parts[0].Trim();
- string modID = parts[1].Trim();
-
- if (vendorModUrls.TryGetValue(vendorKey, out string urlTemplate))
- updateUrls.Add(string.Format(urlTemplate, modID));
+ string url = getUpdateUrl(key);
+ if (url != null)
+ updateUrls.Add(url);
}
if (mod.DataRecord.AlternativeUrl != null)
updateUrls.Add(mod.DataRecord.AlternativeUrl);
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index ec841f4c..85bc83a7 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -360,7 +360,7 @@ namespace StardewModdingAPI
// load manifests
IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), modDatabase).ToArray();
- resolver.ValidateManifests(mods, Constants.ApiVersion, Constants.VendorModUrls);
+ resolver.ValidateManifests(mods, Constants.ApiVersion, Constants.GetUpdateUrl);
// process dependencies
mods = resolver.ProcessDependencies(mods, modDatabase).ToArray();