2021-09-27 20:55:48 +02:00
|
|
|
package io.gitlab.jfronny.libjf.unsafe.asm;
|
|
|
|
|
2021-09-29 18:52:43 +02:00
|
|
|
import io.gitlab.jfronny.libjf.LibJf;
|
2021-09-27 20:55:48 +02:00
|
|
|
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
2021-09-29 18:52:43 +02:00
|
|
|
import net.fabricmc.loader.api.FabricLoader;
|
|
|
|
import net.fabricmc.loader.api.MappingResolver;
|
2021-09-27 20:55:48 +02:00
|
|
|
import org.objectweb.asm.ClassReader;
|
|
|
|
import org.objectweb.asm.ClassWriter;
|
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
2021-10-06 19:01:48 +02:00
|
|
|
import org.spongepowered.asm.mixin.MixinEnvironment;
|
|
|
|
import org.spongepowered.asm.mixin.transformer.IMixinTransformer;
|
|
|
|
import org.spongepowered.asm.mixin.transformer.ext.IExtensionRegistry;
|
2021-09-27 20:55:48 +02:00
|
|
|
import org.spongepowered.asm.transformers.MixinClassWriter;
|
|
|
|
|
2021-10-06 19:01:48 +02:00
|
|
|
import java.util.List;
|
2021-09-29 18:52:43 +02:00
|
|
|
import java.util.Set;
|
|
|
|
|
2021-10-06 19:01:48 +02:00
|
|
|
public class AsmTransformer implements IMixinTransformer {
|
2021-09-29 18:52:43 +02:00
|
|
|
public static AsmTransformer INSTANCE;
|
|
|
|
public static final MappingResolver MAPPING_RESOLVER = FabricLoader.getInstance().getMappingResolver();
|
|
|
|
public static final String INTERMEDIARY = "intermediary";
|
2021-10-06 19:01:48 +02:00
|
|
|
public IMixinTransformer delegate;
|
2021-09-29 18:52:43 +02:00
|
|
|
public Set<AsmConfig> asmConfigs;
|
|
|
|
private AsmConfig currentConfig = null;
|
2021-09-27 20:55:48 +02:00
|
|
|
|
2021-10-06 19:01:48 +02:00
|
|
|
@Override
|
|
|
|
public void audit(MixinEnvironment environment) {
|
|
|
|
delegate.audit(environment);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<String> reload(String mixinClass, ClassNode classNode) {
|
|
|
|
return delegate.reload(mixinClass, classNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean computeFramesForClass(MixinEnvironment environment, String name, ClassNode classNode) {
|
|
|
|
return delegate.computeFramesForClass(environment, name, classNode);
|
|
|
|
}
|
|
|
|
|
2021-09-27 20:55:48 +02:00
|
|
|
@Override
|
2021-09-28 20:31:54 +02:00
|
|
|
public byte[] transformClassBytes(String name, String transformedName, byte[] classBytes) {
|
|
|
|
classBytes = delegate.transformClassBytes(name, transformedName, classBytes);
|
|
|
|
if (classBytes == null || name == null)
|
|
|
|
return classBytes;
|
2021-10-09 12:44:01 +02:00
|
|
|
if (isClassUnmoddable(name, null)) {
|
|
|
|
if (LibJf.DEV) LibJf.LOGGER.info("Skipping " + name);
|
2021-09-28 20:31:54 +02:00
|
|
|
return classBytes;
|
2021-10-09 12:44:01 +02:00
|
|
|
}
|
2021-09-27 20:55:48 +02:00
|
|
|
|
2021-09-29 18:52:43 +02:00
|
|
|
ClassNode klazz = new ClassNode();
|
2021-09-28 20:31:54 +02:00
|
|
|
ClassReader reader = new ClassReader(classBytes);
|
2021-09-29 18:52:43 +02:00
|
|
|
reader.accept(klazz, ClassReader.EXPAND_FRAMES); //ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG
|
|
|
|
|
|
|
|
//if ((klazz.access & Opcodes.ACC_INTERFACE) != 0) {
|
|
|
|
// return classBytes;
|
|
|
|
//}
|
2021-09-27 20:55:48 +02:00
|
|
|
|
2021-09-29 18:52:43 +02:00
|
|
|
for (AsmConfig config : asmConfigs) {
|
|
|
|
currentConfig = config;
|
|
|
|
if (!isClassUnmoddable(name, config)) {
|
|
|
|
for (Patch patch : config.getPatches()) {
|
|
|
|
patch.apply(klazz);
|
|
|
|
}
|
|
|
|
}
|
2021-09-27 20:55:48 +02:00
|
|
|
}
|
2021-09-29 18:52:43 +02:00
|
|
|
currentConfig = null;
|
2021-09-27 20:55:48 +02:00
|
|
|
|
|
|
|
ClassWriter writer = new MixinClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
2021-09-29 18:52:43 +02:00
|
|
|
try {
|
|
|
|
klazz.accept(writer);
|
|
|
|
}
|
|
|
|
catch (NullPointerException t) {
|
|
|
|
LibJf.LOGGER.error("Could not transform " + transformedName, t);
|
|
|
|
return null;
|
|
|
|
}
|
2021-09-28 20:31:54 +02:00
|
|
|
classBytes = writer.toByteArray();
|
2021-10-06 19:01:48 +02:00
|
|
|
//MixinEnvironment.getCurrentEnvironment();
|
2021-09-29 18:52:43 +02:00
|
|
|
return classBytes;
|
|
|
|
}
|
|
|
|
|
2021-10-06 19:01:48 +02:00
|
|
|
@Override
|
|
|
|
public byte[] transformClass(MixinEnvironment environment, String name, byte[] classBytes) {
|
|
|
|
LibJf.LOGGER.error("transformClass called");
|
|
|
|
return delegate.transformClass(environment, name, classBytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean transformClass(MixinEnvironment environment, String name, ClassNode classNode) {
|
|
|
|
LibJf.LOGGER.error("transformClass called");
|
|
|
|
return delegate.transformClass(environment, name, classNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public byte[] generateClass(MixinEnvironment environment, String name) {
|
|
|
|
LibJf.LOGGER.error("generateClass called");
|
|
|
|
return delegate.generateClass(environment, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean generateClass(MixinEnvironment environment, String name, ClassNode classNode) {
|
|
|
|
LibJf.LOGGER.error("generateClass called");
|
|
|
|
return delegate.generateClass(environment, name, classNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IExtensionRegistry getExtensions() {
|
|
|
|
return delegate.getExtensions();
|
|
|
|
}
|
|
|
|
|
2021-10-03 20:12:36 +02:00
|
|
|
public static boolean isClassUnmoddable(String className, AsmConfig config) {
|
2021-09-29 18:52:43 +02:00
|
|
|
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;
|
2021-09-27 20:55:48 +02:00
|
|
|
}
|
|
|
|
}
|