From a4713ea88238e6a6d62447aef97b35321e63c010 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 12 Jun 2017 18:44:36 -0400 Subject: add separate list of obsolete mods --- release-notes.md | 6 ++++++ src/StardewModdingAPI.Tests/ModResolverTests.cs | 6 +++--- .../Framework/ModLoading/ModResolver.cs | 22 +++++++++++++++++----- .../Framework/Models/DisabledMod.cs | 22 ++++++++++++++++++++++ src/StardewModdingAPI/Framework/Models/SConfig.cs | 3 +++ src/StardewModdingAPI/Program.cs | 2 +- .../StardewModdingAPI.config.json | 20 ++++++++++++-------- src/StardewModdingAPI/StardewModdingAPI.csproj | 1 + 8 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 src/StardewModdingAPI/Framework/Models/DisabledMod.cs 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 /// The root path to search for mods. /// The JSON helper with which to read manifests. /// Metadata about mods that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code. + /// Metadata about mods that SMAPI should consider obsolete and not load. /// Returns the manifests by relative folder. - public IEnumerable ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable compatibilityRecords) + public IEnumerable ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable compatibilityRecords, IEnumerable 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 +{ + /// Metadata about for a mod that should never be loaded. + internal class DisabledMod + { + /********* + ** Accessors + *********/ + /**** + ** From config + ****/ + /// The unique mod IDs. + public string[] ID { get; set; } + + /// The mod name. + public string Name { get; set; } + + /// The reason phrase to show in the warning, or null to use the default value. + /// "this mod is no longer supported or used" + 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 @@ /// A list of mod versions which should be considered compatible or incompatible regardless of whether SMAPI detects incompatible code. public ModCompatibility[] ModCompatibility { get; set; } + + /// A list of mods which should be considered obsolete and not loaded. + 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 @@ -26,6 +26,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`. @@ -315,14 +327,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha "UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/798", "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" ], 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 @@ + -- cgit