// code from: https://github.com/Strdate/SmartIntersections/blob/master/SmartIntersections/Patch/LoadPathsPatch.cs public static IEnumerable <CodeInstruction> Transpiler(ILGenerator il, IEnumerable <CodeInstruction> instructions) { var fTempNodeBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempNodeBuffer)) ?? throw new Exception("cound not find NetManager.m_tempNodeBuffer"); var mClear = AccessTools.DeclaredMethod(fTempNodeBuffer.FieldType, nameof(FastList <ushort> .Clear)) ?? throw new Exception("cound not find m_tempNodeBuffer.Clear"); var mAfterIntersectionBuilt = AccessTools.DeclaredMethod( typeof(LoadPathsPatch), nameof(AfterIntersectionBuilt)) ?? throw new Exception("cound not find AfterIntersectionBuilt()"); List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions); bool comp(int i) => codes[i].opcode == OpCodes.Ldfld && codes[i].operand == fTempNodeBuffer && codes[i + 1].opcode == OpCodes.Callvirt && codes[i + 1].operand == mClear; int index = TranspilerUtil.SearchGeneric(codes, comp, index: 0, counter: 2); index -= 1; // index to insert instructions. var newInstructions = new[] { new CodeInstruction(OpCodes.Ldarg_0), // load argument info new CodeInstruction(OpCodes.Call, mAfterIntersectionBuilt), }; TranspilerUtil.InsertInstructions(codes, newInstructions, index); return(codes); }
public static IEnumerable <CodeInstruction> Transpiler(ILGenerator il, IEnumerable <CodeInstruction> instructions) { var fTempSegmentBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempSegmentBuffer)) ?? throw new Exception("Could not find NetManager.m_tempSegmentBuffer"); var mSize = AccessTools.DeclaredField(fTempSegmentBuffer.FieldType, nameof(FastList <ushort> .m_size)) ?? throw new Exception("Could not find m_tempSegmentBuffer.m_size"); var mAfterIntersectionBuilt = AccessTools.DeclaredMethod( typeof(LoadPathsPatch), nameof(AfterIntersectionBuilt)) ?? throw new Exception("Could not find AfterIntersectionBuilt()"); List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions); bool predicate(int i) => codes[i].opcode == OpCodes.Blt && codes[i - 1].opcode == OpCodes.Ldfld && codes[i - 1].operand == mSize && codes[i - 2].opcode == OpCodes.Ldfld && codes[i - 2].operand == fTempSegmentBuffer; int index = TranspilerUtil.SearchGeneric(codes, predicate, index: 0, counter: 1); index += 1; // index to insert instructions. (end of the loop) var newInstructions = new[] { new CodeInstruction(OpCodes.Ldarg_0), // load argument info new CodeInstruction(OpCodes.Call, mAfterIntersectionBuilt), }; TranspilerUtil.InsertInstructions(codes, newInstructions, index); return(codes); }