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)); }
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()); }
//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)); }
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)); }
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); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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()); }
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()); }
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)); }
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)); }
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)); }
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); }
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)); }
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()); }
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)); }
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()); }
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); }
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()); }
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; } }
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)); }