Ejemplo n.º 1
0
        public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> codes             = TranspilerUtil.ToCodeList(instructions);
            MethodInfo             calcStopPosAndDir = typeof(NetLane).GetMethod(nameof(NetLane.CalculateStopPositionAndDirection));

            CodeInstruction searchInstr = new CodeInstruction(OpCodes.Call, calcStopPosAndDir);
            int             index       = codes.FindIndex(instr => TranspilerUtil.IsSameInstruction(instr, searchInstr));

            if (index > -1)
            {
                int targetIndex     = index + 1;
                int replace1stIndex = targetIndex + 3;
                if (codes[replace1stIndex].opcode.Equals(OpCodes.Ldarg_2))
                {
                    codes.RemoveRange(replace1stIndex + 1, 6);
                    codes.Insert(replace1stIndex + 1, new CodeInstruction(OpCodes.Ldloc_3));
                }
                else
                {
                    throw new Exception("Could not find Ldarg.2 instruction or instructions has been patched");
                }
                codes.InsertRange(targetIndex, GetInstructions());
            }
            else
            {
                throw new Exception("Could not find CalculateStopPositionAndDirection call or instructions has been patched");
            }

            return(codes);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Revrites instructions adding necessary TMPE calls
        /// </summary>
        /// <param name="il"> Il Generator</param>
        /// <param name="instructions">List of instructions</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static IEnumerable <CodeInstruction> TranspileTramTrainSimulationStep(ILGenerator il, IEnumerable <CodeInstruction> instructions)
        {
            List <CodeInstruction> codes = TranspilerUtil.ToCodeList(instructions);

            MethodBase trySpawnCall = TranspilerUtil.DeclaredMethod <TrySpawnDelegate>(typeof(VehicleAI), "TrySpawn");

            CodeInstruction searchInstruction = new CodeInstruction(OpCodes.Callvirt, trySpawnCall);
            int             index             = codes.FindIndex(instruction => TranspilerUtil.IsSameInstruction(instruction, searchInstruction));

            if (index > -1)
            {
                int          target1   = index + 2;
                Label        label     = il.DefineLabel();
                List <Label> oldLabels = codes[target1].labels.ToList();
                codes[target1].labels.Clear();                 // clear labels -> they are moved to new instruction
                codes[target1].labels.Add(label);              //add label to next instruction (if() false jump)
                List <CodeInstruction> newInstructions = GetUpdatePositionInstructions(label);
                newInstructions[0].labels.AddRange(oldLabels); // add old labels to redirect here
                codes.InsertRange(target1, newInstructions);   // insert new instructions

                CodeInstruction searchInstruction2 = new CodeInstruction(OpCodes.Ldfld, typeof(Vehicle).GetField(nameof(Vehicle.m_blockCounter)));
                int             index2             = codes.FindIndex(instruction => TranspilerUtil.IsSameInstruction(instruction, searchInstruction2));
                if (index2 > -1 && codes[index2 + 1].opcode.Equals(OpCodes.Ldc_I4) && codes[index2 + 2].opcode.Equals(OpCodes.Bne_Un))
                {
                    int   target2  = index2 + 2;
                    Label retLabel = (Label)codes[target2].operand;
                    codes.InsertRange(target2 + 1, GetModifiedBlockCounterInstructions(retLabel));
                }
                else
                {
                    throw new Exception("Could not find m_blockCounter field usage or instructions has been patched");
                }
            }
            else
            {
                throw new Exception("Could not find TrySpawn call or instructions has been patched");
            }

            return(codes);
        }