mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 07:20:24 +01:00
Fix command signs (#6139)
This commit is contained in:
parent
5ce2cd8c05
commit
67e2594825
4 changed files with 191 additions and 40 deletions
|
@ -51,3 +51,7 @@ c net/minecraft/world/level/block/entity/IHopper net/minecraft/world/level/block
|
||||||
# Teleport method in ServerGamePacketListenerImpl
|
# Teleport method in ServerGamePacketListenerImpl
|
||||||
c net/minecraft/server/network/PlayerConnection net/minecraft/server/network/ServerGamePacketListenerImpl
|
c net/minecraft/server/network/PlayerConnection net/minecraft/server/network/ServerGamePacketListenerImpl
|
||||||
m (DDDFFLorg/bukkit/event/player/PlayerTeleportEvent$TeleportCause;)V a teleport
|
m (DDDFFLorg/bukkit/event/player/PlayerTeleportEvent$TeleportCause;)V a teleport
|
||||||
|
|
||||||
|
# Commands performCommand adds a stripSlash boolean
|
||||||
|
c net/minecraft/commands/CommandDispatcher net/minecraft/commands/Commands
|
||||||
|
m (Lnet/minecraft/commands/CommandListenerWrapper;Ljava/lang/String;Ljava/lang/String;Z)I a performCommand
|
||||||
|
|
46
patches/api/Add-PlayerSignCommandPreprocessEvent.patch
Normal file
46
patches/api/Add-PlayerSignCommandPreprocessEvent.patch
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Fri, 9 Jul 2021 17:44:33 -0700
|
||||||
|
Subject: [PATCH] Add PlayerSignCommandPreprocessEvent
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
|
||||||
|
@@ -0,0 +0,0 @@
|
||||||
|
+package io.papermc.paper.event.player;
|
||||||
|
+
|
||||||
|
+import org.bukkit.block.Sign;
|
||||||
|
+import org.bukkit.entity.Player;
|
||||||
|
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+
|
||||||
|
+import java.util.Set;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Called when a {@link Player} clicks a sign that causes a command to run.
|
||||||
|
+ * <p>
|
||||||
|
+ * This command is run with elevated permissions which allows players to access commands on signs they wouldn't
|
||||||
|
+ * normally be able to run.
|
||||||
|
+ */
|
||||||
|
+public class PlayerSignCommandPreprocessEvent extends PlayerCommandPreprocessEvent {
|
||||||
|
+
|
||||||
|
+ private final Sign sign;
|
||||||
|
+
|
||||||
|
+ public PlayerSignCommandPreprocessEvent(@NotNull Player player, @NotNull String message, @NotNull Set<Player> recipients, @NotNull Sign sign) {
|
||||||
|
+ super(player, message, recipients);
|
||||||
|
+ this.sign = sign;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the sign that the command originated from.
|
||||||
|
+ *
|
||||||
|
+ * @return the sign
|
||||||
|
+ */
|
||||||
|
+ @NotNull
|
||||||
|
+ public Sign getSign() {
|
||||||
|
+ return sign;
|
||||||
|
+ }
|
||||||
|
+}
|
|
@ -0,0 +1,141 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Fri, 9 Jul 2021 13:50:48 -0700
|
||||||
|
Subject: [PATCH] Fix commands from signs not firing command events
|
||||||
|
|
||||||
|
This patch changes sign command logic so that `run_command` click events:
|
||||||
|
- are logged to the console
|
||||||
|
- fire PlayerCommandPreprocessEvent
|
||||||
|
- work with double-slash commands like `//wand`
|
||||||
|
- sends failure messages to the player who clicked the sign
|
||||||
|
|
||||||
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||||
|
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||||
|
private void fixInvulnerableEndCrystalExploit() {
|
||||||
|
fixInvulnerableEndCrystalExploit = getBoolean("unsupported-settings.fix-invulnerable-end-crystal-exploit", fixInvulnerableEndCrystalExploit);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ public boolean showSignClickCommandFailureMessagesToPlayer = false;
|
||||||
|
+ private void showSignClickCommandFailureMessagesToPlayer() {
|
||||||
|
+ showSignClickCommandFailureMessagesToPlayer = getBoolean("show-sign-click-command-failure-msgs-to-player", showSignClickCommandFailureMessagesToPlayer);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
|
||||||
|
@@ -0,0 +0,0 @@
|
||||||
|
+package io.papermc.paper.commands;
|
||||||
|
+
|
||||||
|
+import net.minecraft.commands.CommandSource;
|
||||||
|
+import net.minecraft.commands.CommandSourceStack;
|
||||||
|
+import net.minecraft.network.chat.Component;
|
||||||
|
+import org.bukkit.command.CommandSender;
|
||||||
|
+
|
||||||
|
+import java.util.UUID;
|
||||||
|
+
|
||||||
|
+public class DelegatingCommandSource implements CommandSource {
|
||||||
|
+
|
||||||
|
+ private final CommandSource delegate;
|
||||||
|
+
|
||||||
|
+ public DelegatingCommandSource(CommandSource delegate) {
|
||||||
|
+ this.delegate = delegate;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void sendMessage(Component message, UUID sender) {
|
||||||
|
+ delegate.sendMessage(message, sender);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean acceptsSuccess() {
|
||||||
|
+ return delegate.acceptsSuccess();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean acceptsFailure() {
|
||||||
|
+ return delegate.acceptsFailure();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean shouldInformAdmins() {
|
||||||
|
+ return delegate.shouldInformAdmins();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public CommandSender getBukkitSender(CommandSourceStack wrapper) {
|
||||||
|
+ return delegate.getBukkitSender(wrapper);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||||
|
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||||
|
private boolean renderMessagedFiltered;
|
||||||
|
private DyeColor color;
|
||||||
|
private boolean hasGlowingText;
|
||||||
|
+ private static final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger();
|
||||||
|
|
||||||
|
public SignBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
super(BlockEntityType.SIGN, pos, state);
|
||||||
|
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||||
|
ClickEvent chatclickable = chatmodifier.getClickEvent();
|
||||||
|
|
||||||
|
if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
|
||||||
|
- player.getServer().getCommands().performCommand(this.createCommandSourceStack(player), chatclickable.getValue());
|
||||||
|
+ // Paper start
|
||||||
|
+ String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
|
||||||
|
+ if (org.spigotmc.SpigotConfig.logCommands) {
|
||||||
|
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
|
||||||
|
+ }
|
||||||
|
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) net.minecraft.server.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState());
|
||||||
|
+ if (!event.callEvent()) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ player.getServer().getCommands().performCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||||
|
String s = player == null ? "Sign" : player.getName().getString();
|
||||||
|
Object object = player == null ? new TextComponent("Sign") : player.getDisplayName();
|
||||||
|
|
||||||
|
+ // Paper start - send messages back to the player
|
||||||
|
+ CommandSource commandSource = this.level.paperConfig.showSignClickCommandFailureMessagesToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) {
|
||||||
|
+ @Override
|
||||||
|
+ public void sendMessage(net.minecraft.network.chat.Component message, java.util.UUID sender) {
|
||||||
|
+ player.sendMessage(message, sender);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean acceptsFailure() {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ } : this;
|
||||||
|
+ // Paper end
|
||||||
|
// CraftBukkit - this
|
||||||
|
- return new CommandSourceStack(this, Vec3.atCenterOf((Vec3i) this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player);
|
||||||
|
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf((Vec3i) this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player); // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
public DyeColor getColor() {
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||||
|
@@ -0,0 +0,0 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
|
||||||
|
- return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getInput()) ? 1 : 0;
|
||||||
|
+ return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getRange().get(context.getInput())) ? 1 : 0; // Paper - actually use the StringRange from context
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
|
@ -1,40 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: mdcfe <1917406+mdcfe@users.noreply.github.com>
|
|
||||||
Date: Wed, 7 Jul 2021 12:29:48 +0100
|
|
||||||
Subject: [PATCH] Route sign run_command click events through normal chat logic
|
|
||||||
|
|
||||||
This patch changes sign command logic so that `run_command` click events are routed through the standard chat/command
|
|
||||||
logic used for inbound chat messages.
|
|
||||||
|
|
||||||
This fixes numerous issues related to sign click commands:
|
|
||||||
- Signs with a `run_command` value of "/<plugin command>" would fail and show the "Unknown command" warning. This
|
|
||||||
prevents usage of commands like `//wand` from WorldEdit in sign click events entirely and requires users to drop
|
|
||||||
the leading slash from other plugins' commands. This patch now executes the plugin commands as would be expected,
|
|
||||||
adding a leading slash if necessary.
|
|
||||||
- Signs with a `run_command` value that doesn't match an existing command could fail silently. This patch causes
|
|
||||||
these to *always* show "Unknown command" instead.
|
|
||||||
- Plugins listening to `PlayerCommandPreprocessEvent` would not be able to intercept any command executions from
|
|
||||||
sign click events. This patch allows plugins to intercept player commands when fired by a click event, in the same
|
|
||||||
manner as commands executed by the player typing or clicking on a chat message.
|
|
||||||
- Commands executed from signs would not be logged to the console. This patch fixes this.
|
|
||||||
|
|
||||||
This patch also prepends a leading slash if the `run_command` value lacks one, which matches vanilla behaviour (old
|
|
||||||
code would strip this slash away) while also ensuring `PlayerCommandPreprocessEvent#getMessage` remains consistent
|
|
||||||
with other command executions from chat (which always include the leading slash).
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
|
||||||
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
|
||||||
ClickEvent chatclickable = chatmodifier.getClickEvent();
|
|
||||||
|
|
||||||
if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
|
|
||||||
- player.getServer().getCommands().performCommand(this.createCommandSourceStack(player), chatclickable.getValue());
|
|
||||||
+ // Paper start - route through standard chat/command logic
|
|
||||||
+ final String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
|
|
||||||
+ player.connection.chat(command, false);
|
|
||||||
+ // Paper end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue