--- a/net/minecraft/world/level/block/entity/LecternBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/LecternBlockEntity.java
@@ -23,13 +23,71 @@
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.phys.Vec2;
 import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import org.bukkit.Location;
+import org.bukkit.block.Lectern;
+import org.bukkit.craftbukkit.v1_19_R1.entity.CraftHumanEntity;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.inventory.InventoryHolder;
+// CraftBukkit end
+
+public class LecternBlockEntity extends BlockEntity implements Clearable, MenuProvider, CommandSource { // CraftBukkit - ICommandListener
 
-public class LecternBlockEntity extends BlockEntity implements Clearable, MenuProvider {
     public static final int DATA_PAGE = 0;
     public static final int NUM_DATA = 1;
     public static final int SLOT_BOOK = 0;
     public static final int NUM_SLOTS = 1;
-    public final Container bookAccess = new Container() {
+    // CraftBukkit start - add fields and methods
+    public final Container bookAccess = new LecternInventory();
+    public class LecternInventory implements Container {
+
+        public List<HumanEntity> transaction = new ArrayList<>();
+        private int maxStack = 1;
+
+        @Override
+        public List<ItemStack> getContents() {
+            return Arrays.asList(book);
+        }
+
+        @Override
+        public void onOpen(CraftHumanEntity who) {
+            this.transaction.add(who);
+        }
+
+        @Override
+        public void onClose(CraftHumanEntity who) {
+            this.transaction.remove(who);
+        }
+
+        @Override
+        public List<HumanEntity> getViewers() {
+            return this.transaction;
+        }
+
+        @Override
+        public void setMaxStackSize(int i) {
+            this.maxStack = i;
+        }
+
+        @Override
+        public Location getLocation() {
+            return new Location(level.getWorld(), worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
+        }
+
+        @Override
+        public InventoryHolder getOwner() {
+            return (Lectern) LecternBlockEntity.this.getOwner();
+        }
+
+        public LecternBlockEntity getLectern() {
+            return LecternBlockEntity.this;
+        }
+        // CraftBukkit end
+
         @Override
         public int getContainerSize() {
             return 1;
@@ -48,12 +106,13 @@
         @Override
         public ItemStack removeItem(int slot, int amount) {
             if (slot == 0) {
-                ItemStack itemStack = LecternBlockEntity.this.book.split(amount);
+                ItemStack itemstack = LecternBlockEntity.this.book.split(amount);
+
                 if (LecternBlockEntity.this.book.isEmpty()) {
                     LecternBlockEntity.this.onBookItemRemove();
                 }
 
-                return itemStack;
+                return itemstack;
             } else {
                 return ItemStack.EMPTY;
             }
@@ -62,22 +121,31 @@
         @Override
         public ItemStack removeItemNoUpdate(int slot) {
             if (slot == 0) {
-                ItemStack itemStack = LecternBlockEntity.this.book;
+                ItemStack itemstack = LecternBlockEntity.this.book;
+
                 LecternBlockEntity.this.book = ItemStack.EMPTY;
                 LecternBlockEntity.this.onBookItemRemove();
-                return itemStack;
+                return itemstack;
             } else {
                 return ItemStack.EMPTY;
             }
         }
 
         @Override
+        // CraftBukkit start
         public void setItem(int slot, ItemStack stack) {
+            if (slot == 0) {
+                LecternBlockEntity.this.setBook(stack);
+                if (LecternBlockEntity.this.getLevel() != null) {
+                    LecternBlock.resetBookState(LecternBlockEntity.this.getLevel(), LecternBlockEntity.this.getBlockPos(), LecternBlockEntity.this.getBlockState(), LecternBlockEntity.this.hasBook());
+                }
+            }
         }
+        // CraftBukkit end
 
         @Override
         public int getMaxStackSize() {
-            return 1;
+            return this.maxStack; // CraftBukkit
         }
 
         @Override
@@ -87,11 +155,7 @@
 
         @Override
         public boolean stillValid(Player player) {
-            if (LecternBlockEntity.this.level.getBlockEntity(LecternBlockEntity.this.worldPosition) != LecternBlockEntity.this) {
-                return false;
-            } else {
-                return player.distanceToSqr((double)LecternBlockEntity.this.worldPosition.getX() + 0.5D, (double)LecternBlockEntity.this.worldPosition.getY() + 0.5D, (double)LecternBlockEntity.this.worldPosition.getZ() + 0.5D) > 64.0D ? false : LecternBlockEntity.this.hasBook();
-            }
+            return LecternBlockEntity.this.level.getBlockEntity(LecternBlockEntity.this.worldPosition) != LecternBlockEntity.this ? false : (player.distanceToSqr((double) LecternBlockEntity.this.worldPosition.getX() + 0.5D, (double) LecternBlockEntity.this.worldPosition.getY() + 0.5D, (double) LecternBlockEntity.this.worldPosition.getZ() + 0.5D) > 64.0D ? false : LecternBlockEntity.this.hasBook());
         }
 
         @Override
@@ -100,8 +164,7 @@
         }
 
         @Override
-        public void clearContent() {
-        }
+        public void clearContent() {}
     };
     private final ContainerData dataAccess = new ContainerData() {
         @Override
@@ -122,12 +185,13 @@
             return 1;
         }
     };
-    ItemStack book = ItemStack.EMPTY;
+    ItemStack book;
     int page;
     private int pageCount;
 
     public LecternBlockEntity(BlockPos pos, BlockState state) {
         super(BlockEntityType.LECTERN, pos, state);
+        this.book = ItemStack.EMPTY;
     }
 
     public ItemStack getBook() {
@@ -139,7 +203,7 @@
     }
 
     public void setBook(ItemStack book) {
-        this.setBook(book, (Player)null);
+        this.setBook(book, (Player) null);
     }
 
     void onBookItemRemove() {
@@ -156,11 +220,12 @@
     }
 
     public void setPage(int currentPage) {
-        int i = Mth.clamp(currentPage, 0, this.pageCount - 1);
-        if (i != this.page) {
-            this.page = i;
+        int j = Mth.clamp(currentPage, (int) 0, this.pageCount - 1);
+
+        if (j != this.page) {
+            this.page = j;
             this.setChanged();
-            LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState());
+            if (this.level != null) LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState()); // CraftBukkit
         }
 
     }
@@ -170,7 +235,8 @@
     }
 
     public int getRedstoneSignal() {
-        float f = this.pageCount > 1 ? (float)this.getPage() / ((float)this.pageCount - 1.0F) : 1.0F;
+        float f = this.pageCount > 1 ? (float) this.getPage() / ((float) this.pageCount - 1.0F) : 1.0F;
+
         return Mth.floor(f * 14.0F) + (this.hasBook() ? 1 : 0);
     }
 
@@ -182,19 +248,48 @@
         return book;
     }
 
+    // CraftBukkit start
+    @Override
+    public void sendSystemMessage(Component message) {
+    }
+
+    @Override
+    public org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper) {
+        return wrapper.getEntity() != null ? wrapper.getEntity().getBukkitSender(wrapper) : new org.bukkit.craftbukkit.v1_19_R1.command.CraftBlockCommandSender(wrapper, this);
+    }
+
+    @Override
+    public boolean acceptsSuccess() {
+        return false;
+    }
+
+    @Override
+    public boolean acceptsFailure() {
+        return false;
+    }
+
+    @Override
+    public boolean shouldInformAdmins() {
+        return false;
+    }
+
+    // CraftBukkit end
     private CommandSourceStack createCommandSourceStack(@Nullable Player player) {
-        String string;
-        Component component;
+        String s;
+        Object object;
+
         if (player == null) {
-            string = "Lectern";
-            component = Component.literal("Lectern");
+            s = "Lectern";
+            object = Component.literal("Lectern");
         } else {
-            string = player.getName().getString();
-            component = player.getDisplayName();
+            s = player.getName().getString();
+            object = player.getDisplayName();
         }
 
-        Vec3 vec3 = Vec3.atCenterOf(this.worldPosition);
-        return new CommandSourceStack(CommandSource.NULL, vec3, Vec2.ZERO, (ServerLevel)this.level, 2, string, component, this.level.getServer(), player);
+        Vec3 vec3d = Vec3.atCenterOf(this.worldPosition);
+
+        // CraftBukkit - this
+        return new CommandSourceStack(this, vec3d, Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player);
     }
 
     @Override
@@ -206,13 +301,13 @@
     public void load(CompoundTag nbt) {
         super.load(nbt);
         if (nbt.contains("Book", 10)) {
-            this.book = this.resolveBook(ItemStack.of(nbt.getCompound("Book")), (Player)null);
+            this.book = this.resolveBook(ItemStack.of(nbt.getCompound("Book")), (Player) null);
         } else {
             this.book = ItemStack.EMPTY;
         }
 
         this.pageCount = WrittenBookItem.getPageCount(this.book);
-        this.page = Mth.clamp(nbt.getInt("Page"), 0, this.pageCount - 1);
+        this.page = Mth.clamp(nbt.getInt("Page"), (int) 0, this.pageCount - 1);
     }
 
     @Override
@@ -232,7 +327,7 @@
 
     @Override
     public AbstractContainerMenu createMenu(int syncId, Inventory inv, Player player) {
-        return new LecternMenu(syncId, this.bookAccess, this.dataAccess);
+        return new LecternMenu(syncId, this.bookAccess, this.dataAccess, inv); // CraftBukkit
     }
 
     @Override
