diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj
index 306b9131..75c02622 100644
--- a/IPA.Injector/IPA.Injector.csproj
+++ b/IPA.Injector/IPA.Injector.csproj
@@ -57,7 +57,6 @@
-
diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index e8cc333f..04536d19 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -61,8 +61,8 @@
-
-
+
+
diff --git a/IPA.Injector/LibLoader.cs b/IPA.Loader/Loader/LibLoader.cs
similarity index 74%
rename from IPA.Injector/LibLoader.cs
rename to IPA.Loader/Loader/LibLoader.cs
index 0c57f403..effc6bf8 100644
--- a/IPA.Injector/LibLoader.cs
+++ b/IPA.Loader/Loader/LibLoader.cs
@@ -3,62 +3,87 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection;
using IPA.Logging;
-using static IPA.Logging.Logger;
+using Mono.Cecil;
-namespace IPA.Injector
+namespace IPA.Loader
{
+ internal class CecilLibLoader : BaseAssemblyResolver
+ {
+ public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
+ {
+ LibLoader.SetupAssemblyFilenames();
+
+ var testFile = $"{name.Name}.{name.Version}.dll";
+
+ if (LibLoader.filenameLocations.TryGetValue(testFile, out string path))
+ {
+ if (File.Exists(path))
+ {
+ return AssemblyDefinition.ReadAssembly(path, parameters);
+ }
+ }
+
+ return base.Resolve(name, parameters);
+ }
+ }
+
internal static class LibLoader
{
- private static string LibraryPath => Path.Combine(Environment.CurrentDirectory, "Libs");
- private static string NativeLibraryPath => Path.Combine(LibraryPath, "Native");
- private static Dictionary filenameLocations;
+ internal static string LibraryPath => Path.Combine(Environment.CurrentDirectory, "Libs");
+ internal static string NativeLibraryPath => Path.Combine(LibraryPath, "Native");
+ internal static Dictionary filenameLocations;
- public static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
+ internal static void SetupAssemblyFilenames()
{
- var asmName = new AssemblyName(e.Name);
- Log(Level.Debug, $"Resolving library {asmName}");
-
if (filenameLocations == null)
{
filenameLocations = new Dictionary();
foreach (var fn in TraverseTree(LibraryPath, s => s != NativeLibraryPath))
if (filenameLocations.ContainsKey(fn.Name))
- Log(Level.Critical, $"Multiple instances of {fn.Name} exist in Libs! Ignoring {fn.FullName}");
+ Log(Logger.Level.Critical, $"Multiple instances of {fn.Name} exist in Libs! Ignoring {fn.FullName}");
else filenameLocations.Add(fn.Name, fn.FullName);
}
+ }
+
+ public static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
+ {
+ var asmName = new AssemblyName(e.Name);
+ Log(Logger.Level.Debug, $"Resolving library {asmName}");
+
+ SetupAssemblyFilenames();
var testFile = $"{asmName.Name}.{asmName.Version}.dll";
- Log(Level.Debug, $"Looking for file {testFile}");
+ Log(Logger.Level.Debug, $"Looking for file {testFile}");
if (filenameLocations.TryGetValue(testFile, out string path))
{
- Log(Level.Debug, $"Found file {testFile} as {path}");
+ Log(Logger.Level.Debug, $"Found file {testFile} as {path}");
if (File.Exists(path))
{
return Assembly.LoadFrom(path);
}
- Log(Level.Critical, $"but {path} no longer exists!");
+ Log(Logger.Level.Critical, $"but {path} no longer exists!");
}
- Log(Level.Critical, $"No library {asmName} found");
+ Log(Logger.Level.Critical, $"No library {asmName} found");
return null;
}
- private static void Log(Level lvl, string message)
+ internal static void Log(Logger.Level lvl, string message)
{ // multiple proxy methods to delay loading of assemblies until it's done
- if (LogCreated)
+ if (Logger.LogCreated)
AssemblyLibLoaderCallLogger(lvl, message);
else
if (((byte)lvl & (byte)StandardLogger.PrintFilter) != 0)
Console.WriteLine($"[{lvl}] {message}");
}
- private static void AssemblyLibLoaderCallLogger(Level lvl, string message)
+ private static void AssemblyLibLoaderCallLogger(Logger.Level lvl, string message)
{
- libLoader.Log(lvl, message);
+ Logger.libLoader.Log(lvl, message);
}
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-iterate-through-a-directory-tree
@@ -152,5 +177,7 @@ namespace IPA.Injector
}
}
}
+
+
}
}
diff --git a/IPA.Loader/Loader/PluginLoader.cs b/IPA.Loader/Loader/PluginLoader.cs
index 3233d334..16ebedc5 100644
--- a/IPA.Loader/Loader/PluginLoader.cs
+++ b/IPA.Loader/Loader/PluginLoader.cs
@@ -143,8 +143,9 @@ namespace IPA.Loader
var pluginModule = AssemblyDefinition.ReadAssembly(plugin, new ReaderParameters
{
- ReadingMode = ReadingMode.Immediate,
- ReadWrite = false
+ ReadingMode = ReadingMode.Immediate,
+ ReadWrite = false,
+ AssemblyResolver = new CecilLibLoader()
}).MainModule;
var iBeatSaberPlugin = pluginModule.ImportReference(typeof(IBeatSaberPlugin));
@@ -183,6 +184,7 @@ namespace IPA.Loader
break;
}
+ Logger.loader.Debug($"Adding info for {Path.GetFileName(plugin)}");
PluginsMetadata.Add(metadata);
}
catch (Exception e)
@@ -196,7 +198,7 @@ namespace IPA.Loader
internal static void Resolve()
{ // resolves duplicates and conflicts, etc
PluginsMetadata.Sort((a, b) => a.Version.CompareTo(b.Version));
-
+
var ids = new HashSet();
var ignore = new HashSet();
var resolved = new List(PluginsMetadata.Count);
@@ -377,5 +379,5 @@ namespace IPA.Loader
}
internal static List LoadPlugins() => PluginsMetadata.Select(InitPlugin).Where(p => p != null).ToList();
- }
+ }
}
\ No newline at end of file