summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-01-16 22:56:48 -0500
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-01-16 22:56:48 -0500
commit95f4513727193d0048848d10ded465527a4969c9 (patch)
treebbfc64126c9510e27ad867b74fe397d31b36c03e
parent85f8631beefb5f97088fcecabb32bb8d2829a2fe (diff)
downloadSMAPI-95f4513727193d0048848d10ded465527a4969c9.tar.gz
SMAPI-95f4513727193d0048848d10ded465527a4969c9.tar.bz2
SMAPI-95f4513727193d0048848d10ded465527a4969c9.zip
rewrite fallback assembly resolution
* SMAPI now also searches the root game folder for unresolved assemblies. This fixes an issue resolving the game DLL when the player's DLL version doesn't match the one used to compile SMAPI. * The DLL search folders are now scanned once and cached to avoid repeated iterations on startup.
-rw-r--r--docs/release-notes.md3
-rw-r--r--src/SMAPI/Program.cs38
2 files changed, 34 insertions, 7 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index e555440a..684fb49d 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,6 +1,9 @@
← [README](README.md)
# Release notes
+## Upcoming release
+* Fixed Linux/macOS launch error in 3.13.3.
+
## 3.13.3
Released 16 January 2022 for Stardew Valley 1.5.6 or later.
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index 67ff8322..0c90f2aa 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -16,7 +17,10 @@ namespace StardewModdingAPI
** Fields
*********/
/// <summary>The absolute path to search for SMAPI's internal DLLs.</summary>
- internal static readonly string DllSearchPath = EarlyConstants.InternalFilesPath;
+ private static readonly string DllSearchPath = EarlyConstants.InternalFilesPath;
+
+ /// <summary>The assembly paths in the search folders indexed by assembly name.</summary>
+ private static Dictionary<string, string> AssemblyPathsByName;
/*********
@@ -57,16 +61,36 @@ namespace StardewModdingAPI
/// <param name="e">The event arguments.</param>
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
{
- try
+ // cache assembly paths by name
+ if (Program.AssemblyPathsByName == null)
{
- AssemblyName name = new AssemblyName(e.Name);
- foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll"))
+ Program.AssemblyPathsByName = new(StringComparer.OrdinalIgnoreCase);
+
+ foreach (string searchPath in new[] { EarlyConstants.ExecutionPath, Program.DllSearchPath })
{
- if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.OrdinalIgnoreCase))
- return Assembly.LoadFrom(dll.FullName);
+ foreach (string dllPath in Directory.EnumerateFiles(searchPath, "*.dll"))
+ {
+ try
+ {
+ string curName = AssemblyName.GetAssemblyName(dllPath).Name;
+ if (curName != null)
+ Program.AssemblyPathsByName[curName] = dllPath;
+ }
+ catch
+ {
+ continue;
+ }
+ }
}
+ }
- return null;
+ // resolve
+ try
+ {
+ string searchName = new AssemblyName(e.Name).Name;
+ return searchName != null && Program.AssemblyPathsByName.TryGetValue(searchName, out string assemblyPath)
+ ? Assembly.LoadFrom(assemblyPath)
+ : null;
}
catch (Exception ex)
{