Skip to content

Commit 1c1704e

Browse files
committed
more ASM work...
1 parent f12b740 commit 1c1704e

File tree

7 files changed

+93
-4
lines changed

7 files changed

+93
-4
lines changed

src/main/java/com/falsepattern/lib/asm/ASMUtil.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.falsepattern.lib.asm;
22

3+
import com.falsepattern.lib.asm.exceptions.AsmClassNotFoundException;
4+
import com.falsepattern.lib.asm.exceptions.AsmFieldNotFoundException;
5+
import com.falsepattern.lib.asm.exceptions.AsmMethodNotFoundException;
36
import com.falsepattern.lib.internal.CoreLoadingPlugin;
47
import com.falsepattern.lib.mapping.MappingManager;
58
import com.falsepattern.lib.mapping.types.MappingType;
@@ -9,9 +12,15 @@
912
import com.falsepattern.lib.mapping.types.UniversalMethod;
1013
import lombok.SneakyThrows;
1114
import lombok.val;
15+
import org.apache.logging.log4j.Logger;
16+
import org.objectweb.asm.ClassReader;
17+
import org.objectweb.asm.ClassVisitor;
18+
import org.objectweb.asm.ClassWriter;
19+
import org.objectweb.asm.Opcodes;
1220
import org.objectweb.asm.tree.ClassNode;
1321
import org.objectweb.asm.tree.FieldNode;
1422
import org.objectweb.asm.tree.MethodNode;
23+
import org.objectweb.asm.util.CheckClassAdapter;
1524

1625
import java.util.Arrays;
1726
import java.util.Objects;
@@ -133,6 +142,18 @@ public static UniversalClass toUniversalClass(ClassNode cn) {
133142
}
134143
}
135144

145+
public static ClassNode parseClass(byte[] bytes, int readerFlags) {
146+
val cn = new ClassNode(Opcodes.ASM5);
147+
val reader = new ClassReader(bytes);
148+
reader.accept(cn, readerFlags);
149+
return cn;
150+
}
151+
152+
public static byte[] serializeClass(ClassNode cn, int writerFlags) {
153+
val writer = new ClassWriter(writerFlags);
154+
return writer.toByteArray();
155+
}
156+
136157
public static boolean anyEquals(String str, String... options) {
137158
for (val option: options) {
138159
if (Objects.equals(str, option)) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.falsepattern.lib.asm;
2+
3+
import org.objectweb.asm.tree.ClassNode;
4+
5+
public interface IClassNodeTransformer {
6+
String getName();
7+
boolean shouldTransform(ClassNode cn, String transformedName, boolean obfuscated);
8+
default int internalSortingOrder() {
9+
return 0;
10+
}
11+
12+
void transform(ClassNode cn, String transformedName, boolean obfuscated);
13+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.falsepattern.lib.asm;
2+
3+
import com.falsepattern.lib.asm.exceptions.AsmTransformException;
4+
import com.falsepattern.lib.internal.CoreLoadingPlugin;
5+
import lombok.val;
6+
import org.apache.logging.log4j.Logger;
7+
import org.objectweb.asm.ClassReader;
8+
import org.objectweb.asm.ClassWriter;
9+
10+
import net.minecraft.launchwrapper.IClassTransformer;
11+
12+
import java.util.ArrayList;
13+
import java.util.Comparator;
14+
import java.util.List;
15+
16+
/**
17+
* An ASM transformation dispatcher utility, inspired by mixins.
18+
*/
19+
public interface SmartTransformer extends IClassTransformer {
20+
Logger logger();
21+
List<IClassNodeTransformer> transformers();
22+
@Override
23+
default byte[] transform(String name, String transformedName, byte[] bytes) {
24+
if (bytes == null) {
25+
return null;
26+
}
27+
val transformers = new ArrayList<IClassNodeTransformer>();
28+
val cn = ASMUtil.parseClass(bytes, ClassReader.EXPAND_FRAMES);
29+
for (val transformer: transformers()) {
30+
if (transformer.shouldTransform(cn, transformedName, CoreLoadingPlugin.isObfuscated())) {
31+
transformers.add(transformer);
32+
}
33+
}
34+
if (transformers.isEmpty()) {
35+
return bytes;
36+
}
37+
transformers.sort(Comparator.comparingInt(IClassNodeTransformer::internalSortingOrder));
38+
val log = logger();
39+
for (val transformer: transformers) {
40+
log.debug("Patching {} with {}...", transformedName, transformer.getName());
41+
try {
42+
transformer.transform(cn, transformedName, CoreLoadingPlugin.isObfuscated());
43+
} catch (RuntimeException | Error t) {
44+
log.error("Error transforming {} with {}: {}", transformedName, transformer.getName(), t.getMessage());
45+
throw t;
46+
} catch (Throwable t) {
47+
log.error("Error transforming {} with {}: {}", transformedName, transformer.getName(), t.getMessage());
48+
throw new RuntimeException(t);
49+
}
50+
}
51+
val result = ASMUtil.serializeClass(cn, ClassWriter.COMPUTE_FRAMES);
52+
log.debug("Patched {} successfully.", transformedName);
53+
return result;
54+
}
55+
}

src/main/java/com/falsepattern/lib/asm/AsmClassNotFoundException.java renamed to src/main/java/com/falsepattern/lib/asm/exceptions/AsmClassNotFoundException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.falsepattern.lib.asm;
1+
package com.falsepattern.lib.asm.exceptions;
22

33
public class AsmClassNotFoundException extends AsmTransformException {
44
public AsmClassNotFoundException(final String clazz) {

src/main/java/com/falsepattern/lib/asm/AsmFieldNotFoundException.java renamed to src/main/java/com/falsepattern/lib/asm/exceptions/AsmFieldNotFoundException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.falsepattern.lib.asm;
1+
package com.falsepattern.lib.asm.exceptions;
22

33
public class AsmFieldNotFoundException extends AsmTransformException {
44
public AsmFieldNotFoundException(final String field) {

src/main/java/com/falsepattern/lib/asm/AsmMethodNotFoundException.java renamed to src/main/java/com/falsepattern/lib/asm/exceptions/AsmMethodNotFoundException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.falsepattern.lib.asm;
1+
package com.falsepattern.lib.asm.exceptions;
22

33
public class AsmMethodNotFoundException extends AsmTransformException {
44
public AsmMethodNotFoundException(final String method) {

src/main/java/com/falsepattern/lib/asm/AsmTransformException.java renamed to src/main/java/com/falsepattern/lib/asm/exceptions/AsmTransformException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.falsepattern.lib.asm;
1+
package com.falsepattern.lib.asm.exceptions;
22

33
public class AsmTransformException extends RuntimeException {
44
public AsmTransformException(final String message) {

0 commit comments

Comments
 (0)