
All checks were successful
Release / Get Version (push) Successful in 8s
Release / Build and Publish Nuget (Torch.API) (push) Successful in 59s
Release / Build and Publish Nuget (Torch) (push) Successful in 1m13s
Release / Build and Publish Nuget (Torch.Server) (push) Successful in 1m22s
Release / Build and Publish Package (push) Successful in 1m54s
118 lines
5.5 KiB
C#
118 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using HarmonyLib;
|
|
using Microsoft.CodeAnalysis;
|
|
using Torch.Managers.PatchManager;
|
|
using Torch.Managers.PatchManager.MSIL;
|
|
using Torch.Utils;
|
|
using VRage.FileSystem;
|
|
using VRage.Scripting;
|
|
|
|
namespace Torch.Patches
|
|
{
|
|
[PatchShim]
|
|
public static class ScriptCompilerPatch
|
|
{
|
|
[ReflectedMethodInfo(typeof(MyScriptWhitelist), "Register", Parameters = [typeof(MyWhitelistTarget), typeof(INamespaceSymbol), typeof(Type)])]
|
|
private static MethodInfo _register1Method;
|
|
|
|
[ReflectedMethodInfo(typeof(MyScriptWhitelist), "Register", Parameters = [typeof(MyWhitelistTarget), typeof(ITypeSymbol), typeof(Type)])]
|
|
private static MethodInfo _register2Method;
|
|
|
|
[ReflectedMethodInfo(null, "AllowMembers", TypeName = "VRage.Scripting.MyScriptWhitelist+MyWhitelistBatch, VRage.Scripting")]
|
|
private static MethodInfo _allowMembersMethod;
|
|
|
|
[ReflectedMethodInfo(null, "ResolveTypeSymbol", TypeName = "VRage.Scripting.MyScriptWhitelist+Batch, VRage.Scripting")]
|
|
private static MethodInfo _resolveTypeSymbolMethod;
|
|
|
|
public static void Patch(PatchContext context)
|
|
{
|
|
context.GetPattern(typeof(MyScriptWhitelist).GetConstructor([typeof(MyScriptCompiler)]))
|
|
.AddPrefix(nameof(WhitelistCtorPrefix));
|
|
context.GetPattern(Info.OfMethod("VRage.Scripting", "VRage.Scripting.MyVRageScriptingInternal", "Initialize"))
|
|
.AddPrefix(nameof(InitializePrefix));
|
|
context.GetPattern(_allowMembersMethod).AddPrefix(nameof(AllowMembersPrefix));
|
|
|
|
var harmony = new Harmony(nameof(ScriptCompilerPatch));
|
|
|
|
harmony.Patch(_allowMembersMethod, finalizer: new(typeof(ScriptCompilerPatch), nameof(RegisterFinalizer)));
|
|
harmony.Patch(_register1Method, finalizer: new(typeof(ScriptCompilerPatch), nameof(RegisterFinalizer)));
|
|
harmony.Patch(_register2Method, finalizer: new(typeof(ScriptCompilerPatch), nameof(RegisterFinalizer)));
|
|
harmony.Patch(_resolveTypeSymbolMethod, finalizer: new(typeof(ScriptCompilerPatch), nameof(RegisterFinalizer)));
|
|
}
|
|
|
|
private static void WhitelistCtorPrefix(MyScriptCompiler scriptCompiler)
|
|
{
|
|
var baseDir = new FileInfo(typeof(Type).Assembly.Location).DirectoryName!;
|
|
var binDir =
|
|
#if DEBUG
|
|
baseDir;
|
|
#else
|
|
Path.Join(AppContext.BaseDirectory, "torch64");
|
|
#endif
|
|
|
|
scriptCompiler.AddReferencedAssemblies(
|
|
typeof(Type).Assembly.Location,
|
|
typeof(LinkedList<>).Assembly.Location,
|
|
typeof(Regex).Assembly.Location,
|
|
typeof(Enumerable).Assembly.Location,
|
|
typeof(ConcurrentBag<>).Assembly.Location,
|
|
typeof(ImmutableArray).Assembly.Location,
|
|
typeof(PropertyChangedEventArgs).Assembly.Location,
|
|
typeof(TypeConverter).Assembly.Location,
|
|
typeof(System.Diagnostics.TraceSource).Assembly.Location,
|
|
typeof(System.Security.Policy.Evidence).Assembly.Location,
|
|
Path.Join(binDir, "System.Xml.ReaderWriter.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "ProtoBuf.Net.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "ProtoBuf.Net.Core.dll"),
|
|
Path.Join(binDir, "netstandard.dll"),
|
|
Path.Join(baseDir, "System.Runtime.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "Sandbox.Game.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "Sandbox.Common.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "Sandbox.Graphics.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.Library.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.Math.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.Game.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.Render.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "VRage.Input.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "SpaceEngineers.ObjectBuilders.dll"),
|
|
Path.Join(MyFileSystem.ExePath, "SpaceEngineers.Game.dll"));
|
|
}
|
|
|
|
private static bool InitializePrefix(Thread updateThread, Type[] referencedTypes, string[] symbols)
|
|
{
|
|
MyModWatchdog.Init(updateThread);
|
|
MyScriptCompiler.Static.AddImplicitIngameNamespacesFromTypes(referencedTypes);
|
|
MyScriptCompiler.Static.AddConditionalCompilationSymbols(symbols);
|
|
|
|
using var batch = MyScriptCompiler.Static.Whitelist.OpenBatch();
|
|
batch.AllowTypes(MyWhitelistTarget.ModApi, typeof(ConcurrentQueue<>));
|
|
batch.AllowNamespaceOfTypes(MyWhitelistTarget.Both, typeof(ImmutableArray));
|
|
|
|
return false;
|
|
}
|
|
|
|
[SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")]
|
|
private static void AllowMembersPrefix(ref MemberInfo[] members)
|
|
{
|
|
if (members.Any(b => b is null))
|
|
members = members.Where(b => b is { }).ToArray();
|
|
}
|
|
|
|
private static Exception RegisterFinalizer(Exception __exception)
|
|
{
|
|
return __exception is MyWhitelistException ? null : __exception;
|
|
}
|
|
}
|
|
} |