diff --git a/src/main/java/com/skcraft/alicefixes/AliceFixes.java b/src/main/java/com/skcraft/alicefixes/AliceFixes.java index 66a8b8d..6c009ed 100644 --- a/src/main/java/com/skcraft/alicefixes/AliceFixes.java +++ b/src/main/java/com/skcraft/alicefixes/AliceFixes.java @@ -11,6 +11,7 @@ public class AliceFixes { @EventHandler public void postInit(FMLPostInitializationEvent evt) { MinecraftForge.EVENT_BUS.register(new AFListener()); + BreakerBlacklist.load(); } } diff --git a/src/main/java/com/skcraft/alicefixes/BreakerBlacklist.java b/src/main/java/com/skcraft/alicefixes/BreakerBlacklist.java new file mode 100644 index 0000000..078dd8e --- /dev/null +++ b/src/main/java/com/skcraft/alicefixes/BreakerBlacklist.java @@ -0,0 +1,35 @@ +package com.skcraft.alicefixes; + +import cpw.mods.fml.common.Loader; +import net.minecraftforge.common.Configuration; + +import java.io.File; + +public class BreakerBlacklist { + + public static int[] blacklist = new int[] {}; + + public static void load() { + File configDir = Loader.instance().getConfigDir(); + configDir = new File(configDir, "/cofh/"); + configDir.mkdir(); + configDir = new File(configDir, "breakerblacklist.cfg"); + Configuration list = new Configuration(configDir); + + try { + list.load(); + blacklist = list.get("Blacklist", "blacklist", new int[] {-1}, + "List of block IDs that the block breaker cannot break. Add 1 ID per line.").getIntList(); + } + catch(Throwable t) { + t.printStackTrace(); + } + finally { + list.save(); + } + } + + public static int[] getBlacklist() { + return blacklist; + } +} diff --git a/src/main/java/com/skcraft/alicefixes/LoadingPlugin.java b/src/main/java/com/skcraft/alicefixes/LoadingPlugin.java index 46f60db..cb82b8f 100644 --- a/src/main/java/com/skcraft/alicefixes/LoadingPlugin.java +++ b/src/main/java/com/skcraft/alicefixes/LoadingPlugin.java @@ -1,8 +1,6 @@ package com.skcraft.alicefixes; -import com.skcraft.alicefixes.util.ASMHelper; import cpw.mods.fml.relauncher.IFMLLoadingPlugin; - import java.util.Map; public class LoadingPlugin implements IFMLLoadingPlugin { diff --git a/src/main/java/com/skcraft/alicefixes/transformers/TransformBreaker.java b/src/main/java/com/skcraft/alicefixes/transformers/TransformBreaker.java new file mode 100644 index 0000000..f77ad91 --- /dev/null +++ b/src/main/java/com/skcraft/alicefixes/transformers/TransformBreaker.java @@ -0,0 +1,67 @@ +package com.skcraft.alicefixes.transformers; + +import com.skcraft.alicefixes.util.ASMHelper; +import net.minecraft.launchwrapper.IClassTransformer; +import org.objectweb.asm.*; + +import static org.objectweb.asm.Opcodes.*; + +public class TransformBreaker implements IClassTransformer { + + @Override + public byte[] transform(String name, String transformedName, byte[] bytes) { + if(name.equals("thermalexpansion.block.device.TileBreaker")) { + ClassReader cr = new ClassReader(bytes); + ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); + cr.accept(new BreakerVisitor(cw), 0); + return cw.toByteArray(); + } + return bytes; + } + + class BreakerVisitor extends ClassVisitor { + public BreakerVisitor(ClassVisitor cv) { + super(ASM4, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + + if(name.equals("breakBlock")) { + return new BreakBlockVisitor(super.visitMethod(access, name, + desc, signature, exceptions)); + } + return super.visitMethod(access, name, desc, signature, + exceptions); + } + } + + class BreakBlockVisitor extends MethodVisitor { + public BreakBlockVisitor(MethodVisitor mv) { + super(ASM4, mv); + } + + @Override + public void visitCode() { + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, + "thermalexpansion/block/device/TileBreaker", + "facing", + "B"); + mv.visitMethodInsn(INVOKESTATIC, + "com/skcraft/alicefixes/util/ASMHelper", + "canTileMine", + "(L" + ASMHelper.getObf("TileEntity") + ";B)Z"); + Label l1 = new Label(); + mv.visitJumpInsn(IFNE, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitInsn(RETURN); + mv.visitLabel(l1); + mv.visitCode(); + } + } +} diff --git a/src/main/java/com/skcraft/alicefixes/util/ASMHelper.java b/src/main/java/com/skcraft/alicefixes/util/ASMHelper.java index 6959fbb..6c64572 100644 --- a/src/main/java/com/skcraft/alicefixes/util/ASMHelper.java +++ b/src/main/java/com/skcraft/alicefixes/util/ASMHelper.java @@ -1,10 +1,9 @@ package com.skcraft.alicefixes.util; +import com.skcraft.alicefixes.BreakerBlacklist; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; @@ -40,6 +39,21 @@ public static boolean canMine(EntityLivingBase player, Object obj, int x, int y, return true; } + public static boolean canTileMine(TileEntity tile, byte facing) { + if(tile == null) return true; + + CoordHelper target = new CoordHelper(tile.xCoord, tile.yCoord, tile.zCoord); + target.addFacingAsOffset(facing); + int id = tile.worldObj.getBlockId(target.x, target.y, target.z); + + for(int blacklisted : BreakerBlacklist.getBlacklist()) { + if(id == blacklisted) { + return false; + } + } + return true; + } + private static boolean fireEvent(EntityLivingBase player, int x, int y, int z) { try { Method m = player.getClass().getDeclaredMethod("getBukkitEntity"); @@ -100,6 +114,7 @@ public static String getObf(String key) { mappings.put("World", "abw"); mappings.put("ItemStack", "ye"); mappings.put("EntityLivingBase", "of"); + mappings.put("TileEntity", "asp"); mappings.put("WorldObj", "field_70170_p"); } } diff --git a/src/main/java/com/skcraft/alicefixes/util/CoordHelper.java b/src/main/java/com/skcraft/alicefixes/util/CoordHelper.java new file mode 100644 index 0000000..7235076 --- /dev/null +++ b/src/main/java/com/skcraft/alicefixes/util/CoordHelper.java @@ -0,0 +1,35 @@ +package com.skcraft.alicefixes.util; + +public class CoordHelper { + + public int x, y, z; + + public CoordHelper(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public void addFacingAsOffset(byte facing) { + switch (facing) + { + case 0: + y--; + break; + case 1: + y++; + break; + case 2: + z--; + break; + case 3: + z++; + break; + case 4: + x--; + break; + default: + x++; + } + } +}