--- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
@@ -23,41 +23,80 @@
 import net.minecraft.world.level.block.ChestBlock;
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.level.block.state.properties.ChestType;
+// CraftBukkit start
+import java.util.List;
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
+import org.bukkit.entity.HumanEntity;
+// CraftBukkit end
 
 public class ChestBlockEntity extends RandomizableContainerBlockEntity implements LidBlockEntity {
+
     private static final int EVENT_SET_OPEN_COUNT = 1;
-    private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
-    public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
-        @Override
-        protected void onOpen(Level world, BlockPos pos, BlockState state) {
-            ChestBlockEntity.playSound(world, pos, state, SoundEvents.CHEST_OPEN);
-        }
+    private NonNullList<ItemStack> items;
+    public final ContainerOpenersCounter openersCounter;
+    private final ChestLidController chestLidController;
 
-        @Override
-        protected void onClose(Level world, BlockPos pos, BlockState state) {
-            ChestBlockEntity.playSound(world, pos, state, SoundEvents.CHEST_CLOSE);
-        }
+    // CraftBukkit start - add fields and methods
+    public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
+    private int maxStack = MAX_STACK;
 
-        @Override
-        protected void openerCountChanged(Level world, BlockPos pos, BlockState state, int oldViewerCount, int newViewerCount) {
-            ChestBlockEntity.this.signalOpenCount(world, pos, state, oldViewerCount, newViewerCount);
-        }
+    public List<ItemStack> getContents() {
+        return this.items;
+    }
 
-        @Override
-        protected boolean isOwnContainer(Player player) {
-            if (!(player.containerMenu instanceof ChestMenu)) {
-                return false;
-            } else {
-                Container container = ((ChestMenu)player.containerMenu).getContainer();
-                return container == ChestBlockEntity.this
-                    || container instanceof CompoundContainer && ((CompoundContainer)container).contains(ChestBlockEntity.this);
-            }
-        }
-    };
-    private final ChestLidController chestLidController = new ChestLidController();
+    public void onOpen(CraftHumanEntity who) {
+        this.transaction.add(who);
+    }
+
+    public void onClose(CraftHumanEntity who) {
+        this.transaction.remove(who);
+    }
+
+    public List<HumanEntity> getViewers() {
+        return this.transaction;
+    }
+
+    @Override
+    public int getMaxStackSize() {
+        return this.maxStack;
+    }
+
+    public void setMaxStackSize(int size) {
+        this.maxStack = size;
+    }
+    // CraftBukkit end
 
     protected ChestBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
         super(type, pos, state);
+        this.items = NonNullList.withSize(27, ItemStack.EMPTY);
+        this.openersCounter = new ContainerOpenersCounter() {
+            @Override
+            protected void onOpen(Level world, BlockPos pos, BlockState state) {
+                ChestBlockEntity.playSound(world, pos, state, SoundEvents.CHEST_OPEN);
+            }
+
+            @Override
+            protected void onClose(Level world, BlockPos pos, BlockState state) {
+                ChestBlockEntity.playSound(world, pos, state, SoundEvents.CHEST_CLOSE);
+            }
+
+            @Override
+            protected void openerCountChanged(Level world, BlockPos pos, BlockState state, int oldViewerCount, int newViewerCount) {
+                ChestBlockEntity.this.signalOpenCount(world, pos, state, oldViewerCount, newViewerCount);
+            }
+
+            @Override
+            protected boolean isOwnContainer(Player player) {
+                if (!(player.containerMenu instanceof ChestMenu)) {
+                    return false;
+                } else {
+                    Container iinventory = ((ChestMenu) player.containerMenu).getContainer();
+
+                    return iinventory == ChestBlockEntity.this || iinventory instanceof CompoundContainer && ((CompoundContainer) iinventory).contains(ChestBlockEntity.this);
+                }
+            }
+        };
+        this.chestLidController = new ChestLidController();
     }
 
     public ChestBlockEntity(BlockPos pos, BlockState state) {
@@ -81,6 +120,7 @@
         if (!this.tryLoadLootTable(nbt)) {
             ContainerHelper.loadAllItems(nbt, this.items, registryLookup);
         }
+
     }
 
     @Override
@@ -89,6 +129,7 @@
         if (!this.trySaveLootTable(nbt)) {
             ContainerHelper.saveAllItems(nbt, this.items, registryLookup);
         }
+
     }
 
     public static void lidAnimateTick(Level world, BlockPos pos, BlockState state, ChestBlockEntity blockEntity) {
@@ -96,18 +137,21 @@
     }
 
     public static void playSound(Level world, BlockPos pos, BlockState state, SoundEvent soundEvent) {
-        ChestType chestType = state.getValue(ChestBlock.TYPE);
-        if (chestType != ChestType.LEFT) {
-            double d = (double)pos.getX() + 0.5;
-            double e = (double)pos.getY() + 0.5;
-            double f = (double)pos.getZ() + 0.5;
-            if (chestType == ChestType.RIGHT) {
-                Direction direction = ChestBlock.getConnectedDirection(state);
-                d += (double)direction.getStepX() * 0.5;
-                f += (double)direction.getStepZ() * 0.5;
+        ChestType blockpropertychesttype = (ChestType) state.getValue(ChestBlock.TYPE);
+
+        if (blockpropertychesttype != ChestType.LEFT) {
+            double d0 = (double) pos.getX() + 0.5D;
+            double d1 = (double) pos.getY() + 0.5D;
+            double d2 = (double) pos.getZ() + 0.5D;
+
+            if (blockpropertychesttype == ChestType.RIGHT) {
+                Direction enumdirection = ChestBlock.getConnectedDirection(state);
+
+                d0 += (double) enumdirection.getStepX() * 0.5D;
+                d2 += (double) enumdirection.getStepZ() * 0.5D;
             }
 
-            world.playSound(null, d, e, f, soundEvent, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+            world.playSound((Player) null, d0, d1, d2, soundEvent, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
         }
     }
 
@@ -126,6 +170,7 @@
         if (!this.remove && !player.isSpectator()) {
             this.openersCounter.incrementOpeners(player, this.getLevel(), this.getBlockPos(), this.getBlockState());
         }
+
     }
 
     @Override
@@ -133,6 +178,7 @@
         if (!this.remove && !player.isSpectator()) {
             this.openersCounter.decrementOpeners(player, this.getLevel(), this.getBlockPos(), this.getBlockState());
         }
+
     }
 
     @Override
@@ -151,11 +197,13 @@
     }
 
     public static int getOpenCount(BlockGetter world, BlockPos pos) {
-        BlockState blockState = world.getBlockState(pos);
-        if (blockState.hasBlockEntity()) {
-            BlockEntity blockEntity = world.getBlockEntity(pos);
-            if (blockEntity instanceof ChestBlockEntity) {
-                return ((ChestBlockEntity)blockEntity).openersCounter.getOpenerCount();
+        BlockState iblockdata = world.getBlockState(pos);
+
+        if (iblockdata.hasBlockEntity()) {
+            BlockEntity tileentity = world.getBlockEntity(pos);
+
+            if (tileentity instanceof ChestBlockEntity) {
+                return ((ChestBlockEntity) tileentity).openersCounter.getOpenerCount();
             }
         }
 
@@ -163,9 +211,10 @@
     }
 
     public static void swapContents(ChestBlockEntity from, ChestBlockEntity to) {
-        NonNullList<ItemStack> nonNullList = from.getItems();
+        NonNullList<ItemStack> nonnulllist = from.getItems();
+
         from.setItems(to.getItems());
-        to.setItems(nonNullList);
+        to.setItems(nonnulllist);
     }
 
     @Override
@@ -177,10 +226,19 @@
         if (!this.remove) {
             this.openersCounter.recheckOpeners(this.getLevel(), this.getBlockPos(), this.getBlockState());
         }
+
     }
 
     protected void signalOpenCount(Level world, BlockPos pos, BlockState state, int oldViewerCount, int newViewerCount) {
         Block block = state.getBlock();
+
         world.blockEvent(pos, block, 1, newViewerCount);
     }
+
+    // CraftBukkit start
+    @Override
+    public boolean onlyOpCanSetNbt() {
+        return false; // Paper - Allow chests to be placed with NBT data
+    }
+    // CraftBukkit end
 }
