Skip to content

Instantly share code, notes, and snippets.

@TheGlitch76
Created February 1, 2021 17:15
Show Gist options
  • Save TheGlitch76/49459a81c022f1c8b17b45d24c96a563 to your computer and use it in GitHub Desktop.
Save TheGlitch76/49459a81c022f1c8b17b45d24c96a563 to your computer and use it in GitHub Desktop.
// 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