Начало работы
Как подключить FlectonePulse API к своему проекту и написать первый рабочий код
До версии FlectonePulse 1.12.2 включительно артефакт назывался core. Начиная с 1.13.0 он называется api и содержит только публичный API проекта
В api лежат интерфейсы, модели и константы. Сама реализация находится внутри плагина, поэтому твой проект собирается только с api, а на сервере работает с настоящими объектами FlectonePulse
Через API можно
- слушать и изменять сообщения до того, как игрок их увидит
- добавлять свои MiniMessage теги в чат и любые другие сообщения
- отправлять сообщения через конвейер FlectonePulse со всем форматированием, звуками, дистанцией и прокси
- читать и менять данные игроков, наказания и настройки чата
- включать и выключать модули, регистрировать свои команды и слушателей
- синхронизировать свои данные между серверами сети
Всё API держится на трёх вещах. Внедрение зависимостей через Google Guice, события с аннотацией @Pulse и модули. Разобравшись с ними, ты сможешь работать с любой частью проекта
Зависимость
Артефакт называется net.flectone.pulse:api и лежит в Maven Central
<dependency>
<groupId>net.flectone.pulse</groupId>
<artifactId>api</artifactId>
<version>1.13.1</version> <!-- Замени на актуальную версию -->
<scope>provided</scope>
</dependency>Для snapshot версий нужен отдельный репозиторий
<repositories>
<repository>
<id>central-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
</repository>
</repositories>
<dependency>
<groupId>net.flectone.pulse</groupId>
<artifactId>api</artifactId>
<version>1.13.2-SNAPSHOT</version> <!-- Замени на актуальную версию -->
<scope>provided</scope>
</dependency>Подключай API как provided или compileOnly. Файл FlectonePulse на сервере уже содержит эти классы, и если ты положишь их ещё и в свой jar, то получишь конфликт
Adventure и Cloud приходят вместе с зависимостью, отдельно подключать их не нужно
Мягкая зависимость
Объяви FlectonePulse в описании своего плагина, чтобы он загрузился раньше
# plugin.yml
name: MyPlugin
version: 1.0.0
main: com.example.myplugin.MyPlugin
api-version: '1.13'
softdepend:
- FlectonePulseПолучение экземпляра
Всё начинается со статического метода FlectonePulseAPI.getInstance(). Он отдаёт интерфейс FlectonePulse, через который ты получаешь любой компонент проекта
import net.flectone.pulse.FlectonePulse;
import net.flectone.pulse.FlectonePulseAPI;
import net.flectone.pulse.logging.FLogger;
FlectonePulse flectonePulse = FlectonePulseAPI.getInstance();
// инжектор может быть ещё не готов, поэтому проверяем
if (flectonePulse != null && flectonePulse.isReady()) {
FLogger fLogger = flectonePulse.get(FLogger.class);
fLogger.info("Hello from FlectonePulse");
}getInstance() вернёт null, если FlectonePulse ещё не загрузился, а get() бросит InjectorNotInitializedException, если инжектор не готов
Первый пример
Плагин для Bukkit, который приписывает [Modified] к каждому сообщению
Создай класс слушателя и пометь метод аннотацией @Pulse
Верни изменённое событие через return, потому что события неизменяемы
Зарегистрируй слушателя через ListenerRegistry
package com.example.myplugin;
import net.flectone.pulse.annotation.Pulse;
import net.flectone.pulse.listener.PulseListener;
import net.flectone.pulse.model.event.Event;
import net.flectone.pulse.model.event.message.MessageFormattingEvent;
import net.flectone.pulse.model.event.message.context.MessageContext;
public class MyPulseListener implements PulseListener {
@Pulse(priority = Event.Priority.NORMAL)
public Event onMessageFormatting(MessageFormattingEvent event) {
MessageContext context = event.context();
// контекст неизменяем, поэтому создаём копию с новым текстом
return event.withContext(context.withMessage(context.message() + " [Modified]"));
}
}package com.example.myplugin;
import net.flectone.pulse.FlectonePulse;
import net.flectone.pulse.FlectonePulseAPI;
import net.flectone.pulse.platform.registry.ListenerRegistry;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
if (!Bukkit.getPluginManager().isPluginEnabled("FlectonePulse")) return;
FlectonePulse flectonePulse = FlectonePulseAPI.getInstance();
if (flectonePulse == null || !flectonePulse.isReady()) return;
ListenerRegistry listenerRegistry = flectonePulse.get(ListenerRegistry.class);
// registerPermanent переживёт /flectonepulse reload
listenerRegistry.registerPermanent(new MyPulseListener());
}
}При перезагрузке FlectonePulse удаляет все слушатели. В своих плагинах используй registerPermanent(), иначе после /flectonepulse reload слушатель перестанет работать
Что читать дальше
- Точка входа - интерфейс
FlectonePulse, жизненный цикл, получение компонентов - Система событий - аннотация
@Pulse, приоритеты, отмена и изменение событий - Справочник событий - все события и их поля
- Игроки -
FPlayer,FEntity,FPlayerService, настройки чата - Отправка сообщений -
MessageDispatcher,EventMetadata, дистанция, звуки - Форматирование -
MessagePipeline, свои теги, флаги форматирования - Модули и команды -
ModuleSimple,ModuleController, регистрация команд - Прокси - синхронизация данных между серверами
- Справочник компонентов - все сервисы, адаптеры и утилиты
- Пример плагина - готовый плагин целиком
Исходники и Javadoc публикуются вместе с артефактом, поэтому описание любого метода видно прямо в IDE