New-Project-Final-Final-WIP / HeadlessTweaks

A ResoniteModLoader mod for Resonite. Adds some nice to have features to headless clients
MIT License
14 stars 3 forks source link

ReflectionTypeLoadException on Windows Headless #4

Closed zkxs closed 1 year ago

zkxs commented 1 year ago

full log file

This is a brand new headless install with all default configs, and the only installed mod is HeadlessTweaks v1.2.0.

My reproduction steps:

  1. Install Neos Headless on Windows
  2. Install NeosModLoader and HeadlessTweaks
  3. Unblock NeosModLoaderHeadless.dll, 0Harmony.dll, and HeadlessTweaks.dll in the Windows file properties
  4. Do the evil symlink hack
  5. Run Neos.exe -LoadAssembly "Libraries/NeosModLoaderHeadless.dll"

Now here's the haunted part: I also installed HeadlessTweaks into my normal, head-having Windows install and it didn't throw a ReflectionTypeLoadException. So either .NET is just behaving strangely and differently for the Headless instance, or something in these three lines is causing issues. But also it's crashing before it's even able to hit the "Discord.NET library not found" log, so I'm just confused.

badhaloninja commented 1 year ago

The error is thrown in NML before the OnEngineInit function is even called

From what I remember the error gets thrown here at the GetTypes call because it tries to load every type in my assembly even the ones referencing unloaded types

zkxs commented 1 year ago

If NML was the culprit I'd expect it to have crashed when I ran it on Windows headed. But it actually worked fine. But I see what you're saying: it's not OnEngineInit() that's crashing, it's InitializeMod(). So there's something going on here I still don't understand. For some reason headed can handle this case, while headless can't.

Windows Headed Log Snippet:

11:02:27 PM.100 (  0 FPS)    [DEBUG][NeosModLoader] calling OnEngineInit() for [HeadlessTweaks]
11:02:28 PM.317 (  0 FPS)    [INFO] [NeosModLoader/HeadlessTweaks] Discord.NET library not found
11:02:28 PM.317 (  0 FPS)    [WARN] [NeosModLoader/HeadlessTweaks] Headless Not Detected! Skipping headless specific modules

full log because snippets are annoying

zkxs commented 1 year ago

I'm thinking the move here is to make a test build of NML that pulls the NeosMod type out of an assembly attribute instead of a type scan. So you'd add something like [assembly: NeosMod(typeof(HeadlessTweaks))] to your AssemblyInfo.cs, and this would opt you out of the type scan.

badhaloninja commented 1 year ago

I don't know the reason why there's a difference between headless and headed, might have something to do with why windows headless is more type sensitive than the other versions Just remembered I'm pretty sure this also happens to linux headless, but my test environment is broken currently

On windows headless the error is thrown before OnEngineInit() is called

[INFO] [NeosModLoader] Compatibility hash spoofing succeeded
[INFO] [NeosModLoader] loading assemblies from nml_mods
[DEBUG][NeosModLoader] load assembly HeadlessTweaks.dll
[ERROR][NeosModLoader] ReflectionTypeLoadException initializing mod from C:\Program Files (x86)\Steam\steamapps\common\NeosVR\Tools\HeadlessClient\nml_mods\HeadlessTweaks.dll:
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeModule.GetTypes()
   at System.Reflection.Assembly.GetTypes()
   at NeosModLoader.ModLoader.InitializeMod(AssemblyFile mod)
   at NeosModLoader.ModLoader.LoadMods(Harmony harmony)
badhaloninja commented 1 year ago

I'm thinking the move here is to make a test build of NML that pulls the NeosMod type out of an assembly attribute instead of a type scan. So you'd add something like [assembly: NeosMod(typeof(HeadlessTweaks))] to your AssemblyInfo.cs, and this would opt you out of the type scan.

I found this earlier which seems a little gross but

zkxs commented 1 year ago

Oh that's terrible. I'm using it immediately.

zkxs commented 1 year ago

Well, as I was able to fix this with NML changes alone this issue clearly doesn't represent a HeadlessTweaks bug, so I'm closing it.