Стартап Регистрируем команды без записи в plugin.yml

alexandrage

Старожил
Пользователь
Баллы
173
И снова немного магии рефлексии.
Регистрируем команды без записи в plugin.yml.


Создаем класс CommandRegister.
PHP:
package Example;

import java.lang.reflect.Field;
import java.util.Arrays;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;

public class CommandRegister extends Command implements PluginIdentifiableCommand {
    protected Plugin plugin;
    protected final CommandExecutor owner;
    protected final Object registeredWith;

    public CommandRegister(String[] aliases, String desc, String usage, CommandExecutor owner, Object registeredWith,
            Plugin plugin2) {
        super(aliases[0], desc, usage, Arrays.asList(aliases));
        this.owner = owner;
        this.plugin = plugin2;
        this.registeredWith = registeredWith;
    }

    @Override
    public Plugin getPlugin() {
        return this.plugin;
    }

    @Override
    public boolean execute(CommandSender sender, String label, String[] args) {
        if (!this.testPermission(sender)) {
            return true;
        }
        if (this.owner.onCommand(sender, this, label, args)) {
            return true;
        } else {
            sender.sendMessage(this.usageMessage);
            return false;
        }
    }

    public static void reg(Plugin plugin, CommandExecutor cxecutor, String[] aliases, String desc, String usage) {
        try {
            CommandRegister reg = new CommandRegister(aliases, desc, usage, cxecutor, new Object(), plugin);
            Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
            field.setAccessible(true);
            CommandMap map = (CommandMap) field.get(Bukkit.getServer());
            map.register(plugin.getDescription().getName(), reg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Регистрируем MyCommandExecutor таким вот хитрым образом.
PHP:
CommandRegister.reg(this, new MyCommandExecutor(this), new String[] { "example" }, "example", "example");
 
Последнее редактирование:
Просто если ты хочешь делать хорошую утилиту, то делай в ней всё так, чтобы было максимально удобно.
Благодаря такому классу ты просто создал команду, настроил таб, всё, больше ни о чём не думаешь!
Ну вообще то тема об регистрации через рефлексию. А как вы это примените уже вам решать.
 
Для чего в данном случае сохраняется объект, от куда... вызвали создание нового экземпляра класса команды?
PHP:
protected final Object registeredWith;
 
Для чего в данном случае сохраняется объект, от куда... вызвали создание нового экземпляра класса команды?
PHP:
protected final Object registeredWith;
Запчать от we. Для чего юзалось хз. Вам это не нужно.
 
Здравствуйте, Александр! С регистрацией команд разобрались. А не подскажете, пожалуйста, как можно совершить обратный процесс, то есть разрегистрацию команд. Ибо при выгрузке плагина зарегистрированные команды остаются.???
 
Здравствуйте, Александр! С регистрацией команд разобрались. А не подскажете, пожалуйста, как можно совершить обратный процесс, то есть разрегистрацию команд. Ибо при выгрузке плагина зарегистрированные команды остаются.???
Вот так наверное.
Код:
    public static void unregister(String name) {
        try {
            Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
            field.setAccessible(true);
            CommandMap map = (CommandMap) field.get(Bukkit.getServer());
            Field field2 = SimpleCommandMap.class.getDeclaredField("knownCommands");
            field2.setAccessible(true);
            Map<String, Command> command = (Map<String, Command>) field2.get(map);
            command.get(name).unregister(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
Нет, к сожалению команды все равно остаются ! ( Все равно, спасибо вам!!!
Не должно. Если что попробуй прям из Map<String, Command> удалить.
Код:
    public static void unregister(String name) {
        try {
            Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
            field.setAccessible(true);
            CommandMap map = (CommandMap) field.get(Bukkit.getServer());
            Field field2 = SimpleCommandMap.class.getDeclaredField("knownCommands");
            field2.setAccessible(true);
            Map<String, Command> command = (Map<String, Command>) field2.get(map);
            Command cmd = command.get(name);
            command.remove(cmd.getName());
            for(String tmp : cmd.getAliases()) {
                command.remove(tmp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
Последнее редактирование:
Я просто изменил
command.get(name).unregister(map); на
command.remove(name);
И вроде все заработало!!! Спасибо вам, Александр! И, кстати, как лайкнуть? )
 
Вопрос, а как добавить TabCompleter?

Памагити...
 
Последнее редактирование:
Вопрос, а как добавить TabCompleter?

Памагити...
Как и в обычных командах. В новых версиях игры для комплита, если регистрация идет не на запуске плагина, а позже, требуется вот такая хитрость.
Код:
    private static void syncCommands() {
        String version = Bukkit.getServer().getClass().getName().split("\\.")[3];
        try {
            Class<?> server = Class.forName("org.bukkit.craftbukkit." + version + ".CraftServer");
            Method syncCommands = server.getDeclaredMethod("syncCommands");
            syncCommands.setAccessible(true);
            syncCommands.invoke(Bukkit.getServer());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
Назад
Верх Низ