Minestom/src/main/java/net/minestom/server/extras/selfmodification/mixins/MixinCodeModifier.java

54 lines
2.1 KiB
Java

package net.minestom.server.extras.selfmodification.mixins;
import net.minestom.server.extras.selfmodification.CodeModifier;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.transformers.TreeTransformer;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* CodeModifier responsible for applying Mixins during class load
*/
public class MixinCodeModifier extends CodeModifier {
/**
* Call MixinTransformer's transformClass
*/
private final Method transformClassMethod;
private final TreeTransformer transformer;
public MixinCodeModifier() {
try {
// MixinTransformer is package-protected, so we have to force to gain access
Class<?> mixinTransformerClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinTransformer");
Constructor<?> ctor = mixinTransformerClass.getDeclaredConstructor();
ctor.setAccessible(true);
this.transformer = (TreeTransformer) ctor.newInstance();
// we can't access the MixinTransformer type here, so we use reflection to access the method
transformClassMethod = mixinTransformerClass.getDeclaredMethod("transformClass", MixinEnvironment.class, String.class, ClassNode.class);
transformClassMethod.setAccessible(true);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException | ClassNotFoundException e) {
throw new RuntimeException("Failed to initialize MixinCodeModifier", e);
}
}
@Override
public boolean transform(ClassNode source) {
try {
return (boolean) transformClassMethod.invoke(transformer, MixinEnvironment.getEnvironment(MixinEnvironment.Phase.DEFAULT), source.name.replace("/", "."), source);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
@Override
public String getNamespace() {
return null;
}
}