summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release-notes.md6
-rw-r--r--src/StardewModdingAPI.Tests/ModResolverTests.cs6
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs22
-rw-r--r--src/StardewModdingAPI/Framework/Models/DisabledMod.cs22
-rw-r--r--src/StardewModdingAPI/Framework/Models/SConfig.cs3
-rw-r--r--src/StardewModdingAPI/Program.cs2
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.config.json20
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.csproj1
8 files changed, 65 insertions, 17 deletions
diff --git a/release-notes.md b/release-notes.md
index e39ae3a8..f52e66cd 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -10,6 +10,12 @@ For mod developers:
images).
-->
+## 1.15
+See [log](https://github.com/Pathoschild/SMAPI/compare/1.14...1.15).
+
+For players:
+* SMAPI will no longer load mods known to be obsolete or unneeded.
+
## 1.14
See [log](https://github.com/Pathoschild/SMAPI/compare/1.13...1.14).
diff --git a/src/StardewModdingAPI.Tests/ModResolverTests.cs b/src/StardewModdingAPI.Tests/ModResolverTests.cs
index 23aeba64..a9df2056 100644
--- a/src/StardewModdingAPI.Tests/ModResolverTests.cs
+++ b/src/StardewModdingAPI.Tests/ModResolverTests.cs
@@ -31,7 +31,7 @@ namespace StardewModdingAPI.Tests
Directory.CreateDirectory(rootFolder);
// act
- IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0]).ToArray();
+ IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0], new DisabledMod[0]).ToArray();
// assert
Assert.AreEqual(0, mods.Length, 0, $"Expected to find zero manifests, found {mods.Length} instead.");
@@ -46,7 +46,7 @@ namespace StardewModdingAPI.Tests
Directory.CreateDirectory(modFolder);
// act
- IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0]).ToArray();
+ IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0], new DisabledMod[0]).ToArray();
IModMetadata mod = mods.FirstOrDefault();
// assert
@@ -85,7 +85,7 @@ namespace StardewModdingAPI.Tests
File.WriteAllText(filename, JsonConvert.SerializeObject(original));
// act
- IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0]).ToArray();
+ IModMetadata[] mods = new ModResolver().ReadManifests(rootFolder, new JsonHelper(), new ModCompatibility[0], new DisabledMod[0]).ToArray();
IModMetadata mod = mods.FirstOrDefault();
// assert
diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
index f5139ce5..e8308f3e 100644
--- a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
@@ -17,10 +17,13 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="rootPath">The root path to search for mods.</param>
/// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
/// <param name="compatibilityRecords">Metadata about mods that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code.</param>
+ /// <param name="disabledMods">Metadata about mods that SMAPI should consider obsolete and not load.</param>
/// <returns>Returns the manifests by relative folder.</returns>
- public IEnumerable<IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable<ModCompatibility> compatibilityRecords)
+ public IEnumerable<IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable<ModCompatibility> compatibilityRecords, IEnumerable<DisabledMod> disabledMods)
{
compatibilityRecords = compatibilityRecords.ToArray();
+ disabledMods = disabledMods.ToArray();
+
foreach (DirectoryInfo modDir in this.GetModFolders(rootPath))
{
// read file
@@ -47,20 +50,29 @@ namespace StardewModdingAPI.Framework.ModLoading
error = $"parsing its manifest failed:\n{ex.GetLogSummary()}";
}
- // get compatibility record
+ // validate metadata
ModCompatibility compatibility = null;
if (manifest != null)
{
+ // get unique key for lookups
string key = !string.IsNullOrWhiteSpace(manifest.UniqueID) ? manifest.UniqueID : manifest.EntryDll;
+
+ // check if mod should be disabled
+ DisabledMod disabledMod = disabledMods.FirstOrDefault(mod => mod.ID.Contains(key, StringComparer.InvariantCultureIgnoreCase));
+ if (disabledMod != null)
+ error = $"it's obsolete: {disabledMod.ReasonPhrase}";
+
+ // get compatibility record
compatibility = (
from mod in compatibilityRecords
where
- mod.ID.Contains(key, StringComparer.InvariantCultureIgnoreCase)
- && (mod.LowerSemanticVersion == null || !manifest.Version.IsOlderThan(mod.LowerSemanticVersion))
- && !manifest.Version.IsNewerThan(mod.UpperSemanticVersion)
+ mod.ID.Contains(key, StringComparer.InvariantCultureIgnoreCase)
+ && (mod.LowerSemanticVersion == null || !manifest.Version.IsOlderThan(mod.LowerSemanticVersion))
+ && !manifest.Version.IsNewerThan(mod.UpperSemanticVersion)
select mod
).FirstOrDefault();
}
+
// build metadata
string displayName = !string.IsNullOrWhiteSpace(manifest?.Name)
? manifest.Name
diff --git a/src/StardewModdingAPI/Framework/Models/DisabledMod.cs b/src/StardewModdingAPI/Framework/Models/DisabledMod.cs
new file mode 100644
index 00000000..170fa760
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Models/DisabledMod.cs
@@ -0,0 +1,22 @@
+namespace StardewModdingAPI.Framework.Models
+{
+ /// <summary>Metadata about for a mod that should never be loaded.</summary>
+ internal class DisabledMod
+ {
+ /*********
+ ** Accessors
+ *********/
+ /****
+ ** From config
+ ****/
+ /// <summary>The unique mod IDs.</summary>
+ public string[] ID { get; set; }
+
+ /// <summary>The mod name.</summary>
+ public string Name { get; set; }
+
+ /// <summary>The reason phrase to show in the warning, or <c>null</c> to use the default value.</summary>
+ /// <example>"this mod is no longer supported or used"</example>
+ public string ReasonPhrase { get; set; }
+ }
+}
diff --git a/src/StardewModdingAPI/Framework/Models/SConfig.cs b/src/StardewModdingAPI/Framework/Models/SConfig.cs
index c3f0816e..b2ca4113 100644
--- a/src/StardewModdingAPI/Framework/Models/SConfig.cs
+++ b/src/StardewModdingAPI/Framework/Models/SConfig.cs
@@ -17,5 +17,8 @@
/// <summary>A list of mod versions which should be considered compatible or incompatible regardless of whether SMAPI detects incompatible code.</summary>
public ModCompatibility[] ModCompatibility { get; set; }
+
+ /// <summary>A list of mods which should be considered obsolete and not loaded.</summary>
+ public DisabledMod[] DisabledMods { get; set; }
}
}
diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs
index d75d5193..71f09f5c 100644
--- a/src/StardewModdingAPI/Program.cs
+++ b/src/StardewModdingAPI/Program.cs
@@ -364,7 +364,7 @@ namespace StardewModdingAPI
ModResolver resolver = new ModResolver();
// load manifests
- IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), this.Settings.ModCompatibility).ToArray();
+ IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), this.Settings.ModCompatibility, this.Settings.DisabledMods).ToArray();
resolver.ValidateManifests(mods, Constants.ApiVersion);
// check for deprecated metadata
diff --git a/src/StardewModdingAPI/StardewModdingAPI.config.json b/src/StardewModdingAPI/StardewModdingAPI.config.json
index f62db90c..432a40e5 100644
--- a/src/StardewModdingAPI/StardewModdingAPI.config.json
+++ b/src/StardewModdingAPI/StardewModdingAPI.config.json
@@ -27,6 +27,18 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
"VerboseLogging": false,
/**
+ * A list of mods SMAPI should consider obsolete and not load. Changing this field is not
+ * recommended and may destabilise your game.
+ */
+ "DisabledMods": [
+ {
+ "Name": "StarDustCore",
+ "ID": [ "StarDustCore" ],
+ "ReasonPhrase": "it was only used by earlier versions of Save Anywhere (which no longer uses it), and is no longer maintained."
+ }
+ ],
+
+ /**
* A list of mod versions SMAPI should consider compatible or broken regardless of whether it
* detects incompatible code. Each record can be set to `AssumeCompatible` or `AssumeBroken`.
* Changing this field is not recommended and may destabilise your game.
@@ -316,14 +328,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
"Notes": "Needs update for SDV 1.2."
},
{
- "Name": "StarDustCore",
- "ID": [ "StarDustCore" ],
- "UpperVersion": "1.0",
- "Compatibility": "AssumeBroken",
- "UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/683",
- "Notes": "Obsolete (originally needed by Save Anywhere); broken in SDV 1.2."
- },
- {
"Name": "Teleporter",
"ID": [ "Teleporter" ],
"UpperVersion": "1.0.2",
diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj
index 7cc537ac..0e832848 100644
--- a/src/StardewModdingAPI/StardewModdingAPI.csproj
+++ b/src/StardewModdingAPI/StardewModdingAPI.csproj
@@ -124,6 +124,7 @@
<Compile Include="Events\GraphicsEvents.cs" />
<Compile Include="Framework\Countdown.cs" />
<Compile Include="Framework\IModMetadata.cs" />
+ <Compile Include="Framework\Models\DisabledMod.cs" />
<Compile Include="Framework\ModLoading\InvalidModStateException.cs" />
<Compile Include="Framework\ModLoading\ModDependencyStatus.cs" />
<Compile Include="Framework\ModLoading\ModMetadataStatus.cs" />