From 7fa9ac3140fa82efe03662135b5e6711a438f26f Mon Sep 17 00:00:00 2001 From: krwminer Date: Sun, 6 Dec 2015 20:11:00 -0500 Subject: [PATCH] Add support to prevent Thaumcraft Taint Biome spread. --- src/main/java/myessentials/DepLoader.java | 1 + .../BlockTaintFibersTransformer.java | 69 +++++++++++++++++++ .../myessentials/event/ModifyBiomeEvent.java | 30 ++++++++ 3 files changed, 100 insertions(+) create mode 100644 src/main/java/myessentials/classtransformers/BlockTaintFibersTransformer.java create mode 100644 src/main/java/myessentials/event/ModifyBiomeEvent.java diff --git a/src/main/java/myessentials/DepLoader.java b/src/main/java/myessentials/DepLoader.java index 0bb4ece..5966cf1 100644 --- a/src/main/java/myessentials/DepLoader.java +++ b/src/main/java/myessentials/DepLoader.java @@ -29,6 +29,7 @@ public String[] getASMTransformerClass() { "myessentials.classtransformers.AE2PlaceTransformer", "myessentials.classtransformers.BlockFarmlandTransformer", "myessentials.classtransformers.BlockFireTransformer", + "myessentials.classtransformers.BlockTaintFibersTransformer", "myessentials.classtransformers.EntityFireballTransformer", "myessentials.classtransformers.EntityThrowableTransformer", "myessentials.classtransformers.SignClassTransformer" diff --git a/src/main/java/myessentials/classtransformers/BlockTaintFibersTransformer.java b/src/main/java/myessentials/classtransformers/BlockTaintFibersTransformer.java new file mode 100644 index 0000000..f3b61d4 --- /dev/null +++ b/src/main/java/myessentials/classtransformers/BlockTaintFibersTransformer.java @@ -0,0 +1,69 @@ +package myessentials.classtransformers; + +import net.minecraft.launchwrapper.IClassTransformer; +import net.minecraft.world.World; + +import org.objectweb.asm.*; +import org.objectweb.asm.commons.GeneratorAdapter; + +/** + * Patches BlockTaintFibers to add a hook for the {@link myessentials.event.ModifyBlockEvent}. + *
+ * + */ +public class BlockTaintFibersTransformer implements IClassTransformer { + + private class BlockTaintFibersGeneratorAdapter extends GeneratorAdapter { + + protected BlockTaintFibersGeneratorAdapter(MethodVisitor mv, int access, String name, String desc) { + super(Opcodes.ASM4, mv, access, name, desc); + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + super.visitJumpInsn(opcode, label); + if(opcode == Opcodes.IF_ICMPLT) { + super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitVarInsn(Opcodes.ILOAD, 1); + super.visitVarInsn(Opcodes.ILOAD, 6); + super.visitInsn(Opcodes.IADD); + super.visitVarInsn(Opcodes.ILOAD, 3); + super.visitVarInsn(Opcodes.ILOAD, 7); + super.visitInsn(Opcodes.IADD); + super.visitMethodInsn(Opcodes.INVOKESTATIC, "myessentials/event/ModifyBiomeEvent", "checkBiome", "(Lnet/minecraft/world/World;II)Z", false); + + Label elseLabel = new Label(); + super.visitJumpInsn(Opcodes.IFEQ, elseLabel); + super.visitInsn(Opcodes.RETURN); + super.visitLabel(elseLabel); + } + } + } + + @Override + public byte[] transform(String name, String srgName, byte[] bytes) { + if("thaumcraft.common.blocks.BlockTaintFibres".equals(srgName)) { + ClassReader reader = new ClassReader(bytes); + ClassWriter writer = new ClassWriter(reader, Opcodes.ASM4); + + ClassVisitor visitor = new ClassVisitor(Opcodes.ASM4, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + + if("taintBiomeSpread".equals(name)) { + return new BlockTaintFibersGeneratorAdapter(methodVisitor, access, name, desc); + } + + return methodVisitor; + } + }; + + reader.accept(visitor, ClassReader.EXPAND_FRAMES); + + bytes = writer.toByteArray(); + } + + return bytes; + } +} diff --git a/src/main/java/myessentials/event/ModifyBiomeEvent.java b/src/main/java/myessentials/event/ModifyBiomeEvent.java new file mode 100644 index 0000000..fced4d0 --- /dev/null +++ b/src/main/java/myessentials/event/ModifyBiomeEvent.java @@ -0,0 +1,30 @@ +package myessentials.event; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import cpw.mods.fml.common.eventhandler.Event; +import net.minecraft.block.Block; +import net.minecraftforge.common.MinecraftForge; +import net.minecraft.world.World; + +/** + * Fired when a biome is about to be modified. + * If the event is canceled the biome is not modified. + */ +@Cancelable +public class ModifyBiomeEvent extends Event +{ + public final int x; + public final int z; + public final World world; + + public ModifyBiomeEvent(World world, int x, int z) { + this.x = x; + this.z = z; + this.world = world; + } + + @SuppressWarnings("unused") + public static boolean checkBiome(World world, int x, int z) { + return MinecraftForge.EVENT_BUS.post(new ModifyBiomeEvent(world, x, z)); + } +}