BugFixAddItem.ItemGrabMenuPatches.receiveRightClick_Transpiler C# (CSharp) Метод

receiveRightClick_Transpiler() публичный статический Метод

public static receiveRightClick_Transpiler ( IEnumerable instructions, ILGenerator gen ) : IEnumerable
instructions IEnumerable
gen ILGenerator
Результат IEnumerable
        public static IEnumerable<CodeInstruction> receiveRightClick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator gen)
        {
            try
            {
                var codes = new List<CodeInstruction>(instructions);

                for (int i = 0; i < codes.Count - 8; i++)
                {
                    // Find any sequence matching if(Game1.player.addItemToInventoryBool(this.heldItem, false)
                    //     which is followed by this.heldItem = null assignment if true.

                    if (//call class StardewValley.Farmer StardewValley.Game1::get_player()
                        codes[i].opcode == OpCodes.Call &&
                        (MethodInfo)codes[i].operand == typeof(Game1).GetProperty("player").GetGetMethod() &&
                        //ldarg.0
                        codes[i + 1].opcode == OpCodes.Ldarg_0 &&
                        //ldfld class StardewValley.Item StardewValley.Menus.MenuWithInventory::heldItem
                        codes[i + 2].opcode == OpCodes.Ldfld &&
                        (FieldInfo)codes[i + 2].operand == typeof(MenuWithInventory).GetField("heldItem") &&
                        //ldc.i4.0
                        codes[i + 3].opcode == OpCodes.Ldc_I4_0 &&
                        //callvirt instance bool StardewValley.Farmer::addItemToInventoryBool(class StardewValley.Item, bool)
                        codes[i + 4].opcode == OpCodes.Callvirt &&
                        (MethodInfo)codes[i + 4].operand == typeof(Farmer).GetMethod("addItemToInventoryBool") &&
                        //befalse IL_05dc || brfalse.s IL_02f0 (return)
                        (codes[i + 5].opcode == OpCodes.Brfalse || codes[i + 5].opcode == OpCodes.Brfalse_S) &&
                        //ldarg.0
                        codes[i + 6].opcode == OpCodes.Ldarg_0 && // INSERT NEW CODES AT THIS INDEX
                        //ldnull
                        codes[i + 7].opcode == OpCodes.Ldnull &&
                        //stfld class StardewValley.Item StardewValley.Menus.MenuWithInventory::heldItem
                        codes[i + 8].opcode == OpCodes.Stfld &&
                        (FieldInfo)codes[i + 8].operand == typeof(MenuWithInventory).GetField("heldItem"))
                    {
                        Monitor.Log($"Found a location to insert codes: {codes[i + 6]}", LogLevel.Debug);

                        // Compose the new instructions to inject
                        var codesToInsert = new List<CodeInstruction>
                        {
                            new CIL(OpCodes.Ldarg_0),
                            new CIL(OpCodes.Call, typeof(Game1).GetProperty("player").GetGetMethod()),
                            new CIL(OpCodes.Call, Helper.Reflection.GetMethod(
                                typeof(ItemGrabMenuPatches),nameof(OnAddItemCheck_Hook)).MethodInfo)
                        };

                        // Inject the instructions
                        codes.InsertRange(i + 6, codesToInsert);
                        foreach (CIL cil in codesToInsert)
                        {
                            Monitor.Log($"Inserted new OpCode: {cil}", LogLevel.Debug);
                        }
                    }
                }
                return codes.AsEnumerable();
            }
            catch (Exception ex)
            {
                Monitor.Log($"Failed in {nameof(receiveRightClick_Transpiler)}:\n{ex}", LogLevel.Error);
                return instructions; // use original code
            }
        }