Advertisement
Ameisen

Untitled

May 13th, 2022
874
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. [HarmonizeTranspile(
  2.     type: typeof(XTexture2D),
  3.     "PlatformSetData",
  4.     argumentTypes: new[] { typeof(int), typeof(Array), typeof(int), typeof(int) },
  5.     generic: Generic.Struct,
  6.     platform: Platform.MonoGame
  7. )]
  8. public static IEnumerable<CodeInstruction> PlatformSetDataTranspiler<T>(IEnumerable<CodeInstruction> instructions, ILGenerator generator) where T : unmanaged {
  9.     static bool HasParameters(MethodInfo method) {
  10.         var parameters = method.GetParameters().Types();
  11.  
  12.         return
  13.             parameters.ElementAtOrDefaultF(0) == typeof(XTexture2D) &&
  14.             parameters.ElementAtOrDefaultF(1) == typeof(int) &&
  15.             (parameters.ElementAtOrDefaultF(2)?.IsAssignableTo(typeof(Array)) ?? false) &&
  16.             parameters.ElementAtOrDefaultF(3) == typeof(int) &&
  17.             parameters.ElementAtOrDefaultF(4) == typeof(int);
  18.     }
  19.  
  20.     var preMethod = typeof(PTexture2D).GetMethods(
  21.         name: "OnPlatformSetDataPre",
  22.         bindingFlags: BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public
  23.     ).FirstF(HasParameters)?.MakeGenericMethod(typeof(T));
  24.  
  25.     if (preMethod is null) {
  26.         Debug.Error("Could not apply PlatformSetData patch: could not find MethodInfo for OnPlatformSetDataPre");
  27.         return instructions;
  28.     }
  29.  
  30.     var postMethod = typeof(PTexture2D).GetMethods(
  31.         name: "OnPlatformSetDataPost",
  32.         bindingFlags: BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public
  33.     ).FirstF(HasParameters)?.MakeGenericMethod(typeof(T));
  34.  
  35.     if (postMethod is null) {
  36.         Debug.Error("Could not apply PlatformSetData patch: could not find MethodInfo for OnPlatformSetDataPost");
  37.         return instructions;
  38.     }
  39.  
  40.     var codeInstructions = instructions as CodeInstruction[] ?? instructions.ToArray();
  41.  
  42.     IEnumerable<CodeInstruction> ApplyPatch() {
  43.         var earlyReturn = generator.DefineLabel();
  44.         var postCall = generator.DefineLabel();
  45.  
  46.         yield return new(OpCodes.Ldarg_0);
  47.         yield return new(OpCodes.Ldarg_1);
  48.         yield return new(OpCodes.Ldarg_2);
  49.         yield return new(OpCodes.Ldarg_3);
  50.         yield return new(OpCodes.Ldarg, 4);
  51.         yield return new(OpCodes.Call, preMethod);
  52.  
  53.         yield return new(OpCodes.Brfalse_S, earlyReturn);
  54.  
  55.  
  56.         foreach (var instruction in codeInstructions) {
  57.             if (instruction == codeInstructions.LastF()) {
  58.                 yield return new(OpCodes.Ldarg_0) { labels = { postCall } };
  59.                 yield return new(OpCodes.Ldarg_1);
  60.                 yield return new(OpCodes.Ldarg_2);
  61.                 yield return new(OpCodes.Ldarg_3);
  62.                 yield return new(OpCodes.Ldarg, 4);
  63.                 yield return new(OpCodes.Call, postMethod);
  64.  
  65.                 instruction.labels.Add(earlyReturn);
  66.                 yield return instruction;
  67.             }
  68.             else if (instruction.opcode.Value == OpCodes.Ret.Value) {
  69.                 yield return new(OpCodes.Jmp, postCall);
  70.             }
  71.             else {
  72.                 yield return instruction;
  73.             }
  74.         }
  75.     }
  76.  
  77.     return ApplyPatch();
  78. }
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement