If you know what Reflection is you can do this easily. (In these examples I use a custom class I made called 'ReflectionManager', so you'll need to make your own to get these values)
Clientside Proxy:
public ChunkCoordinates getPlayerBreakingBlockCoords(EntityPlayer entityplayer)
{
int blockX = 0;
int blockY = 0;
int blockZ = 0;
if(entityplayer instanceof EntityClientPlayerMP)
{
PlayerControllerMP controller = Minecraft.getMinecraft().playerController;
boolean hasBlock = ReflectionManager.getPrivateBoolean(controller, "isHittingBlock", PlayerControllerMP.class);
if(hasBlock)
{
blockX = ReflectionManager.getPrivateInt(controller, "currentBlockX", PlayerControllerMP.class);
blockY = ReflectionManager.getPrivateInt(controller, "currentBlockY", PlayerControllerMP.class);
blockZ = ReflectionManager.getPrivateInt(controller, "currentBlockZ", PlayerControllerMP.class);
return new ChunkCoordinates(blockX, blockY, blockZ);
}
}else
{
return super.getPlayerBreakingBlockCoords(entityplayer);
}
return null;
}
Serverside Proxy:
public ChunkCoordinates getPlayerBreakingBlockCoords(EntityPlayer entityplayer)
{
int blockX = 0;
int blockY = 0;
int blockZ = 0;
if(entityplayer instanceof EntityPlayerMP)
{
ItemInWorldManager manager = ((EntityPlayerMP)(entityplayer)).theItemInWorldManager;
boolean hasBlock = ReflectionManager.getPrivateBoolean(manager, "isDestroyingBlock", ItemInWorldManager.class);
if(hasBlock)
{
blockX = ReflectionManager.getPrivateInt(manager, "partiallyDestroyedBlockX", ItemInWorldManager.class);
blockY = ReflectionManager.getPrivateInt(manager, "partiallyDestroyedBlockY", ItemInWorldManager.class);
blockZ = ReflectionManager.getPrivateInt(manager, "partiallyDestroyedBlockZ", ItemInWorldManager.class);
return new ChunkCoordinates(blockX, blockY, blockZ);
}
}
return null;
}
As with all reflection this comes with a performance cost if you use it constantly. Also note that here I use the actual names; When you go to reobfuscate you need to replace the names with the obfuscated names or this won't work.