Flectone LogoFlectonePulse

Точка входа

Интерфейс FlectonePulse, внедрение зависимостей через Google Guice, жизненный цикл проекта и обработка ошибок

Работа с API начинается с двух классов

КлассЗачем нужен
net.flectone.pulse.FlectonePulseAPIХранит запущенный экземпляр и управляет его жизненным циклом
net.flectone.pulse.FlectonePulseДаёт внедрение зависимостей, перезагрузку и доступ к платформе
import net.flectone.pulse.FlectonePulse;
import net.flectone.pulse.FlectonePulseAPI;

FlectonePulse flectonePulse = FlectonePulseAPI.getInstance();

FlectonePulseAPI

МетодВозвращаетЧто делает
getInstance()FlectonePulseОтдаёт запущенный экземпляр или null, если проект ещё не загрузился
isDisabling()booleanОтдаёт true, пока идёт выключение проекта
Информация

Пока isDisabling() отдаёт true, не создавай новые задачи и не трогай базу данных. Проект в этот момент уже сворачивается


FlectonePulse

МетодВозвращаетЧто делает
get(Class<T>)TОтдаёт компонент из Guice
isReady()booleanПроверяет готовность инжектора
reload()voidПеречитывает конфигурацию и бросает ReloadException при ошибке
getLoader()ObjectОтдаёт нативный объект плагина или мода платформы
hook(HookType, Object...)voidВызывает платформенную точку расширения
onLoad(), onEnable(), onDisable()voidВнутренний жизненный цикл, вызывается платформой
throwInitException(Exception)voidЗаворачивает ошибку в InitException

get(Class<T> type)

Отдаёт компонент из инжектора. Почти все компоненты объявлены интерфейсами, а их реализации помечены @Singleton, поэтому повторные вызовы отдают один и тот же объект

import net.flectone.pulse.dispatcher.MessageDispatcher;
import net.flectone.pulse.logging.FLogger;
import net.flectone.pulse.platform.registry.ListenerRegistry;
import net.flectone.pulse.service.FPlayerService;

FLogger fLogger = flectonePulse.get(FLogger.class);

FPlayerService fPlayerService = flectonePulse.get(FPlayerService.class);

MessageDispatcher messageDispatcher = flectonePulse.get(MessageDispatcher.class);

ListenerRegistry listenerRegistry = flectonePulse.get(ListenerRegistry.class);
Внимание

Перед вызовом get() проверяй готовность через isReady(), иначе получишь InjectorNotInitializedException

Запрашивай интерфейс, а не реализацию. Реализации лежат в закрытых модулях и отличаются на разных платформах

// правильно
FPlayerService service = flectonePulse.get(FPlayerService.class);

// неправильно, класса FPlayerServiceImpl нет в артефакте api
FPlayerServiceImpl service = flectonePulse.get(FPlayerServiceImpl.class);

isReady()

Проверяет, поднялся ли инжектор зависимостей

if (flectonePulse.isReady()) {
    FLogger fLogger = flectonePulse.get(FLogger.class);
    fLogger.info("API готов к работе");
}

reload()

Перезагружает конфигурацию, то же самое делает команда /flectonepulse reload

import net.flectone.pulse.exception.ReloadException;

try {
    flectonePulse.reload();
    getLogger().info("FlectonePulse перезагружен");
} catch (ReloadException e) {
    getLogger().severe("Ошибка перезагрузки " + e.getMessage());
}
Предупреждение

Перезагрузка удаляет все слушатели, кроме добавленных через registerPermanent(). Подробности на странице системы событий

getLoader()

Отдаёт нативный объект загрузчика текущей платформы. Пригодится, когда нужен платформенный API, которого нет в абстракциях FlectonePulse

ПлатформаТип объекта
Bukkit и Paperorg.bukkit.plugin.java.JavaPlugin
BungeeCordnet.md_5.bungee.api.plugin.Plugin
Velocityобъект плагина Velocity
Fabric и NeoForgeконтейнер мода
Hytaleзагрузчик мода Hytale
JavaPlugin pulsePlugin = (JavaPlugin) flectonePulse.getLoader();

hook(HookType type, Object... args)

Точки расширения, через которые ядро дёргает платформенный слой. Проект вызывает их сам, вручную они нужны только для низкоуровневой интеграции

HookTypeКогда срабатывает
CONFIGURE_SERIALIZATIONНастройка сериализации платформы
PRE_NEW_PLAYER_PLACEПеред размещением нового игрока в мире
ON_PLAYER_PRE_LOGINПроверка игрока до входа
ON_PLAYER_LOGINВход игрока
POST_RESPAWNПосле возрождения игрока
INIT_PACKET_ADAPTERЗапуск пакетного адаптера
TERMINATE_PACKET_ADAPTERШтатная остановка пакетного адаптера
TERMINATE_FAILED_PACKET_ADAPTERОстановка адаптера после ошибки запуска
CLOSE_UISЗакрытие всех открытых интерфейсов
SIMPLEVOICE_ENTITY_SOUND_PACKETПакет звука сущности Simple Voice Chat
SIMPLEVOICE_MICROPHONE_PACKETПакет микрофона Simple Voice Chat
import net.flectone.pulse.constant.HookType;

// закрыть все открытые интерфейсы FlectonePulse
flectonePulse.hook(HookType.CLOSE_UIS);

throwInitException(Exception e)

Заворачивает ошибку в InitException. В обычном режиме сообщение обрезается до 25 строк, а в debug режиме сохраняется целиком

try {
    // опасная операция при запуске
} catch (Exception e) {
    flectonePulse.throwInitException(e); // всегда бросает InitException
}

Отладка

Debug режим включается системным свойством при запуске сервера

java -Dflectonepulse.debug=true -jar server.jar

В нём FlectonePulse не обрезает сообщения об ошибках и пишет подробные логи при старте


Исключения

Все исключения лежат в пакете net.flectone.pulse.exception

ИсключениеКогда прилетает
InjectorNotInitializedExceptionget() вызван до готовности инжектора
InitExceptionОшибка при запуске проекта
ReloadExceptionОшибка при вызове reload()
LoadingExceptionОшибка загрузки проекта
LibraryLoadExceptionНе получилось скачать или подключить библиотеку
FileLoadExceptionОшибка чтения конфигурации
FileWriteExceptionОшибка записи конфигурации
ListenerRegistrationExceptionКривой слушатель или метод @Pulse
CacheRegistrationExceptionОшибка регистрации кэша
DatabaseNotInitializedExceptionОбращение к базе до её подключения
UnsupportedDatabaseOperationExceptionОперация не поддерживается выбранной базой
ProxyMessageCreateExceptionОшибка при сборке прокси сообщения
SchedulerTaskExceptionОшибка внутри задачи планировщика
ReflectionExceptionОшибка рефлексии в платформенном слое
Примечание

ReloadException и SchedulerTaskException наследуют Exception, поэтому их придётся обработать или пробросить. Все остальные наследуют RuntimeException

Последнее изменение 11 августа 2026 г.
Редактировать на GitHub

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