diff --git a/SiraUtil/Affinity/Harmony/Generator/DynamicHarmonyPatchGenerator.cs b/SiraUtil/Affinity/Harmony/Generator/DynamicHarmonyPatchGenerator.cs index 71bddac..1be74a9 100644 --- a/SiraUtil/Affinity/Harmony/Generator/DynamicHarmonyPatchGenerator.cs +++ b/SiraUtil/Affinity/Harmony/Generator/DynamicHarmonyPatchGenerator.cs @@ -69,7 +69,10 @@ public MethodInfo Patch(IAffinity affinity, MethodInfo affinityMethod, AffinityP Type[]? types = null; if (patch.ArgumentTypes is not null && patch.ArgumentTypes.Length != 0) + { types = patch.ArgumentTypes; + ParseSpecialArguments(types, patch.ArgumentVariations); + } MethodBase originalMethod = patch.MethodType switch { @@ -154,6 +157,35 @@ public void Unpatch(MethodInfo contract) } } + // adapted from https://github.com/pardeike/Harmony/blob/77d37bee5bffd053681b34ba70a650d6d2d45486/Harmony/Public/Attributes.cs#L335-L366 + private void ParseSpecialArguments(Type[] argumentTypes, ArgumentType[]? argumentVariations) + { + if (argumentVariations is null || argumentVariations.Length == 0) + { + return; + } + + if (argumentTypes.Length < argumentVariations.Length) + { + throw new ArgumentException("argumentVariations contains more elements than argumentTypes", nameof(argumentVariations)); + } + + for (var i = 0; i < argumentTypes.Length; i++) + { + var type = argumentTypes[i]; + switch (argumentVariations[i]) + { + case ArgumentType.Ref: + case ArgumentType.Out: + argumentTypes[i] = type.MakeByRefType(); + break; + case ArgumentType.Pointer: + argumentTypes[i] = type.MakePointerType(); + break; + } + } + } + // https://stackoverflow.com/questions/9505117/creating-delegates-dynamically-with-parameter-names private Type CreateDelegateType(MethodInfo method) {