From 34b0fd2870f0057b146dbac812cb7d673f2b11a4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 30 Jun 2018 18:00:32 -0400 Subject: detect broken assembly references not covered by a dependency, and flag as incompatible (#356) --- docs/release-notes.md | 3 ++- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 27 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index adf161b4..80f6e604 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -27,8 +27,9 @@ * Fixed launch issue for Linux players with some terminals. (Thanks to HanFox and kurumushi!) * Fixed issue where a mod crashing in `CanEdit` or `CanLoad` could cause an abort-retry loop. * Fixed many mods not working if the player name is blank. + * Fixed repeated errors in some cases when a mod references a missing assembly. * Renamed `install.exe` to `install on Windows.exe` to avoid confusion. - * Removed the `player_setspeed` and `player_setlevel` commands, which weren't implemented in a useful way. Use a mod like CJB Cheats Menu if you need those. + * Removed the `player_setlevel` and `player_setspeed` commands, which weren't implemented in a useful way. Use a mod like CJB Cheats Menu if you need those. * Updated compatibility list. * For modders: diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index ba4c3f5c..8f5a8316 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -99,6 +99,19 @@ namespace StardewModdingAPI.Framework.ModLoading // rewrite assembly bool changed = this.RewriteAssembly(mod, assembly.Definition, assumeCompatible, loggedMessages, logPrefix: " "); + // detect broken assembly reference + foreach (AssemblyNameReference reference in assembly.Definition.MainModule.AssemblyReferences) + { + if (!this.IsAssemblyLoaded(reference)) + { + this.Monitor.LogOnce(loggedMessages, $" Broken code in {assembly.File.Name}: reference to missing assembly '{reference.FullName}'."); + if (!assumeCompatible) + throw new IncompatibleInstructionException($"assembly reference to {reference.FullName}", $"Found a reference to missing assembly '{reference.FullName}' while loading assembly {assembly.File.Name}."); + mod.SetWarning(ModWarning.BrokenCodeLoaded); + break; + } + } + // load assembly if (changed) { @@ -126,6 +139,20 @@ namespace StardewModdingAPI.Framework.ModLoading return lastAssembly; } + /// Get whether an assembly is loaded. + /// The assembly name reference. + public bool IsAssemblyLoaded(AssemblyNameReference reference) + { + try + { + return this.AssemblyDefinitionResolver.Resolve(reference) != null; + } + catch (AssemblyResolutionException) + { + return false; + } + } + /// Resolve an assembly by its name. /// The assembly name. /// -- cgit