1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
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/build.gradle.kts b/build.gradle.kts
index 80c533bc8966e4f9d7b19ef98faf04146d14be7d..d84e04f2cf8870611d36834c5ea77a82e42df6d5 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,6 +12,7 @@ repositories {
dependencies {
implementation(project(":paper-api"))
+ implementation(project(":paper-mojangapi"))
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
index 5ebf717535eab892898a62ce6aaaf936fe064626..31aaad639b6c285226ca7aca1bd2285cfe0d9117 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
@@ -38,7 +38,7 @@ import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import com.mojang.brigadier.tree.CommandNode; // CraftBukkit
-public class CommandSourceStack implements SharedSuggestionProvider {
+public class CommandSourceStack implements SharedSuggestionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.player"));
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.entity"));
@@ -155,6 +155,25 @@ public class CommandSourceStack implements SharedSuggestionProvider {
return this.textName;
}
+ // Paper start
+ @Override
+ public org.bukkit.entity.Entity getBukkitEntity() {
+ return getEntity() != null ? getEntity().getBukkitEntity() : null;
+ }
+
+ @Override
+ public org.bukkit.World getBukkitWorld() {
+ return getLevel() != null ? getLevel().getWorld() : null;
+ }
+
+ @Override
+ public org.bukkit.Location getBukkitLocation() {
+ Vec3 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 level) {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index f3bbe012541a71ab75c1863990d0c056c62d8c6e..4bc28b66788d06d1446284f5adef6a44be736f92 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -371,6 +371,7 @@ public class Commands {
bukkit.add(node.getName());
}
// Paper start - Async command map building
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper
MinecraftServer.getServer().execute(() -> {
runSync(player, bukkit, rootcommandnode);
});
@@ -378,6 +379,7 @@ public class Commands {
private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
// Paper end - Async command map building
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper
PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
event.getPlayer().getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d8135a0e644b67ed47972eb3bda517323561a93d..43bd11679d881b1039db4ed57e70d1ae4d49a107 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -753,8 +753,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
this.server.getCommands().getDispatcher().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.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions));
+ // Paper start
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
+ // Paper end
});
});
}
@@ -763,7 +767,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
completions.forEach(builder::suggest);
- player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join()));
+ com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join();
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions()));
}
// Paper end - async tab completion
}
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index 21971d52fa8ed92c946c519ba93a39aceae10f5f..0bba36d18d56a4dc2d6c6fb7969e5e6f0e1da404 100644
--- 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.commands.CommandSourceStack;
import org.bukkit.command.Command;
import org.bukkit.craftbukkit.CraftServer;
-public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack> {
+public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack>, com.destroystokyo.paper.brigadier.BukkitBrigadierCommand<CommandSourceStack> { // Paper
private final CraftServer server;
private final Command command;
@@ -28,10 +28,19 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
}
public LiteralCommandNode<CommandSourceStack> register(CommandDispatcher<CommandSourceStack> dispatcher, String label) {
- return dispatcher.register(
- LiteralArgumentBuilder.<CommandSourceStack>literal(label).requires(this).executes(this)
- .then(RequiredArgumentBuilder.<CommandSourceStack, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this))
- );
+ // Paper start - Expose Brigadier to Paper-MojangAPI
+ com.mojang.brigadier.tree.RootCommandNode<CommandSourceStack> root = dispatcher.getRoot();
+ LiteralCommandNode<CommandSourceStack> literal = LiteralArgumentBuilder.<CommandSourceStack>literal(label).requires(this).executes(this).build();
+ com.mojang.brigadier.tree.ArgumentCommandNode<CommandSourceStack, String> defaultArgs = RequiredArgumentBuilder.<CommandSourceStack, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this).build();
+ literal.addChild(defaultArgs);
+ com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent<CommandSourceStack> 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
|