Skip to content

Commit 6e27e4a

Browse files
committed
TransformerTransformer to transform the transformer
No more exception spam on load
1 parent 5cd9c42 commit 6e27e4a

5 files changed

Lines changed: 90 additions & 44 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ buildscript {
1212
apply plugin: 'com.github.johnrengelman.shadow'
1313
apply plugin: 'java'
1414

15-
version = "2.6.2"
15+
version = "2.6.3"
1616
group = "ofdev" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
1717
archivesBaseName = "aa_do_not_rename_OptiFineDevTweaker"
1818

src/main/java/ofdev/launchwrapper/OptifineDevRemapper.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public class OptifineDevRemapper extends Remapper {
3838
try {
3939
cpm = Class.forName("net.minecraftforge.fml.common.patcher.ClassPatchManager");
4040
} catch (ClassNotFoundException ex) {
41-
ex.printStackTrace();
4241
cpm = Class.forName("cpw.mods.fml.common.patcher.ClassPatchManager"); // 1.7.10
4342
}
4443
Object classPathManager = cpm.getField("INSTANCE").get(null);

src/main/java/ofdev/launchwrapper/OptifineDevTransformerWrapper.java

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,43 +72,16 @@ public class OptifineDevTransformerWrapper implements IClassTransformer {
7272
static {
7373
try {
7474
mcJar = FileSystems.newFileSystem(MC_JAR, Launch.classLoader);
75+
Launch.classLoader.addURL(MC_JAR.toUri().toURL());
7576
} catch (IOException e) {
7677
throw new UncheckedIOException(e);
7778
}
7879
}
7980

8081
private static final OptifineDevRemapper remapper = OptifineDevRemapper.NOTCH_MCP;
8182

82-
8383
public static IClassTransformer ofTransformer;
8484

85-
{
86-
try {
87-
Class<? extends IClassTransformer> ofTransformerClass =
88-
(Class<? extends IClassTransformer>) OptifineDevTweakerWrapper.OF_TRANSFORMER_LAUNCH_CLASSLOADER;
89-
90-
ofTransformer = ofTransformerClass.newInstance();
91-
URL ofUrl = ofTransformer.getClass().getProtectionDomain().getCodeSource().getLocation();
92-
93-
JarURLConnection connection = (JarURLConnection) ofUrl.openConnection();
94-
ZipFile file = new ZipFile(new File(connection.getJarFileURL().toURI()));
95-
UtilsLW.setFieldValue(ofTransformerClass, "ofZipFile", ofTransformer, file);
96-
97-
Class<?> ofPatcher = Launch.classLoader.findClass("optifine.Patcher");
98-
99-
Object patchMapVal = UtilsLW.invokeMethod(ofPatcher, null, "getConfigurationMap", file);
100-
Object patternsVal = UtilsLW.invokeMethod(ofPatcher, null, "getConfigurationPatterns", patchMapVal);
101-
102-
UtilsLW.setFieldValue(ofTransformerClass, "patchMap", ofTransformer, patchMapVal);
103-
UtilsLW.setFieldValue(ofTransformerClass, "patterns", ofTransformer, patternsVal);
104-
System.out.println("Ignore the above, OptiFine should run anyway");
105-
106-
Launch.classLoader.addURL(MC_JAR.toUri().toURL());
107-
} catch (InstantiationException | IllegalAccessException | IOException | URISyntaxException | ClassNotFoundException e) {
108-
throw new RuntimeException(e);
109-
}
110-
}
111-
11285
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) {
11386
if (basicClass == null || name == null) {
11487
return null;

src/main/java/ofdev/launchwrapper/OptifineDevTweakerWrapper.java

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,98 @@
55
import net.minecraft.launchwrapper.Launch;
66
import net.minecraft.launchwrapper.LaunchClassLoader;
77
import ofdev.common.Utils;
8+
import org.objectweb.asm.ClassReader;
9+
import org.objectweb.asm.ClassWriter;
10+
import org.objectweb.asm.Opcodes;
11+
import org.objectweb.asm.tree.AbstractInsnNode;
12+
import org.objectweb.asm.tree.ClassNode;
13+
import org.objectweb.asm.tree.InsnNode;
14+
import org.objectweb.asm.tree.IntInsnNode;
15+
import org.objectweb.asm.tree.MethodInsnNode;
16+
import org.objectweb.asm.tree.MethodNode;
817

918
import java.io.File;
1019
import java.io.IOException;
1120
import java.io.UncheckedIOException;
12-
import java.nio.file.FileVisitResult;
13-
import java.nio.file.FileVisitor;
14-
import java.nio.file.Files;
21+
import java.net.JarURLConnection;
22+
import java.net.URISyntaxException;
23+
import java.net.URL;
1524
import java.nio.file.Path;
1625
import java.nio.file.Paths;
17-
import java.nio.file.attribute.BasicFileAttributes;
1826
import java.util.List;
1927
import java.util.Set;
28+
import java.util.zip.ZipFile;
2029

2130
// this is needed only in dev environment to get deobfuscated version of OptiFine running
2231
public class OptifineDevTweakerWrapper implements ITweaker {
2332

2433
// this requires the jar to be loaded by FML before OptiFine, the easiest way to do it is to name it aa_SomeJar
25-
public static final Class<?> OF_TRANSFORMER_LAUNCH_CLASSLOADER = UtilsLW.loadClassLW("optifine.OptiFineClassTransformer");
34+
public static final Class<?> OF_TRANSFORMER_LAUNCH_CLASSLOADER;
35+
36+
static {
37+
Launch.classLoader.registerTransformer("ofdev.launchwrapper.OptifineDevTweakerWrapper$OptiFineTransformerTransformer");
38+
OF_TRANSFORMER_LAUNCH_CLASSLOADER = UtilsLW.loadClassLW("optifine.OptiFineClassTransformer");
39+
}
40+
41+
public static class OptiFineTransformerTransformer implements IClassTransformer {
42+
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) {
43+
if (name != null && name.equals("optifine.OptiFineClassTransformer")) {
44+
ClassReader cr = new ClassReader(basicClass);
45+
ClassNode cn = new ClassNode();
46+
cr.accept(cn, 0);
47+
for (MethodNode method : cn.methods) {
48+
if (method.name.equals("<init>")) {
49+
AbstractInsnNode insn = null;
50+
for (int i = 0; i < method.instructions.size(); i++) {
51+
insn = method.instructions.get(i);
52+
if (insn.getOpcode() == Opcodes.INVOKESPECIAL) {
53+
break;
54+
}
55+
}
56+
IntInsnNode loadThis = new IntInsnNode(Opcodes.ALOAD, 0);
57+
MethodInsnNode initOptiTransformer = new MethodInsnNode(Opcodes.INVOKESTATIC,
58+
"ofdev/launchwrapper/OptifineDevTweakerWrapper",
59+
"initOptiTransformer", "(Ljava/lang/Object;)V", false);
60+
method.instructions.insert(insn, loadThis);
61+
method.instructions.insert(loadThis, initOptiTransformer);
62+
method.instructions.insert(initOptiTransformer, new InsnNode(Opcodes.RETURN));
63+
}
64+
}
65+
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
66+
cn.accept(cw);
67+
return cw.toByteArray();
68+
}
69+
return basicClass;
70+
}
71+
}
72+
73+
public static void initOptiTransformer(Object ofTransformer) {
74+
OptifineDevTransformerWrapper.ofTransformer = (IClassTransformer) ofTransformer;
75+
try {
76+
Class<? extends IClassTransformer> ofTransformerClass =
77+
(Class<? extends IClassTransformer>) OptifineDevTweakerWrapper.OF_TRANSFORMER_LAUNCH_CLASSLOADER;
78+
79+
URL ofUrl = ofTransformer.getClass().getProtectionDomain().getCodeSource().getLocation();
80+
81+
JarURLConnection connection = (JarURLConnection) ofUrl.openConnection();
82+
ZipFile file = new ZipFile(new File(connection.getJarFileURL().toURI()));
83+
UtilsLW.setFieldValue(ofTransformerClass, "ofZipFile", ofTransformer, file);
84+
85+
Class<?> ofPatcher = Launch.classLoader.findClass("optifine.Patcher");
86+
87+
Object patchMapVal = UtilsLW.invokeMethod(ofPatcher, null, "getConfigurationMap", file);
88+
Object patternsVal = UtilsLW.invokeMethod(ofPatcher, null, "getConfigurationPatterns", patchMapVal);
89+
90+
UtilsLW.setFieldValue(ofTransformerClass, "patchMap", ofTransformer, patchMapVal);
91+
UtilsLW.setFieldValue(ofTransformerClass, "patterns", ofTransformer, patternsVal);
92+
//System.out.println("Ignore the above, OptiFine should run anyway");
93+
UtilsLW.setFieldValue(ofTransformer.getClass(), "instance", null, ofTransformer);
94+
95+
} catch (IOException | URISyntaxException | ClassNotFoundException e) {
96+
throw new RuntimeException(e);
97+
}
98+
}
99+
26100
public static Path CLASS_DUMP_LOCATION;
27101

28102
@Override public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
@@ -56,12 +130,6 @@ public class OptifineDevTweakerWrapper implements ITweaker {
56130
Set<String> transformerExceptions =
57131
UtilsLW.getFieldValue(LaunchClassLoader.class, Launch.classLoader, "transformerExceptions");
58132
transformerExceptions.removeIf(t -> t.startsWith("optifine"));
59-
60-
// OptiFine tweaker constructed new instance of optifine transformer, so it changed it's instance field
61-
// now that OptiFine tweaker setup is done,fix it
62-
Object ofTransformer = OptifineDevTransformerWrapper.ofTransformer;
63-
UtilsLW.setFieldValue(ofTransformer.getClass(), "instance", null, ofTransformer);
64-
65133
return new String[0];
66134
}
67135
}

src/main/java/ofdev/launchwrapper/UtilsLW.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,20 @@ public static void fixReflector() {
172172
try {
173173
Class<?> reflector = UtilsLW.loadClassLW("Reflector");
174174

175+
try {
176+
reflector.getDeclaredField("ForgeBlock_getLightOpacity");
177+
} catch (NoSuchFieldException ignored) {
178+
// 1.7.10 doesn't have this
179+
return;
180+
}
175181
Object ForgeBlock = UtilsLW.getFieldValue(reflector, null, "ForgeBlock");
176182
Object ForgeBlock_getLightOpacity = UtilsLW.getFieldValue(reflector, null, "ForgeBlock_getLightOpacity");
177183
Object ForgeBlock_getLightValue = UtilsLW.getFieldValue(reflector, null, "ForgeBlock_getLightValue");
178184

179185
Class<?> ReflectorMethod = ForgeBlock_getLightOpacity.getClass();
180-
Class IBlockState = UtilsLW.loadClassLW("net.minecraft.block.state.IBlockState");
181-
Class IBlockAccess = UtilsLW.loadClassLW("net.minecraft.world.IBlockAccess");
182-
Class BlockPos = UtilsLW.loadClassLW("net.minecraft.util.math.BlockPos");
186+
Class<?> IBlockState = UtilsLW.loadClassLW("net.minecraft.block.state.IBlockState");
187+
Class<?> IBlockAccess = UtilsLW.loadClassLW("net.minecraft.world.IBlockAccess");
188+
Class<?> BlockPos = UtilsLW.loadClassLW("net.minecraft.util.math.BlockPos");
183189

184190
if (UtilsLW.invokeMethod(ReflectorMethod, ForgeBlock_getLightOpacity, "getTargetMethod") == null) {
185191
Object new_ForgeBlock_getLightOpacity = UtilsLW.construct(ReflectorMethod, ForgeBlock, "getLightOpacity", new Class[]{

0 commit comments

Comments
 (0)