From 32cb9729853b6cc9e964857581955af256fed9ea Mon Sep 17 00:00:00 2001 From: Lukas Planz Date: Mon, 23 Oct 2023 20:47:17 +0200 Subject: [PATCH] Add API for client-side signs --- .../0442-Add-API-for-client-side-signs.patch | 121 ++++++++++++++++++ .../1040-Add-API-for-client-side-signs.patch | 43 +++++++ 2 files changed, 164 insertions(+) create mode 100644 patches/api/0442-Add-API-for-client-side-signs.patch create mode 100644 patches/server/1040-Add-API-for-client-side-signs.patch diff --git a/patches/api/0442-Add-API-for-client-side-signs.patch b/patches/api/0442-Add-API-for-client-side-signs.patch new file mode 100644 index 000000000..f23143c99 --- /dev/null +++ b/patches/api/0442-Add-API-for-client-side-signs.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lukas Planz +Date: Mon, 2 Oct 2023 15:47:27 +0200 +Subject: [PATCH] Add API for client-side signs + + +diff --git a/src/main/java/io/papermc/paper/event/packet/PreSignChangeEvent.java b/src/main/java/io/papermc/paper/event/packet/PreSignChangeEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..65e1be58c2b50fcb442bcee32f66d7ac9bba3db5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/packet/PreSignChangeEvent.java +@@ -0,0 +1,85 @@ ++package io.papermc.paper.event.packet; ++ ++import io.papermc.paper.math.BlockPosition; ++import net.kyori.adventure.text.Component; ++import org.bukkit.block.sign.Side; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Unmodifiable; ++import java.util.List; ++ ++/** ++ * Called when a sign edit packet has been received, but the location at which the sign should be edited ++ * has not yet been checked for the existence of a real sign. ++ *

++ * Cancelling this event will prevent further processing of the sign change, but needs further handling ++ * by the plugin because the local world might be in an inconsistent state. ++ */ ++public class PreSignChangeEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ private boolean cancel = false; ++ private final BlockPosition block; ++ private final Side side; ++ private final List lines; ++ ++ @ApiStatus.Internal ++ public PreSignChangeEvent(final @NotNull Player editor, @NotNull final BlockPosition block, final @NotNull Side side, @NotNull final List<@NotNull Component> lines) { ++ super(editor); ++ this.block = block; ++ this.side = side; ++ this.lines = lines; ++ } ++ ++ /** ++ * Gets the location at which an unknown sign was edited. ++ * ++ * @return location where the change happened ++ */ ++ public @NotNull BlockPosition getBlock() { ++ return block; ++ } ++ ++ /** ++ * Gets which side of the sign was edited. ++ * ++ * @return {@link Side} that was edited ++ */ ++ public @NotNull Side getSide() { ++ return side; ++ } ++ ++ /** ++ * Gets the lines that the player has entered ++ * ++ * @return the lines ++ */ ++ public @NotNull @Unmodifiable List<@NotNull Component> getLines() { ++ return lines; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return cancel; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancel = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index 20fa1024f9ad8f478a347be5c554b5e45b398a1c..eb735b76c833a8de171cc98e2a4aceae38a7f741 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -2811,6 +2811,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * @param side The side to edit + */ + public void openSign(@NotNull Sign sign, @NotNull Side side); ++ // Paper start ++ /** ++ * Open a sign for editing by the player. ++ *

++ * The sign must only be placed locally for the player, which can be done with {@link #sendBlockChange(Location, BlockData)} and {@link #sendBlockUpdate(Location, TileState)}. ++ * A side-effect of this is that no events will be called for this action. ++ *

++ * ++ * @param block The block where the client has a sign placed ++ * @param side The side to edit ++ */ ++ void openLocalSign(@NotNull io.papermc.paper.math.BlockPosition block, @NotNull Side side); ++ // Paper end + + /** + * Shows the demo screen to the player, this screen is normally only seen in diff --git a/patches/server/1040-Add-API-for-client-side-signs.patch b/patches/server/1040-Add-API-for-client-side-signs.patch new file mode 100644 index 000000000..3156ec59b --- /dev/null +++ b/patches/server/1040-Add-API-for-client-side-signs.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lukas Planz +Date: Mon, 2 Oct 2023 15:48:13 +0200 +Subject: [PATCH] Add API for client-side signs + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 34fcdeb0f4039f1fc6c4c8c593cc615560af1ba2..764e17cd5bff62ac2f3e21206618bfbae1abe86a 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -3372,6 +3372,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + if (worldserver.hasChunkAt(blockposition)) { + BlockEntity tileentity = worldserver.getBlockEntity(blockposition); + ++ // Paper start ++ if (!new io.papermc.paper.event.packet.PreSignChangeEvent(this.player.getBukkitEntity(), ++ io.papermc.paper.math.Position.block(blockposition.getX(), blockposition.getY(), blockposition.getZ()), ++ packet.isFrontText() ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK, ++ signText.stream().map(line -> (net.kyori.adventure.text.Component) net.kyori.adventure.text.Component.text(line.raw())).toList()) ++ .callEvent()) { ++ return; ++ } ++ // Paper end + if (!(tileentity instanceof SignBlockEntity)) { + return; + } +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 604ed1f6742a6b028b9db2809f7bd4b9a3b38f4d..d2823030771d1b24d55892f75cb51546c88380f6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -2861,6 +2861,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void openSign(@NotNull Sign sign, @NotNull Side side) { + CraftSign.openSign(sign, this, side); + } ++ // Paper start ++ @Override ++ public void openLocalSign(@NotNull io.papermc.paper.math.BlockPosition block, @NotNull Side side) { ++ getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket(new net.minecraft.core.BlockPos(block.blockX(), block.blockY(), block.blockZ()), side == Side.FRONT)); ++ } ++ // Paper end + + @Override + public void showDemoScreen() {