From 083453b512530e204e76069ae0cdef182b6ad8d2 Mon Sep 17 00:00:00 2001 From: Joe O'Hara Date: Thu, 18 Apr 2013 18:24:32 -0400 Subject: [PATCH] Added a block breaker blacklist. Also tabs -> spaces. --- .../com/skcraft/alicefixes/AliceFixes.java | 15 ++ .../skcraft/alicefixes/AliceTransformer.java | 72 ++++---- .../skcraft/alicefixes/BreakerBlacklist.java | 32 ++++ .../com/skcraft/alicefixes/CoordHelper.java | 37 ++++ .../com/skcraft/alicefixes/LoadingPlugin.java | 66 +++---- .../src/com/skcraft/alicefixes/ObfNames.java | 9 +- .../alicefixes/TransformBlockBreaker.java | 86 +++++++++ .../alicefixes/TransformMiningLaser.java | 174 +++++++++--------- 8 files changed, 332 insertions(+), 159 deletions(-) create mode 100644 alicefixes/src/com/skcraft/alicefixes/AliceFixes.java create mode 100644 alicefixes/src/com/skcraft/alicefixes/BreakerBlacklist.java create mode 100644 alicefixes/src/com/skcraft/alicefixes/CoordHelper.java create mode 100644 alicefixes/src/com/skcraft/alicefixes/TransformBlockBreaker.java diff --git a/alicefixes/src/com/skcraft/alicefixes/AliceFixes.java b/alicefixes/src/com/skcraft/alicefixes/AliceFixes.java new file mode 100644 index 0000000..066210d --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/AliceFixes.java @@ -0,0 +1,15 @@ +package com.skcraft.alicefixes; + +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.PreInit; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + +@Mod(modid = "aliceFixes", version = "0.1.0") +public class AliceFixes { + + @PreInit + public void preInit(FMLPreInitializationEvent evt) { + BreakerBlacklist.load(); + } + +} diff --git a/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java b/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java index 8d5f63a..2f1bb4c 100644 --- a/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java +++ b/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java @@ -8,41 +8,41 @@ import cpw.mods.fml.relauncher.IClassTransformer; public class AliceTransformer implements IClassTransformer { - - private final List transformers; - - public AliceTransformer() { - String[] names = LoadingPlugin.getTransformers(); - transformers = new ArrayList(names.length); - for(String transformer : names) { - try { - transformers.add((IClassTransformer)Class.forName(transformer).newInstance()); - } - catch(Throwable t) { - t.printStackTrace(); - } - } - } - - @Override - public byte[] transform(String name, byte[] bytes) { - - if(bytes == null) { - return bytes; - } - - for(IClassTransformer transformer : transformers) { - try { - bytes = transformer.transform(name, bytes); - if(bytes == null) - FMLLog.log(Level.SEVERE, "Transformer " + transformer + " has corrupted class " + name); - } - catch(Throwable t) { - t.printStackTrace(); - } - } - - return bytes; - } + + private final List transformers; + + public AliceTransformer() { + String[] names = LoadingPlugin.getTransformers(); + transformers = new ArrayList(names.length); + for(String transformer : names) { + try { + transformers.add((IClassTransformer)Class.forName(transformer).newInstance()); + } + catch(Throwable t) { + t.printStackTrace(); + } + } + } + + @Override + public byte[] transform(String name, byte[] bytes) { + + if(bytes == null) { + return bytes; + } + + for(IClassTransformer transformer : transformers) { + try { + bytes = transformer.transform(name, bytes); + if(bytes == null) + FMLLog.log(Level.SEVERE, "Transformer " + transformer + " has corrupted class " + name); + } + catch(Throwable t) { + t.printStackTrace(); + } + } + + return bytes; + } } diff --git a/alicefixes/src/com/skcraft/alicefixes/BreakerBlacklist.java b/alicefixes/src/com/skcraft/alicefixes/BreakerBlacklist.java new file mode 100644 index 0000000..220e990 --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/BreakerBlacklist.java @@ -0,0 +1,32 @@ +package com.skcraft.alicefixes; + +import java.io.File; + +import cpw.mods.fml.common.Loader; +import net.minecraftforge.common.Configuration; + +public class BreakerBlacklist { + + public static int[] forbiddenIds = new int[] {}; + + public static void load() { + File configDir = Loader.instance().getConfigDir(); + configDir = new File(configDir, "/redpower/"); + configDir.mkdir(); + configDir = new File(configDir, "blacklist.cfg"); + Configuration blacklist = new Configuration(configDir); + + try { + blacklist.load(); + forbiddenIds = blacklist.get("Blacklist", "forbiddenBlocks", + 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 { + blacklist.save(); + } + } + +} diff --git a/alicefixes/src/com/skcraft/alicefixes/CoordHelper.java b/alicefixes/src/com/skcraft/alicefixes/CoordHelper.java new file mode 100644 index 0000000..ace9e52 --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/CoordHelper.java @@ -0,0 +1,37 @@ +package com.skcraft.alicefixes; + +public class CoordHelper { + + int x; + int y; + int z; + + public CoordHelper(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public void addFacingAsOffset(int facing) { + switch (facing) + { + case 0: + this.y += 1; + break; + case 1: + this.y -= 1; + break; + case 2: + this.z += 1; + break; + case 3: + this.z -= 1; + break; + case 4: + this.x += 1; + break; + default: + this.x -= 1; + } + } +} diff --git a/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java b/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java index fbb56fa..76e7c28 100644 --- a/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java +++ b/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java @@ -8,38 +8,38 @@ @TransformerExclusions("com.skcraft.alicefixes") public class LoadingPlugin implements IFMLLoadingPlugin { - @Override - public String[] getLibraryRequestClass() { - return null; - } - - @Override - public String[] getASMTransformerClass() { - System.out.println("getASMTransformerClass()"); - return new String[] { "com.skcraft.alicefixes.AliceTransformer" }; - } - - @Override - public String getModContainerClass() { - return null; - } - - @Override - public String getSetupClass() { - return null; - } - - @Override - public void injectData(Map data) {} - - public static String[] getTransformers() { - return new String[] { "com.skcraft.alicefixes.TransformMiningLaser", - /*"com.skcraft.alicefixes.TransformIC2Explosions", - "com.skcraft.alicefixes.TransformTCExcWand", - "com.skcraft.alicefixes.TransformTCEquWand", - "com.skcraft.alicefixes.TransformTCFrostWand", - "com.skcraft.alicefixes.TransformTCAxe", - "com.skcraft.alicefixes.TransformTCShovel"*/}; - } + @Override + public String[] getLibraryRequestClass() { + return null; + } + + @Override + public String[] getASMTransformerClass() { + return new String[] { "com.skcraft.alicefixes.AliceTransformer" }; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) {} + + public static String[] getTransformers() { + return new String[] { "com.skcraft.alicefixes.TransformMiningLaser", + "com.skcraft.alicefixes.TransformBlockBreaker" + /*"com.skcraft.alicefixes.TransformIC2Explosions", + "com.skcraft.alicefixes.TransformTCExcWand", + "com.skcraft.alicefixes.TransformTCEquWand", + "com.skcraft.alicefixes.TransformTCFrostWand", + "com.skcraft.alicefixes.TransformTCAxe", + "com.skcraft.alicefixes.TransformTCShovel"*/}; + } } diff --git a/alicefixes/src/com/skcraft/alicefixes/ObfNames.java b/alicefixes/src/com/skcraft/alicefixes/ObfNames.java index 946d607..d56e443 100644 --- a/alicefixes/src/com/skcraft/alicefixes/ObfNames.java +++ b/alicefixes/src/com/skcraft/alicefixes/ObfNames.java @@ -1,8 +1,9 @@ package com.skcraft.alicefixes; public class ObfNames { - - public static final String ENTITY_LIVING = "md"; - public static final String ENTITY = "lq"; - + + public static final String ENTITY_LIVING = "md"; + public static final String ENTITY = "lq"; + public static final String TILE_ENTITY = "any"; + } diff --git a/alicefixes/src/com/skcraft/alicefixes/TransformBlockBreaker.java b/alicefixes/src/com/skcraft/alicefixes/TransformBlockBreaker.java new file mode 100644 index 0000000..cc17f67 --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/TransformBlockBreaker.java @@ -0,0 +1,86 @@ +package com.skcraft.alicefixes; + +import static org.objectweb.asm.Opcodes.*; + +import java.util.Iterator; +import java.util.logging.Level; + +import net.minecraft.tileentity.TileEntity; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.JumpInsnNode; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.relauncher.IClassTransformer; + +public class TransformBlockBreaker implements IClassTransformer { + + @Override + public byte[] transform(String name, byte[] bytes) { + if(name.equals("com.eloraam.redpower.machine.TileBreaker")) { + return handleBreakerTransform(bytes); + } + return bytes; + } + + private byte[] handleBreakerTransform(byte[] bytes) { + + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + + Iterator methods = classNode.methods.iterator(); + while(methods.hasNext()) { + MethodNode method = methods.next(); + if(method.name.equals("onBlockNeighborChange")) { + LabelNode l0 = new LabelNode(); + LabelNode l1 = new LabelNode(); + LabelNode l2 = new LabelNode(); + InsnList toInject = new InsnList(); + toInject.add(l0); + toInject.add(new VarInsnNode(ALOAD, 0)); //this + toInject.add(new VarInsnNode(ALOAD, 0)); //this + toInject.add(new FieldInsnNode(GETFIELD, "com/eloraam/redpower/machine/TileBreaker", "Rotation", "I")); + toInject.add(new MethodInsnNode(INVOKESTATIC, + "com/skcraft/alicefixes/TransformBlockBreaker", + "canMine", + "(L" + ObfNames.TILE_ENTITY + ";I)Z")); //Invoke canMine() in this class + toInject.add(new JumpInsnNode(IFNE, l1)); //if statement + toInject.add(l2); + toInject.add(new InsnNode(RETURN)); + toInject.add(l1); + + method.instructions.insertBefore(method.instructions.getFirst(), toInject); //insert before first instruction + FMLLog.log(Level.INFO, "Block Breaker successfully patched!"); + break; + } + } + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + classNode.accept(writer); + return writer.toByteArray(); + } + + public static boolean canMine(TileEntity tile, int rotation) { + + CoordHelper facingCoords = new CoordHelper(tile.xCoord, tile.yCoord, tile.zCoord); + facingCoords.addFacingAsOffset(rotation); + + int id = tile.worldObj.getBlockId(facingCoords.x, facingCoords.y, facingCoords.z); + + for(int i = 0; i < BreakerBlacklist.forbiddenIds.length; i++) { + if(id == BreakerBlacklist.forbiddenIds[i]) { + return false; + } + } + return true; + } +} diff --git a/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java b/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java index 05fdd29..4d528fd 100644 --- a/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java +++ b/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java @@ -4,6 +4,7 @@ import java.lang.reflect.Method; import java.util.Iterator; +import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -24,94 +25,95 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.IClassTransformer; public class TransformMiningLaser implements IClassTransformer{ - private final String LASER_CLASS_NAME = "ic2.core.item.tool.EntityMiningLaser"; - private final String MINE_METHOD_NAME = "canMine"; - - @Override - public byte[] transform(String name, byte[] bytes) { - if(name.equals(LASER_CLASS_NAME)) { - return handleLaserTransform(bytes); - } - return bytes; - } - - private byte[] handleLaserTransform(byte[] bytes) { - - ClassNode classNode = new ClassNode(); - ClassReader classReader = new ClassReader(bytes); - classReader.accept(classNode, 0); - - Iterator methods = classNode.methods.iterator(); - while(methods.hasNext()) { - MethodNode method = methods.next(); - if(method.name.equals(MINE_METHOD_NAME)) { - LabelNode l0 = new LabelNode(); - LabelNode l1 = new LabelNode(); - LabelNode l2 = new LabelNode(); - InsnList toInject = new InsnList(); - toInject.add(l0); - toInject.add(new VarInsnNode(ALOAD, 0)); //"this" - toInject.add(new VarInsnNode(ALOAD, 0)); //"this" - toInject.add(new FieldInsnNode(GETFIELD, "ic2/core/item/tool/EntityMiningLaser", "owner", - "L" + ObfNames.ENTITY_LIVING + ";")); //owner of laser - //invokes canMine() in this class - toInject.add(new MethodInsnNode(INVOKESTATIC, - "com/skcraft/alicefixes/TransformMiningLaser", - "canMine", - "(L" + ObfNames.ENTITY + ";L" + ObfNames.ENTITY_LIVING + ";)Z")); - toInject.add(new JumpInsnNode(IFNE, l1)); //if statement - toInject.add(l2); - toInject.add(new InsnNode(ICONST_0)); //false - toInject.add(new InsnNode(IRETURN)); //return - toInject.add(l1); - //Insert these instructions at the start of the method's - method.instructions.insertBefore(method.instructions.getFirst(), toInject); - - System.out.println("Mining laser successfully patched!"); - break; - } - } - - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); - classNode.accept(writer); - return writer.toByteArray(); - } - - public static boolean canMine(Entity laser, EntityLiving owner) { - Vec3 currentPos = Vec3.createVectorHelper(laser.posX, laser.posY, laser.posZ); - Vec3 heading = Vec3.createVectorHelper(laser.posX + laser.motionX, laser.posY + laser.motionY, laser.posZ + laser.motionZ); - MovingObjectPosition pos = laser.worldObj.rayTraceBlocks_do_do(currentPos, heading, false, true); - - if(pos != null) { - int xPos = pos.blockX; - int yPos = pos.blockY; - int zPos = pos.blockZ; - - try { - Method m = owner.getClass().getDeclaredMethod("getBukkitEntity", new Class[] {}); - org.bukkit.entity.Entity ent = (org.bukkit.entity.Entity)m.invoke(owner); - if ((ent instanceof Player)) { - Player player = (Player)ent; - org.bukkit.World bukkitWorld = player.getWorld(); - BlockBreakEvent breakEv = new BlockBreakEvent(bukkitWorld.getBlockAt(xPos, yPos, zPos), player); - Bukkit.getPluginManager().callEvent(breakEv); - if (breakEv.isCancelled()) { - laser.setDead(); - return false; - } - - breakEv.setCancelled(true); - } - } - catch(Exception e) { - e.printStackTrace(); - } - } - - return true; - } + private final String LASER_CLASS_NAME = "ic2.core.item.tool.EntityMiningLaser"; + private final String MINE_METHOD_NAME = "canMine"; + + @Override + public byte[] transform(String name, byte[] bytes) { + if(name.equals(LASER_CLASS_NAME)) { + return handleLaserTransform(bytes); + } + return bytes; + } + + private byte[] handleLaserTransform(byte[] bytes) { + + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + + Iterator methods = classNode.methods.iterator(); + while(methods.hasNext()) { + MethodNode method = methods.next(); + if(method.name.equals(MINE_METHOD_NAME)) { + LabelNode l0 = new LabelNode(); + LabelNode l1 = new LabelNode(); + LabelNode l2 = new LabelNode(); + InsnList toInject = new InsnList(); + toInject.add(l0); + toInject.add(new VarInsnNode(ALOAD, 0)); //"this" + toInject.add(new VarInsnNode(ALOAD, 0)); //"this" + toInject.add(new FieldInsnNode(GETFIELD, "ic2/core/item/tool/EntityMiningLaser", "owner", + "L" + ObfNames.ENTITY_LIVING + ";")); //owner of laser + //invokes canMine() in this class + toInject.add(new MethodInsnNode(INVOKESTATIC, + "com/skcraft/alicefixes/TransformMiningLaser", + "canMine", + "(L" + ObfNames.ENTITY + ";L" + ObfNames.ENTITY_LIVING + ";)Z")); + toInject.add(new JumpInsnNode(IFNE, l1)); //if statement + toInject.add(l2); + toInject.add(new InsnNode(ICONST_0)); //false + toInject.add(new InsnNode(IRETURN)); //return + toInject.add(l1); + //Insert these instructions at the start of the method's + method.instructions.insertBefore(method.instructions.getFirst(), toInject); + + FMLLog.log(Level.INFO, "Mining laser successfully patched!"); + break; + } + } + + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + classNode.accept(writer); + return writer.toByteArray(); + } + + public static boolean canMine(Entity laser, EntityLiving owner) { + Vec3 currentPos = Vec3.createVectorHelper(laser.posX, laser.posY, laser.posZ); + Vec3 heading = Vec3.createVectorHelper(laser.posX + laser.motionX, laser.posY + laser.motionY, laser.posZ + laser.motionZ); + MovingObjectPosition pos = laser.worldObj.rayTraceBlocks_do_do(currentPos, heading, false, true); + + if(pos != null) { + int xPos = pos.blockX; + int yPos = pos.blockY; + int zPos = pos.blockZ; + + try { + Method m = owner.getClass().getDeclaredMethod("getBukkitEntity", new Class[] {}); + org.bukkit.entity.Entity ent = (org.bukkit.entity.Entity)m.invoke(owner); + if ((ent instanceof Player)) { + Player player = (Player)ent; + org.bukkit.World bukkitWorld = player.getWorld(); + BlockBreakEvent breakEv = new BlockBreakEvent(bukkitWorld.getBlockAt(xPos, yPos, zPos), player); + Bukkit.getPluginManager().callEvent(breakEv); + if (breakEv.isCancelled()) { + laser.setDead(); + return false; + } + + breakEv.setCancelled(true); + } + } + catch(Exception e) { + e.printStackTrace(); + } + } + + return true; + } }