Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Помогите Command Handler

Тема в разделе "Разработка плагинов для новичков", создана пользователем Smaylik03, 26 фев 2015.

?

Быдло код?

  1. 100%

  2. 80%

  3. 60%

  4. 40%

  5. 20%

  6. Идеал = 0%

Результаты будут видны только после голосования.
  1. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Убегал на семинар по работе, вернулся, продолжаю.
    Исключение весьма простое.
    В моём случае одна строка с throw выгоднее, чем три действия: замена всяких {DARKBLUE} на нормальные цветовые коды §1, отсылка сообщения sender-у, и return. Плюс конструкторы есть для List<String>, String[] и просто String. Я придумал, я пользуюсь, я радуюсь :)

    Пока выходит такой выкидыш:
    Код:
    public final FairyCommandExecutor commands = new FairyCommandExecutor(this);
    ...
    @Override
    public void onLoad() {
        commands.register(
            "rscp",
            new CommandHub(this),
            new FairyArgumentDesc[]
            {
                // Конструктор для регистрации субкоманды: название, обработчик, её аргументы
                new FairyArgumentDesc(
                    "user", new CommandHubUserList(this), new FairyArgumentDesc[]
                    {
                        // Конструктор с указанием только типа аргумента
                        new FairyArgumentDesc(FairyArgumentType.PLAYER).setCaption("").setRequired(true),
                    }
                ).setCaption("Player section").setHint("pex-like commands with users"),
                // Конструктор с аргументами: type, required
                new FairyArgumentDesc(FairyArgumentType.KEYWORD, false),
            });
        ...
    }
    @Override
    public void onEnable() {
        commands.onEnable();
        ...
    }
    @Override
    public void onDisable() {
        commands.onDisable();
        ...
    }
    Жозенько выглядит.
    Обработчики, тем не менее, попроще:
    Код:
    /* /rscp user <user> list (permissions|groups) */
    public class CommandHubUserList implements IFairyCommand
    {
        private final JavaPlugin plugin;
        public CommandHubUserList(BukkitPluginMain plugin)
        {
            this.plugin= plugin;
        }
        @Override
        public void execute(CommandSender sender, FairyArgument[] args) throws CommandAnswerException
        {
            switch(args[0].getKeyword()) // Я уверен, что аргумент 0 есть и его тип KEYWORD
            {
                case "permissions":
                    // DO HERE
                    break;
                case "groups":
                    // DO HERE
                    break;
                default:
                    throw new CommandAnswerException("{_LR}Only `permissions` or `groups`, please.");
            }
            // Ничуть не сложнее, чем sender.sendMessage() и потом return true!
            throw new CommandAnswerException("{_LG}Done.");
        }
    }
    
    Пока есть проблема для суб-команд: если до субкоманды были аргументы простых типов (PLAYER, INTEGER), как получить к ним доступ... В примере для продолжения работы нужно получить Player из аргумента user родительской команды CommandHub.
    И ещё ничего нет про пермишены :) Но тут тоже задумка такая, что норм.
    В общем, пока творю... =\[DOUBLEPOST=1425037665,1425035837][/DOUBLEPOST]Закоммитил текущие разработки :)
    https://github.com/.../Bukkit/Commands
    Прошу ознакомиться и остановить меня, пока не поздно (либо помочь советом).
     
    Последнее редактирование: 27 фев 2015
  2. Хостинг MineCraft
    <
  3. aceJKE

    aceJKE Старожил Пользователь

    Баллы:
    123
    Да, очень удобно, если есть очень много подкоманд
     
  4. JustBlender

    JustBlender Старожил Девелопер Пользователь

    Баллы:
    123
    Skype:
    justblender
    Имя в Minecraft:
    JustBlender
    Мда
     
  5. CraftCoder

    CraftCoder Старожил Пользователь

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Я имел в виду не удобство, а оптимальность. Я тоже для каждой команды делаю класс обработчик, но не создаю его при каждой команде, а просто регистрирую его в OnEnable.
     
  6. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    https://github.com/RuBukkit/FairyCommands/
    Решил сделать прослойку небольшой библиотечкой.
    Что хочется:
    • Чтобы аргументы, приходящие в IFairyCommand, не было необходимости проверять на количество и null.
      • Все аргументы, помеченные при регистрации как required, действительно имеются.
    • Автоматическая проверка прав с подстановками. Поясняю на примере: команда "/dothat limit abc". Первый аргумент опустим, второй является каким-то идентификатором у предполагаемого плагина. Прописываем пермишен обработчику команды в таком виде: "dothat.perm.{$1}" или "dothat.perm.{$id}". Соответсвенно, для значения аргумента "abc" перед выполнением команды произойдёт проверка CommandSender-а на пермишен "dothat.perm.abc".
    • Парсинг интервалов времени вида "1y 12 weeks 1 hour" в кол-во int секунд.
    • Тип аргумента TEXT: /dothat fuck that "and here we have long text". P.S. А сейчас это просто поделится на несколько args?
    • Автоматическая генерация справки (хотя бы выдача списка доступных команд и их правильного синтаксиса).
      • Я даже подумал, что можно сделать каждому аргументы хинт (onCover), который описывал бы его в тексте справки.
    • Субкоманды. Обработчики более глубокого уровня. Например, "/dothat kill ololonka" делает одно, а "/dothat reload" другое :)
    • Ну и само собой — простота использования.
    P.S. do that, а не dot hat.
    Помогите хотя бы составить требования в библиотечке.[DOUBLEPOST=1425043325,1425042887][/DOUBLEPOST]Вообще у ТС-а это всё есть по ссылке в первом посту :D Ну почти всё, и почти красиво. Чуть попозже попизжу код и у него.
     
    Последнее редактирование: 27 фев 2015
  7. aceJKE

    aceJKE Старожил Пользователь

    Баллы:
    123
    для настройки чего-либо такие команды приемлемы, т.к. вызываются, один раз, при настройке, делать в таких случаях оптимизацию нет необходимости, с моей точки зрения, а читабельность в разы повышается (пропорционально деоптимизации xD)
     
  8. Автор темы
    Smaylik03

    Smaylik03 Активный участник Пользователь

    Баллы:
    88
    Skype:
    Bruse_Williams
    Имя в Minecraft:
    Alex_Wells
    Вс
    Все, до корочки - есть в моем коде. И пермишены, и фиксед аргументы, и тексты в скобках, и любой парсер типа "text" или "time" создать проще некуда, в switch дописать. Справка тоже есть, и ошибки в комманде указывает если совпадают все fixed аргументы. И просто. Смысла от этой всей бредятины с выкидышами..)) Имхо.
     
  9. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Возможно, я не разобрался дрстаточно в том, что ты предложил.
    А ты плохо разрекламировал ))
    Я до пнд офф, потом подключусь к происходящему заново...
     
  10. Автор темы
    Smaylik03

    Smaylik03 Активный участник Пользователь

    Баллы:
    88
    Skype:
    Bruse_Williams
    Имя в Minecraft:
    Alex_Wells
    Ну смотри:

    Создаешь класс с командами. К каждой команде, на каждый набор фиксированых аргументов создаешь функцию.
    @CommandExecutor(
    cmd="тут команда",
    args="тут аргументы, и если ввели именно их то вызовется функция внизу",
    desc="Описание для вывода их в cmd+" help"",
    perm="пермишен")
    public void (sender, cmd, label, args) { }

    В args он возвращает уже "пофикшеные" аргументы, где " some string blablabla" уже занимает не три разные ячейки в массиве а одну, причем скобки удаляются.

    Дальше. Аргументы бывают разных типов: string, numeric, player, onplayer, location, time и тд, их можно легко добавлять/удалять/изменять. Все проверки для них тоже легко меняются. Каждый аргумент проверяется отдельно.

    Если совпали все фиксед аргументы (допустим, что нужные это "command arg1 [onplayer:hahhahaSomePlayer] arg2", а введенные это "command arg1 NicknameOfOnlinePlayerThere arg2"), но игрок hahhahaSomePlayer оффлайн (а onplayer означает, что он должен быть онлайн) то система напишет в чате, что игрок такой-то - оффлайн. И так со всеми аргументами.

    В ближайшее время сделаю код читабельным и добавлю систему не обезательных аргументов типа "--тутбуква"
     
  11. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Как ты смотришь на то, чтобы сделвть из этого куска кода минибиблиотеку, и её могли подключать все, кому она нужна?. Заготовка твоя baseplugin тоже хороша, но подходит для интеграции чуть менее, особенно в готовые плагины.
    Плюс нужно лучше задокументировать. Гоу совместно?
     
  12. ptnk

    ptnk Старожил Пользователь

    Баллы:
    173
    Столько мусора для простой работы, вы серьёзно? У меня ощущение, что человек стянул большой кусок с другого места, куски комментов как бы намекают.

    Сделать плагин, чтобы его использовали для написания плагинов? У каждого собственный путь, я лично большого удобства в данной плагине не вижу, у меня своя маленькая библиотечка для быстрого написания небольших плагинов, куча различных реализация многих вещей, начиная от простой и изящной реализации построения функционального интерфейса с действиями на основе сундуков, и заканчивая заготовкой по работе с orm.
     
  13. Автор темы
    Smaylik03

    Smaylik03 Активный участник Пользователь

    Баллы:
    88
    Skype:
    Bruse_Williams
    Имя в Minecraft:
    Alex_Wells
    Оно сейчас в таком херовом состоянии, забагованом и тд что выкладывать его смысла нет. Как доделаю, код отформатирую и тп - напишу.
     
  14. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Я веду речь не про плагин, а тоже про библиотеку. Небольшую, начиная с обработки команд и заканчивая произвольными удобными плюшками. Всё равно каждый второй пишет для себя её родную — готового материала по приватным кодовым базам уже более чем достаточно.
     
  15. Автор темы
    Smaylik03

    Smaylik03 Активный участник Пользователь

    Баллы:
    88
    Skype:
    Bruse_Williams
    Имя в Minecraft:
    Alex_Wells
    Есть идея сделать один базовый плагин, который нужен был бы для каждого написаного с ним плагина. То есть наследовать специальный класс в библиотеке, где будут все методы, включая систему сообщений (с автопереводом под язык игрока), подключение к БД (либо вообще без нее, либо MySQL либо SQLite - по выбору, с автоматическим подключением из конфига), работа с конфигами и тп.. еще парочку "статических" классов типа утилсов и тп..

    Проблема только в моем времени, и в моем "хорошем" знании Java =)
     
  16. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Твоя идея называется "сделать библиотеку". Нет никакого смысла делать всё в одном классе и затем наследовать плагин от него. Код должен быть логично структурирован. Все плюшки — понятны, но опциональны.
     
  17. Автор темы
    Smaylik03

    Smaylik03 Активный участник Пользователь

    Баллы:
    88
    Skype:
    Bruse_Williams
    Имя в Minecraft:
    Alex_Wells
    Ты не понял - в новом плагине наследовать (extend'ить) некий интерфейс BasePlugin. В нем будут методы типа getDatabase, getMessages и тп (понятное дело, что все будет не так просто).. А библиотека будет подключатся как плагин, точно так-же, как тот-же SQLibrary. В этой либе будет и хандлер комманд, и логгер, и утилсы, и работа с БД, и с конфигами/месседжами и что только не будет.. Каждый класс будет работать на main Class того самого плагина, дабы упростить код.

    То-есть эта либа это как большой хандлер всего.
     
  18. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Я всё понял, делай, посмотрим как будет получаться.
    Если просветится что-то толковое — буду помогать.
    Баланс.png
     
  19. ptnk

    ptnk Старожил Пользователь

    Баллы:
    173
    Ты не поверишь, но многие вещи делаются очень просто за минимальное количество времени и с минимальным количеством строк кода. Ты пользуешься jdbc, я пользуюсь jpa и orm, ты пользуешься читым yaml и думаешь, что он удобен, а я использую gson, т.к. его возможности по сериализации позволяют делать более простые конфиги не заморачиваясь на создание методов read/write. Ты пишешь какой-то непонятный логгер, а до тебя уже придумали log4j,slf4j и прочие, ты думаешь от куда взять хандлер комманд и как работать с рефлексией - а уменя простой и понятный код, который в понимание осилишь даже ты:
    http://pastebin.com/vimiALNw .

    Ты будешь думать об удобной основе плагинов, динамической перезагрузке плагинов, а это достигается с помощью скриптовых языков и сделано в VarScript (groovy мне нравится).

    Посему я могу сказать, что ты делаешь велосипед, в качетсве собственного развития, в качестве собственных граблей он пойдёт, а в качестве профессиональной основы для других плагинов - без обид, но гавно.
     
  20. JustBlender

    JustBlender Старожил Девелопер Пользователь

    Баллы:
    123
    Skype:
    justblender
    Имя в Minecraft:
    JustBlender
    А что тут такого сложного в абстрактном классе, который реализует CommandExecutor?
    Даже даун поймет твой код. Уж поверь.

    PS. Насчет дауна может быть получилось уже слишком, но человек понимающий основы Java сможет понять представленный выше код.
     
  21. ptnk

    ptnk Старожил Пользователь

    Баллы:
    173
    Я не про сложный код, а про манеру реализации сабкоманд, и по мне так гораздо проще и эффективнее, чем городить монстра по работе с аннотациями. Свою собственную манеру я привёл в качестве аргумента, как и другие доводы.
     

Поделиться этой страницей