示例#1
0
        public void Test_Class22()
        {
            var instance = new Harmony("test");

            Assert.NotNull(instance, "instance");

            var processor = new PatchClassProcessor(instance, typeof(Class22));

            Assert.NotNull(processor, "processor");
            _ = processor.Patch();

            Class22.bool1 = null;
            Class22.bool2 = null;
            Class22.bool3 = null;
            Class22.bool4 = null;
            Class22.Method22();

            Assert.NotNull(Class22.bool1, "bool1");
            Assert.IsTrue(Class22.bool1.Value, "bool1.Value");

            Assert.NotNull(Class22.bool2, "bool2");
            Assert.IsTrue(Class22.bool2.Value, "bool2.Value");

            Assert.NotNull(Class22.bool3, "bool3");
            Assert.IsFalse(Class22.bool3.Value, "bool3.Value");

            Assert.NotNull(Class22.bool4, "bool3");
            Assert.IsFalse(Class22.bool4.Value, "bool4.Value");
        }
示例#2
0
        public void Test_InjectDelegateForStaticClass()
        {
            Assert.AreEqual("[1999]", InjectDelegateStaticClass.Method(999));

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(InjectDelegateStaticClassPatch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);
            Assert.AreEqual("[123]/[456]", InjectDelegateStaticClass.Method(4444));
        }
示例#3
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");
                }
            }
        }
示例#4
0
        public void Test_HarmonyPatchAll()
        {
            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(Assets.BulkPatchClassPatch));

            Assets.BulkPatchClassPatch.transpileCount = 0;
            var patches = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(3, patches.Count);
            Assert.AreEqual(3, Assets.BulkPatchClassPatch.transpileCount, "transpileCount");

            var instance = new Assets.BulkPatchClass();

            Assert.AreEqual("TEST1+", instance.Method1());
            Assert.AreEqual("TEST2+", instance.Method2());
        }
示例#5
0
        public void Test_BoxingRefValueResults()
        {
            var struct1 = Class21.Method21();

            Assert.AreEqual(123, struct1.value);

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(Class21Patch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);

            var result = Class21.Method21();

            Assert.AreEqual(456, result.value);
        }
示例#6
0
        public void Test_RefResults()
        {
            var intRef1 = Class19.Method19();

            Assert.AreEqual(123, intRef1);

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(Class19Patch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);

            var intRef2 = Class19.Method19();

            Assert.AreEqual(456, intRef2);
        }
示例#7
0
        public void Test_InjectDelegateForValueType()
        {
            var instance = new InjectDelegateStruct()
            {
                pre = "{", post = "}"
            };

            Assert.AreEqual("{1999}", instance.Method(999));

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(InjectDelegateStructPatch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);
            Assert.AreEqual("{123}/{456}", instance.Method(4444));
        }
示例#8
0
        public void Test_Class23()
        {
            var instance = new Harmony("test");

            Assert.NotNull(instance, "instance");

            var processor = new PatchClassProcessor(instance, typeof(Class23));

            Assert.NotNull(processor, "processor");
            _ = processor.Patch();

            Class23.bool1 = null;
            Class23.Method23();

            Assert.NotNull(Class23.bool1, "bool1");
            Assert.IsTrue(Class23.bool1.Value, "bool1.Value");
        }
示例#9
0
        public void Test_BoxingValueResults()
        {
            var struct1 = Class20.Method20();

            Assert.AreEqual(123, struct1.value);

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(Class20Patch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);

            _ = Class20.Method20();
            var result = (Class20.Struct20)Class20Patch.theResult;

            Assert.AreEqual(123, result.value);
        }
示例#10
0
        public void Test_InjectBaseDelegateForClass()
        {
            var instance = new InjectDelegateClass()
            {
                pre = "{", post = "}"
            };

            instance.Method(123);
            Assert.AreEqual("[{test:123}]", instance.result);

            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(InjectDelegateClassPatch));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);

            instance.Method(123);
            Assert.AreEqual("{patch:456} | [{patch:456}]", InjectDelegateClassPatch.result);
        }
示例#11
0
        public void Test_ArrayArguments()
        {
            var harmony   = new Harmony("test");
            var processor = new PatchClassProcessor(harmony, typeof(ArgumentArrayPatches));
            var patches   = processor.Patch();

            Assert.NotNull(patches, "patches");
            Assert.AreEqual(1, patches.Count);

            ArgumentArrayPatches.prefixInput  = null;
            ArgumentArrayPatches.postfixInput = null;

            var instance = new ArgumentArrayMethods();
            var n1       = 8;
            var n2       = 9;
            var s1       = "A";
            var s2       = "B";
            var st1      = new ArgumentArrayMethods.SomeStruct()
            {
                n = 8
            };
            var st2 = new ArgumentArrayMethods.SomeStruct()
            {
                n = 9
            };
            var f1 = new float[] { 8f };
            var f2 = new float[] { 9f };

            instance.Method(
                n1, ref n2, out var n3,
                s1, ref s2, out var s3,
                st1, ref st2, out var st3,
                f1, ref f2, out var f3
                );

            // prefix input
            var r = ArgumentArrayPatches.prefixInput;
            var i = 0;

            Assert.AreEqual(8, r[i], $"prefix[{i++}]");
            Assert.AreEqual(9, r[i], $"prefix[{i++}]");
            Assert.AreEqual(0, r[i], $"prefix[{i++}]");

            Assert.AreEqual("A", r[i], $"prefix[{i++}]");
            Assert.AreEqual("B", r[i], $"prefix[{i++}]");
            Assert.AreEqual(null, r[i], $"prefix[{i++}]");

            Assert.AreEqual(8, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"prefix[{i++}]");
            Assert.AreEqual(9, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"prefix[{i++}]");
            Assert.AreEqual(0, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"prefix[{i++}]");

            Assert.AreEqual(8f, ((float[])r[i])[0], $"prefix[{i++}]");
            Assert.AreEqual(9f, ((float[])r[i])[0], $"prefix[{i++}]");
            Assert.AreEqual(null, (float[])r[i], $"prefix[{i++}]");

            // postfix input
            r = ArgumentArrayPatches.postfixInput;
            i = 0;
            Assert.AreEqual(8, r[i], $"postfix[{i++}]");
            Assert.AreEqual(123, r[i], $"postfix[{i++}]");
            Assert.AreEqual(456, r[i], $"postfix[{i++}]");

            Assert.AreEqual("A", r[i], $"postfix[{i++}]");
            Assert.AreEqual("abc", r[i], $"postfix[{i++}]");
            Assert.AreEqual("def", r[i], $"postfix[{i++}]");

            Assert.AreEqual(8, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"postfix[{i++}]");
            Assert.AreEqual(123, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"postfix[{i++}]");
            Assert.AreEqual(456, ((ArgumentArrayMethods.SomeStruct)r[i]).n, $"postfix[{i++}]");

            Assert.AreEqual(8f, ((float[])r[i])[0], $"postfix[{i++}]");
            Assert.AreEqual(5.6f, ((float[])r[i])[2], $"postfix[{i++}]");
            Assert.AreEqual(6.5f, ((float[])r[i])[2], $"postfix[{i++}]");

            // method output values
            Assert.AreEqual(123, n2, "n2");
            Assert.AreEqual(456, n3, "n3");
            Assert.AreEqual("abc", s2, "s2");
            Assert.AreEqual("def", s3, "s3");
            Assert.AreEqual(123, st2.n, "st2");
            Assert.AreEqual(456, st3.n, "st3");
            Assert.AreEqual(5.6f, f2[2], "f2");
            Assert.AreEqual(6.5f, f3[2], "f3");
        }
示例#12
0
        public void Enable(UnityModManager.ModEntry modEntry, Assembly assembly)
        {
            _logger = modEntry.Logger;

            if (Enabled)
            {
                Debug("Already enabled.");
                return;
            }

            using (ProcessLogger process = new ProcessLogger(_logger)) {
                try {
                    process.Log("Enabling.");
                    var dict = Harmony.VersionInfo(out var myVersion);
                    process.Log($"Harmony version: {myVersion}");
                    foreach (var entry in dict)
                    {
                        process.Log($"Mod {entry.Key} loaded with Harmony version {entry.Value}");
                    }

                    process.Log("Loading settings.");
                    modEntry.OnSaveGUI += HandleSaveGUI;
                    Version             = modEntry.Version;
                    Settings            = UnityModManager.ModSettings.Load <TSettings>(modEntry);
                    Core = new TCore();

                    Type[] types = assembly.GetTypes();

                    if (!Patched)
                    {
                        Harmony harmonyInstance = new Harmony(modEntry.Info.Id);
                        foreach (Type type in types)
                        {
                            List <HarmonyMethod> harmonyMethods = HarmonyMethodExtensions.GetFromType(type);
                            if (harmonyMethods != null && harmonyMethods.Count() > 0)
                            {
                                process.Log($"Patching: {type.FullName}");
                                try {
                                    PatchClassProcessor patchProcessor = harmonyInstance.CreateClassProcessor(type);
                                    patchProcessor.Patch();
                                }
                                catch (Exception e) {
                                    Error(e);
                                }
                            }
                        }
                        Patched = true;
                    }

                    Enabled = true;

                    process.Log("Registering events.");
                    _eventHandlers = types.Where(type => type != typeof(TCore) &&
                                                 !type.IsInterface && !type.IsAbstract && typeof(IModEventHandler).IsAssignableFrom(type))
                                     .Select(type => Activator.CreateInstance(type, true) as IModEventHandler).ToList();
                    if (Core is IModEventHandler core)
                    {
                        _eventHandlers.Add(core);
                    }
                    _eventHandlers.Sort((x, y) => x.Priority - y.Priority);

                    process.Log("Raising events: OnEnable()");
                    for (int i = 0; i < _eventHandlers.Count; i++)
                    {
                        _eventHandlers[i].HandleModEnable();
                    }
                }
                catch (Exception e) {
                    Error(e);
                    Disable(modEntry, true);
                    throw;
                }

                process.Log("Enabled.");
            }
        }