Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Стартап [Туториал] Удобная работа с NMS на Paper/Purpur/Folia 1.17+ (paperweight)

Конечно не будет - просто зависимость ведь - но тут в целом пойдут те же инструкции, что при использовании specialsource.
Странный ход конём получается, но таким образом переносимость проектов с места на место несколько легче должна быть. Что с paperweight, что с buildtools, нам всегда необходимо проделать пару дополнительных шагов перед началом работы.
Проблема в том, что плагины без обфускации просто-напросто не запустятся на стандартных ядрах. Поэтому смысла практически не вижу - разве что отладка проекта на ремапнутом ядре, но без возможности использования на проде.

А по поводу переносимости совсем не понял. Ничего не мешает склонировать проект с paperweight - он заработает сразу из коробки, хотя и времени на процесс сборки, очевидно, уйдёт больше.

Создать новый проект и подключить paperweight, конечно, сложнее, чем просто подключить зависимость.
Но рабочая альтернатива тут только одна - использовать NMS без маппингов.

Короче говоря, я прям совсем не вижу смысла в ремапнутом NMS, если он не мапится обратно в обфу
 
Всё там мапится. Достаточно плагин нужный добавить в сборку и всё.
Код:
            <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>
2tjWqrQ.png
Hb8HaM9.png
 
Проблема в том, что плагины без обфускации просто-напросто не запустятся на стандартных ядрах. Поэтому смысла практически не вижу - разве что отладка проекта на ремапнутом ядре, но без возможности использования на проде.
Так к тому речь про specialsource и завел - он позволяет обфусцировать обратно. Ну, и выше уже скинули, как оно выглядит.
А по поводу переносимости совсем не понял. Ничего не мешает склонировать проект с paperweight - он заработает сразу из коробки, хотя и времени на процесс сборки, очевидно, уйдёт больше.

Создать новый проект и подключить paperweight, конечно, сложнее, чем просто подключить зависимость.
Про то и говорю - с сетапом обычной зависимости+плагина ты просто потратишь куда меньше времени, чем если бы заводил эту махину со сборки ядра. Как бонус - не придется пояснять другим, как собирать плагин, посылать читать документацию.
 
Обновил пост:
- Добавил спойлер для пользователей мавен со всеми предложенными ссылками и примерами
- Добавил ссылку на тестовый плагин на Groovy DSL
- Добавил информацию о настройке paperweight на Groovy DSL
- Обновил версии зависимостей

Спасибо всем за информацию
 
Пока лениво разбираться в теме глубже, но в одном из последних PR наткнулся на упоминание проекта ignite. Он позволяет создавать миксины на сервер.
Кто не в курсе - миксины это по своей сути патчи, которые применяются перед запуском сервера, только в форме jar'ника. Миксины являются одним из основных средств моддинга на Fabric (нынче кажется и в Forge имеются, но там Lex - главный разработчик Кузнецы - долго плевался на них).
В общем, если вам нужны мелкие правки ядра, возможно вам будет проще сделать мод на ignite, нежели собирать свой форк и пытаться поспевать за обновлениям Бумаги. К тому же, этими модами можно делиться, не рекомпилируя сервер вновь и вновь.
 
Пока лениво разбираться в теме глубже, но в одном из последних PR наткнулся на упоминание проекта ignite. Он позволяет создавать миксины на сервер.
Кто не в курсе - миксины это по своей сути патчи, которые применяются перед запуском сервера, только в форме jar'ника. Миксины являются одним из основных средств моддинга на Fabric (нынче кажется и в Forge имеются, но там Lex - главный разработчик Кузнецы - долго плевался на них).
В общем, если вам нужны мелкие правки ядра, возможно вам будет проще сделать мод на ignite, нежели собирать свой форк и пытаться поспевать за обновлениям Бумаги. К тому же, этими модами можно делиться, не рекомпилируя сервер вновь и вновь.
Давно об этом думал. Круто, что сделал кто-то.
Жаль, что изначально spigot и bukkit не пошли по пути патчинга. Некоторые вот свои велосипеды с патчерами изобретают
https://github.com/xenondevs/Nova/b.../nova/transformer/patch/item/WearablePatch.kt
 
Здравствуйте!

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

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

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

Для начала предлагаю вам ознакомиться с моей темой о том, что такое маппинги:
http://rubukkit.org/threads/165824/

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

Использовать будем следующие технологии:
- Среда разработки Intellij IDEA
- Система сборки Gradle (с использованием Groovy DSL или Kotlin DSL)
- Ядро Paper 1.17 или новее
- paperweight - система сборки ядра Paper и плагинов с использованием маппингов Mojang

Данная статья подходит исключительно для проектов с системой сборки Gradle. Тут вы найдёте необходимо информацию по переводу проекта с Maven на Gradle: https://docs.gradle.org/current/userguide/migrating_from_maven.html

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

Зависимость с NMS (спасибо imDaniX за наводку):
https://docs.codemc.io/faq/#what-is-the-nms-maven-repository
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>

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

Подробности можно найти тут: https://blog.jeff-media.com/nms-use-mojang-mappings-for-your-spigot-plugins/

Для применения маппинов при сборке можно использовать SpecialSource:
https://github.com/md-5/SpecialSource
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 за ссылку:
https://github.com/Alvinn8/paper-nms-maven-plugin

Внимание!
Технология работы с маппингами Mojang является достаточно новой для Paper. Я не гарантирую оперативное обновление туториала. Пожалуйста, убедитесь, что используете актуальные версии плагинов, библиотек и прочих зависимостей. Также при необходимости ознакомьтесь с официальной документацией и сообщите в этой теме об изменениях.

Приступаем.

1) Для начала необходимо перевести ваш проект на систему сборки Gradle, а все конфигурации сборщика на Groovy DSL (build.gradle) или Kotlin DSL (build.gradle.kts). По поводу перехода с Maven довольно много информации в интернете.
Если вы не знакомы с понятием "система сборки" - вам придётся изучить эту тему самостоятельно.

2) Далее нужно убедиться, что в нашем проекте используется JDK 17 или новее.
Если у вас возникнут с этим вопросы или сложности - привожу полный список мест, в которых может понадобиться указать целевые версии Java. Данный список поможет вам решить ошибки вида "java: error: release version 17 not supported".
1) В параметрах сборщика:
PHP:
compileJava {
    sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16
}
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 - это 7.6. Следить за релизами можно тут.
Версия 7+ требуется для раз для поддержки Java 17 и новее.
Версия Gradle указывается в файле /gradle/wrapper/gradle-wrapper.properties в строке distributionUrl.
Кстати, папку wrapper'а не рекомендуется добавлять в .gitignore проекта, а загружать в гит вместе со всеми исходниками.

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

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

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

Groovy DSL (мой форк, не обновляется):
https://github.com/Dymeth/paperweight-test-plugin-groovy

Kotlin DSL (регулярно обновляется):
https://github.com/PaperMC/paperweight-test-plugin

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

5) Необходимо указать репозиторий, в котором находится плагин paperweight для Gradle - делается это в файле общих параметров проекта:
PHP:
pluginManagement {
  repositories {
    gradlePluginPortal()
    maven { url 'https://repo.papermc.io/repository/maven-public/' }
  }
}
PHP:
pluginManagement {
  repositories {
    gradlePluginPortal()
    maven("https://papermc.io/repo/repository/maven-public/")
  }
}
Блок управления плагинами должен находиться выше любой другой информации в файле.

6) Затем можно подключить уже сам плагин paperweight к проекту. Делается это в блоке plugins:
PHP:
plugins {
  id('io.papermc.paperweight.userdev') version '1.3.11'
}
PHP:
plugins {
  id("io.papermc.paperweight.userdev") version "1.3.11"
}

Список версий paperweight находится тут.

Помимо этого, по желанию вы можете использовать плагин run-paper от jpenilla, позволяющий для тестирования своего плагина запускать сервер на базе Paper при помощи задач runServer и runMojangMappedServer:
PHP:
id('xyz.jpenilla.run-paper') version '2.0.0'
PHP:
id("xyz.jpenilla.run-paper") version "2.0.0"
В рамках текущей статьи это необязательный шаг.

Помимо этого, рекомендую почитать про плагины java и java-library. Я не уверен в их обязательности в данной ситуации.

После всех манипуляций блок plugins будет выглядеть примерно так:
PHP:
plugins {
  id('java-library')
  id('io.papermc.paperweight.userdev') version '1.3.11'
  id('xyz.jpenilla.run-paper') version '2.0.0'
}
PHP:
plugins {
    java
    `java-library`
    id("io.papermc.paperweight.userdev") version "1.3.11"
    id("xyz.jpenilla.run-paper") version "2.0.0"
}
Обращаю внимание, что блок plugins должен находиться в верхней части файла, выше всех остальных параметров сборки.

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

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

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

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

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

2) При использовании нескольких модулей в проекте вы, вероятно, столкнётесь с тем, что Gradle просто не позволит подключить paperweight в этих самых модулях. Насколько мне известно, это связано с недоработкой Gradle: https://github.com/gradle/gradle/issues/14697
Решение данной проблемы элементарное - достаточно удалить указание версии из дочерних модулей:
PHP:
id('io.papermc.paperweight.userdev')
PHP:
id("io.papermc.paperweight.userdev")

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

3) При обновлении на новые версии paperweight вы можете столкнуться с ошибкой
"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/7.3/md-rule

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

Есть вопросы или дополнения?
Тема открыта, не стесняйтесь

У меня возникла проблема, я не понимаю куда надо устанавливать папку с самим paperweight?
 
У меня возникла проблема, я не понимаю куда надо устанавливать папку с самим paperweight?
Какую папку? Вручную ничего не нужно делать с файлами. Всё, что требуется сделать, указано в статье
 
Какую папку? Вручную ничего не нужно делать с файлами. Всё, что требуется сделать, указано в статье
Просто при попытке билдинга вылезает ошибка
Build file 'C:\Users\makar\IdeaProjects\TESTNMS\build.gradle' line: 3
Plugin [id: 'io.papermc.paperweight.userdev', version: '1.3.11'] was not found in any of the following sources:
* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
Если потребуется могу скинуть полную ошибку, потому что там очень большое кол-во текста
 
Обновил первый пост:
- указал актуальные версии плагинов и зависимостей
- удалил необходимость указывать репозиторий плагина paperweight
- удалил рекомендацию использовать Kotlin DSL вместо Groovy DSL
- добавил упоминание Purpur и Folia

Помимо этого, актуализировал paperweight-test-plugin-groovy:
- Обновлены версии gradle-плагинов и dev-bundle зависимостей (до 1.20)
- Обновлён Gradle до 8+ (gradle-wrapper 8.1.1)
- Добавлен плагин foojay-resolver-convention, который занимается решением зависимостей JDK (для Gradle 8+)
- Удалено указание репозитория paperweight в pluginManagement, т.к. релизы перенесены в Gradle plugin portal (начиная с paperweight v1.5.1)
- Удален плагин net.minecrell.plugin-yml.bukki, добавлен классический plugin.yml, а нужные параметры устанавливаются средствами самого сборщика
- Несколько других небольших изменений

После обновления на новые версии рекомендую очистить все кэши и убедиться, что все зависимости подгружаются корректно:
gradle clean cleanCache cleanAllRunTaskCaches cleanCustomServiceCaches cleanPaperclipCache cleanAllPaperweightUserdevCaches

Информацию по Миксинам пока не стал добавлять в первый пост - корректней будет написать отдельную тему. В любом случае, спасибо ребятам за информацию.
 
Последнее редактирование:
Просто при попытке билдинга вылезает ошибка
Build file 'C:\Users\makar\IdeaProjects\TESTNMS\build.gradle' line: 3
Plugin [id: 'io.papermc.paperweight.userdev', version: '1.3.11'] was not found in any of the following sources:
* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
Если потребуется могу скинуть полную ошибку, потому что там очень большое кол-во текста
Ну, потому что нужно использовать актуальные версии зависимостей. Я не просто так дал ссылки на релизы paperweight.
Обновил сейчас статью, с последними версиями всё должно быть норм. Также обрати внимание на репы с примерами простейших плагинов
 
Ну, потому что нужно использовать актуальные версии зависимостей. Я не просто так дал ссылки на релизы paperweight.
Обновил сейчас статью, с последними версиями всё должно быть норм. Также обрати внимание на репы с примерами простейших плагинов
Большое спасибо, всё работает.
 
Добавил упоминание про настройку зависимости таски reobfJar от assemble. Странно, что никто раньше не упомянул об этой недоработке.

Всем новичкам, которые наткнулись на статью, напоминаю про необходимость использования актуальной версии paperweight и по возможности Gradle
 
Это сделано с целью избежать юридических проблем с Microsoft.
а то что пейпер в открытый доступ выложил исходники майнкрафт сервера с понятными названиями классов и методов это ничего не нарушает? странные законы в этих ваших штатах
 
а то что пейпер в открытый доступ выложил исходники майнкрафт сервера с понятными названиями классов и методов это ничего не нарушает?
Так они вроде и не делали этого? Собстна, вся эта наркомания с PaperWeight и нужна, чтобы избежать выпуска исходников на показ. Тоже самое касается и PaperClip, только там вопрос выпуска бинарников.
 
а то что пейпер в открытый доступ выложил исходники майнкрафт сервера с понятными названиями классов и методов это ничего не нарушает? странные законы в этих ваших штатах
Пейпер нигде не выкладывает исходники ванильного майнкрафт-сервера.

Выкладывает лишь патчи со собственным кодом. Пример: https://github.com/PaperMC/Paper/bl...er/0087-Add-PlayerUseUnknownEntityEvent.patch
Тут из исходного кода ванили лишь по несколько строк перед и после вставки, которые нужны для корректного выполнения этой самой вставки.

Названия классов и пакетов действительно корректные, но взяты они из маппингов, которые официально публикуются самой компанией Mojang
 
Последнее редактирование:
Начиная с версии Paper 1.20.5 больше нет необходимости использовать задачу reobfJarupload_2024-5-1_1-18-13.png
 

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

Назад
Верх