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