lavagang / melonloader Goto Github PK
View Code? Open in Web Editor NEWThe World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono
Home Page: https://discord.gg/2Wn3N2P
License: Apache License 2.0
The World's First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono
Home Page: https://discord.gg/2Wn3N2P
License: Apache License 2.0
The version of SharpZipLib implemented is outdated.
If a mod or plugin adds the VerifyLoaderVersion
attribute but the version number set has a higher mark value than current (such as the major, minor, patch, or revision on its own) the check fails and deems the mod or plugin as incompatible.
This should be changed.
MelonLoader is already setup to handle dnSpy's Debugger and Environment Variables.
Should probably state its usage in the README and Wiki.
To use it currently just run MelonLoader in Debug Mode and follow the steps in this GUIDE after the part about replacing files.
It should work without replacing any files.
Using a non static prefix with HarmonyInstance.Patch throws the following cryptic error
[ERROR] Exception in Harmony patch of method void VRC.UI.PageWorldInfo::Method_Public_Void_ApiWorld_ApiWorldInstance_Boolean_Boolean_Boolean_APIUser_0(VRC.Core.ApiWorld param_1, VRC.Core.ApiWorldInstance param_2, bool param_3, bool param_4, bool param_5, VRC.Core.APIUser param_6):
System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method) VRC.UI.PageWorldInfo:DMD<VRC.UI.PageWorldInfo::Method_Public_Void_ApiWorld_ApiWorldInstance_Boolean_Boolean_Boolean_APIUser_0> (VRC.UI.PageWorldInfo,VRC.Core.ApiWorld,VRC.Core.ApiWorldInstance,bool,bool,bool,VRC.Core.APIUser): IL_0002: call 0x00000001
Needs to be investigated - if it's a fault in the harmony lib it needs to be reported upstream, if it's a fault in the il2cpp patching code, it needs to be fixed our side.
Title says it all.
Useful for users with Multi-Display Setups.
MonoResolveManager appears to induce crashing on x86 Platform.
More work is needed.
Log File Attached
text.txt
If MelonLoader happens to get installed to something that isn't a Unity Game the Proxy still gets loaded.
This forces the loading of the Bootstrap causing errors and crashing as it fails to initialize.
A built-in check in the Proxy for if it is a Unity Game would solve this.
Possibly with a Warning Popup Message.
I'm having an error while opening a game with melon loader 0.5.2 when it tries to initialize and contact the remote API. Seems to be a TLS connection problem, as said in the title I'm on Windows 7.
Following this page, I added the registry keys and have the KB update installed, but it still gives the same error.
Log: [REDACTED]
Add Windows 11 to Core::GetOSVersion
An attribute that lets the Developer of the Melon set an ID to be printed for the Melon.
Useful for things like CurseForge for example where its easier to lookup an ID for the Melon rather than just the Name itself.
Originally Suggested by @PyrrhaDevs
Latest.log
file included. If no file exists then leave this unchecked and state so.Whenever I try to install MelonLoader on to BONEWORKS it just says internal failure and makes a .txt file in my downloads
MLInstaller_22-1-18_13-38-40.771.log
{Game_Directory}\MelonLoader\Latest.log
The F# compiler creates symbols with @
in the name. (Usually in static variables)
As a result, MelonLoader refuses to load any assemblies created in F# due to AssemblyVerifier not whitelisting it.
As the title suggests OnApplicationStart can run too Early on some Mono Games.
This causes unintended behavior for things like GameObjects when instantiated from OnApplicationStart.
Resulting in it ignoring DontDestroyOnLoad or hideFlags, hideFlags causing components not to run, the GameObject getting destroyed on first Scene Load, etc.
Because Unity Assertion is annoying af
Latest.log
file included. If no file exists then leave this unchecked and state so.Both logo and background are not animated. The first frame is shown but doesn't continue like loading does.
{Game_Directory}\MelonLoader\Latest.log
Latest.log
file included. If no file exists then leave this unchecked and state so.I'm working on a mod for VRChat that triggered a bug in 0.5.2. So, to prevent users from using an earlier version, I moved to add the VerifyLoaderVersion
attribute to the assembly. This resulted in the following log (I killed VRChat with CTRL+C after it failed to load the mod).
Code:
[assembly: VerifyLoaderVersion(0,5,3,true)] // Bug in ML 0.5.2 results in false obfuscation detection.
Log:
Latest.log
{Game_Directory}\MelonLoader\Latest.log
Currently MelonLoader just adds multiple custom Assembly Resolve events.
This can have conflict issues in certain use-cases.
The Fix would most likely be changing it to a single custom event or to a central Manager that will handle resolving and redirection.
Some examples of these conflicts are:
• Assembly being resolved to the wrong Assembly.
• Assembly being resolved to the wrong Version.
• Compatibility Layer System overriding File Loads when its not supposed to.
• Compatibility Layer System not overriding File Loads when its supposed to.
After: #94
Mono Library included files can be moved from MelonLoader/Managed to its own Managed folder within the Mono Library Dependencies folder.
Keep all Il2Cpp Generated Assemblies within MelonLoader/Managed.
This will not only clean up the Managed folder but also prevent confusion from developers.
The library files are usually referenced and included from the .NET SDK by the IDE anyways instead of manually referencing from a Managed folder.
We now have the Loading image customizable.
Might as well make everything else customizable to the end-user too.
Some games are missing the System.Drawing
library, making the start screen fails to load.
Some of the ways to fix this are:
System.Drawing
System.Drawing
inside MelonStartScreen.dll
It is hardly used and only causes more issues for the end user to have it load Plugins and Mods from ZIP Archives.
Should remove this and instead throw an error if the file type isn't in the compatible list of extensions.
Extension |
---|
.dll |
.txt |
.json |
.xml |
.mdb |
.pdb |
.md |
For one of the games i am modding, i get a msg "Unable to connect to 127.0.0.1:15881"
I was wondering if there might be a way to suppress this msg.
Usually, if the msg comes from melon loader, it will have [00:00:00.000] before the msg.
or if it comes from a mod, it will have [Mod Name] before, but this error has nothing.
Currently with the way it is designed MelonPreferences_ReflectiveCategory matches a type to only 1 specific category.
This causes a problem when trying to use the same type for multiple categories.
This setup is most common within wine/proton environments where the game dir is mapped to be the D drive, etc.
Mono::CheckLibName tries to check if base_path (which is, in this case, D:
) exists, which it apparently doesn't (missing backslash? root of drive "doesn't exist" according to windows/wine/proton? who knows), and therefore fails, even though the rest of the method would succeed.
This results in an Internal Failure thrown from Mono::SetupPaths because CheckFolderName returns an empty string for every folder.
I suggest simply removing the check for base_path existing and just bailing out if new_path doesn't exist, because clearly base_path must exist in all callers to this method, even if explicitly checking that fact says it doesn't.
MelonLoader only uses level 3 logging (Log
, Warning
, Error
)
Other logging libraries such as slf4j use 5/6/7 level logging.
The common log levels are
Trace
Debug
Info
Notification
(Level 7)Warning
Error
Fatal
(Level 6)In my implementations, Trace
and Debug
are hidden by default and only should show up with a command line option or in the log file.
Latest.log
file included. If no file exists then leave this unchecked and state so.{Game_Directory}\MelonLoader\Latest.log
Latest.log
file included. If no file exists then leave this unchecked and state so.Issue is reproducible by multiple people. Latest.log attached.
Latest.log
{Game_Directory}\MelonLoader\Latest.log
It was reported that Process.MainWindowTitle sometimes returns null.
It might be down to some Mono weirdness.
Need to patch this behavior.
The Bhaptics API implementation in MelonLoader uses the TryGetExePath export to check if the Bhaptics Player is installed.
This causes a problem as TryGetExePath only checks and returns a registry value.
A registry value that only gets set by the installer for the Bhaptics Player when downloaded from their website and not from Steam.
If someone tries to use just the Steam version of the Bhaptics Player without the one from their website it will act as if the user doesn't have the Player installed.
Resulting in the API never initializing and anything using it to fail.
The fix would be to parse Steam Library files and check if the Bhaptics Player is installed from Steam as a fallback.
Failed to download cpp2il and failed to download Unhollower
almost because of the same reason and I don't know why.
[ERROR] System.Net.WebException: Error: SecureChannelFailure (The authentication or decryption has failed.) ---> System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) [0x00037] in <c7286d73afb545c3a75377349eeda263>:0
at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (System.IAsyncResult ar, System.Boolean ignoreEmpty) [0x00000] in <c7286d73afb545c3a75377349eeda263>:0
at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (System.IAsyncResult result) [0x00071] in <c7286d73afb545c3a75377349eeda263>:0
--- End of inner exception stack trace ---
at Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (System.IAsyncResult result) [0x00032] in <c7286d73afb545c3a75377349eeda263>:0
at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (System.IAsyncResult asyncResult) [0x0000c] in <c7286d73afb545c3a75377349eeda263>:0
--- End of inner exception stack trace ---
at Mono.Security.Protocol.Tls.SslStreamBase.EndRead (System.IAsyncResult asyncResult) [0x0004b] in <c7286d73afb545c3a75377349eeda263>:0
at Mono.Net.Security.Private.LegacySslStream.EndAuthenticateAsClient (System.IAsyncResult asyncResult) [0x0000e] in <d2957de1c3fd4781a43d89572183136c>:0
at Mono.Net.Security.Private.LegacySslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) [0x0000e] in <d2957de1c3fd4781a43d89572183136c>:0
at Mono.Net.Security.MonoTlsStream.CreateStream (System.Byte[] buffer) [0x0007b] in <d2957de1c3fd4781a43d89572183136c>:0
at System.Net.WebConnection.CreateStream (System.Net.HttpWebRequest request) [0x00073] in <d2957de1c3fd4781a43d89572183136c>:0
--- End of inner exception stack trace ---
at System.Net.WebClient.DownloadFile (System.Uri address, System.String fileName) [0x000ad] in <d2957de1c3fd4781a43d89572183136c>:0
at System.Net.WebClient.DownloadFile (System.String address, System.String fileName) [0x00016] in <d2957de1c3fd4781a43d89572183136c>:0
at (wrapper remoting-invoke-with-check) System.Net.WebClient.DownloadFile(string,string)
at MelonLoader.Il2CppAssemblyGenerator.Packages.PackageBase.Download (System.Boolean directory_check) [0x00074] in <9bcfd816514243cb928753d2db66f6d7>:0
[13:31:53.501] [INTERNAL FAILURE] Failed to Download Il2CppAssemblyUnhollower!
When the Mono TLS Bridge fails it stops loading ML.
This should be changed to let ML load even when the bridge fails.
Example: #133
I'm trying to debug Terraforming Mars on Windows.
I turned the release build into a debug build with the help of this guide: https://github.com/dnSpy/dnSpy/wiki/Debugging-Unity-Games
But starting the game with the "--melonloader.debug" option now crashes on startup at:
"[21:20:50.698] [DEBUG] Creating Mono Domain..."
Some Melons may depend on native libraries and should have a directory where they can store those dependencies.
While I understand you can just tell the user to put the library into Unity's Plugins folder, I feel like Melons should still store all their dependencies in MelonLoader-generated directories.
Originally reported by @bbepis
Some games don't ship with app.info.
Resulting in MelonLoader running things in Universal Fallback as if everything is Universal.
This also causes the MelonGame attribute to just not be checked or used at all.
Solution is some kind of signature scan of globalgamemanagers or data.unity3d to pull the Game Info from there instead.
Both MelonLoader and Cpp2IL prioritize reading the Unity Version from the EXE.
This results in an issue where some games that have Custom Information on the EXE have a different version.
The fix would be to prioritize a signature scan of an asset bundle like globalgamemanager or have it get from UnityPlayer.dll instead.
Events are a common pattern in F# and JavaScript.
I am pretty sure that none of the MelonMod
overrides return a value so this system should work perfectly.
Delegate invocation (events) has the same speed as virtual invocation (interfaces), so there shouldn't be a performance hit, rather there would've been a performance increase, unfortunately this will not be gained due to backwards compatibility.
Additionally, multiple functions can subscribe to an event, which can result in cleaner looking code instead of a monolithic override function.
Another benefit is unsubscribing from events, instead of if (!enabled) return;
being ran every single time the function is called, the function won't get called at all (faster).
Example:
public Mod() { // class constructor
MelonHandler.OnUpdate += Update;
}
// this could be useful for a 0Reloader plugin if that ever happens
~Mod() { // finalizer/destructor
MelonHandler.OnUpdate -= Update;
}
void Update() { ... }
MelonLoader's preferred versioning system is SemVer, which commonly uses 3 integers delimited by periods.
Some creators have accidentally put a v
into their version number not expecting ML to add one.
Using an integer tuple would prevent this.
Since this would be an override, it shouldn't break old mods using the old constructor.
Additionally, this would allow in the future for MelonLoader to check if a dependency's version meets the minimum that a mod requires.
[assembly: MelonInfo(typeof(...), "Name", "1.2.3", "Author", "Link")]
could be converted to
[assembly: MelonInfo(typeof(...), "Name", (1, 2, 3), "Author", "Link")]
MonoMod seems to fail at Generating IL in certain situations.
An example of this is with JustEmuTarkov.
Error Log for Reference
Possibly from an existing 0Harmony.dll being present and loaded before MelonLoader's Assembly Resolver can redirect it.
May relate to #94
When running a Plugin from a Clean Installation it seems to attempt to resolve it's dependencies too early.
Resulting in dependencies getting resolved to null before Assembly Generation completes for the first time.
Marking as Optional Dependency does not help.
Leveraging Late Dependency usage does not help.
Dependencies get resolved properly from there on out after restarting the game.
At the moment, whenever mod authors have to log some kind of an exception, they either use 2 calls to MelonLogger.Error, or they manually concatenate the message they want to log and the exception, possibly including a new line.
As a quality-of-life improvement, I propose adding an overload MelonLogger.Error(string txt, Exception ex)
, which handles this somewhat common task in a uniform way. It would first print the message txt
, then include a newline character, and then print the exception message as well as its stack trace on the following lines.
This might be a source-incompatible (but binary-compatible) change due to the existence of the overload MelonLogger.Error(string txt, params object[] args)
:
Error("foo", new Exception())
used to resolve to the varargs overload, but would now resolve to the exception-printing overload.
Perhaps, even though it may be a bit uglier, MelonLogger.Error(Exception ex, string txt)
would be the better argument order.
[Ugly and perhaps a bit confusing, since the message gets logged first, followed by the exception. Not sure what's best here.]
This would also allow adding MelonLogger.Error(Exception ex, string txt, params object[] args)
as an analog to MelonLogger.Error(string txt, params object[] args)
.
On some systems and games the Start Screen will induce a crash with the error: Collecting from unknown thread
This possibly means that an object is being mistakenly collected by the garbage collector.
The temporary workaround is to run the game with the --melonloader.disablestartscreen
Launch Option.
Native Libs only resolve from certain specific locations.
Something like the Assembly Resolve Manager has where it allows for specifying custom locations to search would be useful.
Latest.log
file included. If no file exists then leave this unchecked and state so.Failing to download Unity dependencies.
[REDACTED]
{Game_Directory}\MelonLoader\Latest.log
Currently certain Mono based Games come with stripped DLLs in their Managed folder.
This can cause initialization failures with MelonLoader.
An automatic built-in preliminary pass of the Managed folder to unstrip these when a Mono game is detected would be ideal.
Similar to how there is already a preliminary pass to unstrip DLLs on Il2Cpp but for Mono Games.
Most likely needing to destroy the Mono Domain, replacing the files, then recreating the Mono Domain.
Temporary workaround is to manually replace the stripped files with unstripped ones.
Currently relies on custom icalls for MelonUtils.NativeHookAttach
and MelonUtils.NativeHookDetach
They are exported to use MSDetours for Native Hooking.
This needs to be converted to an implementation that will help improve platform compatibility.
Currently MelonLoader cleans the Console of Unity Logs.
Should add a Launch Option to toggle this off if the user desires.
It'd be neat if you could change the positional values of the loading bar or logo within the MelonStartScreen configuration file.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.