--- a/net/minecraft/world/level/block/TripWireBlock.java
+++ b/net/minecraft/world/level/block/TripWireBlock.java
@@ -2,10 +2,12 @@
 
 import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
 import net.minecraft.core.registries.BuiltInRegistries;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.util.RandomSource;
@@ -21,15 +23,19 @@
 import net.minecraft.world.level.block.state.StateDefinition;
 import net.minecraft.world.level.block.state.properties.BlockStateProperties;
 import net.minecraft.world.level.block.state.properties.BooleanProperty;
+import net.minecraft.world.level.block.state.properties.Property;
 import net.minecraft.world.level.gameevent.GameEvent;
 import net.minecraft.world.phys.shapes.CollisionContext;
 import net.minecraft.world.phys.shapes.VoxelShape;
+import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit
 
 public class TripWireBlock extends Block {
-    public static final MapCodec<TripWireBlock> CODEC = RecordCodecBuilder.mapCodec(
-        instance -> instance.group(BuiltInRegistries.BLOCK.byNameCodec().fieldOf("hook").forGetter(block -> block.hook), propertiesCodec())
-                .apply(instance, TripWireBlock::new)
-    );
+
+    public static final MapCodec<TripWireBlock> CODEC = RecordCodecBuilder.mapCodec((instance) -> {
+        return instance.group(BuiltInRegistries.BLOCK.byNameCodec().fieldOf("hook").forGetter((blocktripwire) -> {
+            return blocktripwire.hook;
+        }), propertiesCodec()).apply(instance, TripWireBlock::new);
+    });
     public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
     public static final BooleanProperty ATTACHED = BlockStateProperties.ATTACHED;
     public static final BooleanProperty DISARMED = BlockStateProperties.DISARMED;
@@ -38,57 +44,45 @@
     public static final BooleanProperty SOUTH = PipeBlock.SOUTH;
     public static final BooleanProperty WEST = PipeBlock.WEST;
     private static final Map<Direction, BooleanProperty> PROPERTY_BY_DIRECTION = CrossCollisionBlock.PROPERTY_BY_DIRECTION;
-    protected static final VoxelShape AABB = Block.box(0.0, 1.0, 0.0, 16.0, 2.5, 16.0);
-    protected static final VoxelShape NOT_ATTACHED_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 8.0, 16.0);
+    protected static final VoxelShape AABB = Block.box(0.0D, 1.0D, 0.0D, 16.0D, 2.5D, 16.0D);
+    protected static final VoxelShape NOT_ATTACHED_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D);
     private static final int RECHECK_PERIOD = 10;
     private final Block hook;
 
     @Override
     public MapCodec<TripWireBlock> codec() {
-        return CODEC;
+        return TripWireBlock.CODEC;
     }
 
     public TripWireBlock(Block hookBlock, BlockBehaviour.Properties settings) {
         super(settings);
-        this.registerDefaultState(
-            this.stateDefinition
-                .any()
-                .setValue(POWERED, Boolean.valueOf(false))
-                .setValue(ATTACHED, Boolean.valueOf(false))
-                .setValue(DISARMED, Boolean.valueOf(false))
-                .setValue(NORTH, Boolean.valueOf(false))
-                .setValue(EAST, Boolean.valueOf(false))
-                .setValue(SOUTH, Boolean.valueOf(false))
-                .setValue(WEST, Boolean.valueOf(false))
-        );
+        this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) ((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(TripWireBlock.POWERED, false)).setValue(TripWireBlock.ATTACHED, false)).setValue(TripWireBlock.DISARMED, false)).setValue(TripWireBlock.NORTH, false)).setValue(TripWireBlock.EAST, false)).setValue(TripWireBlock.SOUTH, false)).setValue(TripWireBlock.WEST, false));
         this.hook = hookBlock;
     }
 
     @Override
     protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        return state.getValue(ATTACHED) ? AABB : NOT_ATTACHED_AABB;
+        return (Boolean) state.getValue(TripWireBlock.ATTACHED) ? TripWireBlock.AABB : TripWireBlock.NOT_ATTACHED_AABB;
     }
 
     @Override
     public BlockState getStateForPlacement(BlockPlaceContext ctx) {
-        BlockGetter blockGetter = ctx.getLevel();
-        BlockPos blockPos = ctx.getClickedPos();
-        return this.defaultBlockState()
-            .setValue(NORTH, Boolean.valueOf(this.shouldConnectTo(blockGetter.getBlockState(blockPos.north()), Direction.NORTH)))
-            .setValue(EAST, Boolean.valueOf(this.shouldConnectTo(blockGetter.getBlockState(blockPos.east()), Direction.EAST)))
-            .setValue(SOUTH, Boolean.valueOf(this.shouldConnectTo(blockGetter.getBlockState(blockPos.south()), Direction.SOUTH)))
-            .setValue(WEST, Boolean.valueOf(this.shouldConnectTo(blockGetter.getBlockState(blockPos.west()), Direction.WEST)));
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating
+        Level world = ctx.getLevel();
+        BlockPos blockposition = ctx.getClickedPos();
+
+        return (BlockState) ((BlockState) ((BlockState) ((BlockState) this.defaultBlockState().setValue(TripWireBlock.NORTH, this.shouldConnectTo(world.getBlockState(blockposition.north()), Direction.NORTH))).setValue(TripWireBlock.EAST, this.shouldConnectTo(world.getBlockState(blockposition.east()), Direction.EAST))).setValue(TripWireBlock.SOUTH, this.shouldConnectTo(world.getBlockState(blockposition.south()), Direction.SOUTH))).setValue(TripWireBlock.WEST, this.shouldConnectTo(world.getBlockState(blockposition.west()), Direction.WEST));
     }
 
     @Override
     protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
-        return direction.getAxis().isHorizontal()
-            ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(this.shouldConnectTo(neighborState, direction)))
-            : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating
+        return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, direction, neighborState, world, pos, neighborPos);
     }
 
     @Override
     protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
         if (!oldState.is(state.getBlock())) {
             this.updateSource(world, pos, state);
         }
@@ -96,44 +90,61 @@
 
     @Override
     protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
         if (!moved && !state.is(newState.getBlock())) {
-            this.updateSource(world, pos, state.setValue(POWERED, Boolean.valueOf(true)));
+            this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true));
         }
     }
 
     @Override
     public BlockState playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent disarming tripwires
         if (!world.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) {
-            world.setBlock(pos, state.setValue(DISARMED, Boolean.valueOf(true)), 4);
-            world.gameEvent(player, GameEvent.SHEAR, pos);
+            world.setBlock(pos, (BlockState) state.setValue(TripWireBlock.DISARMED, true), 4);
+            world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos);
         }
 
         return super.playerWillDestroy(world, pos, state, player);
     }
 
     private void updateSource(Level world, BlockPos pos, BlockState state) {
-        for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) {
-            for (int i = 1; i < 42; i++) {
-                BlockPos blockPos = pos.relative(direction, i);
-                BlockState blockState = world.getBlockState(blockPos);
-                if (blockState.is(this.hook)) {
-                    if (blockState.getValue(TripWireHookBlock.FACING) == direction.getOpposite()) {
-                        TripWireHookBlock.calculateState(world, blockPos, blockState, false, true, i, state);
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating
+        Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST};
+        int i = aenumdirection.length;
+        int j = 0;
+
+        while (j < i) {
+            Direction enumdirection = aenumdirection[j];
+            int k = 1;
+
+            while (true) {
+                if (k < 42) {
+                    BlockPos blockposition1 = pos.relative(enumdirection, k);
+                    BlockState iblockdata1 = world.getBlockState(blockposition1);
+
+                    if (iblockdata1.is(this.hook)) {
+                        if (iblockdata1.getValue(TripWireHookBlock.FACING) == enumdirection.getOpposite()) {
+                            TripWireHookBlock.calculateState(world, blockposition1, iblockdata1, false, true, k, state);
+                        }
+                    } else if (iblockdata1.is((Block) this)) {
+                        ++k;
+                        continue;
                     }
-                    break;
                 }
 
-                if (!blockState.is(this)) {
-                    break;
-                }
+                ++j;
+                break;
             }
         }
+
     }
 
     @Override
     protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision
+        if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
         if (!world.isClientSide) {
-            if (!state.getValue(POWERED)) {
+            if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
                 this.checkPressed(world, pos);
             }
         }
@@ -141,58 +152,90 @@
 
     @Override
     protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
-        if (world.getBlockState(pos).getValue(POWERED)) {
+        if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check
+        if ((Boolean) world.getBlockState(pos).getValue(TripWireBlock.POWERED)) {
             this.checkPressed(world, pos);
         }
     }
 
     private void checkPressed(Level world, BlockPos pos) {
-        BlockState blockState = world.getBlockState(pos);
-        boolean bl = blockState.getValue(POWERED);
-        boolean bl2 = false;
-        List<? extends Entity> list = world.getEntities(null, blockState.getShape(world, pos).bounds().move(pos));
+        BlockState iblockdata = world.getBlockState(pos);
+        boolean flag = (Boolean) iblockdata.getValue(TripWireBlock.POWERED);
+        boolean flag1 = false;
+        List<? extends Entity> list = world.getEntities((Entity) null, iblockdata.getShape(world, pos).bounds().move(pos));
+
         if (!list.isEmpty()) {
-            for (Entity entity : list) {
+            Iterator iterator = list.iterator();
+
+            while (iterator.hasNext()) {
+                Entity entity = (Entity) iterator.next();
+
                 if (!entity.isIgnoringBlockTriggers()) {
-                    bl2 = true;
+                    flag1 = true;
                     break;
                 }
             }
         }
 
-        if (bl2 != bl) {
-            blockState = blockState.setValue(POWERED, Boolean.valueOf(bl2));
-            world.setBlock(pos, blockState, 3);
-            this.updateSource(world, pos, blockState);
+        // CraftBukkit start - Call interact even when triggering connected tripwire
+        if (flag != flag1 && flag1 && (Boolean)iblockdata.getValue(TripWireBlock.ATTACHED)) {
+            org.bukkit.World bworld = world.getWorld();
+            org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager();
+            org.bukkit.block.Block block = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+            boolean allowed = false;
+
+            // If all of the events are cancelled block the tripwire trigger, else allow
+            for (Object object : list) {
+                if (object != null) {
+                    org.bukkit.event.Cancellable cancellable;
+
+                    if (object instanceof Player) {
+                        cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) object, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null);
+                    } else if (object instanceof Entity) {
+                        cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block);
+                        manager.callEvent((EntityInteractEvent) cancellable);
+                    } else {
+                        continue;
+                    }
+
+                    if (!cancellable.isCancelled()) {
+                        allowed = true;
+                        break;
+                    }
+                }
+            }
+
+            if (!allowed) {
+                return;
+            }
         }
+        // CraftBukkit end
 
-        if (bl2) {
-            world.scheduleTick(new BlockPos(pos), this, 10);
+        if (flag1 != flag) {
+            iblockdata = (BlockState) iblockdata.setValue(TripWireBlock.POWERED, flag1);
+            world.setBlock(pos, iblockdata, 3);
+            this.updateSource(world, pos, iblockdata);
+        }
+
+        if (flag1) {
+            world.scheduleTick(new BlockPos(pos), (Block) this, 10);
         }
+
     }
 
     public boolean shouldConnectTo(BlockState state, Direction facing) {
-        return state.is(this.hook) ? state.getValue(TripWireHookBlock.FACING) == facing.getOpposite() : state.is(this);
+        return state.is(this.hook) ? state.getValue(TripWireHookBlock.FACING) == facing.getOpposite() : state.is((Block) this);
     }
 
     @Override
     protected BlockState rotate(BlockState state, Rotation rotation) {
         switch (rotation) {
             case CLOCKWISE_180:
-                return state.setValue(NORTH, state.getValue(SOUTH))
-                    .setValue(EAST, state.getValue(WEST))
-                    .setValue(SOUTH, state.getValue(NORTH))
-                    .setValue(WEST, state.getValue(EAST));
+                return (BlockState) ((BlockState) ((BlockState) ((BlockState) state.setValue(TripWireBlock.NORTH, (Boolean) state.getValue(TripWireBlock.SOUTH))).setValue(TripWireBlock.EAST, (Boolean) state.getValue(TripWireBlock.WEST))).setValue(TripWireBlock.SOUTH, (Boolean) state.getValue(TripWireBlock.NORTH))).setValue(TripWireBlock.WEST, (Boolean) state.getValue(TripWireBlock.EAST));
             case COUNTERCLOCKWISE_90:
-                return state.setValue(NORTH, state.getValue(EAST))
-                    .setValue(EAST, state.getValue(SOUTH))
-                    .setValue(SOUTH, state.getValue(WEST))
-                    .setValue(WEST, state.getValue(NORTH));
+                return (BlockState) ((BlockState) ((BlockState) ((BlockState) state.setValue(TripWireBlock.NORTH, (Boolean) state.getValue(TripWireBlock.EAST))).setValue(TripWireBlock.EAST, (Boolean) state.getValue(TripWireBlock.SOUTH))).setValue(TripWireBlock.SOUTH, (Boolean) state.getValue(TripWireBlock.WEST))).setValue(TripWireBlock.WEST, (Boolean) state.getValue(TripWireBlock.NORTH));
             case CLOCKWISE_90:
-                return state.setValue(NORTH, state.getValue(WEST))
-                    .setValue(EAST, state.getValue(NORTH))
-                    .setValue(SOUTH, state.getValue(EAST))
-                    .setValue(WEST, state.getValue(SOUTH));
+                return (BlockState) ((BlockState) ((BlockState) ((BlockState) state.setValue(TripWireBlock.NORTH, (Boolean) state.getValue(TripWireBlock.WEST))).setValue(TripWireBlock.EAST, (Boolean) state.getValue(TripWireBlock.NORTH))).setValue(TripWireBlock.SOUTH, (Boolean) state.getValue(TripWireBlock.EAST))).setValue(TripWireBlock.WEST, (Boolean) state.getValue(TripWireBlock.SOUTH));
             default:
                 return state;
         }
@@ -202,9 +245,9 @@
     protected BlockState mirror(BlockState state, Mirror mirror) {
         switch (mirror) {
             case LEFT_RIGHT:
-                return state.setValue(NORTH, state.getValue(SOUTH)).setValue(SOUTH, state.getValue(NORTH));
+                return (BlockState) ((BlockState) state.setValue(TripWireBlock.NORTH, (Boolean) state.getValue(TripWireBlock.SOUTH))).setValue(TripWireBlock.SOUTH, (Boolean) state.getValue(TripWireBlock.NORTH));
             case FRONT_BACK:
-                return state.setValue(EAST, state.getValue(WEST)).setValue(WEST, state.getValue(EAST));
+                return (BlockState) ((BlockState) state.setValue(TripWireBlock.EAST, (Boolean) state.getValue(TripWireBlock.WEST))).setValue(TripWireBlock.WEST, (Boolean) state.getValue(TripWireBlock.EAST));
             default:
                 return super.mirror(state, mirror);
         }
@@ -212,6 +255,6 @@
 
     @Override
     protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
-        builder.add(POWERED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH);
+        builder.add(TripWireBlock.POWERED, TripWireBlock.ATTACHED, TripWireBlock.DISARMED, TripWireBlock.NORTH, TripWireBlock.EAST, TripWireBlock.WEST, TripWireBlock.SOUTH);
     }
 }
