private void LightingRenderer_DrawLightOccluders(ILContext il)
        {
            MethodReference m_get_Tracker   = il.Import(typeof(Scene).GetProperty("Tracker").GetGetMethod());
            MethodReference m_GetComponents = il.Import(typeof(Tracker).GetMethod("GetComponents").MakeGenericMethod(typeof(LightOccludeList)));
            MethodReference f_get_Tracker   = il.Import(typeof(Tracker).GetProperty("Tracker").GetGetMethod());

            ILCursor c = new ILCursor(il);

            c.GotoNext(i => i.OpCode == OpCodes.Callvirt &&
                       ((MethodReference)i.Operand).Name == "GetComponents")
            .GotoNext(MoveType.After);

            //c.Emit(OpCodes.Ldloc_1);
        }
Example #2
0
        internal static void IlEditing(ILContext il)
        {
            MethodReference getItemReference = null;
            MethodReference setItemReference = null;

            foreach (var instruction in il.Body.Instructions)
            {
                if (instruction.OpCode == OpCodes.Ldftn)
                {
                    MethodReference function = (MethodReference)instruction.Operand;
                    if (!function.Name.Contains(_blacklistLoadFnt[0]) && !function.Name.Contains(_blacklistLoadFnt[1]) && !function.Name.Contains(_blacklistLoadFnt[2]))
                    {
                        InfWorld.Instance.Logger.Info("Loadfnt detected : " + function.Name);
                        HookEndpointManager.Modify(function.ResolveReflection(), new ILContext.Manipulator(IlEditing));
                    }
                }
                else if (instruction.OpCode == OpCodes.Ldsfld)
                {
                    if (instruction.Operand is FieldReference fieldRef && fieldRef.DeclaringType.FullName == "Terraria.Main" && fieldRef.Name == "tile")
                    {
                        FieldReference tileReference =
                            il.Module.ImportReference(typeof(InfWorld).GetField("Tile",
                                                                                BindingFlags.Public | BindingFlags.Static));
                        instruction.Operand = tileReference;
                    }
                }
                else if (instruction.OpCode == OpCodes.Call && instruction.Operand is Mono.Cecil.MethodReference reference)
                {
                    if (reference.FullName == ("Terraria.Tile Terraria.Tile[0...,0...]::Get(System.Int32,System.Int32)"))
                    {
                        instruction.OpCode = OpCodes.Callvirt;
                        if (getItemReference == null)
                        {
                            getItemReference = il.Import(getItem);
                        }
                        instruction.Operand = getItemReference;
                    }
                    else if (reference.FullName == ("System.Void Terraria.Tile[0...,0...]::Set(System.Int32,System.Int32,Terraria.Tile)"))
                    {
                        instruction.OpCode = OpCodes.Callvirt;
                        if (setItemReference == null)
                        {
                            setItemReference = il.Import(setItem);
                        }
                        instruction.Operand = setItemReference;
                    }
                }
            }
        }
Example #3
0
        private static void CreatePatchedMethod(ILContext il) {
            ILCursor c = new ILCursor(il);

            // The original method uses System.Reflection.Emit.

            System.Type t_DynamicTools = GetHarmonyType("DynamicTools");

            // Find and replace DynamicTools.CreateDynamicMethod
            if (!c.TryGotoNext(i => i.MatchCall(t_DynamicTools, "CreateDynamicMethod"))) {
                // Not the right method. Harmony defines two CreatePatchedMethod methods.
                il.MakeReadOnly();
                return;
            }
            c.Next.OpCode = OpCodes.Call;
            c.Next.Operand = il.Import(typeof(HarmonyDetourBridge).GetMethod("CreateDMD", BindingFlags.NonPublic | BindingFlags.Static));
            
            // Find the variable holding the "dynamic method" and update it.
            int varDMDi = -1;
            c.GotoNext(i => i.MatchStloc(out varDMDi));
            VariableDefinition varDMD = il.Body.Variables[varDMDi];
            varDMD.VariableType = il.Import(typeof(DynamicMethodDefinition));

            // Find and replace patch.GetILGenerator
            c.GotoNext(i => i.MatchCallvirt<System.Reflection.Emit.DynamicMethod>("GetILGenerator"));
            c.Next.OpCode = OpCodes.Call;
            c.Next.Operand = il.Import(typeof(DynamicMethodDefinition).GetMethod("GetILGenerator", BindingFlags.Public | BindingFlags.Instance));

            // Find and remove DynamicTools.PrepareDynamicMethod
            c.GotoNext(i => i.MatchCall(t_DynamicTools, "PrepareDynamicMethod"));
            c.Next.OpCode = OpCodes.Pop;
            c.Next.Operand = null;

            // Go to the next ldloc that loads the DynamicMethod.
            // No matter if it gets stored into a local variable or returned immediately,
            // grab it, store it separately and push null as a replacement.
            c.GotoNext(i => i.MatchLdloc(varDMDi));
            c.Index++;
            c.EmitDelegate<Func<DynamicMethodDefinition, System.Reflection.Emit.DynamicMethod>>(dmd => {
                _LastWrapperDMD = dmd;
                return null;
            });
        }
Example #4
0
        private static void SmoothDropDownSuggestionNavigation(ILContext il)
        {
            var cursor = new ILCursor(il);

            var getKey = il.Import(typeof(Input).GetMethodCached("GetKey", new [] { typeof(KeyCode) }));

            cursor.GotoNext(
                MoveType.After,
                x => x.MatchLdcI4(0x111),
                x => x.MatchCallOrCallvirt <Input>("GetKeyDown")
                );
            cursor.Prev.Operand = getKey;
            cursor.EmitDelegate <Func <bool, bool> >(LimitChangeItemFrequency);

            cursor.GotoNext(
                MoveType.After,
                x => x.MatchLdcI4(0x112),
                x => x.MatchCallOrCallvirt <Input>("GetKeyDown")
                );
            cursor.Prev.Operand = getKey;
            cursor.EmitDelegate <Func <bool, bool> >(LimitChangeItemFrequency);

            bool LimitChangeItemFrequency(bool canChangeItem)
            {
                if (canChangeItem)
                {
                    var timeNow = Time.time;
                    if (timeNow > changeSelectedItemTimer + _lastSelectedItemChange)
                    {
                        _lastSelectedItemChange = timeNow;

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(canChangeItem);
            }
        }
Example #5
0
        internal static void Sequence(ILContext il)
        {
            FieldReference fieldRef = il.Import(f_Sequence_this);

            ILCursor c = new ILCursor(il);

            c.GotoNext(MoveType.After, instr => instr.MatchCallOrCallvirt(typeof(Platform), "StopShaking"));
            Instruction next = c.Next;

            Instruction after = new ILCursor(c).GotoNext(instr => instr.Match(OpCodes.Ldarg_0) && instr.Next.OpCode == OpCodes.Ldc_R4 && ((float)instr.Next.Operand) == 0f).Next;

            c.Emit(OpCodes.Ldarg_0);
            c.Emit(OpCodes.Ldfld, fieldRef);
            c.Emit(OpCodes.Isinst, typeof(FancyFallingBlock));
            c.Emit(OpCodes.Brfalse_S, next);
            c.Emit(OpCodes.Ldarg_0);
            c.Emit(OpCodes.Ldfld, fieldRef);
            c.Emit(OpCodes.Call, typeof(FancyFallingBlock).GetMethod(nameof(FallParticles), BindingFlags.NonPublic | BindingFlags.Instance));
            c.Emit(OpCodes.Br, after);
        }
Example #6
0
        internal static void Sequence(ILContext il)
        {
            FieldReference fieldRef = il.Import(f_Sequence_this);
            TypeDefinition typeRef  = ModuleDefinition.ReadModule(typeof(FancyFallingBlock).Assembly.Location).GetType("Celeste.Mod.FancyTileEntities.FancyFallingBlock");

            ILCursor c = new ILCursor(il);

            c.GotoNext(MoveType.After, instr => instr.MatchCallOrCallvirt(typeof(Platform), "StopShaking"));
            Instruction next = c.Next;

            Instruction after = new ILCursor(c).GotoNext(instr => instr.Match(OpCodes.Ldarg_0) && instr.Next.OpCode == OpCodes.Ldc_R4 && ((float)instr.Next.Operand) == 0f).Next;

            c.Emit(OpCodes.Ldarg_0);
            c.Emit(OpCodes.Ldfld, fieldRef);
            c.Emit(OpCodes.Isinst, typeRef);
            c.Emit(OpCodes.Brfalse_S, next);
            c.Emit(OpCodes.Ldarg_0);
            c.Emit(OpCodes.Ldfld, fieldRef);
            c.Emit(OpCodes.Call, typeRef.FindMethod("System.Void FallParticles()"));
            c.Emit(OpCodes.Br, after);
        }
Example #7
0
        private static void FixMoveAllPerformance(ILContext il)
        {
            var cursor = new ILCursor(il);

            var optimizedRemoveItemMethodReference = il.Import(typeof(SaveManager).GetMethod(nameof(SaveManager.OptimizedRemoveItem), ReflectionHelper.AllBindingFlags));

            if (cursor.TryGotoNext(i => i.MatchCallOrCallvirt <Inventory>(nameof(Inventory.RemoveItem))))
            {
                cursor.Next.Operand = optimizedRemoveItemMethodReference;

                if (cursor.TryGotoNext(i => i.MatchCallOrCallvirt <Inventory>(nameof(Inventory.RemoveItem))))
                {
                    cursor.Next.Operand = optimizedRemoveItemMethodReference;
                }
                else
                {
                    Logger.LogError($"Failed ILHook {nameof(Inventory.MoveAll)} 2.");
                }
            }
            else
            {
                Logger.LogError($"Failed ILHook {nameof(Inventory.MoveAll)} 1.");
            }
        }
Example #8
0
        private static void Player_QuickBuff(ILContext il)
        {
            il.Body.Variables.Add(new VariableDefinition(il.Import(typeof(ValueTuple <LegacySoundStyle, bool>))));

            ILCursor cursor = new ILCursor(il);

            if (cursor.TryGotoNext(i => i.MatchLdnull(), i => i.MatchStloc(0)))
            {
                cursor.Index += 2;
                ILLabel label = cursor.DefineLabel();

                cursor.Emit(OpCodes.Ldarg_0);

                cursor.EmitDelegate <Func <Player, ValueTuple <LegacySoundStyle, bool> > >(player =>
                {
                    LegacySoundStyle legacySoundStyle = null;

                    foreach (Item item in player.inventory.OfType <AlchemistBag>().SelectMany(x => x.Handler.Items))
                    {
                        if (player.CountBuffs() == 22)
                        {
                            return(null, true);
                        }

                        if (item.stack > 0 && item.type > 0 && item.buffType > 0 && !item.summon && item.buffType != 90)
                        {
                            int buffType = item.buffType;
                            bool useItem = ItemLoader.CanUseItem(item, player);
                            for (int buffIndex = 0; buffIndex < 22; buffIndex++)
                            {
                                if (buffType == 27 && (player.buffType[buffIndex] == buffType || player.buffType[buffIndex] == 101 || player.buffType[buffIndex] == 102))
                                {
                                    useItem = false;
                                    break;
                                }

                                if (player.buffType[buffIndex] == buffType)
                                {
                                    useItem = false;
                                    break;
                                }

                                if (Main.meleeBuff[buffType] && Main.meleeBuff[player.buffType[buffIndex]])
                                {
                                    useItem = false;
                                    break;
                                }
                            }

                            if (Main.lightPet[item.buffType] || Main.vanityPet[item.buffType])
                            {
                                for (int buffIndex = 0; buffIndex < 22; buffIndex++)
                                {
                                    if (Main.lightPet[player.buffType[buffIndex]] && Main.lightPet[item.buffType])
                                    {
                                        useItem = false;
                                    }
                                    if (Main.vanityPet[player.buffType[buffIndex]] && Main.vanityPet[item.buffType])
                                    {
                                        useItem = false;
                                    }
                                }
                            }

                            if (item.mana > 0 && useItem)
                            {
                                if (player.statMana >= (int)(item.mana * player.manaCost))
                                {
                                    player.manaRegenDelay = (int)player.maxRegenDelay;
                                    player.statMana      -= (int)(item.mana * player.manaCost);
                                }
                                else
                                {
                                    useItem = false;
                                }
                            }

                            if (player.whoAmI == Main.myPlayer && item.type == 603 && !Main.cEd)
                            {
                                useItem = false;
                            }

                            if (buffType == 27)
                            {
                                buffType = Main.rand.Next(3);
                                if (buffType == 0)
                                {
                                    buffType = 27;
                                }
                                if (buffType == 1)
                                {
                                    buffType = 101;
                                }
                                if (buffType == 2)
                                {
                                    buffType = 102;
                                }
                            }

                            if (useItem)
                            {
                                ItemLoader.UseItem(item, player);
                                legacySoundStyle = item.UseSound;
                                int buffTime     = item.buffTime;
                                if (buffTime == 0)
                                {
                                    buffTime = 3600;
                                }

                                player.AddBuff(buffType, buffTime);
                                if (item.consumable)
                                {
                                    if (ItemLoader.ConsumeItem(item, player))
                                    {
                                        item.stack--;
                                    }
                                    if (item.stack <= 0)
                                    {
                                        item.TurnToAir();
                                    }
                                }
                            }
                        }
                    }

                    return(legacySoundStyle, false);
                });

                Type type = typeof(ValueTuple <LegacySoundStyle, bool>);

                cursor.Emit(OpCodes.Stloc, 7);

                cursor.Emit(OpCodes.Ldloc, 7);
                cursor.Emit(OpCodes.Ldfld, type.GetField("Item1", BaseLibrary.Utility.defaultFlags));
                cursor.Emit(OpCodes.Stloc, 0);

                cursor.Emit(OpCodes.Ldloc, 7);
                cursor.Emit(OpCodes.Ldfld, type.GetField("Item2", BaseLibrary.Utility.defaultFlags));
                cursor.Emit(OpCodes.Brfalse, label);
                cursor.Emit(OpCodes.Ret);

                cursor.MarkLabel(label);
            }
        }