Удобная работа с NMS на Paper 1.17+ (paperweight)

Руководство Удобная работа с NMS на Paper 1.17+ (paperweight)

Поддерживаемые версии
  1. 1.17
  2. 1.18
  3. 1.19
  4. 1.20
Здравствуйте!

Сразу хочу показать вам пример кода на NMS с использованием технологии paperweight:
1636985827253.png

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

Заинтересовало? Тогда продолжаем...

Предисловие:
Использование NMS - это крайняя мера, к которой стоит прибегать только в крайнем случае. Если у какой-то функции есть апи - лучше использовать это апи.
Если же нужной вам функции в апи нет - стоит предложить её разработчикам Spigot или Paper на гитхабе данных проектов.

Для начала предлагаю вам ознакомиться с моей темой о том, что такое маппинги:
You must be logged in to see this link.

Итак, с версии 1.14 Mojang начали публиковать официальные маппинги, включающие в себя всё кроме локальных переменных методов.
На версии 1.17 мы наконец-то дождались внедрения этих маппингов в Spigot и Paper 1.17.
Настало время использовать их в полную силу!

Использовать будем следующие технологии:
- Среда разработки Intellij IDEA
- Система сборки Gradle (с использованием Groovy DSL или Kotlin DSL)
- Ядро Paper/Purpur/Folia 1.17 или новее
- You must be logged in to see this link. - система сборки ядра Paper и плагинов с использованием маппингов Mojang

Данная статья подходит исключительно для проектов с системой сборки Gradle. Тут вы найдёте необходимо информацию по переводу проекта с Maven на Gradle: You must be logged in to see this link.

Но если же вы хотите использовать Maven и дальше, то вам придётся разбираться самостоятельно. Я лишь дам наводку.

Зависимость с NMS (спасибо imDaniX за наводку):
You must be logged in to see this link.
PHP:
<dependency>
    <groupId>org.spigotmc</groupId>
    <artifactId>spigot</artifactId>
    <version>1.19.2-R0.1-SNAPSHOT</version>
    <classifier>remapped-mojang</classifier>
    <scope>provided</scope>
</dependency>

При необходимости вы можете самостоятельно добавить зависимость в локальный мавен- репозиторий, для этого используется BuildTools с флагом "--remapped".

Подробности можно найти тут: You must be logged in to see this link.

Для применения маппинов при сборке можно использовать SpecialSource:
You must be logged in to see this link.
PHP:
<plugin>
    <groupId>net.md-5</groupId>
    <artifactId>specialsource-maven-plugin</artifactId>
    <version>1.2.2</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>remap</goal>
            </goals>
            <id>remap-obf</id>
            <configuration>
                <srgIn>org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
                <reverse>true</reverse>
                <remappedDependencies>org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
                <remappedArtifactAttached>true</remappedArtifactAttached>
                <remappedClassifierName>remapped-obf</remappedClassifierName>
            </configuration>
        </execution>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>remap</goal>
            </goals>
            <id>remap-spigot</id>
            <configuration>
                <inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
                <srgIn>org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
                <remappedDependencies>org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
            </configuration>
        </execution>
    </executions>
</plugin>

Помимо этого, существует плагин, позволяющий использовать paperweight на мавене. Спасибо Huze за ссылку:
You must be logged in to see this link.

Внимание!
Я не гарантирую оперативное обновление туториала. Пожалуйста, убедитесь, что используете актуальные версии плагинов, библиотек и прочих зависимостей. Также при необходимости ознакомьтесь с официальной документацией и сообщите в этой теме об изменениях. Полноценного официального гайда по paperweight You must be logged in to see this link., но есть официальная документация репозитория:
You must be logged in to see this link.

Приступаем.

1) Для начала необходимо определиться, какую систему сборки вы хотите использовать. Paperweight поддерживает только Gradle, поэтому вы можете использовать либо Groovy DSL, либо Kotlin DSL. В статье указаны примеры для обеих систем. Если же вы не знакомы с понятием "система сборки" - вам придётся изучить эту тему самостоятельно.

2) Далее нужно убедиться, что в нашем проекте используется JDK 17 или новее.
Если у вас возникнут с этим вопросы или сложности - привожу полный список мест, в которых может понадобиться указать целевые версии Java. Данный список поможет вам решить ошибки вида "java: error: release version 17 not supported".
1) В параметрах сборщика:
PHP:
compileJava {
    sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
}
PHP:
java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

tasks.withType<JavaCompile> {
    options.release.set(17)
}
2) Project Structure > Platform Settings > SDKs
3) Project Structure > Project Settings > Project > Project SDK
4) Project Structure > Project Settings > Project > Project language level
5) Project Structure > Project Settings > Modules > Sources > Language level
6) Project Structure > Project Settings > Modules > Dependencies > Module SDK
7) Settings > Build, Execution, Deployment > Java Compiler > Project bytecode version
8) Settings > Build, Execution, Deployment > Java Compiler > Module > Target bytecode version
9) Settings > Build, Execution, Deployment > Build Tools > Gradle > Gradle JVM

3) Следующим пунктом необходимо проверить, что в нашем проекте используется Gradle 7-й версии или новее. На данный момент последняя версия Gradle - это 8.1.1. Следить за релизами можно You must be logged in to see this link..
Версия 7+ требуется для раз для поддержки Java 17 и новее, однако рекомендую придерживаться именно 8+, поэтому именно под неё указаны все куски кода.

Версия Gradle указывается в файле /gradle/wrapper/gradle-wrapper.properties в строке distributionUrl.
Кстати, папку wrapper'а не рекомендуется добавлять в .gitignore проекта, а загружать в гит вместе со всеми исходниками.

После выполнения 3-го пункта рекомендую вам убедиться, что ваш плагин корректно собирается и запускается на сервере с использованием Java 17+.

4) Последний этап подготовки. Необходимо удалить из проекта все зависимости от всех компонентов ядра: nms/craftbukkit/bukkit/spigot/paper - абсолютно всё. Не имеет значения, подключена ли зависимость из maven-репозитория или локальным jar-файлом. Это нужно для того, чтобы в дальнейшем избежать различных разногласий при работе с классами ядра и не ловить в рантайме NoClassDefFoundError, NoSuchMethodError и прочие.

Пора переходить непосредственно к подключению paperweight. Предлагаю обратить внимание на примеры:

Пример простого paper-плагина на Kotlin DSL:
You must be logged in to see this link.
Всегда актуальная версия, обновляется командой PaperMC.

Пример простого paper-плагина на Groovy DSL:
You must be logged in to see this link.
Мой форк, обновляется по мере возможностей.

Не забывайте ставить звёздочки!
Я помогу вам и разберу каждый необходимый компонент настройки.

5) Для начала подключаем Gradle-плагин paperweight к проекту. Делается это в блоке plugins в файле build.gradle (build.gradle.kts для Kotlin DSL):
PHP:
plugins {
  id("java-library")
  id("io.papermc.paperweight.userdev") version "1.5.5"
}
Блок plugins должен располагаться, как правило, в самом верху файла.

Список версий paperweight находится You must be logged in to see this link..
Указывать репозиторий плагина не требуется, поскольку релизы paperweight находятся в Gradle plugin portal, который используется по-умолчанию.

Как видно из примера, мы также подключили плагин java-library. Указывать версию у него не требуется. Данный плагин требуется для указания параметров java, для работы с задачами сборщика и другого базового функционала.

Помимо этого, по желанию вы можете использовать плагин You must be logged in to see this link., позволяющий для тестирования своего плагина запускать сервер на базе Paper при помощи задач runServer и runMojangMappedServer:
PHP:
id("xyz.jpenilla.run-paper") version "2.1.0"
В рамках текущей статьи это НЕобязательный шаг.

6) Наконец-то мы можем добавить в наш проект зависимость для подключения ядра вместе с заветным NMS с маппингами:
PHP:
dependencies {
  paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.20-R0.1-SNAPSHOT")
}
PHP:
dependencies {
  paperDevBundle("1.20-R0.1-SNAPSHOT")
}

Groovy DSL - build.gradle:
PHP:
paperweightDevelopmentBundle("dev.folia:dev-bundle:1.20-R0.1-SNAPSHOT")

Kotlin DSL - build.gradle.kts:
PHP:
paperweight.foliaDevBundle("1.20-R0.1-SNAPSHOT")
Groovy DSL - build.gradle:
PHP:
paperweightDevelopmentBundle("com.example.paperfork:dev-bundle:1.20-R0.1-SNAPSHOT")

Kotlin DSL - build.gradle.kts:
PHP:
paperweight.devBundle("com.example.paperfork", "1.20-R0.1-SNAPSHOT")

После этого не забываем обновить зависимости проекта.

Готово! На данном этапе вы уже можете писать плагин с использованием NMS с маппингами от Mojang.

Но есть несколько подводных камней, о которых вам стоит знать:

1) Плагин, собранный под одну версию ядра, не обязан работать на другой. Дело в том, что в самом ядре, которое используется на серверах, по-прежнему находится обфусцированный NMS. Фактически при сборке вашего плагина paperweight применяет к коду маппинги, чтобы привести код в обфусцированный вид. Т.е. обфускация отсутствует исключительно на этапе разработки. Это сделано с целью избежать юридических проблем с Microsoft.
Таким образом, если вы хотите добавить в свой плагин поддержку разных версий ядра - вам придётся создавать несколько модулей с разными версиями зависимостей paperweightDevelopmentBundle (для Groovy DSL) или paperDevBundle (для KotlinDSL). Но сам я не проверял, работает ли такая структура.

2) При использовании нескольких модулей в проекте вы, вероятно, столкнётесь с тем, что Gradle просто не позволит подключить paperweight в этих самых модулях. Насколько мне известно, это связано с недоработкой Gradle: You must be logged in to see this link.
Решение данной проблемы элементарное - достаточно удалить указание версии из дочерних модулей:
PHP:
id("io.papermc.paperweight.userdev")

После чего перенести указание версии плагина в скрипт сборки главного (родительского) модуля следующим образом:
PHP:
id("io.papermc.paperweight.userdev") version "1.5.5" apply false
Напоминаю, что блок plugins должен находиться в верхней части файла.

3) Ошибка "The paperweight development bundle you are attempting to use is of data version '1', but the currently running version of paperweight only supports data version '2'"
Данная проблема связана то ли с багом в Gradle, то ли в paperweight. Так или иначе, мне удалось решить её банальным удалением директории %userprofile%/.gradle/caches/<версия>/md-rule
Перед удалением рекомендую закрыть все окна IDE

На этом всё. Материал подготовлен Dymeth.

Есть вопросы или дополнения?
Добро пожаловать в You must be logged in to see this link.
Автор
Dymeth
Просмотры
6 787
Первый выпуск
Обновление
Оценка
5.00 звёзд 1 оценок

Поделиться ресурсом

Последние обновления

  1. Начиная с версии Paper 1.20.5 больше нет необходимости использовать задачу reobfJar

    Начиная с версии Paper 1.20.5 больше нет необходимости использовать задачу reobfJar
  2. Актуализировал всё

    Обновил первый пост: - указал актуальные версии плагинов и зависимостей - удалил необходимость...
  3. Больше информации по Maven и Groovy

    Обновил пост: - Добавил спойлер для пользователей мавен со всеми предложенными ссылками и...

Последние рецензии

Отличный гайд, понятно все рассказано, да и сам paperweight классная штука.
Назад
Сверху Снизу