Identica
API

События

Как слушать события 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.LOW Identica останавливает фазы в обратном порядке, поэтому слушатель с 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. Они предназначены для передачи через канал репликации и повторного воспроизведения на других экземплярах.

Важные свойства реплицируемых событий:

  • они несут идентификатор события репликации для дедупликации
  • они несут идентификатор сервера-источника
  • передаваться по сети могут только зарегистрированные типы реплицируемых событий
  • они должны представлять факты, которые каждый экземпляр может безопасно обработать локально

Последний пункт важен: не каждое событие должно становиться реплицируемым. Однократные глобальные операции обычно лучше выражать командами или вызовами сервисов, а не повторно воспроизводимыми событиями.

Встроенные реплицируемые события

Текущий мост реплицируемых событий регистрирует такие встроенные типы реплицируемых событий:

  • SessionClosedEvent
  • AccountClearEvent
  • AccountDeleteEvent

Они распространяются, потому что представляют изменения состояния, которые другие экземпляры могут безопасно наблюдать и применять локально.

Когда важны реплицируемые события

Автору аддона стоит учитывать реплицируемые события, когда:

  • ваша интеграция работает в среде из нескольких экземпляров с репликацией
  • вам нужно согласованно реагировать на изменения аккаунтов или сессий на всех экземплярах
  • вы собираетесь определить событие, которому может понадобиться повторное воспроизведение на других экземплярах

Если ваш аддон реагирует только локально и ему не нужно повторное воспроизведение на других экземплярах, обычно достаточно обычных событий Identica.

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