2020-05-06 11:48:49 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2020-04-27 07:37:37 +02:00
From: Aikar <aikar@aikar.co>
Date: Sun, 19 Apr 2020 18:15:29 -0400
Subject: [PATCH] Implement Brigadier Mojang API
Adds AsyncPlayerSendCommandsEvent
- Allows modifying on a per command basis what command data they see.
Adds CommandRegisteredEvent
- Allows manipulating the CommandNode to add more children/metadata for the client
diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java
2020-08-25 04:22:08 +02:00
index 4b1ea9bc39191e01f83577c7bad128cf1ab9612f..22d748008d24fd6ed7cd8c4914e2ceb378f32c95 100644
2020-04-27 07:37:37 +02:00
--- a/src/main/java/net/minecraft/server/CommandDispatcher.java
+++ b/src/main/java/net/minecraft/server/CommandDispatcher.java
2020-08-25 04:22:08 +02:00
@@ -270,6 +270,7 @@ public class CommandDispatcher {
2020-04-27 07:37:37 +02:00
bukkit.add(node.getName());
}
// Paper start - Async command map building
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandListenerWrapper>(entityplayer.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper
MinecraftServer.getServer().execute(() -> {
runSync(entityplayer, bukkit, rootcommandnode);
});
2020-08-25 04:22:08 +02:00
@@ -277,6 +278,7 @@ public class CommandDispatcher {
2020-04-27 07:37:37 +02:00
private void runSync(EntityPlayer entityplayer, Collection<String> bukkit, RootCommandNode<ICompletionProvider> rootcommandnode) {
// Paper end - Async command map building
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandListenerWrapper>(entityplayer.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper
PlayerCommandSendEvent event = new PlayerCommandSendEvent(entityplayer.getBukkitEntity(), new LinkedHashSet<>(bukkit));
event.getPlayer().getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/CommandListenerWrapper.java b/src/main/java/net/minecraft/server/CommandListenerWrapper.java
2020-08-25 04:22:08 +02:00
index 27c16946b589a36a47b612c8b10b2955ba2715b1..7608b5021d66c39b8121f33829cd09d77c847277 100644
2020-04-27 07:37:37 +02:00
--- a/src/main/java/net/minecraft/server/CommandListenerWrapper.java
+++ b/src/main/java/net/minecraft/server/CommandListenerWrapper.java
2020-06-26 03:53:21 +02:00
@@ -16,7 +16,7 @@ import java.util.function.BinaryOperator;
2020-04-27 07:37:37 +02:00
import java.util.stream.Stream;
import javax.annotation.Nullable;
-public class CommandListenerWrapper implements ICompletionProvider {
+public class CommandListenerWrapper implements ICompletionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper
2020-06-26 03:53:21 +02:00
public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player"));
public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity"));
2020-08-25 04:22:08 +02:00
@@ -128,6 +128,25 @@ public class CommandListenerWrapper implements ICompletionProvider {
2020-04-27 07:37:37 +02:00
return this.g;
}
+ // Paper start
+ @Override
+ public org.bukkit.entity.Entity getBukkitEntity() {
+ return getEntity() != null ? getEntity().getBukkitEntity() : null;
+ }
+
+ @Override
+ public org.bukkit.World getBukkitWorld() {
+ return getWorld() != null ? getWorld().getWorld() : null;
+ }
+
+ @Override
+ public org.bukkit.Location getBukkitLocation() {
+ Vec3D pos = getPosition();
+ org.bukkit.World world = getBukkitWorld();
+ return world != null && pos != null ? new org.bukkit.Location(world, pos.x, pos.y, pos.z) : null;
+ }
+ // Paper end
+
@Override
public boolean hasPermission(int i) {
// CraftBukkit start
2020-05-02 20:17:17 +02:00
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
2020-08-25 04:22:08 +02:00
index 23002a66f3189d31c1b4382cdbd684e85320539a..5f1e7e4bc3ae80f4ed61f2d65da1cf9935a3882a 100644
2020-05-02 20:17:17 +02:00
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
2020-08-25 04:22:08 +02:00
@@ -578,8 +578,12 @@ public class PlayerConnection implements PacketListenerPlayIn {
2020-06-26 03:53:21 +02:00
ParseResults<CommandListenerWrapper> parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
2020-05-02 20:17:17 +02:00
2020-06-26 03:53:21 +02:00
this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions));
+ // Paper start
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
2020-06-26 14:04:38 +02:00
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
2020-06-26 03:53:21 +02:00
+ // Paper end
});
});
2020-05-02 20:17:17 +02:00
}
2020-08-25 04:22:08 +02:00
@@ -588,7 +592,11 @@ public class PlayerConnection implements PacketListenerPlayIn {
2020-05-02 20:17:17 +02:00
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
completions.forEach(builder::suggest);
- player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), builder.buildFuture().join()));
2020-06-26 14:04:38 +02:00
+ com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join();
2020-05-02 21:25:55 +02:00
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer);
2020-05-02 20:17:17 +02:00
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestEvent.getSuggestions()));
}
// Paper end - async tab completion
2020-06-26 03:53:21 +02:00
}
2020-04-27 07:37:37 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
2020-05-06 11:48:49 +02:00
index 5f33c9e52ac51486d4b22a6dcbfac7f46e0412bb..e16ecdea7d27424053b3f21378af054b2f808eca 100644
2020-04-27 07:37:37 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -17,7 +17,7 @@ import net.minecraft.server.CommandListenerWrapper;
import org.bukkit.command.Command;
import org.bukkit.craftbukkit.CraftServer;
-public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandListenerWrapper>, Predicate<CommandListenerWrapper>, SuggestionProvider<CommandListenerWrapper> {
+public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandListenerWrapper>, Predicate<CommandListenerWrapper>, SuggestionProvider<CommandListenerWrapper>, com.destroystokyo.paper.brigadier.BukkitBrigadierCommand<CommandListenerWrapper> { // Paper
private final CraftServer server;
private final Command command;
@@ -28,10 +28,19 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
}
public LiteralCommandNode<CommandListenerWrapper> register(CommandDispatcher<CommandListenerWrapper> dispatcher, String label) {
- return dispatcher.register(
- LiteralArgumentBuilder.<CommandListenerWrapper>literal(label).requires(this).executes(this)
- .then(RequiredArgumentBuilder.<CommandListenerWrapper, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this))
- );
+ // Paper start - Expose Brigadier to Paper-MojangAPI
+ com.mojang.brigadier.tree.RootCommandNode<CommandListenerWrapper> root = dispatcher.getRoot();
+ LiteralCommandNode<CommandListenerWrapper> literal = LiteralArgumentBuilder.<CommandListenerWrapper>literal(label).requires(this).executes(this).build();
+ com.mojang.brigadier.tree.ArgumentCommandNode<CommandListenerWrapper, String> defaultArgs = RequiredArgumentBuilder.<CommandListenerWrapper, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this).build();
+ literal.addChild(defaultArgs);
+ com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent<CommandListenerWrapper> event = new com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent<>(label, this, this.command, root, literal, defaultArgs);
+ if (!event.callEvent()) {
+ return null;
+ }
+ literal = event.getLiteral();
+ root.addChild(literal);
+ return literal;
+ // Paper end
}
@Override