Как сделать свой плагин для minecraft
Перейти к содержимому

Как сделать свой плагин для minecraft

  • автор:

[Урок][Глава 1] Учимся писать плагин для сервера

[Урок][Глава 1] Учимся писать плагин для сервера

Вводим там следующие пункты
1. name — Название вашего проекта
2. main — Название.main.Название — Будет использоваться чтобы использовать плагин на сервере
3. version — версия плагина.

[Урок][Глава 1] Учимся писать плагин для сервера [Урок][Глава 1] Учимся писать плагин для сервера

Далее мы создаем Package в файле scr и в Package создаем Class. Все файлы называть как название плагина.

[Урок][Глава 1] Учимся писать плагин для сервера

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

[Урок][Глава 1] Учимся писать плагин для сервера

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

private Logger Log — Создает лог плагина, после чего, идут сообщения в консоль.
public void onEnable () < - Данное действие при запуске консоли(сервера), будем информировать нас и включать плагин
getLogger().info(«Enabled!») — Благодаря этому, в консоль будет выводиться сообщение «Enabled», когда плагин будет включен
log.info(«MAIN LOGGER») — Включается когда запускается консоль
log.warning(«Warning») — Включается когда имеется баг
log.error(«Error») — Включается, когда идет фатальная ошибка (полностью отключается плагин)
Все это выше выводит всё в консоль
public void onDisable() < - Данное действие будет выключать всё при выключении сервера
getLogger().info(«Disabled») — Выключение плагина. Выводит сообщение в консоль

Вы наверное спросите, зачем мы пишем < и >> Несколько раз?
Дело в том, что эти скобочки, открывают взаимодействие с пабликом. Если после ввода public void onEnable() поставить Чтобы закрыть паблик, нужно ввести >. Чтобы полностью закончить код, нужно в самом конце и в самом начале строке, написать еще раз >. Это означает, что паблик и код завершены

В сегодняшнем уроке, мы научились выставлять сообщение в консоль о запуске/выключении консоли.

Если у вас есть вопросы, обращайтесь ко мне в ВК — vk.com/vovakostikov
Спасибо за просмотр новости

Как сделать свой плагин #1 Minecraft PE

Хочу сказать одно -> программирование это не простое дело и не сложно. Если вы готовы то давайте начнем.

Давайте начнем наш первый урок!

PM (PocketMine) -> обновился до новой версии API.

Новый API лучше во многом.

Вот например, чтобы сообщить в чат всем игрокам (или сделать broadcast) в старом API нужно было писать:

Теперь на много проще.

Чувствуете разницу? 😀

Создадим папку плагина (Например: mk10).

И в этой папке создадим файл plugin.yml . В этом файле впишем это:

name: ExamplePlugin #Название плагина
main: ExamplePlugin\ExamplePlugin #Тут пишим путь к классу который будет выполняться
version: 1.0 #Ну, тут версия плагина
author: keker228 #Автор плагина
api: [x.xx.x] #Версия API которая должна использоваться.
load: POSTWORLD # (STARTUP / POSTWORLD). Когда плагину загружаться, на самом старте сервера или после загрузки мира.
commands:
helloworld:
default: true #разрешаем её использовать всем. (42)

BukkitWiki

This Wiki is home to Bukkit’s documentation and regulations surrounding the Bukkit Project and it’s services. Want to help out? We would love to have you! Signup to get started!

Don’t have an account?
Advertisement

Installing Plugins/ru

Этот гайд показывает как установить базовые плагины на ваш сервер. Если вы читаете это, значит у вас уже есть работающий сервер CraftBukkit и вы обладаете элементарными знаниями работы с консолью и сервером. В противном случае, пожалуйста, посетите сначала страницу Setting up a server и сделайте всё по инструкции. Этот гайд не охватывает настройку базы данных mySQL или фала permissions, так что, если вам требуется именно это, посетите форум.

Contents

Установка плагинов
[ ]

  1. Скачайте нужный вам плагин .
  2. Скопируйте файл .jar и другие требуемые файлы в папку «plugins» в папке сервера.
  3. Запустите сервер и подождите пока он полностью загрузится.
  4. Введите stop в консоли вашего сервера, чтобы безопасно остановить его.
  5. Запустите сервер снова.
  6. Всё! Теперь ваш плагин установлен и готов к работе.
Notes [ ]

Note: Вы можете скачать плагины отсюда: список Bukkit плагинов, BukkitDev или из категории Плагины в Вики.
Note: Возможно, скачанный вами файл будет архивом (.zip, .rar, .7z) и его потребуется разархивировать используя, например, WinRar или 7zip.
Note: Все плагины хранятся в папке «plugins» в папке где вы создали ваш CraftBukkit сервер.
Note: Вполне возможно, что после запуска сервера свежеустановленный плагин создаст файл настроек в папке ВашСервер/plugins/Плагин , в таком случае, вам стоит прочесть информацию об этом плагине на его странице, дабы узнать о всех его настройках.
Note: При последующем запуске сервера проверьте консоль и лог на наличие ошибок, связанных с установленным плагином, и если таковые имеются, следует повнимательнее прочитать пост об этом плагине на форуме либо вики плагина (скорее всего ошибки будут связаны с неверной настройкой permissions или mySQL, либо с отсутствием настройки как таковой).

Обновление плагинов
[ ]

  1. Создайте в папке ВашСервер/plugins папку «update».
  2. Скачайте новую версию плагина, который хотите обновить.
  3. Вставьте в созданную папку ВашСервер/plugins/update ТОЛЬКО новый файл .jar обновляемого плагина.
  4. Перезапустите сервер, используя команду stop в консоли.
  5. Всё, теперь ваш плагин обновлён!
Notes [ ]

Note: Важно чтобы имя .jar файла в папке update совпадало с таковым файлом плагина в папке plugins .
Note: Команда reload в консоли отключит все плагины и скопирует все файлы из папки update в папку plugins, заменяя все совпадающие файлы, а потом загрузит все плагины обратно. Это лучший способ обновления, так как он не останавливает работу сервера и не мешает игрокам, а к тому же этот метод намного безопаснее, в отличие от самостоятельного копирования файлов.

Разработка собственного плагина для сервера Minecraft

Еще с детства я начал покорять бесконечные просторы Minecraft. Естественно о разработке в то время никакой речи не шло. Но с недавних пор загорелся идеей создать о свой проект серверов.

На Java до этого никогда не писал, но есть бекграунд на других языках, поэтому осталось только приспособиться. Соотвественно разработка плагинов, Bukkit и другие библиотеки вижу впервые, но посмотрев несколько туторов, стала понятна примерная концепция.

Ранее писал на таких языках как PHP, JS. В данный момент веду разработку на языке Go. Сильно привык к «гошке» и его синтаксису и в процессе написания плагина часто использовал синтаксис Go для написания логических конструкций.

Мне не сильно хотелось использовать какие-то готовые решения, ведь тогда не будет углубленных знаний, которые я получу в процессе написания кода. Хочется одновременно и поучить Java и написать что-то свое (самое главное).

В этой статье я не буду затрагивать процесс настройки окружения, установки IDE и стороннего софта.

Идея плагина

На серверах часто используются постройки, находящиеся в пустоте, например летающие лобби, острова. Такую модель постройки мы выбрали вместе с моим другом: летающие острова. Одной из проблем таких построек — Игрок может провалиться в пустоту и не выбраться.

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

Мне захотелось самому понять, как это сделать, разработать собственный плагин, а потом с удовольствием им пользоваться, поддерживать, находить баги — мое мелкое детище, как никак.

Создаем сам плагин

Назвал я плагин просто — VoidTeleport.

Первым делом создал класс для управления конфигурацией плагина.

public class Config < private static File file; private static FileConfiguration config; private static final String fileNameConfig = "config.yml"; /** * Initializes the static Config class. */ public static void init() < // Получаем инстанс нашего плагина. Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin(VoidTeleport.PluginName); if (plugin == null) < // На этом моменте что-то пошло не так, // нужно обработать и залогировать. Bukkit.getLogger().log( Level.WARNING, MessageFormat.format("Cannot get plugin ", VoidTeleport.PluginName) ); return; > file = new File(plugin.getDataFolder(), fileNameConfig); // Мы не знаем существует ли файл, поэтому пытаемся создать его. // Если файл уже есть, то выражение file.createNewFile() вернет false. try < if (file.createNewFile()) < plugin.getLogger().log( Level.INFO, MessageFormat.format("New config file with name was created", fileNameConfig) ); > > catch (IOException e) < plugin.getLogger().log(Level.SEVERE, e.toString()); return; >// На данно моменте наш конфиг пустой, // поэтому подгружаем его из файла. reload(); > /** * Getter * @return FileConfiguration */ public static FileConfiguration get() < return config; >public static void reload() < // Самый простой анмаршаллер YAML из файла. config = YamlConfiguration.loadConfiguration(file); >

Отлично! Класс для работы с конфигом уже есть, теперь нужно определиться со структурой файла config.yml . Нужно реализовать поддержку для разных миров, поэтому не придумал ничего проще, как просто указать список нужных миров.

worlds: # Наименование мира, например spawn, world, world_the_end - name: spawn # Координаты для респавна игрока при падении в пустоту spawnLocation: x: 0 y: 0 z: 0

Конфиг есть, теперь можно приступить к созданию обработчика событий. Мой выбор пал на событие EntityDamageByBlockEvent. Можно было бы и слушать событие PlayerMoveEvent, но оно случается гораздо чаще, чем триггер на получение урона. Лишняя нагрузка на сервер не нужна, поэтому стал слушать урон.

public class PlayerDamageListener implements Listener < // Хеш мапа в которой хранится наименования мира и точка телепортации. private HashMapworlds = new HashMap<>(); @EventHandler public void onPlayerDamage(EntityDamageByBlockEvent e) < if (!(e.getEntity() instanceof Player)) < // Это не игрок. return; >if (e.getCause() != EntityDamageEvent.DamageCause.VOID) < // Урон не от пустоты. return; >Player player = (Player) e.getEntity(); // Получаем мир, в котором находится Игрок. World world = player.getWorld(); // Пытаемся найти в хеш мапе значение по наименованию мира. Location spawnLocation = this.worlds.get(world.getName()); if (spawnLocation == null) < // К этому миру не действует правило телепорта. return; >// Данный код является костылем, который я быстро сообразил. // Проблема в том, что мир может быть = null. // В таком случае устанавливаем мир на тот, в котором находится игрок. if (spawnLocation.getWorld() == null) < spawnLocation.setWorld(world); >// Добрались до самого главного. // Отменяем событие, которое наносит урон игроку. e.setCancelled(true); // Отменяем сам урон от падения, // чтобы при телепортации игрок не разбился. player.setFallDistance(0); // Телепортируем игрока. player.teleport(spawnLocation); // Доабвляем анимацию из частиц при попадании на точку телепортации. Spiral.spawn(player); > @SuppressWarnings("unchecked") public void updateWorlds(@Nullable ArrayList> listWorlds) < if (listWorlds == null) < // Ну если null, так null - ничего не делаем. return; >// Очищаем мапу. this.worlds = new HashMap<>(); for (HashMap world: listWorlds) < String worldName = (String) world.get("name"); if (Objects.equals(worldName, "")) < // Тут хорошо бы залогировать, но просто скипаем. continue; >Location spawnLocation = Location.deserialize((Map) world.get("spawnLocation")); // Т.к. мир у нас не указан, поэтому получаем его. spawnLocation.setWorld(Bukkit.getWorld(worldName)); // Сохраняем в хеш мапу. this.worlds.put(worldName, spawnLocation); > > >

Тепер разберем вызов эффекта анимации при телепортации Spiral.spawn(player) . Назвал класс Spiral, потому что эффект будет в виде спирали.

Т.к. это мой первый плагин, то не стал заморачиваться с Пакетами и ProtocolLib.

Описываем анимацию в отдельном классе Spiral. Я предпочел реализовать спираль под названием Helix — достаточно простая в реализации модель. Пришлось немного вспомнить тригонометрию, но у меня получилось!

public class Spiral < public static void spawn(@NotNull Player player) < Location location = player.getLocation(); // Задаем радиут спирали. double radius = 0.5; for (double y = 0; y catch (InterruptedException e) < Bukkit.getLogger().log(Level.SEVERE, e.toString()); >> > >

Почему в коде 23? Это число является ограничением для координаты y. Т.е. по сути спираль будет подниматься вверх на y = 2.3 . Как можно заметить, при указании смещения particleLocation.add(x, y / 10, z) y делится на 10. Еще одной причиной стало то, что спираль не успевает несколько раз «обернуть» игрока.

Собираем все вместе

Наконец можем собрать наш код в единой точке и протестировать, что получилось.

public final class VoidTeleport extends JavaPlugin < public static final String PluginName = "VoidTeleport"; @Override public void onEnable() < getLogger().log(Level.INFO, "Plugin enabled!"); // Инициализируем конфиг Config.init(); // Регистрируем обработчик событий для входщего урона this.registerDamageEvent(); >@Override public void onDisable() < getLogger().log(Level.INFO, "Plugin disabled!"); >@SuppressWarnings("unchecked") private void registerDamageEvent() < // Инициализируем обработчик PlayerDamageListener damageListener = new PlayerDamageListener(); // Достаем из конфига нужные значения и обновляем хеш мапу в обработчике damageListener.updateWorlds((ArrayList>) Config.get().get("worlds")); // Регистрируем новое событие на сервере getServer().getPluginManager().registerEvents(damageListener, this); > >

Результат

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

И без указания мира в конфиге.

Можно посмотреть код этого плагина в моем репозитории Github.

Скачать можно последний релиз.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *