Add ClassLoadingListener interface

This commit is contained in:
yushijinhun 2018-11-24 14:32:22 +08:00
parent 5010ea67b7
commit 1f5605c973
No known key found for this signature in database
GPG key ID: 5BC167F73EA558E4
2 changed files with 39 additions and 10 deletions

View file

@ -0,0 +1,9 @@
package moe.yushi.authlibinjector.transform;
import java.util.List;
public interface ClassLoadingListener {
void onClassLoading(ClassLoader classLoader, String className, byte[] bytecode, List<TransformUnit> appliedTransformers);
}

View file

@ -1,5 +1,7 @@
package moe.yushi.authlibinjector.transform;
import static java.util.Collections.emptyList;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
@ -9,6 +11,7 @@ import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@ -22,12 +25,13 @@ import moe.yushi.authlibinjector.util.Logging;
public class ClassTransformer implements ClassFileTransformer {
public List<TransformUnit> units = new ArrayList<>();
public List<ClassLoadingListener> listeners = new ArrayList<>();
public Set<String> ignores = new HashSet<>();
public boolean debugSaveClass;
private static class TransformHandle {
private boolean modified = false;
private List<TransformUnit> appliedTransformers;
private boolean currentModified;
private String className;
private byte[] classBuffer;
@ -54,7 +58,10 @@ public class ClassTransformer implements ClassFileTransformer {
reader.accept(optionalVisitor.get(), 0);
if (currentModified) {
Logging.TRANSFORM.info("Transformed [" + className + "] with [" + unit + "]");
modified = true;
if (appliedTransformers == null) {
appliedTransformers = new ArrayList<>();
}
appliedTransformers.add(unit);
classBuffer = writer.toByteArray();
}
} else {
@ -62,14 +69,21 @@ public class ClassTransformer implements ClassFileTransformer {
}
}
public Optional<byte[]> getResult() {
if (modified) {
return Optional.of(classBuffer);
} else {
public Optional<byte[]> getTransformResult() {
if (appliedTransformers == null || appliedTransformers.isEmpty()) {
return Optional.empty();
} else {
return Optional.of(classBuffer);
}
}
public List<TransformUnit> getAppliedTransformers() {
return appliedTransformers == null ? emptyList() : appliedTransformers;
}
public byte[] getFinalResult() {
return classBuffer;
}
}
@Override
@ -77,13 +91,19 @@ public class ClassTransformer implements ClassFileTransformer {
if (internalClassName != null && classfileBuffer != null) {
try {
String className = internalClassName.replace('/', '.');
for (String prefix : ignores)
if (className.startsWith(prefix)) return null;
for (String prefix : ignores) {
if (className.startsWith(prefix)) {
listeners.forEach(it -> it.onClassLoading(loader, className, classfileBuffer, Collections.emptyList()));
return null;
}
}
TransformHandle handle = new TransformHandle(className, classfileBuffer);
units.forEach(handle::accept);
if (handle.getResult().isPresent()) {
byte[] classBuffer = handle.getResult().get();
listeners.forEach(it -> it.onClassLoading(loader, className, handle.getFinalResult(), handle.getAppliedTransformers()));
if (handle.getTransformResult().isPresent()) {
byte[] classBuffer = handle.getTransformResult().get();
if (debugSaveClass) {
saveClassFile(className, classBuffer);
}