mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Fix externally referenced DLLs in scripts
External DLL references weren't being used, this commit fixes them so they are used.
This commit is contained in:
parent
78f9c35800
commit
e006943535
3 changed files with 60 additions and 9 deletions
37
MinecraftClient/Scripting/AssemblyResolver.cs
Normal file
37
MinecraftClient/Scripting/AssemblyResolver.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace MinecraftClient.Scripting;
|
||||||
|
|
||||||
|
public static class AssemblyResolver {
|
||||||
|
private static Dictionary<string, string> ScriptAssemblies = new();
|
||||||
|
static AssemblyResolver() {
|
||||||
|
// Manually resolve assemblies that .NET can't resolve automatically.
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||||
|
{
|
||||||
|
var asmReqName = new AssemblyName(args.Name);
|
||||||
|
|
||||||
|
// Check the script-referenced assemblies if we have the DLL that is required.
|
||||||
|
foreach (var dll in ScriptAssemblies)
|
||||||
|
{
|
||||||
|
// If we have the assembly, load it.
|
||||||
|
if (asmReqName.FullName == dll.Key)
|
||||||
|
{
|
||||||
|
return Assembly.LoadFile(dll.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleIO.WriteLogLine($"[Script Error] Failed to resolve assembly {args.Name} (are you missing a DLL file?)");
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void AddAssembly(string AssemblyFullName, string AssemblyPath)
|
||||||
|
{
|
||||||
|
if (ScriptAssemblies.ContainsKey(AssemblyFullName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScriptAssemblies.Add(AssemblyFullName, AssemblyPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ namespace MinecraftClient
|
||||||
ConsoleIO.WriteLogLine($"[Script] Starting compilation for {scriptName}...");
|
ConsoleIO.WriteLogLine($"[Script] Starting compilation for {scriptName}...");
|
||||||
|
|
||||||
//Compile the C# class in memory using all the currently loaded assemblies
|
//Compile the C# class in memory using all the currently loaded assemblies
|
||||||
var result = compiler.Compile(code, Guid.NewGuid().ToString());
|
var result = compiler.Compile(code, Guid.NewGuid().ToString(), dlls);
|
||||||
|
|
||||||
//Process compile warnings and errors
|
//Process compile warnings and errors
|
||||||
if (result.Failures != null) {
|
if (result.Failures != null) {
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,17 @@ using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using MinecraftClient;
|
using MinecraftClient;
|
||||||
|
using MinecraftClient.Scripting;
|
||||||
using SingleFileExtractor.Core;
|
using SingleFileExtractor.Core;
|
||||||
|
|
||||||
namespace DynamicRun.Builder
|
namespace DynamicRun.Builder
|
||||||
{
|
{
|
||||||
internal class Compiler
|
internal class Compiler
|
||||||
{
|
{
|
||||||
public CompileResult Compile(string filepath, string fileName)
|
public CompileResult Compile(string filepath, string fileName, List<string> additionalAssemblies)
|
||||||
{
|
{
|
||||||
using var peStream = new MemoryStream();
|
using var peStream = new MemoryStream();
|
||||||
var result = GenerateCode(filepath, fileName).Emit(peStream);
|
var result = GenerateCode(filepath, fileName, additionalAssemblies).Emit(peStream);
|
||||||
|
|
||||||
if (!result.Success)
|
if (!result.Success)
|
||||||
{
|
{
|
||||||
|
|
@ -48,24 +49,37 @@ namespace DynamicRun.Builder
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CSharpCompilation GenerateCode(string sourceCode, string fileName)
|
private static CSharpCompilation GenerateCode(string sourceCode, string fileName, List<string> additionalAssemblies)
|
||||||
{
|
{
|
||||||
var codeString = SourceText.From(sourceCode);
|
var codeString = SourceText.From(sourceCode);
|
||||||
var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9);
|
var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9);
|
||||||
|
|
||||||
var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, options);
|
var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, options);
|
||||||
|
|
||||||
|
var references = new List<MetadataReference>();
|
||||||
|
|
||||||
var mods = Assembly.GetEntryAssembly()!.GetModules();
|
// Find if any additional assembly DLL exists in the base directory where the .exe exists.
|
||||||
|
foreach (var assembly in additionalAssemblies)
|
||||||
|
{
|
||||||
|
var dllPath = Path.Combine(AppContext.BaseDirectory, assembly);
|
||||||
|
if (File.Exists(dllPath))
|
||||||
|
{
|
||||||
|
references.Add(MetadataReference.CreateFromFile(dllPath));
|
||||||
|
// Store the reference in our Assembly Resolver for future reference.
|
||||||
|
AssemblyResolver.AddAssembly(Assembly.LoadFile(dllPath).FullName!, dllPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsoleIO.WriteLogLine($"[Script Error] {assembly} is defined in script, but cannot find DLL! Script may not run.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma warning disable IL3000 // We determine if we are in a self-contained binary by checking specifically if the Assembly file path is null.
|
#pragma warning disable IL3000 // We determine if we are in a self-contained binary by checking specifically if the Assembly file path is null.
|
||||||
|
|
||||||
var SystemPrivateCoreLib = typeof(object).Assembly.Location; // System.Private.CoreLib
|
var SystemPrivateCoreLib = typeof(object).Assembly.Location; // System.Private.CoreLib
|
||||||
var SystemConsole = typeof(Console).Assembly.Location; // System.Console
|
var SystemConsole = typeof(Console).Assembly.Location; // System.Console
|
||||||
var MinecraftClientDll = typeof(Program).Assembly.Location; // The path to MinecraftClient.dll
|
var MinecraftClientDll = typeof(Program).Assembly.Location; // The path to MinecraftClient.dll
|
||||||
|
|
||||||
var references = new List<MetadataReference>();
|
|
||||||
|
|
||||||
// We're on a self-contained binary, so we need to extract the executable to get the assemblies.
|
// We're on a self-contained binary, so we need to extract the executable to get the assemblies.
|
||||||
if (string.IsNullOrEmpty(MinecraftClientDll))
|
if (string.IsNullOrEmpty(MinecraftClientDll))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue