diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..49acca4 --- /dev/null +++ b/.classpath @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14075d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/build +/*.bat +/forge +/bin +/download \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..6842c7a --- /dev/null +++ b/.project @@ -0,0 +1,56 @@ + + + Minecraft + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + + + Alice Fixes + 2 + PROJECT_LOC/alicefixes/src + + + jars + 2 + MCP_LOC/jars + + + lib + 2 + MCP_LOC/lib + + + src + 2 + MCP_LOC/src/minecraft + + + + + 1307293455427 + jars + 13 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-bin + + + + + + MCP_LOC + $%7BPROJECT_LOC%7D/forge/mcp + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..600bd72 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +To compile: +Install Ant (http://ant.apache.org/) and run "ant". All dependencies will be downloaded for you. \ No newline at end of file diff --git a/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java b/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java new file mode 100644 index 0000000..8d5f63a --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/AliceTransformer.java @@ -0,0 +1,48 @@ +package com.skcraft.alicefixes; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import cpw.mods.fml.common.FMLLog; +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; + } + +} diff --git a/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java b/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java new file mode 100644 index 0000000..fbb56fa --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/LoadingPlugin.java @@ -0,0 +1,45 @@ +package com.skcraft.alicefixes; + +import java.util.Map; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; + +@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"*/}; + } + +} diff --git a/alicefixes/src/com/skcraft/alicefixes/ObfNames.java b/alicefixes/src/com/skcraft/alicefixes/ObfNames.java new file mode 100644 index 0000000..946d607 --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/ObfNames.java @@ -0,0 +1,8 @@ +package com.skcraft.alicefixes; + +public class ObfNames { + + public static final String ENTITY_LIVING = "md"; + public static final String ENTITY = "lq"; + +} diff --git a/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java b/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java new file mode 100644 index 0000000..408ab79 --- /dev/null +++ b/alicefixes/src/com/skcraft/alicefixes/TransformMiningLaser.java @@ -0,0 +1,117 @@ +package com.skcraft.alicefixes; + +import static org.objectweb.asm.Opcodes.*; + +import java.lang.reflect.Method; +import java.util.Iterator; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; +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 net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; +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(IFEQ, 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; + } +} diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..1fb3374 --- /dev/null +++ b/build.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file