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

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

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

  1. AtomicInteger

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

    Баллы:
    76
    Согласен.Хоть тут и кода не много, но даже если так, мне что, пересчитывать количество символов в строке?А если строка длинная?А если их несколько?А если у меня переменная из конфига, мне что, каждый раз пересчитывать количество символов, залезать в проект, искать то место и менять ту самую циферку?Тут же всё сразу понятно, какая строка и что за число и в некоторых моментах поможет существенно упростить и код, и даже процесс разработки и поддержки этого кода.
     
  2. Dereku

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

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Не, с тобой.
     
  3. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    А так почему не работает в 1.12?
    Код:
    public static String getNmsVersion() {
            String packageName = Bukkit.getServer().getClass().getPackage().getName();
            return packageName.substring(packageName.lastIndexOf('.') + 1);
    }
    Кстати "abc".length() разве подсчитывается не при компиляции?

    А к теме с приоритетами событий, возможно, стоит добавить информацию о том, что в той же банже все выполняется в обратном порядке.

    К порядку загрузки плагинов могу добавить про static-контент :D

    Для любителей считать секунды могу посоветовать статью: https://habrahabr.ru/post/329988/
     
    Последнее редактирование: 9 июн 2017
  4. Dereku

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

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Тоже работает. По идее. Но я не искал простых путей.
     
  5. alexandrage

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

    Баллы:
    173
    Еще один из мухи слона делает. Видимо это заразно.
     
  6. Qmaks

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

    Баллы:
    173
    Имя в Minecraft:
    Qmaks
    По-моему все адекватные люди третьим способом пользуются
     
  7. Exception_Prototype

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

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

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Нужен гайд по фреймворку для создания комманд плагина при помощи аннотаций? Вроде кто-то просил.
    @Exception_Prototype, не ты ли?
     
  9. Exception_Prototype

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

    Баллы:
    96
    Нет, спасибо, я уже свой сделал, если руки дойдут - выложу)
     
  10. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Ок, будет полезно
     
  11. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Ликбез: Область действия зависимостей

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

    Всё чаще вижу, что при разработке плагинов и библиотек используют системы сборки, такие как Gradle, Maven, Ant, и это просто замечательно! Но есть одна типичная ошибка, которая напрочь убивает всю магию автоматического разрешения зависимостей, которое предоставляют эти системы сборки - все забывают про область действия зависимостей (scope в терминах Maven, configuration в Gradle).

    Приведу пример

    Вы модный, стильный, молодёжный и поэтому используете систему сборки для управления зависимостями. И вот вы решили подключить в свой плагин бибилиотеку. Всё, вроде, просто - указываете её в секции зависимостей и, вуаля, всё работает. Но когда дело дошло до сборки плагина в jar, вы захотели включить библиотеку в свой jar, чтобы пользователям не пришлось беспокоиться о её скачивании. И вот тут возникла проблема - плагин стал весить 2 МБ вместо 100 Кб как раньше, а всё потому что разработчик библиотеки использовал в качестве зависимости Bukkit API (не заботясь об области действия зависимости) и весь Bukkit API тоже включился в ваш плагин. Ситуация не из приятных, но самое смешное, что её могло бы просто не быть если бы разработчк изменил всего одно слово в файле сценария сборки.

    Maven: compile и provided

    В Maven у зависимости (dependency) есть свойство scope, которое как раз отвечает за область видимости. Всего это свойство может принимать 6 вариантов значений, но нас интересют только два: compile и provided.

    Если вы не знали о существовании опции scope или знали, но ничего в ней не указали, по умолчанию будет использовано значение "compile". Область действия compile означает, что эта зависимость будет доступна всегда, то есть и во время компиляции, и во время выполнения кода, и когда вы завтракаете хлопьями с молоком. Такие зависимости являются транзитивными, это значит, что они будут подключены и к зависимым проектам. Они, обычно, включаются в исполнимый jar.
    Но на самом деле такое поведение зависимостей при разработке плагинов нам нужно редко и чаще зависимость не надо включать в конечный jar, так как мы рассчитываем, что она будет предоставлена на этапе выполнения кода. Для таких зависимостей есть область действия provided. Такие зависимости не являются транзитивными и не включаются в jar.

    Кратко
    compile нужно использовать, когда вы подключаете api или библиотеку, которая должна являться неотъемлемой частью вашего проекта, и когда вам нужно, чтобы подключаемая зависимость была включёна в конечный jar-файл.
    provide подходит для всех остальных случаев, то есть когда вы знаете, что зависимость будет предоставлена во время работы и вам не нужно включать её в jar-файл. Это именно то, что нужно когда вы подключаете в качестве зависимости Bukkit API, Spigot API, сторонний плагин и т.п.

    По теме: Maven - Introduction to the Dependency Mechanism (EN)

    Gradle: api, implementation и compileOnly
    (если вы думаете, что можете не читать то что написано в разделе про Maven, то вы ошибаетесь :))

    В Gradle вместо термина "область действия" (scope) используется термин "конфигурация" (configuration).
    Конфигураций бывает очень много, но нас интересуют только три из них: api, implementation и compileOnly.

    api это то же самое, что compile в Maven, а compileOnly - то же самое, что provided (название compileOnly выбрано из-за того, что такая зависимость нужна только на этапе компиляции и не должна включаться в jar).
    Возникает совершенно справедливый вопрос "нафига нам знать еще про implementation?". Если объяснять хорошо и с примерами, то этот пост получится совсем уж длинным, поэтому попробую кратко. Зависимость c конфигурацией implementation как и api включается в jar, но не является транзитивной. Это сделано для того, чтобы зависимый проект не знал ничего о таких зависимостях, потому что они являются лишь частью реализации (которая может измениться), а не API. Думаю теперь стало понятно почему они называются api и implementation.

    Ксати, в примерах подключения зависимостей в Gradle, которые вы найдёте в интернете, скорее всего, не будет ни api, ни implementation, ни compileOnly, а везде будет использоваться compile. Я преднамеренно про него не рассказывал потому что эта конфигурация является deprecated и вместо неё нужно использовать implementation или api.

    Кратко
    implementation используется когда вам нужно, чтобы код подключаемой зависимости был включён в конечный jar-файл.
    api используется, когда вы подключаете api, который должен являться неотъемлемой частью вашего проекта и может быть использован зависимыми проектами.
    compileOnly подходит для всех остальных случаев, то есть когда вы знаете, что зависимость не нужно включать jar-файл. Например, Bukkit API, Spigot API, сторонний плагин и т.п.

    По теме: The Java Library Plugin - Gradle User Manual (EN)
     
    Последнее редактирование: 20 авг 2018
  12. Автор темы
    OsipXD

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

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

    Добавлены ссылки:
    - Работа с Bukkit API 1.13
     
  13. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Открытие инвентаря игрока

    С этой проблемой сталкиваются все кто пытается отловить событие открытия инвентаря игрока. Событие открытия инвентаря (InventoryOpenEvent) не работает на пользовательском инвентаре. Для серверной стороны инвентарь игрока открыт всегда, когда не открыт другой инвентарь. При этом событие InventoryCloseEvent работает (хоть на том спасибо).

    Если вы попробуете обхитрить систему и ловить пакеты в надежде засечь тот, который отвечает за открытие инвентаря, у вас тоже ничего не получится. Клиент просто не отправляет серверу никакой информации о том, когда игрок открывает инвентарь. Конечно, и инициировать открытие инвентаря тоже не выйдет.

    Что это даёт?

    Да по сути ничего хорошего. В основном это доставляет только неудобства, но всё-таки вы можете использовать тот факт, что инвентарь игрока всегда открыт. Например, вы можете положить предметы в слоты крафта (2х2) и когда игрок откроет инвентарь они будут уже лежать там. Но стоит помнить, что при выходе с сервера или при закрытии инвентаря эти предметы выпадут на землю или в инвентарь игрока. Можно пойти дальше и сделать "тихий крафт", т.к. вы не только можете класть предметы в слоты крафта, но и забирать предметы из слота результатов.

    Что делать с этой странной возможностью - решать вам.
    Код:
    // Пример помещения предмета в слот крафта
    ItemStack itemToPlace = new ItemStack(Material.DIAMOND); // Предмет, который нужно положить
    player.getOpenInventory().getTopInventory().setItem(1, itemToPlace); // 0 - слот результата, 1-4 - слоты крафта
    // Примечание: В слот результата не удастся ничего положить. Можно только забрать.
     
  14. Автор темы
    OsipXD

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

    Баллы:
    173
    Skype:
    osip.fatkullin
    Имя в Minecraft:
    OsipXD
    Класс, для парсинга и удобной работы с версиями в соответсвии с SemVer: https://gitlab.com/snippets/1757276

    Пример использования:
    Код:
    Version currentVersion = Version.parseVersion("1.0.2-SNAPSHOT");
    
    System.out.println(currentVersion.compare("1.0"));            // будет напечатано "1"
    System.out.println(currentVersion.compare("1.0.2-SNAPSHOT")); // будет напечатано "0"
    System.out.println(currentVersion.compare("1.0.3"));          // будет напечатано "-1"
    
     

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