diff --git a/connector/src/main/java/org/geysermc/connector/inventory/Inventory.java b/connector/src/main/java/org/geysermc/connector/inventory/Inventory.java
index 24ec4a3c7..859257bb2 100644
--- a/connector/src/main/java/org/geysermc/connector/inventory/Inventory.java
+++ b/connector/src/main/java/org/geysermc/connector/inventory/Inventory.java
@@ -52,6 +52,7 @@ public class Inventory {
     @Setter
     protected String title;
 
+    @Getter
     @Setter
     protected ItemStack[] items;
 
diff --git a/connector/src/main/java/org/geysermc/connector/inventory/PlayerInventory.java b/connector/src/main/java/org/geysermc/connector/inventory/PlayerInventory.java
index a11ce856b..52fb786bc 100644
--- a/connector/src/main/java/org/geysermc/connector/inventory/PlayerInventory.java
+++ b/connector/src/main/java/org/geysermc/connector/inventory/PlayerInventory.java
@@ -50,6 +50,6 @@ public class PlayerInventory extends Inventory {
     }
 
     public ItemStack getItemInHand() {
-        return items[heldItemSlot];
+        return items[36 + heldItemSlot];
     }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java
index 18ac3e6dc..4b4f66db4 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java
@@ -32,9 +32,9 @@ import com.nukkitx.nbt.NbtUtils;
 import com.nukkitx.nbt.stream.NBTInputStream;
 import com.nukkitx.nbt.tag.CompoundTag;
 import com.nukkitx.nbt.tag.ListTag;
-import gnu.trove.map.TObjectIntMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
 import it.unimi.dsi.fastutil.ints.*;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.utils.Toolbox;
 
@@ -52,6 +52,8 @@ public class BlockTranslator {
     private static final IntSet WATERLOGGED = new IntOpenHashSet();
 
     private static final Map<BlockState, String> JAVA_ID_TO_BLOCK_ENTITY_MAP = new HashMap<>();
+    public static final Int2FloatMap JAVA_RUNTIME_ID_TO_HARDNESS = new Int2FloatOpenHashMap();
+
 
     private static final int BLOCK_STATE_VERSION = 17760256;
 
@@ -81,7 +83,9 @@ public class BlockTranslator {
         } catch (Exception e) {
             throw new AssertionError("Unable to load Java block mappings", e);
         }
-        TObjectIntMap<CompoundTag> addedStatesMap = new TObjectIntHashMap<>(512, 0.5f, -1);
+
+        Object2IntMap<CompoundTag> addedStatesMap = new Object2IntOpenHashMap<>();
+
         List<CompoundTag> paletteList = new ArrayList<>();
 
         int waterRuntimeId = -1;
@@ -94,6 +98,11 @@ public class BlockTranslator {
             String javaId = entry.getKey();
             BlockState javaBlockState = new BlockState(javaRuntimeId);
             CompoundTag blockTag = buildBedrockState(entry.getValue());
+            // TODO fix this, (no block should have a null hardness)
+            JsonNode hardnessNode = entry.getValue().get("block_hardness");
+            if (hardnessNode != null) {
+                JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.floatValue());
+            }
 
             JAVA_ID_BLOCK_MAP.put(javaId, javaBlockState);
 
@@ -118,7 +127,7 @@ public class BlockTranslator {
                 addedStatesMap.put(blockTag, bedrockRuntimeId);
                 paletteList.add(runtimeTag);
             } else {
-                int duplicateRuntimeId = addedStatesMap.get(blockTag);
+                int duplicateRuntimeId = addedStatesMap.getOrDefault(blockTag, -1);
                 if (duplicateRuntimeId == -1) {
                     GeyserConnector.getInstance().getLogger().debug("Mapping " + javaId + " was not found for bedrock edition!");
                 } else {
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java
index 5deb0370a..bf4d19fc5 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java
@@ -49,11 +49,17 @@ public abstract class BaseInventoryTranslator extends InventoryTranslator{
         if (action.getSource().getContainerId() == ContainerId.INVENTORY) {
             //hotbar
             if (slotnum >= 9) {
+                // TODO REMOVE
+                System.out.println(slotnum);
                 return slotnum + this.size - 9;
             } else {
+                // TODO REMOVE
+                System.out.println(slotnum);
                 return slotnum + this.size + 27;
             }
         }
+        // TODO REMOVE
+        System.out.println(slotnum);
         return slotnum;
     }
 
@@ -62,11 +68,17 @@ public abstract class BaseInventoryTranslator extends InventoryTranslator{
         if (slot >= this.size) {
             final int tmp = slot - this.size;
             if (tmp < 27) {
+                // TODO REMOVE
+                System.out.println(slot);
                 return tmp + 9;
             } else {
+                // TODO REMOVE
+                System.out.println(slot);
                 return tmp - 27;
             }
         }
+        // TODO REMOVE
+        System.out.println(slot);
         return slot;
     }
 
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java
index fd4f0b020..b9d515e9e 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java
@@ -32,7 +32,7 @@ import lombok.Getter;
 @AllArgsConstructor
 public class ItemEntry {
 
-    public static ItemEntry AIR = new ItemEntry("minecraft:air", 0, 0, 0);
+    public static ItemEntry AIR = new ItemEntry("minecraft:air", 0, 0, 0/*, "none", "none"*/);
 
     private String javaIdentifier;
     private int javaId;
@@ -40,6 +40,9 @@ public class ItemEntry {
     private int bedrockId;
     private int bedrockData;
 
+    //private String toolType;
+    //private String toolTier;
+
     @Override
     public boolean equals(Object obj) {
         return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier()));
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java
index 451081a1a..1f0482563 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java
@@ -25,10 +25,22 @@
 
 package org.geysermc.connector.network.translators.java.entity.player;
 
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
 import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket;
+import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.LevelEventType;
+import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
+import org.geysermc.connector.inventory.Inventory;
+import org.geysermc.connector.inventory.PlayerInventory;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.translators.PacketTranslator;
+import org.geysermc.connector.network.translators.block.BlockTranslator;
+import org.geysermc.connector.network.translators.item.ItemEntry;
 import org.geysermc.connector.utils.ChunkUtils;
+import org.geysermc.connector.utils.Toolbox;
+
+import java.util.Arrays;
 
 public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayerActionAckPacket> {
 
@@ -38,6 +50,137 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator<ServerPlayer
             case FINISH_DIGGING:
                 ChunkUtils.updateBlock(session, packet.getNewState(), packet.getPosition());
                 break;
+
+            case START_DIGGING: {
+                LevelEventPacket levelEvent = new LevelEventPacket();
+                levelEvent.setType(LevelEventType.BLOCK_START_BREAK);
+                levelEvent.setPosition(Vector3f.from(
+                        packet.getPosition().getX(),
+                        packet.getPosition().getY(),
+                        packet.getPosition().getZ()
+                ));
+                float blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(packet.getNewState().getId());
+
+                PlayerInventory inventory = session.getInventory();
+                ItemStack[] items = inventory.getItems();
+                System.out.println(Arrays.deepToString(items));
+                for (int i = 0; i != items.length; i++) {
+                    System.out.println("(" + i + ") " + items[i]);
+                }
+                int itemHandSlot = inventory.getHeldItemSlot();
+                System.out.println(itemHandSlot);
+                ItemStack item = inventory.getItemInHand();
+                System.out.println(item);
+                /*if (itemStack.getNbt() == null) {
+                    itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), new CompoundTag(""));
+                }*/
+                //ItemEntry item = Toolbox.ITEM_ENTRIES.get(itemStack.getId());
+                //System.out.println(item);
+                double breakTime = Math.ceil(getBreakTime(blockHardness, packet.getNewState().getId()/*, item*/) * 20);
+                levelEvent.setData((int) (65535 / breakTime));
+                session.getUpstream().sendPacket(levelEvent);
+                break;
+            }
+
+            case CANCEL_DIGGING: {
+                LevelEventPacket levelEvent = new LevelEventPacket();
+                levelEvent.setType(LevelEventType.BLOCK_STOP_BREAK);
+                levelEvent.setPosition(Vector3f.from(
+                        packet.getPosition().getX(),
+                        packet.getPosition().getY(),
+                        packet.getPosition().getZ()
+                ));
+                levelEvent.setData(0);
+                session.getUpstream().sendPacket(levelEvent);
+                break;
+            }
         }
     }
+
+    private double toolBreakTimeBonus0(
+            /*String toolType,*/ String toolTier/*, boolean isWoolBlock, boolean isCobweb*/) {
+        //if (toolType == ItemTool.TYPE_SWORD) return isCobweb ? 15.0 : 1.0;
+        //if (toolType == ItemTool.TYPE_SHEARS) return isWoolBlock ? 5.0 : 15.0;
+        //if (toolType == ItemTool.TYPE_NONE) return 1.0;
+        switch (toolTier) {
+            case "wooden":
+                return 2.0;
+            case "stone":
+                return 4.0;
+            case "iron":
+                return 6.0;
+            case "diamond":
+                return 8.0;
+            case "golden":
+                return 12.0;
+            default:
+                return 1.0;
+        }
+    }
+
+    /*private static double speedBonusByEfficiencyLore0(int efficiencyLoreLevel) {
+        if (efficiencyLoreLevel == 0) return 0;
+        return efficiencyLoreLevel * efficiencyLoreLevel + 1;
+    }*/
+
+    /*private static double speedRateByHasteLore0(int hasteLoreLevel) {
+        return 1.0 + (0.2 * hasteLoreLevel);
+    }*/
+
+    /*private static int toolType0(Item item) {
+        if (item.isSword()) return ItemTool.TYPE_SWORD;
+        if (item.isShovel()) return ItemTool.TYPE_SHOVEL;
+        if (item.isPickaxe()) return ItemTool.TYPE_PICKAXE;
+        if (item.isAxe()) return ItemTool.TYPE_AXE;
+        if (item.isShears()) return ItemTool.TYPE_SHEARS;
+        return ItemTool.TYPE_NONE;
+    }*/
+
+    /*private static boolean correctTool0(int blockToolType, Item item) {
+        return (blockToolType == ItemTool.TYPE_SWORD && item.isSword()) ||
+                (blockToolType == ItemTool.TYPE_SHOVEL && item.isShovel()) ||
+                (blockToolType == ItemTool.TYPE_PICKAXE && item.isPickaxe()) ||
+                (blockToolType == ItemTool.TYPE_AXE && item.isAxe()) ||
+                (blockToolType == ItemTool.TYPE_SHEARS && item.isShears()) ||
+                blockToolType == ItemTool.TYPE_NONE;
+    }*/
+
+    //http://minecraft.gamepedia.com/Breaking
+    private double breakTime0(double blockHardness/*, String toolTier*/
+            /*double blockHardness, boolean correctTool, boolean canHarvestWithHand,
+                                     int blockId, int toolType, String toolTier, int efficiencyLoreLevel, int hasteEffectLevel,
+                                     boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround*/) {
+        double baseTime = (/*(correctTool || canHarvestWithHand)*/true ? 1.5 : 5.0) * blockHardness;
+        double speed = 1.0 / baseTime;
+        //boolean isWoolBlock = blockId == Block.WOOL, isCobweb = blockId == Block.COBWEB;
+        //if (correctTool)
+        //speed *= toolBreakTimeBonus0(toolTier/*toolType, toolTier, isWoolBlock, isCobweb*/);
+        //speed += speedBonusByEfficiencyLore0(efficiencyLoreLevel);
+        //speed *= speedRateByHasteLore0(hasteEffectLevel);
+        //if (insideOfWaterWithoutAquaAffinity) speed *= 0.2;
+        //if (outOfWaterButNotOnGround) speed *= 0.2;
+        return 1.0 / speed;
+    }
+
+    private double getBreakTime(double blockHardness, int blockId/*, ItemEntry item*/) {
+        //Objects.requireNonNull(item, "getBreakTime: Item can not be null");
+        //Objects.requireNonNull(player, "getBreakTime: Player can not be null");
+        //boolean correctTool = correctTool0(getToolType(), item);
+        //boolean canHarvestWithHand = canHarvestWithHand();
+        //int blockId = getId();
+        //int itemToolType = toolType0(item);
+        //int itemTier = item.getTier();
+        //int efficiencyLoreLevel = Optional.ofNullable(item.getEnchantment(Enchantment.ID_EFFICIENCY))
+        //        .map(Enchantment::getLevel).orElse(0);
+        //int hasteEffectLevel = Optional.ofNullable(player.getEffect(Effect.HASTE))
+        //       .map(Effect::getAmplifier).orElse(0);
+        //boolean insideOfWaterWithoutAquaAffinity = player.isInsideOfWater() &&
+        //        Optional.ofNullable(player.getInventory().getHelmet().getEnchantment(Enchantment.ID_WATER_WORKER))
+        //                .map(Enchantment::getLevel).map(l -> l >= 1).orElse(false);
+        //boolean outOfWaterButNotOnGround = (!player.isInsideOfWater()) && (!player.isOnGround());
+        //return breakTime0(blockHardness, correctTool, canHarvestWithHand, blockId, itemToolType, itemTier,
+        //        efficiencyLoreLevel, hasteEffectLevel, insideOfWaterWithoutAquaAffinity, outOfWaterButNotOnGround);
+        return breakTime0(blockHardness/*, item.getToolTier()*/);
+    }
+
 }
diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
index 9601b5819..4c1c21581 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
@@ -52,7 +52,7 @@ public class Toolbox {
     public static final CompoundTag BIOMES;
     public static final ItemData[] CREATIVE_ITEMS;
 
-    public static final Collection<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
+    public static final List<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
 
     public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>();
 
@@ -103,8 +103,12 @@ public class Toolbox {
         Iterator<Map.Entry<String, JsonNode>> iterator = items.fields();
         while (iterator.hasNext()) {
             Map.Entry<String, JsonNode> entry = iterator.next();
-            ITEM_ENTRIES.put(itemIndex, new ItemEntry(entry.getKey(), itemIndex,
-                    entry.getValue().get("bedrock_id").intValue(), entry.getValue().get("bedrock_data").intValue()));
+            ITEM_ENTRIES.put(itemIndex, new ItemEntry(
+                    entry.getKey(), itemIndex,
+                    entry.getValue().get("bedrock_id").intValue(),
+                    entry.getValue().get("bedrock_data").intValue()/*,
+                    entry.getValue().get("tool_type").textValue(),
+                    entry.getValue().get("tool_tier").textValue()*/));
             itemIndex++;
         }