Disable Tab Completion

Discussion in 'Plugin Development' started by Skify, Nov 12, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    Skify

    Hello, I'm trying to disable tab completion so it'll prevent it from revealing player's disguise usernames and if the actual player(s) is/are on. I currently have disabled the /<tab>, and tab completion of usernames without / in front, but when players uses tab completion with a / in front, it works... basically tab completion works on command arguments.
    Any possible way to block this?
     
  2. Offline

    FabeGabeMC

  3. Offline

    I Al Istannen

    @Skify The problem is that the tab completion of plugin commands is handled by the plugins. You can't disable that with your own plugin.
    You would need to modify the Packets send by the server and remove the tab completion this way.
     
  4. Offline

    Skify

  5. Offline

    Mrs. bwfctower

    No. This is not at all necessary.

    @Skify If no tab completer is defined, the tabComplete method in org.bukkit.command.Command will be called.
    Command#tabComplete method (open)

    Code:
    public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
            Validate.notNull(sender, "Sender cannot be null");
            Validate.notNull(args, "Arguments cannot be null");
            Validate.notNull(alias, "Alias cannot be null");
    
            if (args.length == 0) {
                return ImmutableList.of();
            }
    
            String lastWord = args[args.length - 1];
    
            Player senderPlayer = sender instanceof Player ? (Player) sender : null;
    
            ArrayList<String> matchedPlayers = new ArrayList<String>();
            for (Player player : sender.getServer().getOnlinePlayers()) {
                String name = player.getName();
                if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
                    matchedPlayers.add(name);
                }
            }
    
            Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER);
            return matchedPlayers;
        }
    As you can see, there is a check to see if the player who sent the command can see each player before iterating, so setting the disguised player to hidden will stop them from showing up in tab complete.

    tl;dr: Set the disguised player as hidden to all online players and any that join.
     
  6. Offline

    I Al Istannen

    @Mrs. bwfctower @Skify
    Yes, but many plugins define an own tab completer (via Command#setTabCompletor). This wont work for that, if they don't add support. In this case you would need to change the tab listener of every registered command or intercept the packet. If there is another method, please correct me.
     
  7. Offline

    Mrs. bwfctower

    @I Al Istannen He wants to stop players from showing up, most plugins that override the tab completer don't return a list of online players.
     
  8. Offline

    Skify

  9. Offline

    I Al Istannen

    @Skify
    The method Player#hidePlayer() hides the player from the default tab completion. If that is enough, use it. If you want to remove the player from every tab completion, you would need to intercept the Tab-Complete packet. This can easily be done with ProtocolLib and the ProtocolLib Packet wrappers for easier access to the data in the packets.
    The right wrapper would be WrapperPlayServerTabComplete. As always there are probably other ways, but I don't know any more.
     
    ferrybig likes this.
  10. Offline

    ferrybig

    The more easier way is just to patch the incorrect behaving plugin to NOT send a player on the tab list if he is hidden
     
  11. Offline

    Skify

    @I Al Istannen What does the hidePlayer() method do? Are you sure it hides players from the default tab completion only?
     
  12. Offline

    I Al Istannen

    @Skify It just looks like he isn't online. That also means you can't see him ingame or in the tablist. I don't know if chat messages are blocked, you would need to try. If your hide plugin uses the "Player#hidePlayer()" method, the normal tab completion won't show the user. Some plugins that implement a custom tab completion to suit their needs loop through all online players and don't check if the player is hidden.
     
  13. Offline

    Rebel1231

    Try this:
    Code:
    public class TAB implements Listener
    {
    
          @EventHandler
          public void onPlayerClickTab(PlayerChatTabCompleteEvent e)
          {
            e.getTabCompletions().clear();
            e.getChatMessage().charAt(0);
          }
     
Thread Status:
Not open for further replies.

Share This Page