Created
February 1, 2021 17:15
-
-
Save TheGlitch76/49459a81c022f1c8b17b45d24c96a563 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// thank HalfOfTwo for this monstrosity | |
public class Scanner implements PreLaunchEntrypoint { | |
private static final Field ACTIVE_TRANSFORMER, MIXIN_TRANSFORMER; | |
static { | |
Transformer.init(); | |
System.out.println("I am become Mass ASM, destroyer of LexManos"); | |
try { | |
ACTIVE_TRANSFORMER = MixinEnvironment.class.getDeclaredField("transformer"); | |
ACTIVE_TRANSFORMER.setAccessible(true); | |
MIXIN_TRANSFORMER = Class.forName("net.fabricmc.loader.launch.knot.KnotClassDelegate").getDeclaredField("mixinTransformer"); | |
MIXIN_TRANSFORMER.setAccessible(true); | |
} catch (ReflectiveOperationException arg) { | |
throw new RuntimeException(arg); | |
} | |
} | |
public class FabricMixinTransformerProxyProxy extends FabricMixinTransformerProxy { | |
private final FabricMixinTransformerProxy proxy; | |
public FabricMixinTransformerProxyProxy(FabricMixinTransformerProxy proxy) {this.proxy = proxy;} | |
@Override | |
public byte[] transformClassBytes(String name, String transformedName, byte[] basicClass) { | |
if (basicClass == null) { | |
return this.proxy.transformClassBytes(name, transformedName, basicClass); | |
} | |
byte[] transformed = this.proxy.transformClassBytes(name, transformedName, basicClass); | |
return Transformer.transform(transformedName, transformed); | |
} | |
} | |
@Override | |
public void onPreLaunch() { | |
try { | |
// first we need knot's delegate | |
Object delegate = this.getDelegate(); | |
// then we get the current mixin transformer | |
FabricMixinTransformerProxy proxy = (FabricMixinTransformerProxy) MIXIN_TRANSFORMER.get(delegate); | |
Field active = FabricMixinTransformerProxy.class.getDeclaredField("transformer"); | |
active.setAccessible(true); | |
// we need to delete mixin's current mixin transformer to get around it's constructor check | |
Object currentTransformer = active.get(proxy); | |
// we remove the active transformer | |
ACTIVE_TRANSFORMER.set(null, null); | |
// this action overrides the current transformer | |
FabricMixinTransformerProxyProxy proxyProxy = new FabricMixinTransformerProxyProxy(proxy); | |
// so we return the old one | |
ACTIVE_TRANSFORMER.set(null, currentTransformer); | |
MIXIN_TRANSFORMER.set(delegate, proxyProxy); | |
} catch (Throwable e) { | |
throw new RuntimeException(e); | |
} | |
} | |
public Object getDelegate() throws ReflectiveOperationException { | |
ClassLoader loader = Scanner.class.getClassLoader(); | |
Class<?> knotInterface = Class.forName("net.fabricmc.loader.launch.knot.KnotClassLoaderInterface"); | |
while (loader != null && !knotInterface.isInstance(loader)) { | |
loader = loader.getParent(); | |
} | |
Method method = knotInterface.getMethod("getDelegate"); | |
method.setAccessible(true); | |
return method.invoke(loader); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment