Add API for client-side signs

This commit is contained in:
Lukas Planz 2023-10-23 20:47:17 +02:00
parent c1ac98328c
commit 32cb972985
No known key found for this signature in database
GPG Key ID: 81CBFF1A39EB3CF8
2 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lukas Planz <me@md5lukas.de>
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.
+ * <p>
+ * 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<Component> 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.
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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

View File

@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lukas Planz <me@md5lukas.de>
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() {