События
Как слушать события Identica, реагировать на них и учитывать их особенности.
У Identica собственная система событий для плагинов-аддонов, интеграций и внутренних компонентов.
Базовая схема слушателя
Чтобы получать события Identica в плагине-аддоне:
- реализуйте
EventListener - пометьте методы-обработчики аннотацией
@IdenticEvent - зарегистрируйте слушатель через
identica.getEventManager()
Пример слушателя
import me.whereareiam.identica.IdenticaAPI;
import me.whereareiam.identica.event.EventListener;
import me.whereareiam.identica.event.base.IdenticEvent;
import me.whereareiam.identica.event.scenario.registration.RegistrationRequiredEvent;
import java.time.Instant;
public final class ExampleRegistrationListener implements EventListener {
@IdenticEvent
public void onRegistrationRequired(RegistrationRequiredEvent event) {
System.out.println(
"Registration is now required until " + Instant.ofEpochMilli(event.getExpiresAt())
);
}
public void register() {
IdenticaAPI.whenReady(identica -> identica.getEventManager().register(this));
}
}Порядок событий
Если нужен определённый порядок выполнения, передайте его в @IdenticEvent.
import me.whereareiam.identica.event.EventListener;
import me.whereareiam.identica.event.base.IdenticEvent;
import me.whereareiam.identica.event.session.SessionOpenedEvent;
import me.whereareiam.identica.type.event.EventOrder;
public final class ExampleSessionListener implements EventListener {
@IdenticEvent(EventOrder.LOW)
public void onSessionOpened(SessionOpenedEvent event) {
System.out.println("Opened session for: " + event.getSession().getEffectiveUsername());
}
}Запуск и остановка
Identica запускается по фазам, и каждая начинается, когда закончилась предыдущая: конфигурация, журнал, хранилища (база данных и репликация), основные подсистемы, функции, провайдеры, интеграции, например статистика использования, и в конце подключения игроков. Эту последовательность отмечают три события жизненного цикла:
IdenticaBootstrappedEventвызывается, когда функции запущены, до загрузки провайдеров.IdenticaReadyEventвызывается в конце запуска. Провайдеры загружены вместе со своими командами и документами, Identica обрабатывает подключения игроков, а действия, переданные вIdenticaAPI.whenReady(...), уже выполнены.IdenticaShutdownEventвызывается, когда Identica останавливается. НаEventOrder.LOWIdentica останавливает фазы в обратном порядке, поэтому слушатель сEventOrder.LOWESTещё работает при открытых провайдерах и базе данных, а более поздние слушатели — уже после их закрытия.
Сообщения игроку при входе
Клиент игрока показывает чат, заголовки и диалоги, только когда он уже в мире сервера. Пока клиент ещё проходит конфигурацию или переходит на другой сервер, он отбрасывает сообщения чата и закрывает диалоги. ServerJoinedEvent (в me.whereareiam.identica.event.connection) вызывается именно в этот момент: при первом входе и снова после каждого перехода на другой сервер, с Identity игрока и именем сервера. Из этого события Identica доставляет свои отложенные сообщения, например первый запрос и сообщение о завершении.
Показывайте свои сообщения или диалоги входящему игроку из этого события, а не из события входа или подключения платформы:
import me.whereareiam.identica.event.EventListener;
import me.whereareiam.identica.event.base.IdenticEvent;
import me.whereareiam.identica.event.connection.ServerJoinedEvent;
import net.kyori.adventure.text.Component;
public final class WelcomeListener implements EventListener {
@IdenticEvent
public void onServerJoined(ServerJoinedEvent event) {
event.getIdentity().sendMessage(Component.text("Welcome to " + event.getServer()));
}
}На BungeeCord событие вызывается из планировщика Identica сразу после входа, потому что у BungeeCord нет события, которое срабатывает, когда клиент уже в мире.
Основные категории событий
Текущий API предоставляет такие группы событий:
- события жизненного цикла
- события сценариев и конвейера
- события маршрутизации
- события сессий
- события провайдеров
- события, принадлежащие функциям, например привязка верификации (если эта функция выбрана)
- события аккаунтов и идентичности
Это значит, что плагины-аддоны могут реагировать на разных уровнях — от высокоуровневых событий начала сценария до отдельных решений верификации или маршрутизации.
Отменяемые и изменяемые события
Некоторые события только информируют. Другие можно изменить или отменить.
Например, VerificationEnrollEvent можно отменить, и слушатели могут переписать в нём провайдер или метод до начала привязки. Это событие входит в API функции верификации. Подключите этот API как зависимость для компиляции и зарегистрируйте слушатель после инициализации Identica. Поведение верификации следует действующим настройкам задействованного провайдера.
import me.whereareiam.identica.event.EventListener;
import me.whereareiam.identica.event.base.IdenticEvent;
import me.whereareiam.identica.feature.verification.event.enroll.VerificationEnrollEvent;
public final class ExampleVerificationListener implements EventListener {
@IdenticEvent
public void onEnroll(VerificationEnrollEvent event) {
if ("totp".equalsIgnoreCase(event.getMethodId())) {
event.setProviderId("credential");
}
}
}Другой пример — AccountPrepareEvent, в котором слушатели могут повлиять на итоговое решение о подготовке аккаунта.
import me.whereareiam.identica.event.EventListener;
import me.whereareiam.identica.event.account.AccountPrepareEvent;
import me.whereareiam.identica.event.base.IdenticEvent;
import me.whereareiam.identica.model.identity.AccountDecision;
public final class ExampleAccountPrepareListener implements EventListener {
@IdenticEvent
public void onPrepare(AccountPrepareEvent event) {
if (event.getDecision() == null) {
event.setDecision(AccountDecision.allow());
}
}
}Всегда проверяйте конкретный тип события, прежде чем считать его отменяемым или изменяемым.
Синхронные и асинхронные события
Identica различает синхронные и несинхронные события через иерархию типов событий.
Если событие реализует SynchronousEvent, оно обрабатывается синхронно в текущем потоке.
Для авторов аддонов это значит, что обработчики событий нужно считать частью активного процесса выполнения и избегать в них лишней блокирующей работы.
Реплицируемые события
Некоторые события Identica также реализуют ReplicatedEvent.
Они предназначены для передачи через канал репликации и повторного воспроизведения на других экземплярах.
Важные свойства реплицируемых событий:
- они несут идентификатор события репликации для дедупликации
- они несут идентификатор сервера-источника
- передаваться по сети могут только зарегистрированные типы реплицируемых событий
- они должны представлять факты, которые каждый экземпляр может безопасно обработать локально
Последний пункт важен: не каждое событие должно становиться реплицируемым. Однократные глобальные операции обычно лучше выражать командами или вызовами сервисов, а не повторно воспроизводимыми событиями.
Встроенные реплицируемые события
Текущий мост реплицируемых событий регистрирует такие встроенные типы реплицируемых событий:
SessionClosedEventAccountClearEventAccountDeleteEvent
Они распространяются, потому что представляют изменения состояния, которые другие экземпляры могут безопасно наблюдать и применять локально.
Когда важны реплицируемые события
Автору аддона стоит учитывать реплицируемые события, когда:
- ваша интеграция работает в среде из нескольких экземпляров с репликацией
- вам нужно согласованно реагировать на изменения аккаунтов или сессий на всех экземплярах
- вы собираетесь определить событие, которому может понадобиться повторное воспроизведение на других экземплярах
Если ваш аддон реагирует только локально и ему не нужно повторное воспроизведение на других экземплярах, обычно достаточно обычных событий Identica.
