Example #1
0
        public void Test_PatchOrder_AllPriorities()
        {
            var patches = new MethodInfo[9];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new[]
            {
                new Patch(patches[0], 0, "owner A", Priority.Last, new string[0], new string[0], false),
                new Patch(patches[1], 1, "owner B", Priority.VeryLow, new string[0], new string[0], false),
                new Patch(patches[2], 2, "owner C", Priority.Low, new string[0], new string[0], false),
                new Patch(patches[3], 3, "owner D", Priority.LowerThanNormal, new string[0], new string[0], false),
                new Patch(patches[4], 4, "owner E", Priority.Normal, new string[0], new string[0], false),
                new Patch(patches[5], 5, "owner F", Priority.HigherThanNormal, new string[0], new string[0], false),
                new Patch(patches[6], 6, "owner G", Priority.High, new string[0], new string[0], false),
                new Patch(patches[7], 7, "owner H", Priority.VeryHigh, new string[0], new string[0], false),
                new Patch(patches[8], 8, "owner I", Priority.First, new string[0], new string[0], false)
            };

            var expectedOrder = new[] { 8, 7, 6, 5, 4, 3, 2, 1, 0 };
            var methods       = PatchFunctions.GetSortedPatchMethods(null, patchInstances, false);

            for (var i = 0; i < expectedOrder.Length; i++)
            {
                Assert.AreSame(patches[expectedOrder[i]], methods[i],
                               $"#{i} Expected: {patches[expectedOrder[i]].FullDescription()}, Got: {methods[i].FullDescription()}");
            }
        }
Example #2
0
        public void Test_PatchOrder_TransitiveBefore()
        {
            var patches = new MethodInfo[5];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new[]
            {
                new Patch(patches[0], 0, "owner A", Priority.Normal, new string[] { "owner B" }, new string[0], false),
                new Patch(patches[1], 1, "owner B", Priority.HigherThanNormal, new string[] { "owner C" }, new string[0], false),
                new Patch(patches[2], 2, "owner C", Priority.High, new string[] { "owner D" }, new string[0], false),
                new Patch(patches[3], 3, "owner D", Priority.VeryHigh, new string[] { "owner E" }, new string[0], false),
                new Patch(patches[4], 4, "owner E", Priority.First, new string[0], new string[0], false)
            };

            var expectedOrder = new[] { 0, 1, 2, 3, 4 };
            var methods       = PatchFunctions.GetSortedPatchMethods(null, patchInstances, false);

            for (var i = 0; i < expectedOrder.Length; i++)
            {
                Assert.AreSame(patches[expectedOrder[i]], methods[i],
                               $"#{i} Expected: {patches[expectedOrder[i]].FullDescription()}, Got: {methods[i].FullDescription()}");
            }
        }
Example #3
0
        public void Test_PatchOrder_SamePriorities()
        {
            var patches = new MethodInfo[3];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new[]
            {
                new Patch(patches[0], 0, "owner A", Priority.Normal, new string[0], new string[0], false),
                new Patch(patches[1], 1, "owner B", Priority.Normal, new string[0], new string[0], false),
                new Patch(patches[2], 2, "owner C", Priority.Normal, new string[0], new string[0], false)
            };

            var expectedOrder = new[] { 0, 1, 2 };
            var methods       = PatchFunctions.GetSortedPatchMethods(null, patchInstances, false);

            for (var i = 0; i < expectedOrder.Length; i++)
            {
                Assert.AreSame(patches[expectedOrder[i]], methods[i],
                               $"#{i} Expected: {patches[expectedOrder[i]].FullDescription()}, Got: {methods[i].FullDescription()}");
            }
        }
Example #4
0
        public void Test_PatchCycle3()
        {
            var patches = new MethodInfo[8];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new[]
            {
                new Patch(patches[0], 0, "owner A", Priority.Normal, new[] { "owner C" }, new string[0]),
                new Patch(patches[1], 1, "owner B", Priority.Normal, new[] { "owner A" }, new string[0]),
                new Patch(patches[2], 2, "owner C", Priority.Normal, new[] { "owner B" }, new string[0]),
                new Patch(patches[3], 3, "owner D", Priority.Normal, new string[0], new string[0]),
                new Patch(patches[4], 4, "owner E", Priority.First, new string[0], new string[0]),
                new Patch(patches[5], 5, "owner F", Priority.Low, new [] { "owner C", "owner H" }, new[] { "owner G", "owner B" }),
                new Patch(patches[6], 6, "owner G", Priority.Normal, new string[0], new[] { "owner H" }),
                new Patch(patches[7], 7, "owner H", Priority.Normal, new string[0], new[] { "owner F" })
            };

            var expectedOrder = new[] { 4, 3, 5, 7, 6, 2, 1, 0 };
            var methods       = PatchFunctions.GetSortedPatchMethods(null, patchInstances);

            for (var i = 0; i < expectedOrder.Length; i++)
            {
                Assert.AreSame(patches[expectedOrder[i]], methods[i],
                               $"#{i} Expected: {patches[expectedOrder[i]].FullDescription()}, Got: {methods[i].FullDescription()}");
            }
        }
Example #5
0
        public void PatchOrder1()
        {
            var patches = new MethodInfo[5];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new Patch[] {
                new Patch(patches[0], 0, "owner A", Priority.Normal, new string[0], new string[0]),                             // #3
                new Patch(patches[1], 1, "owner A", Priority.Normal, new string[0], new string[0]),                             // #4
                new Patch(patches[2], 2, "owner B", Priority.Normal, new[] { "owner A" }, new string[0]),                       // #2
                new Patch(patches[3], 3, "owner C", Priority.First, new string[0], new string[0]),                              // #1
                new Patch(patches[4], 4, "owner D", Priority.Low, new[] { "owner A" }, new string[0])                           // #5
            };

            var methods = PatchFunctions.GetSortedPatchMethods(null, patchInstances);

            Assert.AreSame(patches[3], methods[0], "#0");
            Assert.AreSame(patches[2], methods[1], "#1");
            Assert.AreSame(patches[0], methods[2], "#2");
            Assert.AreSame(patches[1], methods[3], "#3");
            Assert.AreSame(patches[4], methods[4], "#4");
        }
Example #6
0
        public void PatchOrder_BeforeAndPriorities()
        {
            var patches = new MethodInfo[5];

            for (var i = 0; i < patches.Length; i++)
            {
                patches[i] = GetType().GetMethod("Patch" + (i + 1), AccessTools.all);
            }

            var patchInstances = new[]
            {
                new Patch(patches[0], 0, "owner A", Priority.Normal, new string[0], new string[0]),
                new Patch(patches[1], 1, "owner A", Priority.Normal, new string[0], new string[0]),
                new Patch(patches[2], 2, "owner B", Priority.Normal, new[] { "owner A" }, new string[0]),
                new Patch(patches[3], 3, "owner C", Priority.First, new string[0], new string[0]),
                new Patch(patches[4], 4, "owner D", Priority.Low, new[] { "owner A" }, new string[0])
            };

            var expectedOrder = new[] { 3, 2, 4, 0, 1 };
            var methods       = PatchFunctions.GetSortedPatchMethods(null, patchInstances);

            for (var i = 0; i < expectedOrder.Length; i++)
            {
                Assert.AreSame(patches[expectedOrder[i]], methods[i],
                               $"#{i} Expected: {patches[expectedOrder[i]].FullDescription()}, Got: {methods[i].FullDescription()}");
            }
        }
Example #7
0
        public static MethodInfo UpdateWrapper(MethodBase original, ILGenerator il)
        {
            PatchProcessor    patchProcessor      = RimThreadedHarmony.harmony.CreateProcessor(original);
            PatchInfo         patchInfo           = HarmonySharedState.GetPatchInfo(patchProcessor.original) ?? new PatchInfo();
            bool              debug               = patchInfo.Debugging || Harmony.DEBUG;
            List <MethodInfo> sortedPatchMethods  = PatchFunctions.GetSortedPatchMethods(original, patchInfo.prefixes, debug);
            List <MethodInfo> sortedPatchMethods2 = PatchFunctions.GetSortedPatchMethods(original, patchInfo.postfixes, debug);
            List <MethodInfo> sortedPatchMethods3 = PatchFunctions.GetSortedPatchMethods(original, patchInfo.transpilers, debug);
            List <MethodInfo> sortedPatchMethods4 = PatchFunctions.GetSortedPatchMethods(original, patchInfo.finalizers, debug);
            Dictionary <int, CodeInstruction> finalInstructions;
            MethodPatcher methodPatcher = new MethodPatcher(original, null, sortedPatchMethods, sortedPatchMethods2, sortedPatchMethods3, sortedPatchMethods4, debug);

            methodPatcher.il = il;
            MethodInfo methodInfo = methodPatcher.CreateReplacement(out finalInstructions);

            if (methodInfo == null)
            {
                throw new MissingMethodException("Cannot create replacement for " + original.FullDescription());
            }
            try
            {
                Memory.DetourMethodAndPersist(original, methodInfo);
            } finally
            {
            }
            return(methodInfo);
        }
 static List <PatchContext> Sort(MethodBase original, Patch[] patches, bool debug)
 => PatchFunctions.GetSortedPatchMethodsAsPatches(original, patches, debug)
 .Select(p => new PatchContext {
     method = p.GetMethod(original), wrapTryCatch = p.wrapTryCatch
 })
 .ToList();