Title: Duplicate loading of plugins · Issue #129 · RocketModFix/RocketModFix · GitHub
Open Graph Title: Duplicate loading of plugins · Issue #129 · RocketModFix/RocketModFix
X Title: Duplicate loading of plugins · Issue #129 · RocketModFix/RocketModFix
Description: General Related to #9 I accidentally came across a problem with undefined static behavior in plugins, which led to a critical bug in Rocket.Core.Plugins.RocketPluginManager. The core of the issue lies in plugins being loaded into the gam...
Open Graph Description: General Related to #9 I accidentally came across a problem with undefined static behavior in plugins, which led to a critical bug in Rocket.Core.Plugins.RocketPluginManager. The core of the issue l...
X Description: General Related to #9 I accidentally came across a problem with undefined static behavior in plugins, which led to a critical bug in Rocket.Core.Plugins.RocketPluginManager. The core of the issue l...
Opengraph URL: https://github.com/RocketModFix/RocketModFix/issues/129
X: @github
Domain: patch-diff.githubusercontent.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Duplicate loading of plugins","articleBody":"### General\n\nRelated to #9 \n\nI accidentally came across a problem with undefined static behavior in plugins, which led to a critical bug in `Rocket.Core.Plugins.RocketPluginManager`.\n\nThe core of the issue lies in plugins being loaded into the game process multiple times due to an incorrect DLL loading order.\n\nThis behavior completely breaks the Singleton pattern, effectively turning it into a kind of \"Dualton\".\n\nThe problem is easier to illustrate with an example.\n\n---\n\n### Example/Reproduce\n\nThe `Rocket/Plugins` folder contains the following files:\n- `ADependantPlugin.dll`\n- `CorePlugin.dll`\n\nHere, `ADependantPlugin.dll` references code from `CorePlugin.dll` (the files order matters in this case).\n\nReferencing the code from:\n- https://github.com/RocketModFix/RocketModFix/blob/19e5b744460b8da4a91236154c7af26960c3a9d8/Rocket/Rocket.Core/Plugins/RocketPluginManager.cs#L78\n- https://github.com/RocketModFix/RocketModFix/blob/19e5b744460b8da4a91236154c7af26960c3a9d8/Rocket/Rocket.Core/Plugins/RocketPluginManager.cs#L43\n\nRocket’s behavior is as follows:\n- It caches the paths to all unique DLLs from `Rocket/Libraries` and `Rocket/Plugins`.\n- It starts loading DLLs from `Rocket/Plugins` sequentially into the game process.\n- It loads `ADependantPlugin.dll`, which requires `CorePlugin.dll`.\n- Through `OnAssemblyResolve`, `CorePlugin.dll` is loaded using `Assembly.Load()`.\n- Later, `CorePlugin.dll` is loaded again via `Assembly.LoadFile()` inside the loop of `LoadAssembliesFromDirectory()`.\n\nAs a result, we end up with two identical DLLs loaded into the game. This causes static constructors to be called twice.\n\nSo, even if `public static CorePlugin Instance { get; private set; }` was set during `Load()` of the `CorePlugin`, it will be reset to `null` upon repeated access, throwing an exception.\n\n---\n\n### Note\n\nAt the moment, I haven’t had time to create a repository to reproduce the issue, as I discovered it while working on a client project.\n\nHowever, if a repro repository is needed, feel free to ask and I’ll be happy to provide one.\n\nThe issue can be temporarily resolved by renaming `ADependantPlugin.dll` to `DependantPlugin.dll`, so it loads **after** `CorePlugin.dll`, as the folder content becomes:\n- `CorePlugin.dll`\n- `DependantPlugin.dll`\n\n\n\n### Conclusion\nDespite the possibility of working around this issue, I believe this kind of hidden bug is extremely problematic.","author":{"url":"https://github.com/IlyaSergeevich0","@type":"Person","name":"IlyaSergeevich0"},"datePublished":"2025-05-06T01:07:27.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/129/RocketModFix/issues/129"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:18ef216e-0741-9b9d-8043-419049bf06e1 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 9A22:1A3D6D:7F79E7:A841BC:698EC191 |
| html-safe-nonce | dd36f1d52616ab4f3aa0989cc8c936c2590c98bfddbf0e47dddcd47414693390 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5QTIyOjFBM0Q2RDo3Rjc5RTc6QTg0MUJDOjY5OEVDMTkxIiwidmlzaXRvcl9pZCI6IjUxMzAxNjY3NDU1MjUzMDU3NDUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 2ad1251661695eca9af07a4beca045d97ccb426b9a766a22924c06c312556237 |
| hovercard-subject-tag | issue:3041199471 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/RocketModFix/RocketModFix/129/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c1df4d0252fc347b70f5e2e3bf77e2eeb6a552476a6b973af9798bff10e8c78e/RocketModFix/RocketModFix/issues/129 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c1df4d0252fc347b70f5e2e3bf77e2eeb6a552476a6b973af9798bff10e8c78e/RocketModFix/RocketModFix/issues/129 |
| og:image:alt | General Related to #9 I accidentally came across a problem with undefined static behavior in plugins, which led to a critical bug in Rocket.Core.Plugins.RocketPluginManager. The core of the issue l... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | IlyaSergeevich0 |
| hostname | github.com |
| expected-hostname | github.com |
| None | cb2828a801ee6b7be618f3ac76fbf55def35bbc30f053a9c41bf90210b8b72ba |
| turbo-cache-control | no-preview |
| go-import | github.com/RocketModFix/RocketModFix git https://github.com/RocketModFix/RocketModFix.git |
| octolytics-dimension-user_id | 148712015 |
| octolytics-dimension-user_login | RocketModFix |
| octolytics-dimension-repository_id | 708477287 |
| octolytics-dimension-repository_nwo | RocketModFix/RocketModFix |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | true |
| octolytics-dimension-repository_parent_id | 259763703 |
| octolytics-dimension-repository_parent_nwo | SmartlyDressedGames/Legally-Distinct-Missile |
| octolytics-dimension-repository_network_root_id | 259763703 |
| octolytics-dimension-repository_network_root_nwo | SmartlyDressedGames/Legally-Distinct-Missile |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e6b91a7e6e46287d26887e3fb7a4161657bab8f7 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width