From e7ec7db44781dea4f69fa044256cb153450547d9 Mon Sep 17 00:00:00 2001 From: Chicken Bones Date: Wed, 31 Jul 2013 20:28:29 +1000 Subject: [PATCH] Added handling case for mods that call removeBlockByPlayer when the player isn't looking at the block. Added guard for mods that recursively call PlayerInteractEvent. Fixed npe when obtaining class bytes in ASMMixinCompiler --- codechicken/multipart/BlockMultipart.scala | 22 ++++++++++++++----- .../multipart/asm/ASMMixinCompiler.scala | 5 ++++- .../multipart/minecraft/EventHandler.java | 13 +++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/codechicken/multipart/BlockMultipart.scala b/codechicken/multipart/BlockMultipart.scala index 5228c6f..ebfca29 100644 --- a/codechicken/multipart/BlockMultipart.scala +++ b/codechicken/multipart/BlockMultipart.scala @@ -95,13 +95,14 @@ trait BlockMultipart extends Block override def removeBlockByPlayer(world:World, player:EntityPlayer, x:Int, y:Int, z:Int):Boolean = { - val hit = RayTracer.retraceBlock(world, player, x, y, z); - if(hit == null) - return false; - + val hit = RayTracer.retraceBlock(world, player, x, y, z) val tile = getTile(world, x, y, z) - if(tile == null) - return false + + if(hit == null || tile == null) + { + dropAndDestroy(world, x, y, z) + return true + } val hitInfo:(Int, _) = ExtendedMOP.getData(hit) if(world.isRemote) @@ -113,6 +114,15 @@ trait BlockMultipart extends Block return tile.harvestPart(hitInfo._1, !player.capabilities.isCreativeMode); } + def dropAndDestroy(world:World, x:Int, y:Int, z:Int) + { + val tile = getTile(world, x, y, z) + if(tile != null && !world.isRemote) + tile.dropItems(getBlockDropped(world, x, y, z, 0, 0)) + + world.setBlockToAir(x, y, z) + } + override def quantityDropped(meta:Int, fortune:Int, random:Random) = 0 override def getBlockDropped(world:World, x:Int, y:Int, z:Int, meta:Int, fortune:Int):ArrayList[ItemStack] = diff --git a/codechicken/multipart/asm/ASMMixinCompiler.scala b/codechicken/multipart/asm/ASMMixinCompiler.scala index 2d78abb..39806e3 100644 --- a/codechicken/multipart/asm/ASMMixinCompiler.scala +++ b/codechicken/multipart/asm/ASMMixinCompiler.scala @@ -78,7 +78,10 @@ object ASMMixinCompiler def getBytes(name:String) = { val jName = name.replace('/', '.') - m_runTransformers.invoke(cl, jName, jName, cl.getClassBytes(jName)).asInstanceOf[Array[Byte]] + cl.getClassBytes(jName) match { + case null => null + case v => m_runTransformers.invoke(cl, jName, jName, v).asInstanceOf[Array[Byte]] + } } def internalDefine(name:String, bytes:Array[Byte]) diff --git a/codechicken/multipart/minecraft/EventHandler.java b/codechicken/multipart/minecraft/EventHandler.java index af23f04..55f0b26 100644 --- a/codechicken/multipart/minecraft/EventHandler.java +++ b/codechicken/multipart/minecraft/EventHandler.java @@ -19,11 +19,20 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; public class EventHandler { + private ThreadLocal placing = new ThreadLocal(); + @ForgeSubscribe public void playerInteract(PlayerInteractEvent event) { - if(event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.worldObj.isRemote && place(event.entityPlayer, event.entityPlayer.worldObj)) - event.setCanceled(true); + if(event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.worldObj.isRemote) + { + if(placing.get() != null) + return;//for mods that do dumb stuff and call this event like MFR + placing.set(event); + if(place(event.entityPlayer, event.entityPlayer.worldObj)) + event.setCanceled(true); + placing.set(null); + } } public static boolean place(EntityPlayer player, World world)