--- a/net/minecraft/world/level/block/SignBlock.java
+++ b/net/minecraft/world/level/block/SignBlock.java
@@ -7,6 +7,7 @@
 import net.minecraft.Util;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.core.Holder;
 import net.minecraft.network.chat.CommonComponents;
 import net.minecraft.network.chat.contents.PlainTextContents;
 import net.minecraft.sounds.SoundSource;
@@ -15,6 +16,7 @@
 import net.minecraft.world.InteractionResult;
 import net.minecraft.world.ItemInteractionResult;
 import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.SignApplicator;
 import net.minecraft.world.level.BlockGetter;
@@ -31,6 +33,7 @@
 import net.minecraft.world.level.block.state.properties.BooleanProperty;
 import net.minecraft.world.level.block.state.properties.WoodType;
 import net.minecraft.world.level.gameevent.GameEvent;
+import net.minecraft.world.level.material.Fluid;
 import net.minecraft.world.level.material.FluidState;
 import net.minecraft.world.level.material.Fluids;
 import net.minecraft.world.phys.BlockHitResult;
@@ -39,9 +42,10 @@
 import net.minecraft.world.phys.shapes.VoxelShape;
 
 public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {
+
     public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
     protected static final float AABB_OFFSET = 4.0F;
-    protected static final VoxelShape SHAPE = Block.box(4.0, 0.0, 4.0, 12.0, 16.0, 12.0);
+    protected static final VoxelShape SHAPE = Block.box(4.0D, 0.0D, 4.0D, 12.0D, 16.0D, 12.0D);
     private final WoodType type;
 
     protected SignBlock(WoodType type, BlockBehaviour.Properties settings) {
@@ -54,8 +58,8 @@
 
     @Override
     protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
-        if (state.getValue(WATERLOGGED)) {
-            world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
+        if ((Boolean) state.getValue(SignBlock.WATERLOGGED)) {
+            world.scheduleTick(pos, (Fluid) Fluids.WATER, Fluids.WATER.getTickDelay(world));
         }
 
         return super.updateShape(state, direction, neighborState, world, pos, neighborPos);
@@ -63,7 +67,7 @@
 
     @Override
     protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        return SHAPE;
+        return SignBlock.SHAPE;
     }
 
     @Override
@@ -77,20 +81,30 @@
     }
 
     @Override
-    protected ItemInteractionResult useItemOn(
-        ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit
-    ) {
-        if (world.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity) {
-            SignApplicator signApplicator2 = stack.getItem() instanceof SignApplicator signApplicator ? signApplicator : null;
-            boolean bl = signApplicator2 != null && player.mayBuild();
+    protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
+        BlockEntity tileentity = world.getBlockEntity(pos);
+
+        if (tileentity instanceof SignBlockEntity tileentitysign) {
+            Item item = stack.getItem();
+            SignApplicator signapplicator;
+
+            if (item instanceof SignApplicator signapplicator1) {
+                signapplicator = signapplicator1;
+            } else {
+                signapplicator = null;
+            }
+
+            SignApplicator signapplicator2 = signapplicator;
+            boolean flag = signapplicator2 != null && player.mayBuild();
+
             if (!world.isClientSide) {
-                if (bl && !signBlockEntity.isWaxed() && !this.otherPlayerIsEditingSign(player, signBlockEntity)) {
-                    boolean bl2 = signBlockEntity.isFacingFrontText(player);
-                    if (signApplicator2.canApplyToSign(signBlockEntity.getText(bl2), player)
-                        && signApplicator2.tryApplyToSign(world, signBlockEntity, bl2, player)) {
-                        signBlockEntity.executeClickCommandsIfPresent(player, world, pos, bl2);
+                if (flag && !tileentitysign.isWaxed() && !this.otherPlayerIsEditingSign(player, tileentitysign)) {
+                    boolean flag1 = tileentitysign.isFacingFrontText(player);
+
+                    if (signapplicator2.canApplyToSign(tileentitysign.getText(flag1), player) && signapplicator2.tryApplyToSign(world, tileentitysign, flag1, player)) {
+                        tileentitysign.executeClickCommandsIfPresent(player, world, pos, flag1);
                         player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
-                        world.gameEvent(GameEvent.BLOCK_CHANGE, signBlockEntity.getBlockPos(), GameEvent.Context.of(player, signBlockEntity.getBlockState()));
+                        world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, tileentitysign.getBlockPos(), GameEvent.Context.of(player, tileentitysign.getBlockState()));
                         stack.consume(1, player);
                         return ItemInteractionResult.SUCCESS;
                     } else {
@@ -100,7 +114,7 @@
                     return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
                 }
             } else {
-                return !bl && !signBlockEntity.isWaxed() ? ItemInteractionResult.CONSUME : ItemInteractionResult.SUCCESS;
+                return !flag && !tileentitysign.isWaxed() ? ItemInteractionResult.CONSUME : ItemInteractionResult.SUCCESS;
             }
         } else {
             return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
@@ -109,20 +123,23 @@
 
     @Override
     protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
-        if (world.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity) {
+        BlockEntity tileentity = world.getBlockEntity(pos);
+
+        if (tileentity instanceof SignBlockEntity tileentitysign) {
             if (world.isClientSide) {
                 Util.pauseInIde(new IllegalStateException("Expected to only call this on server"));
             }
 
-            boolean bl = signBlockEntity.isFacingFrontText(player);
-            boolean bl2 = signBlockEntity.executeClickCommandsIfPresent(player, world, pos, bl);
-            if (signBlockEntity.isWaxed()) {
-                world.playSound(null, signBlockEntity.getBlockPos(), signBlockEntity.getSignInteractionFailedSoundEvent(), SoundSource.BLOCKS);
+            boolean flag = tileentitysign.isFacingFrontText(player);
+            boolean flag1 = tileentitysign.executeClickCommandsIfPresent(player, world, pos, flag);
+
+            if (tileentitysign.isWaxed()) {
+                world.playSound((Player) null, tileentitysign.getBlockPos(), tileentitysign.getSignInteractionFailedSoundEvent(), SoundSource.BLOCKS);
                 return InteractionResult.SUCCESS;
-            } else if (bl2) {
+            } else if (flag1) {
                 return InteractionResult.SUCCESS;
-            } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) && player.mayBuild() && this.hasEditableText(player, signBlockEntity, bl)) {
-                this.openTextEdit(player, signBlockEntity, bl);
+            } else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag)) {
+                this.openTextEdit(player, tileentitysign, flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
                 return InteractionResult.SUCCESS;
             } else {
                 return InteractionResult.PASS;
@@ -133,20 +150,22 @@
     }
 
     private boolean hasEditableText(Player player, SignBlockEntity blockEntity, boolean front) {
-        SignText signText = blockEntity.getText(front);
-        return Arrays.stream(signText.getMessages(player.isTextFilteringEnabled()))
-            .allMatch(message -> message.equals(CommonComponents.EMPTY) || message.getContents() instanceof PlainTextContents);
+        SignText signtext = blockEntity.getText(front);
+
+        return Arrays.stream(signtext.getMessages(player.isTextFilteringEnabled())).allMatch((ichatbasecomponent) -> {
+            return ichatbasecomponent.equals(CommonComponents.EMPTY) || ichatbasecomponent.getContents() instanceof PlainTextContents;
+        });
     }
 
     public abstract float getYRotationDegrees(BlockState state);
 
     public Vec3 getSignHitboxCenterPosition(BlockState state) {
-        return new Vec3(0.5, 0.5, 0.5);
+        return new Vec3(0.5D, 0.5D, 0.5D);
     }
 
     @Override
     protected FluidState getFluidState(BlockState state) {
-        return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
+        return (Boolean) state.getValue(SignBlock.WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
     }
 
     public WoodType type() {
@@ -154,29 +173,57 @@
     }
 
     public static WoodType getWoodType(Block block) {
-        WoodType woodType;
+        WoodType blockpropertywood;
+
         if (block instanceof SignBlock) {
-            woodType = ((SignBlock)block).type();
+            blockpropertywood = ((SignBlock) block).type();
         } else {
-            woodType = WoodType.OAK;
+            blockpropertywood = WoodType.OAK;
         }
 
-        return woodType;
+        return blockpropertywood;
     }
 
+    @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerOpenSignEvent
     public void openTextEdit(Player player, SignBlockEntity blockEntity, boolean front) {
-        blockEntity.setAllowedPlayerEditor(player.getUUID());
-        player.openTextEdit(blockEntity, front);
+        // Paper start - Add PlayerOpenSignEvent
+        this.openTextEdit(player, blockEntity, front, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN);
+    }
+    public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) {
+        org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) entityhuman.getBukkitEntity();
+        org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(tileentitysign.getLevel(), tileentitysign.getBlockPos());
+        org.bukkit.craftbukkit.block.CraftSign<?> bukkitSign = (org.bukkit.craftbukkit.block.CraftSign<?>) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(bukkitBlock);
+        io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent(
+            bukkitPlayer,
+            bukkitSign,
+            flag ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK,
+            cause);
+        if (!event.callEvent()) return;
+        if (org.bukkit.event.player.PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
+            final org.bukkit.event.player.PlayerSignOpenEvent.Cause legacyCause = switch (cause) {
+                case PLACE -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE;
+                case PLUGIN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLUGIN;
+                case INTERACT -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT;
+                case UNKNOWN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN;
+            };
+        if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, legacyCause)) {
+        // Paper end - Add PlayerOpenSignEvent
+            return;
+        }
+        } // Paper - Add PlayerOpenSignEvent
+        tileentitysign.setAllowedPlayerEditor(entityhuman.getUUID());
+        entityhuman.openTextEdit(tileentitysign, flag);
     }
 
     private boolean otherPlayerIsEditingSign(Player player, SignBlockEntity blockEntity) {
-        UUID uUID = blockEntity.getPlayerWhoMayEdit();
-        return uUID != null && !uUID.equals(player.getUUID());
+        UUID uuid = blockEntity.getPlayerWhoMayEdit();
+
+        return uuid != null && !uuid.equals(player.getUUID());
     }
 
     @Nullable
     @Override
     public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level world, BlockState state, BlockEntityType<T> type) {
-        return createTickerHelper(type, BlockEntityType.SIGN, SignBlockEntity::tick);
+        return null; // Craftbukkit - remove unnecessary sign ticking
     }
 }
