Solved Unregister plugin command removing all commands of the same name

Discussion in 'Spigot Plugin Development' started by RandomHashTags, Jul 13, 2018.

  1. RandomHashTags

    Supporter

    I am unregistering some commands when they're disabled from a config, and make the command non-existent from the plugin.

    The PluginCommand is got using getCommand() method.

    Code (Java):
    private void unRegisterPluginCommand(PluginCommand cmd) {
            try {
                Object result = getPrivateField(getServer().getPluginManager(), "commandMap");
                SimpleCommandMap commandMap = (SimpleCommandMap) result;
                Object map = getPrivateField(commandMap, "knownCommands");
                HashMap<String, Command> knownCommands = (HashMap<String, Command>) map;
                knownCommands.remove(cmd.getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    I have tried removing the PluginCommand using the below, but it doesn't remove the command if executed without the "pluginname:", and if I use the above code, it removes all commands that have the same name.
    Code (Java):
    knownCommands.remove("randompackage:" + cmd.getName());
    I just want to remove the PluginCommand from the plugin, and not the whole command from all plugins.
    Any help is much appreciated!
     
  2. Its not as neat, but you could use a global bool to toggle the specific commands :)
     
  3. MiniDigger

    Supporter

    I would also call cmd.unregister(command map).

    Also, don't make reflection class every time you unregister. Save the command map and the known commands as fields.
     
  4. RandomHashTags

    Supporter

    Thanks for your help! I have solved this with some of your guy's suggestions!

    The disabled commands are added to the unregisterCommands on plugin onEnable, and then the unRegisterPluginCommands is executed.
    I've noticed this drops the TPS a few when the plugin is enabled. If you know how to optimize this, please let me know!
    Final code
    Code (Java):
    private List<PluginCommand> unregisterCommands = new ArrayList<PluginCommand>();
        private void unRegisterPluginCommands(List<PluginCommand> cmds) {
            try {
                Object result = getPrivateField(getServer().getPluginManager(), "commandMap");
                SimpleCommandMap commandMap = (SimpleCommandMap) result;
                Object map = getPrivateField(commandMap, "knownCommands");
                HashMap<String, Command> knownCommands = (HashMap<String, Command>) map;
                HashMap<String, PluginCommand> Y = new HashMap<String, PluginCommand>();
                for(int i = 0; i < knownCommands.values().size(); i++) {
                    final Command c = (Command) knownCommands.values().toArray()[i];
                    final PluginCommand pc = c instanceof PluginCommand ? (PluginCommand) c : null;
                    if(pc != null) {
                        final String C = (String) knownCommands.keySet().toArray()[i];
                        Y.put(pc.getPlugin().getName() + ":" + C, pc);
                    }
                }
                for(PluginCommand cmd : cmds) {
                    knownCommands.remove("randompackage:" + cmd.getName());
                    cmd.unregister(commandMap);
                    Y.remove("RandomPackage:" + cmd.getName());
                    boolean hasOtherCmd = false;
                    for(int i = 0; i < Y.keySet().size(); i++) {
                        final String otherCmd = (String) Y.keySet().toArray()[i];
                        if(!otherCmd.startsWith("RandomPackage:") && otherCmd.split(":")[1].equals(cmd.getName())) { // gives the last plugin that has the cmd.getName() the command priority
                            hasOtherCmd = true;
                            final PluginCommand othercmd = (PluginCommand) Y.values().toArray()[i];
                            knownCommands.replace(cmd.getName(), cmd, othercmd);
                        }
                    }
                    if(!hasOtherCmd) { // removes the command completely
                        knownCommands.remove(cmd.getName());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
    #4 RandomHashTags, Jul 13, 2018
    Last edited: Jul 13, 2018