Система событий
Механизм событий FlectonePulse для связи модулей. Регистрация слушателей через ListenerRegistry и аннотацию @Pulse
Общая архитектура
FlectonePulse предоставляет механизм событий для взаимодействия между модулями и реагирования на действия игроков, сообщения и жизненный цикл проекта. Все события наследуются от базового класса Event и поддерживают механизм отмены (cancelled). Каждый Event является неизменяемым объектом, поэтому при внесении нового параметра создаётся новый объект, это нужно учитывать при обновлении ивента
| Компонент | Назначение |
|---|---|
EventDispatcher | Маршрутизация событий всем слушателям с учётом приоритета |
ListenerRegistry | Управление регистрацией и удалением слушателей |
@Pulse | Аннотация для объявления метода-обработчика |
PulseListener | Интерфейс-маркер для классов, содержащих обработчики |
Приоритеты обработки
EventDispatcher использует шесть уровней приоритета, определяющих порядок выполнения слушателей.
| Приоритет | Порядок | Типичное применение |
|---|---|---|
LOWEST | Первый | Ранняя отмена события или предварительная обработка |
LOW | Второй | Валидация данных |
NORMAL | Третий | Стандартная обработка события |
HIGH | Четвёртый | Пост-обработка |
HIGHEST | Пятый | Финальные модификации |
MONITOR | Последний | Только для логирования |
Также есть параметр ignoreCancelled и если он true, обработчик будет вызван, даже если событие уже отмечено (по умолчанию false)
Регистрация обработчиков событий
Для создания слушателя необходимо
Реализовать интерфейс PulseListener (маркер)
Внутри класса объявить публичные методы, помеченные аннотацией @Pulse, с одним параметром — типом нужного события
Зарегистрировать экземпляр слушателя через ListenerRegistry (обычно через DI, но можно и обычный объект)
import net.flectone.pulse.listener.PulseListener;
import net.flectone.pulse.model.event.Event;
import net.flectone.pulse.model.event.Pulse;
public class MyCustomListener implements PulseListener {
// Если ивент изменяется, его обязательно нужно вернуть через return
@Pulse(priority = Event.Priority.NORMAL)
public Event onMessagePrepare(MessagePrepareEvent event) {
MessageContext messageContext = event.context();
// Изменяем содержимое сообщения во время форматирования
String modifiedMessage = messageContext.getMessage() + " [Modified]";
return event.withContext(messageContext.withMessage(modifiedMessage));
}
// ignoreCancelled = true означает, что метод будет вызван, даже если событие отменено
@Pulse(priority = Event.Priority.LOWEST, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
// Получаем айпи игрока при входе
String playerIp = event.player().ip();
}
}Регистрация слушателя:
// Где-то в модуле или сервисе
private ListenerRegistry listenerRegistry;
public void init() {
listenerRegistry.register(new MyCustomListener());
}При перезагрузке FlectonePulse удаляет все слушатели и регистрирует их снова. Чтобы навсегда зарегистрировать слушатель, используй метод listenerRegistry.registerPermanent(listener);
Типы событий
Базовый класс
Все события наследуются от базового класса Event, который поддерживает отмену. События могут быть отмечены с помощью .withCancelled(true);
События сообщений
Эти события управляют конвейером обработки сообщений: от форматирования до доставки.
| Событие | Данные | Назначение |
|---|---|---|
MessagePrepareEvent | MessageType, rawFormat, EventMetadata | Просмотр сообщения до начала форматирования, с названием модуля который его вызывает |
MessageFormattingEvent | MessageContext (отправитель, получатель, сообщение, флаги) | Изменение содержимого сообщения на этапе форматирования. Используется форматирующими модулями (например, для добавления тегов <display_name>) |
MessageReceiveEvent | FPlayer, Component (сообщение), overlay (сообщение в Action Bar или нет) | Уведомление о том, что было получено сообщение от сервера конкретному игроку (например при изменение режима gamemode или смерти). Используется, чтобы отменить сообщение от сервера и отправить собственное |
MessageSendEvent | ModuleName, FEntity (отправитель), FPlayer (получатель), Component (формат), Component (подтекст), EventMetadata | Доставка форматированного сообщения конкретному получателю. Используется для воспроизведения звуков, отправки пакетов, логирования в консоль |
StatusResponseEvent | JsonObject (ответ) | Отправка status сообщения игроку при просмотре сервера. Используется для изменения MOTD/icon и т.д. |
События жизненного цикла игрока
| Событие | Данные | Назначение |
|---|---|---|
PlayerPreLoginEvent | FPlayer, Component (причина отключения), allowed (разрешён вход или нет) | Загрузка основных данных игрока для того, чтобы впустить или кикнуть его |
PlayerLoadEvent | FPlayer, reload (это перезагрузка или нет) | Загрузка данных игрока из базы данных (выполняется только если игрок уже на сервере или был успешно подключен) |
PlayerJoinEvent | FPlayer | Успешное подключение игрока к серверу |
PlayerQuitEvent | FPlayer | Выход игрока с сервера |
PlayerPersistAndDisposeEvent | FPlayer | Очистка и сохранение состояния игрока. Очистка кэшей, сохранение данных в базу |
События жизненного цикла плагина
| Событие | Данные | Назначение |
|---|---|---|
EnableEvent | FlectonePulse | Вызывается при главном включении проекта |
DisableEvent | FlectonePulse | Вызывается при главном отключении проекта |
StartReloadEvent | FlectonePulse | Вызывается в начале перезагрузки всего проекта (может быть полезно, чтобы её отменить) |
EndReloadEvent | FlectonePulse, ReloadException (ошибка при выполнении, если возникла) | Вызывается в конце перезагрузки всего проекта |
События модулей
| Событие | Данные | Назначение |
|---|---|---|
ModuleEnableEvent | ModuleSimple | Вызывается при включении модуля |
ModuleDisableEvent | ModuleSimple | Вызывается при отключении модуля |
Примечания
- События обрабатываются синхронно в порядке приоритета. Не выполняйте долгих операций в обработчиках без крайней необходимости
- Используйте
ignoreCancelled = trueв аннотации@Pulse, если ваш обработчик должен выполниться даже после отмены события другими слушателями - Для кастомных событий ваши классы должны наследовать
Eventи корректно реализовать механизм отмены.
Последнее обновление
Редактировать на GitHub
FlectonePulse