BaseChainloader.Execute invoked the Finished event inside the same
try/catch that reports plugin-loading failures, so an exception thrown
by a Finished event listener was logged as "Error occurred loading
plugins:" even though it was unrelated to plugin loading.
Move Finished?.Invoke() into its own try/catch with an accurate
message. Control flow is otherwise unchanged: Finished still runs only
after LoadPlugins succeeds, a throwing listener is still caught, and
"Chainloader startup complete" is still logged afterwards.
Fixes#842
The chainloader collected both not-installed dependencies and
installed-but-incompatible-version dependencies into one list and
reported them all as "missing dependencies", which is confusing when
the plugin is present but on a version outside the requested range.
Separate the two cases and log distinct, actionable messages: one for
dependencies that are not installed, and one for dependencies present
with an incompatible version (showing the found version and the
required range).
Also expand the BepInDependency(string, string) xmldoc: the version is
a SemVer range, link the range syntax, and warn about the BepInEx 5 ->
6 behaviour change (a bare version was a minimum, now it is exact).
Fixes#779
When the Unity base-libraries download fails (commonly a 404 for a
Unity version not yet hosted on unity.bepinex.dev), the uncaught
HttpRequestException surfaced only as a cryptic "Failed to generate
Il2Cpp interop assemblies" and the game would not launch -- even
though a local fallback (the unity-libs directory) already exists.
Catch the download failure and throw a clear message naming the Unity
version, the URL and the two workarounds: place a matching
base-libraries .zip in the unity-libs directory, or point the
[IL2CPP] UnityBaseLibrariesSource config at a valid URL.
Refs #1295, #1084, #986, #941, #515
Change the behaviors of the default providers so if multiple assemblies with the same name exists, but in different directories, ignore any that are located deeper.
Assemblies are often loaded on the il2cpp side but not on the mono side, causing confusion when using reflection.
This will load all interop assemblies right before plugins are loaded, which should mostly avoid these issues at a low time cost of around 40ms.