--- a/net/minecraft/world/level/block/LeverBlock.java
+++ b/net/minecraft/world/level/block/LeverBlock.java
@@ -5,11 +5,13 @@
 import javax.annotation.Nullable;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
 import net.minecraft.core.particles.DustParticleOptions;
 import net.minecraft.sounds.SoundEvents;
 import net.minecraft.sounds.SoundSource;
 import net.minecraft.util.RandomSource;
 import net.minecraft.world.InteractionResult;
+import net.minecraft.world.entity.Entity;
 import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.level.BlockGetter;
@@ -26,65 +28,65 @@
 import net.minecraft.world.phys.BlockHitResult;
 import net.minecraft.world.phys.shapes.CollisionContext;
 import net.minecraft.world.phys.shapes.VoxelShape;
+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
 
 public class LeverBlock extends FaceAttachedHorizontalDirectionalBlock {
+
     public static final MapCodec<LeverBlock> CODEC = simpleCodec(LeverBlock::new);
     public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
     protected static final int DEPTH = 6;
     protected static final int WIDTH = 6;
     protected static final int HEIGHT = 8;
-    protected static final VoxelShape NORTH_AABB = Block.box(5.0, 4.0, 10.0, 11.0, 12.0, 16.0);
-    protected static final VoxelShape SOUTH_AABB = Block.box(5.0, 4.0, 0.0, 11.0, 12.0, 6.0);
-    protected static final VoxelShape WEST_AABB = Block.box(10.0, 4.0, 5.0, 16.0, 12.0, 11.0);
-    protected static final VoxelShape EAST_AABB = Block.box(0.0, 4.0, 5.0, 6.0, 12.0, 11.0);
-    protected static final VoxelShape UP_AABB_Z = Block.box(5.0, 0.0, 4.0, 11.0, 6.0, 12.0);
-    protected static final VoxelShape UP_AABB_X = Block.box(4.0, 0.0, 5.0, 12.0, 6.0, 11.0);
-    protected static final VoxelShape DOWN_AABB_Z = Block.box(5.0, 10.0, 4.0, 11.0, 16.0, 12.0);
-    protected static final VoxelShape DOWN_AABB_X = Block.box(4.0, 10.0, 5.0, 12.0, 16.0, 11.0);
+    protected static final VoxelShape NORTH_AABB = Block.box(5.0D, 4.0D, 10.0D, 11.0D, 12.0D, 16.0D);
+    protected static final VoxelShape SOUTH_AABB = Block.box(5.0D, 4.0D, 0.0D, 11.0D, 12.0D, 6.0D);
+    protected static final VoxelShape WEST_AABB = Block.box(10.0D, 4.0D, 5.0D, 16.0D, 12.0D, 11.0D);
+    protected static final VoxelShape EAST_AABB = Block.box(0.0D, 4.0D, 5.0D, 6.0D, 12.0D, 11.0D);
+    protected static final VoxelShape UP_AABB_Z = Block.box(5.0D, 0.0D, 4.0D, 11.0D, 6.0D, 12.0D);
+    protected static final VoxelShape UP_AABB_X = Block.box(4.0D, 0.0D, 5.0D, 12.0D, 6.0D, 11.0D);
+    protected static final VoxelShape DOWN_AABB_Z = Block.box(5.0D, 10.0D, 4.0D, 11.0D, 16.0D, 12.0D);
+    protected static final VoxelShape DOWN_AABB_X = Block.box(4.0D, 10.0D, 5.0D, 12.0D, 16.0D, 11.0D);
 
     @Override
     public MapCodec<LeverBlock> codec() {
-        return CODEC;
+        return LeverBlock.CODEC;
     }
 
     protected LeverBlock(BlockBehaviour.Properties settings) {
         super(settings);
-        this.registerDefaultState(
-            this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWERED, Boolean.valueOf(false)).setValue(FACE, AttachFace.WALL)
-        );
+        this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(LeverBlock.FACING, Direction.NORTH)).setValue(LeverBlock.POWERED, false)).setValue(LeverBlock.FACE, AttachFace.WALL));
     }
 
     @Override
     protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        switch ((AttachFace)state.getValue(FACE)) {
+        switch ((AttachFace) state.getValue(LeverBlock.FACE)) {
             case FLOOR:
-                switch (state.getValue(FACING).getAxis()) {
+                switch (((Direction) state.getValue(LeverBlock.FACING)).getAxis()) {
                     case X:
-                        return UP_AABB_X;
+                        return LeverBlock.UP_AABB_X;
                     case Z:
                     default:
-                        return UP_AABB_Z;
+                        return LeverBlock.UP_AABB_Z;
                 }
             case WALL:
-                switch ((Direction)state.getValue(FACING)) {
+                switch ((Direction) state.getValue(LeverBlock.FACING)) {
                     case EAST:
-                        return EAST_AABB;
+                        return LeverBlock.EAST_AABB;
                     case WEST:
-                        return WEST_AABB;
+                        return LeverBlock.WEST_AABB;
                     case SOUTH:
-                        return SOUTH_AABB;
+                        return LeverBlock.SOUTH_AABB;
                     case NORTH:
                     default:
-                        return NORTH_AABB;
+                        return LeverBlock.NORTH_AABB;
                 }
             case CEILING:
             default:
-                switch (state.getValue(FACING).getAxis()) {
+                switch (((Direction) state.getValue(LeverBlock.FACING)).getAxis()) {
                     case X:
-                        return DOWN_AABB_X;
+                        return LeverBlock.DOWN_AABB_X;
                     case Z:
                     default:
-                        return DOWN_AABB_Z;
+                        return LeverBlock.DOWN_AABB_Z;
                 }
         }
     }
@@ -92,14 +94,29 @@
     @Override
     protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
         if (world.isClientSide) {
-            BlockState blockState = state.cycle(POWERED);
-            if (blockState.getValue(POWERED)) {
-                makeParticle(blockState, world, pos, 1.0F);
+            BlockState iblockdata1 = (BlockState) state.cycle(LeverBlock.POWERED);
+
+            if ((Boolean) iblockdata1.getValue(LeverBlock.POWERED)) {
+                LeverBlock.makeParticle(iblockdata1, world, pos, 1.0F);
             }
 
             return InteractionResult.SUCCESS;
         } else {
-            this.pull(state, world, pos, null);
+            // CraftBukkit start - Interact Lever
+            boolean powered = state.getValue(LeverBlock.POWERED); // Old powered state
+            org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+            int old = (powered) ? 15 : 0;
+            int current = (!powered) ? 15 : 0;
+
+            BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current);
+            world.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+            if ((eventRedstone.getNewCurrent() > 0) != (!powered)) {
+                return InteractionResult.SUCCESS;
+            }
+            // CraftBukkit end
+
+            this.pull(state, world, pos, (Player) null);
             return InteractionResult.CONSUME;
         }
     }
@@ -107,45 +124,48 @@
     @Override
     protected void onExplosionHit(BlockState state, Level world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stackMerger) {
         if (explosion.canTriggerBlocks()) {
-            this.pull(state, world, pos, null);
+            this.pull(state, world, pos, (Player) null);
         }
 
         super.onExplosionHit(state, world, pos, explosion, stackMerger);
     }
 
     public void pull(BlockState state, Level world, BlockPos pos, @Nullable Player player) {
-        state = state.cycle(POWERED);
+        state = (BlockState) state.cycle(LeverBlock.POWERED);
         world.setBlock(pos, state, 3);
         this.updateNeighbours(state, world, pos);
-        playSound(player, world, pos, state);
-        world.gameEvent(player, state.getValue(POWERED) ? GameEvent.BLOCK_ACTIVATE : GameEvent.BLOCK_DEACTIVATE, pos);
+        LeverBlock.playSound(player, world, pos, state);
+        world.gameEvent((Entity) player, (Holder) ((Boolean) state.getValue(LeverBlock.POWERED) ? GameEvent.BLOCK_ACTIVATE : GameEvent.BLOCK_DEACTIVATE), pos);
     }
 
     protected static void playSound(@Nullable Player player, LevelAccessor world, BlockPos pos, BlockState state) {
-        float f = state.getValue(POWERED) ? 0.6F : 0.5F;
+        float f = (Boolean) state.getValue(LeverBlock.POWERED) ? 0.6F : 0.5F;
+
         world.playSound(player, pos, SoundEvents.LEVER_CLICK, SoundSource.BLOCKS, 0.3F, f);
     }
 
     private static void makeParticle(BlockState state, LevelAccessor world, BlockPos pos, float alpha) {
-        Direction direction = state.getValue(FACING).getOpposite();
-        Direction direction2 = getConnectedDirection(state).getOpposite();
-        double d = (double)pos.getX() + 0.5 + 0.1 * (double)direction.getStepX() + 0.2 * (double)direction2.getStepX();
-        double e = (double)pos.getY() + 0.5 + 0.1 * (double)direction.getStepY() + 0.2 * (double)direction2.getStepY();
-        double f = (double)pos.getZ() + 0.5 + 0.1 * (double)direction.getStepZ() + 0.2 * (double)direction2.getStepZ();
-        world.addParticle(new DustParticleOptions(DustParticleOptions.REDSTONE_PARTICLE_COLOR, alpha), d, e, f, 0.0, 0.0, 0.0);
+        Direction enumdirection = ((Direction) state.getValue(LeverBlock.FACING)).getOpposite();
+        Direction enumdirection1 = getConnectedDirection(state).getOpposite();
+        double d0 = (double) pos.getX() + 0.5D + 0.1D * (double) enumdirection.getStepX() + 0.2D * (double) enumdirection1.getStepX();
+        double d1 = (double) pos.getY() + 0.5D + 0.1D * (double) enumdirection.getStepY() + 0.2D * (double) enumdirection1.getStepY();
+        double d2 = (double) pos.getZ() + 0.5D + 0.1D * (double) enumdirection.getStepZ() + 0.2D * (double) enumdirection1.getStepZ();
+
+        world.addParticle(new DustParticleOptions(DustParticleOptions.REDSTONE_PARTICLE_COLOR, alpha), d0, d1, d2, 0.0D, 0.0D, 0.0D);
     }
 
     @Override
     public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {
-        if (state.getValue(POWERED) && random.nextFloat() < 0.25F) {
-            makeParticle(state, world, pos, 0.5F);
+        if ((Boolean) state.getValue(LeverBlock.POWERED) && random.nextFloat() < 0.25F) {
+            LeverBlock.makeParticle(state, world, pos, 0.5F);
         }
+
     }
 
     @Override
     protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
         if (!moved && !state.is(newState.getBlock())) {
-            if (state.getValue(POWERED)) {
+            if ((Boolean) state.getValue(LeverBlock.POWERED)) {
                 this.updateNeighbours(state, world, pos);
             }
 
@@ -155,12 +175,12 @@
 
     @Override
     protected int getSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        return state.getValue(POWERED) ? 15 : 0;
+        return (Boolean) state.getValue(LeverBlock.POWERED) ? 15 : 0;
     }
 
     @Override
     protected int getDirectSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        return state.getValue(POWERED) && getConnectedDirection(state) == direction ? 15 : 0;
+        return (Boolean) state.getValue(LeverBlock.POWERED) && getConnectedDirection(state) == direction ? 15 : 0;
     }
 
     @Override
@@ -175,6 +195,6 @@
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(FACE, FACING, POWERED);
+        builder.add(LeverBlock.FACE, LeverBlock.FACING, LeverBlock.POWERED);
     }
 }
