public static void PatchAll(Harmony harmony) { var asm = Assembly.GetExecutingAssembly(); var R68 = from t in asm.GetTypes() let attributes = t.GetCustomAttributes(typeof(R68), true) where attributes != null && attributes.Length > 0 select t; var R71 = from t in asm.GetTypes() let attributes = t.GetCustomAttributes(typeof(R71), true) where attributes != null && attributes.Length > 0 select t; if (Main.R68) { Main.Mod.Logger.Log("ADOFAI r68 or lower version detected."); foreach (var i in R68) { Main.Mod.Logger.Log("Patching: " + i.FullName); harmony.CreateClassProcessor(i).Patch(); } } else { Main.Mod.Logger.Log("ADOFAI r71 or newer version detected."); foreach (var i in R71) { Main.Mod.Logger.Log("Patching: " + i.FullName); harmony.CreateClassProcessor(i).Patch(); } } }
public void Test_TargetMethods_Returns_Null() { var patchClass = typeof(Class17Patch); Assert.NotNull(patchClass); var harmonyInstance = new Harmony("test"); Assert.NotNull(harmonyInstance); var processor = harmonyInstance.CreateClassProcessor(patchClass); Assert.NotNull(processor); Exception exception = null; try { Assert.NotNull(processor.Patch()); } catch (Exception ex) { exception = ex; } Assert.NotNull(exception); Assert.NotNull(exception.InnerException); Assert.True(exception.InnerException.Message.Contains("returned an unexpected result: some element was null")); }
/// <param name="method">type with HarmonyPatch attribute</param> internal ManagedPatchAnnotated(Type method, bool createAutomatically = true) { var owner = method.Name; // if its a nested patch prepend with class name if (method.DeclaringType != null) { owner = method.DeclaringType.Name + " " + owner; } // // if its in a namespace prepend last part of namespace // else if (!string.IsNullOrEmpty(type.Namespace)) // { // var ns = type.Namespace; // if (ns.Contains(".")) ns = ns.Substring(ns.LastIndexOf(".", StringComparison.Ordinal)); // owner = ns + owner; // } Name = owner; // mark it as a managed patch owner += ManagedPatchPostfix; instance = new Harmony(method.FullName); Id = instance.Id; Group = method.Assembly.GetGroupName(); proc = instance.CreateClassProcessor(method); ApplyMeta(method.GetCustomAttribute <PatchMeta>()); if (createAutomatically) { OnCreated(); } }
public void Test_ManyFinalizers() { var originalClass = typeof(CombinedPatchClass); Assert.NotNull(originalClass); var patchClass = typeof(CombinedPatchClass_Patch_1); Assert.NotNull(patchClass); var harmonyInstance = new Harmony("test"); Assert.NotNull(harmonyInstance); var processor = harmonyInstance.CreateClassProcessor(patchClass); Assert.NotNull(processor); Assert.NotNull(processor.Patch()); CombinedPatchClass_Patch_1.counter = 0; var instance = new CombinedPatchClass(); instance.Method1(); Assert.AreEqual("tested", instance.Method2("test")); instance.Method3(123); Assert.AreEqual(4, CombinedPatchClass_Patch_1.counter); }
public void Test_Affecting_Original_Prefixes() { var instance = new Harmony("test"); Assert.NotNull(instance, "instance"); var processor = instance.CreateClassProcessor(typeof(Affecting_Original_Prefixes_Patch)); Assert.NotNull(processor, "processor"); var methods = processor.Patch(); Assert.NotNull(methods, "methods"); Assert.AreEqual(1, methods.Count); Affecting_Original_Prefixes_Patch.ResetTest(); var test = new Affecting_Original_Prefixes_Class(); Assert.NotNull(test, "test"); var value = test.Method(100); Assert.AreEqual("patched", value); // note that since passthrough postfixes are async, they run AFTER any finalizer // var events = Affecting_Original_Prefixes_Patch.GetEvents(); Assert.AreEqual(4, events.Count, "event count"); Assert.AreEqual("Prefix1", events[0]); Assert.AreEqual("Prefix2", events[1]); Assert.AreEqual("Prefix3", events[2]); Assert.AreEqual("Prefix5", events[3]); }
public void Test_Attributes() { var originalClass = typeof(AttributesClass); Assert.NotNull(originalClass); var originalMethod = originalClass.GetMethod("Method"); Assert.NotNull(originalMethod); Assert.AreEqual(originalMethod, AttributesPatch.Patch0()); var instance = new Harmony("test"); Assert.NotNull(instance); var patchClass = typeof(AttributesPatch); Assert.NotNull(patchClass); AttributesPatch.ResetTest(); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher); Assert.NotNull(patcher.Patch()); (new AttributesClass()).Method("foo"); Assert.True(AttributesPatch.targeted, "TargetMethod was not executed"); Assert.True(AttributesPatch.postfixed, "Prefix was not executed"); Assert.True(AttributesPatch.postfixed, "Postfix was not executed"); }
public void Test_Patch_ConcreteClass() { var instance = new Harmony("special-case-1"); Assert.NotNull(instance, "instance"); var processor = instance.CreateClassProcessor(typeof(ConcreteClass_Patch)); Assert.NotNull(processor, "processor"); var someStruct1 = new ConcreteClass().Method("test", new AnotherStruct()); Assert.True(someStruct1.accepted, "someStruct1.accepted"); TestTools.Log($"Patching ConcreteClass_Patch start"); var replacements = processor.Patch(); Assert.NotNull(replacements, "replacements"); Assert.AreEqual(1, replacements.Count); TestTools.Log($"Patching ConcreteClass_Patch done"); TestTools.Log($"Running patched ConcreteClass_Patch start"); var someStruct2 = new ConcreteClass().Method("test", new AnotherStruct()); Assert.True(someStruct2.accepted, "someStruct2.accepted"); TestTools.Log($"Running patched ConcreteClass_Patch done"); }
public void Test_MultiplePatches_One_Class() { var originalClass = typeof(MultiplePatches1); Assert.NotNull(originalClass); var originalMethod = originalClass.GetMethod("TestMethod"); Assert.NotNull(originalMethod); var instance = new Harmony("test"); Assert.NotNull(instance); var patchClass = typeof(MultiplePatches1Patch); Assert.NotNull(patchClass); MultiplePatches1.result = "before"; var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher); Assert.NotNull(patcher.Patch()); var result = (new MultiplePatches1()).TestMethod("after"); Assert.AreEqual("after,prefix2,prefix1", MultiplePatches1.result); Assert.AreEqual("ok,postfix", result); }
public void Test_PatchExceptionWithCleanup2() { if (AccessTools.IsMonoRuntime == false) { return; // Assert.Ignore("Only mono allows for detailed IL exceptions. Test ignored."); } var patchClass = typeof(DeadEndCode_Patch3); Assert.NotNull(patchClass); var instance = new Harmony("test"); Assert.NotNull(instance, "Harmony instance"); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher, "Patch processor"); try { _ = patcher.Patch(); } catch (HarmonyException ex) { Assert.NotNull(ex.InnerException); Assert.IsInstanceOf(typeof(ArgumentException), ex.InnerException); Assert.AreEqual("Test", ex.InnerException.Message); return; } Assert.Fail("Patch should throw HarmonyException"); }
public void Test_PatchException() { var patchClass = typeof(DeadEndCode_Patch1); Assert.NotNull(patchClass); var instance = new Harmony("test"); Assert.NotNull(instance); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher); Exception exception = null; try { Assert.NotNull(patcher.Patch()); } catch (Exception ex) { exception = ex; } Assert.NotNull(exception); }
public static void PatchOver(Harmony harmony, Type gamemode) { if (gamemode == null) { return; } // Patch all current Gamemode Patches try { Assembly assembly = new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly; foreach (Type type in assembly.GetTypes()) { var attribute = type.GetCustomAttribute <GameModeCreator.API.Patch.Attributes.PatchOf>(); if (attribute != null) { if (attribute.gamemode == gamemode) { harmony.CreateClassProcessor(type).Patch(); } } } } catch (Exception exception) { Exiled.API.Features.Log.Error($"Patching failed! {exception}"); } }
static bool PatchAll() { try { bool success = true; var harmony = new Harmony(HARMONY_ID); var assembly = Assembly.GetExecutingAssembly(); foreach (var type in AccessTools.GetTypesFromAssembly(assembly)) { try { var methods = harmony.CreateClassProcessor(type).Patch(); if (methods != null && methods.Any()) { var strMethods = methods.Select(_method => _method.Name).ToArray(); } } catch (Exception ex) { ex.LogException(); success = false; } } return(success); } catch (Exception ex) { ex.LogException(); return(false); } }
private static bool PatchAll(string harmonyId, Type required = null, Type forbidden = null) { try { bool success = true; var harmony = new Harmony(harmonyId); var assembly = Assembly.GetExecutingAssembly(); foreach (var type in AccessTools.GetTypesFromAssembly(assembly)) { try { if (required is not null && !type.IsDefined(required, true)) { continue; } if (forbidden is not null && type.IsDefined(forbidden, true)) { continue; } var methods = harmony.CreateClassProcessor(type).Patch(); if (methods != null && methods.Any()) { var strMethods = methods.Select(_method => _method.Name).ToArray(); } } catch (Exception ex) { ex.LogException(); success = false; } } return(success); } catch (Exception ex) { ex.LogException(); return(false); } }
public static void Test_Method11() { var originalClass = typeof(Class14); Assert.NotNull(originalClass); var patchClass = typeof(Class14Patch); Assert.NotNull(patchClass); var harmonyInstance = new Harmony("test"); Assert.NotNull(harmonyInstance); var processor = harmonyInstance.CreateClassProcessor(patchClass); Assert.NotNull(processor); Assert.NotNull(processor.Patch()); _ = new Class14().Test("Test1", new KeyValuePair <string, int>("1", 1)); _ = new Class14().Test("Test2", new KeyValuePair <string, int>("1", 1), new KeyValuePair <string, int>("2", 2)); Assert.AreEqual("Prefix0", Class14.state[0]); Assert.AreEqual("Test1", Class14.state[1]); Assert.AreEqual("Postfix0", Class14.state[2]); Assert.AreEqual("Prefix1", Class14.state[3]); Assert.AreEqual("Test2", Class14.state[4]); Assert.AreEqual("Postfix1", Class14.state[5]); }
public void Test_SubClassPatching() { var instance1 = new Harmony("test1"); Assert.NotNull(instance1); var type1 = typeof(MainClassPatch); Assert.NotNull(type1); var processor1 = instance1.CreateClassProcessor(type1); Assert.NotNull(processor1); Assert.NotNull(processor1.Patch()); var instance2 = new Harmony("test2"); Assert.NotNull(instance2); var type2 = typeof(SubClassPatch); Assert.NotNull(type2); try { _ = instance2.CreateClassProcessor(type2); } catch (System.ArgumentException ex) { Assert.True(ex.Message.Contains("No target method specified")); } }
public void Test_TargetMethod_Returns_Wrong_Type() { var patchClass = typeof(Class16Patch); Assert.NotNull(patchClass); var harmonyInstance = new Harmony("test"); Assert.NotNull(harmonyInstance); var processor = harmonyInstance.CreateClassProcessor(patchClass); Assert.NotNull(processor); Exception exception = null; try { Assert.NotNull(processor.Patch()); } catch (Exception ex) { exception = ex; } Assert.NotNull(exception); Assert.NotNull(exception.InnerException); Assert.True(exception.InnerException.Message.Contains("has wrong return type")); }
public static void Init() { var args = Environment.GetCommandLineArgs(); var ipcType = (IPCType)Enum.Parse(typeof(IPCType), args[2]); var launcherUri = args[3]; IPCUtil.CreateService( ipcType, typeof(InjectorService), typeof(IInjectorService), out var serviceUri ); LauncherService = IPCUtil.CreateChannel <ILauncherService>(ipcType, launcherUri); LauncherService.SendInjectorSettings(serviceUri); Harmony = new Harmony("me.failedshack.usbhelperinjector"); var assembly = Assembly.GetExecutingAssembly(); assembly.GetTypes() .Where(type => VersionSpecific.Applies(type, HelperVersion) && !(Overrides.DisableOptionalPatches && Optional.IsOptional(type)) && (!WineOnly.IsWineOnly(type) || WineCompat) ) .Do(type => Harmony.CreateClassProcessor(type).Patch()); if (WineCompat) { RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; } }
private void EnableTweak() { Tweak.OnEnable(); foreach (Type type in TweakMetadata.PatchesType.GetNestedTypes(AccessTools.all)) { harmony.CreateClassProcessor(type).Patch(); } Tweak.OnPatch(); }
public static void Patch() { harmony = new Harmony("com.koba.plugins.wurstmod"); // MUST patch GetTypes first. // This might result in a double-patch for GetTypes but it won't hurt anything. harmony.CreateClassProcessor(typeof(Patch_Assembly)).Patch(); harmony.PatchAll(Assembly.GetExecutingAssembly()); }
public void Test_MultiplePatches_Multiple_Classes() { var originalClass = typeof(MultiplePatches2); Assert.NotNull(originalClass); var originalMethod = originalClass.GetMethod("TestMethod"); Assert.NotNull(originalMethod); var instance = new Harmony("test"); Assert.NotNull(instance); var patchClass1 = typeof(MultiplePatchesPatch2_Part1); Assert.NotNull(patchClass1); var patchClass2 = typeof(MultiplePatchesPatch2_Part2); Assert.NotNull(patchClass2); var patchClass3 = typeof(MultiplePatchesPatch2_Part3); Assert.NotNull(patchClass3); MultiplePatches2.result = "before"; var patcher1 = instance.CreateClassProcessor(patchClass1); Assert.NotNull(patcher1); Assert.NotNull(patcher1.Patch()); var patcher2 = instance.CreateClassProcessor(patchClass2); Assert.NotNull(patcher2); Assert.NotNull(patcher2.Patch()); var patcher3 = instance.CreateClassProcessor(patchClass3); Assert.NotNull(patcher3); Assert.NotNull(patcher3.Patch()); var result = (new MultiplePatches2()).TestMethod("hey"); Assert.AreEqual("hey,prefix2,prefix1", MultiplePatches2.result); Assert.AreEqual("patched", result); }
public void Test_Patch_Exception_Propagate() { var instance = new Harmony("special-case-exception-throw"); Assert.NotNull(instance); var processor = instance.CreateClassProcessor(typeof(ErrorReportTestPatch)); Assert.NotNull(processor); Assert.Throws <HarmonyException>(() => processor.Patch()); }
public static bool PatchClasses(string id, out Harmony instance, params Type[] types) { instance = new Harmony($"samfundev.tweaks.{id}"); var success = false; foreach (Type type in types) { var result = instance.CreateClassProcessor(type).Patch(); success |= result?.Count > 0; } return(success); }
public void Test_PatchExternalMethod() { var patchClass = typeof(ExternalMethod_Patch); Assert.NotNull(patchClass); var instance = new Harmony("test"); Assert.NotNull(instance, "Harmony instance"); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher, "Patch processor"); _ = patcher.Patch(); }
public void Test_Finalizer_Patch_Order() { var instance = new Harmony("test"); Assert.NotNull(instance, "instance"); var processor = instance.CreateClassProcessor(typeof(Finalizer_Patch_Order_Patch)); Assert.NotNull(processor, "processor"); var methods = processor.Patch(); Assert.NotNull(methods, "methods"); Assert.AreEqual(1, methods.Count); Finalizer_Patch_Order_Patch.ResetTest(); var test = new Finalizer_Patch_Order_Class(); Assert.NotNull(test, "test"); var values = test.Method().ToList(); Console.WriteLine(Finalizer_Patch_Order_Patch.GetEvents().Join(null, "\n")); Assert.NotNull(values, "values"); Assert.AreEqual(3, values.Count); Assert.AreEqual(11, values[0]); Assert.AreEqual(21, values[1]); Assert.AreEqual(31, values[2]); // note that since passthrough postfixes are async, they run AFTER any finalizer // var actualEvents = Finalizer_Patch_Order_Patch.GetEvents(); var correctEvents = new string[] { "Bool_Prefix", "Void_Prefix", "Simple_Postfix", "NonModifying_Finalizer", "ClearException_Finalizer", "Void_Finalizer", "Passthrough_Postfix2 start", "Passthrough_Postfix1 start", "Yield 10 [old=1]", "Yield 11 [old=10]", "Yield 20 [old=2]", "Yield 21 [old=20]", "Yield 30 [old=3]", "Yield 31 [old=30]", "Passthrough_Postfix1 end", "Passthrough_Postfix2 end" }; Assert.True(actualEvents.SequenceEqual(correctEvents), "events"); }
public void Test_PatchExceptionWithCleanup1() { if (AccessTools.IsMonoRuntime == false) { return; // Assert.Ignore("Only mono allows for detailed IL exceptions. Test ignored."); } var patchClass = typeof(DeadEndCode_Patch2); Assert.NotNull(patchClass); DeadEndCode_Patch2.original = null; DeadEndCode_Patch2.exception = null; var instance = new Harmony("test"); Assert.NotNull(instance, "Harmony instance"); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher, "Patch processor"); try { _ = patcher.Patch(); Assert.Fail("Patch should throw exception"); } catch (Exception) { } Assert.AreSame(typeof(DeadEndCode).GetMethod("Method"), DeadEndCode_Patch2.original, "Patch should save original method"); Assert.NotNull(DeadEndCode_Patch2.exception, "Patch should save exception"); var harmonyException = DeadEndCode_Patch2.exception as HarmonyException; Assert.NotNull(harmonyException, $"Exception should be a HarmonyException (is: {DeadEndCode_Patch2.exception.GetType()}"); var instructions = harmonyException.GetInstructions(); Assert.NotNull(instructions, "HarmonyException should have instructions"); Assert.AreEqual(12, instructions.Count); var errorIndex = harmonyException.GetErrorIndex(); Assert.AreEqual(10, errorIndex); var errorOffset = harmonyException.GetErrorOffset(); Assert.AreEqual(50, errorOffset); }
public void Test_PatchExceptionWithCleanup3() { if (AccessTools.IsMonoRuntime == false) { return; // Assert.Ignore("Only mono allows for detailed IL exceptions. Test ignored."); } var patchClass = typeof(DeadEndCode_Patch4); Assert.NotNull(patchClass); var instance = new Harmony("test"); Assert.NotNull(instance, "Harmony instance"); var patcher = instance.CreateClassProcessor(patchClass); Assert.NotNull(patcher, "Patch processor"); _ = patcher.Patch(); }
/// <summary> /// Only applies patches that satisfy any of the given conditions. /// </summary> public static void PatchAllConditional(this Harmony harmony, Assembly asm, params string[] conditions) { var conditionsSet = new HashSet <string>(conditions, StringComparer.OrdinalIgnoreCase); AccessTools.GetTypesFromAssembly(asm) .Do(type => { var typeConditions = type.GetCustomAttributes <HarmonyConditionalPatchAttribute>() .Select(d => d.Condition) .ToList(); if (!typeConditions.Any() || !typeConditions.Any(d => conditionsSet.Contains(d))) { return; } harmony.CreateClassProcessor(type).Patch(); }); }
public void Test_MultiTarget_Class2() { MultiAttributePatchClass2.callCount = 0; var instance = new Harmony("special-case-multi-target-2"); Assert.NotNull(instance); var processor = instance.CreateClassProcessor(typeof(MultiAttributePatchClass2)); Assert.NotNull(processor); processor.Patch(); var testObject = new DeadEndCode(); Assert.NotNull(testObject); Assert.DoesNotThrow(() => testObject.Method(), "Test method 1 wasn't patched"); Assert.DoesNotThrow(() => testObject.Method2(), "Test method 2 wasn't patched"); Assert.AreEqual(2, MultiAttributePatchClass2.callCount); }
public static void Init() { var factory = new ChannelFactory <ILauncherService>(new NetNamedPipeBinding(), "net.pipe://localhost/LauncherService"); LauncherService = factory.CreateChannel(); ServiceHost host = new ServiceHost(typeof(InjectorService), new Uri("net.pipe://localhost/InjectorService")); host.AddServiceEndpoint(typeof(IInjectorService), new NetNamedPipeBinding(), ""); host.Open(); LauncherService.SendInjectorSettings(); Harmony = new Harmony("me.failedshack.usbhelperinjector"); var assembly = Assembly.GetExecutingAssembly(); assembly.GetTypes() .Where(type => VersionSpecific.Applies(type, HelperVersion) && !(Overrides.DisableOptionalPatches && Optional.IsOptional(type))) .Do(type => Harmony.CreateClassProcessor(type).Patch()); }
public void Test_Class18() { var instance = new Harmony("test"); Assert.NotNull(instance, "instance"); var processor = instance.CreateClassProcessor(typeof(Class18Patch)); Assert.NotNull(processor, "processor"); var methods = processor.Patch(); Assert.NotNull(methods, "methods"); Assert.AreEqual(1, methods.Count); Class18Patch.prefixExecuted = false; var color = Class18.GetDefaultNameplateColor(new APIUser()); Assert.IsTrue(Class18Patch.prefixExecuted, "prefixExecuted"); Assert.AreEqual((float)1, color.r); }