[SPIGOT-6323] Plugin Identifiable Brigadier Commands Created: 24/Jan/21 Updated: 25/Jan/21 |
|
Status: | Open |
Project: | Spigot |
Component/s: | None |
Affects Version/s: | None |
Fix Version/s: | None |
Type: | New Feature | Priority: | Minor |
Reporter: | Eoghan Spillane | Assignee: | Unassigned |
Resolution: | Unresolved | Votes: | 0 |
Labels: | None |
Attachments: |
![]() ![]() ![]() |
Version: | 2993-Spigot-5bde311-b5eb2f5 (MC: 1.16.5) (Implementing API version 1.16.5-R0.1-SNAPSHOT) |
Guidelines Read: | Yes |
Description |
Commands registered through brigadier to the CommandDispatcher are wrapped with a VanillaCommandWrapper in the Bukkit command map (CraftServer#setVanillaCommands). Injecting description, permission, aliases etc to the VanillaCommandWrapper is trivial, but it is not possible to assign it to a plugin without VanillaCommandWrapper implementing PluginIdentifiableCommand. As VanillaCommandWrapper is final this is not possible. I have managed to make a wrapper for VanillaCommandWrapper which implements PluginIdentifiableCommand and is injected into Bukkit's command map in place of the VanillaCommandWrapper. This does assign the command to my plugin, however Bukkit (CraftServer#syncCommands) creates a BukkitCommandWrapper around the custom VanillaCommandWrapper as it's no longer an instance of VanillaCommandWrapper. This means suggestions are not provided natively by brigadier, but they're the List<String> suggestions system that Bukkit uses. This causes lots of weird behaviour when using these commands, especially with suggestions in entity selectors. Would it be possible to create an interface to denote vanilla commands instead of just testing for instances of VanillaCommandWrapper? My proposed solution looks like this: package org.bukkit.command; public interface VanillaCommand { public LiteralCommandNode getNode(); } VanillaCommandWrapper then implements this interface as well as my custom wrapper. CraftServer's syncCommands can now test for an instance of this interface instead of VanillaCommandWrapper and use the getNode method to access the LiteralNode instead of the vanillaCommand field. This would allow my brigadier commands to forego BukkitCommandWrappers and as such tab complete completely natively while also being registered as belonging to my plugin in the help menu. Thanks. |
Comments |
Comment by Eoghan Spillane [ 25/Jan/21 ] |
I'm using this API to simply register commands into the Brigadier dispatcher. They have the default metadata for mojang commands which can be seen using the help command. I then want these commands to be identifiable to my plugin. (That's it basically) In order for it to tab complete natively it must have a VanillaCommandWrapper in the CommandMap. But in order for it to be identifiable to my plugin it must implement PluginIdentifiableCommand. As VanillaCommandWrapper is final these are not possible in conjunction. Native tab completion - cursor is preserved, syntax colours etc. (native Brigadier) Bukkit tab completion - cursor is not preserved. Tooltips not visible, no syntax colouring etc (BukkitCommandWrapper emulating brigadier) All I want is a way to stop spigot wrapping my commands with a BukkitCommandWrapper so that this issue doesn't happen. if(command instanceof VanillaCommandWrapper) in CraftServer#syncCommands becomes if(command instanceof VanillaCommand) and no more BukkitCommandWrapper. Developing commands with Brigadier a very easy process compared to the native bukkit methods. I understand this is 3rd party API etc so not exactly within the realm of spigot, but not providing this freedom while also not providing brigadier functionality through the bukkit/spigot API (not within the realm of spigot in my opinion either) does make utilising brigadier harder and limits the potential for what can be achieved with spigot. |
Comment by md_5 [ 24/Jan/21 ] |
Can you be a bit more specific about what you're trying to achieve using the API? |