|
144 | 144 | } |
145 | 145 |
|
146 | 146 | return null; |
147 | | -@@ -360,25 +_,130 @@ |
| 147 | +@@ -360,25 +_,93 @@ |
148 | 148 | } |
149 | 149 |
|
150 | 150 | public void sendCommands(ServerPlayer player) { |
|
218 | 218 | Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> commandNodeToSuggestionNode |
219 | 219 | ) { |
220 | 220 | - for (CommandNode<CommandSourceStack> commandNode : rootCommandSource.getChildren()) { |
221 | | -+ commandNodeToSuggestionNode.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains(":")); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below |
222 | 221 | + for (CommandNode<CommandSourceStack> commandNode : children) { // Paper - Perf: Async command map building; pass copy of children |
223 | 222 | + // Paper start - Brigadier API |
224 | 223 | + if (commandNode.clientNode != null) { |
|
228 | 227 | + if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot |
229 | 228 | if (commandNode.canUse(source)) { |
230 | 229 | ArgumentBuilder<SharedSuggestionProvider, ?> argumentBuilder = (ArgumentBuilder) commandNode.createBuilder(); |
231 | | -+ // Paper start |
232 | | -+ /* |
233 | | -+ Because of how commands can be yeeted right left and center due to bad bukkit practices |
234 | | -+ we need to be able to ensure that ALL commands are registered (even redirects). |
235 | | -+ |
236 | | -+ What this will do is IF the redirect seems to be "dead" it will create a builder and essentially populate (flatten) |
237 | | -+ all the children from the dead redirect to the node. |
238 | | -+ |
239 | | -+ So, if minecraft:msg redirects to msg but the original msg node has been overriden minecraft:msg will now act as msg and will explicilty inherit its children. |
240 | | -+ |
241 | | -+ The only way to fix this is to either: |
242 | | -+ - Send EVERYTHING flattened, don't use redirects |
243 | | -+ - Don't allow command nodes to be deleted |
244 | | -+ - Do this :) |
245 | | -+ */ |
246 | | -+ |
247 | | -+ // Is there an invalid command redirect? |
248 | | -+ if (argumentBuilder.getRedirect() != null && commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()) == null) { |
249 | | -+ // Create the argument builder with the same values as the specified node, but with a different literal and populated children |
250 | | -+ |
251 | | -+ CommandNode<SharedSuggestionProvider> redirect = argumentBuilder.getRedirect(); |
252 | | -+ // Diff copied from LiteralCommand#createBuilder |
253 | | -+ final com.mojang.brigadier.builder.LiteralArgumentBuilder<SharedSuggestionProvider> builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName()); |
254 | | -+ builder.requires(redirect.getRequirement()); |
255 | | -+ // builder.forward(redirect.getRedirect(), redirect.getRedirectModifier(), redirect.isFork()); We don't want to migrate the forward, since it's invalid. |
256 | | -+ if (redirect.getCommand() != null) { |
257 | | -+ builder.executes(redirect.getCommand()); |
258 | | -+ } |
259 | | -+ // Diff copied from LiteralCommand#createBuilder |
260 | | -+ for (CommandNode<SharedSuggestionProvider> child : redirect.getChildren()) { |
261 | | -+ builder.then(child); |
262 | | -+ } |
263 | | -+ |
264 | | -+ argumentBuilder = builder; |
265 | | -+ } |
266 | | -+ // Paper end |
267 | 230 | argumentBuilder.requires(suggestions -> true); |
268 | 231 | if (argumentBuilder.getCommand() != null) { |
269 | 232 | - argumentBuilder.executes(commandContext -> 0); |
|
0 commit comments