Fexty12573 / SharpPluginLoader

A C# plugin loader for Monster Hunter World
MIT License
32 stars 2 forks source link

[Bug] Crash on Plugin Load/Reload when The Game Is Running #21

Closed GreenComfyTea closed 6 months ago

GreenComfyTea commented 6 months ago

Describe The Bug

When the game is running, an attempt to copy-paste a new .dll or overwrite an existing .dll leads to a crash. I assume it is because the copying process locks the files, and the file change event is fired before the files are unlocked, which results in SharpPluginLoader attempting to read locked files.

The crash happens regardless on what is writting the dll:

  1. Manually copying -> sometimes crash;
  2. Building directly into \Monster Hunter World\nativePC\plugins\CSharp\ -> crash;
  3. Running the command xcopy "$(OutDir)" "D:\Programs\Steam\steamapps\common\Monster Hunter World\nativePC\plugins\CSharp\MHWTeaOverlay" /s /i /y as a post-build event -> crash.

SharpPluginLoader and the plugin itself are working normally in almost all other situations. (Except for ImGui having the viewport of 1920x1080 instead of 2880x1620 so it cuts in the middle of screen, but I haven't looked into it yet, it might be because i have super-sampled resolution).

The Exception:

[Core] Unhandled exception: IOException: The process cannot access the file 'D:\Programs\Steam\steamapps\common\Monster Hunter World\nativePC\plugins\CSharp\MHWTeaOverlay\MHWTeaOverlay.dll' because it is being used by another process., Stacktrace:
    at CreateFile (:0:0)
    at Open (:0:0)
    at .ctor (:0:0)
    at IsManageAssembly (:0:0)
    at <.ctor>b__12_2 (:0:0)
    at NotifyFileSystemEventArgs (:0:0)
    at ParseEventBufferAndNotifyForEach (:0:0)
    at ReadDirectoryChangesCallback (:0:0)
    at <StartRaisingEvents>b_85_0 (:0:0)
    at Invoke (:0:0)
    at System.Threading.IThreadPoolWorkItem.Execute (:0:0)
    at Dispatch (:0:0)
    at WorkerThreadStart (:0:0)

To Reproduce

  1. Place the plugin .dll into \Monster Hunter World\nativePC\plugins\CSharp;
  2. Launch the game, wait until Main Menu appears;
  3. Rebuild the plugin, copy-overwrite the existing plugin .dll with a new one in \Monster Hunter World\nativePC\plugins\CSharp;
  4. Crash.

Alternatively:

  1. Launch the game, wait until Main Menu appears;
  2. Place the plugin .dll into \Monster Hunter World\nativePC\plugins\CSharp;
  3. Crash.

Expected Behavior

No crash. SharpPluginLoader should handle the exception, wait until the copy process is done and the files are unlocked before attempting to load/reload the plugin.

Priority

Suggested P3 Priority. The issue directly affects plugin development but is circumvented by relaunching the game each time. The issue doesn't affect how plugins work and perform.

Screenshots/Video

Video

PC Specs

Environment

Game Display Settings

Game Advanced Graphics Settings

Mods and External Tools:

Additional Context

Plugin Repo

Nonetheless, I am very happy with the ability of making plugins in C#. Thank you for creating such a wonderful tool!❤️

Fexty12573 commented 6 months ago

Hi! Thank you very much for the very elaborate report. I have noticed this again before but haven't gotten around to actually fixing it yet. I'll try to make a basic workaround for now.

Fexty12573 commented 6 months ago

Pushed a fix in 02972748cb1f9f18a283967d3b4ca82f87ad0010. This will be part of 0.0.4, which most likely will release within the next couple of days.

PS: Awesome plugin, this is exactly the kind of stuff I envisioned when first creating this. Version 0.0.4 will also have support for loading arbitrary textures/images, so you'll be able to make the overlay look nicer 😄

GreenComfyTea commented 6 months ago

The fix works, thanks! 👍

PS: I guess our meet was destined. Was waiting for either Lua or C# framework to create an overlay mod for World that runs inside the game and not as an external tool, as I did for Rise. As soon as I noticed SPL in like december, I had my eyes wide open! 👀

PPS: I already can draw images thou, ImGui.GetBackgroundDrawList().AddImage() is there 🤔

PPPS: Just saw a PR for custom ImGui. With SPL now having more direct control over ImGui and seeing positive attitude and passion towards developing SPL, I think I will report some issues later that, perhaps, should be addressed by SPL itself, even thou I can fix them plugin-side. I want SPL to become better too!

Fexty12573 commented 6 months ago

Regarding ImGui.GetBackgroundDrawList().AddImage(), yes, that's the intention after all. What I meant by "loading textures/images" is the process of actually creating the relevant Direct3D resources. That function expects an ID3D11ShaderResourceView* when running in DX11 and a D3D12_GPU_DESCRIPTOR_HANDLE when running in DX12.

Sure you could technically pull in the entirety of Silk.NET or something similar and start making graphics api calls yourself but... that's honestly a pain.

The API aims to abstract away all of the low level Direct3D calls in a graphics-api agnostic manner. I.e. you will not have to worry about if the game is running in DX11 or 12 mode and you can just call a LoadTexture function to load any .dds/.png/.jpg and pass that to the ImGui.*Image functions.

PPPS: Please do!

GreenComfyTea commented 6 months ago

Fair enough! ;3