From 1faf6dad076e8116dd165d143f9bc1632e8dc53e 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 --- .../0484-Add-API-for-client-side-signs.patch | 121 ++++++++++++++++++ .../1053-Add-API-for-client-side-signs.patch | 43 +++++++ 2 files changed, 164 insertions(+) create mode 100644 patches/api/0484-Add-API-for-client-side-signs.patch create mode 100644 patches/server/1053-Add-API-for-client-side-signs.patch diff --git a/patches/api/0484-Add-API-for-client-side-signs.patch b/patches/api/0484-Add-API-for-client-side-signs.patch new file mode 100644 index 0000000000..fb84fd0ea9 --- /dev/null +++ b/patches/api/0484-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/UncheckedSignChangeEvent.java b/src/main/java/io/papermc/paper/event/packet/UncheckedSignChangeEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..501c1d5cb62d4929509ae2415f424f6f04f09909 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/packet/UncheckedSignChangeEvent.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 UncheckedSignChangeEvent 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 UncheckedSignChangeEvent(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 a potential 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 f2e1b98880503a9933a20ebcf0ba91413c859a08..14313a8b425f174d518bbad3e219fa130c86c0f6 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -3382,6 +3382,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 - Add API for client-side signs ++ /** ++ * 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 - Add API for client-side signs + + /** + * Shows the demo screen to the player, this screen is normally only seen in diff --git a/patches/server/1053-Add-API-for-client-side-signs.patch b/patches/server/1053-Add-API-for-client-side-signs.patch new file mode 100644 index 0000000000..60973046e4 --- /dev/null +++ b/patches/server/1053-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 4ae88bfcead40cd05f9514a48a922a37767cb3cf..fbe255164e78b4bdfc4b5950d242df1b3451c9f4 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -3448,6 +3448,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + if (worldserver.hasChunkAt(blockposition)) { + BlockEntity tileentity = worldserver.getBlockEntity(blockposition); + ++ // Paper start - Add API for client-side signs ++ if (!new io.papermc.paper.event.packet.UncheckedSignChangeEvent(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 - Add API for client-side signs + 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 7e6116963d835d4606ef3d93b69d3e44b61288e1..9e4e7b4856e448fc35d041552330939fc8bc4fad 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -3039,6 +3039,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void openSign(@NotNull Sign sign, @NotNull Side side) { + CraftSign.openSign(sign, this, side); + } ++ // Paper start - Add API for client-side signs ++ @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 - Add API for client-side signs + + @Override + public void showDemoScreen() {