--- a/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -1,5 +1,6 @@
 package net.minecraft.world.level.block;
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.function.Predicate;
 import net.minecraft.core.BlockPos;
@@ -23,15 +24,17 @@
 import net.minecraft.world.level.block.state.properties.Property;
 import net.minecraft.world.level.block.state.properties.RailShape;
 import net.minecraft.world.phys.AABB;
+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
 
 public class DetectorRailBlock extends BaseRailBlock {
+
     public static final EnumProperty<RailShape> SHAPE = BlockStateProperties.RAIL_SHAPE_STRAIGHT;
     public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
     private static final int PRESSED_CHECK_PERIOD = 20;
 
     public DetectorRailBlock(BlockBehaviour.Properties settings) {
         super(true, settings);
-        this.registerDefaultState(this.stateDefinition.any().setValue(POWERED, Boolean.valueOf(false)).setValue(SHAPE, RailShape.NORTH_SOUTH).setValue(WATERLOGGED, Boolean.valueOf(false)));
+        this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(DetectorRailBlock.POWERED, false)).setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_SOUTH)).setValue(DetectorRailBlock.WATERLOGGED, false));
     }
 
     @Override
@@ -41,8 +44,9 @@
 
     @Override
     public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
         if (!world.isClientSide) {
-            if (!state.getValue(POWERED)) {
+            if (!(Boolean) state.getValue(DetectorRailBlock.POWERED)) {
                 this.checkPressed(world, pos, state);
             }
         }
@@ -50,56 +54,66 @@
 
     @Override
     public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
-        if (state.getValue(POWERED)) {
+        if ((Boolean) state.getValue(DetectorRailBlock.POWERED)) {
             this.checkPressed(world, pos, state);
         }
     }
 
     @Override
     public int getSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        return state.getValue(POWERED) ? 15 : 0;
+        return (Boolean) state.getValue(DetectorRailBlock.POWERED) ? 15 : 0;
     }
 
     @Override
     public int getDirectSignal(BlockState state, BlockGetter world, BlockPos pos, Direction direction) {
-        if (!state.getValue(POWERED)) {
-            return 0;
-        } else {
-            return direction == Direction.UP ? 15 : 0;
-        }
+        return !(Boolean) state.getValue(DetectorRailBlock.POWERED) ? 0 : (direction == Direction.UP ? 15 : 0);
     }
 
     private void checkPressed(Level world, BlockPos pos, BlockState state) {
         if (this.canSurvive(state, world, pos)) {
-            boolean bl = state.getValue(POWERED);
-            boolean bl2 = false;
+            if (state.getBlock() != this) { return; } // Paper - not our block, don't do anything
+            boolean flag = (Boolean) state.getValue(DetectorRailBlock.POWERED);
+            boolean flag1 = false;
             List<AbstractMinecart> list = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, (entity) -> {
                 return true;
             });
+
             if (!list.isEmpty()) {
-                bl2 = true;
+                flag1 = true;
             }
 
-            if (bl2 && !bl) {
-                BlockState blockState = state.setValue(POWERED, Boolean.valueOf(true));
-                world.setBlock(pos, blockState, 3);
-                this.updatePowerToConnected(world, pos, blockState, true);
+            BlockState iblockdata1;
+            // CraftBukkit start
+            if (flag != flag1) {
+                org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+
+                BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0);
+                world.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+                flag1 = eventRedstone.getNewCurrent() > 0;
+            }
+            // CraftBukkit end
+
+            if (flag1 && !flag) {
+                iblockdata1 = (BlockState) state.setValue(DetectorRailBlock.POWERED, true);
+                world.setBlock(pos, iblockdata1, 3);
+                this.updatePowerToConnected(world, pos, iblockdata1, true);
                 world.updateNeighborsAt(pos, this);
                 world.updateNeighborsAt(pos.below(), this);
-                world.setBlocksDirty(pos, state, blockState);
+                world.setBlocksDirty(pos, state, iblockdata1);
             }
 
-            if (!bl2 && bl) {
-                BlockState blockState2 = state.setValue(POWERED, Boolean.valueOf(false));
-                world.setBlock(pos, blockState2, 3);
-                this.updatePowerToConnected(world, pos, blockState2, false);
+            if (!flag1 && flag) {
+                iblockdata1 = (BlockState) state.setValue(DetectorRailBlock.POWERED, false);
+                world.setBlock(pos, iblockdata1, 3);
+                this.updatePowerToConnected(world, pos, iblockdata1, false);
                 world.updateNeighborsAt(pos, this);
                 world.updateNeighborsAt(pos.below(), this);
-                world.setBlocksDirty(pos, state, blockState2);
+                world.setBlocksDirty(pos, state, iblockdata1);
             }
 
-            if (bl2) {
-                world.scheduleTick(pos, this, 20);
+            if (flag1) {
+                world.scheduleTick(pos, (Block) this, 20);
             }
 
             world.updateNeighbourForOutputSignal(pos, this);
@@ -107,11 +121,15 @@
     }
 
     protected void updatePowerToConnected(Level world, BlockPos pos, BlockState state, boolean unpowering) {
-        RailState railState = new RailState(world, pos, state);
+        RailState minecarttracklogic = new RailState(world, pos, state);
+        List<BlockPos> list = minecarttracklogic.getConnections();
+        Iterator iterator = list.iterator();
 
-        for(BlockPos blockPos : railState.getConnections()) {
-            BlockState blockState = world.getBlockState(blockPos);
-            world.neighborChanged(blockState, blockPos, blockState.getBlock(), pos, false);
+        while (iterator.hasNext()) {
+            BlockPos blockposition1 = (BlockPos) iterator.next();
+            BlockState iblockdata1 = world.getBlockState(blockposition1);
+
+            world.neighborChanged(iblockdata1, blockposition1, iblockdata1.getBlock(), pos, false);
         }
 
     }
@@ -119,14 +137,15 @@
     @Override
     public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
         if (!oldState.is(state.getBlock())) {
-            BlockState blockState = this.updateState(state, world, pos, notify);
-            this.checkPressed(world, pos, blockState);
+            BlockState iblockdata2 = this.updateState(state, world, pos, notify);
+
+            this.checkPressed(world, pos, iblockdata2);
         }
     }
 
     @Override
     public Property<RailShape> getShapeProperty() {
-        return SHAPE;
+        return DetectorRailBlock.SHAPE;
     }
 
     @Override
@@ -136,17 +155,19 @@
 
     @Override
     public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
-        if (state.getValue(POWERED)) {
-            List<MinecartCommandBlock> list = this.getInteractingMinecartOfType(world, pos, MinecartCommandBlock.class, (cart) -> {
+        if ((Boolean) state.getValue(DetectorRailBlock.POWERED)) {
+            List<MinecartCommandBlock> list = this.getInteractingMinecartOfType(world, pos, MinecartCommandBlock.class, (entity) -> {
                 return true;
             });
+
             if (!list.isEmpty()) {
-                return list.get(0).getCommandBlock().getSuccessCount();
+                return ((MinecartCommandBlock) list.get(0)).getCommandBlock().getSuccessCount();
             }
 
-            List<AbstractMinecart> list2 = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, EntitySelector.CONTAINER_ENTITY_SELECTOR);
-            if (!list2.isEmpty()) {
-                return AbstractContainerMenu.getRedstoneSignalFromContainer((Container)list2.get(0));
+            List<AbstractMinecart> list1 = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, EntitySelector.CONTAINER_ENTITY_SELECTOR);
+
+            if (!list1.isEmpty()) {
+                return AbstractContainerMenu.getRedstoneSignalFromContainer((Container) list1.get(0));
             }
         }
 
@@ -158,77 +179,78 @@
     }
 
     private AABB getSearchBB(BlockPos pos) {
-        double d = 0.2D;
-        return new AABB((double)pos.getX() + 0.2D, (double)pos.getY(), (double)pos.getZ() + 0.2D, (double)(pos.getX() + 1) - 0.2D, (double)(pos.getY() + 1) - 0.2D, (double)(pos.getZ() + 1) - 0.2D);
+        double d0 = 0.2D;
+
+        return new AABB((double) pos.getX() + 0.2D, (double) pos.getY(), (double) pos.getZ() + 0.2D, (double) (pos.getX() + 1) - 0.2D, (double) (pos.getY() + 1) - 0.2D, (double) (pos.getZ() + 1) - 0.2D);
     }
 
     @Override
     public BlockState rotate(BlockState state, Rotation rotation) {
         switch (rotation) {
             case CLOCKWISE_180:
-                switch ((RailShape)state.getValue(SHAPE)) {
+                switch ((RailShape) state.getValue(DetectorRailBlock.SHAPE)) {
                     case ASCENDING_EAST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_WEST);
                     case ASCENDING_WEST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_EAST);
                     case ASCENDING_NORTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_SOUTH);
                     case ASCENDING_SOUTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_NORTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_NORTH);
                     case SOUTH_EAST:
-                        return state.setValue(SHAPE, RailShape.NORTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_WEST);
                     case SOUTH_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_EAST);
                     case NORTH_WEST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_EAST);
                     case NORTH_EAST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_WEST);
                 }
             case COUNTERCLOCKWISE_90:
-                switch ((RailShape)state.getValue(SHAPE)) {
+                switch ((RailShape) state.getValue(DetectorRailBlock.SHAPE)) {
                     case ASCENDING_EAST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_NORTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_NORTH);
                     case ASCENDING_WEST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_SOUTH);
                     case ASCENDING_NORTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_WEST);
                     case ASCENDING_SOUTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_EAST);
                     case SOUTH_EAST:
-                        return state.setValue(SHAPE, RailShape.NORTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_EAST);
                     case SOUTH_WEST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_EAST);
                     case NORTH_WEST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_WEST);
                     case NORTH_EAST:
-                        return state.setValue(SHAPE, RailShape.NORTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_WEST);
                     case NORTH_SOUTH:
-                        return state.setValue(SHAPE, RailShape.EAST_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.EAST_WEST);
                     case EAST_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_SOUTH);
                 }
             case CLOCKWISE_90:
-                switch ((RailShape)state.getValue(SHAPE)) {
+                switch ((RailShape) state.getValue(DetectorRailBlock.SHAPE)) {
                     case ASCENDING_EAST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_SOUTH);
                     case ASCENDING_WEST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_NORTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_NORTH);
                     case ASCENDING_NORTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_EAST);
                     case ASCENDING_SOUTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_WEST);
                     case SOUTH_EAST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_WEST);
                     case SOUTH_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_WEST);
                     case NORTH_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_EAST);
                     case NORTH_EAST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_EAST);
                     case NORTH_SOUTH:
-                        return state.setValue(SHAPE, RailShape.EAST_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.EAST_WEST);
                     case EAST_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_SOUTH);
                 }
             default:
                 return state;
@@ -237,43 +259,44 @@
 
     @Override
     public BlockState mirror(BlockState state, Mirror mirror) {
-        RailShape railShape = state.getValue(SHAPE);
+        RailShape blockpropertytrackposition = (RailShape) state.getValue(DetectorRailBlock.SHAPE);
+
         switch (mirror) {
             case LEFT_RIGHT:
-                switch (railShape) {
+                switch (blockpropertytrackposition) {
                     case ASCENDING_NORTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_SOUTH);
                     case ASCENDING_SOUTH:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_NORTH);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_NORTH);
                     case SOUTH_EAST:
-                        return state.setValue(SHAPE, RailShape.NORTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_EAST);
                     case SOUTH_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_WEST);
                     case NORTH_WEST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_WEST);
                     case NORTH_EAST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_EAST);
                     default:
                         return super.mirror(state, mirror);
                 }
             case FRONT_BACK:
-                switch (railShape) {
+                switch (blockpropertytrackposition) {
                     case ASCENDING_EAST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_WEST);
                     case ASCENDING_WEST:
-                        return state.setValue(SHAPE, RailShape.ASCENDING_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.ASCENDING_EAST);
                     case ASCENDING_NORTH:
                     case ASCENDING_SOUTH:
                     default:
                         break;
                     case SOUTH_EAST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_WEST);
                     case SOUTH_WEST:
-                        return state.setValue(SHAPE, RailShape.SOUTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.SOUTH_EAST);
                     case NORTH_WEST:
-                        return state.setValue(SHAPE, RailShape.NORTH_EAST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_EAST);
                     case NORTH_EAST:
-                        return state.setValue(SHAPE, RailShape.NORTH_WEST);
+                        return (BlockState) state.setValue(DetectorRailBlock.SHAPE, RailShape.NORTH_WEST);
                 }
         }
 
@@ -282,6 +305,6 @@
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(SHAPE, POWERED, WATERLOGGED);
+        builder.add(DetectorRailBlock.SHAPE, DetectorRailBlock.POWERED, DetectorRailBlock.WATERLOGGED);
     }
 }
