Revert "rework plugin type patch"
All checks were successful
Build / Compute Version (push) Successful in 8s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 4m12s
Build / Build Nuget package (NuGet) (push) Successful in 3m57s
Build / Build Nuget package (CringePlugins) (push) Successful in 5m8s
Build / Build Nuget package (SharedCringe) (push) Successful in 38m39s
Build / Build Launcher (push) Successful in 42m33s
All checks were successful
Build / Compute Version (push) Successful in 8s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 4m12s
Build / Build Nuget package (NuGet) (push) Successful in 3m57s
Build / Build Nuget package (CringePlugins) (push) Successful in 5m8s
Build / Build Nuget package (SharedCringe) (push) Successful in 38m39s
Build / Build Launcher (push) Successful in 42m33s
This reverts commit d4bf30a2
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
<Publicize Include="Sandbox.Game:Sandbox.Engine.Platform.Game.set_DrawThread" />
|
||||
<Publicize Include="Sandbox.Game:Sandbox.MySandboxGame.form" />
|
||||
<Publicize Include="Sandbox.Game:Sandbox.MySandboxGame.RenderThread_SizeChanged" />
|
||||
<Publicize Include="VRage.Render;VRage.Render11;VRage.Platform.Windows;VRage.Scripting;Sandbox.Game" IncludeCompilerGeneratedMembers="false" />
|
||||
<Publicize Include="VRage.Render;VRage.Render11;VRage.Platform.Windows;VRage.Scripting" IncludeCompilerGeneratedMembers="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -3,7 +3,7 @@ using HarmonyLib;
|
||||
using Sandbox.Game.World;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using VRage.Game;
|
||||
using System.Runtime.Loader;
|
||||
using VRage.Game.ObjectBuilder;
|
||||
using VRage.Plugins;
|
||||
|
||||
@@ -12,67 +12,40 @@ namespace CringeLauncher.Patches;
|
||||
[HarmonyPatch]
|
||||
internal static class PluginTypePatch
|
||||
{
|
||||
[HarmonyPatch(typeof(MyGlobalTypeMetadata), nameof(MyGlobalTypeMetadata.Init))]
|
||||
[HarmonyTranspiler]
|
||||
private static IEnumerable<CodeInstruction> MetadataTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
[HarmonyTargetMethods]
|
||||
public static IEnumerable<MethodInfo> TargetMethods()
|
||||
{
|
||||
return new CodeMatcher(instructions, generator)
|
||||
.SearchForward(b => b.opcode == OpCodes.Ldloc_2)
|
||||
.Advance(-1)
|
||||
.CreateLabel(out var regularPluginLabel)
|
||||
.DeclareLocal(typeof(PluginWrapper), out var wrapper)
|
||||
.DefineLabel(out var continueLabel)
|
||||
.Insert(new(OpCodes.Ldloc_2),
|
||||
new(OpCodes.Isinst, typeof(PluginWrapper)), new(OpCodes.Stloc, wrapper),
|
||||
new(OpCodes.Ldloc_S, wrapper),
|
||||
new(OpCodes.Brfalse_S, regularPluginLabel),
|
||||
new(OpCodes.Ldloc_0),
|
||||
new(OpCodes.Ldloc_S, wrapper),
|
||||
new(OpCodes.Call,
|
||||
AccessTools.PropertyGetter(typeof(PluginWrapper), nameof(PluginWrapper.InstanceType))),
|
||||
new(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Type), nameof(Type.Assembly))),
|
||||
CodeInstruction.Call(typeof(MyGlobalTypeMetadata), nameof(MyGlobalTypeMetadata.RegisterAssembly),
|
||||
[typeof(Assembly)]),
|
||||
new(OpCodes.Br_S, continueLabel))
|
||||
.SearchForward(b => b.opcode == OpCodes.Ldloca_S)
|
||||
.AddLabels([continueLabel])
|
||||
yield return AccessTools.Method(typeof(MySession), "RegisterComponentsFromAssemblies");
|
||||
yield return AccessTools.Method(typeof(MyGlobalTypeMetadata), nameof(MyGlobalTypeMetadata.Init));
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
|
||||
{
|
||||
//replaces plugin.GetType() with GetPluginType(plugin)
|
||||
var pve = AccessTools.Method(typeof(Assembly), nameof(Assembly.Load), [typeof(AssemblyName)]);
|
||||
var method = AccessTools.Method(typeof(object), nameof(GetType));
|
||||
var getter = AccessTools.PropertyGetter(typeof(MyPlugins), nameof(MyPlugins.Plugins));
|
||||
|
||||
|
||||
var matcher = new CodeMatcher(instructions);
|
||||
|
||||
if (original.DeclaringType == typeof(MySession))
|
||||
{
|
||||
matcher = matcher
|
||||
.SearchForward(b => b.Calls(pve))
|
||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PluginTypePatch), nameof(LoadAssembly)));
|
||||
}
|
||||
|
||||
return matcher
|
||||
.SearchForward(b => b.Calls(getter))
|
||||
.SearchForward(b => b.Calls(method))
|
||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PluginTypePatch), nameof(GetPluginType)))
|
||||
.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(MySession), "RegisterComponentsFromAssemblies")]
|
||||
[HarmonyPrefix]
|
||||
private static bool RegisterComponentsPrefix(MySession __instance)
|
||||
{
|
||||
__instance.m_componentsToLoad = [..__instance.GameDefinition.SessionComponents.Keys];
|
||||
__instance.m_componentsToLoad.ExceptWith(__instance.SessionComponentDisabled);
|
||||
__instance.m_componentsToLoad.UnionWith(__instance.SessionComponentEnabled);
|
||||
|
||||
__instance.RegisterComponentsFromAssembly(MyPlugins.SandboxAssembly);
|
||||
__instance.RegisterComponentsFromAssembly(MyPlugins.SandboxGameAssembly);
|
||||
__instance.RegisterComponentsFromAssembly(MyPlugins.GameAssembly);
|
||||
|
||||
foreach (var (context, ids) in __instance.ScriptManager.ScriptsPerMod)
|
||||
{
|
||||
foreach (var id in ids)
|
||||
{
|
||||
__instance.RegisterComponentsFromAssembly(__instance.ScriptManager.Scripts[id], true, context);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var plugin in MyPlugins.Plugins)
|
||||
{
|
||||
var type = plugin is PluginWrapper wrapper ? wrapper.InstanceType : plugin.GetType();
|
||||
|
||||
__instance.RegisterComponentsFromAssembly(type.Assembly, true);
|
||||
}
|
||||
|
||||
foreach (var component in __instance.m_sessionComponents.Values)
|
||||
{
|
||||
if (component.ModContext is null or { IsBaseGame: true })
|
||||
__instance.m_sessionComponentForDrawAsync.Add(component);
|
||||
else
|
||||
__instance.m_sessionComponentForDraw.Add(component);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//Assembly.Load is called in MySession.RegisterComponentsFromAssemblies. When patching, it uses the wrong context
|
||||
//todo: maybe there's a better way to do this?
|
||||
private static Assembly LoadAssembly(AssemblyName name) => AssemblyLoadContext.GetLoadContext(typeof(Launcher).Assembly)!.LoadFromAssemblyName(name);
|
||||
private static Type GetPluginType(IPlugin plugin) => plugin is PluginWrapper wrapper ? wrapper.InstanceType : plugin.GetType();
|
||||
}
|
||||
|
Reference in New Issue
Block a user