С чего начать: Обработка событий

Discussion in 'Разработка плагинов' started by fromgate, 11/1/16.

  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
Dismiss Notice
We welcome you on our site. This site is devoted to the Nukkit project and all that is connected with him. Here you can communicate, download plugins, also many other things get acquainted! Register the account right now :3
  1. fromgate

    fromgate Administrator

    Messages:
    665
    Likes Received:
    186

    Обработка событий

    1. Общая информация о событиях
    В процессе работы сервера с игроками и иными объектами происходят какие-то события: игроки перемещаются, пишут команды в чат, ломают и ставят блоки, снег выпадает на землю, криперы взрываются и т.д.
    Когда такое событие случается, сервер сообщает "заинтересованным" плагинам о том что произошло. А плагины в свою очередь могут повлиять на происходимое: запретить игроку заходить в регион, удалить рекламу из чата, запретить ломать и строить в заприваченной, очистить снег, а крипера превратить в котёнка.
    Ну а если отбросить лирику, то можно сказать, что обработка событий — это важнейшая часть в плагиностроении и практически любой плагин в той или иной степени связан с обработкой тех или иных событий.

    Перечень событий, на текущий момент времени лучше всего смотреть прямо на гитхабе. Ну а сам процесс обработки событий реализуется следующим образом:

    1. Плагин "изъявляет" желание обрабатывать какое-то либо событие и для этого регистрирует на обработчик события. Для создагния обработчика можно использовать как независимый клас (их у плагина может быть неограниченное количество) так и сам класс плагина.
    2. В обработчике описываются методы занимающиеся непосредственно обработкой событий. Эти методы собственно и занимаются обработкой события.
    В качестве примера добавим в наш плагин FirstPlugin возможность вывода игроку новости, которая определена в настройках плагина.

    2. Создание обработчика

    Создаем класс обработчика или слушателя событий. Можно конечно использовать класс FirstPlugin, но я предпочитаю всегда выполнять обработку событий в выделенном классе.
    Для этого в пакете создадим новый класс

    01.png

    И назовём его FirstListener

    02.png

    Чтобы превратить этот класс в класс обработчика событий, надо дописать после названия класса "implements Listener"

    03.png

    3. Регистрация слушателя событий
    Итак, класс слушателя создано. Несмотря на то, что он пустой, его уже можно регистрировать. Сделаем это прямо сейчас, чтобы не забыть.

    Для этого в классе плагина добавим строчку регистрирующую плагин, сразу после работы подрузки файла конфигурации.

    Code:
      this.getServer().getPluginManager().registerEvents(new FirstListener(),this);
    04.png

    Всё, обработчик зарегистрирован.

    Кстати, хочу обратить внимание на один момент. Я создаю объект слушателя событий, сразу при вызове метода registerEvents. Часто создается отдельный объект в классе плагина, который используется в качестве параметра. Смысл в этом есть только в одно случае — если Вам нужно обращаться к классу обработчика из других классов плагина и как-то его использовать. В большинстве случаев этого делать не нужно, поэтому мы будем экономны и не будем выдять строчу кода под объявление объекта, которым никогда не воспользуемся.

    4. Создаем метод обрабатывающий событие
    Чтобы реализовать обработку какого-то события, нужно добавить метод, обрабатывающий событие в класс слушателя.

    Создадим пустой (пока) метод:
    Code:
     public void onPlayerJoin (PlayerJoinEvent event){
    }
    Это метод, несмотря на то, что у него параметром для выполнения является объект-событие, не будет вызываться при обработке события.
    Для того, чтобы сервер понял, что этот метод нужно использовать для обработки события нужно перед объявлением метода добавить аннтоацию EvenHandler.
    Code:
     @EventHandler (ignoreCancelled = true, priority = EventPriority.NORMAL)
    public void onPlayerJoin (PlayerJoinEvent event){
    }
    Вообще, можно просто поставить @EventHandler и он будет работать. Однако, я предпочитаю всегда задавать параметры конкретно.
    "ignoreCancelled = true" — означает, что если это событие отменено каким-то плагином, то наш метод уже не будет выполняться.
    "EventPriority.NORMAL" — указывает на приоритет обработки, т.е. на порядок. Обработчики с малым приоритетом (LOW, LOWEST) выполняются первыми. А с большим (HIGH, HIGHER, MONITOR) - последними. В 99% случаев досточно нормально порядка обработки событий — ставьте NORMAL.

    Теперь добавим к нашему обработчику вывод сообщения, которое хранится в конфиге.

    5. Обращение к методам и переменным плагина из другого класса

    При обработке события нам надо вывести игру сообщение, которое хранится в переменной в основном классе плагина. Чтобы получить возможность обращаться к методам плагина, нужно добавить в класс FirstPlugin метод getPlugin() который будет возвращать объект плагина.

    Для этого, созданим статическую переменную plugin в классе FirstPlugin, которую и будет возвращать метод getPlugin():
    Code:
     private static FirstPlugin plugin;
    А инициализироваться эта переменная будет в методом onEnable()
    Code:
     plugin = this;
    И, соответственно, метод getPlugin() будет выглядеть так:
    Code:
     public static FirstPlugin getPlugin(){
    return plugin;
    }
    05.png

    6. Реализуем вывод сообщения игроку
    Вернёмся к классу слушателя.
    Сообщение будем выводить в формате: "[News] Текст сообщения". При этом было бы хорошо, если бы сообщение было цветным, а цвет текста сообщений можно было бы задавать в конфиге.

    Code:
     @EventHandler (ignoreCancelled = true, priority = EventPriority.NORMAL)
    public void onPlayerJoin (PlayerJoinEvent event){
    event.getPlayer().sendMessage(TextFormat.colorize("&3[NEWS] &b"+FirstPlugin.getPlugin().helloMessage));
    }
    Ну и думаю, можно удалить вывод этого сообщения в log-файл сервера. Помните в onEnable() — удаляем его оттуда.

    06.png

    Модфицируем сообщение в файле config.yml (не забудьте удалить старый из папки плагина или внести в него такие же изменения):

    Code:
    # Пример файла конфигурации
    #
    
    [size=7]параметр: hello-message - содержит сообщение, которое будет выводиться[/size]
    [size=7]при старте сервера[/size]
    #
    hello-message: '&6На сервере установлен плагин &4FirstPlugin&6!'
    Кстати, хочу обратить внимание. Использование ряда специальных символов в файлах YAML может приводить к тому, что строки не могут бысть считаны. В данном случае строка начинающаяся на символ "&", что может привести к ошибки при чтении файла конфигурации. Чтобы этого не произошло — просто обрамляйте текст кавычками.

    7. Компилируем и смотрим результат
    Жмём Ctrl+F9, запускаем сервер и заходим

    07.png
     
    Last edited: 12/1/16
    j0sky and DevID like this.
  2. Doomhawk

    Doomhawk Developer

    Messages:
    114
    Likes Received:
    26
    Это не случайность, что обработчики с приоритетом HIGH (С высоким приоритетом) выполняются после LOW (С низким приоритетом)? По-логике все должно быть наоборот: обработчики с высоким приоритетом должны выполняться первыми.
     
  3. fromgate

    fromgate Administrator

    Messages:
    665
    Likes Received:
    186
    Нет, тут другая логика - логика "не кто раньше, у того приоритет выше". А "кто ставит последнюю точку - у того приоритет выше".

    Т.е. к примеру, Вы отменяете событие в обработчике с приоритетом LOW, а другой плагин в обработчике с приоритетом HIGH это событие обратно восстанавливает.

    Или Вы в событие PlayerMoveEvent с приоритетом NORMAL меняете координаты на одни, а другой плагин с приоритетом HIGHEST их корректирует ещё куда-то.

    Главное понимать, что и зачем ты делаешь и не клепать все обработчики с приритетом HIGH, HIGHEST и уж тем более MONITOR.
     
    Last edited: 1/4/16
    Tee7even likes this.

Share This Page