public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions); int minus1OpIndex = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Ldc_I4_M1), 0); //check index and previous instruction if (minus1OpIndex != -1 && codes[minus1OpIndex + 1].opcode.Equals(OpCodes.Bne_Un)) { int ldArg0Index = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Ldarg_0), minus1OpIndex); //check index and previous instruction if (ldArg0Index != -1 && codes[ldArg0Index - 1].opcode.Equals(OpCodes.Stfld)) { int targetIndex = minus1OpIndex + 2;//move index to first item to remove // replace all instruction between targetIndex and Ldarg_0 codes.RemoveRange(targetIndex, ldArg0Index - targetIndex); codes.InsertRange(targetIndex, GetReplacementInstructions()); } else { throw new Exception("Could not found Ldarg_0 Instruction or instruction was already patched!"); } } else { throw new Exception("Could not found Ldc_I4_M1 Instruction or previous instruction was already patched!"); } return(codes); }
public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions); int minus1OpIndex = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Ldc_I4_M1), 0); //check index and previous instruction if (minus1OpIndex != -1 && codes[minus1OpIndex + 1].opcode.Equals(OpCodes.Bne_Un)) { int ldArg0Index = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Ldarg_0), minus1OpIndex); //check index and previous instruction if (ldArg0Index != -1 && codes[ldArg0Index - 1].opcode.Equals(OpCodes.Stfld)) { int targetIndex = minus1OpIndex + 2;//move index to first item to remove // replace all instruction between targetIndex and Ldarg_0 codes.RemoveRange(targetIndex, ldArg0Index - targetIndex); var newInstructions = new[] { new CodeInstruction(OpCodes.Ldarg_1), // load node id new CodeInstruction(OpCodes.Call, typeof(ClickNodeButtonPatch).GetMethod(nameof(ClickNodeButtonPatch.ToggleTrafficLight))), }; codes.InsertRange(targetIndex, newInstructions); } else { throw new Exception("Could not found Ldarg_0 Instruction or instruction was already patched!"); } } else { throw new Exception("Could not found Ldc_I4_M1 Instruction or previous instruction was already patched!"); } return(codes); }
public static IEnumerable <CodeInstruction> Transpiler(ILGenerator il, IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions); int searchInstruction = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Call, CheckSegmentProblemsMethod()), 0, 1, 3); if (searchInstruction != -1 && codes[searchInstruction + 1].opcode.Equals(OpCodes.Ldc_I4_1) && codes[searchInstruction + 2].opcode.Equals(OpCodes.Ret)) { int startTarget = searchInstruction + 3; //first instruction to remove, contains labels to copy int createPathCallIndex = TranspilerUtil.SearchInstruction(codes, new CodeInstruction(OpCodes.Callvirt, CreatePathMethod()), startTarget); if (createPathCallIndex != -1 && codes[createPathCallIndex + 1].opcode.Equals(OpCodes.Brfalse)) { List <Label> labels = codes[startTarget].labels; codes.RemoveRange(startTarget, createPathCallIndex + 1 - startTarget); codes.InsertRange(startTarget, GetInjectInstructions(labels)); } else { throw new Exception("Could not find CreatePath call or instructions has been patched"); } } else { throw new Exception("Could not find 3rd. CheckSegmentProblems call or instructions has been patched"); } return(codes); }