Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [HarmonizeTranspile(
- type: typeof(XTexture2D),
- "PlatformSetData",
- argumentTypes: new[] { typeof(int), typeof(Array), typeof(int), typeof(int) },
- generic: Generic.Struct,
- platform: Platform.MonoGame
- )]
- public static IEnumerable<CodeInstruction> PlatformSetDataTranspiler<T>(IEnumerable<CodeInstruction> instructions, ILGenerator generator) where T : unmanaged {
- static bool HasParameters(MethodInfo method) {
- var parameters = method.GetParameters().Types();
- return
- parameters.ElementAtOrDefaultF(0) == typeof(XTexture2D) &&
- parameters.ElementAtOrDefaultF(1) == typeof(int) &&
- (parameters.ElementAtOrDefaultF(2)?.IsAssignableTo(typeof(Array)) ?? false) &&
- parameters.ElementAtOrDefaultF(3) == typeof(int) &&
- parameters.ElementAtOrDefaultF(4) == typeof(int);
- }
- var preMethod = typeof(PTexture2D).GetMethods(
- name: "OnPlatformSetDataPre",
- bindingFlags: BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public
- ).FirstF(HasParameters)?.MakeGenericMethod(typeof(T));
- if (preMethod is null) {
- Debug.Error("Could not apply PlatformSetData patch: could not find MethodInfo for OnPlatformSetDataPre");
- return instructions;
- }
- var postMethod = typeof(PTexture2D).GetMethods(
- name: "OnPlatformSetDataPost",
- bindingFlags: BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public
- ).FirstF(HasParameters)?.MakeGenericMethod(typeof(T));
- if (postMethod is null) {
- Debug.Error("Could not apply PlatformSetData patch: could not find MethodInfo for OnPlatformSetDataPost");
- return instructions;
- }
- var codeInstructions = instructions as CodeInstruction[] ?? instructions.ToArray();
- IEnumerable<CodeInstruction> ApplyPatch() {
- var earlyReturn = generator.DefineLabel();
- var postCall = generator.DefineLabel();
- yield return new(OpCodes.Ldarg_0);
- yield return new(OpCodes.Ldarg_1);
- yield return new(OpCodes.Ldarg_2);
- yield return new(OpCodes.Ldarg_3);
- yield return new(OpCodes.Ldarg, 4);
- yield return new(OpCodes.Call, preMethod);
- yield return new(OpCodes.Brfalse_S, earlyReturn);
- foreach (var instruction in codeInstructions) {
- if (instruction == codeInstructions.LastF()) {
- yield return new(OpCodes.Ldarg_0) { labels = { postCall } };
- yield return new(OpCodes.Ldarg_1);
- yield return new(OpCodes.Ldarg_2);
- yield return new(OpCodes.Ldarg_3);
- yield return new(OpCodes.Ldarg, 4);
- yield return new(OpCodes.Call, postMethod);
- instruction.labels.Add(earlyReturn);
- yield return instruction;
- }
- else if (instruction.opcode.Value == OpCodes.Ret.Value) {
- yield return new(OpCodes.Jmp, postCall);
- }
- else {
- yield return instruction;
- }
- }
- }
- return ApplyPatch();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement