Сборки серверов

СливПлатные

Сейчас онлайн

  • RimWorld
  • hllper
  • MrLavX
  • Avric_Chel
  • VANG0D123
  • grigorijvasilenko300
  • Danter45
  • WhisAlly
  • Soldi_n
  • vinhky123
  • pro_god_pro
  • LiDeRoN
  • gjgjdhdjh
  • bobobo
  • Whonde
  • Jurom4ik_nett
  • vanio5453
  • ddd_3213132
  • zylang
  • Omn1xz
  • TakumiHiji
  • Pyrexi61
  • qwqeed
  • Frenkinofficial
  • VertoZo
  • GidexPlay
  • Valkryqwees
  • Blanche
  • Krintek
  • girov555
  • Miller_00
  • don't
  • kingclutch23
  • youbileev
  • Whisky
  • VaporyGorilla5
  • nevejin
  • Anrelax
  • пкуер
  • easyder
  • GotyYE_
  • zero_0
  • KrejziBro
  • Joyyys
  • jezza
  • t0rpedv
  • gjhl1q
  • maksimw222
  • Extr1se_
  • Masterok
  • yrnero
  • rjignow
  • артур-дц
  • kal200
  • Smallston
  • dimsskiy
  • Kapybarka
  • tytytuyytty
  • Headus
  • vancorl
  • TheCatCAER
  • фнафер
  • MrGavrik
  • mrmesniy
  • FlickG870
  • homeffgg
  • Kforak152
  • Аrtemchiks
  • KabanKazah
  • Kobalew
  • VilloniHVH
  • KitaKitsune
  • skymonix

Почему мой плагин не одобряют на сайте?

  • Автор темыbobobo
  • Дата начала
bobobo
Хотел бы сегодня поговорить о говнокоде.

1780900259544

Часто разработчики создают тикеты на сайте по причине, что их опубликованный плагин даже не проходит проверку. Да, мы проверяем плагины, в том числе и код. Мы не всегда придираемся к шатким решениям, но определённый кринж сразу улетает в мусорку.

Почему мой плагин удалили?​

Описание​

Не будем говорить про оформление ресурса, хотя оно тоже важно и влияет на публикацию. Просто скажу пару слов об этом.

После публикации зайдите на страницу своего плагина и сами посмотрите на описание. Всё ли в нём понятно? Есть ли описание команд, прав, функций, методов установки и плейсхолдеров? Если всё это есть — отлично. Если нет... Ну, это уже игра в рулетку.

Скачивание​

Никаких Telegram-каналов и Discord-серверов. Если уж использовать внешнюю ссылку, то мы предпочитаем GitHub.

Код... вот где зарыта хрюшка​

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

Но дьявол кроется в мелочах, о которых многие начинающие «разработчики» даже не задумываются.

Например, как вообще работает Minecraft? В основном он работает в одном потоке. И если вы вклиниваете в этот поток свой плагин с синхронными операциями и синхронной работой с базой данных, то довольно часто будете видеть нечто подобное:

Код:
[02:04:00] [Paper Watchdog Thread/ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH  - 1.21.3-66-afb5b13 (MC: 1.21.3) ---
[02:04:00] [Paper Watchdog Thread/ERROR]: The server has not responded for 10 seconds! Creating thread dump
[02:04:00] [Paper Watchdog Thread/ERROR]: ------------------------------
[02:04:00] [Paper Watchdog Thread/ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[02:04:00] [Paper Watchdog Thread/ERROR]: ------------------------------
[02:04:00] [Paper Watchdog Thread/ERROR]: Current Thread: Server thread
[02:04:00] [Paper Watchdog Thread/ERROR]: PID: 129 | Suspended: false | Native: true | State: RUNNABLE
[02:04:00] [Paper Watchdog Thread/ERROR]: Stack:
[02:04:00] [Paper Watchdog Thread/ERROR]: java.base@21.0.5/sun.nio.ch.UnixFileDispatcherImpl.write0(Native Method)
... (и дальше куча строчек)

Не бойтесь его. Paper вам подсказывает:
«The server has not responded for 10 seconds! Creating thread dump»
Paper специально завёл watchdog-поток, который следит за главным потоком сервера. Если тот не успел сделать тик за ~10 секунд — watchdog орёт и сбрасывает дамп стека. И в 95% случаев в этом дампе светится именно твой плагин.
Если ты в этом потоке делаешь:
  • синхронный запрос в БД (Connection.createStatement().executeQuery(...))
  • синхронный HTTP-запрос
  • тяжёлую обработку файлов
  • сложные расчёты без выноса в другой поток
  • даже просто Thread.sleep() по приколу
Всё это должно выполняться асинхронно.

Что делать правильно (чтобы не было такого)​

  1. Всё тяжёлое — только асинхронно.
    • BukkitRunnable#runTaskAsynchronously
    • CompletableFuture.supplyAsync
    • В новых версиях — виртуальные потоки (Thread.startVirtualThread)
  2. Никогда не делай синхронные запросы в:
    • onEnable / onDisable
    • Listener'ах
    • CommandExecutor'ах (если не используешь setExecutor с async)
  3. Используй нормальные пулы соединений (HikariCP) + prepared statements.
  4. Если плагин маленький — хотя бы выноси работу с файлами/БД в отдельный поток.
Вы хотя бы это нейронке своей скормите перед написанием кода, чтобы она следовала этим истинам.

Я не говорю сейчас про «красивый ООП» и архитектуру в целом. Я говорю о реальных багах, которые вы сами впихиваете в код (допустили, что нейронка это вам написала), а потом удивляетесь, почему плагин не приняли или почему он убивает сервера.

Библиотеки​

Да, библиотеки тоже влияют на проверку, хоть и не так критично, как синхронный код.
Сколько уже можно повторять: читайте документацию. Вот она, специально для вас: plugin.yml | PaperMC Docs

С Paper 1.19+ (и всех современных форках) вам не нужно пихать библиотеки внутрь своего jar через maven-shade-plugin или shadowJar. Это устаревший и вредный подход.

Теперь можно просто прописать нужные библиотеки в plugin.yml, и Paper сам их скачает и подгрузит при включении плагина:
YAML:
name: MySuperPlugin
version: 1.0.0
main: com.example.plugin.Main
api-version: 1.21
libraries:
  - com.github.ben-manes.caffeine:caffeine:3.2.3
  - org.apache.commons:commons-math3:3.6.1
  - com.zaxxer:HikariCP:5.1.0

Как и откуда брать эти строчки​

  1. Идёшь на один из этих сайтов:
  2. Ищешь нужную библиотеку (например, caffeine, hikaricp, commons-lang3 и т.д.).
  3. Берёшь Maven координаты в формате:
    groupId:artifactId:version
    Примеры популярных библиотек, которые часто используют:
    БиблиотекаКоординаты для plugin.ymlКомментарий
    Caffeinecom.github.ben-manes.caffeine:caffeine:3.2.3Лучший кэш
    HikariCPcom.zaxxer:HikariCP:5.1.0Нормальный пул соединений (Вроде даже в )
    Commons Lang 3org.apache.commons:commons-lang3:3.14.0Удобные утилиты
    Commons Math 3org.apache.commons:commons-math3:3.6.1Математика
    Gsoncom.google.code.gson:gson:2.11.0Paper и так её даёт, можно не указывать
    AdventureУже встроена в Paper, не трогай

Важные моменты​

В build.gradle / pom.xml эти библиотеки должны быть как compileOnly (или provided), а не implementation. Иначе они всё равно попадут в jar.
gradle
Код:
dependencies {
    compileOnly("com.zaxxer:HikariCP:7.0.2")
}
Maven
Код:
<dependencies>
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>7.0.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
provided - и говорит что не нужно его совать в jar

Не нужно использовать shadowJar для этих библиотек — они будут подгружаться отдельно.
Размер твоего плагина сильно уменьшится.
Меньше конфликтов с другими плагинами (если у кого-то уже есть эта версия библиотеки — Paper умнее справляется).
Если библиотека уже есть в Paper (Adventure, Kyori, некоторые Guava-классы) — её не нужно прописывать.
Многие до сих пор пихают в jar по 5–10 мегабайт лишних библиотек, хотя можно было просто написать 3 строчки в plugin.yml.
Из-за этого плагин становится тяжелее, дольше загружается и чаще конфликтует.

Так что если ты используешь внешние библиотеки — переходи на libraries: в plugin.yml.

Это уже давно стандарт.
Не заставляйте нас проверять каждый раз тонны кода библиотек на... плохой код.

Хотелось бы ещё добавить вот что.​

Я понимаю, что сейчас очень многие пишут код с помощью нейросетей. Это не ок, но я не против. Но если уже просить ИИ писать плагин, то хотя бы стоит дать ему нормальный системный промпт перед началом. Иначе он напишет то, что «в среднем работает», а не то, что правильно для Minecraft.

Вот пример хорошего промпта, который можно скопировать и использовать:​

Код:
Ты — опытный разработчик Minecraft-плагинов для Paper 1.21+.

Пиши код максимально качественно и по лучшим практикам:
- Чётко соблюдай принципы ООП, разделяй ответственность между классами.
- Никогда не выполняй тяжёлые или блокирующие операции (запросы в БД, HTTP, чтение/запись файлов и т.д.) в главном потоке сервера. Всё должно быть асинхронным.
- Если используешь внешние библиотеки — подключай их через секцию `libraries` в plugin.yml[](https://docs.papermc.io/paper/dev/plugin-yml/#libraries). Не шейдь их в jar без крайней необходимости.
- Не хардкодь строки и настройки. Используй конфигурационные файлы (config.yml) и отдельный lang.yml для всех сообщений игрокам.
- Следи за потокобезопасностью. Не модифицируй коллекции без синхронизации.
- Используй правильную структуру пакетов и понятные названия классов и методов.
- Добавляй комментарии и JavaDoc там, где это действительно помогает понять код.
- Предпочитай современные подходы: CompletableFuture, виртуальные потоки (где уместно), records, pattern matching и т.д.
И после этого пишите свой ТЗ, про как на FunTime.

Такой промпт уже сильно повышает шансы, что нейросеть не напишет тебе код, который потом убьёт тикрейт или будет падать при 30+ игроках.
 
Последнее редактирование:
oleg142
Максимально апгрейдим код своего плагина.

Команда b0b0b0 масштабно слила в сеть приватные промпты для генерации плагинов.

Забираем пока не остыло
 
Последнее редактирование:
Last.Exe
Привет дорогой чат гпт сделай мне копию фантайма в одном плагине
Привет! Да конечно вот тебе вся сборка фантайма (Если ты собираешься открывать копию фантайма - тебе может прилететь Авторское Право! Имей ввиду.): Just a moment...
 
ВерхНиз