--- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java
+++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java
@@ -13,8 +13,13 @@
 import net.minecraft.world.item.crafting.SingleRecipeInput;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+// CraftBukkit start
+import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace;
+import org.bukkit.craftbukkit.inventory.view.CraftFurnaceView;
+// CraftBukkit end
 
 public abstract class AbstractFurnaceMenu extends RecipeBookMenu<SingleRecipeInput, AbstractCookingRecipe> {
+
     public static final int INGREDIENT_SLOT = 0;
     public static final int FUEL_SLOT = 1;
     public static final int RESULT_SLOT = 2;
@@ -30,21 +35,27 @@
     private final RecipeType<? extends AbstractCookingRecipe> recipeType;
     private final RecipeBookType recipeBookType;
 
-    protected AbstractFurnaceMenu(
-        MenuType<?> type, RecipeType<? extends AbstractCookingRecipe> recipeType, RecipeBookType category, int syncId, Inventory playerInventory
-    ) {
+    // CraftBukkit start
+    private CraftFurnaceView bukkitEntity = null;
+    private Inventory player;
+
+    @Override
+    public CraftFurnaceView getBukkitView() {
+        if (this.bukkitEntity != null) {
+            return this.bukkitEntity;
+        }
+
+        CraftInventoryFurnace inventory = new CraftInventoryFurnace((AbstractFurnaceBlockEntity) this.container);
+        this.bukkitEntity = new CraftFurnaceView(this.player.player.getBukkitEntity(), inventory, this);
+        return this.bukkitEntity;
+    }
+    // CraftBukkit end
+
+    protected AbstractFurnaceMenu(MenuType<?> type, RecipeType<? extends AbstractCookingRecipe> recipeType, RecipeBookType category, int syncId, Inventory playerInventory) {
         this(type, recipeType, category, syncId, playerInventory, new SimpleContainer(3), new SimpleContainerData(4));
     }
 
-    protected AbstractFurnaceMenu(
-        MenuType<?> type,
-        RecipeType<? extends AbstractCookingRecipe> recipeType,
-        RecipeBookType category,
-        int syncId,
-        Inventory playerInventory,
-        Container inventory,
-        ContainerData propertyDelegate
-    ) {
+    protected AbstractFurnaceMenu(MenuType<?> type, RecipeType<? extends AbstractCookingRecipe> recipeType, RecipeBookType category, int syncId, Inventory playerInventory, Container inventory, ContainerData propertyDelegate) {
         super(type, syncId);
         this.recipeType = recipeType;
         this.recipeBookType = category;
@@ -56,15 +67,18 @@
         this.addSlot(new Slot(inventory, 0, 56, 17));
         this.addSlot(new FurnaceFuelSlot(this, inventory, 1, 56, 53));
         this.addSlot(new FurnaceResultSlot(playerInventory.player, inventory, 2, 116, 35));
+        this.player = playerInventory; // CraftBukkit - save player
 
-        for (int i = 0; i < 3; i++) {
-            for (int j = 0; j < 9; j++) {
-                this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
+        int j;
+
+        for (j = 0; j < 3; ++j) {
+            for (int k = 0; k < 9; ++k) {
+                this.addSlot(new Slot(playerInventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18));
             }
         }
 
-        for (int k = 0; k < 9; k++) {
-            this.addSlot(new Slot(playerInventory, k, 8 + k * 18, 142));
+        for (j = 0; j < 9; ++j) {
+            this.addSlot(new Slot(playerInventory, j, 8 + j * 18, 142));
         }
 
         this.addDataSlots(propertyDelegate);
@@ -73,8 +87,9 @@
     @Override
     public void fillCraftSlotsStackedContents(StackedContents finder) {
         if (this.container instanceof StackedContentsCompatible) {
-            ((StackedContentsCompatible)this.container).fillStackedContents(finder);
+            ((StackedContentsCompatible) this.container).fillStackedContents(finder);
         }
+
     }
 
     @Override
@@ -85,7 +100,7 @@
 
     @Override
     public boolean recipeMatches(RecipeHolder<AbstractCookingRecipe> recipe) {
-        return recipe.value().matches(new SingleRecipeInput(this.container.getItem(0)), this.level);
+        return ((AbstractCookingRecipe) recipe.value()).matches(new SingleRecipeInput(this.container.getItem(0)), this.level);
     }
 
     @Override
@@ -110,56 +125,59 @@
 
     @Override
     public boolean stillValid(Player player) {
+        if (!this.checkReachable) return true; // CraftBukkit
         return this.container.stillValid(player);
     }
 
     @Override
     public ItemStack quickMoveStack(Player player, int slot) {
-        ItemStack itemStack = ItemStack.EMPTY;
-        Slot slot2 = this.slots.get(slot);
-        if (slot2 != null && slot2.hasItem()) {
-            ItemStack itemStack2 = slot2.getItem();
-            itemStack = itemStack2.copy();
+        ItemStack itemstack = ItemStack.EMPTY;
+        Slot slot1 = (Slot) this.slots.get(slot);
+
+        if (slot1 != null && slot1.hasItem()) {
+            ItemStack itemstack1 = slot1.getItem();
+
+            itemstack = itemstack1.copy();
             if (slot == 2) {
-                if (!this.moveItemStackTo(itemStack2, 3, 39, true)) {
+                if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
                     return ItemStack.EMPTY;
                 }
 
-                slot2.onQuickCraft(itemStack2, itemStack);
+                slot1.onQuickCraft(itemstack1, itemstack);
             } else if (slot != 1 && slot != 0) {
-                if (this.canSmelt(itemStack2)) {
-                    if (!this.moveItemStackTo(itemStack2, 0, 1, false)) {
+                if (this.canSmelt(itemstack1)) {
+                    if (!this.moveItemStackTo(itemstack1, 0, 1, false)) {
                         return ItemStack.EMPTY;
                     }
-                } else if (this.isFuel(itemStack2)) {
-                    if (!this.moveItemStackTo(itemStack2, 1, 2, false)) {
+                } else if (this.isFuel(itemstack1)) {
+                    if (!this.moveItemStackTo(itemstack1, 1, 2, false)) {
                         return ItemStack.EMPTY;
                     }
                 } else if (slot >= 3 && slot < 30) {
-                    if (!this.moveItemStackTo(itemStack2, 30, 39, false)) {
+                    if (!this.moveItemStackTo(itemstack1, 30, 39, false)) {
                         return ItemStack.EMPTY;
                     }
-                } else if (slot >= 30 && slot < 39 && !this.moveItemStackTo(itemStack2, 3, 30, false)) {
+                } else if (slot >= 30 && slot < 39 && !this.moveItemStackTo(itemstack1, 3, 30, false)) {
                     return ItemStack.EMPTY;
                 }
-            } else if (!this.moveItemStackTo(itemStack2, 3, 39, false)) {
+            } else if (!this.moveItemStackTo(itemstack1, 3, 39, false)) {
                 return ItemStack.EMPTY;
             }
 
-            if (itemStack2.isEmpty()) {
-                slot2.setByPlayer(ItemStack.EMPTY);
+            if (itemstack1.isEmpty()) {
+                slot1.setByPlayer(ItemStack.EMPTY);
             } else {
-                slot2.setChanged();
+                slot1.setChanged();
             }
 
-            if (itemStack2.getCount() == itemStack.getCount()) {
+            if (itemstack1.getCount() == itemstack.getCount()) {
                 return ItemStack.EMPTY;
             }
 
-            slot2.onTake(player, itemStack2);
+            slot1.onTake(player, itemstack1);
         }
 
-        return itemStack;
+        return itemstack;
     }
 
     protected boolean canSmelt(ItemStack itemStack) {
@@ -173,16 +191,18 @@
     public float getBurnProgress() {
         int i = this.data.get(2);
         int j = this.data.get(3);
-        return j != 0 && i != 0 ? Mth.clamp((float)i / (float)j, 0.0F, 1.0F) : 0.0F;
+
+        return j != 0 && i != 0 ? Mth.clamp((float) i / (float) j, 0.0F, 1.0F) : 0.0F;
     }
 
     public float getLitProgress() {
         int i = this.data.get(1);
+
         if (i == 0) {
             i = 200;
         }
 
-        return Mth.clamp((float)this.data.get(0) / (float)i, 0.0F, 1.0F);
+        return Mth.clamp((float) this.data.get(0) / (float) i, 0.0F, 1.0F);
     }
 
     public boolean isLit() {
