-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] How to load extra mod with mod #682
Comments
Using *Impl classes isn't supported. Unless you are using classes from the api package, your code could break at anytime. What you are trying to do doesn't seem possible without writing your own subclass of the fabric loader?
So what you describe is in the wrong order. Language adaptors in step 3 can't affect step 1 fabric-loader/src/main/java/net/fabricmc/loader/impl/FabricLoaderImpl.java Lines 204 to 207 in d713b2a
Is there any reason why you can't "jar in jar" your additional mod? |
I can create the impl with the same package name for access package private interface
The first is use reflection for inject the mods to list.
It's load basing on user config |
Normally the "user config" is install the optional mod. Your mod code isn't in a "valid state" while the mod loader is determining what mods exist. The reason is because until it has determined what the mods are, it doesn't know whether the code is in the correct mapping or what mixins should be applied, etc. In other words, it can't safely load/run mod code until it knows what the mods are so it can read their mod configurations and determine how their classes (and dependent classes) are defined/modified. |
On the package private/reflection. It doesn't matter how you reference it. The point is referencing implementation details instead of stable apis is brittle. |
https://modrinth.com/mod/thatorthis works well in 1.16, 1.17. Need the approach for 1.18. |
That page is littered with the word "hack".
Your approach should be to propose an api that helps with what you want to do. A simple example would be add a system property that defines a callback (a ModCandidateFinder) that can arbitrarily produce mod candidates. Defining what such a callback can and should not do in terms of classloading would be the hard part, including how the class itself gets loaded, see e.g. #680 But such a simple approach maybe too flexible (lacking in error checking and potentially introducing security concerns?). |
According to #486. The earlier entry point is requested in 2020. And there isn't a implement for that. So, I think I have to do some "hack" for achieving my purpose. Edit: Edit: |
PR 680 is not meant for this use case, I don't think it'll help you with it. There are other ways like -Dfabric.addMods to go beyond the mods directory. It is still quite unclear what your application is, the programmatic APIs for working with the mod set and other early loader interactions are WIP. All that's available right now are the system properties and hacky unsupported approaches. |
Load mods in sub dir of |
The currently officially supported way for this is limited to |
As the second say, there isn't a way to modify the property before |
It is not for mod loading, quite the opposite. See #679 for an explanatio of how the classloading works. In your case, your wrapper might calculate the fabric.addMods system property before passing control to knot. I only mentioned 680 because what is called "loader plugin" in the other discussions would probably need to use this method to load their classes. |
No, 680 is really only useful for code that runs before Fabric Loader, e.g. in-process launchers or wrappers. It doesn't pull in anything extra, but prevents the referenced libraries to be treated as part of the game, leaving them on the system class loader. You'll have to wait for us to add the appropriate APIs to have a clean solution. As far as fixing your hacky solution is concerned, running with |
It fine in dev. And below is errors desc.
|
1 obviously doesn't work because you need to get your classes loaded by knot cl 2 is where you can't use your own ModCandidateFinder because it's package private and faking the package doesn't appear to work across class loaders. You'd have to use one of the existing implementations 3 is probably the same as 2 while also hacking into the jvm |
NOTE: the 680 behaviour to add additional "system" classes is in fabric loader 0.14.8 but you are using 0.14.7 This issue is becoming less of a proper fabric loader issue and more of a "how do hack/structure my code to fool the fabric loader"? |
https://stackoverflow.com/questions/2877262/java-securityexception-signer-information-does-not-match Then, how can I fix the hacky way 🐰 |
Ok, this is caused by fabric loader signing the jar Line 278 in d713b2a
That kind of seals the packages. |
Author of ThatOrThis here. I'm 110% against using hacks to inject mods into the loader, but it just can't be done the other way back when the mod is out. Now that Fabric Loader has evolved to support loading mods from additional directories, and class injection just got much harder with that package signature (just why?), I'm willing to do a rewrite. However there are other problems yet to be solved.
I actually don't think it's the loader's job to provide the APIs. Fabric Loader has one job - loading mods into Minecraft - and it's doing it well enough. All we need is a way to tell the loader which mods to load, and we have |
Letting mods control the mod set is quite an important feature, it allows all sorts of updaters, adapters, server-mod-synchronizers and even your application. I expect to land the feature set sooner than later, so I wouldn't recommend sinking much time in a rewrite. Your approach is likely still workable by (ab)using one of our mod candidate finder implementations instead. Issues like 81 are fairly close to us not wanting the feature by default. The system property is one way to opt into this behavior ( |
As a reference. Quilt have loader plugin that support load |
I faced the same problem while developing Voxel Latest, a mod which modifies Voxel Map 1.17.1 and enables it to run on Minecraft 1.18.1, 1.18.2 and more. However, the license of Voxel Map is ARR. So I have to dynamically download, remap and inject Voxel Map to Fabric Loader instead of using jar-in-jar. Currently, I inject the jar file with Could fabric provide an API to add mods to Fabric Loaderd dynamically? |
@burningtnt https://github.com/SettingDust/preloading-tricks My own impl for reference |
Here's what I tried:
ModCandidateFinder
and inject the mods toFabricLoaderImpl#mods
. Working in 1.16, 1.17.ClassNotFoundException
withFabricLoader
class loader. My classes not in classpath.SecurityException
after I add my classes to classpath.ArgumentModCandidateFinder
. But it's called before language adapter.The text was updated successfully, but these errors were encountered: