// 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);
        }
Exemplo n.º 2
0
        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);
        }