コード例 #1
0
        private static IEnumerable <CodeInstruction> Transpiler(ILGenerator generator, IEnumerable <CodeInstruction> original)
        {
            bool inject                    = false;
            bool injectedPostBranch        = false;
            bool injectedPreClearGatesDone = false;

            int GatesDoneCount = 0;

            Stack <Label> prevJumps = new Stack <Label>();

            foreach (var item in original)
            {
                if (inject)
                {
                    inject = false;

                    CodeInstruction[] inst = SuspendableWireManager.MakeSuspendSnippet(generator, SuspendableWireManager.SuspendMode.perStage);

                    foreach (var item2 in inst)
                    {
                        //ErrorLogger.Log(item2);
                        yield return(item2);
                    }
                }

                //We want to inject after the end of the first loop at IL_0045
                if (!injectedPostBranch && (item.opcode == OpCodes.Bgt || item.opcode == OpCodes.Bgt_S))
                {
                    injectedPostBranch = true;
                    inject             = true;
                }

                //We also need to put one on the end before IL_00D7
                if (!injectedPreClearGatesDone && item.opcode == OpCodes.Ldsfld)
                {
                    FieldInfo SetField = item.operand as FieldInfo;
                    if (SetField != null && SetField.Name == "_GatesDone")
                    {
                        if (++GatesDoneCount == 4)
                        {
                            injectedPreClearGatesDone = true;
                            inject = true;
                        }
                    }
                }

                if (item.opcode == OpCodes.Brfalse || item.opcode == OpCodes.Brfalse_S)
                {
                    prevJumps.Push((Label)item.operand);
                }

                //ErrorLogger.Log(item);
                yield return(item);
            }
        }
コード例 #2
0
ファイル: HitWirePatch.cs プロジェクト: DRKV333/MechScope
        public static IEnumerable <CodeInstruction> Transpiler(ILGenerator generator, IEnumerable <CodeInstruction> original)
        {
            bool injectPostHitWireSingle = false;

            foreach (var item in original)
            {
                if (injectPostHitWireSingle)
                {
                    injectPostHitWireSingle = false;

                    CodeInstruction[] inst = SuspendableWireManager.MakeSuspendSnippet(generator, SuspendableWireManager.SuspendMode.perSingle);

                    //The end of a branch is in front, but we want to be outside if it.
                    inst[0].labels = new List <Label>(item.labels);
                    item.labels.Clear();

                    foreach (var item2 in inst)
                    {
                        //ErrorLogger.Log(item2);
                        yield return(item2);
                    }
                }

                //Inject code after call to HitWireSingle at IL_0085
                if (item.opcode == OpCodes.Call)
                {
                    MethodInfo calledMethod = item.operand as MethodInfo;
                    if (calledMethod != null && calledMethod.Name == "HitWireSingle")
                    {
                        injectPostHitWireSingle = true;
                    }
                }

                //ErrorLogger.Log(item);
                yield return(item);
            }
        }
コード例 #3
0
        public static IEnumerable <CodeInstruction> Transpiler(ILGenerator generator, IEnumerable <CodeInstruction> instructions)
        {
            bool injectPostWire         = false;
            int  postWireCount          = 0;
            bool injectedGrabTeleporter = false;

            Stack <Label> prevJumps = new Stack <Label>();

            foreach (var item in instructions)
            {
                if (injectPostWire)
                {
                    injectPostWire = false;
                    postWireCount++;

                    CodeInstruction[] inst = SuspendableWireManager.MakeSuspendSnippet(generator, SuspendableWireManager.SuspendMode.perWire);

                    //We want to be inside of the Wiring._wireList.Count > 0 branch, but outside of the XferWater branch
                    Label XferWaterLabel1 = prevJumps.Pop();
                    Label XferWaterLabel2 = prevJumps.Pop();
                    item.labels.Remove(XferWaterLabel1);
                    item.labels.Remove(XferWaterLabel2);
                    inst[0].labels.Add(XferWaterLabel1);
                    inst[0].labels.Add(XferWaterLabel2);

                    foreach (var item2 in inst)
                    {
                        //ErrorLogger.Log(item2);
                        yield return(item2);
                    }
                }

                if (postWireCount == 4)
                {
                    postWireCount = 0;

                    CodeInstruction[] inst = SuspendableWireManager.MakeSuspendSnippet(generator, SuspendableWireManager.SuspendMode.perSource);

                    //The end of a branch is in front, but we want to be outside if it.
                    inst[0].labels = new List <Label>(item.labels);
                    item.labels.Clear();

                    foreach (var item2 in inst)
                    {
                        //ErrorLogger.Log(item2);
                        yield return(item2);
                    }
                }

                //Before assigning the local that stores the teleporters queued for triggering, we want to exfiltrate it to the visualizer.
                if (!injectedGrabTeleporter && item.opcode == OpCodes.Stloc_0)
                {
                    injectedGrabTeleporter = true;

                    yield return(new CodeInstruction(OpCodes.Dup));

                    yield return(new CodeInstruction(OpCodes.Call, typeof(VisualizerWorld).GetMethod("ReportTeleporterArray")));
                }

                //Inject code after call to XferWater at IL_011A, IL_022B, IL_033C and IL_044D
                if (item.opcode == OpCodes.Call)
                {
                    MethodInfo calledMethod = item.operand as MethodInfo;
                    if (calledMethod != null && calledMethod.Name == "XferWater")
                    {
                        injectPostWire = true;
                    }
                }

                if (item.opcode == OpCodes.Ble || item.opcode == OpCodes.Ble_S)
                {
                    prevJumps.Push((Label)item.operand);
                }

                //ErrorLogger.Log(item);
                yield return(item);
            }
        }
コード例 #4
0
 public static bool Prefix(int left, int top, int width, int height)
 {
     return(SuspendableWireManager.BeginTripWire(left, top, width, height));
 }