summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-06-30 18:00:32 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-06-30 18:00:32 -0400
commit34b0fd2870f0057b146dbac812cb7d673f2b11a4 (patch)
tree3678b7153da0090f2407d51f528f1a0fa1b270ff
parent599f5851928c82dba118e1d302da731a4ed4f91d (diff)
downloadSMAPI-34b0fd2870f0057b146dbac812cb7d673f2b11a4.tar.gz
SMAPI-34b0fd2870f0057b146dbac812cb7d673f2b11a4.tar.bz2
SMAPI-34b0fd2870f0057b146dbac812cb7d673f2b11a4.zip
detect broken assembly references not covered by a dependency, and flag as incompatible (#356)
-rw-r--r--docs/release-notes.md3
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs27
2 files changed, 29 insertions, 1 deletions
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;
}
+ /// <summary>Get whether an assembly is loaded.</summary>
+ /// <param name="reference">The assembly name reference.</param>
+ public bool IsAssemblyLoaded(AssemblyNameReference reference)
+ {
+ try
+ {
+ return this.AssemblyDefinitionResolver.Resolve(reference) != null;
+ }
+ catch (AssemblyResolutionException)
+ {
+ return false;
+ }
+ }
+
/// <summary>Resolve an assembly by its name.</summary>
/// <param name="name">The assembly name.</param>
/// <remarks>