Giter Site home page Giter Site logo

Comments (9)

rheirman avatar rheirman commented on August 25, 2024

I had exactly the same issue when I tried patching MentalState.PostStart.
Both MentalState.PostStart and Window.PreClose are virtual methods, so I expect that the problem occurs when virtual methods are patched. This issue can easily be overlooked by modders as it doesn't cause problems on Windows machines, so I'm afraid the impact is quite big.

from harmony.

pardeike avatar pardeike commented on August 25, 2024

If this problem is in fact specific to virtual methods on everything non-Windows I need to look into a way to fix it. It could be a limitation on the CIL architecture.

from harmony.

scuba156 avatar scuba156 commented on August 25, 2024

Window.ExtraOnGUI() also crashes which is also virtual.

I did some testing. I can get these patches to work fine if there is only one patch applied, but will crash as soon as you add any other patch.

Here is a log from using ExtraOnGUI and PreClose for Page_ModsConfig, with the crash triggering when closing the console window.

Edit: I noticed that relaunching RimWorld without recompile would give me different logs each time.

1.
2.
3. <- The log got spammed as I have a log event inside of each patch.

from harmony.

pardeike avatar pardeike commented on August 25, 2024

I'm closing this. Cannot reproduce with the latest version. Tested on my Mac with the latest macos and latest Rimworld version with Window.PreClose() double patched.

from harmony.

scuba156 avatar scuba156 commented on August 25, 2024

Still an issue here. I can reproduce the crash, but I can also reproduce it working (kind of). This might be a long post as I'm just going to dump all the info I have here for now.

First off, all my patches are specifically patching Page_ModsConfig methods and are postfix's as this is what my target is, but I can reproduce it for any window. Patching Window directly gives the same results.

Second, the same happens with Window.ExtraOnGUI() in place of PreClose().

I tested in a new test project, this is the only code executed in my main class:

public class Main : Mod
    {
        public Main(ModContentPack content) : base(content)
        {
            Log.Message(string.Format("Starting {0}", content.Name));
            var harmonyInstance = HarmonyInstance.Create("com.scuba156.Harmony_Crash_Test");
            harmonyInstance.PatchAll(Assembly.GetExecutingAssembly());

            foreach (var patchedMethod in harmonyInstance.GetPatchedMethods())
            {
                Log.Message(string.Format("Patched {0}", patchedMethod.Name));
            }

            Log.Message("Everything is loaded, ready to crash!");
        }
    }

Each patch just outputs a line to the log when it is called. Below is an example of my PreClose patch:

    [HarmonyPatch]
    [HarmonyPatch(typeof(Page_ModsConfig))]
    [HarmonyPatch("PreClose")]
    public static class PreClose_Patch {

        public static void Postfix(this Page_ModsConfig __instance) {
            Log.Message("PreClose Postfix called");
        }
    }

To reproduce a non-working example:

To reproduce a semi-working example:

Note the order that the patches are loaded in each log. I would suspect that the crash would also be reproduced by manually patching each method in a specific order rather than adding them to the project in a specific order and using PatchAll(). I haven't tested this as I'm too lazy to do it right now. I can later on though. This was all tested on Linux Mint 18.3 compiled with MonoDevelop 7.4. The same issue was previously tested on Ubuntu and OS X compiled with Visual Studio on Windows 10

from harmony.

pardeike avatar pardeike commented on August 25, 2024

Harmony only patches methods where there is a real method with IL code in the assembly. Page_ModsConfig has no PreClose and therefore you cannot patch it. You cannot argue inheritance when patching. That's not how this works.

from harmony.

pardeike avatar pardeike commented on August 25, 2024

As a follow up, I am going to make sure you can only patch declared methods and let Harmony throw a "method not found" error when the method isn't implemented in the class you specify.

from harmony.

scuba156 avatar scuba156 commented on August 25, 2024

As I said, "Patching Window directly gives the same results." and "I can reproduce it for any window."

While you are correct about the inheritance, and I did not have the chance to look directly at the source today to see if Page_ModsConfig actually exists, the CTD will still occur regardless.

from harmony.

pardeike avatar pardeike commented on August 25, 2024

Something funky goes on. I am currently testing to patch .NET 4+ classes to test Harmony and I get several cases where the patch order matters or else it crashes hard. Quite tricky to debug since it involves undocumented mono/NET API.

from harmony.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.