simpledeobf icon indicating copy to clipboard operation
simpledeobf copied to clipboard

Force public option doesn't change invokespecial on private methods to invokevirtual

Open Niko-sk2x opened this issue 7 years ago • 4 comments

This is what actually causes #3. See: https://github.com/MinecraftForge/MinecraftForge/blob/c20a5e8805f64097430cf0722011f20862a8df9c/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java#L230-L294

I found it while making my own (far more convinient) pile of hacks to make optifine work in dev.

Niko-sk2x avatar Sep 26 '18 18:09 Niko-sk2x

Oh, nice. Thanks for the heads-up! On the 1 year anniversary of this issue as well :)

So, if I understand correctly, with the bytecode thing fixed in Forge, it Just Works now? I don't need to do anything with simpledeobf? Also, if it's not a trade secret, how did you hack Optifine in? I'm all for convenience.

octarine-noise avatar Sep 30 '18 09:09 octarine-noise

This is my awful not yet cleaned up pile of hacks to make it work https://gist.github.com/Barteks2x/38125abcac5cd069f2b23cd63468392b

It just needs to be named something like aa_FileName.jar and has to contain tweaker entry in manifest.

And you do need to modify simple deobf to also contain the same fix fml has. The fml code handles normal access tranaformers. You don't handle overriding newly public method. Javac emits invokespecial insn for private methods. This needs to be changed to invokevirtual when you make them public.

Niko-sk2x avatar Sep 30 '18 12:09 Niko-sk2x

Right, of course. It's been too long since I worked with this stuff.

So basically instead of deobfuscating each version of Optifine externally, you have a deobfuscator tweaker doing it on the fly at boot time. Much more convenient indeed. I'm a bit perplexed by the property pointing to the mapping file. Do you set this yourself in the buildscript/runconf? Or is this a feature of the ForgeGradle bootstrapper?

octarine-noise avatar Sep 30 '18 13:09 octarine-noise

It's a feature of forge gradle. You can see it being set in GradleStartCommon.

There are a few nonobvious parts of my code.

First is loading optifine transformer class from tweaker static initializer. This is done so that OptiFine will see obfuscated MC jar I inject into classpath. Otherwise it won't be loaded with launch class loader and it won't work.

Second non obvious part is creating new optifine transformer instance and then hacking it with reflection. Turns out that loading this with launchclassloader breaks the constructor, but optifine helpfully catches the exception and ignores it. From there it's just a matter of setting the null fields myself with reflection.

Everything else is mostly obvious or a leftover from some dead end I reached.

Niko-sk2x avatar Sep 30 '18 13:09 Niko-sk2x