Comments (9)
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.
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.
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.
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.
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:
- At least 2 patches are needed. I used Window.PreOpen() as the other patch for all tests.
- Add the PreClose() patch to the project AFTER adding the PreOpen() patch
- All compiles will now crash when closing any window
- Here is a log of this specific situation with PreClose()
- Here is a log of this specific situation with ExtraOnGUI()
To reproduce a semi-working example:
- Have only a single patch OR add the PreClose() patch to the project BEFORE adding the PreOpen() patch (ie, add the PreClose patch first)
- All compiles will now load without crashing, but still do not work as expected. For example, PreClose will be called on any window close, but PreOpen will only be called when Page_ModsConfig opens, with the latter being the expected behaviour.
- Here is a log of this specific situation with PreClose() (Notice how many times PreClose is called compared to PreOpen)
- Here is a log of this specific situation with ExtraOnGUI() (The patch is being called on every Window.ExtraOnGUI rather than only on Page_ModsConfig.ExtraOnGUI)
- This is a kind of work around for the issue as you can check the window type before executing code, but its limiting as you can only have one working patched virtual method. For example, you could not patch both PreClose and ExtraOnGUI.
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.
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.
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.
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.
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)
- RtDynamicMethod get MetadataToken throws InvalidOperationException HOT 2
- Patch on .net 7&8 throw TypeLoadException while debugging HOT 18
- Harmony 3.0: Utility Epic
- Investigate Testing the NuGet Package Directly HOT 3
- Add a Release Pipeline
- Hook exception: System.Exception: Cannot get result from void method System.Void HOT 2
- How to patch method of base class? HOT 1
- When applying a patch fails, the replacement's IL is not printed to the debug log HOT 2
- System.Exception: Parameter "xx" not found in method HOT 10
- SymbolExtensions does not resolve overriden method HOT 3
- can lib work in arm64? HOT 2
- Companion project promotion: Harmony Tools HOT 3
- PatchFunctions.UpdateWrapper NotImplementedException on MacOS HOT 11
- How do i change valuetype HOT 1
- Harmony.Patch() is a bit slow. HOT 2
- 'CORINFO_METHOD_INFO' from assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. HOT 4
- I try to hook DateTime.UtcNow but it throw exception HOT 5
- IL Compile Error when using PrefixFactory to provide a non-static Prefix method (Mono)
- x86 platform makes patch fail
- return type only support void and bool? why doesn't string work HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from harmony.