77import com .mojang .brigadier .tree .RootCommandNode ;
88import dev .jorel .commandapi .preprocessor .RequireField ;
99import org .bukkit .command .Command ;
10- import org .bukkit .command .CommandMap ;
1110import org .bukkit .command .SimpleCommandMap ;
1211
1312import java .util .*;
13+ import java .util .function .Function ;
14+ import java .util .function .Predicate ;
1415import java .util .function .Supplier ;
1516
1617/**
1718 * Handles logic for registering commands on Spigot and old versions of Paper
1819 */
1920@ RequireField (in = SimpleCommandMap .class , name = "knownCommands" , ofType = Map .class )
2021public class SpigotCommandRegistration <Source > extends CommandRegistrationStrategy <Source > {
21- private final CommandAPIBukkit <Source > commandAPIBukkit ;
22-
2322 // References to necessary objects
2423 private final CommandDispatcher <Source > brigadierDispatcher ;
24+ private final SimpleCommandMap commandMap ;
25+
26+ // References to necessary methods
2527 private final Supplier <CommandDispatcher <Source >> getResourcesDispatcher ;
28+ private final Predicate <Command > isVanillaCommandWrapper ;
29+ private final Function <CommandNode <Source >, Command > wrapToVanillaCommandWrapper ;
30+ private final Predicate <CommandNode <Source >> isBukkitCommandWrapper ;
2631
2732 // Namespaces
2833 private final Set <String > namespacesToFix = new HashSet <>();
@@ -31,15 +36,63 @@ public class SpigotCommandRegistration<Source> extends CommandRegistrationStrate
3136 // Reflection
3237 private final SafeVarHandle <SimpleCommandMap , Map <String , Command >> commandMapKnownCommands ;
3338
34- public SpigotCommandRegistration (CommandAPIBukkit <Source > commandAPIBukkit , CommandDispatcher <Source > brigadierDispatcher , Supplier <CommandDispatcher <Source >> getResourcesDispatcher ) {
35- this .commandAPIBukkit = commandAPIBukkit ;
36-
39+ public SpigotCommandRegistration (
40+ CommandDispatcher <Source > brigadierDispatcher , SimpleCommandMap commandMap ,
41+ Supplier <CommandDispatcher <Source >> getResourcesDispatcher , Predicate <Command > isVanillaCommandWrapper ,
42+ Function <CommandNode <Source >, Command > wrapToVanillaCommandWrapper , Predicate <CommandNode <Source >> isBukkitCommandWrapper
43+ ) {
3744 this .brigadierDispatcher = brigadierDispatcher ;
45+ this .commandMap = commandMap ;
46+
3847 this .getResourcesDispatcher = getResourcesDispatcher ;
48+ this .isVanillaCommandWrapper = isVanillaCommandWrapper ;
49+ this .wrapToVanillaCommandWrapper = wrapToVanillaCommandWrapper ;
50+ this .isBukkitCommandWrapper = isBukkitCommandWrapper ;
3951
4052 this .commandMapKnownCommands = SafeVarHandle .ofOrNull (SimpleCommandMap .class , "knownCommands" , "knownCommands" , Map .class );
4153 }
4254
55+ // Provide access to internal functions that may be useful to developers
56+
57+ /**
58+ * Returns the Brigadier CommandDispatcher used when commands are sent to Players
59+ *
60+ * @return A Brigadier CommandDispatcher
61+ */
62+ public CommandDispatcher <Source > getResourcesDispatcher () {
63+ return getResourcesDispatcher .get ();
64+ }
65+
66+ /**
67+ * Checks if a Command is an instance of the OBC VanillaCommandWrapper
68+ *
69+ * @param command The Command to check
70+ * @return true if Command is an instance of VanillaCommandWrapper
71+ */
72+ public boolean isVanillaCommandWrapper (Command command ) {
73+ return isVanillaCommandWrapper .test (command );
74+ }
75+
76+ /**
77+ * Wraps a Brigadier command node as Bukkit's VanillaCommandWrapper
78+ *
79+ * @param node The LiteralCommandNode to wrap
80+ * @return A VanillaCommandWrapper representing the given node
81+ */
82+ public Command wrapToVanillaCommandWrapper (CommandNode <Source > node ) {
83+ return wrapToVanillaCommandWrapper .apply (node );
84+ }
85+
86+ /**
87+ * Checks if a Brigadier command node is being handled by Bukkit's BukkitCommandWrapper
88+ *
89+ * @param node The CommandNode to check
90+ * @return true if the CommandNode is being handled by Bukkit's BukkitCommandWrapper
91+ */
92+ public boolean isBukkitCommandWrapper (CommandNode <Source > node ) {
93+ return isBukkitCommandWrapper .test (node );
94+ }
95+
4396 // Utility methods
4497 private String unpackInternalPermissionNodeString (CommandPermission perm ) {
4598 final Optional <String > optionalPerm = perm .getPermission ();
@@ -69,7 +122,7 @@ public void runTasksAfterServerStart() {
69122 }
70123
71124 private void fixNamespaces () {
72- Map <String , Command > knownCommands = commandMapKnownCommands .get (( SimpleCommandMap ) commandAPIBukkit . getPaper (). getCommandMap () );
125+ Map <String , Command > knownCommands = commandMapKnownCommands .get (commandMap );
73126 RootCommandNode <Source > resourcesRootNode = getResourcesDispatcher .get ().getRoot ();
74127
75128 // Remove namespaces
@@ -81,7 +134,7 @@ private void fixNamespaces() {
81134 // Add back certain minecraft: namespace commands
82135 RootCommandNode <Source > brigadierRootNode = brigadierDispatcher .getRoot ();
83136 for (CommandNode <Source > node : minecraftCommandNamespaces .getChildren ()) {
84- knownCommands .put (node .getName (), commandAPIBukkit . wrapToVanillaCommandWrapper (node ));
137+ knownCommands .put (node .getName (), wrapToVanillaCommandWrapper . apply (node ));
85138 resourcesRootNode .addChild (node );
86139
87140 // VanillaCommandWrappers in the CommandMap defer to the Brigadier dispatcher when executing.
@@ -100,7 +153,6 @@ private void fixNamespaces() {
100153 */
101154 private void fixPermissions () {
102155 // Get the command map to find registered commands
103- CommandMap map = commandAPIBukkit .getPaper ().getCommandMap ();
104156 final Map <String , CommandPermission > permissionsToFix = CommandAPIHandler .getInstance ().registeredPermissions ;
105157
106158 if (!permissionsToFix .isEmpty ()) {
@@ -122,8 +174,8 @@ private void fixPermissions() {
122174 * If anyone dares tries to use testPermission() on this command, seriously,
123175 * what are you doing and why?
124176 */
125- Command command = map .getCommand (cmdName );
126- if (command != null && commandAPIBukkit . isVanillaCommandWrapper (command )) {
177+ Command command = commandMap .getCommand (cmdName );
178+ if (command != null && isVanillaCommandWrapper . test (command )) {
127179 command .setPermission (permNode );
128180 }
129181 }
@@ -142,7 +194,7 @@ public void postCommandRegistration(RegisteredCommand registeredCommand, Literal
142194 // We could probably call all those methods to sync everything up, but in the spirit of avoiding side effects
143195 // and avoiding doing things twice for existing commands, this is a distilled version of those methods.
144196
145- Map <String , Command > knownCommands = commandMapKnownCommands .get (( SimpleCommandMap ) commandAPIBukkit . getPaper (). getCommandMap () );
197+ Map <String , Command > knownCommands = commandMapKnownCommands .get (commandMap );
146198 RootCommandNode <Source > root = getResourcesDispatcher .get ().getRoot ();
147199
148200 String name = resultantNode .getLiteral ();
@@ -165,7 +217,7 @@ public void postCommandRegistration(RegisteredCommand registeredCommand, Literal
165217 // We also have to set the permission to simulate the result of `CommandAPIBukkit#fixPermissions`.
166218 RootCommandNode <Source > brigadierRootNode = brigadierDispatcher .getRoot ();
167219 for (CommandNode <Source > node : minecraftNamespacesToFix ) {
168- Command minecraftNamespaceCommand = commandAPIBukkit . wrapToVanillaCommandWrapper (node );
220+ Command minecraftNamespaceCommand = wrapToVanillaCommandWrapper . apply (node );
169221 knownCommands .put (node .getName (), minecraftNamespaceCommand );
170222 minecraftNamespaceCommand .setPermission (permNode );
171223 brigadierRootNode .addChild (node );
@@ -178,7 +230,7 @@ public void postCommandRegistration(RegisteredCommand registeredCommand, Literal
178230 private void registerCommand (Map <String , Command > knownCommands , RootCommandNode <Source > root , String name , String permNode , String namespace , LiteralCommandNode <Source > resultantNode ) {
179231 // Wrapping Brigadier nodes into VanillaCommandWrappers and putting them in the CommandMap usually happens
180232 // in `CraftServer#setVanillaCommands`
181- Command command = commandAPIBukkit . wrapToVanillaCommandWrapper (resultantNode );
233+ Command command = wrapToVanillaCommandWrapper . apply (resultantNode );
182234 knownCommands .putIfAbsent (name , command );
183235
184236 // Adding permissions to these Commands usually happens in `CommandAPIBukkit#fixPermissions`
@@ -198,7 +250,7 @@ private void registerCommand(Map<String, Command> knownCommands, RootCommandNode
198250 } else {
199251 // A custom namespace should be registered like a separate command, so that it can reference the namespaced
200252 // node, rather than the original unnamespaced node
201- Command namespacedCommand = commandAPIBukkit . wrapToVanillaCommandWrapper (namespacedNode );
253+ Command namespacedCommand = wrapToVanillaCommandWrapper . apply (namespacedNode );
202254 knownCommands .putIfAbsent (namespacedCommand .getName (), namespacedCommand );
203255 namespacedCommand .setPermission (permNode );
204256 }
@@ -273,15 +325,15 @@ public void unregister(String commandName, boolean unregisterNamespaces, boolean
273325 // We need to remove commands from Bukkit's CommandMap if we're unregistering a Bukkit command, or
274326 // if we're unregistering after the server is enabled, because `CraftServer#setVanillaCommands` will have
275327 // moved the Vanilla command into the CommandMap
276- Map <String , Command > knownCommands = commandMapKnownCommands .get (( SimpleCommandMap ) commandAPIBukkit . getPaper (). getCommandMap () );
328+ Map <String , Command > knownCommands = commandMapKnownCommands .get (commandMap );
277329
278330 // If we are unregistering a Bukkit command, DO NOT unregister VanillaCommandWrappers
279331 // If we are unregistering a Vanilla command, ONLY unregister VanillaCommandWrappers
280- boolean isMainVanilla = commandAPIBukkit . isVanillaCommandWrapper (knownCommands .get (commandName ));
332+ boolean isMainVanilla = isVanillaCommandWrapper . test (knownCommands .get (commandName ));
281333 if (unregisterBukkit ^ isMainVanilla ) knownCommands .remove (commandName );
282334
283335 if (unregisterNamespaces ) {
284- removeCommandNamespace (knownCommands , commandName , c -> unregisterBukkit ^ commandAPIBukkit . isVanillaCommandWrapper (c ));
336+ removeCommandNamespace (knownCommands , commandName , c -> unregisterBukkit ^ isVanillaCommandWrapper . test (c ));
285337 }
286338 }
287339
@@ -292,7 +344,7 @@ public void unregister(String commandName, boolean unregisterNamespaces, boolean
292344 // If we are unregistering a Bukkit command, ONLY unregister BukkitCommandWrappers
293345 // If we are unregistering a Vanilla command, DO NOT unregister BukkitCommandWrappers
294346 removeBrigadierCommands (getResourcesDispatcher .get ().getRoot (), commandName , unregisterNamespaces ,
295- c -> !unregisterBukkit ^ commandAPIBukkit . isBukkitCommandWrapper (c ));
347+ c -> !unregisterBukkit ^ isBukkitCommandWrapper . test (c ));
296348 }
297349 }
298350
0 commit comments