Гайд Первый плагин на Paper: от пустого проекта до команды

CloudDelight сегодня в 12:00 0 ответов 3
#1
Для тех, кто немного знает Java и хочет написать свой первый плагин под Paper. Соберём проект на Gradle, сделаем сообщение при входе и команду /hello, запустим всё на тестовом сервере.

Что понадобится

  • JDK 21: Paper под 1.21.x работает на Java 21.
  • IntelliJ IDEA, Community хватает. Есть плагин Minecraft Development, который создаёт каркас проекта, но здесь всё руками, чтобы было видно, что где.
  • Gradle отдельно ставить не нужно, IDEA создаст проект с Gradle Wrapper.
Создайте проект Gradle с Kotlin DSL и языком Java. Структура будет такой:
Код
hello-cloud/
  settings.gradle.kts
  build.gradle.kts
  src/main/java/ru/example/hellocloud/HelloCloud.java
  src/main/java/ru/example/hellocloud/JoinListener.java
  src/main/java/ru/example/hellocloud/HelloCommand.java
  src/main/resources/plugin.yml
В settings.gradle.kts достаточно строки rootProject.name = "hello-cloud".

build.gradle.kts

Код
plugins {
    java
    id("xyz.jpenilla.run-paper") version "2.3.1"
}

group = "ru.example"
version = "1.0.0"

repositories {
    mavenCentral()
    maven("https://repo.papermc.io/repository/maven-public/")
}

dependencies {
    compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}

tasks {
    runServer {
        minecraftVersion("1.21.4")
    }
}
paper-api подключается как compileOnly: API уже есть на сервере, класть его в ваш jar не нужно. Версию API и minecraftVersion ставьте под версию своего сервера. run-paper - Gradle-плагин, который скачивает Paper и запускает тестовый сервер с вашим плагином, свежую версию run-paper смотрите в Gradle Plugin Portal.

plugin.yml

Код
name: HelloCloud
version: '1.0.0'
main: ru.example.hellocloud.HelloCloud
api-version: '1.21'
commands:
  hello:
    description: Поприветствовать игрока
    usage: /hello
    permission: hellocloud.hello
permissions:
  hellocloud.hello:
    default: true
main - полный путь к главному классу. api-version говорит серверу, под какую версию API написан плагин. Без него Paper считает плагин старым и включает режим совместимости.

Главный класс

Код
package ru.example.hellocloud;

import org.bukkit.plugin.java.JavaPlugin;

public final class HelloCloud extends JavaPlugin {

    @Override
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new JoinListener(), this);
        getCommand("hello").setExecutor(new HelloCommand());
        getLogger().info("HelloCloud включён");
    }
}
onEnable вызывается при запуске плагина, здесь регистрируются слушатель событий и обработчик команды. Имя в getCommand должно совпадать с командой из plugin.yml, иначе получите NullPointerException.

Слушатель входа

Код
package ru.example.hellocloud;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public final class JoinListener implements Listener {

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        event.joinMessage(Component.text("+ " + player.getName(), NamedTextColor.GREEN));
        if (!player.hasPlayedBefore()) {
            player.sendMessage(Component.text("Добро пожаловать! Напиши /hello", NamedTextColor.GOLD));
        }
    }
}
В Paper текст - это компоненты Adventure, а не строки с цветовыми кодами. joinMessage заменяет стандартное сообщение о входе, hasPlayedBefore отличает новичка.

Команда

Код
package ru.example.hellocloud;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public final class HelloCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage(Component.text("Команда только для игроков"));
            return true;
        }
        player.sendMessage(Component.text("Привет, " + player.getName() + "!", NamedTextColor.AQUA));
        return true;
    }
}
return true значит «команда обработана». Если вернуть false, игрок увидит строку usage из plugin.yml.

Сборка и запуск

Код
./gradlew build
./gradlew runServer
build кладёт готовый jar в build/libs, его можно копировать в plugins любого сервера. runServer запускает Paper в папке run уже с вашим плагином. Если при первом запуске сервер остановится и попросит принять EULA, поставьте eula=true в run/eula.txt и запустите снова. На Windows вместо ./gradlew пишется gradlew.bat.

Что дальше

  • Не тестируйте через /reload, перезапускайте сервер: reload оставляет в памяти старые классы и слушатели.
  • Настройки в config.yml: saveDefaultConfig() в onEnable и getConfig() для чтения.
  • В новых версиях Paper есть регистрация команд через Brigadier с подсказками аргументов, к ней стоит перейти, когда освоитесь.
Прежде чем писать плагин под задачу, проверьте, не решена ли она готовым: каталог плагинов.

Вопросы по теме — пишите ниже, ответим.

Чтобы ответить, войдите или зарегистрируйтесь.

Регистрация — минута, без подтверждения почты.

Регистрация Вход