Browse Source

Fixed library detection when loading from Mono.Cecil

pull/46/head
Anairkoen Schno 5 years ago
parent
commit
d491dfde50
4 changed files with 53 additions and 25 deletions
  1. +0
    -1
      IPA.Injector/IPA.Injector.csproj
  2. +2
    -2
      IPA.Loader/IPA.Loader.csproj
  3. +45
    -18
      IPA.Loader/Loader/LibLoader.cs
  4. +6
    -4
      IPA.Loader/Loader/PluginLoader.cs

+ 0
- 1
IPA.Injector/IPA.Injector.csproj View File

@ -57,7 +57,6 @@
<Compile Include="Bootstrapper.cs" />
<Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" />
<Compile Include="LibLoader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updates.cs" />
<Compile Include="Virtualizer.cs" />


+ 2
- 2
IPA.Loader/IPA.Loader.csproj View File

@ -61,8 +61,8 @@
<Compile Include="Config\IConfigProvider.cs" />
<Compile Include="Config\SelfConfig.cs" />
<Compile Include="Loader\Composite\CompositeBSPlugin.cs" />
<Compile Include="Loader\Features\Feature.cs" />
<Compile Include="Loader\PluginLoader.cs" />
<Compile Include="Loader\LibLoader.cs" />
<Compile Include="Loader\Features\Feature.cs" /> <Compile Include="Loader\PluginLoader.cs" />
<Compile Include="Loader\PluginManifest.cs" />
<Compile Include="Logging\Printers\PluginSubLogPrinter.cs" />
<Compile Include="PluginInterfaces\BeatSaber\IBeatSaberPlugin.cs" />


IPA.Injector/LibLoader.cs → IPA.Loader/Loader/LibLoader.cs View File

@ -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<string, string> filenameLocations;
internal static string LibraryPath => Path.Combine(Environment.CurrentDirectory, "Libs");
internal static string NativeLibraryPath => Path.Combine(LibraryPath, "Native");
internal static Dictionary<string, string> 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<string, string>();
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
}
}
}
}
}

+ 6
- 4
IPA.Loader/Loader/PluginLoader.cs View File

@ -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<string>();
var ignore = new HashSet<PluginMetadata>();
var resolved = new List<PluginMetadata>(PluginsMetadata.Count);
@ -377,5 +379,5 @@ namespace IPA.Loader
}
internal static List<PluginInfo> LoadPlugins() => PluginsMetadata.Select(InitPlugin).Where(p => p != null).ToList();
}
}
}

Loading…
Cancel
Save