diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java b/paper-api/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java index 4c47414fc0..577a9d5aea 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java @@ -1,5 +1,7 @@ package io.papermc.paper.plugin.bootstrap; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -12,5 +14,13 @@ import org.jspecify.annotations.NullMarked; @ApiStatus.Experimental @NullMarked @ApiStatus.NonExtendable -public interface BootstrapContext extends PluginProviderContext { +public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner { + + /** + * Get the lifecycle event manager for registering handlers + * for lifecycle events allowed on the {@link BootstrapContext}. + * + * @return the lifecycle event manager + */ + LifecycleEventManager getLifecycleManager(); } diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java new file mode 100644 index 0000000000..0b8eafd3e7 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java @@ -0,0 +1,17 @@ +package io.papermc.paper.plugin.lifecycle.event; + +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; +import org.jetbrains.annotations.ApiStatus; + +/** + * Base type for all Lifecycle Events. + *

+ * Lifecycle events are generally fired when the older + * event system is not available, like during early + * server initialization. + * @see LifecycleEvents + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface LifecycleEvent { +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java new file mode 100644 index 0000000000..e05cdb7ab1 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java @@ -0,0 +1,53 @@ +package io.papermc.paper.plugin.lifecycle.event; + +import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Manages a plugin's lifecycle events. Can be obtained + * from {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext}. + * + * @param the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface LifecycleEventManager { + + /** + * Registers an event handler for a specific event type. + *

+ * This is shorthand for creating a new {@link LifecycleEventHandlerConfiguration} and + * just passing in the {@link LifecycleEventHandler}. + *

{@code
+     * LifecycleEventHandler> handler = new Handler();
+     * manager.registerEventHandler(LifecycleEvents.COMMANDS, handler);
+     * }
+ * is equivalent to + *
{@code
+     * LifecycleEventHandler> handler = new Handler();
+     * manager.registerEventHandler(LifecycleEvents.COMMANDS.newHandler(handler));
+     * }
+ * + * @param eventType the event type to listen to + * @param eventHandler the handler for that event + * @param the type of the event object + */ + default void registerEventHandler(final LifecycleEventType eventType, final LifecycleEventHandler eventHandler) { + this.registerEventHandler(eventType.newHandler(eventHandler)); + } + + /** + * Registers an event handler configuration. + *

+ * Configurations are created via {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. + * Event types may have different configurations options available on the builder-like object + * returned by {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. + * + * @param handlerConfiguration the handler configuration to register + */ + void registerEventHandler(LifecycleEventHandlerConfiguration handlerConfiguration); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java new file mode 100644 index 0000000000..ce5891eb11 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java @@ -0,0 +1,25 @@ +package io.papermc.paper.plugin.lifecycle.event; + +import io.papermc.paper.plugin.configuration.PluginMeta; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Implemented by types that are considered owners + * of registered handlers for lifecycle events. Generally + * the types that implement this interface also provide + * a {@link LifecycleEventManager} where you can register + * event handlers. + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface LifecycleEventOwner { + + /** + * Get the plugin meta for this plugin. + * + * @return the plugin meta + */ + PluginMeta getPluginMeta(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java new file mode 100644 index 0000000000..3093ef23dd --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java @@ -0,0 +1,19 @@ +package io.papermc.paper.plugin.lifecycle.event.handler; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * A handler for a specific event. Can be implemented + * in a concrete class or as a lambda. + * + * @param the event + */ +@ApiStatus.Experimental +@NullMarked +@FunctionalInterface +public interface LifecycleEventHandler { + + void run(E event); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java new file mode 100644 index 0000000000..9b9f4655f2 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java @@ -0,0 +1,20 @@ +package io.papermc.paper.plugin.lifecycle.event.handler.configuration; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Base type for constructing configured event handlers for + * lifecycle events. Usually created via {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType#newHandler(LifecycleEventHandler)} + * from event types in {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents} + * + * @param + */ +@SuppressWarnings("unused") +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface LifecycleEventHandlerConfiguration { +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java new file mode 100644 index 0000000000..a2acc6e386 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java @@ -0,0 +1,27 @@ +package io.papermc.paper.plugin.lifecycle.event.handler.configuration; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * Handler configuration for event types that allow "monitor" handlers. + * + * @param the required owner type + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface MonitorLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { + + /** + * Sets this handler configuration to be considered a "monitor". + * These handlers will run last and should only be used by plugins + * to observe changes from previously run handlers. + * + * @return this configuration for chaining + */ + @Contract("-> this") + MonitorLifecycleEventHandlerConfiguration monitor(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java new file mode 100644 index 0000000000..100e5d169f --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java @@ -0,0 +1,41 @@ +package io.papermc.paper.plugin.lifecycle.event.handler.configuration; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * Handler configuration that allows both "monitor" and prioritized handlers. + * The default priority is 0. + * + * @param the required owner type + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface PrioritizedLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { + + /** + * Sets the priority for this handler. Resets + * all previous calls to {@link #monitor()}. A + * lower numeric value correlates to the handler + * being run earlier. + * + * @param priority the numerical priority + * @return this configuration for chaining + */ + @Contract("_ -> this") + PrioritizedLifecycleEventHandlerConfiguration priority(int priority); + + /** + * Sets this handler configuration to be considered a "monitor". + * These handlers will run last and should only be used by plugins + * to observe any changes from previously ran handlers. + * + * @return this configuration for chaining + */ + @Contract("-> this") + PrioritizedLifecycleEventHandlerConfiguration monitor(); + +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java new file mode 100644 index 0000000000..fd9c3605a8 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java @@ -0,0 +1,12 @@ +package io.papermc.paper.plugin.lifecycle.event.registrar; + +import org.jetbrains.annotations.ApiStatus; + +/** + * To be implemented by types that provide ways to register types + * either on server start or during a reload + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface Registrar { +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java new file mode 100644 index 0000000000..7dca6be092 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java @@ -0,0 +1,28 @@ +package io.papermc.paper.plugin.lifecycle.event.registrar; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * A lifecycle event that exposes a {@link Registrar} of some kind + * to allow management of various things. Look at implementations of + * {@link Registrar} for an idea of what uses this event. + * + * @param registrar type + * @see ReloadableRegistrarEvent + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface RegistrarEvent extends LifecycleEvent { + + /** + * Get the registrar related to this event. + * + * @return the registrar + */ + @Contract(pure = true) + R registrar(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java new file mode 100644 index 0000000000..9bce1c13c8 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java @@ -0,0 +1,39 @@ +package io.papermc.paper.plugin.lifecycle.event.registrar; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * A lifecycle event that exposes a {@link Registrar} that is + * reloadable. + * + * @param the registrar type + * @see RegistrarEvent + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface ReloadableRegistrarEvent extends RegistrarEvent { + + /** + * Get the cause of this reload. + * + * @return the cause + */ + @Contract(pure = true) + Cause cause(); + + @ApiStatus.Experimental + enum Cause { + /** + * The initial load of the server. + */ + INITIAL, + /** + * A reload, triggered via one of the various mechanisms like + * the bukkit or minecraft reload commands. + */ + RELOAD + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java new file mode 100644 index 0000000000..75d9e20f53 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java @@ -0,0 +1,74 @@ +package io.papermc.paper.plugin.lifecycle.event.types; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * Base type for all types of lifecycle events. Differs from + * {@link LifecycleEvent} which is the actual event object, whereas + * this is an object representing the type of the event. Used + * to construct subtypes of {@link LifecycleEventHandlerConfiguration} for + * use in {@link LifecycleEventManager} + * + * @param the required owner type + * @param the event object type + * @param the configuration type + */ +@ApiStatus.Experimental +@NullMarked +@ApiStatus.NonExtendable +public interface LifecycleEventType> { + + /** + * Gets the name of the lifecycle event. + * + * @return the name + */ + @Contract(pure = true) + String name(); + + /** + * Create a configuration for this event with the specified + * handler. + * + * @param handler the event handler + * @return a new configuration + * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration) + */ + @Contract("_ -> new") + C newHandler(LifecycleEventHandler handler); + + /** + * Lifecycle event type that supports separate registration + * of handlers as "monitors" that are run last. Useful + * if a plugin wants to only observe the changes other handlers + * made. + * + * @param the required owner type + * @param the event object type + */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Monitorable extends LifecycleEventType> { + } + + /** + * Lifecycle event type that supports both {@link Monitorable "monitors"} and + * specific numeric-based priorities. + * + * @param the required owner type + * @param the event object type + */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Prioritizable extends LifecycleEventType> { + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java new file mode 100644 index 0000000000..e15e09c2a4 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java @@ -0,0 +1,24 @@ +package io.papermc.paper.plugin.lifecycle.event.types; + +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import java.util.Optional; +import java.util.ServiceLoader; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +@ApiStatus.Internal +@NullMarked +interface LifecycleEventTypeProvider { + + Optional INSTANCE = ServiceLoader.load(LifecycleEventTypeProvider.class) + .findFirst(); + + static LifecycleEventTypeProvider provider() { + return INSTANCE.orElseThrow(); + } + + LifecycleEventType.Monitorable monitor(String name, Class ownerType); + + LifecycleEventType.Prioritizable prioritized(String name, Class ownerType); +} diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java new file mode 100644 index 0000000000..f70814de0d --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java @@ -0,0 +1,54 @@ +package io.papermc.paper.plugin.lifecycle.event.types; + +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Holds various types of lifecycle events for + * use when creating event handler configurations + * in {@link LifecycleEventManager}. + */ +@ApiStatus.Experimental +@NullMarked +public final class LifecycleEvents { + + // + @ApiStatus.Internal + static LifecycleEventType.Monitorable plugin(final String name) { + return monitor(name, Plugin.class); + } + + @ApiStatus.Internal + static LifecycleEventType.Prioritizable pluginPrioritized(final String name) { + return prioritized(name, Plugin.class); + } + + @ApiStatus.Internal + static LifecycleEventType.Monitorable bootstrap(final String name) { + return monitor(name, BootstrapContext.class); + } + + @ApiStatus.Internal + static LifecycleEventType.Prioritizable bootstrapPrioritized(final String name) { + return prioritized(name, BootstrapContext.class); + } + + @ApiStatus.Internal + static LifecycleEventType.Monitorable monitor(final String name, final Class ownerType) { + return LifecycleEventTypeProvider.provider().monitor(name, ownerType); + } + + @ApiStatus.Internal + static LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { + return LifecycleEventTypeProvider.provider().prioritized(name, ownerType); + } + // + + private LifecycleEvents() { + } +} diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java index ffe382002c..159e96b1ee 100644 --- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java +++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java @@ -271,4 +271,12 @@ public interface UnsafeValues { */ @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); // Paper end - spawn egg color visibility + + // Paper start - lifecycle event API + /** + * @hidden + */ + @org.jetbrains.annotations.ApiStatus.Internal + io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); + // Paper end - lifecycle event API } diff --git a/paper-api/src/main/java/org/bukkit/plugin/Plugin.java b/paper-api/src/main/java/org/bukkit/plugin/Plugin.java index 46fc37a364..0ff8b53f90 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/Plugin.java +++ b/paper-api/src/main/java/org/bukkit/plugin/Plugin.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; *

* The use of {@link PluginBase} is recommended for actual Implementation */ -public interface Plugin extends TabExecutor { +public interface Plugin extends TabExecutor, io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner { // Paper /** * Returns the folder that the plugin data files are located in. The * folder may not yet exist. @@ -224,4 +224,14 @@ public interface Plugin extends TabExecutor { */ @NotNull public String getName(); + + // Paper start - lifecycle events + /** + * Get the lifecycle event manager for registering handlers + * for lifecycle events allowed on the {@link Plugin}. + * + * @return the lifecycle event manager + */ + io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager(); + // Paper end - lifecycle events } diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java index 2d64fc065d..e0203f1997 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -48,6 +48,11 @@ public abstract class JavaPlugin extends PluginBase { private FileConfiguration newConfig = null; private File configFile = null; private Logger logger = null; // Paper - PluginLogger -> Logger + // Paper start - lifecycle events + @SuppressWarnings("deprecation") + private final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager lifecycleEventManager = org.bukkit.Bukkit.getUnsafe().createPluginLifecycleEventManager(this, () -> this.allowsLifecycleRegistration); + private boolean allowsLifecycleRegistration = true; + // Paper end public JavaPlugin() { // Paper start @@ -279,7 +284,9 @@ public abstract class JavaPlugin extends PluginBase { isEnabled = enabled; if (isEnabled) { + try { // Paper - lifecycle events onEnable(); + } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events } else { onDisable(); } @@ -457,4 +464,11 @@ public abstract class JavaPlugin extends PluginBase { } return plugin; } + + // Paper start - lifecycle events + @Override + public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager() { + return this.lifecycleEventManager; + } + // Paper end - lifecycle events } diff --git a/paper-api/src/test/java/org/bukkit/plugin/TestPlugin.java b/paper-api/src/test/java/org/bukkit/plugin/TestPlugin.java index 43b58e920e..affe88cf8e 100644 --- a/paper-api/src/test/java/org/bukkit/plugin/TestPlugin.java +++ b/paper-api/src/test/java/org/bukkit/plugin/TestPlugin.java @@ -133,4 +133,11 @@ public class TestPlugin extends PluginBase { public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { throw new UnsupportedOperationException("Not supported."); } + + // Paper start - lifecycle events + @Override + public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager getLifecycleManager() { + throw new UnsupportedOperationException("Not supported."); + } + // Paper end - lifecycle events }