From 239173558c5a6b9d1340ed9d77edb7fce2cb19f9 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 18 Sep 2018 18:49:07 -0400 Subject: fix dependencies not enforced if the dependency failed in the load phase --- src/SMAPI/Framework/SCore.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 28994060..14380f7b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -701,7 +701,7 @@ namespace StardewModdingAPI.Framework InterfaceProxyFactory proxyFactory = new InterfaceProxyFactory(); foreach (IModMetadata mod in mods) { - if (!this.TryLoadMod(mod, modAssemblyLoader, proxyFactory, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out string errorPhrase, out string errorDetails)) + if (!this.TryLoadMod(mod, mods, modAssemblyLoader, proxyFactory, jsonHelper, contentCore, modDatabase, suppressUpdateChecks, out string errorPhrase, out string errorDetails)) { skippedMods[mod] = Tuple.Create(errorPhrase, errorDetails); if (mod.Status != ModMetadataStatus.Failed) @@ -840,6 +840,7 @@ namespace StardewModdingAPI.Framework /// Load a given mod. /// The mod to load. + /// The mods being loaded. /// Preprocesses and loads mod assemblies /// Generates proxy classes to access mod APIs through an arbitrary interface. /// The JSON helper with which to read mods' JSON files. @@ -849,7 +850,7 @@ namespace StardewModdingAPI.Framework /// The user-facing reason phrase explaining why the mod couldn't be loaded (if applicable). /// More detailed details about the error intended for developers (if any). /// Returns whether the mod was successfully loaded. - private bool TryLoadMod(IModMetadata mod, AssemblyLoader assemblyLoader, InterfaceProxyFactory proxyFactory, JsonHelper jsonHelper, ContentCoordinator contentCore, ModDatabase modDatabase, HashSet suppressUpdateChecks, out string errorReasonPhrase, out string errorDetails) + private bool TryLoadMod(IModMetadata mod, IModMetadata[] mods, AssemblyLoader assemblyLoader, InterfaceProxyFactory proxyFactory, JsonHelper jsonHelper, ContentCoordinator contentCore, ModDatabase modDatabase, HashSet suppressUpdateChecks, out string errorReasonPhrase, out string errorDetails) { errorDetails = null; @@ -875,6 +876,23 @@ namespace StardewModdingAPI.Framework return false; } + // validate dependencies + // Although dependences are validated before mods are loaded, a dependency may have failed. + if (mod.Manifest.Dependencies?.Any() == true) + { + foreach (IManifestDependency dependency in mod.Manifest.Dependencies) + { + if (this.ModRegistry.Get(dependency.UniqueID) == null) + { + string dependencyName = mods + .FirstOrDefault(p => dependency.UniqueID.Equals(p.Manifest.UniqueID, StringComparison.InvariantCultureIgnoreCase)) + ?.DisplayName ?? dependency.UniqueID; + errorReasonPhrase = $"it needs the '{dependencyName}' mod, which couldn't be loaded."; + return false; + } + } + } + // load as content pack if (mod.IsContentPack) { -- cgit