public void MatchAssignment()
        {
            var ax = RegW("ax");
            var pattern = m.Assign(ax, m.IAdd(ax, ExpressionMatcher.AnyConstant("c")));

            var instrmatcher = new InstructionMatcher(pattern);
            Assert.IsTrue(instrmatcher.Match(
                m.Assign(ax, m.IAdd(ax, m.Word16(42)))));

            Assert.AreEqual("0x002A", instrmatcher.CapturedExpressions("c").ToString());
        }
Esempio n. 2
0
        public void MatchAssignment()
        {
            var ax      = RegW("ax");
            var pattern = m.Assign(ax, m.IAdd(ax, ExpressionMatcher.AnyConstant("c")));

            var instrmatcher = new InstructionMatcher(pattern);

            Assert.IsTrue(instrmatcher.Match(
                              m.Assign(ax, m.IAdd(ax, m.Word16(42)))));

            Assert.AreEqual("0x002A", instrmatcher.CapturedExpressions("c").ToString());
        }
Esempio n. 3
0
        // Support harvesting of spring onions with scythe
        private void Crop_harvest_support_spring_onion(LocalBuilder var_vector)
        {
            if (config.HarvestMode.SpringOnion == HarvestModeEnum.HAND)
            {
                return;
            }

            // Note: the branch
            //   if (this.forageCrop)
            // refers mainly to the crop spring union.

            // Find the lines:
            var AddItem = FindCode(
                // if (Game1.player.addItemToInventoryBool (@object, false)) {
                Instructions.Call_get(typeof(Game1), nameof(Game1.player)),
                InstructionMatcher.AnyOf( // @object
                    OpCodes.Ldloc_0,
                    OpCodes.Ldloc_1
                    ),
                OpCodes.Ldc_I4_0,
                Instructions.Callvirt(typeof(Farmer), nameof(Farmer.addItemToInventoryBool), typeof(Item), typeof(bool)),
                OpCodes.Brfalse
                );

            var ldarg_0      = Instructions.Ldarg_0();
            var Ldloc_object = AddItem[1];
            var tail         = AttachLabel(AddItem.FindNext(
                                               OpCodes.Ldarg_0,
                                               Instructions.Ldfld(typeof(Crop), nameof(Crop.regrowAfterHarvest))
                                               )[0]);

            // Insert check for harvesting with scythe and act accordingly.
            AddItem.ReplaceJump(0, ldarg_0);
            AddItem.Prepend(
                // if (this.harvestMethod != 0) {
                ldarg_0,
                Instructions.Ldfld(typeof(Crop), nameof(Crop.harvestMethod)),
                Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)),
                Instructions.Brfalse(AttachLabel(AddItem[0])),
                // Game1.createItemDebris (@object, vector, -1, null, -1)
                Ldloc_object,                     // @object
                Instructions.Ldloc_S(var_vector), // vector
                Instructions.Ldc_I4_M1(),         // -1
                Instructions.Ldnull(),            // null
                Instructions.Ldc_I4_M1(),         // -1
                Instructions.Call(typeof(Game1), nameof(Game1.createItemDebris), typeof(Item), typeof(Vector2), typeof(int), typeof(GameLocation), typeof(int)),
                Instructions.Pop(),               // For SDV 1.4
                // Jump to tail
                Instructions.Br(tail)
                );
        }
Esempio n. 4
0
        static LongAddRewriter()
        {
            condm = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("grf"),
                    new ConditionOf(
                        ExpressionMatcher.AnyExpression("exp"))));

            addPattern = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("dst"),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"),
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("left"),
                        ExpressionMatcher.AnyExpression("right"))));

            adcPattern = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("dst"),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op1"),
                        VoidType.Instance,
                        new BinaryExpression(
                            ExpressionMatcher.AnyOperator("op2"),
                            VoidType.Instance,
                            ExpressionMatcher.AnyExpression("left"),
                            ExpressionMatcher.AnyExpression("right")),
                        ExpressionMatcher.AnyExpression("cf"))));

            memOffset = new ExpressionMatcher(
                new MemoryAccess(
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"),
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("base"),
                        ExpressionMatcher.AnyConstant("offset")),
                    ExpressionMatcher.AnyDataType("dt")));

            segMemOffset = new ExpressionMatcher(
                new SegmentedAccess(
                    null,
                    ExpressionMatcher.AnyId(),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"),
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("base"),
                        ExpressionMatcher.AnyConstant("offset")),
                    ExpressionMatcher.AnyDataType("dt")));
        }
Esempio n. 5
0
        static LongAddRewriter()
        {
            condm = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("grf"),
                    new ConditionOf(
                        ExpressionMatcher.AnyExpression("exp"))));

            addPattern = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("dst"),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"), 
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("left"),
                        ExpressionMatcher.AnyExpression("right"))));

            adcPattern = new InstructionMatcher(
                new Assignment(
                    ExpressionMatcher.AnyId("dst"),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op1"),
                        VoidType.Instance,
                        new BinaryExpression(
                            ExpressionMatcher.AnyOperator("op2"),
                            VoidType.Instance,
                            ExpressionMatcher.AnyExpression("left"),
                            ExpressionMatcher.AnyExpression("right")),
                        ExpressionMatcher.AnyExpression("cf"))));

            memOffset = new ExpressionMatcher(
                new MemoryAccess(
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"),
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("base"),
                        ExpressionMatcher.AnyConstant("offset")),
                    ExpressionMatcher.AnyDataType("dt")));

            segMemOffset = new ExpressionMatcher(
                new SegmentedAccess(
                    null,
                    ExpressionMatcher.AnyId(),
                    new BinaryExpression(
                        ExpressionMatcher.AnyOperator("op"),
                        VoidType.Instance,
                        ExpressionMatcher.AnyExpression("base"),
                        ExpressionMatcher.AnyConstant("offset")),
                    ExpressionMatcher.AnyDataType("dt")));
        }
Esempio n. 6
0
        // Change the behavior of the grass growth & spreading.
        void GameLocation_growWeedGrass()
        {
            // Stop grass from growing & spreading.
            if (config.DisableGrowth)
            {
                AllCode().Replace(
                    Instructions.Ret()
                    );
                return;
            }

            // Change grass growth to spread mostly everywhere.
            if (config.GrowEverywhere)
            {
                var growWeedGrass = BeginCode();
                // For each of the 4 directions
                for (int i = 0; i < 4; i++)
                {
                    growWeedGrass = growWeedGrass.FindNext(
                        OpCodes.Ldarg_0,
                        null,
                        null,
                        null,
                        null,
                        Instructions.Ldstr("Diggable"),
                        Instructions.Ldstr("Back"),
                        InstructionMatcher.AnyOf(
                            Instructions.Call(typeof(GameLocation), nameof(GameLocation.doesTileHaveProperty), typeof(int), typeof(int), typeof(string), typeof(string)),
                            Instructions.Callvirt(typeof(GameLocation), nameof(GameLocation.doesTileHaveProperty), typeof(int), typeof(int), typeof(string), typeof(string))
                            ),
                        OpCodes.Brfalse
                        );
                    growWeedGrass.Remove();
                }
            }

            // Growth chance
            if (Math.Abs(config.GrowthChance - 0.65) < 1e-6)
            {
                FindCode(
                    Instructions.Ldc_R8(0.65),
                    OpCodes.Bge_Un,
                    OpCodes.Ldloca_S
                    )[0].operand = config.GrowthChance;
            }

            // Spread
            if (Math.Abs(config.SpreadChance - 0.25) < 1e-6)
            {
                var spreadGrass = BeginCode();
                // For each of the 4 directions
                for (int i = 0; i < 4; i++)
                {
                    spreadGrass = spreadGrass.FindNext(
                        Instructions.Ldc_R8(0.25),
                        OpCodes.Bge_Un,
                        OpCodes.Ldarg_0
                        );
                    spreadGrass[0].operand = config.SpreadChance;
                }
            }
        }
Esempio n. 7
0
        // Support harvesting of spring onions with scythe
        private void Crop_harvest_support_spring_onion(LocalBuilder var_vector)
        {
            if (config.HarvestMode.SpringOnion == HarvestModeEnum.HAND)
            {
                return;
            }

            // Note: the branch
            //   if (this.forageCrop)
            // refers mainly to the crop spring union.

            InstructionMatcher addItemToInventoryBool = Instructions.Callvirt(typeof(Farmer), nameof(Farmer.addItemToInventoryBool), typeof(Item), typeof(bool));

            if (helper.ModRegistry.IsLoaded("spacechase0.MoreRings"))
            {
                try {
                    addItemToInventoryBool = InstructionMatcher.AnyOf(
                        addItemToInventoryBool,
                        Instructions.Callvirt(AccessTools.TypeByName("MoreRings.Patches.CropPatcher"), "Farmer_AddItemToInventoryBool", typeof(Farmer), typeof(Item), typeof(bool))
                        );
                } catch (Exception e) {
                    Monitor.Log("The More Rings mod was loaded, but MoreRings.Patches.CropPatcher.Farmer_AddItemToInventoryBool(...) was not found.");
                    LogException(e, LogLevel.Warn);
                }
            }

            // Find the lines:
            InstructionRange AddItem;

            AddItem = FindCode(
                // if (Game1.player.addItemToInventoryBool (@object, false)) {
                Instructions.Call_get(typeof(Game1), nameof(Game1.player)),
                InstructionMatcher.AnyOf( // @object
                    OpCodes.Ldloc_0,
                    OpCodes.Ldloc_1
                    ),
                OpCodes.Ldc_I4_0,
                addItemToInventoryBool,
                OpCodes.Brfalse
                );

            var ldarg_0      = Instructions.Ldarg_0();
            var Ldloc_object = AddItem[1];
            var tail         = AttachLabel(AddItem.FindNext(
                                               OpCodes.Ldarg_0,
                                               Instructions.Ldfld(typeof(Crop), nameof(Crop.regrowAfterHarvest))
                                               )[0]);

            // Insert check for harvesting with scythe and act accordingly.
            AddItem.ReplaceJump(0, ldarg_0);
            AddItem.Prepend(
                // if (this.harvestMethod != 0) {
                ldarg_0,
                Instructions.Ldfld(typeof(Crop), nameof(Crop.harvestMethod)),
                Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)),
                Instructions.Brfalse(AttachLabel(AddItem[0])),
                // Game1.createItemDebris (@object, vector, -1, null, -1)
                Ldloc_object,                     // @object
                Instructions.Ldloc_S(var_vector), // vector
                Instructions.Ldc_I4_M1(),         // -1
                Instructions.Ldnull(),            // null
                Instructions.Ldc_I4_M1(),         // -1
                Instructions.Call(typeof(Game1), nameof(Game1.createItemDebris), typeof(Item), typeof(Vector2), typeof(int), typeof(GameLocation), typeof(int)),
                Instructions.Pop(),               // For SDV 1.4
                // Jump to tail
                Instructions.Br(tail)
                );
        }