Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Allow loading of mods with unloadable types #83

Merged
merged 3 commits into from
Mar 10, 2023
Merged

Conversation

zkxs
Copy link
Collaborator

@zkxs zkxs commented Mar 7, 2023

Short story: this fixes New-Project-Final-Final-WIP/HeadlessTweaks#4.

Long story: It turns out some mods have types that cannot be loaded at runtime, because assemblies they depend on are in turn not loaded. .NET really doesn't like if you try to inspect those types with reflection, which both NML and Neos try to do. Two things were done to fix this:

  1. ModLoader.cs now loads types through an alternate, safer mechanism (that's an evil hack involving slinging a bunch of exceptions around)
  2. If Neos tries to call AppDomain.CurrentDomain.GetAssemblies() we intercept that and filter out mod assemblies

With these fixes in place I've confirmed that HeadlessTweaks no longer crashes on Windows headless.

@zkxs zkxs changed the title Evil type load hack to allow loading of mods with unloadable types Evil hack to allow loading of mods with unloadable types Mar 7, 2023
@zkxs zkxs changed the title Evil hack to allow loading of mods with unloadable types Allow loading of mods with unloadable types Mar 7, 2023
Copy link
Member

@ljoonal ljoonal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't say I really understand the implications of this change, though the code seems good enough, so leaving it at least for a while others to comment & approve if they understand it better...

NeosModLoader/ModLoader.cs Show resolved Hide resolved
NeosModLoader/AssemblyHider.cs Show resolved Hide resolved

private static bool IsModType(Type type)
{
return IsModAssembly(type.Assembly, "type", type.ToString(), true, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also quite a few parameters, which starts getting a bit messy keeping track of which one is which, would probably be clearer if named params are a available in net472? Or alternatively could change the input type to be an object, but iirc that wasn't as convenient in .NET...

Copy link
Collaborator Author

@zkxs zkxs Mar 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've named the bools and added some more method docs in f24d079

... and also fixed a blunder in some of my boolean algebra

@zkxs
Copy link
Collaborator Author

zkxs commented Mar 8, 2023

Can't say I really understand the implications of this change...

Oh yeah. The fact that I'm patching AppDomain.GetAssemblies is ludicrous. My plan is to pre-release this and have a couple of people who are affected by New-Project-Final-Final-WIP/HeadlessTweaks#4 test it out. If they don't notice anything going terribly wrong after a while, then I'll promote it to a real release.

You might be wondering why I didn't just patch the Neos methods that were calling AppDomain.GetAssemblies. It's because they have generics on the method and Harmony implodes if you try and patch them. I was actually able to segfault .NET when I tried, which is insane.

Copy link
Member

@ljoonal ljoonal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seal

@zkxs zkxs merged commit 70ce801 into master Mar 10, 2023
@ljoonal ljoonal deleted the evil-type-load-hack branch March 10, 2023 17:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ReflectionTypeLoadException on Windows Headless
2 participants