Skip to content

Commit

Permalink
Dependency check does not take plugins that embed dependencies into a…
Browse files Browse the repository at this point in the history
…ccount. (#52)

* try loading first, then check for missing dependencies so plugins that have them embedded can be loaded

* print errors if dependencies match

* resolve embedded resources

* docs

* Update NwPluginAPI/Loader/AssemblyLoader.cs

Co-authored-by: Łukasz Jurczyk <zabszk@protonmail.ch>

* Update NwPluginAPI/Loader/AssemblyLoader.cs

Co-authored-by: Łukasz Jurczyk <zabszk@protonmail.ch>

Co-authored-by: Łukasz Jurczyk <zabszk@protonmail.ch>
  • Loading branch information
ced777ric and zabszk authored Nov 30, 2022
1 parent db74f85 commit 8631c3d
Showing 1 changed file with 77 additions and 13 deletions.
90 changes: 77 additions & 13 deletions NwPluginAPI/Loader/AssemblyLoader.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace PluginAPI.Loader
{
using System.IO.Compression;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -124,19 +125,31 @@ private static void LoadPlugins(PluginDirectory directory)
if (!TryGetAssembly(pluginPath, out Assembly assembly))
continue;

var missingDependencies = assembly
.GetReferencedAssemblies()
.Select(x =>
$"{x.Name}&r v&6{x.Version.ToString(3)}")
.Where(x => !loadedAssemblies.Contains(x)).ToArray();

if (missingDependencies.Length != 0)
{
Log.Error($"Failed loading plugin &2{Path.GetFileNameWithoutExtension(pluginPath)}&r, missing dependencies\n&2{string.Join("\n", missingDependencies.Select(x => $"&r - &2{x}&r"))}", "Loader");
continue;
}

var types = assembly.GetTypes();
Type[] types = null;

var missingDependencies = assembly
.GetReferencedAssemblies()
.Select(x =>
$"{x.Name}&r v&6{x.Version.ToString(3)}")
.Where(x => !loadedAssemblies.Contains(x)).ToArray();

try
{
if (missingDependencies.Length != 0)
ResolveAssemblyEmbeddedResources(assembly);
types = assembly.GetTypes();
}
catch (Exception e)
{
if (missingDependencies.Length != 0)
{
Log.Error($"Failed loading plugin &2{Path.GetFileNameWithoutExtension(pluginPath)}&r, missing dependencies\n&2{string.Join("\n", missingDependencies.Select(x => $"&r - &2{x}&r"))}\n\n{e}", "Loader");
continue;
}

Log.Error($"Failed loading plugin &2{Path.GetFileNameWithoutExtension(pluginPath)}&r, {e.ToString()}");
continue;
}

foreach (var entryType in types)
{
Expand Down Expand Up @@ -226,5 +239,56 @@ private static bool TryGetAssembly(string path, out Assembly assembly)
assembly = null;
return false;
}

/// <summary>
/// Attempts to load Embedded assemblies (compressed) from the target
/// </summary>
/// <param name="target">Assembly to check for embedded assemblies</param>
private static void ResolveAssemblyEmbeddedResources(Assembly target)
{
Log.Debug($"Attempting to load embedded resources for {target.FullName}", Log.DebugMode);


var resourceNames = target.GetManifestResourceNames();
foreach (var name in resourceNames)
{
Log.Debug($"Found {name}", Log.DebugMode);
if (name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
{
using (MemoryStream stream = new MemoryStream())
{
Log.Debug($"Loading {name}", Log.DebugMode);
var dataStream = target.GetManifestResourceStream(name);
if (dataStream == null)
{
Log.Error($"Unable to resolve {name} Stream was null");
continue;
}

dataStream.CopyTo(stream);
Assembly.Load(stream.ToArray());
Log.Debug($"Loaded {name}", Log.DebugMode);
}
}
else if (name.EndsWith(".dll.compressed", StringComparison.OrdinalIgnoreCase))
{
var dataStream = target.GetManifestResourceStream(name);
if (dataStream == null)
{
Log.Error($"Unable to resolve {name} Stream was null");
continue;
}

using (DeflateStream stream = new DeflateStream(dataStream, CompressionMode.Decompress))
using (MemoryStream memStream = new MemoryStream())
{
Log.Debug($"Loading {name}", Log.DebugMode);
stream.CopyTo(memStream);
Assembly.Load(memStream.ToArray());
Log.Debug($"Loaded {name}", Log.DebugMode);
}
}
}
}
}
}

0 comments on commit 8631c3d

Please sign in to comment.