justalemon / PlayerCompanion

Mod for GTA V that adds some extra features for Addon Peds and the Player Characters
MIT License
12 stars 1 forks source link

Update Newtonsoft.Json? #7

Closed WithLithum closed 3 years ago

WithLithum commented 3 years ago

I was creating a project earlier, but when I got into the game, the script crashes. After investigating, it turns out that I referenced the latest version of Newtonsoft.Json while PC referenced 12.0.3, with the Newtonsoft.Json assembly is signed with strong name (means your mod wont load if it found different assembly than it built with).

Workaround would be forcing projects that needs to reference Newtonsoft.Json to use 12.0.3.

WithLithum commented 3 years ago

I wrote a proof-of-concept project that reference Newtonsoft.Json 13.0.1 instead of 12.0.3, and it resulted like this:

Failed to instantiate script Jobs.Main because constructor threw an exception: System.IO.FileLoadException: Failed to load assembly “Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed” or one of it's dependencies. The located assembly's manifest definition doesn't match the assembly reference. (from HRESULT:0x80131040)
File name:“Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”
   at Jobs.Main..ctor()

The text above was translated and may or may not match the correct text in english.

justalemon commented 3 years ago

Weird, as I never had problems with mismatched Newtonsoft.Json versions.

If I update from 12 to 13 ill probably have to recompile every single mod that uses 12 to work with 13.

WithLithum commented 3 years ago

Well. Since SHVDN uses scripts folder and game folder for all dependencies (and RPH with the game folder only), DLL Hell was unavoidable. Building Newtonsoft.Json assemblies for SHVDN use without strong-signing could solve this.

justalemon commented 3 years ago

Hold up, I think I got this one. From Strong-named assemblies at the .NET Docs:

  • An app needs access to different versions of the same assembly. This means you need different versions of an assembly to load side by side in the same app domain without conflict. For example, if different extensions of an API exist in assemblies that have the same simple name, strong-naming provides a unique identity for each version of the assembly.
justalemon commented 3 years ago

Maybe I just need to ship the Newtonsoft.Json DLL with a different name? Kinda like Newtonsoft.Json_VERSION.dll, so SHVDN uses the correct assembly for the different mods.

The wrong part? There might be lot of unused DLL files in the long term for users.

WithLithum commented 3 years ago

If a user didn't clean up properly, they sure will probably left tons of assemblies in their game directory. Someone might want to build a Newtonsoft.Json without strong-name signing, or SHVDN could bring a major overhaul to their dependency management system to isolate dependencies just like these normal apps.

I will clear those reference next time I reply via email client.

justalemon commented 3 years ago

Someone might want to build a Newtonsoft.Json without strong-name signing

Probably not an option for me, as that would require recompilation on every Newtonsoft.Json update and manual installation by the end user which might cause further confusion.

or SHVDN could bring a major overhaul to their dependency management system to isolate dependencies just like these normal apps

This will probably be the best option.

ScriptHookVDotNet already supports loading DLLs from subdirectories, but not the dependencies of the game Scripts (in other words, those that inherit from GTA.Script will load but not the dependencies of it as that requires them to be in the scripts directory).

Quick example:

image image

[02:03:04] [DEBUG] Loading API from .\ScriptHookVDotNet2.dll ... [02:03:04] [DEBUG] Loading API from .\ScriptHookVDotNet3.dll ... [02:03:04] [DEBUG] Loading scripts from E:\Grand Theft Auto V - Modded\scripts ... [02:03:04] [DEBUG] Loading assembly $PlayerCompanion.RuntimePatching.dll ... [02:03:04] [INFO] Found 1 script(s) in $PlayerCompanion.RuntimePatching.dll resolved to API 3.1.0. [02:03:04] [DEBUG] Loading assembly 0Harmony.dll ... [02:03:04] [INFO] Found 0 script(s) in 0Harmony.dll. [02:03:04] [DEBUG] Loading assembly LemonUI.SHVDN3.dll ... [02:03:05] [INFO] Found 0 script(s) in LemonUI.SHVDN3.dll. [02:03:05] [DEBUG] Loading assembly Newtonsoft.Json.dll ... [02:03:05] [INFO] Found 0 script(s) in Newtonsoft.Json.dll. [02:03:05] [DEBUG] Loading assembly PlayerCompanion.dll ... [02:03:05] [ERROR] Failed to load assembly PlayerCompanion.dll: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified. File name: 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'

WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

[02:03:05] [DEBUG] Instantiating script PlayerCompanion.RuntimePatching.Patcher ... [02:03:05] [INFO] Started script PlayerCompanion.RuntimePatching.Patcher.

justalemon commented 3 years ago

Looks like I just had to add an App.config to the csproj and then tell .NET to redirect v12 to v13. That appears to have fixed it and should allow you to use v13 in your project.

is this the right way? Probably not. But hey! It works!

Ill close this issue now, but feel free to leave a comment if commit 2162c96f123a59580058cdc0b82b23f446b29ae2 does not works for you.

image

WithLithum commented 3 years ago

I might using the wrong version, but it still says FileNotFoundException. It still won't work even after I downloaded 13.0.1 from GitHub releases.

justalemon commented 3 years ago

I used the Newtonsoft.Json.dll from NuGet (net45, 13.0.1).

WithLithum commented 3 years ago

I am using pretty much the same. I simply upgraded to new Newtonsoft.Json version, grabbed the build from 5Mods, and copied it over, then I copied the Newtonsoft.Json.dll directly from my Debug folder, and it crashes still.