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

Туториал Пишем простой плагин для bukkit (v1.2.5+)

Тема в разделе "Руководства, инструкции, утилиты", создана пользователем DmitriyMX, 13 июн 2012.

?

Продолжать выкладывать туториалы по написанию плагинов?

  1. Да

    158 голосов
    95,8%
  2. Нет

    7 голосов
    4,2%
  1. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    Подготовка
    Для написания своих плагинов нам понадобятся:
    Так же понадобятся базовые знания по Java. Если таковых нет, то вот ссылки по “поднятию скила”:
    Установка и настройка Eclipse

    Если вы уже знакомы с Eclipse или увас другая IDE, то пропускайте этот раздел.
    Проблем с установкой эклипса возниктуть не должно: его нужно просто распаковать в любоую папку и запустить. Сразу после этого, эклипс попросит указать, какое рабочее пространство(workspace) сейчас открыть. Это папка, в которой будут сохранятся все созданные проекты и где ее располагать – лично ваше решение. Если вам всеранво, то оставляйте все как есть. Если вдруг захотите изменить рабочее пространстро, то не переживайте: при каждом следующем запуске, эклипс сново спросит вас о рабочем пространстве. Таких пространств можно наделать сколько угодно и каждое может быть настроено по разному, под какие-то определенные цели. К примеру у меня есть 2 рабочих пространства: для написания обычных java-приложений и для написания плагинов под “ведро”. Если вдруг вам надоест это сообщение, там есть галочка «Use this as the default and do not ask again», что позволяет задать workspace по-умолчанию.

    Как только вы определитесь с выбором места и загрузится Eclipse, то мы увидим пригласительную вкладку… которую сразу же закрываем. Она нам ни к чему.

    [​IMG][​IMG]
    Теперь же мы видим рабочее пространство самого эклипса. Из всего этого, нам понадобится только следующие панели:

    • Package Explorer
      Здесь будут отображаться ваши проекты, пакеты(о них позже) и всевозможные файлы наших будующих плагинов.
    • Problems
      Этой панелькой мы будем редко пользоваться(если вообще до нее дело дойдет), но сказать о ней стоит. Здесь будут показываться ошибки, допущенные в коде, а так же предупреждающие сообщения о возможных ошибках или неточностях.
    • Outline
      Тут будет отображаться навигация непосредственно по коду открытого java исходника.
    Последние 2 описанные панели можно вообще свернуть, т.к. пользоваться ими будем редко.
    Рабочее место почти готово. Осталось только поставить еще 2 галочки в настройках.

    Переходим в меню Window -> Preferences, далее по древу General -> Editor -> Text Editors и выставляем галочку «Show line numbers», чтобы включить отображение нумерации строк. Теперь переходим в General -> Workspace и в группе «Text file encoding» выставляем кодировку UTF-8, тем самым установив кодировку по-умолчанию.
    [​IMG][​IMG]
    С установкой и настройкой покончено. Теперь поясню, как создавать новый проект для плагина. Это можно сделать одим из 3-х способов:
    • Меню File -> New -> Java Project
    • Кнопка на панели инструментов
    • Правый клик в Package Explorer
    [​IMG]
    Перед нами откроется окно New Java Project. В Project name указываем название нашему проекту.
    [​IMG]
    Нажимаем Next.
    В появившемся окне, переходим на вкладку Libraries, нажимаем кнопку Add External JARs и выбираем скаченный Bukkit API.
    [​IMG]
    Жмем Finish.
    Слева, в Package Explorer, показался наш проект с папкой src, в которой будут храниться наши исходные коды. Теперь созданим новый класс. Делается это точно так же, как и с Java Project.
    [​IMG]
    В окне New Java Class нам понадобятся только следующие графы:
    • Package
      указывается пакет, в котором будет хранится наш класс. Формат имени должен быть примерно такой: ru.dmitriymx.bukkit.tutorial.
      Если в двух словах и на пальцах, то пакеты в ява – это пространство имен(namespace) или «виртуальные папки», в которые помещаются классы. Подробнее про это можно прочитать здесь: [1], [2], [3].
    • Name
      указываем название класса (у меня это DmxFirstPlugin)
    Все остальные пункты оставляем как есть и жмем Finish.
    Вот теперь переходим непосредственно к коду.

    Пишем простой плагин
    Как только мы создали новый класс, нашему взору предстает уже готовый пустой шаблон:
    Код:
    package ru.dmitriymx.bukkit.tutorial;
     
    public class DmxFirstPlugin {
     
    }
    Пока это всего лишь пустой класс, который абсолютно бесполезен в быту. Будем это исправлять. Изменяем вот это:
    Код:
    public class DmxFirstPlugin
    на это
    Код:
    public class DmxFirstPlugin extends JavaPlugin
    Эклипс подчеркнет нам JavaPlugin, указывая на ошибку в коде. Если подвести мышь к такому подчеркнутому коду, то откроется окошко с описанием ошибки и способы ее решения. В данном случае нам нужно импортировать класс из Bukkit API, для чего выбираем пункт «Import ‘JavaPlugin’(org.bukkit.plugin.java)».
    [​IMG]
    Сразу же замечаем, как над всем нашим кодом вписалась строчка
    Код:
    import org.bukkit.plugin.java.JavaPlugin;
    Немного теоретического материала. У плагинов есть 3 основных метода: onEnable(), onDisable() и onLoad(). Первые два отвечают за включение и отключение плагина, а последний срабатывает когда плагин непосредственно подгружается в память сервера. Из этого следует, что onLoad выполняется самым первым, но сам плагин начинает работать только после вызова onEnable со стороны сервера. По выключению или перезагрузки сервера, вызывается метод onDisable.
    С “точками входа-выхода” разобрались. Давайте теперь напишем что-нибудь более-менее работоспособное. Приведем общий код класса к следующему виду:
    Код:
    package ru.dmitriymx.bukkit.tutorial;
     
    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class DmxFirstPlugin extends JavaPlugin implements Listener {
      public static final Logger _log = Logger.getLogger("Minecraft");
     
      @Override
      public void onEnable() {
          _log.info("[DMX PLG] onEnable()"); //вывод произвольного текста в консоль сервера
          Bukkit.getPluginManager().registerEvents(this, this);
      }
     
      @EventHandler
      public void onJoin(PlayerJoinEvent event){
          event.getPlayer().sendMessage(ChatColor.GREEN + "Добро подаловать на сервер, " + ChatColor.GOLD + event.getPlayer().getName());
          event.setJoinMessage(ChatColor.GRAY + "Игрок " + ChatColor.GOLD + event.getPlayer().getName() + " зашел на сервер");
      }
     
      @EventHandler
      public void onQuit(PlayerQuitEvent event){
          event.setQuitMessage("");
          getServer().broadcastMessage(ChatColor.GRAY + "Игрок " + ChatColor.GOLD + event.getPlayer().getName() + " покинул сервер");
      }
    }
    То что мы сейчас написали – готовый плагин. Все что он делает – это пишет в чат о приходе и уходе игрока на сервер. Разбираться в его работе будем по порядку(а как иначе?).
    Сперва обращу внимание на строку объявления класса. Как видно, к нашему классу добавилось расширение Listener. Не углубляясь в дебри явы, скажу проще: указывая данное расширение, мы тем самым расширяем область применения класса не только как плагина(JavaPlugin), но и как обработчика событий(Listener). А вот как раз в методе onEnable() мы регистрируем наш класс на сервере как обработчик событий(this – это указание «на самого себя», если кто забыл).
    В этом и есть координальное отличие от старой системы обработки событий, которые были мною описаны ранее. Теперь, вместо того, чтобы лепить кучу классов, и запоминатьточные названия методов событий, нам достаточно расширить класс до листенера и указать с помощью «@EventHandler», какие функции будут являтся обработчиками событий. Просто? Да не то слово как просто!!
    Далее следует 2 наших обработчика событий onJoin() и onQuit(). Первый отвечает а событие входа игрока на сервер, а второй – за уход. С помощью метода event.getPlayer().sendMessage(), мы можем отправить сообщение тому игроку, которое вызвал данное событие(в нашем случае игроку, который зашел). Статический класс ChatColor хранит в себе константы цветов для окраски. Думаю как им пользоваться уже видно из примера. Так же, оба наших обработчка оповещают других игроков на сервере о произошетших событиях, но делают это по разному. В onJoin() с помощью метода event.setJoinMessage() мы меняем привычное сообщение «Player joined the game» на любое другое. А в onQuit() мы поступили инача(в целях примера): убрали вывод сообщения о выходе и сообщаем об этом через метод getServer().broadcastMessage(), который просто посылает всем игрокам на сервере указанное сообщение.
    Дело осталось за малым: написание важного файлика plugin.yml и упаковка всего этого в jar-файл.
    plugin.yml – это файл описания плагина. В нем задается название плагина, главный класс, описание и какие комманды зарегестрировать за плагинов(об этом позже) и т.д. В нашем случае, файлик должен выглядеть так:
    Код:
    name: Dmx First Plugin
    main: ru.dmitriymx.bukkit.tutorial.DmxFirstPlugin
    description: Простой плагин с сайта dmitriymx.ru
    version: 1.0
    Ой, забфл сказать, где этот файлик должен находится. Жмем правой кнопкой мыши в PackageExplorer по папке src и через меню New выбираем File. В поле File name пишем plugin.yml и жмем Finish. В открывшемся текстовом редакторе, пишем то, что я указывал выше. Всё сохраняем и переходим к последней фазе: упаковке.
    Правый тык по папке src -> Export. В древе папок, открываем Java и выбираем JAR file и жмем Next. Из голочек оставляем только «Export generated class files and resources» и «Compress the contents of the JAR file». В поле JAR file указываем, куда будем сохранять полученный плагин. После нажатия на Finish, плагин можно класть в папку plugins, запускать сервер и проверять его работу.

    [​IMG][​IMG][​IMG]
    Видите? Это совсем просто. С практикой вы наберетесь больше опыта и сможете делать более крутые плагины, даже такие легендарные как WorldEdit и WorldGuard.

    Ссылки
    Следующая статья:
    Документация:
    Полезности:
    ________________________________________​
     
    SaMEC, DavidShabaev, zuma2 и 11 другим нравится это.
  2. Хостинг MineCraft
    <
  3. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    UPD: починил картинки/скриншоты
     
  4. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    Кстати, не стесняйтесь и пишите в комментариях вопросы, ответы на которые хотели бы увидеть в следующих уроках.
     
  5. DanteS

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

    Баллы:
    103
    Имя в Minecraft:
    JustBlah
    Отличная работа!
    Крайне полезно для новичков.
     
  6. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
  7. ensirius

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

    Баллы:
    123
    Listener в main классе это нечто.
     
  8. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    :confused: это замечание? Если да, то объясните почему
     
    Earstorm нравится это.
  9. Ission

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

    Баллы:
    173
    Skype:
    lokivava
    Когда лепишь до лесу обработчиков событий, обработчики событий одного пакета(например player или block) нужно делить события по разным классам, иначе они начинают материться и частично не работать. Также помимо этого желательно указывать приоритет обработки классов.
     
    DmitriyMX нравится это.
  10. Ission

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

    Баллы:
    173
    Skype:
    lokivava
    На счёт Вас не знаю, но с версии 1.7.3 точно был(на английском).
     
    caNek нравится это.
  11. Ission

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

    Баллы:
    173
    Skype:
    lokivava
    Я, когда первый раз писал плагин, ничего не знал о Java, были основные знания в C++(мог написать hello world и пару циклов). Первый плагин - я разобрал чужой плагин и собрал что-то нечто своё. Eclipse - до сих пор без-понятия-что-это-такое, ни с чем, кроме жвачки не ассоциируется. Далее пришлось читать статьи на bukkit'е)
     
  12. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    На счет приоритетов, то они до сих пор могут выставляться(правда, я пока не нашел им применение... да и плохо понимаю). Делается это теперь так:
    Код:
    @EventHandler(priority=EventPriority.HIGH)
    Про GitHub, то пользоваться стал им совсем не давно и только начинаю в нем разбираться. Как станет более-менее понятно, напишу статью про него (точнее связку Eclipse + EGit). Если не терпится, можете написать мне в скайп, расскажу что знаю :)

    :) Вот потому, что не было туториалов на русском, я и начал всё это писать
     
  13. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    Я не уверен, но может для таких случаев нужно использовать void registerEvent(Class<? extends Event> event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin) ?

    Код:
    void registerEvent(Class<? extends Event> event,
                    Listener listener,
                    EventPriority priority,
                    EventExecutor executor,
                    Plugin plugin)
    Регистрирует указанный исполнителем в данном классе событий
    (Registers the specified executor to the given event class)
    Параметры:
    event - Тип события для регистрации (Event type to register)
    listener - Приемник для регистрации (Listener to register)
    priority - Приоритетными для регистрации этого события в (Priority to register this event at)
    executor - EventExecutor зарегистрироваться (EventExecutor to register)
    plugin - Плагин для регистрации (Plugin to register)
    Спонсор перевода: Google Translate.
     
  14. Jers

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

    Баллы:
    153
    [​IMG]
    Сделал плагин (по туториалу) вылезла ошибка. Не ругайтесь сильно, я первый раз это делаю )
     
  15. mayor123

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

    Баллы:
    173
    В plugin.yml гл. класс правильно указан?
     
    caNek и Jers нравится это.
  16. Jers

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

    Баллы:
    153
    Код:
    package ru.jers.bukkit.welcom;
     
    import java.util.logging.Logger;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerQuitEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class wel extends JavaPlugin implements Listener {
      public static final Logger _log = Logger.getLogger("Minecraft");
     
      @Override
      public void onEnable() {
          _log.info("[DMX PLG] onEnable()");
          Bukkit.getPluginManager().registerEvents(this, this);
      }
     
      @EventHandler
      public void onJoin(PlayerJoinEvent event){
          event.getPlayer().sendMessage(ChatColor.GREEN + "Добро подаловать на сервер, " + ChatColor.GOLD + event.getPlayer().getName());
          event.setJoinMessage(ChatColor.GRAY + "Игрок " + ChatColor.GOLD + event.getPlayer().getName() + " зашел на сервер");
      }
     
      @EventHandler
      public void onQuit(PlayerQuitEvent event){
          event.setQuitMessage("");
          getServer().broadcastMessage(ChatColor.GRAY + "Игрок " + ChatColor.GOLD + event.getPlayer().getName() + " покинул сервер");
      }
    }
    Код:
    name: Wel
    main: ru.jers.bukkit.welcom
    description: Free
    version: 1.2.5
     
  17. mayor123

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

    Баллы:
    173
    Нужно:
    P.S. Чтобы указывать домен в имени пакета, нужно владеть им.
     
    DmitriyMX и Jers нравится это.
  18. Инкогнито_о

    Инкогнито_о Старожил

    Баллы:
    153
    ТС молодец!)
    Ждем новых уроков)
     
  19. Автор темы
    DmitriyMX

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

    Баллы:
    153
    Skype:
    dmn550
    Инкогнито_о и Jers нравится это.
  20. Shkrest

    Shkrest Активный участник

    Баллы:
    63
    Имя в Minecraft:
    Shkrest
    Не давно обнаружил что мой сервер использует только 1 проц а у меня их 8.Подскажите как сделать что бы были задействованы хотя бы 4 процессора?
    Прошу прощения , затыркал поиск может просто не те слова ввожу если есть тема дайте почитать.
    Буду признателен.
     
    zuma2 нравится это.
  21. mayor123

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

    Баллы:
    173
    Бакит однопоточный
     
    Jers нравится это.

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