fixed plugin dependencies resolution
This commit is contained in:
@@ -1,34 +1,52 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace Torch.Plugins;
|
namespace Torch.Plugins;
|
||||||
|
|
||||||
internal static class AssemblyRewriter
|
internal static class AssemblyRewriter
|
||||||
{
|
{
|
||||||
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
|
private static readonly ZipResolver _zipResolver;
|
||||||
|
private static readonly DefaultAssemblyResolver _defaultResolver;
|
||||||
private static readonly IAssemblyResolver Resolver;
|
|
||||||
|
|
||||||
static AssemblyRewriter()
|
static AssemblyRewriter()
|
||||||
{
|
{
|
||||||
var resolver = new DefaultAssemblyResolver();
|
_defaultResolver = new();
|
||||||
Resolver = resolver;
|
_zipResolver = new(_defaultResolver);
|
||||||
resolver.AddSearchDirectory(Directory.GetCurrentDirectory());
|
_defaultResolver.AddSearchDirectory(Directory.GetCurrentDirectory());
|
||||||
resolver.AddSearchDirectory(Path.Combine(Directory.GetCurrentDirectory(), "DedicatedServer64"));
|
_defaultResolver.AddSearchDirectory(Path.Combine(Directory.GetCurrentDirectory(), "DedicatedServer64"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Assembly ProcessWeavers(this Stream stream)
|
public static Assembly ProcessWeavers(this Stream stream, ZipArchive archive)
|
||||||
{
|
{
|
||||||
|
_zipResolver.Archive = archive;
|
||||||
using var assStream = new MemoryStream();
|
using var assStream = new MemoryStream();
|
||||||
stream.CopyTo(assStream);
|
stream.CopyTo(assStream);
|
||||||
assStream.Position = 0;
|
assStream.Position = 0;
|
||||||
using var module = ModuleDefinition.ReadModule(assStream, new()
|
var ass = ProcessInternal(assStream, _zipResolver);
|
||||||
|
_zipResolver.Archive = null;
|
||||||
|
return ass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Assembly ProcessWeavers(this Stream stream, string path)
|
||||||
{
|
{
|
||||||
AssemblyResolver = Resolver
|
_defaultResolver.AddSearchDirectory(path);
|
||||||
|
using var assStream = new MemoryStream();
|
||||||
|
stream.CopyTo(assStream);
|
||||||
|
assStream.Position = 0;
|
||||||
|
var ass = ProcessInternal(assStream, _defaultResolver);
|
||||||
|
_defaultResolver.RemoveSearchDirectory(path);
|
||||||
|
return ass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Assembly ProcessInternal(Stream inputStream, IAssemblyResolver resolver)
|
||||||
|
{
|
||||||
|
using var module = ModuleDefinition.ReadModule(inputStream, new()
|
||||||
|
{
|
||||||
|
AssemblyResolver = _zipResolver
|
||||||
});
|
});
|
||||||
foreach (var fieldDefinition in FindAllToRewrite(module))
|
foreach (var fieldDefinition in FindAllToRewrite(module))
|
||||||
{
|
{
|
||||||
@@ -47,4 +65,40 @@ internal static class AssemblyRewriter
|
|||||||
|
|
||||||
private static bool HasValidAttributes(FieldDefinition definition) =>
|
private static bool HasValidAttributes(FieldDefinition definition) =>
|
||||||
definition.CustomAttributes.Any(b => b.AttributeType.Name.Contains("Reflected") || b.AttributeType.Name == "DependencyAttribute");
|
definition.CustomAttributes.Any(b => b.AttributeType.Name.Contains("Reflected") || b.AttributeType.Name == "DependencyAttribute");
|
||||||
|
|
||||||
|
private class ZipResolver : IAssemblyResolver
|
||||||
|
{
|
||||||
|
private readonly IAssemblyResolver _fallbackResolver;
|
||||||
|
public ZipArchive Archive { get; set; }
|
||||||
|
|
||||||
|
public ZipResolver(IAssemblyResolver fallbackResolver)
|
||||||
|
{
|
||||||
|
_fallbackResolver = fallbackResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_fallbackResolver.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssemblyDefinition Resolve(AssemblyNameReference name)
|
||||||
|
{
|
||||||
|
return Resolve(name, new());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
|
||||||
|
{
|
||||||
|
var fileName = $"{name.Name}.dll";
|
||||||
|
|
||||||
|
if (Archive.Entries.FirstOrDefault(entry => entry.Name == fileName) is not { } archiveEntry)
|
||||||
|
return _fallbackResolver.Resolve(name, parameters);
|
||||||
|
|
||||||
|
using var stream = archiveEntry.Open();
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
stream.CopyTo(memStream);
|
||||||
|
memStream.Position = 0;
|
||||||
|
|
||||||
|
return AssemblyDefinition.ReadAssembly(memStream, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -360,7 +360,7 @@ namespace Torch.Managers
|
|||||||
|
|
||||||
|
|
||||||
using var stream = entry.Open();
|
using var stream = entry.Open();
|
||||||
assemblies.Add(stream.ProcessWeavers());
|
assemblies.Add(stream.ProcessWeavers(zipFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -378,7 +378,7 @@ namespace Torch.Managers
|
|||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
using var stream = File.OpenRead(file);
|
using var stream = File.OpenRead(file);
|
||||||
assemblies.Add(stream.ProcessWeavers());
|
assemblies.Add(stream.ProcessWeavers(item.Path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user