--- a/net/minecraft/world/level/block/SculkSensorBlock.java
+++ b/net/minecraft/world/level/block/SculkSensorBlock.java
@@ -102,6 +_,18 @@
             && level.getBlockEntity(pos) instanceof SculkSensorBlockEntity sculkSensorBlockEntity
             && level instanceof ServerLevel serverLevel
             && sculkSensorBlockEntity.getVibrationUser().canReceiveVibration(serverLevel, pos, GameEvent.STEP, GameEvent.Context.of(state))) {
+            // CraftBukkit start
+            org.bukkit.event.Cancellable cancellable;
+            if (entity instanceof net.minecraft.world.entity.player.Player player) {
+                cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null);
+            } else {
+                cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos));
+                level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable);
+            }
+            if (cancellable.isCancelled()) {
+                return;
+            }
+            // CraftBukkit end
             sculkSensorBlockEntity.getListener().forceScheduleVibration(serverLevel, GameEvent.STEP, GameEvent.Context.of(entity), entity.position());
         }
 
@@ -191,10 +_,19 @@
     }
 
     public static boolean canActivate(BlockState state) {
-        return getPhase(state) == SculkSensorPhase.INACTIVE;
+        return state.getBlock() instanceof SculkSensorBlock &&  getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type
     }
 
     public static void deactivate(Level level, BlockPos pos, BlockState state) {
+        // CraftBukkit start
+        org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), 0);
+        level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+        if (eventRedstone.getNewCurrent() > 0) {
+            level.setBlock(pos, state.setValue(SculkSensorBlock.POWER, eventRedstone.getNewCurrent()), 3);
+            return;
+        }
+        // CraftBukkit end
         level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.COOLDOWN).setValue(POWER, 0), 3);
         level.scheduleTick(pos, state.getBlock(), 10);
         updateNeighbours(level, pos, state);
@@ -206,6 +_,15 @@
     }
 
     public void activate(@Nullable Entity entity, Level level, BlockPos pos, BlockState state, int power, int frequency) {
+        // CraftBukkit start
+        org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), power);
+        level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+        if (eventRedstone.getNewCurrent() <= 0) {
+            return;
+        }
+        power = eventRedstone.getNewCurrent();
+        // CraftBukkit end
         level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.ACTIVE).setValue(POWER, power), 3);
         level.scheduleTick(pos, state.getBlock(), this.getActiveTicks());
         updateNeighbours(level, pos, state);
@@ -283,8 +_,16 @@
     @Override
     protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
         super.spawnAfterBreak(state, level, pos, stack, dropExperience);
+        // CraftBukkit start - Delegate to getExpDrop
+    }
+
+    @Override
+    public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
         if (dropExperience) {
-            this.tryDropExperience(level, pos, stack, ConstantInt.of(5));
+            return this.tryDropExperience(level, pos, stack, ConstantInt.of(5));
         }
+
+        return 0;
+        // CraftBukkit end
     }
 }
