--- a/net/minecraft/world/level/block/LecternBlock.java
+++ b/net/minecraft/world/level/block/LecternBlock.java
@@ -4,6 +4,7 @@
 import javax.annotation.Nullable;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
 import net.minecraft.core.component.DataComponents;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.sounds.SoundEvents;
@@ -40,51 +41,30 @@
 import net.minecraft.world.phys.shapes.VoxelShape;
 
 public class LecternBlock extends BaseEntityBlock {
+
     public static final MapCodec<LecternBlock> CODEC = simpleCodec(LecternBlock::new);
     public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
     public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
     public static final BooleanProperty HAS_BOOK = BlockStateProperties.HAS_BOOK;
-    public static final VoxelShape SHAPE_BASE = Block.box(0.0, 0.0, 0.0, 16.0, 2.0, 16.0);
-    public static final VoxelShape SHAPE_POST = Block.box(4.0, 2.0, 4.0, 12.0, 14.0, 12.0);
-    public static final VoxelShape SHAPE_COMMON = Shapes.or(SHAPE_BASE, SHAPE_POST);
-    public static final VoxelShape SHAPE_TOP_PLATE = Block.box(0.0, 15.0, 0.0, 16.0, 15.0, 16.0);
-    public static final VoxelShape SHAPE_COLLISION = Shapes.or(SHAPE_COMMON, SHAPE_TOP_PLATE);
-    public static final VoxelShape SHAPE_WEST = Shapes.or(
-        Block.box(1.0, 10.0, 0.0, 5.333333, 14.0, 16.0),
-        Block.box(5.333333, 12.0, 0.0, 9.666667, 16.0, 16.0),
-        Block.box(9.666667, 14.0, 0.0, 14.0, 18.0, 16.0),
-        SHAPE_COMMON
-    );
-    public static final VoxelShape SHAPE_NORTH = Shapes.or(
-        Block.box(0.0, 10.0, 1.0, 16.0, 14.0, 5.333333),
-        Block.box(0.0, 12.0, 5.333333, 16.0, 16.0, 9.666667),
-        Block.box(0.0, 14.0, 9.666667, 16.0, 18.0, 14.0),
-        SHAPE_COMMON
-    );
-    public static final VoxelShape SHAPE_EAST = Shapes.or(
-        Block.box(10.666667, 10.0, 0.0, 15.0, 14.0, 16.0),
-        Block.box(6.333333, 12.0, 0.0, 10.666667, 16.0, 16.0),
-        Block.box(2.0, 14.0, 0.0, 6.333333, 18.0, 16.0),
-        SHAPE_COMMON
-    );
-    public static final VoxelShape SHAPE_SOUTH = Shapes.or(
-        Block.box(0.0, 10.0, 10.666667, 16.0, 14.0, 15.0),
-        Block.box(0.0, 12.0, 6.333333, 16.0, 16.0, 10.666667),
-        Block.box(0.0, 14.0, 2.0, 16.0, 18.0, 6.333333),
-        SHAPE_COMMON
-    );
+    public static final VoxelShape SHAPE_BASE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D);
+    public static final VoxelShape SHAPE_POST = Block.box(4.0D, 2.0D, 4.0D, 12.0D, 14.0D, 12.0D);
+    public static final VoxelShape SHAPE_COMMON = Shapes.or(LecternBlock.SHAPE_BASE, LecternBlock.SHAPE_POST);
+    public static final VoxelShape SHAPE_TOP_PLATE = Block.box(0.0D, 15.0D, 0.0D, 16.0D, 15.0D, 16.0D);
+    public static final VoxelShape SHAPE_COLLISION = Shapes.or(LecternBlock.SHAPE_COMMON, LecternBlock.SHAPE_TOP_PLATE);
+    public static final VoxelShape SHAPE_WEST = Shapes.or(Block.box(1.0D, 10.0D, 0.0D, 5.333333D, 14.0D, 16.0D), Block.box(5.333333D, 12.0D, 0.0D, 9.666667D, 16.0D, 16.0D), Block.box(9.666667D, 14.0D, 0.0D, 14.0D, 18.0D, 16.0D), LecternBlock.SHAPE_COMMON);
+    public static final VoxelShape SHAPE_NORTH = Shapes.or(Block.box(0.0D, 10.0D, 1.0D, 16.0D, 14.0D, 5.333333D), Block.box(0.0D, 12.0D, 5.333333D, 16.0D, 16.0D, 9.666667D), Block.box(0.0D, 14.0D, 9.666667D, 16.0D, 18.0D, 14.0D), LecternBlock.SHAPE_COMMON);
+    public static final VoxelShape SHAPE_EAST = Shapes.or(Block.box(10.666667D, 10.0D, 0.0D, 15.0D, 14.0D, 16.0D), Block.box(6.333333D, 12.0D, 0.0D, 10.666667D, 16.0D, 16.0D), Block.box(2.0D, 14.0D, 0.0D, 6.333333D, 18.0D, 16.0D), LecternBlock.SHAPE_COMMON);
+    public static final VoxelShape SHAPE_SOUTH = Shapes.or(Block.box(0.0D, 10.0D, 10.666667D, 16.0D, 14.0D, 15.0D), Block.box(0.0D, 12.0D, 6.333333D, 16.0D, 16.0D, 10.666667D), Block.box(0.0D, 14.0D, 2.0D, 16.0D, 18.0D, 6.333333D), LecternBlock.SHAPE_COMMON);
     private static final int PAGE_CHANGE_IMPULSE_TICKS = 2;
 
     @Override
     public MapCodec<LecternBlock> codec() {
-        return CODEC;
+        return LecternBlock.CODEC;
     }
 
     protected LecternBlock(BlockBehaviour.Properties settings) {
         super(settings);
-        this.registerDefaultState(
-            this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWERED, Boolean.valueOf(false)).setValue(HAS_BOOK, Boolean.valueOf(false))
-        );
+        this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(LecternBlock.FACING, Direction.NORTH)).setValue(LecternBlock.POWERED, false)).setValue(LecternBlock.HAS_BOOK, false));
     }
 
     @Override
@@ -94,7 +74,7 @@
 
     @Override
     protected VoxelShape getOcclusionShape(BlockState state, BlockGetter world, BlockPos pos) {
-        return SHAPE_COMMON;
+        return LecternBlock.SHAPE_COMMON;
     }
 
     @Override
@@ -104,54 +84,56 @@
 
     @Override
     public BlockState getStateForPlacement(BlockPlaceContext ctx) {
-        Level level = ctx.getLevel();
-        ItemStack itemStack = ctx.getItemInHand();
-        Player player = ctx.getPlayer();
-        boolean bl = false;
-        if (!level.isClientSide && player != null && player.canUseGameMasterBlocks()) {
-            CustomData customData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
-            if (customData.contains("Book")) {
-                bl = true;
+        Level world = ctx.getLevel();
+        ItemStack itemstack = ctx.getItemInHand();
+        Player entityhuman = ctx.getPlayer();
+        boolean flag = false;
+
+        if (!world.isClientSide && entityhuman != null && entityhuman.canUseGameMasterBlocks()) {
+            CustomData customdata = (CustomData) itemstack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
+
+            if (customdata.contains("Book")) {
+                flag = true;
             }
         }
 
-        return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()).setValue(HAS_BOOK, Boolean.valueOf(bl));
+        return (BlockState) ((BlockState) this.defaultBlockState().setValue(LecternBlock.FACING, ctx.getHorizontalDirection().getOpposite())).setValue(LecternBlock.HAS_BOOK, flag);
     }
 
     @Override
     protected VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        return SHAPE_COLLISION;
+        return LecternBlock.SHAPE_COLLISION;
     }
 
     @Override
     protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        switch ((Direction)state.getValue(FACING)) {
+        switch ((Direction) state.getValue(LecternBlock.FACING)) {
             case NORTH:
-                return SHAPE_NORTH;
+                return LecternBlock.SHAPE_NORTH;
             case SOUTH:
-                return SHAPE_SOUTH;
+                return LecternBlock.SHAPE_SOUTH;
             case EAST:
-                return SHAPE_EAST;
+                return LecternBlock.SHAPE_EAST;
             case WEST:
-                return SHAPE_WEST;
+                return LecternBlock.SHAPE_WEST;
             default:
-                return SHAPE_COMMON;
+                return LecternBlock.SHAPE_COMMON;
         }
     }
 
     @Override
     protected BlockState rotate(BlockState state, Rotation rotation) {
-        return state.setValue(FACING, rotation.rotate(state.getValue(FACING)));
+        return (BlockState) state.setValue(LecternBlock.FACING, rotation.rotate((Direction) state.getValue(LecternBlock.FACING)));
     }
 
     @Override
     protected BlockState mirror(BlockState state, Mirror mirror) {
-        return state.rotate(mirror.getRotation(state.getValue(FACING)));
+        return state.rotate(mirror.getRotation((Direction) state.getValue(LecternBlock.FACING)));
     }
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(FACING, POWERED, HAS_BOOK);
+        builder.add(LecternBlock.FACING, LecternBlock.POWERED, LecternBlock.HAS_BOOK);
     }
 
     @Override
@@ -160,9 +142,9 @@
     }
 
     public static boolean tryPlaceBook(@Nullable LivingEntity user, Level world, BlockPos pos, BlockState state, ItemStack stack) {
-        if (!state.getValue(HAS_BOOK)) {
+        if (!(Boolean) state.getValue(LecternBlock.HAS_BOOK)) {
             if (!world.isClientSide) {
-                placeBook(user, world, pos, state, stack);
+                LecternBlock.placeBook(user, world, pos, state, stack);
             }
 
             return true;
@@ -172,29 +154,43 @@
     }
 
     private static void placeBook(@Nullable LivingEntity user, Level world, BlockPos pos, BlockState state, ItemStack stack) {
-        if (world.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) {
-            lecternBlockEntity.setBook(stack.consumeAndReturn(1, user));
-            resetBookState(user, world, pos, state, true);
-            world.playSound(null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F);
+        BlockEntity tileentity = world.getBlockEntity(pos);
+
+        if (tileentity instanceof LecternBlockEntity tileentitylectern) {
+            tileentitylectern.setBook(stack.consumeAndReturn(1, user));
+            LecternBlock.resetBookState(user, world, pos, state, true);
+            world.playSound((Player) null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F);
         }
+
     }
 
     public static void resetBookState(@Nullable Entity user, Level world, BlockPos pos, BlockState state, boolean hasBook) {
-        BlockState blockState = state.setValue(POWERED, Boolean.valueOf(false)).setValue(HAS_BOOK, Boolean.valueOf(hasBook));
-        world.setBlock(pos, blockState, 3);
-        world.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(user, blockState));
-        updateBelow(world, pos, state);
+        BlockState iblockdata1 = (BlockState) ((BlockState) state.setValue(LecternBlock.POWERED, false)).setValue(LecternBlock.HAS_BOOK, hasBook);
+
+        world.setBlock(pos, iblockdata1, 3);
+        world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(user, iblockdata1));
+        LecternBlock.updateBelow(world, pos, state);
     }
 
     public static void signalPageChange(Level world, BlockPos pos, BlockState state) {
-        changePowered(world, pos, state, true);
+        LecternBlock.changePowered(world, pos, state, true);
         world.scheduleTick(pos, state.getBlock(), 2);
         world.levelEvent(1043, pos, 0);
     }
 
     private static void changePowered(Level world, BlockPos pos, BlockState state, boolean powered) {
-        world.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(powered)), 3);
-        updateBelow(world, pos, state);
+        // Paper start - call BlockRedstoneEvents for lecterns
+        final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0;
+        if (currentRedstoneLevel != targetRedstoneLevel) {
+            final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, pos, currentRedstoneLevel, targetRedstoneLevel);
+
+            if (event.getNewCurrent() != targetRedstoneLevel) {
+                return;
+            }
+        }
+        // Paper end - call BlockRedstoneEvents for lecterns
+        world.setBlock(pos, (BlockState) state.setValue(LecternBlock.POWERED, powered), 3);
+        LecternBlock.updateBelow(world, pos, state);
     }
 
     private static void updateBelow(Level world, BlockPos pos, BlockState state) {
@@ -203,17 +199,17 @@
 
     @Override
     protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
-        changePowered(world, pos, state, false);
+        LecternBlock.changePowered(world, pos, state, false);
     }
 
     @Override
     protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
         if (!state.is(newState.getBlock())) {
-            if (state.getValue(HAS_BOOK)) {
+            if ((Boolean) state.getValue(LecternBlock.HAS_BOOK)) {
                 this.popBook(state, world, pos);
             }
 
-            if (state.getValue(POWERED)) {
+            if ((Boolean) state.getValue(LecternBlock.POWERED)) {
                 world.updateNeighborsAt(pos.below(), this);
             }
 
@@ -222,18 +218,21 @@
     }
 
     private void popBook(BlockState state, Level world, BlockPos pos) {
-        if (world.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) {
-            Direction direction = state.getValue(FACING);
-            ItemStack itemStack = lecternBlockEntity.getBook().copy();
-            float f = 0.25F * (float)direction.getStepX();
-            float g = 0.25F * (float)direction.getStepZ();
-            ItemEntity itemEntity = new ItemEntity(
-                world, (double)pos.getX() + 0.5 + (double)f, (double)(pos.getY() + 1), (double)pos.getZ() + 0.5 + (double)g, itemStack
-            );
-            itemEntity.setDefaultPickUpDelay();
-            world.addFreshEntity(itemEntity);
-            lecternBlockEntity.clearContent();
+        BlockEntity tileentity = world.getBlockEntity(pos, false); // CraftBukkit - don't validate, type may be changed already
+
+        if (tileentity instanceof LecternBlockEntity tileentitylectern) {
+            Direction enumdirection = (Direction) state.getValue(LecternBlock.FACING);
+            ItemStack itemstack = tileentitylectern.getBook().copy();
+            if (itemstack.isEmpty()) return; // CraftBukkit - SPIGOT-5500
+            float f = 0.25F * (float) enumdirection.getStepX();
+            float f1 = 0.25F * (float) enumdirection.getStepZ();
+            ItemEntity entityitem = new ItemEntity(world, (double) pos.getX() + 0.5D + (double) f, (double) (pos.getY() + 1), (double) pos.getZ() + 0.5D + (double) f1, itemstack);
+
+            entityitem.setDefaultPickUpDelay();
+            world.addFreshEntity(entityitem);
+            tileentitylectern.clearContent();
         }
+
     }
 
     @Override
@@ -243,12 +242,12 @@
 
     @Override
     protected int getSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        return state.getValue(POWERED) ? 15 : 0;
+        return (Boolean) state.getValue(LecternBlock.POWERED) ? 15 : 0;
     }
 
     @Override
     protected int getDirectSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        return direction == Direction.UP && state.getValue(POWERED) ? 15 : 0;
+        return direction == Direction.UP && (Boolean) state.getValue(LecternBlock.POWERED) ? 15 : 0;
     }
 
     @Override
@@ -258,10 +257,11 @@
 
     @Override
     protected int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
-        if (state.getValue(HAS_BOOK)) {
-            BlockEntity blockEntity = world.getBlockEntity(pos);
-            if (blockEntity instanceof LecternBlockEntity) {
-                return ((LecternBlockEntity)blockEntity).getRedstoneSignal();
+        if ((Boolean) state.getValue(LecternBlock.HAS_BOOK)) {
+            BlockEntity tileentity = world.getBlockEntity(pos);
+
+            if (tileentity instanceof LecternBlockEntity) {
+                return ((LecternBlockEntity) tileentity).getRedstoneSignal();
             }
         }
 
@@ -269,25 +269,13 @@
     }
 
     @Override
-    protected ItemInteractionResult useItemOn(
-        ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit
-    ) {
-        if (state.getValue(HAS_BOOK)) {
-            return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
-        } else if (stack.is(ItemTags.LECTERN_BOOKS)) {
-            return tryPlaceBook(player, world, pos, state, stack)
-                ? ItemInteractionResult.sidedSuccess(world.isClientSide)
-                : ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
-        } else {
-            return stack.isEmpty() && hand == InteractionHand.MAIN_HAND
-                ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION
-                : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
-        }
+    protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
+        return (Boolean) state.getValue(LecternBlock.HAS_BOOK) ? ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION : (stack.is(ItemTags.LECTERN_BOOKS) ? (LecternBlock.tryPlaceBook(player, world, pos, state, stack) ? ItemInteractionResult.sidedSuccess(world.isClientSide) : ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION) : (stack.isEmpty() && hand == InteractionHand.MAIN_HAND ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION));
     }
 
     @Override
     protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
-        if (state.getValue(HAS_BOOK)) {
+        if ((Boolean) state.getValue(LecternBlock.HAS_BOOK)) {
             if (!world.isClientSide) {
                 this.openScreen(world, pos, player);
             }
@@ -301,15 +289,17 @@
     @Nullable
     @Override
     public MenuProvider getMenuProvider(BlockState state, Level world, BlockPos pos) {
-        return !state.getValue(HAS_BOOK) ? null : super.getMenuProvider(state, world, pos);
+        return !(Boolean) state.getValue(LecternBlock.HAS_BOOK) ? null : super.getMenuProvider(state, world, pos);
     }
 
     private void openScreen(Level world, BlockPos pos, Player player) {
-        BlockEntity blockEntity = world.getBlockEntity(pos);
-        if (blockEntity instanceof LecternBlockEntity) {
-            player.openMenu((LecternBlockEntity)blockEntity);
+        BlockEntity tileentity = world.getBlockEntity(pos);
+
+        if (tileentity instanceof LecternBlockEntity) {
+            player.openMenu((LecternBlockEntity) tileentity);
             player.awardStat(Stats.INTERACT_WITH_LECTERN);
         }
+
     }
 
     @Override
