Solved TabComplete a Vanilla command (1.13+)

Discussion in 'Spigot Plugin Development' started by 469512345, Feb 10, 2020.

  1. Hi, so I'm trying to write a sudo command with full tab complete support. I have the following code in my tab complete method that handles tab completing a command.
    Code (Java):

                   Command command;//Command Instance - got from the knownCommands field in SimpleCommandMap

                    Player target;//Player being sudo'd

                    String[] commandArgs = Arrays.copyOfRange(args, 2, args.length);

                    return command.tabComplete(target, args[0], commandArgs);

     
    This works perfectly for all spigot and plugin commands, but doesn't work with Vanilla Commands (just returns an empty list). Has anyone got any idea if I'm doing something wrong for this, and if I am what I should try instead. I don't mind getting my hands dirty with reflection or anything, I just want to make this work.

    For vanilla Commands, command is a VanillaCommandWrapper (org.bukkit.craftbukkit.VERSION.command.VanillaCommandWrapper), which has a tabComplete method which seems to be populated with the necessary code to get the suggestions from Brigadier's ParseResults but I'm still always getting an empty list. As vanilla commands have the little text bar telling you extra information which isn't something supported by a simple List<String>, I'm guessing that it's handled somewhere else in the code and the method in the VanillaCommandWrapper's method is just a red-herring. I'm just not sure where this would be and if I could get any useful pointers of where to look so I can emulate this, that'd be great.

    Thanks.
     
  2. md_5

    Administrator Developer

    Strictly speaking that would be a bug
     
  3. This repo is 6 years old. Commands were completely revamped in 1.13 so this class no longer exists and the brigadier code is totally different.

    Oh nice I'll report this on the Jira.

    I've actually found a solution the issue - it's a combination of two things that need to be changed.

    The syncCommands method on CraftServer creates a new CommandDispatcher instance, but the old one given to the VanillaCommandWrapper when instantiated is what it tries to use to tabComplete. It needs to use the new CommandDispatcher instance to work for some reason.

    Also the toDispatcher method in VanillaCommandWrapper gives an initial "/" on the command. Tab completion only seems to work when there is no initial slash on this.

    With these two changes the tab complete method seems to work fine again.

    Edit: I think I was just using the tabComplete(CommandSender, String, String[]) method, when the tabComplete(CommandSender, String, String[], Location) one is the one that's defined. The Command class actually passes the second one to the first, not the other way around (which would be expected) so that's also why this doesn't work.
     
    #4 469512345, Feb 10, 2020
    Last edited: Feb 10, 2020