Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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");
                }
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
    }
}