Describe the bug
When Transpiling using BepInEx and HarmonyX, I encounter an error at runtime complaining that System.Reflection.Emit.ILGeneration could not be found near the use of LocalBuilder and CodeInstruction.IsStLoc.
To Reproduce
Steps to reproduce the behavior:
The original method and its signature and class:
namespace Assets.Scripts.Objects.Items
{
public class Stackable : Item, IQuantity
{
public virtual void SplitStack(Interaction interaction, int quantity);
}
}
The patch code:
using Assets.Scripts.Objects.Items;
[HarmonyPatch(typeof(Stackable), "SplitStack")]
public class Stackable_SplitStack
{
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insnsIter)
{
foreach(var insn in insnsIter)
{
if (insn.IsStloc())
{
if (insn.operand is LocalBuilder stackableVar)
{
...
The output of the Harmony debug log
See below
The stacktrace or other errors:
[Error : HarmonyX] Failed to patch virtual void Assets.Scripts.Objects.Items.Stackable::SplitStack(Assets.Scripts.Objects.Interaction interaction, int quantity): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeLoadException: Could not load type of field 'MyMod.Stackable_SplitStack+<Transpiler>d__1:<stackableVar>5__5' (9) due to: Could not load file or assembly 'System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. assembly:System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:<unknown type> member:(null) signature:<none>
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <695d1cc93cca45069c528c15c9fdd749>:0
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00048] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at HarmonyLib.Internal.Patching.ILManipulator.ApplyTranspilers (System.Reflection.Emit.ILGenerator il, System.Reflection.MethodBase original, System.Func`2[T,TResult] getLocal, System.Func`1[TResult] defineLabel) [0x00093] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Internal.Patching.ILManipulator.WriteTo (Mono.Cecil.Cil.MethodBody body, System.Reflection.MethodBase original) [0x00066] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.HarmonyManipulator.WriteTranspiledMethod (MonoMod.Cil.ILContext ctx, System.Reflection.MethodBase original, System.Collections.Generic.List`1[T] transpilers, System.Boolean debug) [0x00073] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.HarmonyManipulator.MakePatched (System.Reflection.MethodBase original, MonoMod.Cil.ILContext ctx, System.Collections.Generic.List`1[T] prefixes, System.Collections.Generic.List`1[T] postfixes, System.Collections.Generic.List`1[T] transpilers, System.Collections.Generic.List`1[T] finalizers, System.Collections.Generic.List`1[T] ilmanipulators, System.Boolean debug) [0x0003b] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
TypeLoadException: Could not load type of field 'MyMod.Stackable_SplitStack+<Transpiler>d__1:<stackableVar>5__5' (9) due to: Could not load file or assembly 'System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. assembly:System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:<unknown type> member:(null) signature:<none>
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <695d1cc93cca45069c528c15c9fdd749>:0
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00048] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at HarmonyLib.Internal.Patching.ILManipulator.ApplyTranspilers (System.Reflection.Emit.ILGenerator il, System.Reflection.MethodBase original, System.Func`2[T,TResult] getLocal, System.Func`1[TResult] defineLabel) [0x00093] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Internal.Patching.ILManipulator.WriteTo (Mono.Cecil.Cil.MethodBody body, System.Reflection.MethodBase original) [0x00066] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.HarmonyManipulator.WriteTranspiledMethod (MonoMod.Cil.ILContext ctx, System.Reflection.MethodBase original, System.Collections.Generic.List`1[T] transpilers, System.Boolean debug) [0x00073] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.HarmonyManipulator.MakePatched (System.Reflection.MethodBase original, MonoMod.Cil.ILContext ctx, System.Collections.Generic.List`1[T] prefixes, System.Collections.Generic.List`1[T] postfixes, System.Collections.Generic.List`1[T] transpilers, System.Collections.Generic.List`1[T] finalizers, System.Collections.Generic.List`1[T] ilmanipulators, System.Boolean debug) [0x0003b] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
Rethrow as HarmonyException: IL Compile Error (unknown location)
at HarmonyLib.Public.Patching.HarmonyManipulator.MakePatched (System.Reflection.MethodBase original, MonoMod.Cil.ILContext ctx, System.Collections.Generic.List`1[T] prefixes, System.Collections.Generic.List`1[T] postfixes, System.Collections.Generic.List`1[T] transpilers, System.Collections.Generic.List`1[T] finalizers, System.Collections.Generic.List`1[T] ilmanipulators, System.Boolean debug) [0x002a8] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.HarmonyManipulator.Manipulate (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo, MonoMod.Cil.ILContext ctx) [0x00051] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Public.Patching.ManagedMethodPatcher.Manipulator (MonoMod.Cil.ILContext ctx) [0x0001d] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at MonoMod.Cil.ILContext.Invoke (MonoMod.Cil.ILContext+Manipulator manip) [0x00087] in <5be58f3c80ca41c4960cf35eb47d4341>:0
at MonoMod.RuntimeDetour.ILHook+Context.InvokeManipulator (Mono.Cecil.MethodDefinition def, MonoMod.Cil.ILContext+Manipulator cb) [0x00012] in <a3e7db5d9f924acea1a3fada3479a63b>:0
at (wrapper dynamic-method) MonoMod.RuntimeDetour.ILHook+Context.DMD<MonoMod.RuntimeDetour.ILHook+Context::Refresh>(MonoMod.RuntimeDetour.ILHook/Context)
at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Trampoline<MonoMod.RuntimeDetour.ILHook+Context::Refresh>?274797568(object)
at HarmonyLib.Internal.RuntimeFixes.StackTraceFixes.OnILChainRefresh (System.Object self) [0x00000] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at MonoMod.RuntimeDetour.ILHook.Apply () [0x00059] in <a3e7db5d9f924acea1a3fada3479a63b>:0
at HarmonyLib.Public.Patching.ManagedMethodPatcher.DetourTo (System.Reflection.MethodBase replacement) [0x00047] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
Rethrow as HarmonyException: IL Compile Error (unknown location)
at HarmonyLib.Public.Patching.ManagedMethodPatcher.DetourTo (System.Reflection.MethodBase replacement) [0x0005f] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo) [0x00033] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
Rethrow as HarmonyException: IL Compile Error (unknown location)
at HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) [0x00045] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.PatchClassProcessor.Patch () [0x00084] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Harmony.<PatchAll>b__11_0 (System.Type type) [0x00007] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00014] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Harmony.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at HarmonyLib.Harmony.PatchAll () [0x0001b] in <7f26c0a74c5b43c2a5fc5efd29ec63d6>:0
at MyMod.Plugin.Awake () [0x00029] in <db3587d50c3340b9b774b44a545dc379>:0
Expected behavior
I expect the above use of LocalBuilder and CodeInstruction.IsStLoc to transpile without error.
Additional context
After experiencing this error, I assumed the game's runtime did not provide the System.Reflection.Emit.ILGeneration library, so I tried downloading it from Nuget (System.Reflection.Emit.ILGeneration==4.7.0) and stashing the ILGeneration DLL along with the output DLL under BepInEx\plugins. Then I received a new "missing method exception" for the usage of IsStloc, shown below.
Describe the bug When Transpiling using BepInEx and HarmonyX, I encounter an error at runtime complaining that
System.Reflection.Emit.ILGeneration
could not be found near the use ofLocalBuilder
andCodeInstruction.IsStLoc
.To Reproduce Steps to reproduce the behavior:
See below
Expected behavior I expect the above use of
LocalBuilder
andCodeInstruction.IsStLoc
to transpile without error.Build environment:
Runtime environment:
Assembly-CSharp.dll
)Additional context After experiencing this error, I assumed the game's runtime did not provide the
System.Reflection.Emit.ILGeneration
library, so I tried downloading it from Nuget (System.Reflection.Emit.ILGeneration==4.7.0
) and stashing the ILGeneration DLL along with the output DLL underBepInEx\plugins
. Then I received a new "missing method exception" for the usage ofIsStloc
, shown below.I'm sort of stuck on how to work around this or what the issue is.