LibJF/libjf-unsafe-v0/src/main/java/io/gitlab/jfronny/libjf/unsafe/asm/AsmTransformer.java
2021-09-29 18:52:43 +02:00

77 lines
2.9 KiB
Java

package io.gitlab.jfronny.libjf.unsafe.asm;
import io.gitlab.jfronny.libjf.LibJf;
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.MappingResolver;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.transformer.FabricMixinTransformerProxy;
import org.spongepowered.asm.transformers.MixinClassWriter;
import java.util.Set;
public class AsmTransformer extends FabricMixinTransformerProxy {
public static AsmTransformer INSTANCE;
public static final MappingResolver MAPPING_RESOLVER = FabricLoader.getInstance().getMappingResolver();
public static final String INTERMEDIARY = "intermediary";
public FabricMixinTransformerProxy delegate;
public Set<AsmConfig> asmConfigs;
private AsmConfig currentConfig = null;
@Override
public byte[] transformClassBytes(String name, String transformedName, byte[] classBytes) {
classBytes = delegate.transformClassBytes(name, transformedName, classBytes);
if (classBytes == null || name == null)
return classBytes;
if (isClassUnmoddable(name, null))
return classBytes;
ClassNode klazz = new ClassNode();
ClassReader reader = new ClassReader(classBytes);
reader.accept(klazz, ClassReader.EXPAND_FRAMES); //ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG
//if ((klazz.access & Opcodes.ACC_INTERFACE) != 0) {
// return classBytes;
//}
for (AsmConfig config : asmConfigs) {
currentConfig = config;
if (!isClassUnmoddable(name, config)) {
for (Patch patch : config.getPatches()) {
patch.apply(klazz);
}
}
}
currentConfig = null;
ClassWriter writer = new MixinClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
try {
klazz.accept(writer);
}
catch (NullPointerException t) {
LibJf.LOGGER.error("Could not transform " + transformedName, t);
return null;
}
classBytes = writer.toByteArray();
return classBytes;
}
public boolean isClassUnmoddable(String className, AsmConfig config) {
if (className.replace('/', '.').startsWith("org.objectweb.asm")
//|| className.startsWith("net.fabricmc.loader")
//|| className.startsWith("io.gitlab.jfronny.libjf.unsafe.asm")
)
return true;
if (config == null) return false;
Set<String> classes = config.skipClasses();
if (classes == null) return false;
return classes.contains(MAPPING_RESOLVER.unmapClassName(INTERMEDIARY, className));
}
public AsmConfig getCurrentConfig() {
return currentConfig;
}
}