public virtual bool SearchMethod(MethodInfo searchMethod, List <MethodInfo> targets, out List <ItemPos <MethodInfo> > Results) { Results = new List <ItemPos <MethodInfo> >(); List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(searchMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(searchMethod); } bool foundResult = false; for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo calledMethod && targets.Exists(t => IsBaseMethod(t, calledMethod))) { foundResult = true; Results.Add((ItemPos <MethodInfo>)(i, calledMethod)); if (!FindAll) { return(true); } } } return(foundResult); }
public virtual bool SearchMethod(MethodInfo searchMethod, out List <ItemPos <JobDef> > Results) { Results = new List <ItemPos <JobDef> >(); bool foundResult = false; List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(searchMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(searchMethod); } for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; // Ambiguous method call if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo calledMethod) { if (calledMethod.ReturnType == typeof(JobDef)) { foundResult = true; Results.Add((ItemPos <JobDef>)(i, null)); } } // StatDefOf call if (instruction.opcode == OpCodes.Ldsfld && instruction.operand is FieldInfo jobField && jobField.FieldType == typeof(JobDef) && JobDefOfFieldInfo.Contains(jobField)) { Results.Add((ItemPos <JobDef>)(i, FieldToJob[jobField])); foundResult = true; } if (!FindAll && foundResult) { return(foundResult); } } return(foundResult); }
public Mock() { //var harmony = HarmonyInstance.Create("AltV.Net"); var methodBase = AccessTools.Method(typeof(AltNative.Player), "Player_GetID", new [] { typeof(IntPtr) }); Console.WriteLine("methodbase:" + methodBase); MethodBase getIdMethodBase = typeof(Mock).GetMethod("GetId"); var originalInstructions2 = PatchProcessor.GetCurrentInstructions(methodBase); var originalInstructions = PatchProcessor.GetCurrentInstructions(getIdMethodBase); Console.WriteLine(originalInstructions.ToString()); Console.WriteLine(originalInstructions.Count); foreach (var instruction in originalInstructions) { Console.WriteLine(instruction); } Console.WriteLine(originalInstructions2.ToString()); Console.WriteLine(originalInstructions2.Count); foreach (var instruction in originalInstructions2) { Console.WriteLine(instruction); } var harmony = new Harmony("AltV.Net"); harmony.PatchAll(Assembly.GetExecutingAssembly()); var bla = AltNative.Player.Player_GetID(IntPtr.Zero); Console.WriteLine(bla); }
public void Test_GetCurrentInstructions() { var instance = new InstructionTest(); var method = SymbolExtensions.GetMethodInfo(() => instance.Method("")); Assert.AreEqual(1, instance.Method("Foo Bar")); var originalInstructions = PatchProcessor.GetCurrentInstructions(method); var m_get_Chars = AccessTools.Method("System.String:get_Chars"); Assert.IsTrue(originalInstructions.Any(instr => instr.Calls(m_get_Chars))); var m_get_Length = AccessTools.Method("System.String:get_Length"); Assert.IsTrue(originalInstructions.Any(instr => instr.Calls(m_get_Length))); var processor = new PatchClassProcessor(new Harmony("instructions"), typeof(InstructionTest.Patch)); var patches = processor.Patch(); Assert.AreEqual(1, patches.Count); Assert.AreEqual(1, instance.Method("Foo*Bar")); var newInstructions = PatchProcessor.GetCurrentInstructions(method); Assert.AreEqual(originalInstructions.Count, newInstructions.Count); var changed = new List <CodeInstruction>(); for (var i = 0; i < originalInstructions.Count; i++) { if (originalInstructions[i].ToString() != newInstructions[i].ToString()) { changed.Add(newInstructions[i]); } } Assert.AreEqual(1, changed.Count); Assert.AreEqual('*', changed[0].operand); var unchangedInstructions = PatchProcessor.GetCurrentInstructions(method, 0); Assert.AreEqual(originalInstructions.Count, unchangedInstructions.Count); for (var i = 0; i < originalInstructions.Count; i++) { if (originalInstructions[i].ToString() != unchangedInstructions[i].ToString()) { Assert.Fail("Instruction " + i + " differs"); } } }
private static FieldInfo GetFieldInfo(MethodInfo getterMethod) { List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(getterMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(getterMethod); } var length = instructionList.Count; for (int i = 0; i < length; i++) { CodeInstruction instruction = instructionList[length - 1 - i]; if (instruction.opcode == OpCodes.Ldfld && instructionList[length - 2 - i].IsLdarg(0)) { return(instruction.operand as FieldInfo); } } return(null); }
private bool SearchToilGenerator(MethodInfo searchMethod, List <MethodInfo> ActionList, out List <MethodInfo> ActionsFound) { ActionsFound = new List <MethodInfo>(); bool foundResult = false; List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(searchMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(searchMethod); } foreach (var instruction in instructionList) { if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Ldftn) && instruction.operand is MethodInfo calledMethod && ActionList.Any(t => IsBaseMethod(t, calledMethod))) { foundResult = true; ActionsFound.Add(calledMethod); if (!FindAll) { return(true); } } } return(foundResult); }
public virtual bool SearchMethod(MethodInfo searchMethod, out List <ItemPos <StatDef> > Results, out List <CodeInstruction> PawnIns) { Results = new List <ItemPos <StatDef> >(); PawnIns = new List <CodeInstruction>(); bool foundResult = false; bool foundPawn = false; List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(searchMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(searchMethod); } List <int?> ParamList = searchMethod.GetParameters()?.Where(t => t.ParameterType.IsAssignableFrom(typeof(Pawn)))?.Select(t => new int?(t.Position))?.ToList() ?? new List <int?>(); List <LocalBuilder> LocalList = new List <LocalBuilder>(); if (!ParamList.NullOrEmpty()) { foundPawn = true; } for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo pawnField && pawnField.FieldType.IsAssignableFrom(typeof(Pawn))) { foundPawn = true; for (int j = 1; j < i; j++) { if (instructionList[i - j].IsLdarg(0)) { PawnIns = new List <CodeInstruction>(instructionList.GetRange(i - j, j + 1)); break; } } } if (ParamList.Any(t => instruction.IsLdarg(t))) { PawnIns = new List <CodeInstruction>() { instruction } } ; if (instruction.IsStloc() && instruction.operand is LocalBuilder local && !LocalList.Contains(local) && local.LocalType.IsAssignableFrom(typeof(Pawn))) { LocalList.Add(local); } if (LocalList.Any(t => instruction.IsLdloc(t))) { PawnIns = new List <CodeInstruction>() { instruction } } ; // Ambiguous method call if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo calledMethod) { if (calledMethod.ReturnType == typeof(StatDef)) { foundResult = true; Results.Add((ItemPos <StatDef>)(i, null)); } else if (calledMethod.ReturnType.IsAssignableFrom(typeof(Pawn))) { foundPawn = true; if (calledMethod.IsStatic) { PawnIns = new List <CodeInstruction>() { instruction } } ; else { for (int j = 1; j < i; j++) { if (instructionList[i - j].IsLdarg(0)) { PawnIns = new List <CodeInstruction>(instructionList.GetRange(i - j, j + 1)); break; } } } } } // StatDefOf call if (instruction.opcode == OpCodes.Ldsfld && instruction.operand is FieldInfo statField && statField.FieldType == typeof(StatDef) && StatDefOfFieldInfo.Contains(statField)) { Results.Add((ItemPos <StatDef>)(i, FieldToStat[statField])); foundResult = true; } if (!FindAll && foundResult && (!findPawn || foundPawn)) { return(foundResult); } } return(foundResult); } } }