Flectone Logo FlectonePulse

Система событий

Механизм событий 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);

События сообщений

Эти события управляют конвейером обработки сообщений: от форматирования до доставки.

СобытиеДанныеНазначение
MessagePrepareEventMessageType, rawFormat, EventMetadataПросмотр сообщения до начала форматирования, с названием модуля который его вызывает
MessageFormattingEventMessageContext (отправитель, получатель, сообщение, флаги)Изменение содержимого сообщения на этапе форматирования. Используется форматирующими модулями (например, для добавления тегов <display_name>)
MessageReceiveEventFPlayer, Component (сообщение), overlay (сообщение в Action Bar или нет)Уведомление о том, что было получено сообщение от сервера конкретному игроку (например при изменение режима gamemode или смерти). Используется, чтобы отменить сообщение от сервера и отправить собственное
MessageSendEventModuleName, FEntity (отправитель), FPlayer (получатель), Component (формат), Component (подтекст), EventMetadataДоставка форматированного сообщения конкретному получателю. Используется для воспроизведения звуков, отправки пакетов, логирования в консоль
StatusResponseEventJsonObject (ответ)Отправка status сообщения игроку при просмотре сервера. Используется для изменения MOTD/icon и т.д.

События жизненного цикла игрока

СобытиеДанныеНазначение
PlayerPreLoginEventFPlayer, Component (причина отключения), allowed (разрешён вход или нет)Загрузка основных данных игрока для того, чтобы впустить или кикнуть его
PlayerLoadEventFPlayer, reload (это перезагрузка или нет)Загрузка данных игрока из базы данных (выполняется только если игрок уже на сервере или был успешно подключен)
PlayerJoinEventFPlayerУспешное подключение игрока к серверу
PlayerQuitEventFPlayerВыход игрока с сервера
PlayerPersistAndDisposeEventFPlayerОчистка и сохранение состояния игрока. Очистка кэшей, сохранение данных в базу

События жизненного цикла плагина

СобытиеДанныеНазначение
EnableEventFlectonePulseВызывается при главном включении проекта
DisableEventFlectonePulseВызывается при главном отключении проекта
StartReloadEventFlectonePulseВызывается в начале перезагрузки всего проекта (может быть полезно, чтобы её отменить)
EndReloadEventFlectonePulse, ReloadException (ошибка при выполнении, если возникла)Вызывается в конце перезагрузки всего проекта

События модулей

СобытиеДанныеНазначение
ModuleEnableEventModuleSimpleВызывается при включении модуля
ModuleDisableEventModuleSimpleВызывается при отключении модуля

Примечания

  • События обрабатываются синхронно в порядке приоритета. Не выполняйте долгих операций в обработчиках без крайней необходимости
  • Используйте ignoreCancelled = true в аннотации @Pulse, если ваш обработчик должен выполниться даже после отмены события другими слушателями
  • Для кастомных событий ваши классы должны наследовать Event и корректно реализовать механизм отмены.

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

Редактировать на GitHub

На этой странице