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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Баллы:
    46
  5. Автор темы
    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
  6. xDark

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

    Баллы:
    96
    Skype:
    ailyashevich
    Имя в Minecraft:
    xDark
    Немного про мапы и числа
    Чтобы не писать:
    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
     
  7. Автор темы
    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);
    }
    Если при планировании задачи не указать значение задержки, оно по умолчанию будет равно одному тику.
     
    Последнее редактирование: 29 апр 2017
  8. CraftCoder

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Баллы:
    96
    Skype:
    thecoolboy2070
    Имя в Minecraft:
    CoolBoy
  19. Jampire

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

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

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

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

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

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

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