コード例 #1
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "AmmoCategory").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(Weapon_HasAmmo), nameof(AmmoCategory));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #2
0
 private static IEnumerable <CodeInstruction> FilterDrops(IEnumerable <CodeInstruction> instructions)
 {
     return(new CodeMatcher(instructions)
            .MatchForward(false, new CodeMatch(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(CharacterDrop), nameof(CharacterDrop.m_drops))))
            .SetInstructionAndAdvance(Transpilers.EmitDelegate(ConditionChecker.FilterOnDeath))
            .InstructionEnumeration());
 }
コード例 #3
0
        //public void DoPlaySettingsGlobalControls(WidgetRow row, bool worldView)
        public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            MethodInfo ToggleableIconInfo        = AccessTools.Method(typeof(WidgetRow), nameof(WidgetRow.ToggleableIcon));
            MethodInfo ToggleableIconReplacement = AccessTools.Method(typeof(RemoveUnusedToggles), nameof(ToggleableIconFiltered));

            return(Transpilers.MethodReplacer(instructions, ToggleableIconInfo, ToggleableIconReplacement));
        }
コード例 #4
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(AIUtil_ExpectedDamageForMeleeAttackUsingUnitsBVs), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #5
0
ファイル: Transpiling.cs プロジェクト: riQQ/HarmonyX
        public void EmitDelegateTest()
        {
            var instruction = Transpilers.EmitDelegate <Action>(TranspliersClasses.TestStaticMethod);

            Assert.AreEqual(OpCodes.Call, instruction.opcode);
            Assert.IsTrue(instruction.operand is MethodInfo);

            instruction = Transpilers.EmitDelegate <Action>(() => TranspliersClasses.TestStaticField = 5);

            Assert.AreEqual(OpCodes.Call, instruction.opcode);
            Assert.IsTrue(instruction.operand is MethodInfo);

            CompileInstruction(instruction)(null);

            Assert.AreEqual(5, TranspliersClasses.TestStaticField);

            int dummy = 0;

            instruction = Transpilers.EmitDelegate <Action>(() => dummy = 15);

            Assert.AreEqual(OpCodes.Call, instruction.opcode);
            Assert.IsTrue(instruction.operand is MethodInfo);

            CompileInstruction(instruction)(null);

            Assert.AreEqual(15, dummy);
        }
コード例 #6
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(SelectionStateMove_ProjectedHeatForState), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #7
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(CombatTestFire_MeleeAttackSequence), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #8
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(LOFCache_UnitHasLOFToTarget), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #9
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(AIRoleAssignment_EvaluateSniper), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #10
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(PreferNotLethalPositionFactor_expectedDamageForShooting), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #11
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(CombatHUDWeaponTickMarks_GetValidSlots), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #12
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(PreferFiringSolutionWhenExposedAllyPositionalFactor_EvaluateInfluenceMapFactorAtPosition), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #13
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(PreferExposedAlonePositionalFactor_InitEvaluationForPhaseForUnit), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #14
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(MultiAttack_ValidateMultiAttackOrder), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #15
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var from = AccessTools.Constructor(typeof(DamageFlasher), new Type[] { typeof(Pawn) });
            var to   = AccessTools.Constructor(typeof(ZombieDamageFlasher), new Type[] { typeof(Pawn) });

            return(Transpilers.MethodReplacer(instructions, from, to));
        }
コード例 #16
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(AbstractActor_GetLongestRangeWeapon), nameof(IndirectFireCapable));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #17
0
ファイル: BetterFPS.cs プロジェクト: songyandong/QOL
        static IEnumerable <CodeInstruction> DysonSphereSegmentRenderer_DrawModels_Patch(IEnumerable <CodeInstruction> instructions)
        {
            CodeMatcher matcher = new CodeMatcher(instructions)
                                  .MatchForward(true,
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphereSegmentRenderer), nameof(DysonSphereSegmentRenderer.dysonSphere))),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphere), nameof(DysonSphere.layersIdBased)))
                                                )
                                  .MatchForward(false,
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphereSegmentRenderer), nameof(DysonSphereSegmentRenderer.dysonSphere))),
                                                new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphere), nameof(DysonSphere.layersIdBased)))
                                                )
                                  .SetOpcodeAndAdvance(OpCodes.Nop)
                                  .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop))
                                  .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop))
                                  .Advance(1)
                                  .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                                  .SetInstructionAndAdvance(Transpilers.EmitDelegate <Func <uint, DysonSphereSegmentRenderer, DysonSphereLayer> >((uint index, DysonSphereSegmentRenderer renderer) =>
            {
                if (hideDysonSphereMesh.Value && DysonSphere.renderPlace == ERenderPlace.Universe)
                {
                    return(null);
                }

                return(renderer.dysonSphere.layersIdBased[(int)((UIntPtr)index)]);
            }));

            return(matcher.InstructionEnumeration());
        }
コード例 #18
0
ファイル: ThreadSafety.cs プロジェクト: songyandong/QOL
        public static IEnumerable <CodeInstruction> CargoContainer_Expand2x_Patch(IEnumerable <CodeInstruction> instructions)
        {
            CodeMatcher matcher = new CodeMatcher(instructions)
                                  .MatchForward(true,
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldloc_0),
                                                new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(CargoContainer), nameof(CargoContainer.poolCapacity)))
                                                )
                                  .Advance(1)
                                  .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                                  .InsertAndAdvance(Transpilers.EmitDelegate <Action <CargoContainer> >((CargoContainer __instance) =>
            {
                if (executeNow)
                {
                    UpdateCargoBuffer(__instance);
                }
                else
                {
                    expandedCargos.Add(__instance);
                }
            }))
                                  .InsertAndAdvance(new CodeInstruction(OpCodes.Ret));

            return(matcher.InstructionEnumeration());
        }
コード例 #19
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(MechRepresentation_PlayImpactAnim), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #20
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var markerMethod = AccessTools.Method(typeof(Messages), nameof(Messages.Message), new Type[] { typeof(string), typeof(LookTargets), typeof(MessageTypeDef), typeof(bool) });
            var sneakyMethod = AccessTools.Method(typeof(Patch_FailConstruction), nameof(Patch_FailConstruction.ConditionalMessage));

            return(Transpilers.MethodReplacer(instructions, markerMethod, sneakyMethod));
        }
コード例 #21
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(MoveTowardsHighestPriorityMoveCandidateNode_Tick), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #22
0
        static IEnumerable <CodeInstruction> Transpiler1(IEnumerable <CodeInstruction> instructions)
        {
            var custominstruc = new CodeMatcher(instructions)
                                .MatchForward(false,
                                              new CodeMatch(OpCodes.Ldarg_0),
                                              new CodeMatch(OpCodes.Ldarg_0),
                                              new CodeMatch(l => l.opcode == OpCodes.Call && l.Calls(AccessTools.Method(typeof(SceneEdit), "InitMenuNative"))))
                                .SetAndAdvance(OpCodes.Nop, null)
                                .SetAndAdvance(OpCodes.Nop, null)
                                .SetAndAdvance(OpCodes.Nop, null)
                                .SetAndAdvance(OpCodes.Nop, null)
                                .SetAndAdvance(OpCodes.Nop, null)
                                .Insert(
                new CodeInstruction(OpCodes.Ldarg_0),
                Transpilers.EmitDelegate <Action>(() =>
            {
                Debug.Log("Calling your control test coroutine.");
                @this2.StartCoroutine(InitMenuNative());
            }),
                new CodeInstruction(OpCodes.Pop)
                )
                                .InstructionEnumeration();

            return(custominstruc);
        }
コード例 #23
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "Category").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(AttackEvaluator_MakeAttackOrderForTarget_AP), nameof(Category));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }
コード例 #24
0
 private static IEnumerable <CodeInstruction> Transpile_Player_AddKnownItem(IEnumerable <CodeInstruction> instructions)
 {
     // Insert our own callback after:
     // this.m_knownMaterial.Add(item.m_shared.m_name);
     return(new CodeMatcher(instructions)
            .MatchForward(true,
                          // IL_0032: ldfld    class [System.Core] System.Collections.Generic.HashSet`1<string> Player::m_knownMaterial
                          // IL_0037: ldarg.1
                          // IL_0038: ldfld    class ItemDrop/ItemData/SharedData ItemDrop/ItemData::m_shared
                          // IL_003D: ldfld    string ItemDrop/ItemData/SharedData::m_name
                          // IL_0042: callvirt instance bool class [System.Core] System.Collections.Generic.HashSet`1<string>::Add(!0)
                          // IL_0047: pop
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(Player), nameof(Player.m_knownMaterial))),
                          new CodeMatch(OpCodes.Ldarg_1),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ItemDrop.ItemData), nameof(ItemDrop.ItemData.m_shared))),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ItemDrop.ItemData.SharedData), nameof(ItemDrop.ItemData.SharedData.m_name))),
                          new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(HashSet <string>), nameof(HashSet <string> .Add))),
                          new CodeMatch(OpCodes.Pop)
                          )
            .Insert(
                new CodeInstruction(OpCodes.Ldarg_1),
                Transpilers.EmitDelegate <Action <ItemDrop.ItemData> >(
                    item => PlayerKnownManager.OnPlayerAddKnownItem(item.m_shared.m_name)
                    )
                )
            .InstructionEnumeration());
 }
コード例 #25
0
        public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            MethodInfo DestroyInfo        = AccessTools.Method(typeof(Thing), nameof(Thing.Destroy));
            MethodInfo DestroyReplaceInfo = AccessTools.Method(typeof(RebuildTransportPod), nameof(DestroyReplace));

            return(Transpilers.MethodReplacer(instructions, DestroyInfo, DestroyReplaceInfo));
        }
コード例 #26
0
 private static IEnumerable <CodeInstruction> Transpile_Player_AddKnownRecipe(IEnumerable <CodeInstruction> instructions)
 {
     // Insert our own callback after:
     // this.m_knownRecipes.Add(recipe.m_item.m_itemData.m_shared.m_name);
     return(new CodeMatcher(instructions)
            // IL_0022: ldarg.0
            // IL_0023: ldfld    class [System.Core] System.Collections.Generic.HashSet`1<string> Player::m_knownRecipes
            // IL_0028: ldarg.1
            // IL_0029: ldfld    class ItemDrop Recipe::m_item
            // IL_002E: ldfld    class ItemDrop/ItemData ItemDrop::m_itemData
            // IL_0033: ldfld    class ItemDrop/ItemData/SharedData ItemDrop/ItemData::m_shared
            // IL_0038: ldfld    string ItemDrop/ItemData/SharedData::m_name
            // IL_003D: callvirt instance bool class [System.Core] System.Collections.Generic.HashSet`1<string>::Add(!0)
            // IL_0042: pop
            .MatchForward(true,
                          new CodeMatch(OpCodes.Ldarg_0),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(Player), nameof(Player.m_knownRecipes))),
                          new CodeMatch(OpCodes.Ldarg_1),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(Recipe), nameof(Recipe.m_item))),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ItemDrop), nameof(ItemDrop.m_itemData))),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ItemDrop.ItemData), nameof(ItemDrop.ItemData.m_shared))),
                          new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(ItemDrop.ItemData.SharedData), nameof(ItemDrop.ItemData.SharedData.m_name))),
                          new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(HashSet <string>), nameof(HashSet <string> .Add))),
                          new CodeMatch(OpCodes.Pop)
                          )
            .Insert(
                new CodeInstruction(OpCodes.Ldarg_1),
                Transpilers.EmitDelegate <Action <Recipe> >(
                    recipe => PlayerKnownManager.OnPlayerAddKnownRecipe(recipe.m_item.m_itemData.m_shared.m_name)
                    )
                )
            .InstructionEnumeration());
 }
コード例 #27
0
        public static string StringOperation(string original)
        {
            // This inner transpiler will be applied to the original and
            // the result will replace this method
            //
            // That will allow this method to have a different signature
            // than the original and it must match the transpiled result
            //
            IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
            {
                var list = Transpilers.Manipulator(instructions,
                                                   item => item.opcode == OpCodes.Ldarg_1,
                                                   item => item.opcode = OpCodes.Ldarg_0
                                                   ).ToList();
                var mJoin = SymbolExtensions.GetMethodInfo(() => string.Join(null, null));
                var idx   = list.FindIndex(item => item.opcode == OpCodes.Call && item.operand as MethodInfo == mJoin);

                list.RemoveRange(idx + 1, list.Count - (idx + 1));
                list.Add(new CodeInstruction(OpCodes.Ret));
                return(list.AsEnumerable());
            }

            // make compiler happy
            _ = Transpiler(null);
            return(original);
        }
コード例 #28
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            CodeMatcher matcher = new CodeMatcher(instructions)
                                  .MatchForward(false,
                                                new CodeMatch(OpCodes.Ldc_R4),
                                                new CodeMatch(OpCodes.Ldarg_0),
                                                new CodeMatch(OpCodes.Ldfld),
                                                new CodeMatch(i =>
                                                              i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "GetVeinsInAreaNonAlloc"))
                                  .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Ldloc_3))
                                  .InsertAndAdvance(
                Transpilers.EmitDelegate <Func <BuildPreview, float> >(preview => DSPAdvancedMiner.getMinerRadius(preview.desc) + 4)
                ).MatchForward(true,
                               new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Vector3), nameof(Vector3.Dot))),
                               new CodeMatch(OpCodes.Stloc_S),
                               new CodeMatch(OpCodes.Ldloc_S),
                               new CodeMatch(OpCodes.Ldc_R4))
                                  .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Ldloc_3))
                                  .InsertAndAdvance(
                Transpilers.EmitDelegate <Func <BuildPreview, float> >(preview =>
            {
                float radius = DSPAdvancedMiner.getMinerRadius(preview.desc);
                return(radius * radius);
            })
                );

            return(matcher.InstructionEnumeration());
        }
コード例 #29
0
ファイル: DecoratedMethod.cs プロジェクト: raydleemsc/Torch
        internal void Commit()
        {
            try
            {
                // non-greedy so they are all reset
                if (!Prefixes.HasChanges(true) & !Suffixes.HasChanges(true) & !Transpilers.HasChanges(true) & !PostTranspilers.HasChanges(true))
                {
                    return;
                }
                Revert();

                if (Prefixes.Count == 0 && Suffixes.Count == 0 && Transpilers.Count == 0 && PostTranspilers.Count == 0)
                {
                    return;
                }
                _log.Log(PrintMsil ? LogLevel.Info : LogLevel.Debug,
                         $"Begin patching {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
                var patch = ComposePatchedMethod();

                _revertAddress = AssemblyMemory.GetMethodBodyStart(_method);
                var newAddress = AssemblyMemory.GetMethodBodyStart(patch);
                _revertData  = AssemblyMemory.WriteJump(_revertAddress, newAddress);
                _pinnedPatch = GCHandle.Alloc(patch);
                _log.Log(PrintMsil ? LogLevel.Info : LogLevel.Debug,
                         $"Done patching {_method.DeclaringType?.FullName}#{_method.Name}({string.Join(", ", _method.GetParameters().Select(x => x.ParameterType.Name))})");
            }
            catch (Exception exception)
            {
                _log.Fatal(exception, $"Error patching {_method.DeclaringType?.FullName}#{_method}");
                throw;
            }
        }
コード例 #30
0
        static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "AmmoCategory").GetGetMethod();
            var replacementMethod    = AccessTools.Method(typeof(PoorlyMaintainedEffect_ApplyEffectsToVehicle), nameof(AmmoCategory));

            return(Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod));
        }