1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Стартап [WIP] Code Snippets - Полезные куски кода и некоторые неочевидные вещи. [+ Ликбез]

Тема в разделе "Разработка плагинов для новичков", создана пользователем OsipXD, 25 апр 2017.

  1. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Доброго времени суток.
    Чем дольше пишешь под Bukkit, тем чаще возникают одни и те же задачи и нарабатывается некая база как ты эти задачи решаешь. Поэтому мы с @Dereku решили создать эту тему, чтобы собрать всё в одно место и уменьшить количество одинаковых вопросов.

    Ликбез
    Обязательно к прочтению, если вы еще не знаете об этом.
    - Отладка плагина (Удаленная отладка)
    - Область действия зависимостей

    Инструменты
    Здесь приведен список инстументов, которые могут помочь разработчикам плагинов под Bukkit
    - Minecraft Dev: плагин для Intellij IDEA, добавляющий функционал для облегчения разработки под Minecraft, например, автогенерация EventHandler'ов, полезные рефакторинги и т.д.
    - BukkitGradle: плагин для Gradle, облегчающий создание Bukkit-плагинов с использованием Gradle.
    - Inspector: библиотека, которая позволяет автоматически отправлять отчёты об ошибках, при их возникновении, авторам плагинов.
    - EventsLogger: Bukkit-плагин, который логгирует все события и пакеты.

    Полезное
    Этот раздел постепенно будет дополняться полезными фишками​
    - Регистрируем команды без записи в plugin.yml: Вариант 1, Вариант 2
    - Работа с множественными конфигами
    - Локализация плагина
    - Работа с пакетами: ProtocolLib [EN]
    - Цветные сообщения
    - Определение версии сервера (1.12-pre6+)
    - Работа с Bukkit API 1.13
    - Класс для работы с версиями

    Нетривиальные вещи
    Здесь будут собраны те моменты, которые работают не совсем так как кажется на первый взгляд​
    - Приоритеты обработки событий
    - Порядок загрузки плагинов
    - Отмена PlayerInteractEvent
    - Открытие инвентаря игрока

    Полезные ссылки
    Plugin Snippets - Сниппеты на SpigotMC [EN]
    Подробный разбор plugin.yml [RU]
    BukkitWiki [EN, RU]
    ______________________________________________________________________
    В процессе написания...
    Е
    сли Вы видите, что нет ссылки по какой-то теме, но у Вас есть сниппет - пишите
     
    Последнее редактирование: 4 янв 2020
  2. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Рекомендации к написанию заметки или snippet'а
    Если вы хотите опубликовать snippet, то лучшим вариантом будет опубликовать его на GitHub Gist и прислать ссылку мне в ЛС, Discord, Skype, ВК или Telegram.

    Если это какая-то заметка, то, пожалуйста, добавляйте к ней заголовок, как это сделано в этом сообщении.
     
    Последнее редактирование: 16 май 2017
  3. Exception_Prototype

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

    Баллы:
    96
  4. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Приоритеты обработки событий
    В Bukkit в аннотации обработчика события можно написать его приоритет, от которого будет зависеть порядок в котором будут обработчики. Выглядит это примерно так:
    Код:
    @EventHandler(priority = EventPriority.LOW)
    public void onEvent(....) {
        // Some code...
    }
    Значения могут быть LOWEST, LOW, NORMAL (по умолчанию), HIGH, HIGHEST и MONITOR.
    На первый взгляд всё вроде понятно, но... какой бы вы думали приоритет обработается первым? Нет, не HIGHEST, и даже не MONITOR, а LOWEST. Да, события обрабатываются в порядке от LOWEST до HIGHEST. Логика такого наименования объясняется тем, что этот приоритет относится к уровню контроля обработчика над событием. То есть у приоритета HIGHEST наиболее высокий уровень контроля над событием, т.к. он больше всех остальных приоритетов влияет на конечный результат события.

    Приоритет MONITOR выполняется последним и предназначен для того чтобы следить за результатом события. Другими словами, если вам не нужно менять результат события, и нужно быть уверенным, что никакой другой плагин не отменит событие после того как вы его проверили, то это тот приоритет, который вам нужен.
    В этой этой стадии не следует влиять на результат события. Вы это можете сделать, но в таком случае это, возможно, сломает логику других плагинов (разве что вы этого и добиваетесь).

    И еще. В @EventHandler есть опция ignoreCancelled, которая тоже чрезвычайно важна.
    Она отвечает за то, будет ли метод вызываться, если событие было отменено до этого, или нет. То есть вы вы можете поймать отмененное событие и отменить его отмену :D
    Внимание! Это значение по умолчанию false, так что, если вы делаете проверку event.isCancelled(), то можете смело убирать эту проверку и выставлять флаг в true

    Источник: Event API Reference: Event priorities [EN]
     
    Последнее редактирование: 28 апр 2017
  5. xDark

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

    Баллы:
    96
    Немного про мапы и числа
    Чтобы не писать:
    map.put(..., map.get(...) + 1);
    Заменим мапу вот на такой вид:
    HashMap<...., AtomicInteger> map = new HashMap<>();
    В итоге:
    map.put(..., new AtomicInteger(начальное число, можно не писать, тогда оно будет равно нулю));
    Получить значение:
    int value = map.get(...).get();
    Прибавляем единичку:
    map.get(...).incrementAndGet();
    Полный список того, что можно сделать:
    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html
     
  6. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Порядок загрузки плагинов
    Бывают ситуации когда нужно выполнить какие-либо действия до или после загрузки другого плагина.

    Это настраивается довольно просто в файле plugin.yml. Чтобы загрузить свой плагин раньше другого, вы можете использовать атрибут loadbefore, а чтобы позже другого - depend или softpend.

    Но что если вам нужно выполнить действия до или после загрузки всех плагинов, а не какого-то определенного?
    Загрузка плагинов разделена на две стадии: загрузка (
    onLoad) и включение (onEnable). Сначала для всех плагинов выполняется первая стадия загрузки, а затем вторая. Поэтому можно использовать метод onLoad для того чтобы выполнить что-либо до включения всех плагинов. Кроме того, вы можете выполнить какой-либо код переопределив конструктор без параметров. Код в конструкторе выполнится до стадии onLoad всех плагинов, а значит
    на момент выполнения onLoad все плагины будут уже будут загружены Class Loader'ом и вы можете использовать их классы.

    Для выполнения действий после загрузки всех плагинов вы можете использовать грязный хак с планировщиком задач (task sheduler).
    Код:
    @Override
    void onEnable() {
        new BukkitRunnable() {
            @Override
            public void run() {
                getLogger().info("Этот код выполнится после включения всех плагинов");
            }
         }.runTask(this);
    }
    Если при планировании задачи не указать значение задержки, оно по умолчанию будет равно одному тику.
     
    Последнее редактирование: 15 май 2018
  7. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Настройка load о другом. Она указывает на то, что плагин должен загрузиться во время старта сервера(STARTUP) или только после того как все миры загрузились(POSTWORLD).
     
  8. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Да, я в курсе. Но когда я её тестировал на последнем билде спигота она не работала. Что с ней, что без нее плагины грузились все вместе
     
  9. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Игра слов: не загрузиться, а запуститься(enable).
     
  10. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Ок, напишу это
    Вернее нет. Удалю, пока сам не разобрался
     
  11. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Это работает по крайней мере на 1.9.4, я это использовал для добавления новых tileentity до загрузки миров, чтобы эти tileentity могли загрузиться из миров(load: STARTUP, т.к. по умолчанию POSTWORLD)
     
  12. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Да, я думаю это всё же должно работать. Ведь есть генераторы биомов и т.д.
     
  13. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Кстати, а есть ли какие-то ограничения для метода onLoad по сравнению с onEnable? Если нет, то этот параметр load действительно бесполезен.
     
  14. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Есть. На этой стадии плагин еще не загружен. Ну то есть не удастся, например зарегистрировать события или запустить шедулер (те методы Bukkit API, которые требуют передачи плагина как аргумента). Наверняка есть еще ограничения, с которыми я не сталкивался.
    ___________________________________________________________________​

    Цветные сообщения
    Для меня было сюрпризом, что многие не знают как работать с цветовыми кодами и городят огороды из String.replace'ов и т.д. Для этого предусмотрена функция:
    Код:
    ChatColor.translateAlternateColorCodes('&', message);
    Где '&' - это символ, по которому определяется цветовой код, а message это ваше сообщение, которое нужно колоризовать.

    Внимание! Использование String.replace() - неправильный способ колоризации, если интересно знать почему - читайте сообщения ниже.​
     
    Последнее редактирование: 3 авг 2020
  15. Blc_Dragon

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

    Баллы:
    76
    вот знаешь, я про эту функцию знаю, но использовал ее целых 0 раз.

    вот по такой причине:
     
  16. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    в кратце - не убедил. твой вариант [то что я хотел сказать стало бы причиной удаления этого поста]
     
  17. CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
  18. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    а вот и аргумент почему
     
  19. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Прямой пример того как не надо бенчить. А ещё replace - не прямая альтернатива translate, ибо заменит & в сообщении, даже если он используется не для цветовых кодов.
     
  20. CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Да и вообще, подобного рода тесты - далеки от нормальных, ибо не учитывается целая куча вещей. Как минимум - тест нужно проводить в уже запущенном приложении, дабы миновать подгрузку jvm и библиотеки spigot для translate метода. Ну и ещё существует "холодный старт". Надеюсь об этом тоже слышали. Также соглашусь с @Shevchik, так как метод реплейса заменяет абсолютно все '&'. Ну а по поводу того, что вы использовали метод замены колор кода из апи целых 0 раз говорит лишь о качестве написанного вами кода :)
     

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