3 changed files with 118 additions and 46 deletions
@ -1,53 +1,88 @@ |
|||||||
package kcauldron; |
package kcauldron; |
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level; |
||||||
import org.objectweb.asm.ClassReader; |
import org.objectweb.asm.ClassReader; |
||||||
import org.objectweb.asm.ClassVisitor; |
import org.objectweb.asm.ClassVisitor; |
||||||
import org.objectweb.asm.ClassWriter; |
import org.objectweb.asm.ClassWriter; |
||||||
import org.objectweb.asm.FieldVisitor; |
import org.objectweb.asm.FieldVisitor; |
||||||
import org.objectweb.asm.MethodVisitor; |
import org.objectweb.asm.MethodVisitor; |
||||||
|
import org.objectweb.asm.tree.FieldInsnNode; |
||||||
|
import org.objectweb.asm.tree.InsnList; |
||||||
|
import org.objectweb.asm.tree.InsnNode; |
||||||
|
import org.objectweb.asm.tree.IntInsnNode; |
||||||
|
|
||||||
|
import pw.prok.imagine.api.Pair; |
||||||
|
import pw.prok.imagine.asm.ImagineASM; |
||||||
|
import pw.prok.imagine.asm.ImagineMethod; |
||||||
|
import pw.prok.imagine.asm.ImagineRemapper; |
||||||
|
import pw.prok.imagine.asm.Transformer; |
||||||
|
|
||||||
|
import com.avaje.ebean.annotation.Transactional; |
||||||
|
|
||||||
|
import cpw.mods.fml.common.FMLLog; |
||||||
import net.minecraft.launchwrapper.IClassTransformer; |
import net.minecraft.launchwrapper.IClassTransformer; |
||||||
|
import net.minecraft.world.WorldServer; |
||||||
|
import net.minecraft.world.chunk.IChunkProvider; |
||||||
import static org.objectweb.asm.Opcodes.*; |
import static org.objectweb.asm.Opcodes.*; |
||||||
|
|
||||||
public class KCauldronClassTransformer implements IClassTransformer { |
@Transformer.RegisterTransformer |
||||||
public static boolean DEV; |
public class KCauldronClassTransformer implements Transformer { |
||||||
|
|
||||||
@Override |
@Override |
||||||
public byte[] transform(String name, String transformedName, byte[] basicClass) { |
public void transform(final ImagineASM asm) { |
||||||
if ("net.minecraft.world.gen.ChunkProviderServer".equals(transformedName) || "net.minecraftforge.common.chunkio.ChunkIOProvider".equals(transformedName)) { |
if (asm.is("net.minecraft.world.gen.ChunkProviderServer") |
||||||
return patchChunkCall(basicClass); |
|| asm.is("net.minecraftforge.common.chunkio.ChunkIOProvider")) { |
||||||
} |
FMLLog.log(Level.INFO, "KCauldron: Patching " + asm.getActualName() + " for compatibility with Mystcraft"); |
||||||
return basicClass; |
ClassReader reader = new ClassReader(asm.build()); |
||||||
} |
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); |
||||||
|
reader.accept(new ClassVisitor(ASM5, writer) { |
||||||
private byte[] patchChunkCall(byte[] bytes) { |
@Override |
||||||
ClassReader reader = new ClassReader(bytes); |
public FieldVisitor visitField(int access, String name, |
||||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); |
String desc, String signature, Object value) { |
||||||
reader.accept(new ClassVisitor(ASM5, writer) { |
if ("loadedChunkHashMap_vanilla".equals(name)) { |
||||||
@Override |
name = asm.isDev() ? "loadedChunkHashMap" : "field_73244_f"; |
||||||
public FieldVisitor visitField(int access, String name, |
} |
||||||
String desc, String signature, Object value) { |
return super.visitField(access, name, desc, signature, |
||||||
if ("loadedChunkHashMap_vanilla".equals(name)) { |
value); |
||||||
name = DEV ? "loadedChunkHashMap" : "field_73244_f"; |
|
||||||
} |
} |
||||||
return super.visitField(access, name, desc, signature, value); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
@Override |
||||||
public MethodVisitor visitMethod(int access, String name, |
public MethodVisitor visitMethod(int access, String name, |
||||||
String desc, String signature, String[] exceptions) { |
String desc, String signature, String[] exceptions) { |
||||||
return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) { |
return new MethodVisitor(api, super.visitMethod(access, |
||||||
@Override |
name, desc, signature, exceptions)) { |
||||||
public void visitFieldInsn(int opcode, String owner, |
@Override |
||||||
String name, String desc) { |
public void visitFieldInsn(int opcode, String owner, |
||||||
if ("loadedChunkHashMap_vanilla".equals(name)) { |
String name, String desc) { |
||||||
name = DEV ? "loadedChunkHashMap" : "field_73244_f"; |
if ("loadedChunkHashMap_vanilla".equals(name)) { |
||||||
|
name = asm.isDev() ? "loadedChunkHashMap" : "field_73244_f"; |
||||||
|
} |
||||||
|
super.visitFieldInsn(opcode, owner, name, desc); |
||||||
} |
} |
||||||
super.visitFieldInsn(opcode, owner, name, desc); |
}; |
||||||
} |
} |
||||||
}; |
}, 0); |
||||||
|
asm.loadClass(writer.toByteArray()); |
||||||
|
} |
||||||
|
if (asm.is("climateControl.utils.ChunkGeneratorExtractor")) { |
||||||
|
boolean undergroundBiomesInstalled = false; |
||||||
|
try { |
||||||
|
Class.forName("exterminatorJeff.undergroundBiomes.worldGen.ChunkProviderWrapper"); |
||||||
|
undergroundBiomesInstalled = true; |
||||||
|
} catch (Exception ignored) { |
||||||
|
} |
||||||
|
if (!undergroundBiomesInstalled) { |
||||||
|
FMLLog.log(Level.INFO, "KCauldron: Patching " + asm.getActualName() + " for compatibility with Climate Control"); |
||||||
|
extractFrom(asm, asm.method("extractFrom", |
||||||
|
"(Lnet/minecraft/world/WorldServer;)Lnet/minecraft/world/chunk/IChunkProvider;").instructions()); |
||||||
} |
} |
||||||
}, 0); |
} |
||||||
return writer.toByteArray(); |
} |
||||||
|
|
||||||
|
public void extractFrom(ImagineASM asm, InsnList list) { |
||||||
|
//Pair<String, String> fieldChunkProvider = asm.field("net/minecraft/world/World", "chunkProvider");
|
||||||
|
list.clear(); |
||||||
|
list.add(new IntInsnNode(ALOAD, 1)); |
||||||
|
list.add(new FieldInsnNode(GETFIELD, "ahb", "v", "Lapu;")); |
||||||
|
list.add(new InsnNode(ARETURN)); |
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue