Finish converting most of the undeprecated api to jspecify

This commit is contained in:
Jake Potrebic 2024-09-30 11:44:36 -07:00
parent 29a25df60e
commit 0adf5876db
45 changed files with 782 additions and 718 deletions

View File

@ -14,11 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import org.bukkit.DyeColor; +import org.bukkit.DyeColor;
+import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.LivingEntity;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Entities that can have their collars colored. + * Entities that can have their collars colored.
+ */ + */
+@NullMarked
+public interface CollarColorable extends LivingEntity { +public interface CollarColorable extends LivingEntity {
+ +
+ /** + /**
@ -26,14 +27,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the color of the collar + * @return the color of the collar
+ */ + */
+ @NotNull DyeColor getCollarColor(); + DyeColor getCollarColor();
+ +
+ /** + /**
+ * Set the collar color of this entity + * Set the collar color of this entity
+ * + *
+ * @param color the color to apply + * @param color the color to apply
+ */ + */
+ void setCollarColor(@NotNull DyeColor color); + void setCollarColor(DyeColor color);
+} +}
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java diff --git a/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java
new file mode 100644 new file mode 100644

View File

@ -14,9 +14,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import java.util.Set; +import java.util.Set;
+import org.bukkit.FeatureFlag; +import org.bukkit.FeatureFlag;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Implemented by types in built-in registries that are controlled by {@link FeatureFlag FeatureFlags}. + * Implemented by types in built-in registries that are controlled by {@link FeatureFlag FeatureFlags}.
@ -24,6 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @apiNote When a type that currently implements this interface transitions to being data-drive, this + * @apiNote When a type that currently implements this interface transitions to being data-drive, this
+ * interface will be removed from that type in the following major version. + * interface will be removed from that type in the following major version.
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface FeatureDependant { +public interface FeatureDependant {
+ +
@ -33,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the immutable set of feature flags + * @return the immutable set of feature flags
+ */ + */
+ default @Unmodifiable @NonNull Set<FeatureFlag> requiredFeatures() { + default @Unmodifiable Set<FeatureFlag> requiredFeatures() {
+ return FeatureFlagProvider.provider().requiredFeatures(this); + return FeatureFlagProvider.provider().requiredFeatures(this);
+ } + }
+} +}
@ -50,7 +51,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Set; +import java.util.Set;
+import org.bukkit.FeatureFlag; +import org.bukkit.FeatureFlag;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+interface FeatureFlagProvider { +interface FeatureFlagProvider {
+ +
@ -72,14 +75,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import java.util.Set; +import java.util.Set;
+import org.bukkit.FeatureFlag; +import org.bukkit.FeatureFlag;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Implemented by types that hold {@link FeatureFlag FeatureFlags} like + * Implemented by types that hold {@link FeatureFlag FeatureFlags} like
+ * {@link org.bukkit.generator.WorldInfo} and {@link org.bukkit.RegionAccessor}. + * {@link org.bukkit.generator.WorldInfo} and {@link org.bukkit.RegionAccessor}.
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface FeatureFlagSetHolder { +public interface FeatureFlagSetHolder {
+ +
@ -88,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return true if enabled + * @return true if enabled
+ */ + */
+ default boolean isEnabled(final @NonNull FeatureDependant featureDependant) { + default boolean isEnabled(final FeatureDependant featureDependant) {
+ return this.getFeatureFlags().containsAll(featureDependant.requiredFeatures()); + return this.getFeatureFlags().containsAll(featureDependant.requiredFeatures());
+ } + }
+ +
@ -97,7 +101,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return all enabled {@link FeatureFlag FeatureFlags} + * @return all enabled {@link FeatureFlag FeatureFlags}
+ */ + */
+ @Unmodifiable @NonNull Set<FeatureFlag> getFeatureFlags(); + @Unmodifiable Set<FeatureFlag> getFeatureFlags();
+} +}
diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -189,12 +193,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import java.util.HashSet; +import java.util.HashSet;
+import java.util.Set; +import java.util.Set;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record FeatureFlagImpl(NamespacedKey key) implements FeatureFlag { +record FeatureFlagImpl(NamespacedKey key) implements FeatureFlag {
+ +
+ static final Set<FeatureFlag> ALL_FLAGS = new HashSet<>(); + static final Set<FeatureFlag> ALL_FLAGS = new HashSet<>();
@ -205,7 +208,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @ApiStatus.Internal + @ApiStatus.Internal
+ @DefaultQualifier(NonNull.class)
+ record Deprecated(NamespacedKey key) implements FeatureFlag { + record Deprecated(NamespacedKey key) implements FeatureFlag {
+ +
+ @Override + @Override

View File

@ -15,13 +15,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.Fluid; +import org.bukkit.Fluid;
+import org.bukkit.Location; +import org.bukkit.Location;
+import org.bukkit.util.Vector; +import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range; +import org.jetbrains.annotations.Range;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A representation of a fluid in a specific state of data. + * A representation of a fluid in a specific state of data.
+ * This type is not linked to a specific location and hence mostly resembles a {@link org.bukkit.block.data.BlockData}. + * This type is not linked to a specific location and hence mostly resembles a {@link org.bukkit.block.data.BlockData}.
+ */ + */
+@NullMarked
+public interface FluidData extends Cloneable { +public interface FluidData extends Cloneable {
+ +
+ /** + /**
@ -29,14 +30,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the fluid type + * @return the fluid type
+ */ + */
+ @NotNull Fluid getFluidType(); + Fluid getFluidType();
+ +
+ /** + /**
+ * Returns a copy of this FluidData. + * Returns a copy of this FluidData.
+ * + *
+ * @return a copy of the fluid data + * @return a copy of the fluid data
+ */ + */
+ @NotNull FluidData clone(); + FluidData clone();
+ +
+ /** + /**
+ * Computes the direction of the flow of the liquid at the given location as a vector. + * Computes the direction of the flow of the liquid at the given location as a vector.
@ -48,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param location - the location to check the liquid flow + * @param location - the location to check the liquid flow
+ * @return the flow direction vector at the given location + * @return the flow direction vector at the given location
+ */ + */
+ @NotNull Vector computeFlowDirection(@NotNull Location location); + Vector computeFlowDirection(Location location);
+ +
+ /** + /**
+ * Returns the level of liquid this fluid data holds. + * Returns the level of liquid this fluid data holds.
@ -69,7 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the height as a float value + * @return the height as a float value
+ */ + */
+ @Range(from = 0, to = 1) + @Range(from = 0, to = 1)
+ float computeHeight(@NotNull Location location); + float computeHeight(Location location);
+ +
+ /** + /**
+ * Returns whether this fluid is a source block + * Returns whether this fluid is a source block

View File

@ -17,13 +17,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; import org.jspecify.annotations.NullMarked;
/** @@ -0,0 +0,0 @@ import org.jspecify.annotations.NullMarked;
* Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.ApiStatus;
*/
@ApiStatus.Experimental @ApiStatus.Experimental
@NullMarked
@ApiStatus.NonExtendable @ApiStatus.NonExtendable
-public interface BootstrapContext extends PluginProviderContext { -public interface BootstrapContext extends PluginProviderContext {
+public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner { +public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner {
@ -34,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the lifecycle event manager + * @return the lifecycle event manager
+ */ + */
+ @NotNull LifecycleEventManager<BootstrapContext> getLifecycleManager(); + LifecycleEventManager<BootstrapContext> getLifecycleManager();
} }
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java
new file mode 100644 new file mode 100644
@ -71,7 +69,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Manages a plugin's lifecycle events. Can be obtained + * Manages a plugin's lifecycle events. Can be obtained
@ -80,6 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <O> the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} + * @param <O> the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext}
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface LifecycleEventManager<O extends LifecycleEventOwner> { +public interface LifecycleEventManager<O extends LifecycleEventOwner> {
+ +
@ -102,7 +101,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param eventHandler the handler for that event + * @param eventHandler the handler for that event
+ * @param <E> the type of the event object + * @param <E> the type of the event object
+ */ + */
+ default <E extends LifecycleEvent> void registerEventHandler(final @NotNull LifecycleEventType<? super O, ? extends E, ?> eventType, final @NotNull LifecycleEventHandler<? super E> eventHandler) { + default <E extends LifecycleEvent> void registerEventHandler(final LifecycleEventType<? super O, ? extends E, ?> eventType, final LifecycleEventHandler<? super E> eventHandler) {
+ this.registerEventHandler(eventType.newHandler(eventHandler)); + this.registerEventHandler(eventType.newHandler(eventHandler));
+ } + }
+ +
@ -115,7 +114,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param handlerConfiguration the handler configuration to register + * @param handlerConfiguration the handler configuration to register
+ */ + */
+ void registerEventHandler(@NotNull LifecycleEventHandlerConfiguration<? super O> handlerConfiguration); + void registerEventHandler(LifecycleEventHandlerConfiguration<? super O> handlerConfiguration);
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java
new file mode 100644 new file mode 100644
@ -127,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.plugin.configuration.PluginMeta; +import io.papermc.paper.plugin.configuration.PluginMeta;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Implemented by types that are considered owners + * Implemented by types that are considered owners
@ -137,6 +136,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * event handlers. + * event handlers.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface LifecycleEventOwner { +public interface LifecycleEventOwner {
+ +
@ -145,7 +145,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the plugin meta + * @return the plugin meta
+ */ + */
+ @NotNull PluginMeta getPluginMeta(); + PluginMeta getPluginMeta();
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java
new file mode 100644 new file mode 100644
@ -157,7 +157,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A handler for a specific event. Can be implemented + * A handler for a specific event. Can be implemented
@ -166,10 +166,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <E> the event + * @param <E> the event
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@FunctionalInterface +@FunctionalInterface
+public interface LifecycleEventHandler<E extends LifecycleEvent> { +public interface LifecycleEventHandler<E extends LifecycleEvent> {
+ +
+ void run(@NotNull E event); + void run(E event);
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java
new file mode 100644 new file mode 100644
@ -182,6 +183,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +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.LifecycleEventHandler;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Base type for constructing configured event handlers for + * Base type for constructing configured event handlers for
@ -192,6 +194,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ */ + */
+@SuppressWarnings("unused") +@SuppressWarnings("unused")
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface LifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> { +public interface LifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> {
+} +}
@ -206,6 +209,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Handler configuration for event types that allow "monitor" handlers. + * Handler configuration for event types that allow "monitor" handlers.
@ -213,6 +217,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <O> the required owner type + * @param <O> the required owner type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface MonitorLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> { +public interface MonitorLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> {
+ +
@ -237,6 +242,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Handler configuration that allows both "monitor" and prioritized handlers. + * Handler configuration that allows both "monitor" and prioritized handlers.
@ -245,6 +251,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <O> the required owner type + * @param <O> the required owner type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface PrioritizedLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> { +public interface PrioritizedLifecycleEventHandlerConfiguration<O extends LifecycleEventOwner> extends LifecycleEventHandlerConfiguration<O> {
+ +
@ -300,7 +307,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A lifecycle event that exposes a {@link Registrar} of some kind + * A lifecycle event that exposes a {@link Registrar} of some kind
@ -311,6 +318,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see ReloadableRegistrarEvent + * @see ReloadableRegistrarEvent
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistrarEvent<R extends Registrar> extends LifecycleEvent { +public interface RegistrarEvent<R extends Registrar> extends LifecycleEvent {
+ +
@ -320,7 +328,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the registrar + * @return the registrar
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ @NotNull R registrar(); + R registrar();
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java
new file mode 100644 new file mode 100644
@ -332,7 +340,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A lifecycle event that exposes a {@link Registrar} that is + * A lifecycle event that exposes a {@link Registrar} that is
@ -342,6 +350,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see RegistrarEvent + * @see RegistrarEvent
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface ReloadableRegistrarEvent<R extends Registrar> extends RegistrarEvent<R> { +public interface ReloadableRegistrarEvent<R extends Registrar> extends RegistrarEvent<R> {
+ +
@ -351,7 +360,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the cause + * @return the cause
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ @NotNull Cause cause(); + Cause cause();
+ +
+ @ApiStatus.Experimental + @ApiStatus.Experimental
+ enum Cause { + enum Cause {
@ -383,7 +392,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Base type for all types of lifecycle events. Differs from + * Base type for all types of lifecycle events. Differs from
@ -397,6 +406,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <C> the configuration type + * @param <C> the configuration type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface LifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent, C extends LifecycleEventHandlerConfiguration<O>> { +public interface LifecycleEventType<O extends LifecycleEventOwner, E extends LifecycleEvent, C extends LifecycleEventHandlerConfiguration<O>> {
+ +
@ -406,7 +416,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the name + * @return the name
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ @NotNull String name(); + String name();
+ +
+ /** + /**
+ * Create a configuration for this event with the specified + * Create a configuration for this event with the specified
@ -417,7 +427,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration) + * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration)
+ */ + */
+ @Contract("_ -> new") + @Contract("_ -> new")
+ @NotNull C newHandler(@NotNull LifecycleEventHandler<? super E> handler); + C newHandler(LifecycleEventHandler<? super E> handler);
+ +
+ /** + /**
+ * Lifecycle event type that supports separate registration + * Lifecycle event type that supports separate registration
@ -458,8 +468,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Optional; +import java.util.Optional;
+import java.util.ServiceLoader; +import java.util.ServiceLoader;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@NullMarked
+interface LifecycleEventTypeProvider { +interface LifecycleEventTypeProvider {
+ +
+ Optional<LifecycleEventTypeProvider> INSTANCE = ServiceLoader.load(LifecycleEventTypeProvider.class) + Optional<LifecycleEventTypeProvider> INSTANCE = ServiceLoader.load(LifecycleEventTypeProvider.class)
@ -487,6 +499,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
+import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.Plugin;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Holds various types of lifecycle events for + * Holds various types of lifecycle events for
@ -494,6 +507,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * in {@link LifecycleEventManager}. + * in {@link LifecycleEventManager}.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public final class LifecycleEvents { +public final class LifecycleEvents {
+ +
+ //<editor-fold desc="helper methods" defaultstate="collapsed"> + //<editor-fold desc="helper methods" defaultstate="collapsed">

View File

@ -15,8 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockFace;
+import org.bukkit.block.TileState; +import org.bukkit.block.TileState;
+import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.BlockData;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+public interface MovingPiston extends TileState { +public interface MovingPiston extends TileState {
+ +
+ /** + /**
@ -24,7 +25,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the pushed block + * @return the pushed block
+ */ + */
+ @NotNull
+ BlockData getMovingBlock(); + BlockData getMovingBlock();
+ +
+ /** + /**
@ -33,7 +33,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the direction + * @return the direction
+ */ + */
+ @NotNull
+ BlockFace getDirection(); + BlockFace getDirection();
+ +
+ /** + /**

View File

@ -16,15 +16,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockFace;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A position represented with integers. + * A position represented with integers.
+ * <p> + * <p>
+ * <b>May see breaking changes until Experimental annotation is removed.</b> + * <b>May see breaking changes until Experimental annotation is removed.</b>
+ *
+ * @see FinePosition + * @see FinePosition
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface BlockPosition extends Position { +public interface BlockPosition extends Position {
+ +
+ @Override + @Override
@ -53,17 +55,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ default @NotNull BlockPosition toBlock() { + default BlockPosition toBlock() {
+ return this; + return this;
+ } + }
+ +
+ @Override + @Override
+ default @NotNull BlockPosition offset(int x, int y, int z) { + default BlockPosition offset(final int x, final int y, final int z) {
+ return x == 0 && y == 0 && z == 0 ? this : new BlockPositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z); + return x == 0 && y == 0 && z == 0 ? this : new BlockPositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z);
+ } + }
+ +
+ @Override + @Override
+ default @NotNull FinePosition offset(double x, double y, double z) { + default FinePosition offset(final double x, final double y, final double z) {
+ return new FinePositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z); + return new FinePositionImpl(this.blockX() + x, this.blockY() + y, this.blockZ() + z);
+ } + }
+ +
@ -74,7 +76,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the offset block position + * @return the offset block position
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ default @NotNull BlockPosition offset(@NotNull BlockFace blockFace) { + default BlockPosition offset(final BlockFace blockFace) {
+ return this.offset(blockFace, 1); + return this.offset(blockFace, 1);
+ } + }
+ +
@ -87,7 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the offset block position + * @return the offset block position
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ default @NotNull BlockPosition offset(@NotNull BlockFace blockFace, int amount) { + default BlockPosition offset(final BlockFace blockFace, final int amount) {
+ return amount == 0 ? this : new BlockPositionImpl(this.blockX() + (blockFace.getModX() * amount), this.blockY() + (blockFace.getModY() * amount), this.blockZ() + (blockFace.getModZ() * amount)); + return amount == 0 ? this : new BlockPositionImpl(this.blockX() + (blockFace.getModX() * amount), this.blockY() + (blockFace.getModY() * amount), this.blockZ() + (blockFace.getModZ() * amount));
+ } + }
+ +
@ -100,7 +102,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the offset block position + * @return the offset block position
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ default @NotNull BlockPosition offset(@NotNull Axis axis, int amount) { + default BlockPosition offset(final Axis axis, final int amount) {
+ return amount == 0 ? this : switch (axis) { + return amount == 0 ? this : switch (axis) {
+ case X -> new BlockPositionImpl(this.blockX() + amount, this.blockY(), this.blockZ()); + case X -> new BlockPositionImpl(this.blockX() + amount, this.blockY(), this.blockZ());
+ case Y -> new BlockPositionImpl(this.blockX(), this.blockY() + amount, this.blockZ()); + case Y -> new BlockPositionImpl(this.blockX(), this.blockY() + amount, this.blockZ());
@ -127,17 +129,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.math; +package io.papermc.paper.math;
+ +
+import org.bukkit.util.NumberConversions; +import org.bukkit.util.NumberConversions;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A position represented with doubles. + * A position represented with doubles.
+ * <p> + * <p>
+ * <b>May see breaking changes until Experimental annotation is removed.</b> + * <b>May see breaking changes until Experimental annotation is removed.</b>
+ *
+ * @see BlockPosition + * @see BlockPosition
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface FinePosition extends Position { +public interface FinePosition extends Position {
+ +
+ @Override + @Override
@ -166,17 +169,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ default @NotNull BlockPosition toBlock() { + default BlockPosition toBlock() {
+ return new BlockPositionImpl(this.blockX(), this.blockY(), this.blockZ()); + return new BlockPositionImpl(this.blockX(), this.blockY(), this.blockZ());
+ } + }
+ +
+ @Override + @Override
+ default @NotNull FinePosition offset(int x, int y, int z) { + default FinePosition offset(final int x, final int y, final int z) {
+ return this.offset((double) x, y, z); + return this.offset((double) x, y, z);
+ } + }
+ +
+ @Override + @Override
+ default @NotNull FinePosition offset(double x, double y, double z) { + default FinePosition offset(final double x, final double y, final double z) {
+ return x == 0.0 && y == 0.0 && z == 0.0 ? this : new FinePositionImpl(this.x() + x, this.y() + y, this.z() + z); + return x == 0.0 && y == 0.0 && z == 0.0 ? this : new FinePositionImpl(this.x() + x, this.y() + y, this.z() + z);
+ } + }
+} +}
@ -203,7 +206,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.util.Vector; +import org.bukkit.util.Vector;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Common interface for {@link FinePosition} and {@link BlockPosition}. + * Common interface for {@link FinePosition} and {@link BlockPosition}.
@ -211,6 +214,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * <b>May see breaking changes until Experimental annotation is removed.</b> + * <b>May see breaking changes until Experimental annotation is removed.</b>
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface Position { +public interface Position {
+ +
+ FinePosition FINE_ZERO = new FinePositionImpl(0, 0, 0); + FinePosition FINE_ZERO = new FinePositionImpl(0, 0, 0);
@ -287,7 +291,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z z value to offset + * @param z z value to offset
+ * @return the offset position + * @return the offset position
+ */ + */
+ @NotNull Position offset(int x, int y, int z); + Position offset(int x, int y, int z);
+ +
+ /** + /**
+ * Returns a position offset by the specified amounts. + * Returns a position offset by the specified amounts.
@ -297,7 +301,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z z value to offset + * @param z z value to offset
+ * @return the offset position + * @return the offset position
+ */ + */
+ @NotNull FinePosition offset(double x, double y, double z); + FinePosition offset(double x, double y, double z);
+ +
+ /** + /**
+ * Returns a new position at the center of the block position this represents + * Returns a new position at the center of the block position this represents
@ -305,7 +309,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new center position + * @return a new center position
+ */ + */
+ @Contract(value = "-> new", pure = true) + @Contract(value = "-> new", pure = true)
+ default @NotNull FinePosition toCenter() { + default FinePosition toCenter() {
+ return new FinePositionImpl(this.blockX() + 0.5, this.blockY() + 0.5, this.blockZ() + 0.5); + return new FinePositionImpl(this.blockX() + 0.5, this.blockY() + 0.5, this.blockZ() + 0.5);
+ } + }
+ +
@ -316,7 +320,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the block position + * @return the block position
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ @NotNull BlockPosition toBlock(); + BlockPosition toBlock();
+ +
+ /** + /**
+ * Converts this position to a vector + * Converts this position to a vector
@ -324,7 +328,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new vector + * @return a new vector
+ */ + */
+ @Contract(value = "-> new", pure = true) + @Contract(value = "-> new", pure = true)
+ default @NotNull Vector toVector() { + default Vector toVector() {
+ return new Vector(this.x(), this.y(), this.z()); + return new Vector(this.x(), this.y(), this.z());
+ } + }
+ +
@ -335,7 +339,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new location + * @return a new location
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ default @NotNull Location toLocation(@NotNull World world) { + default Location toLocation(final World world) {
+ return new Location(world, this.x(), this.y(), this.z()); + return new Location(world, this.x(), this.y(), this.z());
+ } + }
+ +
@ -348,7 +352,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a position with those coords + * @return a position with those coords
+ */ + */
+ @Contract(value = "_, _, _ -> new", pure = true) + @Contract(value = "_, _, _ -> new", pure = true)
+ static @NotNull BlockPosition block(int x, int y, int z) { + static BlockPosition block(final int x, final int y, final int z) {
+ return new BlockPositionImpl(x, y, z); + return new BlockPositionImpl(x, y, z);
+ } + }
+ +
@ -359,7 +363,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new position at that location + * @return a new position at that location
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ static @NotNull BlockPosition block(@NotNull Location location) { + static BlockPosition block(final Location location) {
+ return new BlockPositionImpl(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + return new BlockPositionImpl(location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ } + }
+ +
@ -372,7 +376,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a position with those coords + * @return a position with those coords
+ */ + */
+ @Contract(value = "_, _, _ -> new", pure = true) + @Contract(value = "_, _, _ -> new", pure = true)
+ static @NotNull FinePosition fine(double x, double y, double z) { + static FinePosition fine(final double x, final double y, final double z) {
+ return new FinePositionImpl(x, y, z); + return new FinePositionImpl(x, y, z);
+ } + }
+ +
@ -383,7 +387,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new position at that location + * @return a new position at that location
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ static @NotNull FinePosition fine(@NotNull Location location) { + static FinePosition fine(final Location location) {
+ return new FinePositionImpl(location.getX(), location.getY(), location.getZ()); + return new FinePositionImpl(location.getX(), location.getY(), location.getZ());
+ } + }
+} +}

View File

@ -105,14 +105,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.bukkit.Registry; +import org.bukkit.Registry;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Used for accessing different {@link Registry} instances + * Used for accessing different {@link Registry} instances
+ * by a {@link RegistryKey}. Get the main instance of {@link RegistryAccess} + * by a {@link RegistryKey}. Get the main instance of {@link RegistryAccess}
+ * with {@link RegistryAccess#registryAccess()}. + * with {@link RegistryAccess#registryAccess()}.
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryAccess { +public interface RegistryAccess {
+ +
@ -121,7 +122,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the RegistryAccess instance + * @return the RegistryAccess instance
+ */ + */
+ static @NotNull RegistryAccess registryAccess() { + static RegistryAccess registryAccess() {
+ return RegistryAccessHolder.INSTANCE.orElseThrow(() -> new IllegalStateException("No RegistryAccess implementation found")); + return RegistryAccessHolder.INSTANCE.orElseThrow(() -> new IllegalStateException("No RegistryAccess implementation found"));
+ } + }
+ +
@ -134,7 +135,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated use {@link #getRegistry(RegistryKey)} with keys from {@link RegistryKey} + * @deprecated use {@link #getRegistry(RegistryKey)} with keys from {@link RegistryKey}
+ */ + */
+ @Deprecated(since = "1.20.6", forRemoval = true) + @Deprecated(since = "1.20.6", forRemoval = true)
+ <T extends Keyed> @Nullable Registry<T> getRegistry(@NotNull Class<T> type); + <T extends Keyed> @Nullable Registry<T> getRegistry(Class<T> type);
+ +
+ /** + /**
+ * Gets the registry with the specified key. + * Gets the registry with the specified key.
@ -147,7 +148,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ */ + */
+ // Future note: We should have no trouble removing this generic qualifier when + // Future note: We should have no trouble removing this generic qualifier when
+ // registry types no longer have to be "keyed" as it shouldn't break ABI or API. + // registry types no longer have to be "keyed" as it shouldn't break ABI or API.
+ <T extends Keyed> @NotNull Registry<T> getRegistry(@NotNull RegistryKey<T> registryKey); + <T extends Keyed> Registry<T> getRegistry(RegistryKey<T> registryKey);
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java b/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java diff --git a/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java b/src/main/java/io/papermc/paper/registry/RegistryAccessHolder.java
new file mode 100644 new file mode 100644
@ -171,13 +172,13 @@ diff --git a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java --- a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java
+++ b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java +++ b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java
@@ -0,0 +0,0 @@ record RegistryKeyImpl<T>(@NotNull Key key) implements RegistryKey<T> { @@ -0,0 +0,0 @@ record RegistryKeyImpl<T>(Key key) implements RegistryKey<T> {
static final Set<RegistryKey<?>> REGISTRY_KEYS = Sets.newIdentityHashSet(); static final Set<RegistryKey<?>> REGISTRY_KEYS = Sets.newIdentityHashSet();
+ // override equals and hashCode to this can be used to simulate an "identity" hashmap + // override equals and hashCode to this can be used to simulate an "identity" hashmap
+ @Override + @Override
+ public boolean equals(final Object obj) { + public boolean equals(final @Nullable Object obj) {
+ return obj == this; + return obj == this;
+ } + }
+ +

View File

@ -14,11 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import net.kyori.adventure.sound.Sound; +import net.kyori.adventure.sound.Sound;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents an entity that can be sheared. + * Represents an entity that can be sheared.
+ */ + */
+@NullMarked
+public interface Shearable extends Entity { +public interface Shearable extends Entity {
+ +
+ /** + /**
@ -44,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param source Sound source to play any sound effects on + * @param source Sound source to play any sound effects on
+ */ + */
+ void shear(@NotNull Sound.Source source); + void shear(Sound.Source source);
+ +
+ /** + /**
+ * Gets if the entity would be able to be sheared or not naturally using shears. + * Gets if the entity would be able to be sheared or not naturally using shears.

View File

@ -12,40 +12,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.util; +package io.papermc.paper.util;
+ +
+import net.kyori.adventure.util.Ticks;
+import org.jetbrains.annotations.NotNull;
+
+import java.time.Duration; +import java.time.Duration;
+import java.time.temporal.ChronoUnit; +import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal; +import java.time.temporal.Temporal;
+import java.time.temporal.TemporalUnit; +import java.time.temporal.TemporalUnit;
+import java.util.Objects; +import java.util.Objects;
+import net.kyori.adventure.util.Ticks;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A TemporalUnit that represents the target length of one server tick. This is defined + * A TemporalUnit that represents the target length of one server tick. This is defined
+ * as 50 milliseconds. Note that this class is not for measuring the length that a tick + * as 50 milliseconds. Note that this class is not for measuring the length that a tick
+ * took, rather it is used for simple conversion between times and ticks. + * took, rather it is used for simple conversion between times and ticks.
+ *
+ * @see #tick() + * @see #tick()
+ */ + */
+@NullMarked
+public final class Tick implements TemporalUnit { +public final class Tick implements TemporalUnit {
+
+ private static final Tick INSTANCE = new Tick(Ticks.SINGLE_TICK_DURATION_MS); + private static final Tick INSTANCE = new Tick(Ticks.SINGLE_TICK_DURATION_MS);
+ +
+ private final long milliseconds; + private final long milliseconds;
+ +
+ /** + /**
+ * Gets the instance of the tick temporal unit. + * Gets the instance of the tick temporal unit.
+ *
+ * @return the tick instance + * @return the tick instance
+ */ + */
+ public static @NotNull Tick tick() { + public static Tick tick() {
+ return INSTANCE; + return INSTANCE;
+ } + }
+ +
+ /** + /**
+ * Creates a new tick. + * Creates a new tick.
+ *
+ * @param length the length of the tick in milliseconds + * @param length the length of the tick in milliseconds
+ * @see #tick() + * @see #tick()
+ */ + */
+ private Tick(long length) { + private Tick(final long length) {
+ this.milliseconds = length; + this.milliseconds = length;
+ } + }
+ +
@ -53,27 +57,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * Creates a duration from an amount of ticks. This is shorthand for + * Creates a duration from an amount of ticks. This is shorthand for
+ * {@link Duration#of(long, TemporalUnit)} called with the amount of ticks and + * {@link Duration#of(long, TemporalUnit)} called with the amount of ticks and
+ * {@link #tick()}. + * {@link #tick()}.
+ *
+ * @param ticks the amount of ticks + * @param ticks the amount of ticks
+ * @return the duration + * @return the duration
+ */ + */
+ public static @NotNull Duration of(long ticks) { + public static Duration of(final long ticks) {
+ return Duration.of(ticks, INSTANCE); + return Duration.of(ticks, INSTANCE);
+ } + }
+ +
+ /** + /**
+ * Gets the number of whole ticks that occur in the provided duration. Note that this + * Gets the number of whole ticks that occur in the provided duration. Note that this
+ * method returns an {@code int} as this is the unit that Minecraft stores ticks in. + * method returns an {@code int} as this is the unit that Minecraft stores ticks in.
+ *
+ * @param duration the duration + * @param duration the duration
+ * @return the number of whole ticks in this duration + * @return the number of whole ticks in this duration
+ * @throws ArithmeticException if the duration is zero or an overflow occurs + * @throws ArithmeticException if the duration is zero or an overflow occurs
+ */ + */
+ public int fromDuration(@NotNull Duration duration) { + public int fromDuration(final Duration duration) {
+ Objects.requireNonNull(duration, "duration cannot be null"); + Objects.requireNonNull(duration, "duration cannot be null");
+ return Math.toIntExact(Math.floorDiv(duration.toMillis(), this.milliseconds)); + return Math.toIntExact(Math.floorDiv(duration.toMillis(), this.milliseconds));
+ } + }
+ +
+ @Override + @Override
+ public @NotNull Duration getDuration() { + public Duration getDuration() {
+ return Duration.ofMillis(this.milliseconds); + return Duration.ofMillis(this.milliseconds);
+ } + }
+ +
@ -96,12 +102,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @SuppressWarnings("unchecked") // following ChronoUnit#addTo + @SuppressWarnings("unchecked") // following ChronoUnit#addTo
+ @Override + @Override
+ public <R extends Temporal> @NotNull R addTo(@NotNull R temporal, long amount) { + public <R extends Temporal> R addTo(final R temporal, final long amount) {
+ return (R) temporal.plus(getDuration().multipliedBy(amount)); + return (R) temporal.plus(this.getDuration().multipliedBy(amount));
+ } + }
+ +
+ @Override + @Override
+ public long between(@NotNull Temporal start, @NotNull Temporal end) { + public long between(final Temporal start, final Temporal end) {
+ return start.until(end, ChronoUnit.MILLIS) / this.milliseconds; + return start.until(end, ChronoUnit.MILLIS) / this.milliseconds;
+ } + }
+} +}

View File

@ -19,22 +19,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.event.HandlerList; +import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Thrown when a player executes a command that is not defined + * Thrown when a player executes a command that is not defined
+ */ + */
+@NullMarked
+public class UnknownCommandEvent extends Event { +public class UnknownCommandEvent extends Event {
+ +
+ private static final HandlerList HANDLER_LIST = new HandlerList(); + private static final HandlerList HANDLER_LIST = new HandlerList();
+ +
+ @NotNull private final CommandSender sender; + private final CommandSender sender;
+ @NotNull private final String commandLine; + private final String commandLine;
+ @Nullable private Component message; + private @Nullable Component message;
+ +
+ @ApiStatus.Internal + @ApiStatus.Internal
+ public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final Component message) { + public UnknownCommandEvent(final CommandSender sender, final String commandLine, final @Nullable Component message) {
+ super(false); + super(false);
+ this.sender = sender; + this.sender = sender;
+ this.commandLine = commandLine; + this.commandLine = commandLine;
@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Sender of the command + * @return Sender of the command
+ */ + */
+ @NotNull
+ public CommandSender getSender() { + public CommandSender getSender() {
+ return this.sender; + return this.sender;
+ } + }
@ -56,7 +56,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Command sent + * @return Command sent
+ */ + */
+ @NotNull
+ public String getCommandLine() { + public String getCommandLine() {
+ return this.commandLine; + return this.commandLine;
+ } + }
@ -67,9 +66,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return Unknown command message + * @return Unknown command message
+ * @deprecated use {@link #message()} + * @deprecated use {@link #message()}
+ */ + */
+ @Nullable
+ @Deprecated + @Deprecated
+ public String getMessage() { + public @Nullable String getMessage() {
+ return this.message == null ? null : LegacyComponentSerializer.legacySection().serialize(this.message); + return this.message == null ? null : LegacyComponentSerializer.legacySection().serialize(this.message);
+ } + }
+ +
@ -91,9 +89,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Unknown command message + * @return Unknown command message
+ */ + */
+ @Nullable
+ @Contract(pure = true) + @Contract(pure = true)
+ public Component message() { + public @Nullable Component message() {
+ return this.message; + return this.message;
+ } + }
+ +
@ -108,13 +105,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.message = message; + this.message = message;
+ } + }
+ +
+ @NotNull
+ @Override + @Override
+ public HandlerList getHandlers() { + public HandlerList getHandlers() {
+ return HANDLER_LIST; + return HANDLER_LIST;
+ } + }
+ +
+ @NotNull
+ public static HandlerList getHandlerList() { + public static HandlerList getHandlerList() {
+ return HANDLER_LIST; + return HANDLER_LIST;
+ } + }

View File

@ -16,14 +16,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Set; +import java.util.Set;
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import org.bukkit.FeatureFlag; +import org.bukkit.FeatureFlag;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * This is a snapshot of a datapack on the server. It + * This is a snapshot of a datapack on the server. It
+ * won't be updated as datapacks are updated. + * won't be updated as datapacks are updated.
+ */ + */
+@NullMarked
+public interface Datapack { +public interface Datapack {
+ +
+ /** + /**
@ -32,21 +33,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the name of the pack + * @return the name of the pack
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ @NonNull String getName(); + String getName();
+ +
+ /** + /**
+ * Gets the title component of this datapack. + * Gets the title component of this datapack.
+ * + *
+ * @return the title + * @return the title
+ */ + */
+ @NonNull Component getTitle(); + Component getTitle();
+ +
+ /** + /**
+ * Gets the description component of this datapack. + * Gets the description component of this datapack.
+ * + *
+ * @return the description + * @return the description
+ */ + */
+ @NonNull Component getDescription(); + Component getDescription();
+ +
+ /** + /**
+ * Gets if this datapack is required to be enabled. + * Gets if this datapack is required to be enabled.
@ -60,14 +61,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the compatibility of the pack + * @return the compatibility of the pack
+ */ + */
+ @NonNull Compatibility getCompatibility(); + Compatibility getCompatibility();
+ +
+ /** + /**
+ * Gets the set of required features for this datapack. + * Gets the set of required features for this datapack.
+ * + *
+ * @return the set of required features + * @return the set of required features
+ */ + */
+ @NonNull @Unmodifiable Set<FeatureFlag> getRequiredFeatures(); + @Unmodifiable Set<FeatureFlag> getRequiredFeatures();
+ +
+ /** + /**
+ * Gets the enabled state of this pack. + * Gets the enabled state of this pack.
@ -91,7 +92,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the pack source + * @return the pack source
+ */ + */
+ @NonNull DatapackSource getSource(); + DatapackSource getSource();
+ +
+ /** + /**
+ * Computes the component vanilla Minecraft uses + * Computes the component vanilla Minecraft uses
@ -101,7 +102,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new component + * @return a new component
+ */ + */
+ @Contract(pure = true, value = "-> new") + @Contract(pure = true, value = "-> new")
+ @NonNull Component computeDisplayName(); + Component computeDisplayName();
+ +
+ enum Compatibility { + enum Compatibility {
+ TOO_OLD, + TOO_OLD,
@ -117,12 +118,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.datapack; +package io.papermc.paper.datapack;
+ +
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+import java.util.Collection; +import java.util.Collection;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+public interface DatapackManager { +public interface DatapackManager {
+ +
+ /** + /**
@ -140,7 +141,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param name the name/id of the datapack + * @param name the name/id of the datapack
+ * @return the datapack, or null if not found + * @return the datapack, or null if not found
+ */ + */
+ @Nullable Datapack getPack(@NonNull String name); + @Nullable Datapack getPack(String name);
+ +
+ /** + /**
+ * Gets the available datapacks. May require calling {@link #refreshPacks()} before + * Gets the available datapacks. May require calling {@link #refreshPacks()} before
@ -148,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return all the packs known to the server + * @return all the packs known to the server
+ */ + */
+ @NonNull @Unmodifiable Collection<Datapack> getPacks(); + @Unmodifiable Collection<Datapack> getPacks();
+ +
+ /** + /**
+ * Gets the enabled datapacks. May require calling {@link #refreshPacks()} before + * Gets the enabled datapacks. May require calling {@link #refreshPacks()} before
@ -156,7 +157,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return all the packs which are currently enabled + * @return all the packs which are currently enabled
+ */ + */
+ @NonNull @Unmodifiable Collection<Datapack> getEnabledPacks(); + @Unmodifiable Collection<Datapack> getEnabledPacks();
+} +}
diff --git a/src/main/java/io/papermc/paper/datapack/DatapackSource.java b/src/main/java/io/papermc/paper/datapack/DatapackSource.java diff --git a/src/main/java/io/papermc/paper/datapack/DatapackSource.java b/src/main/java/io/papermc/paper/datapack/DatapackSource.java
new file mode 100644 new file mode 100644
@ -166,9 +167,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.datapack; +package io.papermc.paper.datapack;
+ +
+import org.jspecify.annotations.NullMarked;
+
+/** +/**
+ * Source of a datapack. + * Source of a datapack.
+ */ + */
+@NullMarked
+public sealed interface DatapackSource permits DatapackSourceImpl { +public sealed interface DatapackSource permits DatapackSourceImpl {
+ +
+ DatapackSource DEFAULT = create("default"); + DatapackSource DEFAULT = create("default");
@ -190,8 +194,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.datapack; +package io.papermc.paper.datapack;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@NullMarked
+record DatapackSourceImpl(String name) implements DatapackSource { +record DatapackSourceImpl(String name) implements DatapackSource {
+ +
+ @Override + @Override

View File

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.world; +package io.papermc.paper.world;
+ +
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap; +import java.util.HashMap;
+import java.util.Map; +import java.util.Map;
+import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+public enum MoonPhase { +public enum MoonPhase {
+ FULL_MOON(0L), + FULL_MOON(0L),
+ WANING_GIBBOUS(1L), + WANING_GIBBOUS(1L),
@ -29,20 +29,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ private final long day; + private final long day;
+ +
+ MoonPhase(long day) { + MoonPhase(final long day) {
+ this.day = day; + this.day = day;
+ } + }
+ +
+ private static final Map<Long, MoonPhase> BY_DAY = new HashMap<>(); + private static final Map<Long, MoonPhase> BY_DAY = new HashMap<>();
+ +
+ static { + static {
+ for (MoonPhase phase : values()) { + for (final MoonPhase phase : values()) {
+ BY_DAY.put(phase.day, phase); + BY_DAY.put(phase.day, phase);
+ } + }
+ } + }
+ +
+ @NotNull + public static MoonPhase getPhase(final long day) {
+ public static MoonPhase getPhase(long day) {
+ return BY_DAY.get(day % 8L); + return BY_DAY.get(day % 8L);
+ } + }
+} +}

View File

@ -20,8 +20,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.util.Index; +import net.kyori.adventure.util.Index;
+import org.bukkit.NamespacedKey; +import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Describes the display of an advancement. + * Describes the display of an advancement.
@ -29,6 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * The display is used in the chat, in the toast messages and the advancements + * The display is used in the chat, in the toast messages and the advancements
+ * screen. + * screen.
+ */ + */
+@NullMarked
+public interface AdvancementDisplay { +public interface AdvancementDisplay {
+ +
+ /** + /**
@ -39,7 +40,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the frame type + * @return the frame type
+ */ + */
+ @NotNull
+ Frame frame(); + Frame frame();
+ +
+ /** + /**
@ -47,7 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the title + * @return the title
+ */ + */
+ @NotNull
+ Component title(); + Component title();
+ +
+ /** + /**
@ -55,7 +54,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the description + * @return the description
+ */ + */
+ @NotNull
+ Component description(); + Component description();
+ +
+ /** + /**
@ -63,7 +61,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a copy of the icon + * @return a copy of the icon
+ */ + */
+ @NotNull
+ ItemStack icon(); + ItemStack icon();
+ +
+ /** + /**
@ -104,8 +101,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the background texture path + * @return the background texture path
+ */ + */
+ @Nullable + @Nullable NamespacedKey backgroundPath();
+ NamespacedKey backgroundPath();
+ +
+ /** + /**
+ * Gets the formatted display name for this display. This + * Gets the formatted display name for this display. This
@ -115,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the display name + * @return the display name
+ * @see org.bukkit.advancement.Advancement#displayName() + * @see org.bukkit.advancement.Advancement#displayName()
+ */ + */
+ @NotNull Component displayName(); + Component displayName();
+ +
+ /** + /**
+ * Defines how the {@link #icon()} appears in the advancements screen and + * Defines how the {@link #icon()} appears in the advancements screen and
@ -148,7 +144,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private final String name; + private final String name;
+ private final TextColor color; + private final TextColor color;
+ +
+ Frame(String name, TextColor color) { + Frame(final String name, final TextColor color) {
+ this.name = name; + this.name = name;
+ this.color = color; + this.color = color;
+ } + }
@ -158,7 +154,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the text color + * @return the text color
+ */ + */
+ @NotNull
+ public TextColor color() { + public TextColor color() {
+ return this.color; + return this.color;
+ } + }
@ -171,7 +166,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the toast message key + * @return the toast message key
+ */ + */
+ @Override + @Override
+ @NotNull
+ public String translationKey() { + public String translationKey() {
+ return "advancements.toast." + this.name; + return "advancements.toast." + this.name;
+ } + }

View File

@ -13,10 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package com.destroystokyo.paper.entity.villager; +package com.destroystokyo.paper.entity.villager;
+ +
+import com.google.common.base.Preconditions; +import com.google.common.base.Preconditions;
+
+import java.util.EnumMap; +import java.util.EnumMap;
+import java.util.Map; +import java.util.Map;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
@ -31,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this(new EnumMap<>(ReputationType.class)); + this(new EnumMap<>(ReputationType.class));
+ } + }
+ +
+ public Reputation(Map<ReputationType, Integer> reputation) { + public Reputation(final Map<ReputationType, Integer> reputation) {
+ Preconditions.checkNotNull(reputation, "reputation cannot be null"); + Preconditions.checkNotNull(reputation, "reputation cannot be null");
+ this.reputation = reputation; + this.reputation = reputation;
+ } + }
@ -42,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param type The {@link ReputationType type} of reputation to get. + * @param type The {@link ReputationType type} of reputation to get.
+ * @return The value of the {@link ReputationType type}. + * @return The value of the {@link ReputationType type}.
+ */ + */
+ public int getReputation(ReputationType type) { + public int getReputation(final ReputationType type) {
+ Preconditions.checkNotNull(type, "the reputation type cannot be null"); + Preconditions.checkNotNull(type, "the reputation type cannot be null");
+ return this.reputation.getOrDefault(type, 0); + return this.reputation.getOrDefault(type, 0);
+ } + }
@ -53,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param type The {@link ReputationType type} of reputation to set. + * @param type The {@link ReputationType type} of reputation to set.
+ * @param value The value of the {@link ReputationType type}. + * @param value The value of the {@link ReputationType type}.
+ */ + */
+ public void setReputation(ReputationType type, int value) { + public void setReputation(final ReputationType type, final int value) {
+ Preconditions.checkNotNull(type, "the reputation type cannot be null"); + Preconditions.checkNotNull(type, "the reputation type cannot be null");
+ this.reputation.put(type, value); + this.reputation.put(type, value);
+ } + }
@ -64,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param type The {@link ReputationType type} to check + * @param type The {@link ReputationType type} to check
+ * @return If there is a value for this {@link ReputationType type} set. + * @return If there is a value for this {@link ReputationType type} set.
+ */ + */
+ public boolean hasReputationSet(ReputationType type) { + public boolean hasReputationSet(final ReputationType type) {
+ return this.reputation.containsKey(type); + return this.reputation.containsKey(type);
+ } + }
+} +}

View File

@ -101,13 +101,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player; +import org.bukkit.entity.Player;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A chat renderer is responsible for rendering chat messages sent by {@link Player}s to the server. + * A chat renderer is responsible for rendering chat messages sent by {@link Player}s to the server.
+ */ + */
+@NullMarked
+@FunctionalInterface +@FunctionalInterface
+public interface ChatRenderer { +public interface ChatRenderer {
+
+ /** + /**
+ * Renders a chat message. This will be called once for each receiving {@link Audience}. + * Renders a chat message. This will be called once for each receiving {@link Audience}.
+ * + *
@ -118,15 +120,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a rendered chat message + * @return a rendered chat message
+ */ + */
+ @ApiStatus.OverrideOnly + @ApiStatus.OverrideOnly
+ @NotNull + Component render(Player source, Component sourceDisplayName, Component message, Audience viewer);
+ Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer);
+ +
+ /** + /**
+ * Create a new instance of the default {@link ChatRenderer}. + * Create a new instance of the default {@link ChatRenderer}.
+ * + *
+ * @return a new {@link ChatRenderer} + * @return a new {@link ChatRenderer}
+ */ + */
+ @NotNull
+ static ChatRenderer defaultRenderer() { + static ChatRenderer defaultRenderer() {
+ return new ViewerUnawareImpl.Default((source, sourceDisplayName, message) -> Component.translatable("chat.type.text", sourceDisplayName, message)); + return new ViewerUnawareImpl.Default((source, sourceDisplayName, message) -> Component.translatable("chat.type.text", sourceDisplayName, message));
+ } + }
@ -142,8 +142,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param renderer the viewer unaware renderer + * @param renderer the viewer unaware renderer
+ * @return a new {@link ChatRenderer} + * @return a new {@link ChatRenderer}
+ */ + */
+ @NotNull + static ChatRenderer viewerUnaware(final ViewerUnaware renderer) {
+ static ChatRenderer viewerUnaware(final @NotNull ViewerUnaware renderer) {
+ return new ViewerUnawareImpl(renderer); + return new ViewerUnawareImpl(renderer);
+ } + }
+ +
@ -153,6 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see ChatRenderer#viewerUnaware(ViewerUnaware) + * @see ChatRenderer#viewerUnaware(ViewerUnaware)
+ */ + */
+ interface ViewerUnaware { + interface ViewerUnaware {
+
+ /** + /**
+ * Renders a chat message. + * Renders a chat message.
+ * + *
@ -162,8 +162,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a rendered chat message + * @return a rendered chat message
+ */ + */
+ @ApiStatus.OverrideOnly + @ApiStatus.OverrideOnly
+ @NotNull + Component render(Player source, Component sourceDisplayName, Component message);
+ Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message);
+ } + }
+} +}
diff --git a/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java b/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java diff --git a/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java b/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java
@ -177,9 +176,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player; +import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+@ApiStatus.Internal
+@NullMarked
+sealed class ViewerUnawareImpl implements ChatRenderer, ChatRenderer.ViewerUnaware permits ViewerUnawareImpl.Default { +sealed class ViewerUnawareImpl implements ChatRenderer, ChatRenderer.ViewerUnaware permits ViewerUnawareImpl.Default {
+ private final ViewerUnaware unaware; + private final ViewerUnaware unaware;
+ private @Nullable Component message; + private @Nullable Component message;
@ -189,12 +191,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public @NotNull Component render(final @NotNull Player source, final @NotNull Component sourceDisplayName, final @NotNull Component message, final @NotNull Audience viewer) { + public Component render(final Player source, final Component sourceDisplayName, final Component message, final Audience viewer) {
+ return this.render(source, sourceDisplayName, message); + return this.render(source, sourceDisplayName, message);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull Component render(final @NotNull Player source, final @NotNull Component sourceDisplayName, final @NotNull Component message) { + public Component render(final Player source, final Component sourceDisplayName, final Component message) {
+ if (this.message == null) { + if (this.message == null) {
+ this.message = this.unaware.render(source, sourceDisplayName, message); + this.message = this.unaware.render(source, sourceDisplayName, message);
+ } + }
@ -585,6 +587,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.text; +package io.papermc.paper.text;
+ +
+import java.io.IOException;
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.flattener.ComponentFlattener; +import net.kyori.adventure.text.flattener.ComponentFlattener;
+import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.NamedTextColor;
@ -595,15 +598,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.Bukkit; +import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+
+import java.io.IOException;
+ +
+/** +/**
+ * Paper API-specific methods for working with {@link Component}s and related. + * Paper API-specific methods for working with {@link Component}s and related.
+ */ + */
+@NullMarked
+public final class PaperComponents { +public final class PaperComponents {
+
+ private PaperComponents() { + private PaperComponents() {
+ throw new RuntimeException("PaperComponents is not to be instantiated!"); + throw new RuntimeException("PaperComponents is not to be instantiated!");
+ } + }
@ -633,7 +636,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the resolved component + * @return the resolved component
+ * @throws IOException if a syntax error tripped during resolving + * @throws IOException if a syntax error tripped during resolving
+ */ + */
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject) throws IOException { + public static Component resolveWithContext(final Component input, final @Nullable CommandSender context, final @Nullable Entity scoreboardSubject) throws IOException {
+ return resolveWithContext(input, context, scoreboardSubject, true); + return resolveWithContext(input, context, scoreboardSubject, true);
+ } + }
+ +
@ -664,7 +667,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the resolved component + * @return the resolved component
+ * @throws IOException if a syntax error tripped during resolving + * @throws IOException if a syntax error tripped during resolving
+ */ + */
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject, boolean bypassPermissions) throws IOException { + @SuppressWarnings("deprecation") // using unsafe as a bridge
+ public static Component resolveWithContext(final Component input, final @Nullable CommandSender context, final @Nullable Entity scoreboardSubject, final boolean bypassPermissions) throws IOException {
+ return Bukkit.getUnsafe().resolveWithContext(input, context, scoreboardSubject, bypassPermissions); + return Bukkit.getUnsafe().resolveWithContext(input, context, scoreboardSubject, bypassPermissions);
+ } + }
+ +
@ -673,7 +677,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a component flattener + * @return a component flattener
+ */ + */
+ public static @NotNull ComponentFlattener flattener() { + @SuppressWarnings("deprecation") // using unsafe as a bridge
+ public static ComponentFlattener flattener() {
+ return Bukkit.getUnsafe().componentFlattener(); + return Bukkit.getUnsafe().componentFlattener();
+ } + }
+ +
@ -688,7 +693,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated will be removed in adventure 5.0.0, use {@link PlainTextComponentSerializer#plainText()} + * @deprecated will be removed in adventure 5.0.0, use {@link PlainTextComponentSerializer#plainText()}
+ */ + */
+ @Deprecated(forRemoval = true, since = "1.18.1") + @Deprecated(forRemoval = true, since = "1.18.1")
+ public static @NotNull PlainComponentSerializer plainSerializer() { + public static PlainComponentSerializer plainSerializer() {
+ return Bukkit.getUnsafe().plainComponentSerializer(); + return Bukkit.getUnsafe().plainComponentSerializer();
+ } + }
+ +
@ -703,7 +708,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated use {@link PlainTextComponentSerializer#plainText()} + * @deprecated use {@link PlainTextComponentSerializer#plainText()}
+ */ + */
+ @Deprecated(forRemoval = true, since = "1.18.2") + @Deprecated(forRemoval = true, since = "1.18.2")
+ public static @NotNull PlainTextComponentSerializer plainTextSerializer() { + public static PlainTextComponentSerializer plainTextSerializer() {
+ return Bukkit.getUnsafe().plainTextSerializer(); + return Bukkit.getUnsafe().plainTextSerializer();
+ } + }
+ +
@ -719,7 +724,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated use {@link GsonComponentSerializer#gson()} + * @deprecated use {@link GsonComponentSerializer#gson()}
+ */ + */
+ @Deprecated(forRemoval = true, since = "1.18.2") + @Deprecated(forRemoval = true, since = "1.18.2")
+ public static @NotNull GsonComponentSerializer gsonSerializer() { + public static GsonComponentSerializer gsonSerializer() {
+ return Bukkit.getUnsafe().gsonComponentSerializer(); + return Bukkit.getUnsafe().gsonComponentSerializer();
+ } + }
+ +
@ -736,7 +741,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated use {@link GsonComponentSerializer#colorDownsamplingGson()} + * @deprecated use {@link GsonComponentSerializer#colorDownsamplingGson()}
+ */ + */
+ @Deprecated(forRemoval = true, since = "1.18.2") + @Deprecated(forRemoval = true, since = "1.18.2")
+ public static @NotNull GsonComponentSerializer colorDownsamplingGsonSerializer() { + public static GsonComponentSerializer colorDownsamplingGsonSerializer() {
+ return Bukkit.getUnsafe().colorDownsamplingGsonComponentSerializer(); + return Bukkit.getUnsafe().colorDownsamplingGsonComponentSerializer();
+ } + }
+ +
@ -756,7 +761,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @deprecated use {@link LegacyComponentSerializer#legacySection()} + * @deprecated use {@link LegacyComponentSerializer#legacySection()}
+ */ + */
+ @Deprecated(forRemoval = true, since = "1.18.2") + @Deprecated(forRemoval = true, since = "1.18.2")
+ public static @NotNull LegacyComponentSerializer legacySectionSerializer() { + public static LegacyComponentSerializer legacySectionSerializer() {
+ return Bukkit.getUnsafe().legacyComponentSerializer(); + return Bukkit.getUnsafe().legacyComponentSerializer();
+ } + }
+} +}

View File

@ -362,9 +362,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.util; +package io.papermc.paper.util;
+ +
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.AbstractList; +import java.util.AbstractList;
+import java.util.Iterator; +import java.util.Iterator;
+import java.util.List; +import java.util.List;
@ -372,6 +369,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.RandomAccess; +import java.util.RandomAccess;
+import java.util.function.Function; +import java.util.function.Function;
+import java.util.function.Predicate; +import java.util.function.Predicate;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkNotNull;
+ +
@ -381,7 +380,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <F> backing list element type + * @param <F> backing list element type
+ * @param <T> transformed list element type + * @param <T> transformed list element type
+ */ + */
+@NullMarked
+@ApiStatus.Internal
+public final class TransformingRandomAccessList<F, T> extends AbstractList<T> implements RandomAccess { +public final class TransformingRandomAccessList<F, T> extends AbstractList<T> implements RandomAccess {
+
+ final List<F> fromList; + final List<F> fromList;
+ final Function<? super F, ? extends T> toFunction; + final Function<? super F, ? extends T> toFunction;
+ final Function<? super T, ? extends F> fromFunction; + final Function<? super T, ? extends F> fromFunction;
@ -394,9 +396,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param fromFunction function mapping transformed list element type to backing list element type + * @param fromFunction function mapping transformed list element type to backing list element type
+ */ + */
+ public TransformingRandomAccessList( + public TransformingRandomAccessList(
+ final @NonNull List<F> fromList, + final List<F> fromList,
+ final @NonNull Function<? super F, ? extends T> toFunction, + final Function<? super F, ? extends T> toFunction,
+ final @NonNull Function<? super T, ? extends F> fromFunction + final Function<? super T, ? extends F> fromFunction
+ ) { + ) {
+ this.fromList = checkNotNull(fromList); + this.fromList = checkNotNull(fromList);
+ this.toFunction = checkNotNull(toFunction); + this.toFunction = checkNotNull(toFunction);
@ -409,25 +411,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public T get(int index) { + public T get(final int index) {
+ return this.toFunction.apply(this.fromList.get(index)); + return this.toFunction.apply(this.fromList.get(index));
+ } + }
+ +
+ @Override + @Override
+ public @NotNull Iterator<T> iterator() { + public Iterator<T> iterator() {
+ return this.listIterator(); + return this.listIterator();
+ } + }
+ +
+ @Override + @Override
+ public @NotNull ListIterator<T> listIterator(int index) { + public ListIterator<T> listIterator(final int index) {
+ return new TransformedListIterator<F, T>(this.fromList.listIterator(index)) { + return new TransformedListIterator<>(this.fromList.listIterator(index)) {
+ @Override + @Override
+ T transform(F from) { + T transform(final F from) {
+ return TransformingRandomAccessList.this.toFunction.apply(from); + return TransformingRandomAccessList.this.toFunction.apply(from);
+ } + }
+ +
+ @Override + @Override
+ F transformBack(T from) { + F transformBack(final T from) {
+ return TransformingRandomAccessList.this.fromFunction.apply(from); + return TransformingRandomAccessList.this.fromFunction.apply(from);
+ } + }
+ }; + };
@ -439,13 +441,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public boolean removeIf(Predicate<? super T> filter) { + public boolean removeIf(final Predicate<? super T> filter) {
+ checkNotNull(filter); + checkNotNull(filter);
+ return this.fromList.removeIf(element -> filter.test(this.toFunction.apply(element))); + return this.fromList.removeIf(element -> filter.test(this.toFunction.apply(element)));
+ } + }
+ +
+ @Override + @Override
+ public T remove(int index) { + public T remove(final int index) {
+ return this.toFunction.apply(this.fromList.remove(index)); + return this.toFunction.apply(this.fromList.remove(index));
+ } + }
+ +
@ -455,19 +457,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public T set(int i, T t) { + public T set(final int i, final T t) {
+ return this.toFunction.apply(this.fromList.set(i, this.fromFunction.apply(t))); + return this.toFunction.apply(this.fromList.set(i, this.fromFunction.apply(t)));
+ } + }
+ +
+ @Override + @Override
+ public void add(int i, T t) { + public void add(final int i, final T t) {
+ this.fromList.add(i, this.fromFunction.apply(t)); + this.fromList.add(i, this.fromFunction.apply(t));
+ } + }
+ +
+ static abstract class TransformedListIterator<F, T> implements ListIterator<T>, Iterator<T> { + abstract static class TransformedListIterator<F, T> implements ListIterator<T>, Iterator<T> {
+
+ final Iterator<F> backingIterator; + final Iterator<F> backingIterator;
+ +
+ TransformedListIterator(ListIterator<F> backingIterator) { + TransformedListIterator(final ListIterator<F> backingIterator) {
+ this.backingIterator = checkNotNull((Iterator<F>) backingIterator); + this.backingIterator = checkNotNull((Iterator<F>) backingIterator);
+ } + }
+ +
@ -475,7 +478,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return cast(this.backingIterator); + return cast(this.backingIterator);
+ } + }
+ +
+ static <A> ListIterator<A> cast(Iterator<A> iterator) { + static <A> ListIterator<A> cast(final Iterator<A> iterator) {
+ return (ListIterator<A>) iterator; + return (ListIterator<A>) iterator;
+ } + }
+ +
@ -500,12 +503,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public void set(T element) { + public void set(final T element) {
+ this.backingIterator().set(this.transformBack(element)); + this.backingIterator().set(this.transformBack(element));
+ } + }
+ +
+ @Override + @Override
+ public void add(T element) { + public void add(final T element) {
+ this.backingIterator().add(this.transformBack(element)); + this.backingIterator().add(this.transformBack(element));
+ } + }
+ +

View File

@ -16,20 +16,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collection; +import java.util.Collection;
+import java.util.Set; +import java.util.Set;
+import java.util.UUID; +import java.util.UUID;
+
+import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletableFuture;
+import org.bukkit.profile.PlayerTextures; +import org.bukkit.profile.PlayerTextures;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Represents a players profile for the game, such as UUID, Name, and textures. + * Represents a players profile for the game, such as UUID, Name, and textures.
+ */ + */
+@NullMarked
+public interface PlayerProfile extends org.bukkit.profile.PlayerProfile { +public interface PlayerProfile extends org.bukkit.profile.PlayerProfile {
+ +
+ /** + /**
+ * @return The players name, if set + * @return The players name, if set
+ */ + */
+ @Override
+ @Nullable + @Nullable
+ String getName(); + String getName();
+ +
@ -39,14 +40,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param name The new Name + * @param name The new Name
+ * @return The previous Name + * @return The previous Name
+ */ + */
+ @NotNull
+ @Deprecated(forRemoval = true, since = "1.18.1") + @Deprecated(forRemoval = true, since = "1.18.1")
+ String setName(@Nullable String name); + String setName(@Nullable String name);
+ +
+ /** + /**
+ * @return The players unique identifier, if set + * @return The players unique identifier, if set
+ */ + */
+ @Nullable UUID getId(); + @Nullable
+ UUID getId();
+ +
+ /** + /**
+ * Sets this profiles UUID + * Sets this profiles UUID
@ -54,8 +55,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param uuid The new UUID + * @param uuid The new UUID
+ * @return The previous UUID + * @return The previous UUID
+ */ + */
+ @Nullable
+ @Deprecated(forRemoval = true, since = "1.18.1") + @Deprecated(forRemoval = true, since = "1.18.1")
+ @Nullable
+ UUID setId(@Nullable UUID uuid); + UUID setId(@Nullable UUID uuid);
+ +
+ /** + /**
@ -65,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the textures, not <code>null</code> + * @return the textures, not <code>null</code>
+ */ + */
+ @NotNull + @Override
+ PlayerTextures getTextures(); + PlayerTextures getTextures();
+ +
+ /** + /**
@ -74,16 +75,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param textures the textures to copy, or <code>null</code> to clear the + * @param textures the textures to copy, or <code>null</code> to clear the
+ * textures + * textures
+ */ + */
+ @Override
+ void setTextures(@Nullable PlayerTextures textures); + void setTextures(@Nullable PlayerTextures textures);
+ +
+ /** + /**
+ * @return A Mutable set of this players properties, such as textures. + * @return A Mutable set of this players properties, such as textures.
+ * Values specified here are subject to implementation details. + * Values specified here are subject to implementation details.
+ */ + */
+ @NotNull Set<ProfileProperty> getProperties(); + Set<ProfileProperty> getProperties();
+ +
+ /** + /**
+ * Check if the Profile has the specified property + * Check if the Profile has the specified property
+ *
+ * @param property Property name to check + * @param property Property name to check
+ * @return If the property is set + * @return If the property is set
+ */ + */
@ -95,17 +98,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param property Property to set. + * @param property Property to set.
+ * @throws IllegalArgumentException if setting the property results in more than 16 properties + * @throws IllegalArgumentException if setting the property results in more than 16 properties
+ */ + */
+ void setProperty(@NotNull ProfileProperty property); + void setProperty(ProfileProperty property);
+ +
+ /** + /**
+ * Sets multiple properties. If any of the set properties already exist, it will be replaced + * Sets multiple properties. If any of the set properties already exist, it will be replaced
+ *
+ * @param properties The properties to set + * @param properties The properties to set
+ * @throws IllegalArgumentException if the number of properties exceeds 16 + * @throws IllegalArgumentException if the number of properties exceeds 16
+ */ + */
+ void setProperties(@NotNull Collection<ProfileProperty> properties); + void setProperties(Collection<ProfileProperty> properties);
+ +
+ /** + /**
+ * Removes a specific property from this profile + * Removes a specific property from this profile
+ *
+ * @param property The property to remove + * @param property The property to remove
+ * @return If a property was removed + * @return If a property was removed
+ */ + */
@ -113,22 +118,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ /** + /**
+ * Removes a specific property from this profile + * Removes a specific property from this profile
+ *
+ * @param property The property to remove + * @param property The property to remove
+ * @return If a property was removed + * @return If a property was removed
+ */ + */
+ default boolean removeProperty(@NotNull ProfileProperty property) { + default boolean removeProperty(final ProfileProperty property) {
+ return removeProperty(property.getName()); + return this.removeProperty(property.getName());
+ } + }
+ +
+ /** + /**
+ * Removes all properties in the collection + * Removes all properties in the collection
+ *
+ * @param properties The properties to remove + * @param properties The properties to remove
+ * @return If any property was removed + * @return If any property was removed
+ */ + */
+ default boolean removeProperties(@NotNull Collection<ProfileProperty> properties) { + default boolean removeProperties(final Collection<ProfileProperty> properties) {
+ boolean removed = false; + boolean removed = false;
+ for (ProfileProperty property : properties) { + for (final ProfileProperty property : properties) {
+ if (removeProperty(property)) { + if (this.removeProperty(property)) {
+ removed = true; + removed = true;
+ } + }
+ } + }
@ -143,6 +150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /** + /**
+ * @return If the profile is now complete (has UUID and Name) + * @return If the profile is now complete (has UUID and Name)
+ */ + */
+ @Override
+ boolean isComplete(); + boolean isComplete();
+ +
+ /** + /**
@ -175,21 +183,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /** + /**
+ * If this profile is not complete, then make the API call to complete it. + * If this profile is not complete, then make the API call to complete it.
+ * This is a blocking operation and should be done asynchronously. + * This is a blocking operation and should be done asynchronously.
+ * + * <p>
+ * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}} + * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}}
+ *
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) + * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
+ */ + */
+ default boolean complete() { + default boolean complete() {
+ return complete(true); + return this.complete(true);
+ } + }
+ +
+ /** + /**
+ * If this profile is not complete, then make the API call to complete it. + * If this profile is not complete, then make the API call to complete it.
+ * This is a blocking operation and should be done asynchronously. + * This is a blocking operation and should be done asynchronously.
+ * + * <p>
+ * Optionally will also fill textures. + * Optionally will also fill textures.
+ * + * <p>
+ * Online mode will be automatically determined + * Online mode will be automatically determined
+ *
+ * @param textures controls if we should fill the profile with texture properties + * @param textures controls if we should fill the profile with texture properties
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) + * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
+ */ + */
@ -198,8 +208,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /** + /**
+ * If this profile is not complete, then make the API call to complete it. + * If this profile is not complete, then make the API call to complete it.
+ * This is a blocking operation and should be done asynchronously. + * This is a blocking operation and should be done asynchronously.
+ * + * <p>
+ * Optionally will also fill textures. + * Optionally will also fill textures.
+ *
+ * @param textures controls if we should fill the profile with texture properties + * @param textures controls if we should fill the profile with texture properties
+ * @param onlineMode Treat this server as online mode or not + * @param onlineMode Treat this server as online mode or not
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) + * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
@ -235,14 +246,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * </pre> + * </pre>
+ */ + */
+ @Override + @Override
+ @NotNull CompletableFuture<PlayerProfile> update(); + CompletableFuture<PlayerProfile> update();
+ +
+ /** + /**
+ * Whether this Profile has textures associated to it + * Whether this Profile has textures associated to it
+ *
+ * @return If it has a textures property + * @return If it has a textures property
+ */ + */
+ default boolean hasTextures() { + default boolean hasTextures() {
+ return hasProperty("textures"); + return this.hasProperty("textures");
+ } + }
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
@ -254,24 +266,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
+import com.google.common.base.Preconditions; +import com.google.common.base.Preconditions;
+
+import java.util.Objects; +import java.util.Objects;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Represents a property on a {@link PlayerProfile} + * Represents a property on a {@link PlayerProfile}
+ */ + */
+@NullMarked
+public final class ProfileProperty { +public final class ProfileProperty {
+
+ private final String name; + private final String name;
+ private final String value; + private final String value;
+ private final String signature; + private final @Nullable String signature;
+ +
+ public ProfileProperty(@NotNull String name, @NotNull String value) { + public ProfileProperty(final String name, final String value) {
+ this(name, value, null); + this(name, value, null);
+ } + }
+ +
+ public ProfileProperty(@NotNull String name, @NotNull String value, @Nullable String signature) { + public ProfileProperty(final String name, final String value, final @Nullable String signature) {
+ this.name = Preconditions.checkNotNull(name, "ProfileProperty name can not be null"); + this.name = Preconditions.checkNotNull(name, "ProfileProperty name can not be null");
+ this.value = Preconditions.checkNotNull(value, "ProfileProperty value can not be null"); + this.value = Preconditions.checkNotNull(value, "ProfileProperty value can not be null");
+ this.signature = signature; + this.signature = signature;
@ -283,25 +296,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /** + /**
+ * @return The property name, ie "textures" + * @return The property name, ie "textures"
+ */ + */
+ @NotNull
+ public String getName() { + public String getName() {
+ return name; + return this.name;
+ } + }
+ +
+ /** + /**
+ * @return The property value, likely to be base64 encoded + * @return The property value, likely to be base64 encoded
+ */ + */
+ @NotNull
+ public String getValue() { + public String getValue() {
+ return value; + return this.value;
+ } + }
+ +
+ /** + /**
+ * @return A signature from Mojang for signed properties + * @return A signature from Mojang for signed properties
+ */ + */
+ @Nullable + public @Nullable String getSignature() {
+ public String getSignature() { + return this.signature;
+ return signature;
+ } + }
+ +
+ /** + /**
@ -312,18 +322,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public boolean equals(Object o) { + public boolean equals(final @Nullable Object o) {
+ if (this == o) return true; + if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false; + if (o == null || this.getClass() != o.getClass()) return false;
+ ProfileProperty that = (ProfileProperty) o; + final ProfileProperty that = (ProfileProperty) o;
+ return Objects.equals(name, that.name) && + return Objects.equals(this.name, that.name) &&
+ Objects.equals(value, that.value) && + Objects.equals(this.value, that.value) &&
+ Objects.equals(signature, that.signature); + Objects.equals(this.signature, that.signature);
+ } + }
+ +
+ @Override + @Override
+ public int hashCode() { + public int hashCode() {
+ return Objects.hash(name); + return Objects.hash(this.name);
+ } + }
+} +}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java

View File

@ -512,14 +512,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collections; +import java.util.Collections;
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Implementing this interface allows for easily creating "Bukkit-style" {@code String[] args} commands. + * Implementing this interface allows for easily creating "Bukkit-style" {@code String[] args} commands.
+ * The implementation handles converting the command to a representation compatible with Brigadier on registration, usually in the form of {@literal /commandlabel <greedy_string>}. + * The implementation handles converting the command to a representation compatible with Brigadier on registration, usually in the form of {@literal /commandlabel <greedy_string>}.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@FunctionalInterface +@FunctionalInterface
+public interface BasicCommand { +public interface BasicCommand {
+ +
@ -530,7 +531,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param args the arguments of the command ignoring repeated spaces + * @param args the arguments of the command ignoring repeated spaces
+ */ + */
+ @ApiStatus.OverrideOnly + @ApiStatus.OverrideOnly
+ void execute(@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args); + void execute(CommandSourceStack commandSourceStack, String[] args);
+ +
+ /** + /**
+ * Suggests possible completions for the given command {@link CommandSourceStack} and arguments. + * Suggests possible completions for the given command {@link CommandSourceStack} and arguments.
@ -540,7 +541,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a collection of suggestions + * @return a collection of suggestions
+ */ + */
+ @ApiStatus.OverrideOnly + @ApiStatus.OverrideOnly
+ default @NotNull Collection<String> suggest(final @NotNull CommandSourceStack commandSourceStack, final @NotNull String[] args) { + default Collection<String> suggest(final CommandSourceStack commandSourceStack, final String[] args) {
+ return Collections.emptyList(); + return Collections.emptyList();
+ } + }
+ +
@ -552,8 +553,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #permission() + * @see #permission()
+ */ + */
+ @ApiStatus.OverrideOnly + @ApiStatus.OverrideOnly
+ default boolean canUse(final @NotNull CommandSender sender) { + default boolean canUse(final CommandSender sender) {
+ return this.permission() == null || sender.hasPermission(this.permission()); + final String permission = this.permission();
+ return permission == null || sender.hasPermission(permission);
+ } + }
+ +
+ /** + /**
@ -598,8 +600,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * The command source type for Brigadier commands registered using Paper API. + * The command source type for Brigadier commands registered using Paper API.
@ -613,8 +615,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * exist yet, or no specific sender is available. Methods on such a {@link CommandSender} + * exist yet, or no specific sender is available. Methods on such a {@link CommandSender}
+ * will either have no effect or throw an {@link UnsupportedOperationException}.</p> + * will either have no effect or throw an {@link UnsupportedOperationException}.</p>
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable
+public interface CommandSourceStack { +public interface CommandSourceStack {
+ +
+ /** + /**
@ -622,7 +625,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a cloned location instance. + * @return a cloned location instance.
+ */ + */
+ @NotNull Location getLocation(); + Location getLocation();
+ +
+ /** + /**
+ * Gets the command sender that executed this command. + * Gets the command sender that executed this command.
@ -631,7 +634,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the command sender instance + * @return the command sender instance
+ */ + */
+ @NotNull CommandSender getSender(); + CommandSender getSender();
+ +
+ /** + /**
+ * Gets the entity that executes this command. + * Gets the entity that executes this command.
@ -664,9 +667,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collections; +import java.util.Collections;
+import java.util.Set; +import java.util.Set;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * The registrar for custom commands. Supports Brigadier commands and {@link BasicCommand}. + * The registrar for custom commands. Supports Brigadier commands and {@link BasicCommand}.
@ -709,6 +712,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#COMMANDS + * @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#COMMANDS
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface Commands extends Registrar { +public interface Commands extends Registrar {
+ +
@ -718,7 +722,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param literal literal name + * @param literal literal name
+ * @return a new builder instance + * @return a new builder instance
+ */ + */
+ static @NotNull LiteralArgumentBuilder<CommandSourceStack> literal(final @NotNull String literal) { + static LiteralArgumentBuilder<CommandSourceStack> literal(final String literal) {
+ return LiteralArgumentBuilder.literal(literal); + return LiteralArgumentBuilder.literal(literal);
+ } + }
+ +
@ -730,7 +734,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the generic type of the argument value + * @param <T> the generic type of the argument value
+ * @return a new required argument builder + * @return a new required argument builder
+ */ + */
+ static <T> @NotNull RequiredArgumentBuilder<CommandSourceStack, T> argument(final @NotNull String name, final @NotNull ArgumentType<T> argumentType) { + static <T> RequiredArgumentBuilder<CommandSourceStack, T> argument(final String name, final ArgumentType<T> argumentType) {
+ return RequiredArgumentBuilder.argument(name, argumentType); + return RequiredArgumentBuilder.argument(name, argumentType);
+ } + }
+ +
@ -754,7 +758,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the dispatcher instance + * @return the dispatcher instance
+ */ + */
+ @ApiStatus.Experimental + @ApiStatus.Experimental
+ @NotNull CommandDispatcher<CommandSourceStack> getDispatcher(); + CommandDispatcher<CommandSourceStack> getDispatcher();
+ +
+ /** + /**
+ * Registers a command for the current plugin context. + * Registers a command for the current plugin context.
@ -768,7 +772,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param node the built literal command node + * @param node the built literal command node
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull LiteralCommandNode<CommandSourceStack> node) { + default @Unmodifiable Set<String> register(final LiteralCommandNode<CommandSourceStack> node) {
+ return this.register(node, null, Collections.emptyList()); + return this.register(node, null, Collections.emptyList());
+ } + }
+ +
@ -785,7 +789,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param description the help description for the root literal node + * @param description the help description for the root literal node
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull LiteralCommandNode<CommandSourceStack> node, final @Nullable String description) { + default @Unmodifiable Set<String> register(final LiteralCommandNode<CommandSourceStack> node, final @Nullable String description) {
+ return this.register(node, description, Collections.emptyList()); + return this.register(node, description, Collections.emptyList());
+ } + }
+ +
@ -802,7 +806,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param aliases a collection of aliases to register the literal node's command to + * @param aliases a collection of aliases to register the literal node's command to
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull LiteralCommandNode<CommandSourceStack> node, final @NotNull Collection<String> aliases) { + default @Unmodifiable Set<String> register(final LiteralCommandNode<CommandSourceStack> node, final Collection<String> aliases) {
+ return this.register(node, null, aliases); + return this.register(node, null, aliases);
+ } + }
+ +
@ -820,7 +824,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param aliases a collection of aliases to register the literal node's command to + * @param aliases a collection of aliases to register the literal node's command to
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ @Unmodifiable @NotNull Set<String> register(@NotNull LiteralCommandNode<CommandSourceStack> node, @Nullable String description, @NotNull Collection<String> aliases); + @Unmodifiable Set<String> register(LiteralCommandNode<CommandSourceStack> node, @Nullable String description, Collection<String> aliases);
+ +
+ /** + /**
+ * Registers a command for a plugin. + * Registers a command for a plugin.
@ -837,7 +841,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param aliases a collection of aliases to register the literal node's command to + * @param aliases a collection of aliases to register the literal node's command to
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ @Unmodifiable @NotNull Set<String> register(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode<CommandSourceStack> node, @Nullable String description, @NotNull Collection<String> aliases); + @Unmodifiable Set<String> register(PluginMeta pluginMeta, LiteralCommandNode<CommandSourceStack> node, @Nullable String description, Collection<String> aliases);
+ +
+ /** + /**
+ * This allows configuring the registration of your command, which is not intended for public use. + * This allows configuring the registration of your command, which is not intended for public use.
@ -854,7 +858,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * See {@link CommandRegistrationFlag} for a more indepth explanation of this method's use-case. + * See {@link CommandRegistrationFlag} for a more indepth explanation of this method's use-case.
+ */ + */
+ @ApiStatus.Internal + @ApiStatus.Internal
+ @Unmodifiable @NotNull Set<String> registerWithFlags(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode<CommandSourceStack> node, @Nullable String description, @NotNull Collection<String> aliases, @NotNull Set<CommandRegistrationFlag> flags); + @Unmodifiable Set<String> registerWithFlags(PluginMeta pluginMeta, LiteralCommandNode<CommandSourceStack> node, @Nullable String description, Collection<String> aliases, Set<CommandRegistrationFlag> flags);
+ +
+ /** + /**
+ * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. + * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}.
@ -863,7 +867,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param basicCommand the basic command instance to register + * @param basicCommand the basic command instance to register
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull String label, final @NotNull BasicCommand basicCommand) { + default @Unmodifiable Set<String> register(final String label, final BasicCommand basicCommand) {
+ return this.register(label, null, Collections.emptyList(), basicCommand); + return this.register(label, null, Collections.emptyList(), basicCommand);
+ } + }
+ +
@ -875,7 +879,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param basicCommand the basic command instance to register + * @param basicCommand the basic command instance to register
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull String label, final @Nullable String description, final @NotNull BasicCommand basicCommand) { + default @Unmodifiable Set<String> register(final String label, final @Nullable String description, final BasicCommand basicCommand) {
+ return this.register(label, description, Collections.emptyList(), basicCommand); + return this.register(label, description, Collections.emptyList(), basicCommand);
+ } + }
+ +
@ -887,7 +891,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param basicCommand the basic command instance to register + * @param basicCommand the basic command instance to register
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ default @Unmodifiable @NotNull Set<String> register(final @NotNull String label, final @NotNull Collection<String> aliases, final @NotNull BasicCommand basicCommand) { + default @Unmodifiable Set<String> register(final String label, final Collection<String> aliases, final BasicCommand basicCommand) {
+ return this.register(label, null, aliases, basicCommand); + return this.register(label, null, aliases, basicCommand);
+ } + }
+ +
@ -900,7 +904,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param basicCommand the basic command instance to register + * @param basicCommand the basic command instance to register
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ @Unmodifiable @NotNull Set<String> register(@NotNull String label, @Nullable String description, @NotNull Collection<String> aliases, @NotNull BasicCommand basicCommand); + @Unmodifiable Set<String> register(String label, @Nullable String description, Collection<String> aliases, BasicCommand basicCommand);
+ +
+ /** + /**
+ * Registers a command under the same logic as {@link Commands#register(PluginMeta, LiteralCommandNode, String, Collection)}. + * Registers a command under the same logic as {@link Commands#register(PluginMeta, LiteralCommandNode, String, Collection)}.
@ -912,7 +916,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param basicCommand the basic command instance to register + * @param basicCommand the basic command instance to register
+ * @return successfully registered root command labels (including aliases and namespaced variants) + * @return successfully registered root command labels (including aliases and namespaced variants)
+ */ + */
+ @Unmodifiable @NotNull Set<String> register(@NotNull PluginMeta pluginMeta, @NotNull String label, @Nullable String description, @NotNull Collection<String> aliases, @NotNull BasicCommand basicCommand); + @Unmodifiable Set<String> register(PluginMeta pluginMeta, String label, @Nullable String description, Collection<String> aliases, BasicCommand basicCommand);
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java
new file mode 100644 new file mode 100644
@ -926,12 +930,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.ComponentSerializer; +import net.kyori.adventure.text.serializer.ComponentSerializer;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A component serializer for converting between {@link Message} and {@link Component}. + * A component serializer for converting between {@link Message} and {@link Component}.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface MessageComponentSerializer extends ComponentSerializer<Component, Component, Message> { +public interface MessageComponentSerializer extends ComponentSerializer<Component, Component, Message> {
+ +
@ -940,7 +945,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return serializer instance + * @return serializer instance
+ */ + */
+ static @NotNull MessageComponentSerializer message() { + static MessageComponentSerializer message() {
+ return MessageComponentSerializerHolder.PROVIDER.orElseThrow(); + return MessageComponentSerializerHolder.PROVIDER.orElseThrow();
+ } + }
+} +}
@ -998,7 +1003,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.scoreboard.Criteria; +import org.bukkit.scoreboard.Criteria;
+import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.DisplaySlot;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+import static io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider.provider; +import static io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider.provider;
+ +
@ -1011,6 +1016,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * <p>{@link CustomArgumentType} is provided for customizing parsing or result types server-side, while sending the vanilla argument type to the client.</p> + * <p>{@link CustomArgumentType} is provided for customizing parsing or result types server-side, while sending the vanilla argument type to the client.</p>
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public final class ArgumentTypes { +public final class ArgumentTypes {
+ +
+ /** + /**
@ -1019,7 +1025,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument that takes one entity + * @return argument that takes one entity
+ */ + */
+ public static @NotNull ArgumentType<EntitySelectorArgumentResolver> entity() { + public static ArgumentType<EntitySelectorArgumentResolver> entity() {
+ return provider().entity(); + return provider().entity();
+ } + }
+ +
@ -1029,7 +1035,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument that takes multiple entities + * @return argument that takes multiple entities
+ */ + */
+ public static @NotNull ArgumentType<EntitySelectorArgumentResolver> entities() { + public static ArgumentType<EntitySelectorArgumentResolver> entities() {
+ return provider().entities(); + return provider().entities();
+ } + }
+ +
@ -1039,7 +1045,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument that takes one player + * @return argument that takes one player
+ */ + */
+ public static @NotNull ArgumentType<PlayerSelectorArgumentResolver> player() { + public static ArgumentType<PlayerSelectorArgumentResolver> player() {
+ return provider().player(); + return provider().player();
+ } + }
+ +
@ -1049,7 +1055,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument that takes multiple players + * @return argument that takes multiple players
+ */ + */
+ public static @NotNull ArgumentType<PlayerSelectorArgumentResolver> players() { + public static ArgumentType<PlayerSelectorArgumentResolver> players() {
+ return provider().players(); + return provider().players();
+ } + }
+ +
@ -1059,7 +1065,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return player profile argument + * @return player profile argument
+ */ + */
+ public static @NotNull ArgumentType<PlayerProfileListResolver> playerProfiles() { + public static ArgumentType<PlayerProfileListResolver> playerProfiles() {
+ return provider().playerProfiles(); + return provider().playerProfiles();
+ } + }
+ +
@ -1068,7 +1074,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return block position argument + * @return block position argument
+ */ + */
+ public static @NotNull ArgumentType<BlockPositionResolver> blockPosition() { + public static ArgumentType<BlockPositionResolver> blockPosition() {
+ return provider().blockPosition(); + return provider().blockPosition();
+ } + }
+ +
@ -1078,7 +1084,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return fine position argument + * @return fine position argument
+ * @see #finePosition(boolean) to center whole numbers + * @see #finePosition(boolean) to center whole numbers
+ */ + */
+ public static @NotNull ArgumentType<FinePositionResolver> finePosition() { + public static ArgumentType<FinePositionResolver> finePosition() {
+ return finePosition(false); + return finePosition(false);
+ } + }
+ +
@ -1088,7 +1094,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param centerIntegers if whole numbers should be centered (+0.5) + * @param centerIntegers if whole numbers should be centered (+0.5)
+ * @return fine position argument + * @return fine position argument
+ */ + */
+ public static @NotNull ArgumentType<FinePositionResolver> finePosition(final boolean centerIntegers) { + public static ArgumentType<FinePositionResolver> finePosition(final boolean centerIntegers) {
+ return provider().finePosition(centerIntegers); + return provider().finePosition(centerIntegers);
+ } + }
+ +
@ -1098,7 +1104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<BlockState> blockState() { + public static ArgumentType<BlockState> blockState() {
+ return provider().blockState(); + return provider().blockState();
+ } + }
+ +
@ -1108,7 +1114,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<ItemStack> itemStack() { + public static ArgumentType<ItemStack> itemStack() {
+ return provider().itemStack(); + return provider().itemStack();
+ } + }
+ +
@ -1117,7 +1123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<ItemStackPredicate> itemPredicate() { + public static ArgumentType<ItemStackPredicate> itemPredicate() {
+ return provider().itemStackPredicate(); + return provider().itemStackPredicate();
+ } + }
+ +
@ -1126,7 +1132,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<NamedTextColor> namedColor() { + public static ArgumentType<NamedTextColor> namedColor() {
+ return provider().namedColor(); + return provider().namedColor();
+ } + }
+ +
@ -1135,7 +1141,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<Component> component() { + public static ArgumentType<Component> component() {
+ return provider().component(); + return provider().component();
+ } + }
+ +
@ -1144,7 +1150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<Style> style() { + public static ArgumentType<Style> style() {
+ return provider().style(); + return provider().style();
+ } + }
+ +
@ -1155,7 +1161,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<SignedMessageResolver> signedMessage() { + public static ArgumentType<SignedMessageResolver> signedMessage() {
+ return provider().signedMessage(); + return provider().signedMessage();
+ } + }
+ +
@ -1164,7 +1170,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<DisplaySlot> scoreboardDisplaySlot() { + public static ArgumentType<DisplaySlot> scoreboardDisplaySlot() {
+ return provider().scoreboardDisplaySlot(); + return provider().scoreboardDisplaySlot();
+ } + }
+ +
@ -1173,7 +1179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<NamespacedKey> namespacedKey() { + public static ArgumentType<NamespacedKey> namespacedKey() {
+ return provider().namespacedKey(); + return provider().namespacedKey();
+ } + }
+ +
@ -1183,7 +1189,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return argument + * @return argument
+ */ + */
+ // include both key types as we are slowly moving to use adventure's key + // include both key types as we are slowly moving to use adventure's key
+ public static @NotNull ArgumentType<Key> key() { + public static ArgumentType<Key> key() {
+ return provider().key(); + return provider().key();
+ } + }
+ +
@ -1192,7 +1198,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<IntegerRangeProvider> integerRange() { + public static ArgumentType<IntegerRangeProvider> integerRange() {
+ return provider().integerRange(); + return provider().integerRange();
+ } + }
+ +
@ -1201,7 +1207,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<DoubleRangeProvider> doubleRange() { + public static ArgumentType<DoubleRangeProvider> doubleRange() {
+ return provider().doubleRange(); + return provider().doubleRange();
+ } + }
+ +
@ -1210,7 +1216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<World> world() { + public static ArgumentType<World> world() {
+ return provider().world(); + return provider().world();
+ } + }
+ +
@ -1219,16 +1225,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<GameMode> gameMode() { + public static ArgumentType<GameMode> gameMode() {
+ return provider().gameMode(); + return provider().gameMode();
+ } + }
+ +
+ /** + /**
+ * A argument for getting a heightmap type. + * An argument for getting a heightmap type.
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<HeightMap> heightMap() { + public static ArgumentType<HeightMap> heightMap() {
+ return provider().heightMap(); + return provider().heightMap();
+ } + }
+ +
@ -1237,7 +1243,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<UUID> uuid() { + public static ArgumentType<UUID> uuid() {
+ return provider().uuid(); + return provider().uuid();
+ } + }
+ +
@ -1246,7 +1252,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<Criteria> objectiveCriteria() { + public static ArgumentType<Criteria> objectiveCriteria() {
+ return provider().objectiveCriteria(); + return provider().objectiveCriteria();
+ } + }
+ +
@ -1255,7 +1261,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<LookAnchor> entityAnchor() { + public static ArgumentType<LookAnchor> entityAnchor() {
+ return provider().entityAnchor(); + return provider().entityAnchor();
+ } + }
+ +
@ -1271,7 +1277,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<Integer> time() { + public static ArgumentType<Integer> time() {
+ return time(0); + return time(0);
+ } + }
+ +
@ -1288,7 +1294,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param mintime The minimum time required for this argument. + * @param mintime The minimum time required for this argument.
+ * @return argument + * @return argument
+ */ + */
+ public static @NotNull ArgumentType<Integer> time(final int mintime) { + public static ArgumentType<Integer> time(final int mintime) {
+ return provider().time(mintime); + return provider().time(mintime);
+ } + }
+ +
@ -1298,7 +1304,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return argument + * @return argument
+ * @see Mirror + * @see Mirror
+ */ + */
+ public static @NotNull ArgumentType<Mirror> templateMirror() { + public static ArgumentType<Mirror> templateMirror() {
+ return provider().templateMirror(); + return provider().templateMirror();
+ } + }
+ +
@ -1308,7 +1314,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return argument + * @return argument
+ * @see StructureRotation + * @see StructureRotation
+ */ + */
+ public static @NotNull ArgumentType<StructureRotation> templateRotation() { + public static ArgumentType<StructureRotation> templateRotation() {
+ return provider().templateRotation(); + return provider().templateRotation();
+ } + }
+ +
@ -1319,7 +1325,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return argument + * @return argument
+ * @param <T> the registry value type + * @param <T> the registry value type
+ */ + */
+ public static <T> @NotNull ArgumentType<T> resource(final @NotNull RegistryKey<T> registryKey) { + public static <T> ArgumentType<T> resource(final RegistryKey<T> registryKey) {
+ return provider().resource(registryKey); + return provider().resource(registryKey);
+ } + }
+ +
@ -1331,7 +1337,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the registry value type + * @param <T> the registry value type
+ * @see RegistryArgumentExtractor#getTypedKey(com.mojang.brigadier.context.CommandContext, RegistryKey, String) + * @see RegistryArgumentExtractor#getTypedKey(com.mojang.brigadier.context.CommandContext, RegistryKey, String)
+ */ + */
+ public static <T> @NotNull ArgumentType<TypedKey<T>> resourceKey(final @NotNull RegistryKey<T> registryKey) { + public static <T> ArgumentType<TypedKey<T>> resourceKey(final RegistryKey<T> registryKey) {
+ return provider().resourceKey(registryKey); + return provider().resourceKey(registryKey);
+ } + }
+ +
@ -1355,7 +1361,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collection; +import java.util.Collection;
+import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletableFuture;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * An argument type that wraps around a native-to-vanilla argument type. + * An argument type that wraps around a native-to-vanilla argument type.
@ -1370,6 +1376,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <N> type with an argument native to vanilla Minecraft (from {@link ArgumentTypes}) + * @param <N> type with an argument native to vanilla Minecraft (from {@link ArgumentTypes})
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface CustomArgumentType<T, N> extends ArgumentType<T> { +public interface CustomArgumentType<T, N> extends ArgumentType<T> {
+ +
+ /** + /**
@ -1384,7 +1391,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws CommandSyntaxException if an error occurs while parsing + * @throws CommandSyntaxException if an error occurs while parsing
+ */ + */
+ @Override + @Override
+ @NotNull T parse(final @NotNull StringReader reader) throws CommandSyntaxException; + T parse(final StringReader reader) throws CommandSyntaxException;
+ +
+ /** + /**
+ * Gets the native type that this argument uses, + * Gets the native type that this argument uses,
@ -1392,7 +1399,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return native argument type + * @return native argument type
+ */ + */
+ @NotNull ArgumentType<N> getNativeType(); + ArgumentType<N> getNativeType();
+ +
+ /** + /**
+ * Cannot be controlled by the server. + * Cannot be controlled by the server.
@ -1403,7 +1410,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ */ + */
+ @Override + @Override
+ @ApiStatus.NonExtendable + @ApiStatus.NonExtendable
+ default @NotNull Collection<String> getExamples() { + default Collection<String> getExamples() {
+ return this.getNativeType().getExamples(); + return this.getNativeType().getExamples();
+ } + }
+ +
@ -1416,7 +1423,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <S> context type + * @param <S> context type
+ */ + */
+ @Override + @Override
+ default <S> @NotNull CompletableFuture<Suggestions> listSuggestions(final @NotNull CommandContext<S> context, final @NotNull SuggestionsBuilder builder) { + default <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
+ return ArgumentType.super.listSuggestions(context, builder); + return ArgumentType.super.listSuggestions(context, builder);
+ } + }
+ +
@ -1436,7 +1443,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @ApiStatus.NonExtendable + @ApiStatus.NonExtendable
+ @Override + @Override
+ default @NotNull T parse(final @NotNull StringReader reader) throws CommandSyntaxException { + default T parse(final StringReader reader) throws CommandSyntaxException {
+ return this.convert(this.getNativeType().parse(reader)); + return this.convert(this.getNativeType().parse(reader));
+ } + }
+ +
@ -1447,7 +1454,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return converted value + * @return converted value
+ * @throws CommandSyntaxException if an exception occurs while parsing + * @throws CommandSyntaxException if an exception occurs while parsing
+ */ + */
+ @NotNull T convert(@NotNull N nativeType) throws CommandSyntaxException; + T convert(N nativeType) throws CommandSyntaxException;
+ } + }
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/RegistryArgumentExtractor.java b/src/main/java/io/papermc/paper/command/brigadier/argument/RegistryArgumentExtractor.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/RegistryArgumentExtractor.java b/src/main/java/io/papermc/paper/command/brigadier/argument/RegistryArgumentExtractor.java
@ -1461,11 +1468,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.context.CommandContext;
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.TypedKey;
+import org.checkerframework.checker.nullness.qual.NonNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Utilities for extracting registry-related arguments from a {@link CommandContext}. + * Utilities for extracting registry-related arguments from a {@link CommandContext}.
+ */ + */
+@NullMarked
+public final class RegistryArgumentExtractor { +public final class RegistryArgumentExtractor {
+ +
+ /** + /**
@ -1480,7 +1488,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws IllegalArgumentException if the registry key doesn't match the typed key + * @throws IllegalArgumentException if the registry key doesn't match the typed key
+ */ + */
+ @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked")
+ public static <T, S> @NonNull TypedKey<T> getTypedKey(final @NonNull CommandContext<S> context, final @NonNull RegistryKey<T> registryKey, final @NonNull String name) { + public static <T, S> TypedKey<T> getTypedKey(final CommandContext<S> context, final RegistryKey<T> registryKey, final String name) {
+ final TypedKey<T> typedKey = context.getArgument(name, TypedKey.class); + final TypedKey<T> typedKey = context.getArgument(name, TypedKey.class);
+ if (typedKey.registryKey().equals(registryKey)) { + if (typedKey.registryKey().equals(registryKey)) {
+ return typedKey; + return typedKey;
@ -1505,7 +1513,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletableFuture;
+import net.kyori.adventure.chat.SignedMessage; +import net.kyori.adventure.chat.SignedMessage;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A resolver for a {@link SignedMessage} + * A resolver for a {@link SignedMessage}
@ -1513,6 +1521,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see ArgumentTypes#signedMessage() + * @see ArgumentTypes#signedMessage()
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface SignedMessageResolver { +public interface SignedMessageResolver {
+ +
@ -1521,7 +1530,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return string content + * @return string content
+ */ + */
+ @NotNull String content(); + String content();
+ +
+ /** + /**
+ * Resolves this signed message. This will the {@link CommandContext} + * Resolves this signed message. This will the {@link CommandContext}
@ -1535,7 +1544,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a completable future for the {@link SignedMessage} + * @return a completable future for the {@link SignedMessage}
+ * @throws CommandSyntaxException syntax exception + * @throws CommandSyntaxException syntax exception
+ */ + */
+ @NotNull CompletableFuture<SignedMessage> resolveSignedMessage(@NotNull String argumentName, @NotNull CommandContext<CommandSourceStack> context) throws CommandSyntaxException; + CompletableFuture<SignedMessage> resolveSignedMessage(String argumentName, CommandContext<CommandSourceStack> context) throws CommandSyntaxException;
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java b/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java b/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java
@ -1575,12 +1584,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.bukkit.scoreboard.Criteria; +import org.bukkit.scoreboard.Criteria;
+import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.DisplaySlot;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+interface VanillaArgumentProvider { +interface VanillaArgumentProvider {
+ +
+ Optional<VanillaArgumentProvider> PROVIDER = ServiceLoader.load(VanillaArgumentProvider.class) + Optional<VanillaArgumentProvider> PROVIDER = ServiceLoader.load(VanillaArgumentProvider.class)
@ -1722,7 +1730,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import com.google.common.collect.Range; +import com.google.common.collect.Range;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A provider for a range of numbers + * A provider for a range of numbers
@ -1731,13 +1739,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.command.brigadier.argument.ArgumentTypes + * @see io.papermc.paper.command.brigadier.argument.ArgumentTypes
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public sealed interface RangeProvider<T extends Comparable<?>> permits DoubleRangeProvider, IntegerRangeProvider { +public sealed interface RangeProvider<T extends Comparable<?>> permits DoubleRangeProvider, IntegerRangeProvider {
+ +
+ /** + /**
+ * Provides the given range. + * Provides the given range.
+ * @return range + * @return range
+ */ + */
+ @NotNull
+ Range<T> range(); + Range<T> range();
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/ArgumentResolver.java b/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/ArgumentResolver.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/ArgumentResolver.java b/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/ArgumentResolver.java
@ -1751,7 +1759,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.CommandSourceStack;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * An {@link ArgumentResolver} is capable of resolving + * An {@link ArgumentResolver} is capable of resolving
@ -1761,6 +1769,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.command.brigadier.argument.ArgumentTypes + * @see io.papermc.paper.command.brigadier.argument.ArgumentTypes
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface ArgumentResolver<T> { +public interface ArgumentResolver<T> {
+ +
@ -1770,7 +1779,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param sourceStack source stack + * @param sourceStack source stack
+ * @return resolved + * @return resolved
+ */ + */
+ @NotNull T resolve(@NotNull CommandSourceStack sourceStack) throws CommandSyntaxException; + T resolve(CommandSourceStack sourceStack) throws CommandSyntaxException;
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/BlockPositionResolver.java b/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/BlockPositionResolver.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/BlockPositionResolver.java b/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/BlockPositionResolver.java
new file mode 100644 new file mode 100644
@ -1928,9 +1937,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent; +import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.ApiStatus; @@ -0,0 +0,0 @@ import org.jspecify.annotations.NullMarked;
@ApiStatus.Experimental @NullMarked
public final class LifecycleEvents { public final class LifecycleEvents {
+ /** + /**

View File

@ -15,11 +15,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.Sound; +import org.bukkit.Sound;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents an entity that can be bucketed. + * Represents an entity that can be bucketed.
+ */ + */
+@NullMarked
+public interface Bucketable extends Entity { +public interface Bucketable extends Entity {
+ +
+ /** + /**
@ -41,7 +42,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return bucket form + * @return bucket form
+ */ + */
+ @NotNull
+ ItemStack getBaseBucketItem(); + ItemStack getBaseBucketItem();
+ +
+ /** + /**
@ -49,7 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * is picked up in a bucket. + * is picked up in a bucket.
+ * @return bucket pickup sound + * @return bucket pickup sound
+ */ + */
+ @NotNull
+ Sound getPickupSound(); + Sound getPickupSound();
+} +}
diff --git a/src/main/java/org/bukkit/entity/Axolotl.java b/src/main/java/org/bukkit/entity/Axolotl.java diff --git a/src/main/java/org/bukkit/entity/Axolotl.java b/src/main/java/org/bukkit/entity/Axolotl.java

View File

@ -121,6 +121,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionEffectType;
+import org.bukkit.potion.PotionType; +import org.bukkit.potion.PotionType;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+import static io.papermc.paper.registry.RegistryKeyImpl.create; +import static io.papermc.paper.registry.RegistryKeyImpl.create;
+ +
@ -137,6 +138,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the value type + * @param <T> the value type
+ */ + */
+@SuppressWarnings("unused") +@SuppressWarnings("unused")
+@NullMarked
+public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl { +public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
+ +
+ /* ******************* * + /* ******************* *
@ -278,9 +280,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Set; +import java.util.Set;
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import org.intellij.lang.annotations.Subst; +import org.intellij.lang.annotations.Subst;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+record RegistryKeyImpl<T>(@NotNull Key key) implements RegistryKey<T> { +@NullMarked
+record RegistryKeyImpl<T>(Key key) implements RegistryKey<T> {
+ +
+ static final Set<RegistryKey<?>> REGISTRY_KEYS = Sets.newIdentityHashSet(); + static final Set<RegistryKey<?>> REGISTRY_KEYS = Sets.newIdentityHashSet();
+ +
@ -307,7 +311,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import net.kyori.adventure.key.Keyed; +import net.kyori.adventure.key.Keyed;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a key for a value in a specific registry. + * Represents a key for a value in a specific registry.
@ -315,6 +319,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the value type for the registry + * @param <T> the value type for the registry
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public sealed interface TypedKey<T> extends Keyed permits TypedKeyImpl { +public sealed interface TypedKey<T> extends Keyed permits TypedKeyImpl {
+ +
+ /** + /**
@ -323,7 +328,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the value's key + * @return the value's key
+ */ + */
+ @Override + @Override
+ @NotNull Key key(); + Key key();
+ +
+ /** + /**
+ * Gets the registry key for the value this key + * Gets the registry key for the value this key
@ -331,7 +336,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NotNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+ +
+ /** + /**
+ * Create a typed key from a key and a registry key. + * Create a typed key from a key and a registry key.
@ -342,7 +347,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new key for the value key and registry key + * @return a new key for the value key and registry key
+ */ + */
+ @ApiStatus.Experimental + @ApiStatus.Experimental
+ static <T> @NotNull TypedKey<T> create(final @NotNull RegistryKey<T> registryKey, final @NotNull Key key) { + static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final Key key) {
+ return new TypedKeyImpl<>(key, registryKey); + return new TypedKeyImpl<>(key, registryKey);
+ } + }
+} +}
@ -355,10 +360,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.registry; +package io.papermc.paper.registry;
+ +
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import net.kyori.adventure.key.Keyed; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.NotNull;
+ +
+record TypedKeyImpl<T>(@NotNull Key key, @NotNull RegistryKey<T> registryKey) implements TypedKey<T> { +@NullMarked
+record TypedKeyImpl<T>(Key key, RegistryKey<T> registryKey) implements TypedKey<T> {
+} +}
diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -12,22 +12,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.potion; +package io.papermc.paper.potion;
+ +
+import java.util.Objects;
+import java.util.function.Predicate; +import java.util.function.Predicate;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey; +import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.RecipeChoice; +import org.bukkit.inventory.RecipeChoice;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+
+import java.util.Objects;
+ +
+/** +/**
+ * Represents a potion mix made in a Brewing Stand. + * Represents a potion mix made in a Brewing Stand.
+ */ + */
+@ApiStatus.NonExtendable +@NullMarked
+public class PotionMix implements Keyed { +public final class PotionMix implements Keyed {
+ +
+ private final NamespacedKey key; + private final NamespacedKey key;
+ private final ItemStack result; + private final ItemStack result;
@ -42,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param input the input placed into the bottom 3 slots + * @param input the input placed into the bottom 3 slots
+ * @param ingredient the ingredient placed into the top slot + * @param ingredient the ingredient placed into the top slot
+ */ + */
+ public PotionMix(final @NotNull NamespacedKey key, final @NotNull ItemStack result, final @NotNull RecipeChoice input, final @NotNull RecipeChoice ingredient) { + public PotionMix(final NamespacedKey key, final ItemStack result, final RecipeChoice input, final RecipeChoice ingredient) {
+ this.key = key; + this.key = key;
+ this.result = result; + this.result = result;
+ this.input = input; + this.input = input;
@ -57,12 +55,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new RecipeChoice + * @return a new RecipeChoice
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ public static @NotNull RecipeChoice createPredicateChoice(final @NotNull Predicate<? super ItemStack> stackPredicate) { + public static RecipeChoice createPredicateChoice(final Predicate<? super ItemStack> stackPredicate) {
+ return new PredicateRecipeChoice(stackPredicate); + return new PredicateRecipeChoice(stackPredicate);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull NamespacedKey getKey() { + public NamespacedKey getKey() {
+ return this.key; + return this.key;
+ } + }
+ +
@ -71,7 +69,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the result itemstack + * @return the result itemstack
+ */ + */
+ public @NotNull ItemStack getResult() { + public ItemStack getResult() {
+ return this.result; + return this.result;
+ } + }
+ +
@ -80,7 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the bottom 3 slot ingredients + * @return the bottom 3 slot ingredients
+ */ + */
+ public @NotNull RecipeChoice getInput() { + public RecipeChoice getInput() {
+ return this.input; + return this.input;
+ } + }
+ +
@ -89,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the top slot input + * @return the top slot input
+ */ + */
+ public @NotNull RecipeChoice getIngredient() { + public RecipeChoice getIngredient() {
+ return this.ingredient; + return this.ingredient;
+ } + }
+ +
@ -126,12 +124,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.function.Predicate; +import java.util.function.Predicate;
+import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.RecipeChoice; +import org.bukkit.inventory.RecipeChoice;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record PredicateRecipeChoice(Predicate<? super ItemStack> itemStackPredicate) implements RecipeChoice, Cloneable { +record PredicateRecipeChoice(Predicate<? super ItemStack> itemStackPredicate) implements RecipeChoice, Cloneable {
+ +
+ @Override + @Override

View File

@ -18,12 +18,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.math; +package io.papermc.paper.math;
+ +
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Rotations is an immutable object that stores rotations + * Rotations is an immutable object that stores rotations
+ * in degrees on each axis (X, Y, Z). + * in degrees on each axis (X, Y, Z).
+ */ + */
+@NullMarked
+public interface Rotations { +public interface Rotations {
+ +
+ /** + /**
@ -39,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z the angle for the Z axis in degrees + * @param z the angle for the Z axis in degrees
+ * @return Rotations instance holding the provided rotations + * @return Rotations instance holding the provided rotations
+ */ + */
+ static @NotNull Rotations ofDegrees(double x, double y, double z) { + static Rotations ofDegrees(final double x, final double y, final double z) {
+ return new RotationsImpl(x, y, z); + return new RotationsImpl(x, y, z);
+ } + }
+ +
@ -71,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param x the angle in degrees + * @param x the angle in degrees
+ * @return the resultant Rotations + * @return the resultant Rotations
+ */ + */
+ @NotNull Rotations withX(double x); + Rotations withX(double x);
+ +
+ /** + /**
+ * Returns a new Rotations instance which is the result + * Returns a new Rotations instance which is the result
@ -80,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param y the angle in degrees + * @param y the angle in degrees
+ * @return the resultant Rotations + * @return the resultant Rotations
+ */ + */
+ @NotNull Rotations withY(double y); + Rotations withY(double y);
+ +
+ /** + /**
+ * Returns a new Rotations instance which is the result + * Returns a new Rotations instance which is the result
@ -89,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z the angle in degrees + * @param z the angle in degrees
+ * @return the resultant Rotations + * @return the resultant Rotations
+ */ + */
+ @NotNull Rotations withZ(double z); + Rotations withZ(double z);
+ +
+ /** + /**
+ * Returns a new Rotations instance which is the result of adding + * Returns a new Rotations instance which is the result of adding
@ -100,7 +101,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z the angle to add to the Z axis in degrees + * @param z the angle to add to the Z axis in degrees
+ * @return the resultant Rotations + * @return the resultant Rotations
+ */ + */
+ @NotNull Rotations add(double x, double y, double z); + Rotations add(double x, double y, double z);
+ +
+ /** + /**
+ * Returns a new Rotations instance which is the result of subtracting + * Returns a new Rotations instance which is the result of subtracting
@ -111,8 +112,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param z the angle to subtract from the Z axis in degrees + * @param z the angle to subtract from the Z axis in degrees
+ * @return the resultant Rotations + * @return the resultant Rotations
+ */ + */
+ default @NotNull Rotations subtract(double x, double y, double z) { + default Rotations subtract(final double x, final double y, final double z) {
+ return add(-x, -y, -z); + return this.add(-x, -y, -z);
+ } + }
+ +
+} +}
@ -124,27 +125,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.math; +package io.papermc.paper.math;
+ +
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+record RotationsImpl(double x, double y, double z) implements Rotations { +record RotationsImpl(double x, double y, double z) implements Rotations {
+ +
+ @Override + @Override
+ public @NotNull RotationsImpl withX(double x) { + public RotationsImpl withX(final double x) {
+ return new RotationsImpl(x, y, z); + return new RotationsImpl(x, this.y, this.z);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull RotationsImpl withY(double y) { + public RotationsImpl withY(final double y) {
+ return new RotationsImpl(x, y, z); + return new RotationsImpl(this.x, y, this.z);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull RotationsImpl withZ(double z) { + public RotationsImpl withZ(final double z) {
+ return new RotationsImpl(x, y, z); + return new RotationsImpl(this.x, this.y, z);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull RotationsImpl add(double x, double y, double z) { + public RotationsImpl add(final double x, final double y, final double z) {
+ return new RotationsImpl(this.x + x, this.y + y, this.z + z); + return new RotationsImpl(this.x + x, this.y + y, this.z + z);
+ } + }
+ +

View File

@ -75,11 +75,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import net.kyori.adventure.util.Services; +import net.kyori.adventure.util.Services;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Information about the current server build. + * Information about the current server build.
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface ServerBuildInfo { +public interface ServerBuildInfo {
+ /** + /**
@ -92,7 +93,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the {@code ServerBuildInfo} + * @return the {@code ServerBuildInfo}
+ */ + */
+ static @NotNull ServerBuildInfo buildInfo() { + static ServerBuildInfo buildInfo() {
+ //<editor-fold defaultstate="collapsed" desc="Holder"> + //<editor-fold defaultstate="collapsed" desc="Holder">
+ final class Holder { + final class Holder {
+ static final Optional<ServerBuildInfo> INSTANCE = Services.service(ServerBuildInfo.class); + static final Optional<ServerBuildInfo> INSTANCE = Services.service(ServerBuildInfo.class);
@ -106,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the brand id of the server (e.g. "papermc:paper") + * @return the brand id of the server (e.g. "papermc:paper")
+ */ + */
+ @NotNull Key brandId(); + Key brandId();
+ +
+ /** + /**
+ * Checks if the current server supports the specified brand. + * Checks if the current server supports the specified brand.
@ -115,56 +116,56 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return {@code true} if the server supports the specified brand + * @return {@code true} if the server supports the specified brand
+ */ + */
+ @ApiStatus.Experimental + @ApiStatus.Experimental
+ boolean isBrandCompatible(final @NotNull Key brandId); + boolean isBrandCompatible(final Key brandId);
+ +
+ /** + /**
+ * Gets the brand name of the server. + * Gets the brand name of the server.
+ * + *
+ * @return the brand name of the server (e.g. "Paper") + * @return the brand name of the server (e.g. "Paper")
+ */ + */
+ @NotNull String brandName(); + String brandName();
+ +
+ /** + /**
+ * Gets the Minecraft version id. + * Gets the Minecraft version id.
+ * + *
+ * @return the Minecraft version id (e.g. "1.20.4", "1.20.2-pre2", "23w31a") + * @return the Minecraft version id (e.g. "1.20.4", "1.20.2-pre2", "23w31a")
+ */ + */
+ @NotNull String minecraftVersionId(); + String minecraftVersionId();
+ +
+ /** + /**
+ * Gets the Minecraft version name. + * Gets the Minecraft version name.
+ * + *
+ * @return the Minecraft version name (e.g. "1.20.4", "1.20.2 Pre-release 2", "23w31a") + * @return the Minecraft version name (e.g. "1.20.4", "1.20.2 Pre-release 2", "23w31a")
+ */ + */
+ @NotNull String minecraftVersionName(); + String minecraftVersionName();
+ +
+ /** + /**
+ * Gets the build number. + * Gets the build number.
+ * + *
+ * @return the build number + * @return the build number
+ */ + */
+ @NotNull OptionalInt buildNumber(); + OptionalInt buildNumber();
+ +
+ /** + /**
+ * Gets the build time. + * Gets the build time.
+ * + *
+ * @return the build time + * @return the build time
+ */ + */
+ @NotNull Instant buildTime(); + Instant buildTime();
+ +
+ /** + /**
+ * Gets the git commit branch. + * Gets the git commit branch.
+ * + *
+ * @return the git commit branch + * @return the git commit branch
+ */ + */
+ @NotNull Optional<String> gitBranch(); + Optional<String> gitBranch();
+ +
+ /** + /**
+ * Gets the git commit hash. + * Gets the git commit hash.
+ * + *
+ * @return the git commit hash + * @return the git commit hash
+ */ + */
+ @NotNull Optional<String> gitCommit(); + Optional<String> gitCommit();
+ +
+ /** + /**
+ * Creates a string representation of the server build information. + * Creates a string representation of the server build information.
@ -172,7 +173,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param representation the type of representation + * @param representation the type of representation
+ * @return a string + * @return a string
+ */ + */
+ @NotNull String asString(final @NotNull StringRepresentation representation); + String asString(final StringRepresentation representation);
+ +
+ /** + /**
+ * String representation types. + * String representation types.
@ -204,9 +205,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.WeakHashMap; +import java.util.WeakHashMap;
+import java.util.jar.Manifest; +import java.util.jar.Manifest;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public final class JarManifests { +public final class JarManifests {
+ private JarManifests() { + private JarManifests() {
@ -214,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ private static final Map<ClassLoader, Manifest> MANIFESTS = Collections.synchronizedMap(new WeakHashMap<>()); + private static final Map<ClassLoader, Manifest> MANIFESTS = Collections.synchronizedMap(new WeakHashMap<>());
+ +
+ public static @Nullable Manifest manifest(final @NotNull Class<?> clazz) { + public static @Nullable Manifest manifest(final Class<?> clazz) {
+ return MANIFESTS.computeIfAbsent(clazz.getClassLoader(), classLoader -> { + return MANIFESTS.computeIfAbsent(clazz.getClassLoader(), classLoader -> {
+ final String classLocation = "/" + clazz.getName().replace(".", "/") + ".class"; + final String classLocation = "/" + clazz.getName().replace(".", "/") + ".class";
+ final URL resource = clazz.getResource(classLocation); + final URL resource = clazz.getResource(classLocation);

View File

@ -63,12 +63,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package org.bukkit.inventory; +package org.bukkit.inventory;
+ +
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record EmptyRecipeChoice() implements RecipeChoice { +record EmptyRecipeChoice() implements RecipeChoice {
+ +
+ static final RecipeChoice INSTANCE = new EmptyRecipeChoice(); + static final RecipeChoice INSTANCE = new EmptyRecipeChoice();

View File

@ -14,11 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import net.kyori.adventure.util.TriState; +import net.kyori.adventure.util.TriState;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents an {@link Entity} that can experience friction with the air and ground. + * Represents an {@link Entity} that can experience friction with the air and ground.
+ */ + */
+@NullMarked
+public interface Frictional { +public interface Frictional {
+ +
+ /** + /**
@ -29,7 +30,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the entity's friction state + * @return the entity's friction state
+ */ + */
+ @NotNull
+ TriState getFrictionState(); + TriState getFrictionState();
+ +
+ /** + /**
@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param state the new friction state to set for the entity + * @param state the new friction state to set for the entity
+ */ + */
+ void setFrictionState(@NotNull TriState state); + void setFrictionState(TriState state);
+ +
+} +}
diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukkit/entity/Item.java diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukkit/entity/Item.java

View File

@ -14,8 +14,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package org.bukkit.inventory; +package org.bukkit.inventory;
+ +
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+public interface ArmoredHorseInventory extends AbstractHorseInventory { +public interface ArmoredHorseInventory extends AbstractHorseInventory {
+ +
+ /** + /**
@ -23,8 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the armor item + * @return the armor item
+ */ + */
+ @Nullable + @Nullable ItemStack getArmor();
+ ItemStack getArmor();
+ +
+ /** + /**
+ * Sets the item in the horse's armor slot. + * Sets the item in the horse's armor slot.
@ -80,4 +81,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package org.bukkit.inventory; +package org.bukkit.inventory;
+ +
+public interface SaddledHorseInventory extends AbstractHorseInventory {} +import org.jspecify.annotations.NullMarked;
+
+@NullMarked
+public interface SaddledHorseInventory extends AbstractHorseInventory {
+}

View File

@ -40,18 +40,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.EquipmentSlotGroup; +import org.bukkit.inventory.EquipmentSlotGroup;
+import org.bukkit.inventory.ItemType; +import org.bukkit.inventory.ItemType;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range; +import org.jetbrains.annotations.Range;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * A data-centric version-specific registry entry for the {@link Enchantment} type. + * A data-centric version-specific registry entry for the {@link Enchantment} type.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface EnchantmentRegistryEntry { +public interface EnchantmentRegistryEntry {
+ +
@ -61,14 +61,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the description component. + * @return the description component.
+ */ + */
+ @NonNull Component description(); + Component description();
+ +
+ /** + /**
+ * Provides the registry key set referencing the items this enchantment is supported on. + * Provides the registry key set referencing the items this enchantment is supported on.
+ * + *
+ * @return the registry key set. + * @return the registry key set.
+ */ + */
+ @NonNull RegistryKeySet<ItemType> supportedItems(); + RegistryKeySet<ItemType> supportedItems();
+ +
+ /** + /**
+ * Provides the registry key set referencing the item types this enchantment can be applied to when + * Provides the registry key set referencing the item types this enchantment can be applied to when
@ -106,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see <a href="https://minecraft.wiki/w/Enchanting/Levels">https://minecraft.wiki/w/Enchanting/Levels</a> for + * @see <a href="https://minecraft.wiki/w/Enchanting/Levels">https://minecraft.wiki/w/Enchanting/Levels</a> for
+ * examplary costs. + * examplary costs.
+ */ + */
+ @NonNull EnchantmentCost minimumCost(); + EnchantmentCost minimumCost();
+ +
+ /** + /**
+ * Provides the maximum cost allowed to enchant an item with this enchantment. + * Provides the maximum cost allowed to enchant an item with this enchantment.
@ -117,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see <a href="https://minecraft.wiki/w/Enchanting/Levels">https://minecraft.wiki/w/Enchanting/Levels</a> for + * @see <a href="https://minecraft.wiki/w/Enchanting/Levels">https://minecraft.wiki/w/Enchanting/Levels</a> for
+ * examplary costs. + * examplary costs.
+ */ + */
+ @NonNull EnchantmentCost maximumCost(); + EnchantmentCost maximumCost();
+ +
+ /** + /**
+ * Provides the cost of applying this enchantment using an anvil. + * Provides the cost of applying this enchantment using an anvil.
@ -140,7 +140,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a list of equipment slot groups. + * @return a list of equipment slot groups.
+ * @see Enchantment#getActiveSlotGroups() + * @see Enchantment#getActiveSlotGroups()
+ */ + */
+ @NonNull @Unmodifiable List<EquipmentSlotGroup> activeSlots(); + @Unmodifiable List<EquipmentSlotGroup> activeSlots();
+ +
+ /** + /**
+ * Provides the registry key set of enchantments that this enchantment is exclusive with. + * Provides the registry key set of enchantments that this enchantment is exclusive with.
@ -150,7 +150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a registry set of enchantments exclusive to this one. + * @return a registry set of enchantments exclusive to this one.
+ */ + */
+ @NonNull RegistryKeySet<Enchantment> exclusiveWith(); + RegistryKeySet<Enchantment> exclusiveWith();
+ +
+ /** + /**
+ * A mutable builder for the {@link EnchantmentRegistryEntry} plugins may change in applicable registry events. + * A mutable builder for the {@link EnchantmentRegistryEntry} plugins may change in applicable registry events.
@ -179,7 +179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return this builder. + * @return this builder.
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder description(@NonNull Component description); + Builder description(Component description);
+ +
+ /** + /**
+ * Configures the set of supported items this enchantment can be applied on. This + * Configures the set of supported items this enchantment can be applied on. This
@ -195,7 +195,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey)
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder supportedItems(@NonNull RegistryKeySet<ItemType> supportedItems); + Builder supportedItems(RegistryKeySet<ItemType> supportedItems);
+ +
+ /** + /**
+ * Configures a set of item types this enchantment can naturally be applied to, when enchanting in an + * Configures a set of item types this enchantment can naturally be applied to, when enchanting in an
@ -216,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey)
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder primaryItems(@Nullable RegistryKeySet<ItemType> primaryItems); + Builder primaryItems(@Nullable RegistryKeySet<ItemType> primaryItems);
+ +
+ /** + /**
+ * Configures the weight of this enchantment used by the weighted random when selecting enchantments. + * Configures the weight of this enchantment used by the weighted random when selecting enchantments.
@ -226,7 +226,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see <a href="https://minecraft.wiki/w/Enchanting">https://minecraft.wiki/w/Enchanting</a> for examplary weights. + * @see <a href="https://minecraft.wiki/w/Enchanting">https://minecraft.wiki/w/Enchanting</a> for examplary weights.
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder weight(@Range(from = 1, to = 1024) int weight); + Builder weight(@Range(from = 1, to = 1024) int weight);
+ +
+ /** + /**
+ * Configures the maximum level this enchantment can have when applied. + * Configures the maximum level this enchantment can have when applied.
@ -235,7 +235,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return this builder. + * @return this builder.
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder maxLevel(@Range(from = 1, to = 255) int maxLevel); + Builder maxLevel(@Range(from = 1, to = 255) int maxLevel);
+ +
+ /** + /**
+ * Configures the minimum cost needed to enchant an item with this enchantment. + * Configures the minimum cost needed to enchant an item with this enchantment.
@ -248,7 +248,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * examplary costs. + * examplary costs.
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder minimumCost(@NotNull EnchantmentCost minimumCost); + Builder minimumCost(EnchantmentCost minimumCost);
+ +
+ /** + /**
+ * Configures the maximum cost to enchant an item with this enchantment. + * Configures the maximum cost to enchant an item with this enchantment.
@ -261,7 +261,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * examplary costs. + * examplary costs.
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder maximumCost(@NotNull EnchantmentCost maximumCost); + Builder maximumCost(EnchantmentCost maximumCost);
+ +
+ /** + /**
+ * Configures the cost of applying this enchantment using an anvil. + * Configures the cost of applying this enchantment using an anvil.
@ -275,7 +275,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see Enchantment#getAnvilCost() + * @see Enchantment#getAnvilCost()
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder anvilCost(@Range(from = 0, to = Integer.MAX_VALUE) int anvilCost); + Builder anvilCost(@Range(from = 0, to = Integer.MAX_VALUE) int anvilCost);
+ +
+ /** + /**
+ * Configures the list of slot groups this enchantment may be active in. + * Configures the list of slot groups this enchantment may be active in.
@ -288,7 +288,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see Enchantment#getActiveSlotGroups() + * @see Enchantment#getActiveSlotGroups()
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ default @NonNull Builder activeSlots(final @NonNull EquipmentSlotGroup @NonNull... activeSlots) { + default Builder activeSlots(final EquipmentSlotGroup... activeSlots) {
+ return this.activeSlots(List.of(activeSlots)); + return this.activeSlots(List.of(activeSlots));
+ } + }
+ +
@ -303,7 +303,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see Enchantment#getActiveSlotGroups() + * @see Enchantment#getActiveSlotGroups()
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder activeSlots(@NonNull Iterable<@NonNull EquipmentSlotGroup> activeSlots); + Builder activeSlots(Iterable<EquipmentSlotGroup> activeSlots);
+ +
+ /** + /**
+ * Configures the registry key set of enchantments that this enchantment is exclusive with. + * Configures the registry key set of enchantments that this enchantment is exclusive with.
@ -319,7 +319,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey)
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder exclusiveWith(@NonNull RegistryKeySet<Enchantment> exclusiveWith); + Builder exclusiveWith(RegistryKeySet<Enchantment> exclusiveWith);
+ } + }
+ +
+ /** + /**
@ -369,15 +369,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilder;
+import org.bukkit.GameEvent; +import org.bukkit.GameEvent;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Range; +import org.jetbrains.annotations.Range;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A data-centric version-specific registry entry for the {@link GameEvent} type. + * A data-centric version-specific registry entry for the {@link GameEvent} type.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface GameEventRegistryEntry { +public interface GameEventRegistryEntry {
+ +
@ -410,7 +411,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see GameEvent#getRange() + * @see GameEvent#getRange()
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull Builder range(@Range(from = 0, to = Integer.MAX_VALUE) int range); + Builder range(@Range(from = 0, to = Integer.MAX_VALUE) int range);
+ } + }
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/data/package-info.java b/src/main/java/io/papermc/paper/registry/data/package-info.java diff --git a/src/main/java/io/papermc/paper/registry/data/package-info.java b/src/main/java/io/papermc/paper/registry/data/package-info.java
@ -441,14 +442,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.GameEvent; +import org.bukkit.GameEvent;
+import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
+import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create; +import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create;
+ +
/** /**
* Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent} * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent}
* handlers for each applicable registry. * handlers for each applicable registry.
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.ApiStatus; @@ -0,0 +0,0 @@ import org.jspecify.annotations.NullMarked;
@ApiStatus.Experimental @NullMarked
public final class RegistryEvents { public final class RegistryEvents {
+ public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT); + public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT);

View File

@ -14,12 +14,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import org.bukkit.entity.Player; +import org.bukkit.entity.Player;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Context for computing itemstack tooltips via + * Context for computing itemstack tooltips via
+ * {@link org.bukkit.inventory.ItemStack#computeTooltipLines(TooltipContext, Player)} + * {@link org.bukkit.inventory.ItemStack#computeTooltipLines(TooltipContext, Player)}
+ */ + */
+@NullMarked
+public interface TooltipContext { +public interface TooltipContext {
+ +
+ /** + /**
@ -31,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new context + * @return a new context
+ */ + */
+ @Contract("_, _ -> new") + @Contract("_, _ -> new")
+ static @NotNull TooltipContext create(final boolean advanced, final boolean creative) { + static TooltipContext create(final boolean advanced, final boolean creative) {
+ return new TooltipContextImpl(advanced, creative); + return new TooltipContextImpl(advanced, creative);
+ } + }
+ +
@ -41,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new context + * @return a new context
+ */ + */
+ @Contract("-> new") + @Contract("-> new")
+ static @NotNull TooltipContext create() { + static TooltipContext create() {
+ return new TooltipContextImpl(false, false); + return new TooltipContextImpl(false, false);
+ } + }
+ +
@ -74,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new context + * @return a new context
+ */ + */
+ @Contract("-> new") + @Contract("-> new")
+ @NotNull TooltipContext asAdvanced(); + TooltipContext asAdvanced();
+ +
+ /** + /**
+ * Returns a new context with {@link #isCreative()} + * Returns a new context with {@link #isCreative()}
@ -83,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a new context + * @return a new context
+ */ + */
+ @Contract("-> new") + @Contract("-> new")
+ @NotNull TooltipContext asCreative(); + TooltipContext asCreative();
+} +}
diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java
new file mode 100644 new file mode 100644
@ -93,17 +94,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.inventory.tooltip; +package io.papermc.paper.inventory.tooltip;
+ +
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+record TooltipContextImpl(boolean isAdvanced, boolean isCreative) implements TooltipContext { +record TooltipContextImpl(boolean isAdvanced, boolean isCreative) implements TooltipContext {
+ +
+ @Override + @Override
+ public @NotNull TooltipContext asCreative() { + public TooltipContext asCreative() {
+ return new TooltipContextImpl(this.isAdvanced, true); + return new TooltipContextImpl(this.isAdvanced, true);
+ } + }
+ +
+ @Override + @Override
+ public @NotNull TooltipContext asAdvanced() { + public TooltipContext asAdvanced() {
+ return new TooltipContextImpl(true, this.isCreative); + return new TooltipContextImpl(true, this.isCreative);
+ } + }
+} +}

View File

@ -13,12 +13,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.entity; +package io.papermc.paper.entity;
+ +
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.checkerframework.checker.nullness.qual.NonNull; +import org.jspecify.annotations.NullMarked;
+import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Represents an entity that can be leashed. + * Represents an entity that can be leashed.
+ */ + */
+@NullMarked
+public interface Leashable extends Entity { +public interface Leashable extends Entity {
+ +
+ /** + /**
@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the entity holding the leash + * @return the entity holding the leash
+ * @throws IllegalStateException if not currently leashed + * @throws IllegalStateException if not currently leashed
+ */ + */
+ @NonNull Entity getLeashHolder() throws IllegalStateException; + Entity getLeashHolder() throws IllegalStateException;
+ +
+ /** + /**
+ * Sets the leash on this entity to be held by the supplied entity. + * Sets the leash on this entity to be held by the supplied entity.

View File

@ -19,7 +19,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package com.destroystokyo.paper.loottable; +package com.destroystokyo.paper.loottable;
+ +
+import org.bukkit.block.Block; +import org.bukkit.block.Block;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
@ -43,7 +42,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package com.destroystokyo.paper.loottable; +package com.destroystokyo.paper.loottable;
+ +
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
@ -69,8 +67,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.UUID; +import java.util.UUID;
+import org.bukkit.entity.Player; +import org.bukkit.entity.Player;
+import org.bukkit.loot.Lootable; +import org.bukkit.loot.Lootable;
+import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Represents an Inventory that contains a Loot Table associated to it that will + * Represents an Inventory that contains a Loot Table associated to it that will
@ -141,8 +139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param player The player to check + * @param player The player to check
+ * @return Timestamp last looted, or null if player has not looted this object + * @return Timestamp last looted, or null if player has not looted this object
+ */ + */
+ @Nullable + @Nullable Long getLastLooted(UUID player);
+ Long getLastLooted(UUID player);
+ +
+ /** + /**
+ * Change the state of whether a player has looted this block + * Change the state of whether a player has looted this block

View File

@ -18,15 +18,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataHolder; +import org.bukkit.persistence.PersistentDataHolder;
+import org.bukkit.persistence.PersistentDataType; +import org.bukkit.persistence.PersistentDataType;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * This represents a view of a persistent data container. No + * This represents a view of a persistent data container. No
+ * methods on this interface mutate the container. + * methods on this interface mutate the container.
+ *
+ * @see PersistentDataContainer + * @see PersistentDataContainer
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface PersistentDataContainerView { +public interface PersistentDataContainerView {
+ +
@ -52,14 +54,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param type the type the primative stored value has to match + * @param type the type the primative stored value has to match
+ * @param <P> the generic type of the stored primitive + * @param <P> the generic type of the stored primitive
+ * @param <C> the generic type of the eventually created complex object + * @param <C> the generic type of the eventually created complex object
+ *
+ * @return if a value with the provided key and type exists + * @return if a value with the provided key and type exists
+ *
+ * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the key to look up is null
+ * @throws IllegalArgumentException if the type to cast the found object to is + * @throws IllegalArgumentException if the type to cast the found object to is
+ * null + * null
+ */ + */
+ <P, C> boolean has(@NonNull NamespacedKey key, @NonNull PersistentDataType<P, C> type); + <P, C> boolean has(NamespacedKey key, PersistentDataType<P, C> type);
+ +
+ /** + /**
+ * Returns if the persistent metadata provider has metadata registered matching + * Returns if the persistent metadata provider has metadata registered matching
@ -73,12 +73,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * namespace. + * namespace.
+ * + *
+ * @param key the key the value is stored under + * @param key the key the value is stored under
+ *
+ * @return if a value with the provided key exists + * @return if a value with the provided key exists
+ *
+ * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the key to look up is null
+ */ + */
+ boolean has(@NonNull NamespacedKey key); + boolean has(NamespacedKey key);
+ +
+ /** + /**
+ * Returns the metadata value that is stored on the + * Returns the metadata value that is stored on the
@ -88,10 +86,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param type the type the value must have and will be casted to + * @param type the type the value must have and will be casted to
+ * @param <P> the generic type of the stored primitive + * @param <P> the generic type of the stored primitive
+ * @param <C> the generic type of the eventually created complex object + * @param <C> the generic type of the eventually created complex object
+ *
+ * @return the value or {@code null} if no value was mapped under the given + * @return the value or {@code null} if no value was mapped under the given
+ * value + * value
+ *
+ * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the key to look up is null
+ * @throws IllegalArgumentException if the type to cast the found object to is + * @throws IllegalArgumentException if the type to cast the found object to is
+ * null + * null
@ -101,7 +97,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * the {@link + * the {@link
+ * PersistentDataType#getPrimitiveType()} + * PersistentDataType#getPrimitiveType()}
+ */ + */
+ <P, C> @Nullable C get(@NonNull NamespacedKey key, @NonNull PersistentDataType<P, C> type); + <P, C> @Nullable C get(NamespacedKey key, PersistentDataType<P, C> type);
+ +
+ /** + /**
+ * Returns the metadata value that is stored on the + * Returns the metadata value that is stored on the
@ -114,10 +110,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * the provided key + * the provided key
+ * @param <P> the generic type of the stored primitive + * @param <P> the generic type of the stored primitive
+ * @param <C> the generic type of the eventually created complex object + * @param <C> the generic type of the eventually created complex object
+ *
+ * @return the value or the default value if no value was mapped under the + * @return the value or the default value if no value was mapped under the
+ * given key + * given key
+ *
+ * @throws IllegalArgumentException if the key to look up is null + * @throws IllegalArgumentException if the key to look up is null
+ * @throws IllegalArgumentException if the type to cast the found object to is + * @throws IllegalArgumentException if the type to cast the found object to is
+ * null + * null
@ -126,18 +120,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws IllegalArgumentException if no suitable adapter was found for + * @throws IllegalArgumentException if no suitable adapter was found for
+ * the {@link PersistentDataType#getPrimitiveType()} + * the {@link PersistentDataType#getPrimitiveType()}
+ */ + */
+ <P, C> @NonNull C getOrDefault(@NonNull NamespacedKey key, @NonNull PersistentDataType<P, C> type, @NonNull C defaultValue); + <P, C> C getOrDefault(NamespacedKey key, PersistentDataType<P, C> type, C defaultValue);
+ +
+ /** + /**
+ * Get the set of keys present on this {@link PersistentDataContainer} + * Get the set of keys present on this {@link PersistentDataContainer}
+ * instance. + * instance.
+ * + * <p>
+ * Any changes made to the returned set will not be reflected on the + * Any changes made to the returned set will not be reflected on the
+ * instance. + * instance.
+ * + *
+ * @return the key set + * @return the key set
+ */ + */
+ @NonNull Set<NamespacedKey> getKeys(); + Set<NamespacedKey> getKeys();
+ +
+ /** + /**
+ * Returns if the container instance is empty, therefore has no entries + * Returns if the container instance is empty, therefore has no entries
@ -156,17 +150,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param other the container to copy to + * @param other the container to copy to
+ * @param replace whether to replace any matching values in the target container + * @param replace whether to replace any matching values in the target container
+ *
+ * @throws IllegalArgumentException if the other container is null + * @throws IllegalArgumentException if the other container is null
+ */ + */
+ void copyTo(@NonNull PersistentDataContainer other, boolean replace); + void copyTo(PersistentDataContainer other, boolean replace);
+ +
+ /** + /**
+ * Returns the adapter context this tag container uses. + * Returns the adapter context this tag container uses.
+ * + *
+ * @return the tag context + * @return the tag context
+ */ + */
+ @NonNull PersistentDataAdapterContext getAdapterContext(); + PersistentDataAdapterContext getAdapterContext();
+ +
+ /** + /**
+ * Serialize this {@link PersistentDataContainer} instance to a + * Serialize this {@link PersistentDataContainer} instance to a
@ -175,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a binary representation of this container + * @return a binary representation of this container
+ * @throws java.io.IOException if we fail to write this container to a byte array + * @throws java.io.IOException if we fail to write this container to a byte array
+ */ + */
+ byte @NonNull [] serializeToBytes() throws java.io.IOException; + byte[] serializeToBytes() throws java.io.IOException;
+} +}
diff --git a/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java b/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java diff --git a/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java b/src/main/java/io/papermc/paper/persistence/PersistentDataViewHolder.java
new file mode 100644 new file mode 100644
@ -185,13 +178,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.persistence; +package io.papermc.paper.persistence;
+ +
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * The {@link PersistentDataViewHolder} interface defines an object that can view + * The {@link PersistentDataViewHolder} interface defines an object that can view
+ * custom persistent data on it. + * custom persistent data on it.
+ */ + */
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface PersistentDataViewHolder { +public interface PersistentDataViewHolder {
+ +
@ -204,7 +198,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the persistent data container view + * @return the persistent data container view
+ */ + */
+ @NonNull PersistentDataContainerView getPersistentDataContainer(); + PersistentDataContainerView getPersistentDataContainer();
+} +}
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -14,33 +14,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.LongAdder; +import java.util.concurrent.atomic.LongAdder;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+@ApiStatus.Internal
+public class CachedSizeConcurrentLinkedQueue<E> extends ConcurrentLinkedQueue<E> { +public class CachedSizeConcurrentLinkedQueue<E> extends ConcurrentLinkedQueue<E> {
+
+ private final LongAdder cachedSize = new LongAdder(); + private final LongAdder cachedSize = new LongAdder();
+ +
+ @Override + @Override
+ public boolean add(@NotNull E e) { + public boolean add(final E e) {
+ boolean result = super.add(e); + final boolean result = super.add(e);
+ if (result) { + if (result) {
+ cachedSize.increment(); + this.cachedSize.increment();
+ } + }
+ return result; + return result;
+ } + }
+ +
+ @Nullable
+ @Override + @Override
+ public E poll() { + public @Nullable E poll() {
+ E result = super.poll(); + final E result = super.poll();
+ if (result != null) { + if (result != null) {
+ cachedSize.decrement(); + this.cachedSize.decrement();
+ } + }
+ return result; + return result;
+ } + }
+ +
+ @Override + @Override
+ public int size() { + public int size() {
+ return cachedSize.intValue(); + return this.cachedSize.intValue();
+ } + }
+} +}

View File

@ -23,12 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.entity; +package io.papermc.paper.entity;
+ +
+import org.bukkit.entity.Fish; +import org.bukkit.entity.Fish;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * Represents a fish that can school with other fish. + * Represents a fish that can school with other fish.
+ */ + */
+@NullMarked
+public interface SchoolableFish extends Fish { +public interface SchoolableFish extends Fish {
+ +
+ /** + /**
@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param leader fish to follow + * @param leader fish to follow
+ */ + */
+ void startFollowing(@NotNull SchoolableFish leader); + void startFollowing(SchoolableFish leader);
+ +
+ /** + /**
+ * Causes the fish to stop following their current + * Causes the fish to stop following their current
@ -63,8 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return following fish + * @return following fish
+ */ + */
+ @Nullable + @Nullable SchoolableFish getSchoolLeader();
+ SchoolableFish getSchoolLeader();
+ +
+} +}
diff --git a/src/main/java/org/bukkit/entity/AbstractHorse.java b/src/main/java/org/bukkit/entity/AbstractHorse.java diff --git a/src/main/java/org/bukkit/entity/AbstractHorse.java b/src/main/java/org/bukkit/entity/AbstractHorse.java

View File

@ -13,9 +13,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.command; +package io.papermc.paper.command;
+ +
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+public interface CommandBlockHolder { +public interface CommandBlockHolder {
+ +
+ /** + /**
@ -25,7 +26,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Command that this CommandBlock will run when activated. + * @return Command that this CommandBlock will run when activated.
+ */ + */
+ @NotNull
+ String getCommand(); + String getCommand();
+ +
+ /** + /**
@ -42,7 +42,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the last output + * @return the last output
+ */ + */
+ @NotNull
+ Component lastOutput(); + Component lastOutput();
+ +
+ /** + /**

View File

@ -33,20 +33,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.plugin; +package io.papermc.paper.plugin;
+ +
+import java.util.List;
+import java.util.Set;
+import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permissible;
+import org.bukkit.permissions.Permission; +import org.bukkit.permissions.Permission;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+
+import java.util.List;
+import java.util.Set;
+ +
+/** +/**
+ * A permission manager implementation to keep backwards compatibility partially alive with existing plugins that used + * A permission manager implementation to keep backwards compatibility partially alive with existing plugins that used
+ * the bukkit one before. + * the bukkit one before.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface PermissionManager { +public interface PermissionManager {
+ +
+ /** + /**
@ -55,8 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param name Name of the permission + * @param name Name of the permission
+ * @return Permission, or null if none + * @return Permission, or null if none
+ */ + */
+ @Nullable + @Nullable Permission getPermission(String name);
+ Permission getPermission(@NotNull String name);
+ +
+ /** + /**
+ * Adds a {@link Permission} to this plugin manager. + * Adds a {@link Permission} to this plugin manager.
@ -68,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws IllegalArgumentException Thrown when a permission with the same + * @throws IllegalArgumentException Thrown when a permission with the same
+ * name already exists + * name already exists
+ */ + */
+ void addPermission(@NotNull Permission perm); + void addPermission(Permission perm);
+ +
+ /** + /**
+ * Removes a {@link Permission} registration from this plugin manager. + * Removes a {@link Permission} registration from this plugin manager.
@ -81,7 +80,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param perm Permission to remove + * @param perm Permission to remove
+ */ + */
+ void removePermission(@NotNull Permission perm); + void removePermission(Permission perm);
+ +
+ /** + /**
+ * Removes a {@link Permission} registration from this plugin manager. + * Removes a {@link Permission} registration from this plugin manager.
@ -94,7 +93,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param name Permission to remove + * @param name Permission to remove
+ */ + */
+ void removePermission(@NotNull String name); + void removePermission(String name);
+ +
+ /** + /**
+ * Gets the default permissions for the given op status + * Gets the default permissions for the given op status
@ -102,7 +101,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param op Which set of default permissions to get + * @param op Which set of default permissions to get
+ * @return The default permissions + * @return The default permissions
+ */ + */
+ @NotNull
+ Set<Permission> getDefaultPermissions(boolean op); + Set<Permission> getDefaultPermissions(boolean op);
+ +
+ /** + /**
@ -113,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param perm Permission to recalculate + * @param perm Permission to recalculate
+ */ + */
+ void recalculatePermissionDefaults(@NotNull Permission perm); + void recalculatePermissionDefaults(Permission perm);
+ +
+ /** + /**
+ * Subscribes the given Permissible for information about the requested + * Subscribes the given Permissible for information about the requested
@ -125,7 +123,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param permission Permission to subscribe to + * @param permission Permission to subscribe to
+ * @param permissible Permissible subscribing + * @param permissible Permissible subscribing
+ */ + */
+ void subscribeToPermission(@NotNull String permission, @NotNull Permissible permissible); + void subscribeToPermission(String permission, Permissible permissible);
+ +
+ /** + /**
+ * Unsubscribes the given Permissible for information about the requested + * Unsubscribes the given Permissible for information about the requested
@ -134,7 +132,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param permission Permission to unsubscribe from + * @param permission Permission to unsubscribe from
+ * @param permissible Permissible subscribing + * @param permissible Permissible subscribing
+ */ + */
+ void unsubscribeFromPermission(@NotNull String permission, @NotNull Permissible permissible); + void unsubscribeFromPermission(String permission, Permissible permissible);
+ +
+ /** + /**
+ * Gets a set containing all subscribed {@link Permissible}s to the given + * Gets a set containing all subscribed {@link Permissible}s to the given
@ -143,8 +141,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param permission Permission to query for + * @param permission Permission to query for
+ * @return Set containing all subscribed permissions + * @return Set containing all subscribed permissions
+ */ + */
+ @NotNull + Set<Permissible> getPermissionSubscriptions(String permission);
+ Set<Permissible> getPermissionSubscriptions(@NotNull String permission);
+ +
+ /** + /**
+ * Subscribes to the given Default permissions by operator status + * Subscribes to the given Default permissions by operator status
@ -155,7 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param op Default list to subscribe to + * @param op Default list to subscribe to
+ * @param permissible Permissible subscribing + * @param permissible Permissible subscribing
+ */ + */
+ void subscribeToDefaultPerms(boolean op, @NotNull Permissible permissible); + void subscribeToDefaultPerms(boolean op, Permissible permissible);
+ +
+ /** + /**
+ * Unsubscribes from the given Default permissions by operator status + * Unsubscribes from the given Default permissions by operator status
@ -163,7 +160,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param op Default list to unsubscribe from + * @param op Default list to unsubscribe from
+ * @param permissible Permissible subscribing + * @param permissible Permissible subscribing
+ */ + */
+ void unsubscribeFromDefaultPerms(boolean op, @NotNull Permissible permissible); + void unsubscribeFromDefaultPerms(boolean op, Permissible permissible);
+ +
+ /** + /**
+ * Gets a set containing all subscribed {@link Permissible}s to the given + * Gets a set containing all subscribed {@link Permissible}s to the given
@ -172,7 +169,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param op Default list to query for + * @param op Default list to query for
+ * @return Set containing all subscribed permissions + * @return Set containing all subscribed permissions
+ */ + */
+ @NotNull
+ Set<Permissible> getDefaultPermSubscriptions(boolean op); + Set<Permissible> getDefaultPermSubscriptions(boolean op);
+ +
+ /** + /**
@ -182,7 +178,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Set containing all current registered permissions + * @return Set containing all current registered permissions
+ */ + */
+ @NotNull
+ Set<Permission> getPermissions(); + Set<Permission> getPermissions();
+ +
+ /** + /**
@ -192,7 +187,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param perm permission + * @param perm permission
+ */ + */
+ void addPermissions(@NotNull List<Permission> perm); + void addPermissions(List<Permission> perm);
+ +
+ /** + /**
+ * Clears the current registered permissinos. + * Clears the current registered permissinos.
@ -211,6 +206,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.plugin.bootstrap; +package io.papermc.paper.plugin.bootstrap;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin + * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin
@ -219,6 +215,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * like the plugin's configuration or logger during the plugins bootstrap. + * like the plugin's configuration or logger during the plugins bootstrap.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface BootstrapContext extends PluginProviderContext { +public interface BootstrapContext extends PluginProviderContext {
+} +}
@ -233,7 +230,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.provider.util.ProviderUtil; +import io.papermc.paper.plugin.provider.util.ProviderUtil;
+import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A plugin bootstrap is meant for loading certain parts of the plugin before the server is loaded. + * A plugin bootstrap is meant for loading certain parts of the plugin before the server is loaded.
@ -245,8 +242,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * <p> + * <p>
+ * <b>All calls to Bukkit may throw a NullPointerExceptions or return null unexpectedly. You should only call api methods that are explicitly documented to work in the bootstrapper</b> + * <b>All calls to Bukkit may throw a NullPointerExceptions or return null unexpectedly. You should only call api methods that are explicitly documented to work in the bootstrapper</b>
+ */ + */
+@ApiStatus.OverrideOnly
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.OverrideOnly
+public interface PluginBootstrap { +public interface PluginBootstrap {
+ +
+ /** + /**
@ -254,7 +252,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param context the server provided context + * @param context the server provided context
+ */ + */
+ void bootstrap(@NotNull BootstrapContext context); + void bootstrap(BootstrapContext context);
+ +
+ /** + /**
+ * Called by the server to instantiate your main class. + * Called by the server to instantiate your main class.
@ -264,8 +262,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param context the server created bootstrap object + * @param context the server created bootstrap object
+ * @return the server requested instance of the plugins main class. + * @return the server requested instance of the plugins main class.
+ */ + */
+ @NotNull + default JavaPlugin createPlugin(final PluginProviderContext context) {
+ default JavaPlugin createPlugin(@NotNull PluginProviderContext context) {
+ return ProviderUtil.loadClass(context.getConfiguration().getMainClass(), JavaPlugin.class, this.getClass().getClassLoader()); + return ProviderUtil.loadClass(context.getConfiguration().getMainClass(), JavaPlugin.class, this.getClass().getClassLoader());
+ } + }
+} +}
@ -278,11 +275,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.plugin.bootstrap; +package io.papermc.paper.plugin.bootstrap;
+ +
+import io.papermc.paper.plugin.configuration.PluginMeta; +import io.papermc.paper.plugin.configuration.PluginMeta;
+import java.nio.file.Path;
+import net.kyori.adventure.text.logger.slf4j.ComponentLogger; +import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+
+import java.nio.file.Path;
+ +
+/** +/**
+ * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin + * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin
@ -290,8 +286,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * A bootstrap context may be used to access data or logic usually provided to {@link org.bukkit.plugin.Plugin} instances + * A bootstrap context may be used to access data or logic usually provided to {@link org.bukkit.plugin.Plugin} instances
+ * like the plugin's configuration or logger during the plugins bootstrap. + * like the plugin's configuration or logger during the plugins bootstrap.
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable
+public interface PluginProviderContext { +public interface PluginProviderContext {
+ +
+ /** + /**
@ -299,7 +296,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the plugin's configuration + * @return the plugin's configuration
+ */ + */
+ @NotNull
+ PluginMeta getConfiguration(); + PluginMeta getConfiguration();
+ +
+ /** + /**
@ -307,7 +303,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the previously described path + * @return the previously described path
+ */ + */
+ @NotNull
+ Path getDataDirectory(); + Path getDataDirectory();
+ +
+ /** + /**
@ -315,7 +310,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the logger instance + * @return the logger instance
+ */ + */
+ @NotNull
+ ComponentLogger getLogger(); + ComponentLogger getLogger();
+ +
+ /** + /**
@ -323,7 +317,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the previously described path + * @return the previously described path
+ */ + */
+ @NotNull
+ Path getPluginSource(); + Path getPluginSource();
+ +
+} +}
@ -335,21 +328,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.plugin.configuration; +package io.papermc.paper.plugin.configuration;
+ +
+import java.util.List;
+import org.bukkit.permissions.Permission; +import org.bukkit.permissions.Permission;
+import org.bukkit.permissions.PermissionDefault; +import org.bukkit.permissions.PermissionDefault;
+import org.bukkit.plugin.PluginLoadOrder; +import org.bukkit.plugin.PluginLoadOrder;
+import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+
+import java.util.List;
+ +
+/** +/**
+ * This class acts as an abstraction for a plugin configuration. + * This class acts as an abstraction for a plugin configuration.
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental // Subject to change! +@ApiStatus.Experimental // Subject to change!
+@NullMarked
+@ApiStatus.NonExtendable
+public interface PluginMeta { +public interface PluginMeta {
+ +
+ /** + /**
@ -369,7 +362,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the name of the plugin + * @return the name of the plugin
+ */ + */
+ @NotNull
+ String getName(); + String getName();
+ +
+ /** + /**
@ -377,7 +369,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a descriptive name of the plugin and respective version + * @return a descriptive name of the plugin and respective version
+ */ + */
+ @NotNull
+ default String getDisplayName() { + default String getDisplayName() {
+ return this.getName() + " v" + this.getVersion(); + return this.getName() + " v" + this.getVersion();
+ } + }
@ -388,7 +379,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the fully qualified class name of the plugin's main class. + * @return the fully qualified class name of the plugin's main class.
+ */ + */
+ @NotNull
+ String getMainClass(); + String getMainClass();
+ +
+ /** + /**
@ -397,7 +387,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the plugin load order + * @return the plugin load order
+ * @see PluginLoadOrder for further details regards the available load orders. + * @see PluginLoadOrder for further details regards the available load orders.
+ */ + */
+ @NotNull
+ PluginLoadOrder getLoadOrder(); + PluginLoadOrder getLoadOrder();
+ +
+ /** + /**
@ -407,7 +396,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the string representation of the plugin's version + * @return the string representation of the plugin's version
+ */ + */
+ @NotNull
+ String getVersion(); + String getVersion();
+ +
+ /** + /**
@ -418,8 +406,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the specific overwrite of the logger prefix as defined by the plugin. If the plugin did not define a + * @return the specific overwrite of the logger prefix as defined by the plugin. If the plugin did not define a
+ * custom logger prefix, this method will return null + * custom logger prefix, this method will return null
+ */ + */
+ @Nullable + @Nullable String getLoggerPrefix();
+ String getLoggerPrefix();
+ +
+ /** + /**
+ * Provides a list of dependencies that are required for this plugin to load. + * Provides a list of dependencies that are required for this plugin to load.
@ -430,7 +417,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return an immutable list of required dependency names + * @return an immutable list of required dependency names
+ */ + */
+ @NotNull
+ List<String> getPluginDependencies(); + List<String> getPluginDependencies();
+ +
+ /** + /**
@ -443,7 +429,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return immutable list of soft dependencies + * @return immutable list of soft dependencies
+ */ + */
+ @NotNull
+ List<String> getPluginSoftDependencies(); + List<String> getPluginSoftDependencies();
+ +
+ /** + /**
@ -456,7 +441,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return immutable list of plugins to load before this plugin + * @return immutable list of plugins to load before this plugin
+ */ + */
+ @NotNull
+ List<String> getLoadBeforePlugins(); + List<String> getLoadBeforePlugins();
+ +
+ /** + /**
@ -466,7 +450,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return immutable list of provided plugins/dependencies + * @return immutable list of provided plugins/dependencies
+ */ + */
+ @NotNull
+ List<String> getProvidedPlugins(); + List<String> getProvidedPlugins();
+ +
+ /** + /**
@ -475,7 +458,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return an immutable list of the plugin's authors + * @return an immutable list of the plugin's authors
+ */ + */
+ @NotNull
+ List<String> getAuthors(); + List<String> getAuthors();
+ +
+ /** + /**
@ -484,7 +466,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return an immutable list of the plugin's contributors + * @return an immutable list of the plugin's contributors
+ */ + */
+ @NotNull
+ List<String> getContributors(); + List<String> getContributors();
+ +
+ /** + /**
@ -493,8 +474,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return description or null if the plugin did not define a human readable description. + * @return description or null if the plugin did not define a human readable description.
+ */ + */
+ @Nullable + @Nullable String getDescription();
+ String getDescription();
+ +
+ /** + /**
+ * Provides the website for the plugin or the plugin's author. + * Provides the website for the plugin or the plugin's author.
@ -502,8 +482,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a string representation of the website that serves as the main hub for this plugin/its author. + * @return a string representation of the website that serves as the main hub for this plugin/its author.
+ */ + */
+ @Nullable + @Nullable String getWebsite();
+ String getWebsite();
+ +
+ /** + /**
+ * Provides the list of permissions that are defined via the plugin meta instance. + * Provides the list of permissions that are defined via the plugin meta instance.
@ -511,7 +490,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return an immutable list of permissions + * @return an immutable list of permissions
+ */ + */
+ // TODO: Do we even want this? Why not just use the bootstrapper + // TODO: Do we even want this? Why not just use the bootstrapper
+ @NotNull
+ List<Permission> getPermissions(); + List<Permission> getPermissions();
+ +
+ /** + /**
@ -521,7 +499,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #getPermissions() + * @see #getPermissions()
+ */ + */
+ // TODO: Do we even want this? Why not just use the bootstrapper + // TODO: Do we even want this? Why not just use the bootstrapper
+ @NotNull
+ PermissionDefault getPermissionDefault(); + PermissionDefault getPermissionDefault();
+ +
+ /** + /**
@ -532,8 +509,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the version string made up of the major and minor version (e.g. 1.18 or 1.19). Minor versions like 1.18.2 + * @return the version string made up of the major and minor version (e.g. 1.18 or 1.19). Minor versions like 1.18.2
+ * are unified to their major release version (in this example 1.18) + * are unified to their major release version (in this example 1.18)
+ */ + */
+ @Nullable + @Nullable String getAPIVersion();
+ String getAPIVersion();
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/configuration/package-info.java b/src/main/java/io/papermc/paper/plugin/configuration/package-info.java diff --git a/src/main/java/io/papermc/paper/plugin/configuration/package-info.java b/src/main/java/io/papermc/paper/plugin/configuration/package-info.java
@ -563,14 +539,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.loader.library.LibraryStore; +import io.papermc.paper.plugin.loader.library.LibraryStore;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A mutable builder that may be used to collect and register all {@link ClassPathLibrary} instances a + * A mutable builder that may be used to collect and register all {@link ClassPathLibrary} instances a
+ * {@link PluginLoader} aims to provide to its plugin at runtime. + * {@link PluginLoader} aims to provide to its plugin at runtime.
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable
+public interface PluginClasspathBuilder { +public interface PluginClasspathBuilder {
+ +
+ /** + /**
@ -587,11 +564,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.plugin.loader.library.impl.JarLibrary + * @see io.papermc.paper.plugin.loader.library.impl.JarLibrary
+ * @see io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver + * @see io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver
+ */ + */
+ @NotNull
+ @Contract("_ -> this") + @Contract("_ -> this")
+ PluginClasspathBuilder addLibrary(@NotNull ClassPathLibrary classPathLibrary); + PluginClasspathBuilder addLibrary(ClassPathLibrary classPathLibrary);
+ +
+ @NotNull
+ PluginProviderContext getContext(); + PluginProviderContext getContext();
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/loader/PluginLoader.java b/src/main/java/io/papermc/paper/plugin/loader/PluginLoader.java diff --git a/src/main/java/io/papermc/paper/plugin/loader/PluginLoader.java b/src/main/java/io/papermc/paper/plugin/loader/PluginLoader.java
@ -603,7 +578,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.plugin.loader; +package io.papermc.paper.plugin.loader;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A plugin loader is responsible for creating certain aspects of a plugin before it is created. + * A plugin loader is responsible for creating certain aspects of a plugin before it is created.
@ -615,8 +590,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * It should be noted that this class will be called from a different classloader, this will cause any static values + * It should be noted that this class will be called from a different classloader, this will cause any static values
+ * set in this class/any other classes loaded not to persist when the plugin loads. + * set in this class/any other classes loaded not to persist when the plugin loads.
+ */ + */
+@ApiStatus.OverrideOnly
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.OverrideOnly
+public interface PluginLoader { +public interface PluginLoader {
+ +
+ /** + /**
@ -627,7 +603,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param classpathBuilder a mutable classpath builder that may be used to register custom runtime dependencies + * @param classpathBuilder a mutable classpath builder that may be used to register custom runtime dependencies
+ * for the plugin the loader was registered for. + * for the plugin the loader was registered for.
+ */ + */
+ void classloader(@NotNull PluginClasspathBuilder classpathBuilder); + void classloader(PluginClasspathBuilder classpathBuilder);
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/ClassPathLibrary.java b/src/main/java/io/papermc/paper/plugin/loader/library/ClassPathLibrary.java diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/ClassPathLibrary.java b/src/main/java/io/papermc/paper/plugin/loader/library/ClassPathLibrary.java
@ -638,12 +614,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.plugin.loader.library; +package io.papermc.paper.plugin.loader.library;
+ +
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * The classpath library interface represents libraries that are capable of registering themselves via + * The classpath library interface represents libraries that are capable of registering themselves via
+ * {@link #register(LibraryStore)} on any given {@link LibraryStore}. + * {@link #register(LibraryStore)} on any given {@link LibraryStore}.
+ */ + */
+@NullMarked
+public interface ClassPathLibrary { +public interface ClassPathLibrary {
+ +
+ /** + /**
@ -654,7 +631,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param store the library store instance to register this library into + * @param store the library store instance to register this library into
+ * @throws LibraryLoadingException if library loading failed for this classpath library + * @throws LibraryLoadingException if library loading failed for this classpath library
+ */ + */
+ void register(@NotNull LibraryStore store) throws LibraryLoadingException; + void register(LibraryStore store) throws LibraryLoadingException;
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/LibraryLoadingException.java b/src/main/java/io/papermc/paper/plugin/loader/library/LibraryLoadingException.java diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/LibraryLoadingException.java b/src/main/java/io/papermc/paper/plugin/loader/library/LibraryLoadingException.java
new file mode 100644 new file mode 100644
@ -685,10 +662,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package io.papermc.paper.plugin.loader.library; +package io.papermc.paper.plugin.loader.library;
+ +
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.nio.file.Path; +import java.nio.file.Path;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a storage that stores library jars. + * Represents a storage that stores library jars.
@ -699,6 +675,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see io.papermc.paper.plugin.loader.PluginLoader + * @see io.papermc.paper.plugin.loader.PluginLoader
+ */ + */
+@ApiStatus.Internal +@ApiStatus.Internal
+@NullMarked
+public interface LibraryStore { +public interface LibraryStore {
+ +
+ /** + /**
@ -706,7 +683,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param library path to the libraries jar file on the disk + * @param library path to the libraries jar file on the disk
+ */ + */
+ void addLibrary(@NotNull Path library); + void addLibrary(Path library);
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/impl/JarLibrary.java b/src/main/java/io/papermc/paper/plugin/loader/library/impl/JarLibrary.java diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/impl/JarLibrary.java b/src/main/java/io/papermc/paper/plugin/loader/library/impl/JarLibrary.java
@ -720,10 +697,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.loader.library.ClassPathLibrary; +import io.papermc.paper.plugin.loader.library.ClassPathLibrary;
+import io.papermc.paper.plugin.loader.library.LibraryLoadingException; +import io.papermc.paper.plugin.loader.library.LibraryLoadingException;
+import io.papermc.paper.plugin.loader.library.LibraryStore; +import io.papermc.paper.plugin.loader.library.LibraryStore;
+import org.jetbrains.annotations.NotNull;
+
+import java.nio.file.Files; +import java.nio.file.Files;
+import java.nio.file.Path; +import java.nio.file.Path;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A simple jar library implementation of the {@link ClassPathLibrary} that allows {@link io.papermc.paper.plugin.loader.PluginLoader}s to + * A simple jar library implementation of the {@link ClassPathLibrary} that allows {@link io.papermc.paper.plugin.loader.PluginLoader}s to
@ -738,6 +714,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * <p> + * <p>
+ * The jar library implementation will error if the file does not exist at the specified path. + * The jar library implementation will error if the file does not exist at the specified path.
+ */ + */
+@NullMarked
+public class JarLibrary implements ClassPathLibrary { +public class JarLibrary implements ClassPathLibrary {
+ +
+ private final Path path; + private final Path path;
@ -747,12 +724,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @param path the path, relative to the JVMs start directory. + * @param path the path, relative to the JVMs start directory.
+ */ + */
+ public JarLibrary(@NotNull Path path) { + public JarLibrary(final Path path) {
+ this.path = path; + this.path = path;
+ } + }
+ +
+ @Override + @Override
+ public void register(@NotNull LibraryStore store) throws LibraryLoadingException { + public void register(final LibraryStore store) throws LibraryLoadingException {
+ if (Files.notExists(this.path)) { + if (Files.notExists(this.path)) {
+ throw new LibraryLoadingException("Could not find library at " + this.path); + throw new LibraryLoadingException("Could not find library at " + this.path);
+ } + }
@ -771,6 +748,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.loader.library.ClassPathLibrary; +import io.papermc.paper.plugin.loader.library.ClassPathLibrary;
+import io.papermc.paper.plugin.loader.library.LibraryLoadingException; +import io.papermc.paper.plugin.loader.library.LibraryLoadingException;
+import io.papermc.paper.plugin.loader.library.LibraryStore; +import io.papermc.paper.plugin.loader.library.LibraryStore;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystem;
@ -791,14 +771,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.eclipse.aether.transfer.TransferCancelledException; +import org.eclipse.aether.transfer.TransferCancelledException;
+import org.eclipse.aether.transfer.TransferEvent; +import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transport.http.HttpTransporterFactory; +import org.eclipse.aether.transport.http.HttpTransporterFactory;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.slf4j.Logger; +import org.slf4j.Logger;
+import org.slf4j.LoggerFactory; +import org.slf4j.LoggerFactory;
+ +
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/** +/**
+ * The maven library resolver acts as a resolver for yet to be resolved jar libraries that may be pulled from a + * The maven library resolver acts as a resolver for yet to be resolved jar libraries that may be pulled from a
+ * remote maven repository. + * remote maven repository.
@ -813,12 +789,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * "central", "default", "https://repo1.maven.org/maven2/" + * "central", "default", "https://repo1.maven.org/maven2/"
+ * ).build()); + * ).build());
+ * }</pre> + * }</pre>
+ * + * <p>
+ * Plugins may create and register a {@link MavenLibraryResolver} after configuring it. + * Plugins may create and register a {@link MavenLibraryResolver} after configuring it.
+ */ + */
+@NullMarked
+public class MavenLibraryResolver implements ClassPathLibrary { +public class MavenLibraryResolver implements ClassPathLibrary {
+ +
+ private static final Logger logger = LoggerFactory.getLogger("MavenLibraryResolver"); + private static final Logger LOGGER = LoggerFactory.getLogger("MavenLibraryResolver");
+ +
+ private final RepositorySystem repository; + private final RepositorySystem repository;
+ private final DefaultRepositorySystemSession session; + private final DefaultRepositorySystemSession session;
@ -834,7 +811,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * submitting the {@link MavenLibraryResolver} to the {@link io.papermc.paper.plugin.loader.PluginClasspathBuilder}. + * submitting the {@link MavenLibraryResolver} to the {@link io.papermc.paper.plugin.loader.PluginClasspathBuilder}.
+ */ + */
+ public MavenLibraryResolver() { + public MavenLibraryResolver() {
+ DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + final DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+ locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
+ locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
+ +
@ -846,8 +823,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.session.setLocalRepositoryManager(this.repository.newLocalRepositoryManager(this.session, new LocalRepository("libraries"))); + this.session.setLocalRepositoryManager(this.repository.newLocalRepositoryManager(this.session, new LocalRepository("libraries")));
+ this.session.setTransferListener(new AbstractTransferListener() { + this.session.setTransferListener(new AbstractTransferListener() {
+ @Override + @Override
+ public void transferInitiated(@NotNull TransferEvent event) throws TransferCancelledException { + public void transferInitiated(final TransferEvent event) throws TransferCancelledException {
+ logger.info("Downloading {}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName()); + LOGGER.info("Downloading {}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName());
+ } + }
+ }); + });
+ this.session.setReadOnly(); + this.session.setReadOnly();
@ -860,7 +837,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param dependency the definition of the dependency the maven library resolver should resolve when running + * @param dependency the definition of the dependency the maven library resolver should resolve when running
+ * @see MavenLibraryResolver#addRepository(RemoteRepository) + * @see MavenLibraryResolver#addRepository(RemoteRepository)
+ */ + */
+ public void addDependency(@NotNull Dependency dependency) { + public void addDependency(final Dependency dependency) {
+ this.dependencies.add(dependency); + this.dependencies.add(dependency);
+ } + }
+ +
@ -872,7 +849,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param remoteRepository the configuration that defines the maven repository this library resolver should fetch + * @param remoteRepository the configuration that defines the maven repository this library resolver should fetch
+ * dependencies from + * dependencies from
+ */ + */
+ public void addRepository(@NotNull RemoteRepository remoteRepository) { + public void addRepository(final RemoteRepository remoteRepository) {
+ this.repositories.add(remoteRepository); + this.repositories.add(remoteRepository);
+ } + }
+ +
@ -883,18 +860,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws LibraryLoadingException if resolving a dependency failed + * @throws LibraryLoadingException if resolving a dependency failed
+ */ + */
+ @Override + @Override
+ public void register(@NotNull LibraryStore store) throws LibraryLoadingException { + public void register(final LibraryStore store) throws LibraryLoadingException {
+ List<RemoteRepository> repos = this.repository.newResolutionRepositories(this.session, this.repositories); + final List<RemoteRepository> repos = this.repository.newResolutionRepositories(this.session, this.repositories);
+ +
+ DependencyResult result; + final DependencyResult result;
+ try { + try {
+ result = this.repository.resolveDependencies(this.session, new DependencyRequest(new CollectRequest((Dependency) null, this.dependencies, repos), null)); + result = this.repository.resolveDependencies(this.session, new DependencyRequest(new CollectRequest((Dependency) null, this.dependencies, repos), null));
+ } catch (DependencyResolutionException ex) { + } catch (final DependencyResolutionException ex) {
+ throw new LibraryLoadingException("Error resolving libraries", ex); + throw new LibraryLoadingException("Error resolving libraries", ex);
+ } + }
+ +
+ for (ArtifactResult artifact : result.getArtifactResults()) { + for (final ArtifactResult artifact : result.getArtifactResults()) {
+ File file = artifact.getArtifact().getFile(); + final File file = artifact.getArtifact().getFile();
+ store.addLibrary(file.toPath()); + store.addLibrary(file.toPath());
+ } + }
+ } + }
@ -908,7 +885,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.plugin.provider.classloader; +package io.papermc.paper.plugin.provider.classloader;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * The class loader access interface is an <b>internal</b> representation of a class accesses' ability to see types + * The class loader access interface is an <b>internal</b> representation of a class accesses' ability to see types
@ -919,6 +896,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * is owned by a direct or transitive dependency of the plugin, preventing the plugin for accidentally discovering and + * is owned by a direct or transitive dependency of the plugin, preventing the plugin for accidentally discovering and
+ * using class types that are supplied by plugins/libraries the plugin did not actively define as a dependency. + * using class types that are supplied by plugins/libraries the plugin did not actively define as a dependency.
+ */ + */
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public interface ClassLoaderAccess { +public interface ClassLoaderAccess {
+ +
@ -948,12 +926,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.plugin.provider.classloader; +package io.papermc.paper.plugin.provider.classloader;
+ +
+import io.papermc.paper.plugin.configuration.PluginMeta; +import io.papermc.paper.plugin.configuration.PluginMeta;
+import java.io.Closeable;
+import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +import org.jspecify.annotations.Nullable;
+import java.io.Closeable;
+import org.jetbrains.annotations.Nullable;
+ +
+/** +/**
+ * The configured plugin class loader represents an <b>internal</b> abstraction over the classloaders used by the server + * The configured plugin class loader represents an <b>internal</b> abstraction over the classloaders used by the server
@ -962,6 +939,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * It implements {@link Closeable} to define the ability to shutdown and close the classloader that implements this + * It implements {@link Closeable} to define the ability to shutdown and close the classloader that implements this
+ * interface. + * interface.
+ */ + */
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public interface ConfiguredPluginClassLoader extends Closeable { +public interface ConfiguredPluginClassLoader extends Closeable {
+ +
@ -987,7 +965,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see ClassLoader#loadClass(String) + * @see ClassLoader#loadClass(String)
+ * @see Class#forName(String, boolean, ClassLoader) + * @see Class#forName(String, boolean, ClassLoader)
+ */ + */
+ Class<?> loadClass(@NotNull String name, + Class<?> loadClass(String name,
+ boolean resolve, + boolean resolve,
+ boolean checkGlobal, + boolean checkGlobal,
+ boolean checkLibraries) throws ClassNotFoundException; + boolean checkLibraries) throws ClassNotFoundException;
@ -1013,8 +991,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * that is used by the underlying classloader + * that is used by the underlying classloader
+ * @return classloader + * @return classloader
+ */ + */
+ @Nullable + @Nullable PluginClassLoaderGroup getGroup();
+ PluginClassLoaderGroup getGroup();
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java b/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java diff --git a/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java b/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java
new file mode 100644 new file mode 100644
@ -1147,7 +1124,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * A plugin classloader group represents a group of classloaders that a plugins classloader may access. + * A plugin classloader group represents a group of classloaders that a plugins classloader may access.
@ -1155,6 +1133,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * An example of this would be a classloader group that holds all direct and transitive dependencies a plugin declared, + * An example of this would be a classloader group that holds all direct and transitive dependencies a plugin declared,
+ * allowing a plugins classloader to access classes included in these dependencies via this group. + * allowing a plugins classloader to access classes included in these dependencies via this group.
+ */ + */
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public interface PluginClassLoaderGroup { +public interface PluginClassLoaderGroup {
+ +
@ -1172,8 +1151,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * will be returned. + * will be returned.
+ * @see ConfiguredPluginClassLoader#loadClass(String, boolean, boolean, boolean) + * @see ConfiguredPluginClassLoader#loadClass(String, boolean, boolean, boolean)
+ */ + */
+ @Nullable + @Nullable Class<?> getClassByName(String name, boolean resolve, ConfiguredPluginClassLoader requester);
+ Class<?> getClassByName(String name, boolean resolve, ConfiguredPluginClassLoader requester);
+ +
+ /** + /**
+ * Removes a configured plugin classloader from this class loader group. + * Removes a configured plugin classloader from this class loader group.
@ -1218,7 +1196,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.plugin.configuration.PluginMeta; +import io.papermc.paper.plugin.configuration.PluginMeta;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A dependency context is a read-only abstraction of a type/concept that can resolve dependencies between plugins. + * A dependency context is a read-only abstraction of a type/concept that can resolve dependencies between plugins.
@ -1226,6 +1204,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * This may for example be the server wide plugin manager itself, capable of validating if a dependency exists between + * This may for example be the server wide plugin manager itself, capable of validating if a dependency exists between
+ * two {@link PluginMeta} instances, however the implementation is not limited to such a concrete use-case. + * two {@link PluginMeta} instances, however the implementation is not limited to such a concrete use-case.
+ */ + */
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public interface DependencyContext { +public interface DependencyContext {
+ +
@ -1245,7 +1224,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param depend the potential transitive dependency of the {@code plugin} parameter. + * @param depend the potential transitive dependency of the {@code plugin} parameter.
+ * @return a simple boolean flag indicating if {@code plugin} considers {@code depend} as a transitive dependency. + * @return a simple boolean flag indicating if {@code plugin} considers {@code depend} as a transitive dependency.
+ */ + */
+ boolean isTransitiveDependency(@NotNull PluginMeta plugin, @NotNull PluginMeta depend); + boolean isTransitiveDependency(PluginMeta plugin, PluginMeta depend);
+ +
+ /** + /**
+ * Computes if this dependency context is aware of a dependency that provides/matches the passed identifier. + * Computes if this dependency context is aware of a dependency that provides/matches the passed identifier.
@ -1259,7 +1238,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return a plain boolean flag indicating if this dependency context is aware of a potential dependency with the + * @return a plain boolean flag indicating if this dependency context is aware of a potential dependency with the
+ * passed identifier. + * passed identifier.
+ */ + */
+ boolean hasDependency(@NotNull String pluginIdentifier); + boolean hasDependency(String pluginIdentifier);
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java b/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java diff --git a/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java b/src/main/java/io/papermc/paper/plugin/provider/util/ProviderUtil.java
@ -1272,16 +1251,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import com.destroystokyo.paper.util.SneakyThrow; +import com.destroystokyo.paper.util.SneakyThrow;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+/** +/**
+ * An <b>internal</b> utility type that holds logic for loading a provider-like type from a classloaders. + * An <b>internal</b> utility type that holds logic for loading a provider-like type from a classloaders.
+ * Provides, at least in the context of this utility, define themselves as implementations of a specific parent + * Provides, at least in the context of this utility, define themselves as implementations of a specific parent
+ * interface/type, e.g. {@link org.bukkit.plugin.java.JavaPlugin} and implement a no-args constructor. + * interface/type, e.g. {@link org.bukkit.plugin.java.JavaPlugin} and implement a no-args constructor.
+ */ + */
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+public class ProviderUtil { +public final class ProviderUtil {
+ +
+ /** + /**
+ * Loads the class found at the provided fully qualified class name from the passed classloader, creates a new + * Loads the class found at the provided fully qualified class name from the passed classloader, creates a new
@ -1294,8 +1274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the generic type of the parent class the created object will be cast to + * @param <T> the generic type of the parent class the created object will be cast to
+ * @return the object instantiated from the class found at the provided FQN, cast to the parent type + * @return the object instantiated from the class found at the provided FQN, cast to the parent type
+ */ + */
+ @NotNull + public static <T> T loadClass(final String clazz, final Class<T> classType, final ClassLoader loader) {
+ public static <T> T loadClass(@NotNull String clazz, @NotNull Class<T> classType, @NotNull ClassLoader loader) {
+ return loadClass(clazz, classType, loader, null); + return loadClass(clazz, classType, loader, null);
+ } + }
+ +
@ -1312,30 +1291,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the object instantiated from the class found at the provided fully qualified class name, cast to the + * @return the object instantiated from the class found at the provided fully qualified class name, cast to the
+ * parent type + * parent type
+ */ + */
+ @NotNull + public static <T> T loadClass(final String clazz, final Class<T> classType, final ClassLoader loader, final @Nullable Runnable onError) {
+ public static <T> T loadClass(@NotNull String clazz, @NotNull Class<T> classType, @NotNull ClassLoader loader, @Nullable Runnable onError) {
+ try { + try {
+ T clazzInstance; + final T clazzInstance;
+ +
+ try { + try {
+ Class<?> jarClass = Class.forName(clazz, true, loader); + final Class<?> jarClass = Class.forName(clazz, true, loader);
+ +
+ Class<? extends T> pluginClass; + final Class<? extends T> pluginClass;
+ try { + try {
+ pluginClass = jarClass.asSubclass(classType); + pluginClass = jarClass.asSubclass(classType);
+ } catch (ClassCastException ex) { + } catch (final ClassCastException ex) {
+ throw new ClassCastException("class '%s' does not extend '%s'".formatted(clazz, classType)); + throw new ClassCastException("class '%s' does not extend '%s'".formatted(clazz, classType));
+ } + }
+ +
+ clazzInstance = pluginClass.getDeclaredConstructor().newInstance(); + clazzInstance = pluginClass.getDeclaredConstructor().newInstance();
+ } catch (IllegalAccessException exception) { + } catch (final IllegalAccessException exception) {
+ throw new RuntimeException("No public constructor"); + throw new RuntimeException("No public constructor");
+ } catch (InstantiationException exception) { + } catch (final InstantiationException exception) {
+ throw new RuntimeException("Abnormal class instantiation", exception); + throw new RuntimeException("Abnormal class instantiation", exception);
+ } + }
+ +
+ return clazzInstance; + return clazzInstance;
+ } catch (Throwable e) { + } catch (final Throwable e) {
+ if (onError != null) { + if (onError != null) {
+ onError.run(); + onError.run();
+ } + }

View File

@ -17,16 +17,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.event.Cancellable; +import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList; +import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Thrown when a player attempts to pick an item up from the ground + * Thrown when a player attempts to pick an item up from the ground
+ */ + */
+@NullMarked
+public class PlayerAttemptPickupItemEvent extends PlayerEvent implements Cancellable { +public class PlayerAttemptPickupItemEvent extends PlayerEvent implements Cancellable {
+ +
+ private static final HandlerList HANDLER_LIST = new HandlerList(); + private static final HandlerList HANDLER_LIST = new HandlerList();
+ +
+ @NotNull private final Item item; + private final Item item;
+ private final int remaining; + private final int remaining;
+ private boolean flyAtPlayer = true; + private boolean flyAtPlayer = true;
+ +
@ -34,12 +35,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @Deprecated // Remove in 1.13 // Remove in 1.14? + @Deprecated // Remove in 1.13 // Remove in 1.14?
+ @ApiStatus.Internal + @ApiStatus.Internal
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item) { + public PlayerAttemptPickupItemEvent(final Player player, final Item item) {
+ this(player, item, 0); + this(player, item, 0);
+ } + }
+ +
+ @ApiStatus.Internal + @ApiStatus.Internal
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item, final int remaining) { + public PlayerAttemptPickupItemEvent(final Player player, final Item item, final int remaining) {
+ super(player); + super(player);
+ this.item = item; + this.item = item;
+ this.remaining = remaining; + this.remaining = remaining;
@ -50,7 +51,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return Item + * @return Item
+ */ + */
+ @NotNull
+ public Item getItem() { + public Item getItem() {
+ return this.item; + return this.item;
+ } + }
@ -95,13 +95,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.flyAtPlayer = !cancel; + this.flyAtPlayer = !cancel;
+ } + }
+ +
+ @NotNull
+ @Override + @Override
+ public HandlerList getHandlers() { + public HandlerList getHandlers() {
+ return HANDLER_LIST; + return HANDLER_LIST;
+ } + }
+ +
+ @NotNull
+ public static HandlerList getHandlerList() { + public static HandlerList getHandlerList() {
+ return HANDLER_LIST; + return HANDLER_LIST;
+ } + }

View File

@ -13,14 +13,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.registry; +package io.papermc.paper.registry;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * To be implemented by any type used for modifying registries. + * To be implemented by any type used for modifying registries.
+ * + *
+ * @param <T> registry value type + * @param <T> registry value type
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable
+public interface RegistryBuilder<T> { +public interface RegistryBuilder<T> {
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java b/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java b/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java
@ -36,8 +38,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.Tag;
+import io.papermc.paper.registry.tag.TagKey; +import io.papermc.paper.registry.tag.TagKey;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Event object for {@link RegistryEventProvider#entryAdd()}. This + * Event object for {@link RegistryEventProvider#entryAdd()}. This
@ -48,6 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <B> registry entry builder type + * @param <B> registry entry builder type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> { +public interface RegistryEntryAddEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> {
+ +
@ -56,14 +59,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the object builder + * @return the object builder
+ */ + */
+ @NonNull B builder(); + B builder();
+ +
+ /** + /**
+ * Gets the key for this entry in the registry. + * Gets the key for this entry in the registry.
+ * + *
+ * @return the key + * @return the key
+ */ + */
+ @NonNull TypedKey<T> key(); + TypedKey<T> key();
+ +
+ /** + /**
+ * Gets or creates a tag for the given tag key. This tag + * Gets or creates a tag for the given tag key. This tag
@ -74,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the tag + * @return the tag
+ * @param <V> the tag value type + * @param <V> the tag value type
+ */ + */
+ @NonNull <V extends Keyed> Tag<V> getOrCreateTag(@NonNull TagKey<V> tagKey); + <V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java b/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java b/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java
new file mode 100644 new file mode 100644
@ -86,8 +89,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Base type for all registry events. + * Base type for all registry events.
@ -95,6 +98,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> registry entry type + * @param <T> registry entry type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryEvent<T> extends LifecycleEvent { +public interface RegistryEvent<T> extends LifecycleEvent {
+ +
@ -103,7 +107,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java b/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java b/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java
new file mode 100644 new file mode 100644
@ -115,14 +119,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.bootstrap.BootstrapContext;
+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; +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.PrioritizedLifecycleEventHandlerConfiguration;
+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
+import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; +import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Provider for registry events for a specific registry. + * Provider for registry events for a specific registry.
@ -137,6 +139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <B> registry entry builder type + * @param <B> registry entry builder type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryEventProvider<T, B extends RegistryBuilder<T>> { +public interface RegistryEventProvider<T, B extends RegistryBuilder<T>> {
+ +
@ -149,7 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry entry add event type + * @return the registry entry add event type
+ */ + */
+ @NonNull RegistryEntryAddEventType<T, B> entryAdd(); + RegistryEntryAddEventType<T, B> entryAdd();
+ +
+ /** + /**
+ * Gets the event type for {@link RegistryFreezeEvent} which is fired just before + * Gets the event type for {@link RegistryFreezeEvent} which is fired just before
@ -160,14 +163,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry freeze event type + * @return the registry freeze event type
+ */ + */
+ LifecycleEventType.@NonNull Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> freeze(); + LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> freeze();
+ +
+ /** + /**
+ * Gets the registry key associated with this event type provider. + * Gets the registry key associated with this event type provider.
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java b/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java diff --git a/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java b/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java
new file mode 100644 new file mode 100644
@ -182,12 +185,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; +import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record RegistryEventProviderImpl<T, B extends RegistryBuilder<T>>(RegistryKey<T> registryKey) implements RegistryEventProvider<T, B> { +record RegistryEventProviderImpl<T, B extends RegistryBuilder<T>>(RegistryKey<T> registryKey) implements RegistryEventProvider<T, B> {
+ +
+ static <T, B extends RegistryBuilder<T>> RegistryEventProvider<T, B> create(final RegistryKey<T> registryKey) { + static <T, B extends RegistryBuilder<T>> RegistryEventProvider<T, B> create(final RegistryKey<T> registryKey) {
@ -244,12 +246,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.registry.event; +package io.papermc.paper.registry.event;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent} + * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent}
+ * handlers for each applicable registry. + * handlers for each applicable registry.
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public final class RegistryEvents { +public final class RegistryEvents {
+ +
+ private RegistryEvents() { + private RegistryEvents() {
@ -267,8 +271,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.Tag;
+import io.papermc.paper.registry.tag.TagKey; +import io.papermc.paper.registry.tag.TagKey;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Event object for {@link RegistryEventProvider#freeze()}. This + * Event object for {@link RegistryEventProvider#freeze()}. This
@ -279,6 +283,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <B> registry entry builder type + * @param <B> registry entry builder type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryFreezeEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> { +public interface RegistryFreezeEvent<T, B extends RegistryBuilder<T>> extends RegistryEvent<T> {
+ +
@ -287,7 +292,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a writable registry + * @return a writable registry
+ */ + */
+ @NonNull WritableRegistry<T, B> registry(); + WritableRegistry<T, B> registry();
+ +
+ /** + /**
+ * Gets or creates a tag for the given tag key. This tag + * Gets or creates a tag for the given tag key. This tag
@ -298,7 +303,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the tag + * @return the tag
+ * @param <V> the tag value type + * @param <V> the tag value type
+ */ + */
+ @NonNull <V extends Keyed> Tag<V> getOrCreateTag(@NonNull TagKey<V> tagKey); + <V extends Keyed> Tag<V> getOrCreateTag(TagKey<V> tagKey);
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java diff --git a/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java
new file mode 100644 new file mode 100644
@ -311,8 +316,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.TypedKey;
+import java.util.function.Consumer; +import java.util.function.Consumer;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A registry which supports registering new objects. + * A registry which supports registering new objects.
@ -320,8 +325,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> registry entry type + * @param <T> registry entry type
+ * @param <B> registry entry builder type + * @param <B> registry entry builder type
+ */ + */
+@ApiStatus.NonExtendable
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable
+public interface WritableRegistry<T, B extends RegistryBuilder<T>> { +public interface WritableRegistry<T, B extends RegistryBuilder<T>> {
+ +
+ /** + /**
@ -331,7 +337,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param key the entry's key (must be unique from others) + * @param key the entry's key (must be unique from others)
+ * @param value a consumer for the entry's builder + * @param value a consumer for the entry's builder
+ */ + */
+ void register(@NonNull TypedKey<T> key, @NonNull Consumer<? super B> value); + void register(TypedKey<T> key, Consumer<? super B> value);
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java b/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java diff --git a/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java b/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java
new file mode 100644 new file mode 100644
@ -345,14 +351,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; +import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration;
+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.TypedKey;
+import java.util.function.Predicate; +import java.util.function.Predicate;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Specific configuration for {@link io.papermc.paper.registry.event.RegistryEntryAddEvent}s. + * Specific configuration for {@link io.papermc.paper.registry.event.RegistryEntryAddEvent}s.
+ * + *
+ * @param <T> registry entry type + * @param <T> registry entry type
+ */ + */
+@NullMarked
+public interface RegistryEntryAddConfiguration<T> extends PrioritizedLifecycleEventHandlerConfiguration<BootstrapContext> { +public interface RegistryEntryAddConfiguration<T> extends PrioritizedLifecycleEventHandlerConfiguration<BootstrapContext> {
+ +
+ /** + /**
@ -362,7 +369,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return this configuration + * @return this configuration
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ default @NonNull RegistryEntryAddConfiguration<T> filter(final @NonNull TypedKey<T> key) { + default RegistryEntryAddConfiguration<T> filter(final TypedKey<T> key) {
+ return this.filter(key::equals); + return this.filter(key::equals);
+ } + }
+ +
@ -373,13 +380,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return this configuration + * @return this configuration
+ */ + */
+ @Contract(value = "_ -> this", mutates = "this") + @Contract(value = "_ -> this", mutates = "this")
+ @NonNull RegistryEntryAddConfiguration<T> filter(@NonNull Predicate<TypedKey<T>> filter); + RegistryEntryAddConfiguration<T> filter(Predicate<TypedKey<T>> filter);
+ +
+ @Override + @Override
+ @NonNull RegistryEntryAddConfiguration<T> priority(int priority); + RegistryEntryAddConfiguration<T> priority(int priority);
+ +
+ @Override + @Override
+ @NonNull RegistryEntryAddConfiguration<T> monitor(); + RegistryEntryAddConfiguration<T> monitor();
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java b/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java diff --git a/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java b/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java
new file mode 100644 new file mode 100644
@ -394,6 +401,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilder;
+import io.papermc.paper.registry.event.RegistryEntryAddEvent; +import io.papermc.paper.registry.event.RegistryEntryAddEvent;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Lifecycle event type for {@link RegistryEntryAddEvent}s. + * Lifecycle event type for {@link RegistryEntryAddEvent}s.
@ -402,6 +410,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <B> registry entry builder type + * @param <B> registry entry builder type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface RegistryEntryAddEventType<T, B extends RegistryBuilder<T>> extends LifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, RegistryEntryAddConfiguration<T>> { +public interface RegistryEntryAddEventType<T, B extends RegistryBuilder<T>> extends LifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, RegistryEntryAddConfiguration<T>> {
+} +}
@ -418,11 +427,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Iterator; +import java.util.Iterator;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.bukkit.Registry; +import org.bukkit.Registry;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public non-sealed interface RegistryKeySet<T extends Keyed> extends Iterable<TypedKey<T>>, RegistrySet<T> { // TODO remove Keyed +public non-sealed interface RegistryKeySet<T extends Keyed> extends Iterable<TypedKey<T>>, RegistrySet<T> { // TODO remove Keyed
+ +
@ -436,7 +446,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the keys + * @return the keys
+ */ + */
+ @NonNull @Unmodifiable Collection<TypedKey<T>> values(); + @Unmodifiable Collection<TypedKey<T>> values();
+ +
+ /** + /**
+ * Resolve this set into a collection of values. Prefer using + * Resolve this set into a collection of values. Prefer using
@ -446,7 +456,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the resolved values + * @return the resolved values
+ * @see RegistryKeySet#values() + * @see RegistryKeySet#values()
+ */ + */
+ @NonNull @Unmodifiable Collection<T> resolve(final @NonNull Registry<T> registry); + @Unmodifiable Collection<T> resolve(final Registry<T> registry);
+ +
+ /** + /**
+ * Checks if this set contains the value with the given key. + * Checks if this set contains the value with the given key.
@ -454,10 +464,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param valueKey the key to check + * @param valueKey the key to check
+ * @return true if the value is in this set + * @return true if the value is in this set
+ */ + */
+ boolean contains(@NonNull TypedKey<T> valueKey); + boolean contains(TypedKey<T> valueKey);
+ +
+ @Override + @Override
+ default @NonNull Iterator<TypedKey<T>> iterator() { + default Iterator<TypedKey<T>> iterator() {
+ return this.values().iterator(); + return this.values().iterator();
+ } + }
+} +}
@ -480,20 +490,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey; +import org.bukkit.NamespacedKey;
+import org.bukkit.Registry; +import org.bukkit.Registry;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record RegistryKeySetImpl<T extends Keyed>(RegistryKey<T> registryKey, List<TypedKey<T>> values) implements RegistryKeySet<T> { // TODO remove Keyed +record RegistryKeySetImpl<T extends @Nullable Keyed>(RegistryKey<T> registryKey, List<TypedKey<T>> values) implements RegistryKeySet<T> { // TODO remove Keyed
+ +
+ static <T extends Keyed> RegistryKeySet<T> create(final RegistryKey<T> registryKey, final Iterable<? extends T> values) { // TODO remove Keyed + static <T extends Keyed> RegistryKeySet<T> create(final RegistryKey<T> registryKey, final Iterable<? extends T> values) { // TODO remove Keyed
+ final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(registryKey); + final Registry<T> registry = RegistryAccess.registryAccess().getRegistry(registryKey);
+ final ArrayList<TypedKey<T>> keys = new ArrayList<>(); + final ArrayList<TypedKey<T>> keys = new ArrayList<>();
+ for (final T value : values) { + for (final T value : values) {
+ final @Nullable NamespacedKey key = registry.getKey(value); + final NamespacedKey key = registry.getKey(value);
+ Preconditions.checkArgument(key != null, value + " does not have a key in " + registryKey); + Preconditions.checkArgument(key != null, value + " does not have a key in " + registryKey);
+ keys.add(TypedKey.create(registryKey, key)); + keys.add(TypedKey.create(registryKey, key));
+ } + }
@ -513,7 +522,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public Collection<T> resolve(final Registry<T> registry) { + public Collection<T> resolve(final Registry<T> registry) {
+ final List<T> values = new ArrayList<>(this.values.size()); + final List<T> values = new ArrayList<>(this.values.size());
+ for (final TypedKey<T> key : this.values) { + for (final TypedKey<T> key : this.values) {
+ final @Nullable T value = registry.get(key.key()); + final T value = registry.get(key.key());
+ Preconditions.checkState(value != null, "Trying to access unbound TypedKey: " + key); + Preconditions.checkState(value != null, "Trying to access unbound TypedKey: " + key);
+ values.add(value); + values.add(value);
+ } + }
@ -533,9 +542,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.TypedKey;
+import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.Tag;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a collection tied to a registry. + * Represents a collection tied to a registry.
@ -553,6 +562,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> registry value type + * @param <T> registry value type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public sealed interface RegistrySet<T> permits RegistryKeySet, RegistryValueSet { +public sealed interface RegistrySet<T> permits RegistryKeySet, RegistryValueSet {
+ +
+ // TODO uncomment when direct holder sets need to be exposed to the API + // TODO uncomment when direct holder sets need to be exposed to the API
@ -566,7 +576,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // * @param <T> the type of the values + // * @param <T> the type of the values
+ // */ + // */
+ // @Contract(value = "_, _ -> new", pure = true) + // @Contract(value = "_, _ -> new", pure = true)
+ // static <T> @NonNull RegistryValueSet<T> valueSet(final @NonNull RegistryKey<T> registryKey, final @NonNull Iterable<? extends T> values) { + // static <T> RegistryValueSet<T> valueSet(final RegistryKey<T> registryKey, final Iterable<? extends T> values) {
+ // return RegistryValueSetImpl.create(registryKey, values); + // return RegistryValueSetImpl.create(registryKey, values);
+ // } + // }
+ +
@ -584,7 +594,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @throws IllegalArgumentException if the registry isn't available yet or if any value doesn't have a key in that registry + * @throws IllegalArgumentException if the registry isn't available yet or if any value doesn't have a key in that registry
+ */ + */
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static <T extends Keyed> @NonNull RegistryKeySet<T> keySetFromValues(final @NonNull RegistryKey<T> registryKey, final @NonNull Iterable<? extends T> values) { // TODO remove Keyed + static <T extends Keyed> RegistryKeySet<T> keySetFromValues(final RegistryKey<T> registryKey, final Iterable<? extends T> values) { // TODO remove Keyed
+ return RegistryKeySetImpl.create(registryKey, values); + return RegistryKeySetImpl.create(registryKey, values);
+ } + }
+ +
@ -597,7 +607,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of the values + * @param <T> the type of the values
+ */ + */
+ @SafeVarargs + @SafeVarargs
+ static <T extends Keyed> RegistryKeySet<T> keySet(final @NonNull RegistryKey<T> registryKey, final @NonNull TypedKey<T> @NonNull... keys) { // TODO remove Keyed + static <T extends Keyed> RegistryKeySet<T> keySet(final RegistryKey<T> registryKey, final TypedKey<T>... keys) { // TODO remove Keyed
+ return keySet(registryKey, Lists.newArrayList(keys)); + return keySet(registryKey, Lists.newArrayList(keys));
+ } + }
+ +
@ -611,7 +621,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ */ + */
+ @SuppressWarnings("BoundedWildcard") + @SuppressWarnings("BoundedWildcard")
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static <T extends Keyed> @NonNull RegistryKeySet<T> keySet(final @NonNull RegistryKey<T> registryKey, final @NonNull Iterable<TypedKey<T>> keys) { // TODO remove Keyed + static <T extends Keyed> RegistryKeySet<T> keySet(final RegistryKey<T> registryKey, final Iterable<TypedKey<T>> keys) { // TODO remove Keyed
+ return new RegistryKeySetImpl<>(registryKey, Lists.newArrayList(keys)); + return new RegistryKeySetImpl<>(registryKey, Lists.newArrayList(keys));
+ } + }
+ +
@ -620,7 +630,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+ +
+ /** + /**
+ * Get the size of this set. + * Get the size of this set.
@ -648,9 +658,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import java.util.Collection; +import java.util.Collection;
+import java.util.Iterator; +import java.util.Iterator;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A collection of anonymous values relating to a registry. These + * A collection of anonymous values relating to a registry. These
@ -659,6 +669,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> registry value type + * @param <T> registry value type
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public sealed interface RegistryValueSet<T> extends Iterable<T>, RegistrySet<T> permits RegistryValueSetImpl { +public sealed interface RegistryValueSet<T> extends Iterable<T>, RegistrySet<T> permits RegistryValueSetImpl {
+ +
+ @Override + @Override
@ -671,10 +682,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the values + * @return the values
+ */ + */
+ @NonNull @Unmodifiable Collection<T> values(); + @Unmodifiable Collection<T> values();
+ +
+ @Override + @Override
+ default @NonNull Iterator<T> iterator() { + default Iterator<T> iterator() {
+ return this.values().iterator(); + return this.values().iterator();
+ } + }
+} +}
@ -690,8 +701,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import java.util.List; +import java.util.List;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@NullMarked
+record RegistryValueSetImpl<T>(RegistryKey<T> registryKey, List<T> values) implements RegistryValueSet<T> { +record RegistryValueSetImpl<T>(RegistryKey<T> registryKey, List<T> values) implements RegistryValueSet<T> {
+ +
+ RegistryValueSetImpl { + RegistryValueSetImpl {
@ -712,8 +725,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.registry.set.RegistryKeySet; +import io.papermc.paper.registry.set.RegistryKeySet;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A named {@link RegistryKeySet} which are created + * A named {@link RegistryKeySet} which are created
@ -724,6 +737,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see org.bukkit.Registry#getTag(TagKey) + * @see org.bukkit.Registry#getTag(TagKey)
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public interface Tag<T extends Keyed> extends RegistryKeySet<T> { // TODO remove Keyed +public interface Tag<T extends Keyed> extends RegistryKeySet<T> { // TODO remove Keyed
+ +
+ /** + /**
@ -731,7 +745,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the tag key identifier + * @return the tag key identifier
+ */ + */
+ @NonNull TagKey<T> tagKey(); + TagKey<T> tagKey();
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKey.java b/src/main/java/io/papermc/paper/registry/tag/TagKey.java diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKey.java b/src/main/java/io/papermc/paper/registry/tag/TagKey.java
new file mode 100644 new file mode 100644
@ -744,11 +758,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import net.kyori.adventure.key.Keyed; +import net.kyori.adventure.key.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+public sealed interface TagKey<T> extends Keyed permits TagKeyImpl { +public sealed interface TagKey<T> extends Keyed permits TagKeyImpl {
+ +
+ /** + /**
@ -760,7 +775,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the registry value type + * @param <T> the registry value type
+ */ + */
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static <T> @NonNull TagKey<T> create(final @NonNull RegistryKey<T> registryKey, final @NonNull Key key) { + static <T> TagKey<T> create(final RegistryKey<T> registryKey, final Key key) {
+ return new TagKeyImpl<>(registryKey, key); + return new TagKeyImpl<>(registryKey, key);
+ } + }
+ +
@ -769,7 +784,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+} +}
diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java b/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java diff --git a/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java b/src/main/java/io/papermc/paper/registry/tag/TagKeyImpl.java
new file mode 100644 new file mode 100644
@ -781,12 +796,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+@DefaultQualifier(NonNull.class) +@NullMarked
+record TagKeyImpl<T>(RegistryKey<T> registryKey, Key key) implements TagKey<T> { +record TagKeyImpl<T>(RegistryKey<T> registryKey, Key key) implements TagKey<T> {
+ +
+ @Override + @Override

View File

@ -24,11 +24,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionEffectType;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a {@link PotionEffectType} paired with a duration. + * Represents a {@link PotionEffectType} paired with a duration.
+ */ + */
+@NullMarked
+public sealed interface SuspiciousEffectEntry permits SuspiciousEffectEntryImpl { +public sealed interface SuspiciousEffectEntry permits SuspiciousEffectEntryImpl {
+ +
+ /** + /**
@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return effect type + * @return effect type
+ */ + */
+ @NotNull PotionEffectType effect(); + PotionEffectType effect();
+ +
+ /** + /**
+ * Gets the duration for this effect instance. + * Gets the duration for this effect instance.
@ -53,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return new instance of an entry + * @return new instance of an entry
+ */ + */
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static @NotNull SuspiciousEffectEntry create(final @NotNull PotionEffectType effectType, final int duration) { + static SuspiciousEffectEntry create(final PotionEffectType effectType, final int duration) {
+ return new SuspiciousEffectEntryImpl(effectType, duration); + return new SuspiciousEffectEntryImpl(effectType, duration);
+ } + }
+} +}
@ -66,9 +67,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.potion; +package io.papermc.paper.potion;
+ +
+import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionEffectType;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+record SuspiciousEffectEntryImpl(@NotNull PotionEffectType effect, int duration) implements SuspiciousEffectEntry { +@ApiStatus.Internal
+@NullMarked
+record SuspiciousEffectEntryImpl(PotionEffectType effect, int duration) implements SuspiciousEffectEntry {
+} +}
diff --git a/src/main/java/org/bukkit/entity/MushroomCow.java b/src/main/java/org/bukkit/entity/MushroomCow.java diff --git a/src/main/java/org/bukkit/entity/MushroomCow.java b/src/main/java/org/bukkit/entity/MushroomCow.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -45,8 +45,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.tag.PostFlattenTagRegistrar; +import io.papermc.paper.tag.PostFlattenTagRegistrar;
+import io.papermc.paper.tag.PreFlattenTagRegistrar; +import io.papermc.paper.tag.PreFlattenTagRegistrar;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Provides event types for tag registration. + * Provides event types for tag registration.
@ -55,6 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see PostFlattenTagRegistrar + * @see PostFlattenTagRegistrar
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface TagEventTypeProvider { +public interface TagEventTypeProvider {
+ +
@ -66,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value in the tag + * @param <T> the type of value in the tag
+ * @see PreFlattenTagRegistrar + * @see PreFlattenTagRegistrar
+ */ + */
+ <T> LifecycleEventType.@NonNull Prioritizable<BootstrapContext, ReloadableRegistrarEvent<PreFlattenTagRegistrar<T>>> preFlatten(@NonNull RegistryKey<T> registryKey); + <T> LifecycleEventType.Prioritizable<BootstrapContext, ReloadableRegistrarEvent<PreFlattenTagRegistrar<T>>> preFlatten(RegistryKey<T> registryKey);
+ +
+ /** + /**
+ * Get a prioritizable, reloadable registrar event for tags after they are flattened. + * Get a prioritizable, reloadable registrar event for tags after they are flattened.
@ -76,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value in the tag + * @param <T> the type of value in the tag
+ * @see PostFlattenTagRegistrar + * @see PostFlattenTagRegistrar
+ */ + */
+ <T> LifecycleEventType.@NonNull Prioritizable<BootstrapContext, ReloadableRegistrarEvent<PostFlattenTagRegistrar<T>>> postFlatten(@NonNull RegistryKey<T> registryKey); + <T> LifecycleEventType.Prioritizable<BootstrapContext, ReloadableRegistrarEvent<PostFlattenTagRegistrar<T>>> postFlatten(RegistryKey<T> registryKey);
+} +}
diff --git a/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java diff --git a/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java
new file mode 100644 new file mode 100644
@ -92,10 +93,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.tag.TagKey; +import io.papermc.paper.registry.tag.TagKey;
+import java.util.Collection; +import java.util.Collection;
+import java.util.Map; +import java.util.Map;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Registrar for tags after they have been flattened. Flattened + * Registrar for tags after they have been flattened. Flattened
@ -110,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * class YourBootstrapClass implements PluginBootstrap { + * class YourBootstrapClass implements PluginBootstrap {
+ * + *
+ * @Override + * @Override
+ * public void bootstrap(@NotNull BootstrapContext context) { + * public void bootstrap(BootstrapContext context) {
+ * LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager(); + * LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
+ * manager.registerEventHandler(LifecycleEvents.TAGS.postFlatten(RegistryKey.ENCHANTMENT), event -> { + * manager.registerEventHandler(LifecycleEvents.TAGS.postFlatten(RegistryKey.ENCHANTMENT), event -> {
+ * final PostFlattenTagRegistrar<Enchantment> registrar = event.registrar(); + * final PostFlattenTagRegistrar<Enchantment> registrar = event.registrar();
@ -127,6 +128,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see PreFlattenTagRegistrar + * @see PreFlattenTagRegistrar
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface PostFlattenTagRegistrar<T> extends Registrar { +public interface PostFlattenTagRegistrar<T> extends Registrar {
+ +
@ -135,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+ +
+ /** + /**
+ * Get a copy of all tags currently held in this registrar. + * Get a copy of all tags currently held in this registrar.
@ -143,7 +145,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return an immutable map of all tags + * @return an immutable map of all tags
+ */ + */
+ @Contract(value = "-> new", pure = true) + @Contract(value = "-> new", pure = true)
+ @Unmodifiable @NonNull Map<TagKey<T>, Collection<TypedKey<T>>> getAllTags(); + @Unmodifiable Map<TagKey<T>, Collection<TypedKey<T>>> getAllTags();
+ +
+ /** + /**
+ * Checks if this registrar has a tag with the given key. + * Checks if this registrar has a tag with the given key.
@ -152,7 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return true if the tag exists, false otherwise + * @return true if the tag exists, false otherwise
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ boolean hasTag(@NonNull TagKey<T> tagKey); + boolean hasTag(TagKey<T> tagKey);
+ +
+ /** + /**
+ * Get the tag with the given key. Use {@link #hasTag(TagKey)} to check + * Get the tag with the given key. Use {@link #hasTag(TagKey)} to check
@ -164,7 +166,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #hasTag(TagKey) + * @see #hasTag(TagKey)
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ @Unmodifiable @NonNull Collection<TypedKey<T>> getTag(@NonNull TagKey<T> tagKey); + @Unmodifiable Collection<TypedKey<T>> getTag(TagKey<T> tagKey);
+ +
+ /** + /**
+ * Adds values to the given tag. If the tag does not exist, it will be created. + * Adds values to the given tag. If the tag does not exist, it will be created.
@ -174,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #setTag(TagKey, Collection) + * @see #setTag(TagKey, Collection)
+ */ + */
+ @Contract(mutates = "this") + @Contract(mutates = "this")
+ void addToTag(@NonNull TagKey<T> tagKey, @NonNull Collection<TypedKey<T>> values); + void addToTag(TagKey<T> tagKey, Collection<TypedKey<T>> values);
+ +
+ /** + /**
+ * Sets the values of the given tag. If the tag does not exist, it will be created. + * Sets the values of the given tag. If the tag does not exist, it will be created.
@ -185,7 +187,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #addToTag(TagKey, Collection) + * @see #addToTag(TagKey, Collection)
+ */ + */
+ @Contract(mutates = "this") + @Contract(mutates = "this")
+ void setTag(@NonNull TagKey<T> tagKey, @NonNull Collection<TypedKey<T>> values); + void setTag(TagKey<T> tagKey, Collection<TypedKey<T>> values);
+} +}
diff --git a/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java diff --git a/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java
new file mode 100644 new file mode 100644
@ -201,10 +203,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Collection; +import java.util.Collection;
+import java.util.List; +import java.util.List;
+import java.util.Map; +import java.util.Map;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Unmodifiable; +import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Registrar for tags before they are flattened. Flattened + * Registrar for tags before they are flattened. Flattened
@ -218,7 +220,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * class YourBootstrapClass implements PluginBootstrap { + * class YourBootstrapClass implements PluginBootstrap {
+ * + *
+ * @Override + * @Override
+ * public void bootstrap(@NotNull BootstrapContext context) { + * public void bootstrap(BootstrapContext context) {
+ * LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager(); + * LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
+ * manager.registerEventHandler(LifecycleEvents.TAGS.preFlatten(RegistryKey.ITEM), event -> { + * manager.registerEventHandler(LifecycleEvents.TAGS.preFlatten(RegistryKey.ITEM), event -> {
+ * final PreFlattenTagRegistrar<ItemType> registrar = event.registrar(); + * final PreFlattenTagRegistrar<ItemType> registrar = event.registrar();
@ -235,6 +237,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see PostFlattenTagRegistrar + * @see PostFlattenTagRegistrar
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface PreFlattenTagRegistrar<T> extends Registrar { +public interface PreFlattenTagRegistrar<T> extends Registrar {
+ +
@ -243,7 +246,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the registry key + * @return the registry key
+ */ + */
+ @NonNull RegistryKey<T> registryKey(); + RegistryKey<T> registryKey();
+ +
+ /** + /**
+ * Get a copy of all tags currently held in this registrar. + * Get a copy of all tags currently held in this registrar.
@ -251,7 +254,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return an immutable map of all tags + * @return an immutable map of all tags
+ */ + */
+ @Contract(value = "-> new", pure = true) + @Contract(value = "-> new", pure = true)
+ @Unmodifiable @NonNull Map<TagKey<T>, Collection<TagEntry<T>>> getAllTags(); + @Unmodifiable Map<TagKey<T>, Collection<TagEntry<T>>> getAllTags();
+ +
+ /** + /**
+ * Checks if this registrar has a tag with the given key. + * Checks if this registrar has a tag with the given key.
@ -260,7 +263,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return true if the tag exists, false otherwise + * @return true if the tag exists, false otherwise
+ */ + */
+ @Contract(pure = true) + @Contract(pure = true)
+ boolean hasTag(@NonNull TagKey<T> tagKey); + boolean hasTag(TagKey<T> tagKey);
+ +
+ /** + /**
+ * Get the tag with the given key. Use {@link #hasTag(TagKey)} to check + * Get the tag with the given key. Use {@link #hasTag(TagKey)} to check
@ -272,7 +275,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #hasTag(TagKey) + * @see #hasTag(TagKey)
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ @Unmodifiable @NonNull List<TagEntry<T>> getTag(@NonNull TagKey<T> tagKey); + @Unmodifiable List<TagEntry<T>> getTag(TagKey<T> tagKey);
+ +
+ /** + /**
+ * Adds entries to the given tag. If the tag does not exist, it will be created. + * Adds entries to the given tag. If the tag does not exist, it will be created.
@ -282,7 +285,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #setTag(TagKey, Collection) + * @see #setTag(TagKey, Collection)
+ */ + */
+ @Contract(mutates = "this") + @Contract(mutates = "this")
+ void addToTag(@NonNull TagKey<T> tagKey, @NonNull Collection<TagEntry<T>> entries); + void addToTag(TagKey<T> tagKey, Collection<TagEntry<T>> entries);
+ +
+ /** + /**
+ * Sets the entries of the given tag. If the tag does not exist, it will be created. + * Sets the entries of the given tag. If the tag does not exist, it will be created.
@ -293,7 +296,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see #addToTag(TagKey, Collection) + * @see #addToTag(TagKey, Collection)
+ */ + */
+ @Contract(mutates = "this") + @Contract(mutates = "this")
+ void setTag(@NonNull TagKey<T> tagKey, @NonNull Collection<TagEntry<T>> entries); + void setTag(TagKey<T> tagKey, Collection<TagEntry<T>> entries);
+} +}
diff --git a/src/main/java/io/papermc/paper/tag/TagEntry.java b/src/main/java/io/papermc/paper/tag/TagEntry.java diff --git a/src/main/java/io/papermc/paper/tag/TagEntry.java b/src/main/java/io/papermc/paper/tag/TagEntry.java
new file mode 100644 new file mode 100644
@ -306,9 +309,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.TypedKey;
+import io.papermc.paper.registry.tag.TagKey; +import io.papermc.paper.registry.tag.TagKey;
+import net.kyori.adventure.key.Keyed; +import net.kyori.adventure.key.Keyed;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * An entry is a pre-flattened tag. Represents + * An entry is a pre-flattened tag. Represents
@ -318,6 +321,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @see PreFlattenTagRegistrar + * @see PreFlattenTagRegistrar
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+@NullMarked
+@ApiStatus.NonExtendable +@ApiStatus.NonExtendable
+public interface TagEntry<T> extends Keyed { +public interface TagEntry<T> extends Keyed {
+ +
@ -329,7 +333,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value + * @param <T> the type of value
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ static <T> @NonNull TagEntry<T> valueEntry(final @NonNull TypedKey<T> entryKey) { + static <T> TagEntry<T> valueEntry(final TypedKey<T> entryKey) {
+ return valueEntry(entryKey, true); + return valueEntry(entryKey, true);
+ } + }
+ +
@ -342,7 +346,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value + * @param <T> the type of value
+ */ + */
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static <T> @NonNull TagEntry<T> valueEntry(final @NonNull TypedKey<T> entryKey, final boolean isRequired) { + static <T> TagEntry<T> valueEntry(final TypedKey<T> entryKey, final boolean isRequired) {
+ return new TagEntryImpl<>(entryKey.key(), false, isRequired); + return new TagEntryImpl<>(entryKey.key(), false, isRequired);
+ } + }
+ +
@ -354,7 +358,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value + * @param <T> the type of value
+ */ + */
+ @Contract(value = "_ -> new", pure = true) + @Contract(value = "_ -> new", pure = true)
+ static <T> @NonNull TagEntry<T> tagEntry(final @NonNull TagKey<T> tagKey) { + static <T> TagEntry<T> tagEntry(final TagKey<T> tagKey) {
+ return tagEntry(tagKey, true); + return tagEntry(tagKey, true);
+ } + }
+ +
@ -367,7 +371,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param <T> the type of value + * @param <T> the type of value
+ */ + */
+ @Contract(value = "_, _ -> new", pure = true) + @Contract(value = "_, _ -> new", pure = true)
+ static <T> @NonNull TagEntry<T> tagEntry(final @NonNull TagKey<T> tagKey, final boolean isRequired) { + static <T> TagEntry<T> tagEntry(final TagKey<T> tagKey, final boolean isRequired) {
+ return new TagEntryImpl<>(tagKey.key(), true, isRequired); + return new TagEntryImpl<>(tagKey.key(), true, isRequired);
+ } + }
+ +
@ -400,7 +404,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Key;
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+ +
+@NullMarked
+@ApiStatus.Internal +@ApiStatus.Internal
+record TagEntryImpl<T>(Key key, boolean isTag, boolean isRequired) implements TagEntry<T> { +record TagEntryImpl<T>(Key key, boolean isTag, boolean isRequired) implements TagEntry<T> {
+} +}

View File

@ -26,11 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.ComponentLike; +import net.kyori.adventure.text.ComponentLike;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A scoreboard number format that replaces the score number with a chat component. + * A scoreboard number format that replaces the score number with a chat component.
+ */ + */
+@NullMarked
+public interface FixedFormat extends NumberFormat, ComponentLike { +public interface FixedFormat extends NumberFormat, ComponentLike {
+ +
+ /** + /**
@ -38,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the chat component + * @return the chat component
+ */ + */
+ @NotNull Component component(); + Component component();
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java
@ -50,12 +51,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.scoreboard.numbers; +package io.papermc.paper.scoreboard.numbers;
+ +
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+record FixedFormatImpl(@NotNull Component component) implements FixedFormat { +@NullMarked
+record FixedFormatImpl(Component component) implements FixedFormat {
+ +
+ @Override + @Override
+ public @NotNull Component asComponent() { + public Component asComponent() {
+ return this.component(); + return this.component();
+ } + }
+} +}
@ -70,11 +72,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.kyori.adventure.text.ComponentLike; +import net.kyori.adventure.text.ComponentLike;
+import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.StyleBuilderApplicable; +import net.kyori.adventure.text.format.StyleBuilderApplicable;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Describes a scoreboard number format that applies custom formatting to scoreboard scores. + * Describes a scoreboard number format that applies custom formatting to scoreboard scores.
+ */ + */
+@NullMarked
+public interface NumberFormat { +public interface NumberFormat {
+ +
+ /** + /**
@ -82,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return a blank number format + * @return a blank number format
+ */ + */
+ static @NotNull NumberFormat blank() { + static NumberFormat blank() {
+ return BlankFormatImpl.INSTANCE; + return BlankFormatImpl.INSTANCE;
+ } + }
+ +
@ -91,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return an un-styled number format + * @return an un-styled number format
+ */ + */
+ static @NotNull StyledFormat noStyle() { + static StyledFormat noStyle() {
+ return StyledFormatImpl.NO_STYLE; + return StyledFormatImpl.NO_STYLE;
+ } + }
+ +
@ -101,7 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param style the style to apply on the number + * @param style the style to apply on the number
+ * @return a styled number format + * @return a styled number format
+ */ + */
+ static @NotNull StyledFormat styled(final @NotNull Style style) { + static StyledFormat styled(final Style style) {
+ return new StyledFormatImpl(style); + return new StyledFormatImpl(style);
+ } + }
+ +
@ -111,7 +114,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param styleBuilderApplicables the style to apply on the number + * @param styleBuilderApplicables the style to apply on the number
+ * @return a styled number format + * @return a styled number format
+ */ + */
+ static @NotNull StyledFormat styled(final @NotNull StyleBuilderApplicable @NotNull... styleBuilderApplicables) { + static StyledFormat styled(final StyleBuilderApplicable... styleBuilderApplicables) {
+ return styled(Style.style(styleBuilderApplicables)); + return styled(Style.style(styleBuilderApplicables));
+ } + }
+ +
@ -121,7 +124,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @param component the component to replace the number with + * @param component the component to replace the number with
+ * @return a fixed number format + * @return a fixed number format
+ */ + */
+ static @NotNull FixedFormat fixed(final @NotNull ComponentLike component) { + static FixedFormat fixed(final ComponentLike component) {
+ return new FixedFormatImpl(component.asComponent()); + return new FixedFormatImpl(component.asComponent());
+ } + }
+} +}
@ -135,11 +138,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.StyleBuilderApplicable; +import net.kyori.adventure.text.format.StyleBuilderApplicable;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * A scoreboard number format that applies a custom formatting to the score number. + * A scoreboard number format that applies a custom formatting to the score number.
+ */ + */
+@NullMarked
+public interface StyledFormat extends NumberFormat, StyleBuilderApplicable { +public interface StyledFormat extends NumberFormat, StyleBuilderApplicable {
+ +
+ /** + /**
@ -147,7 +151,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the style to apply + * @return the style to apply
+ */ + */
+ @NotNull Style style(); + Style style();
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java
@ -159,13 +163,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.scoreboard.numbers; +package io.papermc.paper.scoreboard.numbers;
+ +
+import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.Style;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+record StyledFormatImpl(@NotNull Style style) implements StyledFormat { +@NullMarked
+record StyledFormatImpl(Style style) implements StyledFormat {
+ static final StyledFormat NO_STYLE = new StyledFormatImpl(Style.empty()); + static final StyledFormat NO_STYLE = new StyledFormatImpl(Style.empty());
+ +
+ @Override + @Override
+ public void styleApply(final Style.@NotNull Builder style) { + public void styleApply(final Style.Builder style) {
+ style.merge(this.style); + style.merge(this.style);
+ } + }
+} +}

View File

@ -16,11 +16,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.block.TileState; +import org.bukkit.block.TileState;
+import org.bukkit.inventory.BlockInventoryHolder; +import org.bukkit.inventory.BlockInventoryHolder;
+import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.Inventory;
+import org.checkerframework.checker.nullness.qual.NonNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a {@link TileState} block that has an inventory. + * Represents a {@link TileState} block that has an inventory.
+ */ + */
+@NullMarked
+public interface TileStateInventoryHolder extends TileState, BlockInventoryHolder { +public interface TileStateInventoryHolder extends TileState, BlockInventoryHolder {
+ +
+ /** + /**
@ -35,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * @return the inventory + * @return the inventory
+ */ + */
+ @Override + @Override
+ @NonNull Inventory getInventory(); + Inventory getInventory();
+ +
+ /** + /**
+ * Gets the captured inventory snapshot of this container. + * Gets the captured inventory snapshot of this container.
@ -47,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the captured inventory snapshot + * @return the captured inventory snapshot
+ */ + */
+ @NonNull Inventory getSnapshotInventory(); + Inventory getSnapshotInventory();
+} +}
diff --git a/src/main/java/org/bukkit/block/ChiseledBookshelf.java b/src/main/java/org/bukkit/block/ChiseledBookshelf.java diff --git a/src/main/java/org/bukkit/block/ChiseledBookshelf.java b/src/main/java/org/bukkit/block/ChiseledBookshelf.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -15,12 +15,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import org.bukkit.BanList; +import org.bukkit.BanList;
+import org.bukkit.ban.IpBanList; +import org.bukkit.ban.IpBanList;
+import org.bukkit.ban.ProfileBanList; +import org.bukkit.ban.ProfileBanList;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+/** +/**
+ * Represents a ban-type that a {@link BanList} may track. + * Represents a ban-type that a {@link BanList} may track.
+ * It enforces the correct return value at compile time. + * It enforces the correct return value at compile time.
+ */ + */
+@NullMarked
+public interface BanListType<T> { +public interface BanListType<T> {
+ +
+ /** + /**
@ -37,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ * + *
+ * @return the type class + * @return the type class
+ */ + */
+ @NotNull Class<T> typeClass(); + Class<T> typeClass();
+} +}
diff --git a/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java diff --git a/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java
new file mode 100644 new file mode 100644
@ -48,10 +49,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package io.papermc.paper.ban; +package io.papermc.paper.ban;
+ +
+import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+ +
+@ApiStatus.Internal +@ApiStatus.Internal
+record BanListTypeImpl<T>(@NotNull Class<T> typeClass) implements BanListType<T> { +@NullMarked
+record BanListTypeImpl<T>(Class<T> typeClass) implements BanListType<T> {
+} +}
diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -1053,13 +1053,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import java.util.concurrent.CompletableFuture;
+import net.kyori.adventure.chat.SignedMessage; +import net.kyori.adventure.chat.SignedMessage;
+import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.arguments.MessageArgument; +import net.minecraft.commands.arguments.MessageArgument;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+
+import java.util.concurrent.CompletableFuture;
+ +
+@NullMarked
+public record SignedMessageResolverImpl(MessageArgument.Message message) implements SignedMessageResolver { +public record SignedMessageResolverImpl(MessageArgument.Message message) implements SignedMessageResolver {
+ +
+ @Override + @Override
@ -1067,13 +1067,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return this.message.text(); + return this.message.text();
+ } + }
+ +
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Override + @Override
+ public @NotNull CompletableFuture<SignedMessage> resolveSignedMessage(final String argumentName, final CommandContext erased) throws CommandSyntaxException { + public CompletableFuture<SignedMessage> resolveSignedMessage(final String argumentName, final CommandContext erased) throws CommandSyntaxException {
+ final CommandContext<CommandSourceStack> type = erased;
+ final CompletableFuture<SignedMessage> future = new CompletableFuture<>(); + final CompletableFuture<SignedMessage> future = new CompletableFuture<>();
+ +
+ final MessageArgument.Message response = type.getArgument(argumentName, SignedMessageResolverImpl.class).message; + final MessageArgument.Message response = ((CommandContext<CommandSourceStack>) erased).getArgument(argumentName, SignedMessageResolverImpl.class).message;
+ MessageArgument.resolveChatMessage(response, type, argumentName, (message) -> { + MessageArgument.resolveChatMessage(response, erased, argumentName, (message) -> {
+ future.complete(message.adventureView()); + future.complete(message.adventureView());
+ }); + });
+ return future; + return future;

View File

@ -16,31 +16,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import io.papermc.paper.command.CommandBlockHolder; +import io.papermc.paper.command.CommandBlockHolder;
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import net.minecraft.world.level.BaseCommandBlock; +import net.minecraft.world.level.BaseCommandBlock;
+import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked;
+import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable;
+ +
+@NullMarked
+public interface PaperCommandBlockHolder extends CommandBlockHolder { +public interface PaperCommandBlockHolder extends CommandBlockHolder {
+ +
+ BaseCommandBlock getCommandBlockHandle(); + BaseCommandBlock getCommandBlockHandle();
+ +
+ @Override + @Override
+ default @NotNull Component lastOutput() { + default Component lastOutput() {
+ return PaperAdventure.asAdventure(getCommandBlockHandle().getLastOutput()); + return PaperAdventure.asAdventure(this.getCommandBlockHandle().getLastOutput());
+ } + }
+ +
+ @Override + @Override
+ default void lastOutput(@Nullable Component lastOutput) { + default void lastOutput(final @Nullable Component lastOutput) {
+ getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput)); + this.getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput));
+ } + }
+ +
+ @Override + @Override
+ default int getSuccessCount() { + default int getSuccessCount() {
+ return getCommandBlockHandle().getSuccessCount(); + return this.getCommandBlockHandle().getSuccessCount();
+ } + }
+ +
+ @Override + @Override
+ default void setSuccessCount(int successCount) { + default void setSuccessCount(final int successCount) {
+ getCommandBlockHandle().setSuccessCount(successCount); + this.getCommandBlockHandle().setSuccessCount(successCount);
+ } + }
+} +}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java

View File

@ -98,12 +98,12 @@ public final class Registration {
commands.register(plugin.getPluginMeta(), "example", "test", Collections.emptyList(), new BasicCommand() { commands.register(plugin.getPluginMeta(), "example", "test", Collections.emptyList(), new BasicCommand() {
@Override @Override
public void execute(@NotNull final CommandSourceStack commandSourceStack, final @NotNull String[] args) { public void execute(@NotNull final CommandSourceStack commandSourceStack, final @NotNull String @NotNull [] args) {
System.out.println(Arrays.toString(args)); System.out.println(Arrays.toString(args));
} }
@Override @Override
public @NotNull Collection<String> suggest(final @NotNull CommandSourceStack commandSourceStack, final @NotNull String[] args) { public @NotNull Collection<String> suggest(final @NotNull CommandSourceStack commandSourceStack, final @NotNull String @NotNull [] args) {
System.out.println(Arrays.toString(args)); System.out.println(Arrays.toString(args));
return List.of("apple", "banana"); return List.of("apple", "banana");
} }