summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2024-09-29 16:48:34 -0700
committerJake Potrebic <[email protected]>2024-09-29 19:13:41 -0700
commitba3c29b92ec29c8c321f7e6160a4a25f65f18088 (patch)
tree822022fb0a406a3c23533578de55ab8bcf5bd3e5
parentea00be3aaa1a5727151db9cd82d876613c99e727 (diff)
downloadPaper-ba3c29b92ec29c8c321f7e6160a4a25f65f18088.tar.gz
Paper-ba3c29b92ec29c8c321f7e6160a4a25f65f18088.zip
Finish converting all events to jspecify annotations
-rw-r--r--patches/api/0002-Build-system-changes.patch7
-rw-r--r--patches/api/0003-Test-changes.patch4
-rw-r--r--patches/api/0004-Code-Generation.patch4
-rw-r--r--patches/api/0006-Adventure.patch91
-rw-r--r--patches/api/0007-Paper-Utils.patch17
-rw-r--r--patches/api/0008-Use-ASM-for-event-executors.patch150
-rw-r--r--patches/api/0009-Paper-Plugins.patch4
-rw-r--r--patches/api/0015-Expose-server-build-information.patch16
-rw-r--r--patches/api/0021-Add-exception-reporting-event.patch16
-rw-r--r--patches/api/0031-Entity-AddTo-RemoveFrom-World-Events.patch10
-rw-r--r--patches/api/0032-EntityPathfindEvent.patch5
-rw-r--r--patches/api/0035-Add-PlayerUseUnknownEntityEvent.patch17
-rw-r--r--patches/api/0039-LootTable-API.patch80
-rw-r--r--patches/api/0049-PlayerTeleportEndGatewayEvent.patch10
-rw-r--r--patches/api/0057-Basic-PlayerProfile-API.patch4
-rw-r--r--patches/api/0066-ProfileWhitelistVerifyEvent.patch35
-rw-r--r--patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch4
-rw-r--r--patches/api/0069-Add-PlayerJumpEvent.patch23
-rw-r--r--patches/api/0070-Add-workaround-for-plugins-modifying-the-parent-of-t.patch26
-rw-r--r--patches/api/0071-Add-PlayerArmorChangeEvent.patch35
-rw-r--r--patches/api/0073-AsyncTabCompleteEvent.patch7
-rw-r--r--patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch14
-rw-r--r--patches/api/0076-PlayerPickupExperienceEvent.patch16
-rw-r--r--patches/api/0082-Add-PlayerAdvancementCriterionGrantEvent.patch22
-rw-r--r--patches/api/0083-Fill-Profile-Property-Events.patch43
-rw-r--r--patches/api/0091-Add-legacy-ping-support-to-PaperServerListPingEvent.patch4
-rw-r--r--patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch283
-rw-r--r--patches/api/0099-EndermanAttackPlayerEvent.patch5
-rw-r--r--patches/api/0100-WitchConsumePotionEvent.patch5
-rw-r--r--patches/api/0110-PlayerReadyArrowEvent.patch22
-rw-r--r--patches/api/0115-RangedEntity-API.patch11
-rw-r--r--patches/api/0120-EnderDragon-Events.patch5
-rw-r--r--patches/api/0121-PlayerElytraBoostEvent.patch23
-rw-r--r--patches/api/0122-PlayerLaunchProjectileEvent.patch21
-rw-r--r--patches/api/0127-AnvilDamageEvent.patch5
-rw-r--r--patches/api/0133-Slime-Pathfinder-Events.patch6
-rw-r--r--patches/api/0135-Add-More-Creeper-API.patch6
-rw-r--r--patches/api/0143-Mob-Pathfinding-API.patch73
-rw-r--r--patches/api/0151-Turtle-API.patch18
-rw-r--r--patches/api/0152-Add-spectator-target-events.patch35
-rw-r--r--patches/api/0164-Add-PlayerPostRespawnEvent.patch14
-rw-r--r--patches/api/0167-Server-Tick-Events.patch10
-rw-r--r--patches/api/0178-Entity-Jump-API.patch6
-rw-r--r--patches/api/0183-Add-Player-Client-Options-API.patch39
-rw-r--r--patches/api/0184-Add-PlayerAttackEntityCooldownResetEvent.patch16
-rw-r--r--patches/api/0187-Add-Mob-Goal-API.patch100
-rw-r--r--patches/api/0188-Add-villager-reputation-API.patch15
-rw-r--r--patches/api/0192-Add-and-implement-PlayerRecipeBookClickEvent.patch20
-rw-r--r--patches/api/0196-Add-PrepareResultEvent-PrepareGrindstoneEvent.patch6
-rw-r--r--patches/api/0216-Add-PlayerItemCooldownEvent.patch17
-rw-r--r--patches/api/0219-Player-Chunk-Load-Unload-Events.patch24
-rw-r--r--patches/api/0222-Added-PlayerTradeEvent.patch33
-rw-r--r--patches/api/0226-Add-PlayerFlowerPotManipulateEvent.patch17
-rw-r--r--patches/api/0229-Added-WorldGameRuleChangeEvent.patch24
-rw-r--r--patches/api/0231-Add-BlockFailedDispenseEvent.patch5
-rw-r--r--patches/api/0232-Added-PlayerLecternPageChangeEvent.patch18
-rw-r--r--patches/api/0233-Added-PlayerLoomPatternSelectEvent.patch17
-rw-r--r--patches/api/0237-Add-StructuresLocateEvent.patch35
-rw-r--r--patches/api/0238-Add-BlockPreDispenseEvent.patch5
-rw-r--r--patches/api/0239-Added-PlayerChangeBeaconEffectEvent.patch31
-rw-r--r--patches/api/0240-Added-PlayerStonecutterRecipeSelectEvent.patch17
-rw-r--r--patches/api/0249-Add-worldborder-events.patch54
-rw-r--r--patches/api/0250-added-PlayerNameEntityEvent.patch27
-rw-r--r--patches/api/0259-Added-PlayerDeepSleepEvent.patch13
-rw-r--r--patches/api/0261-Added-PlayerBedFailEnterEvent.patch26
-rw-r--r--patches/api/0283-Add-ElderGuardianAppearanceEvent.patch5
-rw-r--r--patches/api/0288-Adds-PlayerArmSwingEvent.patch8
-rw-r--r--patches/api/0289-Add-PlayerSignCommandPreprocessEvent.patch14
-rw-r--r--patches/api/0293-Add-PlayerSetSpawnEvent.patch35
-rw-r--r--patches/api/0313-Add-PlayerItemFrameChangeEvent.patch21
-rw-r--r--patches/api/0347-Add-PlayerStopUsingItemEvent.patch14
-rw-r--r--patches/api/0363-Add-PlayerInventorySlotChangeEvent.patch15
-rw-r--r--patches/api/0370-Add-PrePlayerAttackEntityEvent.patch15
-rw-r--r--patches/api/0373-Add-paper-dumplisteners-command.patch34
-rw-r--r--patches/api/0377-Player-Entity-Tracking-Events.patch26
-rw-r--r--patches/api/0396-Add-event-for-player-editing-sign.patch17
-rw-r--r--patches/api/0401-Add-PlayerFailMoveEvent.patch19
-rw-r--r--patches/api/0412-Add-PlayerPickItemEvent.patch23
-rw-r--r--patches/api/0435-Add-PlayerShieldDisableEvent.patch14
-rw-r--r--patches/api/0455-Add-CartographyItemEvent.patch19
-rw-r--r--patches/api/0466-Brigadier-based-command-API.patch24
-rw-r--r--patches/server/0353-Implement-Mob-Goal-API.patch6
82 files changed, 977 insertions, 1103 deletions
diff --git a/patches/api/0002-Build-system-changes.patch b/patches/api/0002-Build-system-changes.patch
index 768ba2bc98..60f39fcfce 100644
--- a/patches/api/0002-Build-system-changes.patch
+++ b/patches/api/0002-Build-system-changes.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Build system changes
diff --git a/build.gradle.kts b/build.gradle.kts
-index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..2e99ea99cfc96b3602ba26b20a402e7d30f0f05f 100644
+index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..78aadebda145fe83327ceb430c4b38f9a8e45a2b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -18,15 +18,27 @@ dependencies {
@@ -37,7 +37,7 @@ index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..2e99ea99cfc96b3602ba26b20a402e7d
testImplementation("org.apache.commons:commons-lang3:3.12.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.hamcrest:hamcrest:2.2")
-@@ -69,8 +81,12 @@ tasks.withType<Javadoc> {
+@@ -69,8 +81,13 @@ tasks.withType<Javadoc> {
options.links(
"https://guava.dev/releases/32.1.2-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
@@ -47,11 +47,12 @@ index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..2e99ea99cfc96b3602ba26b20a402e7d
+ // Paper start - add missing javadoc links
+ "https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
+ "https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
++ "https://jspecify.dev/docs/api/",
+ // Paper end
)
options.tags("apiNote:a:API Note:")
-@@ -89,3 +105,14 @@ tasks.withType<Javadoc> {
+@@ -89,3 +106,14 @@ tasks.withType<Javadoc> {
tasks.test {
useJUnitPlatform()
}
diff --git a/patches/api/0003-Test-changes.patch b/patches/api/0003-Test-changes.patch
index 1d9364efc5..f712825f8b 100644
--- a/patches/api/0003-Test-changes.patch
+++ b/patches/api/0003-Test-changes.patch
@@ -12,10 +12,10 @@ Co-authored-by: Riley Park <[email protected]>
Co-authored-by: Jake Potrebic <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index 2e99ea99cfc96b3602ba26b20a402e7d30f0f05f..d91ce069b5fce4afb245691bd90f448d6dfdc492 100644
+index 78aadebda145fe83327ceb430c4b38f9a8e45a2b..8c7a5be5193ae397ec324d78566edce90608ed57 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -106,6 +106,12 @@ tasks.test {
+@@ -107,6 +107,12 @@ tasks.test {
useJUnitPlatform()
}
diff --git a/patches/api/0004-Code-Generation.patch b/patches/api/0004-Code-Generation.patch
index 6bad58426f..c19456fe12 100644
--- a/patches/api/0004-Code-Generation.patch
+++ b/patches/api/0004-Code-Generation.patch
@@ -7,7 +7,7 @@ Currently includes generated key holder classes for types
used in the Registry Modification API
diff --git a/build.gradle.kts b/build.gradle.kts
-index d91ce069b5fce4afb245691bd90f448d6dfdc492..f715ae19c1e71d854a722130d3db447887fa2d2b 100644
+index 8c7a5be5193ae397ec324d78566edce90608ed57..877ea06c0ea8c8c0c73d23fbb996f6692c100d98 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,6 +1,7 @@
@@ -41,7 +41,7 @@ index d91ce069b5fce4afb245691bd90f448d6dfdc492..f715ae19c1e71d854a722130d3db4478
configure<PublishingExtension> {
publications.create<MavenPublication>("maven") {
from(components["java"])
-@@ -122,3 +139,14 @@ tasks.check {
+@@ -123,3 +140,14 @@ tasks.check {
dependsOn(scanJar)
}
// Paper end
diff --git a/patches/api/0006-Adventure.patch b/patches/api/0006-Adventure.patch
index efad521b02..a26f91f269 100644
--- a/patches/api/0006-Adventure.patch
+++ b/patches/api/0006-Adventure.patch
@@ -8,7 +8,7 @@ Co-authored-by: Jake Potrebic <[email protected]>
Co-authored-by: Yannick Lamprecht <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index 7470f18dc36c5e4357ce3bb936c4842066df9114..7624069435a9be6c4249a444db0bf1bf54691caa 100644
+index 3383fb91249ea53740326b538abd905f84ff0e3c..74f0e2b812c1e2e922b136fefe505fc8cbe33e83 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,12 +11,28 @@ java {
@@ -55,7 +55,7 @@ index 7470f18dc36c5e4357ce3bb936c4842066df9114..7624069435a9be6c4249a444db0bf1bf
// Paper end
compileOnly("org.apache.maven:maven-resolver-provider:3.9.6")
-@@ -100,14 +123,31 @@ tasks.withType<Javadoc> {
+@@ -100,15 +123,32 @@ tasks.withType<Javadoc> {
"https://guava.dev/releases/32.1.2-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
"https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/", // Paper - we don't want Java 5 annotations
@@ -64,6 +64,7 @@ index 7470f18dc36c5e4357ce3bb936c4842066df9114..7624069435a9be6c4249a444db0bf1bf
// Paper start - add missing javadoc links
"https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
+ "https://jspecify.dev/docs/api/",
// Paper end
+ // Paper start
+ "https://jd.advntr.dev/api/$adventureVersion/",
@@ -208,13 +209,14 @@ index 0000000000000000000000000000000000000000..2ad76b1751ba707f7ae0d283aa1cbaf6
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java b/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803a7017a28
+index 0000000000000000000000000000000000000000..9a95d203151d2c91b0eec494e3674f0facfaa305
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java
-@@ -0,0 +1,127 @@
+@@ -0,0 +1,122 @@
+package io.papermc.paper.event.player;
+
+import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
@@ -222,9 +224,7 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Set;
++import org.jspecify.annotations.NullMarked;
+
+import static java.util.Objects.requireNonNull;
+
@@ -232,6 +232,7 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ * An abstract implementation of a chat event, handling shared logic.
+ */
++@NullMarked
+public abstract class AbstractChatEvent extends PlayerEvent implements Cancellable {
+
+ private final Set<Audience> viewers;
@@ -242,7 +243,7 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+
+ private boolean cancelled;
+
-+ AbstractChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++ AbstractChatEvent(final boolean async, final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
+ super(player, async);
+ this.viewers = viewers;
+ this.renderer = renderer;
@@ -259,7 +260,6 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ *
+ * @return a mutable set of {@link Audience audiences} who will receive the chat message
+ */
-+ @NotNull
+ public final Set<Audience> viewers() {
+ return this.viewers;
+ }
@@ -270,7 +270,7 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ * @param renderer the chat renderer
+ * @throws NullPointerException if {@code renderer} is {@code null}
+ */
-+ public final void renderer(final @NotNull ChatRenderer renderer) {
++ public final void renderer(final ChatRenderer renderer) {
+ this.renderer = requireNonNull(renderer, "renderer");
+ }
+
@@ -279,7 +279,6 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ *
+ * @return the chat renderer
+ */
-+ @NotNull
+ public final ChatRenderer renderer() {
+ return this.renderer;
+ }
@@ -290,7 +289,6 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ *
+ * @return the user-supplied message
+ */
-+ @NotNull
+ public final Component message() {
+ return this.message;
+ }
@@ -301,7 +299,7 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ * @param message the user-supplied message
+ * @throws NullPointerException if {@code message} is {@code null}
+ */
-+ public final void message(final @NotNull Component message) {
++ public final void message(final Component message) {
+ this.message = requireNonNull(message, "message");
+ }
+
@@ -312,7 +310,6 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ *
+ * @return the original user-supplied message
+ */
-+ @NotNull
+ public final Component originalMessage() {
+ return this.originalMessage;
+ }
@@ -324,7 +321,6 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+ *
+ * @return the signed message
+ */
-+ @NotNull
+ public final SignedMessage signedMessage() {
+ return this.signedMessage;
+ }
@@ -341,41 +337,42 @@ index 0000000000000000000000000000000000000000..a0fd845bc9b2540c398fe1dbbf821803
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..01cf89d3558132912c4d0eb48c98cd8c06e46a67
+index 0000000000000000000000000000000000000000..ddd4c90f83b5cb8f069ff53760abb3c4adfd1168
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java
-@@ -0,0 +1,28 @@
+@@ -0,0 +1,29 @@
+package io.papermc.paper.event.player;
+
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
++@NullMarked
+public class AsyncChatCommandDecorateEvent extends AsyncChatDecorateEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
-+ public AsyncChatCommandDecorateEvent(@Nullable Player player, @NotNull Component originalMessage) {
++ public AsyncChatCommandDecorateEvent(final @Nullable Player player, final Component originalMessage) {
+ super(player, originalMessage);
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ public static @NotNull HandlerList getHandlerList() {
++ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb562be2f06
+index 0000000000000000000000000000000000000000..9e5ea0cd006bd9744b84923620841f07fa40c2cb
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java
@@ -0,0 +1,105 @@
@@ -387,9 +384,8 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.Contract;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * This event is fired when the server decorates a component for chat purposes. This is called
@@ -401,18 +397,19 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+ * See {@link AsyncChatCommandDecorateEvent} for the decoration of messages sent via commands
+ */
++@NullMarked
+public class AsyncChatDecorateEvent extends ServerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ private final Player player;
++ private final @Nullable Player player;
+ private final Component originalMessage;
+ private Component result;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public AsyncChatDecorateEvent(final @Nullable Player player, final @NotNull Component originalMessage) {
++ public AsyncChatDecorateEvent(final @Nullable Player player, final Component originalMessage) {
+ super(true);
+ this.player = player;
+ this.originalMessage = originalMessage;
@@ -436,7 +433,7 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+ *
+ * @return the input
+ */
-+ public @NotNull Component originalMessage() {
++ public Component originalMessage() {
+ return this.originalMessage;
+ }
+
@@ -447,7 +444,7 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+ *
+ * @return the result
+ */
-+ public @NotNull Component result() {
++ public Component result() {
+ return this.result;
+ }
+
@@ -456,7 +453,7 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+ *
+ * @param result the result
+ */
-+ public void result(@NotNull Component result) {
++ public void result(final Component result) {
+ this.result = result;
+ }
+
@@ -471,36 +468,36 @@ index 0000000000000000000000000000000000000000..2e492f4cd179135bd40ad951ab23acb5
+ * component.
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ public static @NotNull HandlerList getHandlerList() {
++ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..4adae8b8a8640ffbd6a86b0908ca21fded737b88
+index 0000000000000000000000000000000000000000..50c3e117dec63811823b4e6395bf4f090692ee8c
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java
-@@ -0,0 +1,45 @@
+@@ -0,0 +1,44 @@
+package io.papermc.paper.event.player;
+
-+import java.util.Set;
+import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * An event fired when a {@link Player} sends a chat message to the server.
@@ -515,36 +512,35 @@ index 0000000000000000000000000000000000000000..4adae8b8a8640ffbd6a86b0908ca21fd
+ * Care should be taken to check {@link #isAsynchronous()} and treat the event
+ * appropriately.
+ */
++@NullMarked
+public final class AsyncChatEvent extends AbstractChatEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
-+ public AsyncChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++ public AsyncChatEvent(final boolean async, final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
+ super(async, player, viewers, renderer, message, originalMessage, signedMessage);
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/ChatEvent.java b/src/main/java/io/papermc/paper/event/player/ChatEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..7411f58f9f36beaadcc47c2264a4af313956ee03
+index 0000000000000000000000000000000000000000..42a82ce2316a4aad2883d24c7e2ff95d95f5881a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/ChatEvent.java
-@@ -0,0 +1,41 @@
+@@ -0,0 +1,40 @@
+package io.papermc.paper.event.player;
+
-+import java.util.Set;
+import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
@@ -552,7 +548,7 @@ index 0000000000000000000000000000000000000000..7411f58f9f36beaadcc47c2264a4af31
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * An event fired when a {@link Player} sends a chat message to the server.
@@ -562,22 +558,21 @@ index 0000000000000000000000000000000000000000..7411f58f9f36beaadcc47c2264a4af31
+ */
+@Deprecated
+@Warning(reason = "Listening to this event forces chat to wait for the main thread, delaying chat messages.")
++@NullMarked
+public final class ChatEvent extends AbstractChatEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
-+ public ChatEvent(final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++ public ChatEvent(final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
+ super(false, player, viewers, renderer, message, originalMessage, signedMessage);
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0007-Paper-Utils.patch b/patches/api/0007-Paper-Utils.patch
index a647b698ad..38f5ac80ad 100644
--- a/patches/api/0007-Paper-Utils.patch
+++ b/patches/api/0007-Paper-Utils.patch
@@ -6,22 +6,25 @@ Subject: [PATCH] Paper Utils
diff --git a/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java b/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9db0056ab94145819628b3ad8d8d26130d117fcf
+index 0000000000000000000000000000000000000000..fbcd82b513b4cb9839f9d2b38d9c6c73148e30a6
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/SneakyThrow.java
-@@ -0,0 +1,16 @@
+@@ -0,0 +1,19 @@
+package com.destroystokyo.paper.util;
+
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
-+public class SneakyThrow {
++@NullMarked
++public final class SneakyThrow {
+
-+ public static void sneaky(@NotNull Throwable exception) {
-+ SneakyThrow.<RuntimeException>throwSneaky(exception);
++ public static void sneaky(final Throwable exception) {
++ SneakyThrow.throwSneaky(exception);
+ }
+
+ @SuppressWarnings("unchecked")
-+ private static <T extends Throwable> void throwSneaky(@NotNull Throwable exception) throws T {
++ private static <T extends Throwable> void throwSneaky(final Throwable exception) throws T {
+ throw (T) exception;
+ }
+
diff --git a/patches/api/0008-Use-ASM-for-event-executors.patch b/patches/api/0008-Use-ASM-for-event-executors.patch
index d06ca16763..964f911f67 100644
--- a/patches/api/0008-Use-ASM-for-event-executors.patch
+++ b/patches/api/0008-Use-ASM-for-event-executors.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Use ASM for event executors.
Uses method handles for private or static methods.
diff --git a/build.gradle.kts b/build.gradle.kts
-index af3514113abdf3f42c41f1e7ff0f930cc1a417f5..ed0b67ac322aa22b191cd35502ae5b4f20af19f8 100644
+index 74f0e2b812c1e2e922b136fefe505fc8cbe33e83..1f627e81622e77b81b1228a467fbb9e6fd979e7a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -47,6 +47,9 @@ dependencies {
@@ -21,127 +21,138 @@ index af3514113abdf3f42c41f1e7ff0f930cc1a417f5..ed0b67ac322aa22b191cd35502ae5b4f
compileOnly("org.apache.maven:maven-resolver-provider:3.9.6")
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
new file mode 100644
-index 0000000000000000000000000000000000000000..5b28e9b1daba7834af67dbc193dd656bedd9a994
+index 0000000000000000000000000000000000000000..5a702481d28d90cb503faad0d9b9c3231bbff940
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
-@@ -0,0 +1,42 @@
+@@ -0,0 +1,46 @@
+package com.destroystokyo.paper.event.executor;
+
++import com.destroystokyo.paper.util.SneakyThrow;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
-+
-+import com.destroystokyo.paper.util.SneakyThrow;
+import org.bukkit.event.Event;
+import org.bukkit.event.EventException;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
++@NullMarked
+public class MethodHandleEventExecutor implements EventExecutor {
++
+ private final Class<? extends Event> eventClass;
+ private final MethodHandle handle;
+
-+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
++ public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
+ this.eventClass = eventClass;
+ this.handle = handle;
+ }
+
-+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
++ public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
+ this.eventClass = eventClass;
+ try {
+ m.setAccessible(true);
+ this.handle = MethodHandles.lookup().unreflect(m);
-+ } catch (IllegalAccessException e) {
++ } catch (final IllegalAccessException e) {
+ throw new AssertionError("Unable to set accessible", e);
+ }
+ }
+
+ @Override
-+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
-+ if (!eventClass.isInstance(event)) return;
++ public void execute(final Listener listener, final Event event) throws EventException {
++ if (!this.eventClass.isInstance(event)) return;
+ try {
-+ handle.invoke(listener, event);
-+ } catch (Throwable t) {
++ this.handle.invoke(listener, event);
++ } catch (final Throwable t) {
+ SneakyThrow.sneaky(t);
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
new file mode 100644
-index 0000000000000000000000000000000000000000..827f2b27f70a7ec0bc11d039305c3e58c02a4ef4
+index 0000000000000000000000000000000000000000..bbdb5b472df116b71c459bdc6cc4b74267ea0f5e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
-@@ -0,0 +1,42 @@
+@@ -0,0 +1,44 @@
+package com.destroystokyo.paper.event.executor;
+
++import com.destroystokyo.paper.util.SneakyThrow;
++import com.google.common.base.Preconditions;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
-+
-+import com.destroystokyo.paper.util.SneakyThrow;
-+import com.google.common.base.Preconditions;
-+
+import org.bukkit.event.Event;
+import org.bukkit.event.EventException;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class StaticMethodHandleEventExecutor implements EventExecutor {
++
+ private final Class<? extends Event> eventClass;
+ private final MethodHandle handle;
+
-+ public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
++ public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
+ Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
+ Preconditions.checkArgument(eventClass != null, "eventClass is null");
+ this.eventClass = eventClass;
+ try {
+ m.setAccessible(true);
+ this.handle = MethodHandles.lookup().unreflect(m);
-+ } catch (IllegalAccessException e) {
++ } catch (final IllegalAccessException e) {
+ throw new AssertionError("Unable to set accessible", e);
+ }
+ }
+
+ @Override
-+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
-+ if (!eventClass.isInstance(event)) return;
++ public void execute(final Listener listener, final Event event) throws EventException {
++ if (!this.eventClass.isInstance(event)) return;
+ try {
-+ handle.invoke(event);
-+ } catch (Throwable throwable) {
++ this.handle.invoke(event);
++ } catch (final Throwable throwable) {
+ SneakyThrow.sneaky(throwable);
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
new file mode 100644
-index 0000000000000000000000000000000000000000..084c31af1a7ba32bb4c3dc8f16f67fd09ce0b6a4
+index 0000000000000000000000000000000000000000..abfcb6e8383ff311940d82afe4ff990649a082dc
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,59 @@
+package com.destroystokyo.paper.event.executor.asm;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.atomic.AtomicInteger;
-+
+import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.GeneratorAdapter;
+
-+import static org.objectweb.asm.Opcodes.*;
++import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
++import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
++import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
++import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
++import static org.objectweb.asm.Opcodes.V1_8;
+
-+public class ASMEventExecutorGenerator {
++@NullMarked
++public final class ASMEventExecutorGenerator {
+
+ private static final String EXECUTE_DESCRIPTOR = "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V";
+
-+ @NotNull
-+ public static byte[] generateEventExecutor(@NotNull Method m, @NotNull String name) {
-+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
-+ writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[] {Type.getInternalName(EventExecutor.class)});
++ public static byte[] generateEventExecutor(final Method m, final String name) {
++ final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
++ writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(EventExecutor.class)});
+ // Generate constructor
+ GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
+ methodGenerator.loadThis();
@@ -169,22 +180,25 @@ index 0000000000000000000000000000000000000000..084c31af1a7ba32bb4c3dc8f16f67fd0
+ }
+
+ public static AtomicInteger NEXT_ID = new AtomicInteger(1);
-+ @NotNull
++
+ public static String generateName() {
-+ int id = NEXT_ID.getAndIncrement();
++ final int id = NEXT_ID.getAndIncrement();
+ return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
new file mode 100644
-index 0000000000000000000000000000000000000000..f79685b48bb581277a6891927988b6f7a4389dc4
+index 0000000000000000000000000000000000000000..581561fbd32c81ab1774ba8f0b7f3cec9392d99a
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
-@@ -0,0 +1,34 @@
+@@ -0,0 +1,35 @@
+package com.destroystokyo.paper.event.executor.asm;
+
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public interface ClassDefiner {
+
+ /**
@@ -192,7 +206,7 @@ index 0000000000000000000000000000000000000000..f79685b48bb581277a6891927988b6f7
+ *
+ * @return if classes bypass access checks
+ */
-+ public default boolean isBypassAccessChecks() {
++ default boolean isBypassAccessChecks() {
+ return false;
+ }
+
@@ -206,79 +220,79 @@ index 0000000000000000000000000000000000000000..f79685b48bb581277a6891927988b6f7
+ * @throws ClassFormatError if the class data is invalid
+ * @throws NullPointerException if any of the arguments are null
+ */
-+ @NotNull
-+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data);
++ Class<?> defineClass(ClassLoader parentLoader, String name, byte[] data);
+
-+ @NotNull
-+ public static ClassDefiner getInstance() {
++ static ClassDefiner getInstance() {
+ return SafeClassDefiner.INSTANCE;
+ }
+
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
new file mode 100644
-index 0000000000000000000000000000000000000000..abcc966d8ee01d73c1d1480237ab46fa0ab55fdc
+index 0000000000000000000000000000000000000000..48bcc72293c2a31b6e2dd2dcd6a79d618c72a137
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
-@@ -0,0 +1,64 @@
+@@ -0,0 +1,66 @@
+package com.destroystokyo.paper.event.executor.asm;
+
-+import java.util.concurrent.ConcurrentMap;
-+
+import com.google.common.base.Preconditions;
-+
+import com.google.common.collect.MapMaker;
-+import org.jetbrains.annotations.NotNull;
++import java.util.concurrent.ConcurrentMap;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class SafeClassDefiner implements ClassDefiner {
++
+ /* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
+
-+ private SafeClassDefiner() {}
++ private SafeClassDefiner() {
++ }
+
+ private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
+
-+ @NotNull
+ @Override
-+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data) {
-+ GeneratedClassLoader loader = loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
++ public Class<?> defineClass(final ClassLoader parentLoader, final String name, final byte[] data) {
++ final GeneratedClassLoader loader = this.loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
+ synchronized (loader.getClassLoadingLock(name)) {
+ Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
-+ Class<?> c = loader.define(name, data);
++ final Class<?> c = loader.define(name, data);
+ assert c.getName().equals(name);
+ return c;
+ }
+ }
+
+ private static class GeneratedClassLoader extends ClassLoader {
++
+ static {
+ ClassLoader.registerAsParallelCapable();
+ }
+
-+ protected GeneratedClassLoader(@NotNull ClassLoader parent) {
++ protected GeneratedClassLoader(final ClassLoader parent) {
+ super(parent);
+ }
+
-+ private Class<?> define(@NotNull String name, byte[] data) {
-+ synchronized (getClassLoadingLock(name)) {
-+ assert !hasClass(name);
-+ Class<?> c = defineClass(name, data, 0, data.length);
-+ resolveClass(c);
++ private Class<?> define(final String name, final byte[] data) {
++ synchronized (this.getClassLoadingLock(name)) {
++ assert !this.hasClass(name);
++ final Class<?> c = this.defineClass(name, data, 0, data.length);
++ this.resolveClass(c);
+ return c;
+ }
+ }
+
+ @Override
-+ @NotNull
-+ public Object getClassLoadingLock(@NotNull String name) {
++ public Object getClassLoadingLock(final String name) {
+ return super.getClassLoadingLock(name);
+ }
+
-+ public boolean hasClass(@NotNull String name) {
-+ synchronized (getClassLoadingLock(name)) {
++ public boolean hasClass(final String name) {
++ synchronized (this.getClassLoadingLock(name)) {
+ try {
+ Class.forName(name);
+ return true;
-+ } catch (ClassNotFoundException e) {
++ } catch (final ClassNotFoundException e) {
+ return false;
+ }
+ }
diff --git a/patches/api/0009-Paper-Plugins.patch b/patches/api/0009-Paper-Plugins.patch
index b36c62b38c..b29d687ccf 100644
--- a/patches/api/0009-Paper-Plugins.patch
+++ b/patches/api/0009-Paper-Plugins.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Paper Plugins
diff --git a/build.gradle.kts b/build.gradle.kts
-index dd1e8d3fda7ae6e5f0dfc6a5293f1ac4eb5fd3f4..b88bf39df6fb920b2c802e7057468c1476d63778 100644
+index 1f627e81622e77b81b1228a467fbb9e6fd979e7a..3c50362de25617d878ef58f14f67c240005ff624 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -52,7 +52,7 @@ dependencies {
@@ -17,7 +17,7 @@ index dd1e8d3fda7ae6e5f0dfc6a5293f1ac4eb5fd3f4..b88bf39df6fb920b2c802e7057468c14
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
-@@ -140,6 +140,7 @@ tasks.withType<Javadoc> {
+@@ -141,6 +141,7 @@ tasks.withType<Javadoc> {
"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
// Paper end
diff --git a/patches/api/0015-Expose-server-build-information.patch b/patches/api/0015-Expose-server-build-information.patch
index f0299bf5fe..3f8bdaf317 100644
--- a/patches/api/0015-Expose-server-build-information.patch
+++ b/patches/api/0015-Expose-server-build-information.patch
@@ -10,18 +10,21 @@ Co-authored-by: Riley Park <[email protected]>
diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a736d7bcdc5861a01b66ba36158db1c716339346
+index 0000000000000000000000000000000000000000..023cc52a9e28e1238c7452c0f3f577f2850fd861
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
-@@ -0,0 +1,45 @@
+@@ -0,0 +1,47 @@
+package com.destroystokyo.paper.util;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public interface VersionFetcher {
++
+ /**
+ * Amount of time to cache results for in milliseconds
+ * <p>
@@ -39,9 +42,9 @@ index 0000000000000000000000000000000000000000..a736d7bcdc5861a01b66ba36158db1c7
+ * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
+ * @return the message to show when requesting a version
+ */
-+ @NotNull
-+ Component getVersionMessage(@NotNull String serverVersion);
++ Component getVersionMessage(String serverVersion);
+
++ @ApiStatus.Internal
+ class DummyVersionFetcher implements VersionFetcher {
+
+ @Override
@@ -49,9 +52,8 @@ index 0000000000000000000000000000000000000000..a736d7bcdc5861a01b66ba36158db1c7
+ return -1;
+ }
+
-+ @NotNull
+ @Override
-+ public Component getVersionMessage(@NotNull String serverVersion) {
++ public Component getVersionMessage(final String serverVersion) {
+ Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
+ Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
+ new Throwable().printStackTrace();
diff --git a/patches/api/0021-Add-exception-reporting-event.patch b/patches/api/0021-Add-exception-reporting-event.patch
index 7d46942622..adf50a8c29 100644
--- a/patches/api/0021-Add-exception-reporting-event.patch
+++ b/patches/api/0021-Add-exception-reporting-event.patch
@@ -6,30 +6,31 @@ Subject: [PATCH] Add exception reporting event
diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9377ee1c2368ce058397037952d17bc010f66957
+index 0000000000000000000000000000000000000000..95a5a59e6bd88345177fca0b12008ddd689cb448
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
-@@ -0,0 +1,45 @@
+@@ -0,0 +1,43 @@
+package com.destroystokyo.paper.event.server;
+
++import com.destroystokyo.paper.exception.ServerException;
+import org.bukkit.Bukkit;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
-+import com.destroystokyo.paper.exception.ServerException;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called whenever an exception is thrown in a recoverable section of the server.
+ */
++@NullMarked
+public class ServerExceptionEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final ServerException exception;
++ private final ServerException exception;
+
+ @ApiStatus.Internal
-+ public ServerExceptionEvent(@NotNull ServerException exception) {
++ public ServerExceptionEvent(final ServerException exception) {
+ super(!Bukkit.isPrimaryThread());
+ this.exception = exception;
+ }
@@ -39,18 +40,15 @@ index 0000000000000000000000000000000000000000..9377ee1c2368ce058397037952d17bc0
+ *
+ * @return Exception thrown
+ */
-+ @NotNull
+ public ServerException getException() {
+ return this.exception;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0031-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/api/0031-Entity-AddTo-RemoveFrom-World-Events.patch
index 5748bb7aae..23dad970bc 100644
--- a/patches/api/0031-Entity-AddTo-RemoveFrom-World-Events.patch
+++ b/patches/api/0031-Entity-AddTo-RemoveFrom-World-Events.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..990b307801be996a4707d87e420b05ee25286d5b
+index 0000000000000000000000000000000000000000..11f8540a4752cf4d2112eff48bcca3b935c9f8b1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,44 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.World;
@@ -45,6 +45,7 @@ index 0000000000000000000000000000000000000000..990b307801be996a4707d87e420b05ee
+ return this.world;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
@@ -55,10 +56,10 @@ index 0000000000000000000000000000000000000000..990b307801be996a4707d87e420b05ee
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..b7776c1e65c8140a1e800df56bda5bec5717b50e
+index 0000000000000000000000000000000000000000..5ad5632d4d47d8b42e4f2af19c0fe6cf94ac5643
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
-@@ -0,0 +1,41 @@
+@@ -0,0 +1,42 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.World;
@@ -92,6 +93,7 @@ index 0000000000000000000000000000000000000000..b7776c1e65c8140a1e800df56bda5bec
+ return this.world;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0032-EntityPathfindEvent.patch b/patches/api/0032-EntityPathfindEvent.patch
index e6ee2e1f3f..5a2e0c0ffa 100644
--- a/patches/api/0032-EntityPathfindEvent.patch
+++ b/patches/api/0032-EntityPathfindEvent.patch
@@ -7,10 +7,10 @@ Fires when an Entity decides to start moving to a location.
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2dd25136d81624025244a82de119fbecd0d7224c
+index 0000000000000000000000000000000000000000..8624e0a528985c9b118f5e8a0f33d3286af2fc36
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
-@@ -0,0 +1,83 @@
+@@ -0,0 +1,84 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@@ -49,6 +49,7 @@ index 0000000000000000000000000000000000000000..2dd25136d81624025244a82de119fbec
+ *
+ * @return The Entity that is pathfinding.
+ */
++ @Override
+ public Entity getEntity() {
+ return this.entity;
+ }
diff --git a/patches/api/0035-Add-PlayerUseUnknownEntityEvent.patch b/patches/api/0035-Add-PlayerUseUnknownEntityEvent.patch
index e0d410dc6e..49715a5255 100644
--- a/patches/api/0035-Add-PlayerUseUnknownEntityEvent.patch
+++ b/patches/api/0035-Add-PlayerUseUnknownEntityEvent.patch
@@ -10,10 +10,10 @@ Co-authored-by: Nassim Jahnke <[email protected]>
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..dbb635686e9108b9d3df5d373e6972cca07c0621
+index 0000000000000000000000000000000000000000..9ff2bbf7f99df45cc626cad60bec4d14a8a04e3e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
-@@ -0,0 +1,86 @@
+@@ -0,0 +1,85 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.entity.Player;
@@ -23,8 +23,8 @@ index 0000000000000000000000000000000000000000..dbb635686e9108b9d3df5d373e6972cc
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Represents an event that is called when a player right-clicks an unknown entity.
@@ -33,17 +33,18 @@ index 0000000000000000000000000000000000000000..dbb635686e9108b9d3df5d373e6972cc
+ * This event may be called multiple times per interaction with different interaction hands
+ * and with or without the clicked position.
+ */
++@NullMarked
+public class PlayerUseUnknownEntityEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final int entityId;
+ private final boolean attack;
-+ private final @NotNull EquipmentSlot hand;
++ private final EquipmentSlot hand;
+ private final @Nullable Vector clickedPosition;
+
+ @ApiStatus.Internal
-+ public PlayerUseUnknownEntityEvent(@NotNull Player player, int entityId, boolean attack, @NotNull EquipmentSlot hand, @Nullable Vector clickedPosition) {
++ public PlayerUseUnknownEntityEvent(final Player player, final int entityId, final boolean attack, final EquipmentSlot hand, final @Nullable Vector clickedPosition) {
+ super(player);
+ this.entityId = entityId;
+ this.attack = attack;
@@ -74,7 +75,7 @@ index 0000000000000000000000000000000000000000..dbb635686e9108b9d3df5d373e6972cc
+ *
+ * @return the hand used to interact
+ */
-+ public @NotNull EquipmentSlot getHand() {
++ public EquipmentSlot getHand() {
+ return this.hand;
+ }
+
@@ -89,13 +90,11 @@ index 0000000000000000000000000000000000000000..dbb635686e9108b9d3df5d373e6972cc
+ return this.clickedPosition != null ? this.clickedPosition.clone() : null;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0039-LootTable-API.patch b/patches/api/0039-LootTable-API.patch
index e1252ab848..40be416e93 100644
--- a/patches/api/0039-LootTable-API.patch
+++ b/patches/api/0039-LootTable-API.patch
@@ -12,96 +12,100 @@ Provides methods to determine players looted state for an object
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
new file mode 100644
-index 0000000000000000000000000000000000000000..92d7b853a2ccaae5afa8ac141bead840942944ef
+index 0000000000000000000000000000000000000000..08e82b9de34c5ce8c5e83631b1229e90e5aa9694
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
-@@ -0,0 +1,17 @@
+@@ -0,0 +1,18 @@
+package com.destroystokyo.paper.loottable;
+
+import org.bukkit.block.Block;
+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Represents an Inventory that can generate loot, such as Chests inside of Fortresses and Mineshafts
+ */
++@NullMarked
+public interface LootableBlockInventory extends LootableInventory {
+
+ /**
+ * Gets the block that is lootable
+ * @return The Block
+ */
-+ @NotNull
+ Block getBlock();
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
new file mode 100644
-index 0000000000000000000000000000000000000000..b387894fe8001edb41ad2ad2b70ebabe065b682e
+index 0000000000000000000000000000000000000000..a1e1a0256010f293e7dfa63c6622e9125eb4cc73
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
-@@ -0,0 +1,17 @@
+@@ -0,0 +1,18 @@
+package com.destroystokyo.paper.loottable;
+
+import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Represents an Inventory that can generate loot, such as Minecarts inside of Mineshafts
+ */
++@NullMarked
+public interface LootableEntityInventory extends LootableInventory {
+
+ /**
+ * Gets the entity that is lootable
+ * @return The Entity
+ */
-+ @NotNull
+ Entity getEntity();
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
new file mode 100644
-index 0000000000000000000000000000000000000000..b18a0b50c12fe8d8c954e5c070f2ecd1854a2583
+index 0000000000000000000000000000000000000000..b085e1217838012e4f4c6bcce100d8282190cdbc
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
-@@ -0,0 +1,124 @@
+@@ -0,0 +1,129 @@
+package com.destroystokyo.paper.loottable;
+
++import java.util.UUID;
+import org.bukkit.entity.Player;
+import org.bukkit.loot.Lootable;
-+
-+import java.util.UUID;
-+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Represents an Inventory that contains a Loot Table associated to it that will
+ * automatically fill on first open.
-+ *
++ * <p>
+ * A new feature and API is provided to support automatically refreshing the contents
+ * of the inventory based on that Loot Table after a configurable amount of time has passed.
-+ *
++ * <p>
+ * The behavior of how the Inventory is filled based on the loot table may vary based
+ * on Minecraft versions and the Loot Table feature.
+ */
++@NullMarked
+public interface LootableInventory extends Lootable {
+
+ /**
-+ * Server owners have to enable whether or not an object in a world should refill
++ * Server owners have to enable whether an object in a world should refill
+ *
+ * @return If the world this inventory is currently in has Replenishable Lootables enabled
+ */
+ boolean isRefillEnabled();
+
+ /**
-+ * Whether or not this object has ever been filled
++ * Whether this object has ever been filled
++ *
+ * @return Has ever been filled
+ */
+ boolean hasBeenFilled();
+
+ /**
+ * Has this player ever looted this block
++ *
+ * @param player The player to check
-+ * @return Whether or not this player has looted this block
++ * @return Whether this player has looted this block
+ */
-+ default boolean hasPlayerLooted(final @NotNull Player player) {
++ default boolean hasPlayerLooted(final Player player) {
+ return this.hasPlayerLooted(player.getUniqueId());
+ }
+
@@ -109,17 +113,17 @@ index 0000000000000000000000000000000000000000..b18a0b50c12fe8d8c954e5c070f2ecd1
+ * Checks if this player can loot this block. Takes into account the "restrict player reloot" settings
+ *
+ * @param player the player to check
-+ *
+ * @return Whether this player can loot this block
+ */
-+ boolean canPlayerLoot(@NotNull UUID player);
++ boolean canPlayerLoot(UUID player);
+
+ /**
+ * Has this player ever looted this block
++ *
+ * @param player The player to check
-+ * @return Whether or not this player has looted this block
++ * @return Whether this player has looted this block
+ */
-+ boolean hasPlayerLooted(@NotNull UUID player);
++ boolean hasPlayerLooted(UUID player);
+
+ /**
+ * Gets the timestamp, in milliseconds, of when the player last looted this object
@@ -127,7 +131,7 @@ index 0000000000000000000000000000000000000000..b18a0b50c12fe8d8c954e5c070f2ecd1
+ * @param player The player to check
+ * @return Timestamp last looted, or null if player has not looted this object
+ */
-+ default @Nullable Long getLastLooted(final @NotNull Player player) {
++ default @Nullable Long getLastLooted(final Player player) {
+ return this.getLastLooted(player.getUniqueId());
+ }
+
@@ -138,28 +142,31 @@ index 0000000000000000000000000000000000000000..b18a0b50c12fe8d8c954e5c070f2ecd1
+ * @return Timestamp last looted, or null if player has not looted this object
+ */
+ @Nullable
-+ Long getLastLooted(@NotNull UUID player);
++ Long getLastLooted(UUID player);
+
+ /**
-+ * Change the state of whether or not a player has looted this block
++ * Change the state of whether a player has looted this block
++ *
+ * @param player The player to change state for
+ * @param looted true to add player to looted list, false to remove
+ * @return The previous state of whether the player had looted this or not
+ */
-+ default boolean setHasPlayerLooted(final @NotNull Player player, final boolean looted) {
++ default boolean setHasPlayerLooted(final Player player, final boolean looted) {
+ return this.setHasPlayerLooted(player.getUniqueId(), looted);
+ }
+
+ /**
-+ * Change the state of whether or not a player has looted this block
++ * Change the state of whether a player has looted this block
++ *
+ * @param player The player to change state for
+ * @param looted true to add player to looted list, false to remove
+ * @return The previous state of whether the player had looted this or not
+ */
-+ boolean setHasPlayerLooted(@NotNull UUID player, boolean looted);
++ boolean setHasPlayerLooted(UUID player, boolean looted);
+
+ /**
-+ * Returns Whether or not this object has been filled and now has a pending refill
++ * Returns Whether this object has been filled and now has a pending refill
++ *
+ * @return Has pending refill
+ */
+ boolean hasPendingRefill();
@@ -188,10 +195,10 @@ index 0000000000000000000000000000000000000000..b18a0b50c12fe8d8c954e5c070f2ecd1
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..5ee1a04aaaa4ef09559f2cf757811e463e2a1be6
+index 0000000000000000000000000000000000000000..994c2183db89fc40d5991d5e1906e4bd04db6291
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
-@@ -0,0 +1,47 @@
+@@ -0,0 +1,46 @@
+package com.destroystokyo.paper.loottable;
+
+import org.bukkit.entity.Player;
@@ -199,22 +206,22 @@ index 0000000000000000000000000000000000000000..5ee1a04aaaa4ef09559f2cf757811e46
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final LootableInventory inventory;
++ private final LootableInventory inventory;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public LootableInventoryReplenishEvent(@NotNull Player player, @NotNull LootableInventory inventory) {
++ public LootableInventoryReplenishEvent(final Player player, final LootableInventory inventory) {
+ super(player);
+ this.inventory = inventory;
+ }
+
-+ @NotNull
+ public LootableInventory getInventory() {
+ return this.inventory;
+ }
@@ -225,16 +232,15 @@ index 0000000000000000000000000000000000000000..5ee1a04aaaa4ef09559f2cf757811e46
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0049-PlayerTeleportEndGatewayEvent.patch b/patches/api/0049-PlayerTeleportEndGatewayEvent.patch
index b964a35e5d..b52aaaead8 100644
--- a/patches/api/0049-PlayerTeleportEndGatewayEvent.patch
+++ b/patches/api/0049-PlayerTeleportEndGatewayEvent.patch
@@ -7,7 +7,7 @@ Allows you to access the Gateway being used in a teleport event
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..40bd79fbe30f19bc93e34da52d2b2bf0768be974
+index 0000000000000000000000000000000000000000..4488154d3f99f4281b08eef8a44c13fd896e538f
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
@@ -0,0 +1,32 @@
@@ -18,17 +18,18 @@ index 0000000000000000000000000000000000000000..40bd79fbe30f19bc93e34da52d2b2bf0
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a teleport is triggered for an End Gateway
+ */
++@NullMarked
+public class PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
+
-+ @NotNull private final EndGateway gateway;
++ private final EndGateway gateway;
+
+ @ApiStatus.Internal
-+ public PlayerTeleportEndGatewayEvent(@NotNull Player player, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
++ public PlayerTeleportEndGatewayEvent(final Player player, final Location from, final Location to, final EndGateway gateway) {
+ super(player, from, to, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
+ this.gateway = gateway;
+ }
@@ -38,7 +39,6 @@ index 0000000000000000000000000000000000000000..40bd79fbe30f19bc93e34da52d2b2bf0
+ *
+ * @return EndGateway used
+ */
-+ @NotNull
+ public EndGateway getGateway() {
+ return this.gateway;
+ }
diff --git a/patches/api/0057-Basic-PlayerProfile-API.patch b/patches/api/0057-Basic-PlayerProfile-API.patch
index 1161dbaabf..1e069d46b5 100644
--- a/patches/api/0057-Basic-PlayerProfile-API.patch
+++ b/patches/api/0057-Basic-PlayerProfile-API.patch
@@ -247,7 +247,7 @@ index 0000000000000000000000000000000000000000..b4f9ffbebab8eef99dbd81c816c16c27
+}
diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
new file mode 100644
-index 0000000000000000000000000000000000000000..8f913a078dd692a9feafb98a6e6c9583f3253bd4
+index 0000000000000000000000000000000000000000..8f6240484d12f01bb555972feb0937bc74399a64
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
@@ -0,0 +1,75 @@
@@ -262,7 +262,7 @@ index 0000000000000000000000000000000000000000..8f913a078dd692a9feafb98a6e6c9583
+/**
+ * Represents a property on a {@link PlayerProfile}
+ */
-+public class ProfileProperty {
++public final class ProfileProperty {
+ private final String name;
+ private final String value;
+ private final String signature;
diff --git a/patches/api/0066-ProfileWhitelistVerifyEvent.patch b/patches/api/0066-ProfileWhitelistVerifyEvent.patch
index 8c653d95af..d0fac0687c 100644
--- a/patches/api/0066-ProfileWhitelistVerifyEvent.patch
+++ b/patches/api/0066-ProfileWhitelistVerifyEvent.patch
@@ -9,10 +9,10 @@ Allows you to do dynamic whitelisting and change of kick message
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab8133478f7c6
+index 0000000000000000000000000000000000000000..31884c55d45931a313292df552b604d929a22586
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java
-@@ -0,0 +1,147 @@
+@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 - Daniel Ennis (Aikar) - MIT License
+ *
@@ -44,8 +44,8 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Fires when the server needs to verify if a player is whitelisted.
@@ -53,24 +53,25 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+ * Plugins may override/control the servers whitelist with this event,
+ * and dynamically change the kick message.
+ */
++@NullMarked
+public class ProfileWhitelistVerifyEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final PlayerProfile profile;
++ private final PlayerProfile profile;
+ private final boolean whitelistEnabled;
+ private final boolean isOp;
+ private boolean whitelisted;
-+ @Nullable private Component kickMessage;
++ private @Nullable Component kickMessage;
+
+ @Deprecated
+ @ApiStatus.Internal
-+ public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable String kickMessage) {
++ public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable String kickMessage) {
+ this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
+ }
+
+ @ApiStatus.Internal
-+ public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable Component kickMessage) {
++ public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable Component kickMessage) {
+ this.profile = profile;
+ this.whitelistEnabled = whitelistEnabled;
+ this.whitelisted = whitelisted;
@@ -83,8 +84,7 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+ * @deprecated use {@link #kickMessage()}
+ */
+ @Deprecated
-+ @Nullable
-+ public String getKickMessage() {
++ public @Nullable String getKickMessage() {
+ return this.kickMessage == null ? null : LegacyComponentSerializer.legacySection().serialize(this.kickMessage);
+ }
+
@@ -93,35 +93,33 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+ * @deprecated Use {@link #kickMessage(Component)}
+ */
+ @Deprecated
-+ public void setKickMessage(@Nullable String kickMessage) {
++ public void setKickMessage(final @Nullable String kickMessage) {
+ this.kickMessage(kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
+ }
+
+ /**
+ * @return the currently planned message to send to the user if they are not whitelisted
+ */
-+ @Nullable
-+ public Component kickMessage() {
++ public @Nullable Component kickMessage() {
+ return this.kickMessage;
+ }
+
+ /**
+ * @param kickMessage The message to send to the player on kick if not whitelisted. May set to {@code null} to use the server configured default
+ */
-+ public void kickMessage(@Nullable Component kickMessage) {
++ public void kickMessage(final @Nullable Component kickMessage) {
+ this.kickMessage = kickMessage;
+ }
+
+ /**
+ * @return The profile of the player trying to connect
+ */
-+ @NotNull
+ public PlayerProfile getPlayerProfile() {
+ return this.profile;
+ }
+
+ /**
-+ * @return Whether the player is whitelisted to play on this server (whitelist may be off is why its true)
++ * @return Whether the player is whitelisted to play on this server (whitelist may be off is why it's true)
+ */
+ public boolean isWhitelisted() {
+ return this.whitelisted;
@@ -129,9 +127,10 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+
+ /**
+ * Changes the players whitelisted state. {@code false} will deny the login
++ *
+ * @param whitelisted The new whitelisted state
+ */
-+ public void setWhitelisted(boolean whitelisted) {
++ public void setWhitelisted(final boolean whitelisted) {
+ this.whitelisted = whitelisted;
+ }
+
@@ -149,13 +148,11 @@ index 0000000000000000000000000000000000000000..52959c2d19c5b73ccd85afce6b2ab813
+ return this.whitelistEnabled;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch b/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch
index a76fe3bb21..1b451c151b 100644
--- a/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch
+++ b/patches/api/0067-Allow-plugins-to-use-SLF4J-for-logging.patch
@@ -14,7 +14,7 @@ it without having to shade it in the plugin and going through
several layers of logging abstraction.
diff --git a/build.gradle.kts b/build.gradle.kts
-index b88bf39df6fb920b2c802e7057468c1476d63778..37ff4cb89dfb28eab6f836840ff1838d67895c1e 100644
+index 3c50362de25617d878ef58f14f67c240005ff624..76aa23da778b0fe8a093429c56cb29b044359b40 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,6 +12,8 @@ java {
@@ -35,7 +35,7 @@ index b88bf39df6fb920b2c802e7057468c1476d63778..37ff4cb89dfb28eab6f836840ff1838d
implementation("org.ow2.asm:asm:9.7")
implementation("org.ow2.asm:asm-commons:9.7")
-@@ -139,6 +143,8 @@ tasks.withType<Javadoc> {
+@@ -140,6 +144,8 @@ tasks.withType<Javadoc> {
"https://jd.advntr.dev/text-serializer-legacy/$adventureVersion/",
"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
diff --git a/patches/api/0069-Add-PlayerJumpEvent.patch b/patches/api/0069-Add-PlayerJumpEvent.patch
index fef1ccd347..f43b25a51f 100644
--- a/patches/api/0069-Add-PlayerJumpEvent.patch
+++ b/patches/api/0069-Add-PlayerJumpEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerJumpEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272ad3a67b6f
+index 0000000000000000000000000000000000000000..1d07c3d6bf3b9283371ca45698178979113085fa
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java
-@@ -0,0 +1,106 @@
+@@ -0,0 +1,105 @@
+package com.destroystokyo.paper.event.player;
+
+import com.google.common.base.Preconditions;
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the server detects the player is jumping.
@@ -29,17 +29,18 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ * when checking for jumps via {@link PlayerMoveEvent}, this event is fired whenever
+ * the server detects that the player is jumping.
+ */
++@NullMarked
+public class PlayerJumpEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Location to;
-+ @NotNull private Location from;
++ private final Location to;
++ private Location from;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerJumpEvent(@NotNull final Player player, @NotNull final Location from, @NotNull final Location to) {
++ public PlayerJumpEvent(final Player player, final Location from, final Location to) {
+ super(player);
+ this.from = from;
+ this.to = to;
@@ -54,6 +55,7 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ *
+ * @return {@code true} if this event is cancelled
+ */
++ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
@@ -67,7 +69,8 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ *
+ * @param cancel {@code true} if you wish to cancel this event
+ */
-+ public void setCancelled(boolean cancel) {
++ @Override
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
@@ -76,7 +79,6 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ *
+ * @return Location the player jumped from
+ */
-+ @NotNull
+ public Location getFrom() {
+ return this.from;
+ }
@@ -86,7 +88,7 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ *
+ * @param from New location to mark as the players previous location
+ */
-+ public void setFrom(@NotNull Location from) {
++ public void setFrom(final Location from) {
+ Preconditions.checkArgument(from != null, "Cannot use null from location!");
+ Preconditions.checkArgument(from.getWorld() != null, "Cannot use from location with null world!");
+ this.from = from;
@@ -100,18 +102,15 @@ index 0000000000000000000000000000000000000000..8c2fd2c1120d634052f9bc345365272a
+ *
+ * @return Location the player jumped to
+ */
-+ @NotNull
+ public Location getTo() {
+ return this.to.clone();
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0070-Add-workaround-for-plugins-modifying-the-parent-of-t.patch b/patches/api/0070-Add-workaround-for-plugins-modifying-the-parent-of-t.patch
index 12d008b482..9afdf0a360 100644
--- a/patches/api/0070-Add-workaround-for-plugins-modifying-the-parent-of-t.patch
+++ b/patches/api/0070-Add-workaround-for-plugins-modifying-the-parent-of-t.patch
@@ -14,33 +14,31 @@ parent of the plugin logger to avoid this.
diff --git a/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java b/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java
new file mode 100644
-index 0000000000000000000000000000000000000000..087ee57fe5485bc760fadd45a176d4d90a18f9f8
+index 0000000000000000000000000000000000000000..c78a359566a11904d2dd41098ced556a91a7fa36
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,46 @@
+package com.destroystokyo.paper.utils;
+
+import io.papermc.paper.plugin.configuration.PluginMeta;
-+import org.bukkit.plugin.PluginDescriptionFile;
-+
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
-+import org.jetbrains.annotations.NotNull;
++import org.bukkit.plugin.PluginDescriptionFile;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Prevents plugins (e.g. Essentials) from changing the parent of the plugin logger.
+ */
++@NullMarked
+public class PaperPluginLogger extends Logger {
+
+ @Deprecated(forRemoval = true)
-+ @NotNull
-+ public static Logger getLogger(@NotNull PluginDescriptionFile description) {
++ public static Logger getLogger(final PluginDescriptionFile description) {
+ return getLogger((PluginMeta) description);
+ }
+
-+ @NotNull
-+ public static Logger getLogger(@NotNull PluginMeta meta) {
++ public static Logger getLogger(final PluginMeta meta) {
+ Logger logger = new PaperPluginLogger(meta);
+ if (!LogManager.getLogManager().addLogger(logger)) {
+ // Disable this if it's going to happen across reloads anyways...
@@ -51,14 +49,14 @@ index 0000000000000000000000000000000000000000..087ee57fe5485bc760fadd45a176d4d9
+ return logger;
+ }
+
-+ private PaperPluginLogger(@NotNull PluginMeta meta) {
++ private PaperPluginLogger(final PluginMeta meta) {
+ super(meta.getLoggerPrefix() != null ? meta.getLoggerPrefix() : meta.getName(), null);
+ }
+
+ @Override
-+ public void setParent(@NotNull Logger parent) {
-+ if (getParent() != null) {
-+ warning("Ignoring attempt to change parent of plugin logger");
++ public void setParent(final Logger parent) {
++ if (this.getParent() != null) {
++ this.warning("Ignoring attempt to change parent of plugin logger");
+ } else {
+ this.log(Level.FINE, "Setting plugin logger parent to {0}", parent);
+ super.setParent(parent);
@@ -67,7 +65,7 @@ index 0000000000000000000000000000000000000000..087ee57fe5485bc760fadd45a176d4d9
+
+}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
-index f81e335a4e533221529355bec2f5d588aa79e60c..d359ea9b02952f981b9cf9d778c56eb995454c60 100644
+index 801578de8599d6b546cde63b3f2655fab48eee03..2d64fc065d53dcd8c01d05215c3e63aaf4428177 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
@@ -292,10 +292,10 @@ public abstract class JavaPlugin extends PluginBase {
diff --git a/patches/api/0071-Add-PlayerArmorChangeEvent.patch b/patches/api/0071-Add-PlayerArmorChangeEvent.patch
index d0fc3edb36..9b30ad2abc 100644
--- a/patches/api/0071-Add-PlayerArmorChangeEvent.patch
+++ b/patches/api/0071-Add-PlayerArmorChangeEvent.patch
@@ -6,22 +6,21 @@ Subject: [PATCH] Add PlayerArmorChangeEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180b335bf20
+index 0000000000000000000000000000000000000000..c7cc612ec81b0c7da6ee6676167e047e69347966
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java
-@@ -0,0 +1,127 @@
+@@ -0,0 +1,120 @@
+package com.destroystokyo.paper.event.player;
+
++import java.util.Set;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
-+
-+import java.util.Set;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+import static org.bukkit.Material.*;
+
@@ -30,16 +29,17 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ * <p>
+ * Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
+ */
++@NullMarked
+public class PlayerArmorChangeEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final SlotType slotType;
-+ @NotNull private final ItemStack oldItem;
-+ @NotNull private final ItemStack newItem;
++ private final SlotType slotType;
++ private final ItemStack oldItem;
++ private final ItemStack newItem;
+
+ @ApiStatus.Internal
-+ public PlayerArmorChangeEvent(@NotNull Player player, @NotNull SlotType slotType, @NotNull ItemStack oldItem, @NotNull ItemStack newItem) {
++ public PlayerArmorChangeEvent(final Player player, final SlotType slotType, final ItemStack oldItem, final ItemStack newItem) {
+ super(player);
+ this.slotType = slotType;
+ this.oldItem = oldItem;
@@ -51,7 +51,6 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ *
+ * @return type of slot being altered
+ */
-+ @NotNull
+ public SlotType getSlotType() {
+ return this.slotType;
+ }
@@ -61,7 +60,6 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ *
+ * @return old item
+ */
-+ @NotNull
+ public ItemStack getOldItem() {
+ return this.oldItem;
+ }
@@ -71,18 +69,15 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ *
+ * @return new item
+ */
-+ @NotNull
+ public ItemStack getNewItem() {
+ return this.newItem;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@@ -95,7 +90,7 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+
+ private final Set<Material> types;
+
-+ SlotType(Material... types) {
++ SlotType(final Material... types) {
+ this.types = Set.of(types);
+ }
+
@@ -105,7 +100,6 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ *
+ * @return immutable set of material types
+ */
-+ @NotNull
+ public Set<Material> getTypes() {
+ return this.types;
+ }
@@ -116,9 +110,8 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ * @param material material to get slot by
+ * @return slot type the material will go in, or {@code null} if it won't
+ */
-+ @Nullable
-+ public static SlotType getByMaterial(@NotNull Material material) {
-+ for (SlotType slotType : values()) {
++ public static @Nullable SlotType getByMaterial(final Material material) {
++ for (final SlotType slotType : values()) {
+ if (slotType.getTypes().contains(material)) {
+ return slotType;
+ }
@@ -132,7 +125,7 @@ index 0000000000000000000000000000000000000000..ab08219497f7e362f113321c4bcfd180
+ * @param material material to check
+ * @return whether this material can be equipped
+ */
-+ public static boolean isEquipable(@NotNull Material material) {
++ public static boolean isEquipable(final Material material) {
+ return getByMaterial(material) != null;
+ }
+ }
diff --git a/patches/api/0073-AsyncTabCompleteEvent.patch b/patches/api/0073-AsyncTabCompleteEvent.patch
index b5de053456..2ad169a7c5 100644
--- a/patches/api/0073-AsyncTabCompleteEvent.patch
+++ b/patches/api/0073-AsyncTabCompleteEvent.patch
@@ -17,10 +17,10 @@ Co-authored-by: Aikar <[email protected]>
diff --git a/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..e2bfd86c964ce5a75470fef1ea7e031a95735fb3
+index 0000000000000000000000000000000000000000..0482ecf5b84ba8e0260679049f384f3449bbe7b5
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
-@@ -0,0 +1,332 @@
+@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
+ *
@@ -244,6 +244,7 @@ index 0000000000000000000000000000000000000000..e2bfd86c964ce5a75470fef1ea7e031a
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
@@ -592,7 +593,7 @@ index 270e6d8ad4358baa256cee5f16cff281f063ce3b..6465e290c090d82986352d5ab7ba5dc6
@Override
diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
-index 65cca227207efb8177f3cdbcbff5fe0c3b8a563f..d3a2cb7cf1bc708002fa0b7a44c03ed53fc0c454 100644
+index 7ff939ea41417bad3a436a87c89d5efa7ecefe86..88d5db2995829cba919d78f988d5c735cf70cb1b 100644
--- a/src/test/java/org/bukkit/AnnotationTest.java
+++ b/src/test/java/org/bukkit/AnnotationTest.java
@@ -48,6 +48,8 @@ public class AnnotationTest {
diff --git a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch
index c6ce0e9872..0a078f013d 100644
--- a/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch
+++ b/patches/api/0074-Expose-client-protocol-version-and-virtual-host.patch
@@ -11,20 +11,20 @@ Add a NetworkClient interface that provides access to:
diff --git a/src/main/java/com/destroystokyo/paper/network/NetworkClient.java b/src/main/java/com/destroystokyo/paper/network/NetworkClient.java
new file mode 100644
-index 0000000000000000000000000000000000000000..7b2af1bd72dfbcf4e962a982940fc49b851aa04f
+index 0000000000000000000000000000000000000000..c84ce3fc874eea3d8f0b1cf5273996d9b4af6225
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/network/NetworkClient.java
-@@ -0,0 +1,41 @@
+@@ -0,0 +1,39 @@
+package com.destroystokyo.paper.network;
+
+import java.net.InetSocketAddress;
-+
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Represents a client connected to the server.
+ */
++@NullMarked
+public interface NetworkClient {
+
+ /**
@@ -32,7 +32,6 @@ index 0000000000000000000000000000000000000000..7b2af1bd72dfbcf4e962a982940fc49b
+ *
+ * @return The client's socket address
+ */
-+ @NotNull
+ InetSocketAddress getAddress();
+
+ /**
@@ -52,8 +51,7 @@ index 0000000000000000000000000000000000000000..7b2af1bd72dfbcf4e962a982940fc49b
+ *
+ * @return The client's virtual host, or {@code null} if unknown
+ */
-+ @Nullable
-+ InetSocketAddress getVirtualHost();
++ @Nullable InetSocketAddress getVirtualHost();
+
+}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
diff --git a/patches/api/0076-PlayerPickupExperienceEvent.patch b/patches/api/0076-PlayerPickupExperienceEvent.patch
index 9f4dfd145c..0f6ff806cd 100644
--- a/patches/api/0076-PlayerPickupExperienceEvent.patch
+++ b/patches/api/0076-PlayerPickupExperienceEvent.patch
@@ -7,10 +7,10 @@ Allows plugins to cancel a player picking up an experience orb
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0ef10ac6bac990837e21520c800d89420a18e3d4
+index 0000000000000000000000000000000000000000..0c6ddf0724780245ad01a3b5a5b0e477c25fc62e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java
-@@ -0,0 +1,83 @@
+@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
+ *
@@ -42,20 +42,21 @@ index 0000000000000000000000000000000000000000..0ef10ac6bac990837e21520c800d8942
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a player is attempting to pick up an experience orb
+ */
++@NullMarked
+public class PlayerPickupExperienceEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final ExperienceOrb experienceOrb;
++ private final ExperienceOrb experienceOrb;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerPickupExperienceEvent(@NotNull Player player, @NotNull ExperienceOrb experienceOrb) {
++ public PlayerPickupExperienceEvent(final Player player, final ExperienceOrb experienceOrb) {
+ super(player);
+ this.experienceOrb = experienceOrb;
+ }
@@ -63,7 +64,6 @@ index 0000000000000000000000000000000000000000..0ef10ac6bac990837e21520c800d8942
+ /**
+ * @return Returns the Orb that the player is picking up
+ */
-+ @NotNull
+ public ExperienceOrb getExperienceOrb() {
+ return this.experienceOrb;
+ }
@@ -79,17 +79,15 @@ index 0000000000000000000000000000000000000000..0ef10ac6bac990837e21520c800d8942
+ * If {@code true}, cancels picking up the experience orb, leaving it in the world
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0082-Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/api/0082-Add-PlayerAdvancementCriterionGrantEvent.patch
index acab81b457..852e4d9d1e 100644
--- a/patches/api/0082-Add-PlayerAdvancementCriterionGrantEvent.patch
+++ b/patches/api/0082-Add-PlayerAdvancementCriterionGrantEvent.patch
@@ -7,10 +7,10 @@ Co-authored-by: The456gamer <[email protected]>
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d738dde7ae
+index 0000000000000000000000000000000000000000..0fb316e34ec9728610237a08f37fffb61fd5afa8
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,80 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.advancement.Advancement;
@@ -20,24 +20,25 @@ index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d7
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called after a player is granted a criteria in an advancement.
+ * If cancelled the criteria will be revoked.
+ */
++@NullMarked
+public class PlayerAdvancementCriterionGrantEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Advancement advancement;
-+ @NotNull private final String criterion;
-+ @NotNull private final AdvancementProgress advancementProgress;
++ private final Advancement advancement;
++ private final String criterion;
++ private final AdvancementProgress advancementProgress;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerAdvancementCriterionGrantEvent(@NotNull Player player, @NotNull Advancement advancement, @NotNull String criterion) {
++ public PlayerAdvancementCriterionGrantEvent(final Player player, final Advancement advancement, final String criterion) {
+ super(player);
+ this.advancement = advancement;
+ this.criterion = criterion;
@@ -49,7 +50,6 @@ index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d7
+ *
+ * @return affected advancement
+ */
-+ @NotNull
+ public Advancement getAdvancement() {
+ return this.advancement;
+ }
@@ -59,7 +59,6 @@ index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d7
+ *
+ * @return granted criterion
+ */
-+ @NotNull
+ public String getCriterion() {
+ return this.criterion;
+ }
@@ -69,7 +68,6 @@ index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d7
+ *
+ * @return advancement progress
+ */
-+ @NotNull
+ public AdvancementProgress getAdvancementProgress() {
+ return this.advancementProgress;
+ }
@@ -80,17 +78,15 @@ index 0000000000000000000000000000000000000000..9502f94b3567fc22c4b61fea5aa251d7
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0083-Fill-Profile-Property-Events.patch b/patches/api/0083-Fill-Profile-Property-Events.patch
index 28d3b1fa04..137c383e9e 100644
--- a/patches/api/0083-Fill-Profile-Property-Events.patch
+++ b/patches/api/0083-Fill-Profile-Property-Events.patch
@@ -12,10 +12,10 @@ This is useful for implementing a ProfileCache for Player Skulls
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c97ded9f9ef1c550cca7d0a3a3b09a85e5999cdf
+index 0000000000000000000000000000000000000000..8625d60eb822f39140152f2f74ec5bfe5ecd0039
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java
-@@ -0,0 +1,79 @@
+@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ *
@@ -43,24 +43,24 @@ index 0000000000000000000000000000000000000000..c97ded9f9ef1c550cca7d0a3a3b09a85
+
+import com.destroystokyo.paper.profile.PlayerProfile;
+import com.destroystokyo.paper.profile.ProfileProperty;
++import java.util.Set;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
-+
-+import java.util.Set;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired once a profiles additional properties (such as textures) has been filled
+ */
++@NullMarked
+public class FillProfileEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final PlayerProfile profile;
++ private final PlayerProfile profile;
+
+ @ApiStatus.Internal
-+ public FillProfileEvent(@NotNull PlayerProfile profile) {
++ public FillProfileEvent(final PlayerProfile profile) {
+ super(!org.bukkit.Bukkit.isPrimaryThread());
+ this.profile = profile;
+ }
@@ -68,7 +68,6 @@ index 0000000000000000000000000000000000000000..c97ded9f9ef1c550cca7d0a3a3b09a85
+ /**
+ * @return The Profile that had properties filled
+ */
-+ @NotNull
+ public PlayerProfile getPlayerProfile() {
+ return this.profile;
+ }
@@ -76,31 +75,28 @@ index 0000000000000000000000000000000000000000..c97ded9f9ef1c550cca7d0a3a3b09a85
+ /**
+ * Same as .getPlayerProfile().getProperties()
+ *
-+ * @see PlayerProfile#getProperties()
+ * @return The new properties on the profile.
++ * @see PlayerProfile#getProperties()
+ */
-+ @NotNull
+ public Set<ProfileProperty> getProperties() {
+ return this.profile.getProperties();
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..e2a47c4af2c368a361e4a370a01111abe8e48062
+index 0000000000000000000000000000000000000000..177c23274d6dad709b05706117303b70ae8b4c7b
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java
-@@ -0,0 +1,81 @@
+@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ *
@@ -128,26 +124,26 @@ index 0000000000000000000000000000000000000000..e2a47c4af2c368a361e4a370a01111ab
+
+import com.destroystokyo.paper.profile.PlayerProfile;
+import com.destroystokyo.paper.profile.ProfileProperty;
++import java.util.Collection;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
-+
-+import java.util.Collection;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when the server is requesting to fill in properties of an incomplete profile, such as textures.
+ * <p>
+ * Allows plugins to pre-populate cached properties and avoid a call to the Mojang API
+ */
++@NullMarked
+public class PreFillProfileEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final PlayerProfile profile;
++ private final PlayerProfile profile;
+
+ @ApiStatus.Internal
-+ public PreFillProfileEvent(@NotNull PlayerProfile profile) {
++ public PreFillProfileEvent(final PlayerProfile profile) {
+ super(!org.bukkit.Bukkit.isPrimaryThread());
+ this.profile = profile;
+ }
@@ -155,7 +151,6 @@ index 0000000000000000000000000000000000000000..e2a47c4af2c368a361e4a370a01111ab
+ /**
+ * @return The profile that needs its properties filled
+ */
-+ @NotNull
+ public PlayerProfile getPlayerProfile() {
+ return this.profile;
+ }
@@ -163,21 +158,19 @@ index 0000000000000000000000000000000000000000..e2a47c4af2c368a361e4a370a01111ab
+ /**
+ * Sets the properties on the profile, avoiding the call to the Mojang API
+ * Same as .getPlayerProfile().setProperties(properties);
-+ *
-+ * @see PlayerProfile#setProperties(Collection)
++ *
+ * @param properties The properties to set/append
++ * @see PlayerProfile#setProperties(Collection)
+ */
-+ public void setProperties(@NotNull Collection<ProfileProperty> properties) {
++ public void setProperties(final Collection<ProfileProperty> properties) {
+ this.profile.setProperties(properties);
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0091-Add-legacy-ping-support-to-PaperServerListPingEvent.patch b/patches/api/0091-Add-legacy-ping-support-to-PaperServerListPingEvent.patch
index f21c766148..96ed5420a2 100644
--- a/patches/api/0091-Add-legacy-ping-support-to-PaperServerListPingEvent.patch
+++ b/patches/api/0091-Add-legacy-ping-support-to-PaperServerListPingEvent.patch
@@ -8,7 +8,7 @@ client that does not support all of the features provided in the
event.
diff --git a/src/main/java/com/destroystokyo/paper/network/StatusClient.java b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
-index 517d15238ed117f38bbd39f570874014cecf7bb5..ffda9f6a8b094942009aa78b331d22d9dcca2802 100644
+index 517d15238ed117f38bbd39f570874014cecf7bb5..a8437bbd80b3a20772352a3b1797990ea13806ad 100644
--- a/src/main/java/com/destroystokyo/paper/network/StatusClient.java
+++ b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
@@ -10,4 +10,16 @@ import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
@@ -17,7 +17,7 @@ index 517d15238ed117f38bbd39f570874014cecf7bb5..ffda9f6a8b094942009aa78b331d22d9
+ /**
+ * Returns whether the client is using an older version that doesn't
-+ * support all of the features in {@link PaperServerListPingEvent}.
++ * support all the features in {@link PaperServerListPingEvent}.
+ *
+ * <p>For Vanilla, this returns {@code true} for all clients older than 1.7.</p>
+ *
diff --git a/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch
index 1ba1794b5d..884983b69f 100644
--- a/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch
+++ b/patches/api/0098-Expand-World.spawnParticle-API-and-add-Builder.patch
@@ -10,46 +10,45 @@ This adds a new Builder API which is much friendlier to use.
diff --git a/src/main/java/com/destroystokyo/paper/ParticleBuilder.java b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
new file mode 100644
-index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c769aca67e
+index 0000000000000000000000000000000000000000..6c405755f4507d6fbc6c3877c611a7191206f3ff
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
-@@ -0,0 +1,609 @@
+@@ -0,0 +1,582 @@
+package com.destroystokyo.paper;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
++import java.util.Collection;
++import java.util.List;
+import org.bukkit.Color;
+import org.bukkit.Location;
+import org.bukkit.Particle;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.util.NumberConversions;
-+
-+import java.util.Collection;
-+import java.util.List;
-+import org.jetbrains.annotations.Contract;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Helps prepare a particle to be sent to players.
-+ *
++ * <p>
+ * Usage of the builder is preferred over the super long {@link World#spawnParticle(Particle, Location, int, double, double, double, double, Object)} API
+ */
++@NullMarked
+public class ParticleBuilder implements Cloneable {
+
+ private Particle particle;
-+ private List<Player> receivers;
-+ private Player source;
-+ private Location location;
++ private @Nullable List<Player> receivers;
++ private @Nullable Player source;
++ private @Nullable Location location;
+ private int count = 1;
+ private double offsetX = 0, offsetY = 0, offsetZ = 0;
+ private double extra = 1;
-+ private Object data;
++ private @Nullable Object data;
+ private boolean force = true;
+
-+ public ParticleBuilder(@NotNull Particle particle) {
++ public ParticleBuilder(final Particle particle) {
+ this.particle = particle;
+ }
+
@@ -59,14 +58,14 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ *
+ * @return a reference to this object.
+ */
-+ @NotNull
+ public ParticleBuilder spawn() {
+ if (this.location == null) {
+ throw new IllegalStateException("Please specify location for this particle");
+ }
-+ location.getWorld().spawnParticle(particle, receivers, source,
-+ location.getX(), location.getY(), location.getZ(),
-+ count, offsetX, offsetY, offsetZ, extra, data, force
++ this.location.getWorld().spawnParticle(
++ this.particle, this.receivers, this.source,
++ this.location.getX(), this.location.getY(), this.location.getZ(),
++ this.count, this.offsetX, this.offsetY, this.offsetZ, this.extra, this.data, this.force
+ );
+ return this;
+ }
@@ -74,9 +73,8 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ /**
+ * @return The particle going to be sent
+ */
-+ @NotNull
+ public Particle particle() {
-+ return particle;
++ return this.particle;
+ }
+
+ /**
@@ -85,8 +83,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param particle The particle
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder particle(@NotNull Particle particle) {
++ public ParticleBuilder particle(final Particle particle) {
+ this.particle = particle;
+ return this;
+ }
@@ -94,32 +91,30 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ /**
+ * @return List of players who will receive the particle, or null for all in world
+ */
-+ @Nullable
-+ public List<Player> receivers() {
-+ return receivers;
++ public @Nullable List<Player> receivers() {
++ return this.receivers;
+ }
+
+ /**
+ * Example use:
-+ *
++ * <p>
+ * builder.receivers(16); if (builder.hasReceivers()) { sendParticleAsync(builder); }
+ *
+ * @return If this particle is going to be sent to someone
+ */
+ public boolean hasReceivers() {
-+ return (receivers == null && !location.getWorld().getPlayers().isEmpty()) || (
-+ receivers != null && !receivers.isEmpty());
++ return (this.receivers == null && this.location != null && !this.location.getWorld().getPlayers().isEmpty()) || (
++ this.receivers != null && !this.receivers.isEmpty());
+ }
+
+ /**
-+ * Sends this particle to all players in the world. This is rather silly and you should likely not
++ * Sends this particle to all players in the world. This is rather silly, and you should likely not
+ * be doing this.
-+ *
++ * <p>
+ * Just be a logical person and use receivers by radius or collection.
+ *
+ * @return a reference to this object.
+ */
-+ @NotNull
+ public ParticleBuilder allPlayers() {
+ this.receivers = null;
+ return this;
@@ -127,11 +122,10 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+
+ /**
+ * @param receivers List of players to receive this particle, or null for all players in the
-+ * world
++ * world
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(@Nullable List<Player> receivers) {
++ public ParticleBuilder receivers(final @Nullable List<Player> receivers) {
+ // Had to keep this as we first made API List<> and not Collection, but removing this may break plugins compiled on older jars
+ // TODO: deprecate?
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
@@ -140,22 +134,20 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+
+ /**
+ * @param receivers List of players to receive this particle, or null for all players in the
-+ * world
++ * world
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(@Nullable Collection<Player> receivers) {
++ public ParticleBuilder receivers(final @Nullable Collection<Player> receivers) {
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
+ return this;
+ }
+
+ /**
-+ * @param receivers List of players to be receive this particle, or null for all players in the
-+ * world
++ * @param receivers List of players to receive this particle, or null for all players in the
++ * world
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(@Nullable Player... receivers) {
++ public ParticleBuilder receivers(final Player @Nullable... receivers) {
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
+ return this;
+ }
@@ -168,9 +160,8 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param radius amount to add on all axis
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(int radius) {
-+ return receivers(radius, radius);
++ public ParticleBuilder receivers(final int radius) {
++ return this.receivers(radius, radius);
+ }
+
+ /**
@@ -178,22 +169,24 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
+ * true, radius is tested by distance in a spherical shape
+ *
-+ * @param radius amount to add on each axis
++ * @param radius amount to add on each axis
+ * @param byDistance true to use a spherical radius, false to use a cuboid
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(int radius, boolean byDistance) {
++ public ParticleBuilder receivers(final int radius, final boolean byDistance) {
+ if (!byDistance) {
-+ return receivers(radius, radius, radius);
++ return this.receivers(radius, radius, radius);
+ } else {
++ if (this.location == null) {
++ throw new IllegalStateException("Please set location first");
++ }
+ this.receivers = Lists.newArrayList();
-+ for (Player nearbyPlayer : location.getWorld()
-+ .getNearbyPlayers(location, radius, radius, radius)) {
-+ Location loc = nearbyPlayer.getLocation();
-+ double x = NumberConversions.square(location.getX() - loc.getX());
-+ double y = NumberConversions.square(location.getY() - loc.getY());
-+ double z = NumberConversions.square(location.getZ() - loc.getZ());
++ for (final Player nearbyPlayer : this.location.getWorld()
++ .getNearbyPlayers(this.location, radius, radius, radius)) {
++ final Location loc = nearbyPlayer.getLocation();
++ final double x = NumberConversions.square(this.location.getX() - loc.getX());
++ final double y = NumberConversions.square(this.location.getY() - loc.getY());
++ final double z = NumberConversions.square(this.location.getZ() - loc.getZ());
+ if (Math.sqrt(x + y + z) > radius) {
+ continue;
+ }
@@ -210,12 +203,11 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * see {@link #receivers(int, boolean)}
+ *
+ * @param xzRadius amount to add on the x/z axis
-+ * @param yRadius amount to add on the y axis
++ * @param yRadius amount to add on the y axis
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(int xzRadius, int yRadius) {
-+ return receivers(xzRadius, yRadius, xzRadius);
++ public ParticleBuilder receivers(final int xzRadius, final int yRadius) {
++ return this.receivers(xzRadius, yRadius, xzRadius);
+ }
+
+ /**
@@ -223,25 +215,28 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
+ * true, radius is tested by distance on the y plane and on the x/z plane, in a cylinder shape.
+ *
-+ * @param xzRadius amount to add on the x/z axis
-+ * @param yRadius amount to add on the y axis
++ * @param xzRadius amount to add on the x/z axis
++ * @param yRadius amount to add on the y axis
+ * @param byDistance true to use a cylinder shape, false to use cuboid
+ * @return a reference to this object.
++ * @throws IllegalStateException if a location hasn't been specified yet
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(int xzRadius, int yRadius, boolean byDistance) {
++ public ParticleBuilder receivers(final int xzRadius, final int yRadius, final boolean byDistance) {
+ if (!byDistance) {
-+ return receivers(xzRadius, yRadius, xzRadius);
++ return this.receivers(xzRadius, yRadius, xzRadius);
+ } else {
++ if (this.location == null) {
++ throw new IllegalStateException("Please set location first");
++ }
+ this.receivers = Lists.newArrayList();
-+ for (Player nearbyPlayer : location.getWorld()
-+ .getNearbyPlayers(location, xzRadius, yRadius, xzRadius)) {
-+ Location loc = nearbyPlayer.getLocation();
++ for (final Player nearbyPlayer : this.location.getWorld()
++ .getNearbyPlayers(this.location, xzRadius, yRadius, xzRadius)) {
++ final Location loc = nearbyPlayer.getLocation();
+ if (Math.abs(loc.getY() - this.location.getY()) > yRadius) {
+ continue;
+ }
-+ double x = NumberConversions.square(location.getX() - loc.getX());
-+ double z = NumberConversions.square(location.getZ() - loc.getZ());
++ final double x = NumberConversions.square(this.location.getX() - loc.getX());
++ final double z = NumberConversions.square(this.location.getZ() - loc.getZ());
+ if (x + z > NumberConversions.square(xzRadius)) {
+ continue;
+ }
@@ -261,20 +256,18 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param zRadius amount to add on the z axis
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder receivers(int xRadius, int yRadius, int zRadius) {
-+ if (location == null) {
++ public ParticleBuilder receivers(final int xRadius, final int yRadius, final int zRadius) {
++ if (this.location == null) {
+ throw new IllegalStateException("Please set location first");
+ }
-+ return receivers(location.getWorld().getNearbyPlayers(location, xRadius, yRadius, zRadius));
++ return this.receivers(this.location.getWorld().getNearbyPlayers(this.location, xRadius, yRadius, zRadius));
+ }
+
+ /**
+ * @return The player considered the source of this particle (for Visibility concerns), or null
+ */
-+ @Nullable
-+ public Player source() {
-+ return source;
++ public @Nullable Player source() {
++ return this.source;
+ }
+
+ /**
@@ -283,8 +276,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param source The player who is considered the source
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder source(@Nullable Player source) {
++ public ParticleBuilder source(final @Nullable Player source) {
+ this.source = source;
+ return this;
+ }
@@ -292,9 +284,8 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ /**
+ * @return Location of where the particle will spawn
+ */
-+ @Nullable
-+ public Location location() {
-+ return location;
++ public @Nullable Location location() {
++ return this.location;
+ }
+
+ /**
@@ -303,8 +294,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param location The location of the particle
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder location(@NotNull Location location) {
++ public ParticleBuilder location(final Location location) {
+ this.location = location.clone();
+ return this;
+ }
@@ -313,13 +303,12 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * Sets the location of where to spawn the particle
+ *
+ * @param world World to spawn particle in
-+ * @param x X location
-+ * @param y Y location
-+ * @param z Z location
++ * @param x X location
++ * @param y Y location
++ * @param z Z location
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder location(@NotNull World world, double x, double y, double z) {
++ public ParticleBuilder location(final World world, final double x, final double y, final double z) {
+ this.location = new Location(world, x, y, z);
+ return this;
+ }
@@ -328,7 +317,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return Number of particles to spawn
+ */
+ public int count() {
-+ return count;
++ return this.count;
+ }
+
+ /**
@@ -337,8 +326,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param count Number of particles
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder count(int count) {
++ public ParticleBuilder count(final int count) {
+ this.count = count;
+ return this;
+ }
@@ -349,7 +337,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return Particle offset X.
+ */
+ public double offsetX() {
-+ return offsetX;
++ return this.offsetX;
+ }
+
+ /**
@@ -358,7 +346,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return Particle offset Y.
+ */
+ public double offsetY() {
-+ return offsetY;
++ return this.offsetY;
+ }
+
+ /**
@@ -367,7 +355,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return Particle offset Z.
+ */
+ public double offsetZ() {
-+ return offsetZ;
++ return this.offsetZ;
+ }
+
+ /**
@@ -378,8 +366,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param offsetZ Particle offset Z
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder offset(double offsetX, double offsetY, double offsetZ) {
++ public ParticleBuilder offset(final double offsetX, final double offsetY, final double offsetZ) {
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+ this.offsetZ = offsetZ;
@@ -392,7 +379,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return the extra particle data
+ */
+ public double extra() {
-+ return extra;
++ return this.extra;
+ }
+
+ /**
@@ -401,8 +388,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param extra the extra particle data
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder extra(double extra) {
++ public ParticleBuilder extra(final double extra) {
+ this.extra = extra;
+ return this;
+ }
@@ -413,21 +399,19 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param <T> The Particle data type
+ * @return the ParticleData for this particle
+ */
-+ @Nullable
-+ public <T> T data() {
++ public @Nullable <T> T data() {
+ //noinspection unchecked
-+ return (T) data;
++ return (T) this.data;
+ }
+
+ /**
+ * Sets the particle custom data. Varies by particle on how this is used
+ *
+ * @param data The new particle data
-+ * @param <T> The Particle data type
++ * @param <T> The Particle data type
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public <T> ParticleBuilder data(@Nullable T data) {
++ public <T> ParticleBuilder data(final @Nullable T data) {
+ this.data = data;
+ return this;
+ }
@@ -436,7 +420,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @return whether the particle is forcefully shown to players.
+ */
+ public boolean force() {
-+ return force;
++ return this.force;
+ }
+
+ /**
@@ -447,8 +431,7 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param force true to force, false for normal
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder force(boolean force) {
++ public ParticleBuilder force(final boolean force) {
+ this.force = force;
+ return this;
+ }
@@ -460,12 +443,11 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param color the new particle color
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder color(@Nullable Color color) {
-+ if (particle.getDataType() == Color.class) {
-+ return data(color);
++ public ParticleBuilder color(final @Nullable Color color) {
++ if (this.particle.getDataType() == Color.class) {
++ return this.data(color);
+ }
-+ return color(color, 1);
++ return this.color(color, 1);
+ }
+
+ /**
@@ -473,25 +455,24 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * Only valid for particles with a data type of {@link Particle.DustOptions}.
+ *
+ * @param color the new particle color
-+ * @param size the size of the particle
++ * @param size the size of the particle
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder color(@Nullable Color color, float size) {
-+ if (particle.getDataType() != Particle.DustOptions.class && color != null) {
++ public ParticleBuilder color(final @Nullable Color color, final float size) {
++ if (this.particle.getDataType() != Particle.DustOptions.class && color != null) {
+ throw new IllegalStateException("The combination of Color and size cannot be set on this particle type.");
+ }
+
+ // We don't officially support reusing these objects, but here we go
+ if (color == null) {
-+ if (data instanceof Particle.DustOptions) {
-+ return data(null);
++ if (this.data instanceof Particle.DustOptions) {
++ return this.data(null);
+ } else {
+ return this;
+ }
+ }
+
-+ return data(new Particle.DustOptions(color, size));
++ return this.data(new Particle.DustOptions(color, size));
+ }
+
+ /**
@@ -503,9 +484,8 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param b blue color component
+ * @return a reference to this object.
+ */
-+ @NotNull
-+ public ParticleBuilder color(int r, int g, int b) {
-+ return color(Color.fromRGB(r, g, b));
++ public ParticleBuilder color(final int r, final int g, final int b) {
++ return this.color(Color.fromRGB(r, g, b));
+ }
+
+ /**
@@ -519,13 +499,12 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * the color is treated as RGB. Otherwise, it is treated as ARGB.
+ * @return a reference to this object.
+ */
-+ @NotNull
+ public ParticleBuilder color(final int color) {
-+ int alpha = (color >> 24) & 0xFF;
++ final int alpha = (color >> 24) & 0xFF;
+ if (alpha == 0) {
-+ return color(Color.fromRGB(color));
++ return this.color(Color.fromRGB(color));
+ }
-+ return color(Color.fromARGB(color));
++ return this.color(Color.fromARGB(color));
+ }
+
+ /**
@@ -538,9 +517,8 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * @param b blue color component
+ * @return a reference to this object.
+ */
-+ @NotNull
+ public ParticleBuilder color(final int a, final int r, final int g, final int b) {
-+ return color(Color.fromARGB(a, r, g, b));
++ return this.color(Color.fromARGB(a, r, g, b));
+ }
+
+ /**
@@ -548,69 +526,64 @@ index 0000000000000000000000000000000000000000..970084a788ab5547d16a5e08d4e9d9c7
+ * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
+ *
+ * @param fromColor the new particle from color
-+ * @param toColor the new particle to color
++ * @param toColor the new particle to color
+ * @return a reference to this object.
+ * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
+ */
-+ @NotNull
-+ public ParticleBuilder colorTransition(@NotNull final Color fromColor, @NotNull final Color toColor) {
-+ return colorTransition(fromColor, toColor, 1);
++ public ParticleBuilder colorTransition(final Color fromColor, final Color toColor) {
++ return this.colorTransition(fromColor, toColor, 1);
+ }
+
+ /**
+ * Sets the particle Color Transition.
+ * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
+ *
-+ * @param fromRed red color component for the from color
-+ * @param fromGreen green color component for the from color
-+ * @param fromBlue blue color component for the from color
-+ * @param toRed red color component for the to color
-+ * @param toGreen green color component for the to color
-+ * @param toBlue blue color component for the to color
++ * @param fromRed red color component for the "from" color
++ * @param fromGreen green color component for the "from" color
++ * @param fromBlue blue color component for the "from" color
++ * @param toRed red color component for the to color
++ * @param toGreen green color component for the to color
++ * @param toBlue blue color component for the to color
+ * @return a reference to this object.
+ * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
+ */
-+ @NotNull
-+ public ParticleBuilder colorTransition(final int fromRed, final int fromGreen, final int fromBlue,
-+ final int toRed, final int toGreen, final int toBlue) {
-+ return colorTransition(Color.fromRGB(fromRed, fromGreen, fromBlue), Color.fromRGB(toRed, toGreen, toBlue));
++ public ParticleBuilder colorTransition(
++ final int fromRed, final int fromGreen, final int fromBlue,
++ final int toRed, final int toGreen, final int toBlue
++ ) {
++ return this.colorTransition(Color.fromRGB(fromRed, fromGreen, fromBlue), Color.fromRGB(toRed, toGreen, toBlue));
+ }
+
+ /**
+ * Sets the particle Color Transition.
+ * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
+ *
-+ * @param fromRgb an integer representing the red, green, and blue color components for the from color
-+ * @param toRgb an integer representing the red, green, and blue color components for the to color
++ * @param fromRgb an integer representing the red, green, and blue color components for the "from" color
++ * @param toRgb an integer representing the red, green, and blue color components for the "to" color
+ * @return a reference to this object.
+ * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
+ */
-+ @NotNull
+ public ParticleBuilder colorTransition(final int fromRgb, final int toRgb) {
-+ return colorTransition(Color.fromRGB(fromRgb), Color.fromRGB(toRgb));
++ return this.colorTransition(Color.fromRGB(fromRgb), Color.fromRGB(toRgb));
+ }
+
+ /**
+ * Sets the particle Color Transition and size.
+ * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
+ *
-+ * @param fromColor the new particle color for the from color.
-+ * @param toColor the new particle color for the to color.
-+ * @param size the size of the particle
++ * @param fromColor the new particle color for the "from" color.
++ * @param toColor the new particle color for the "to" color.
++ * @param size the size of the particle
+ * @return a reference to this object.
+ * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
+ */
-+ @NotNull
-+ public ParticleBuilder colorTransition(@NotNull final Color fromColor,
-+ @NotNull final Color toColor,
-+ final float size) {
++ public ParticleBuilder colorTransition(final Color fromColor, final Color toColor, final float size) {
+ Preconditions.checkArgument(fromColor != null, "Cannot define color transition with null fromColor.");
+ Preconditions.checkArgument(toColor != null, "Cannot define color transition with null toColor.");
+ Preconditions.checkArgument(this.particle() == Particle.DUST_COLOR_TRANSITION, "Can only define a color transition on particle DUST_COLOR_TRANSITION.");
-+ return data(new Particle.DustTransition(fromColor, toColor, size));
++ return this.data(new Particle.DustTransition(fromColor, toColor, size));
+ }
+
-+ @NotNull
+ @Override
+ public ParticleBuilder clone() {
+ try {
diff --git a/patches/api/0099-EndermanAttackPlayerEvent.patch b/patches/api/0099-EndermanAttackPlayerEvent.patch
index 25dc5e0c39..f3abe83e89 100644
--- a/patches/api/0099-EndermanAttackPlayerEvent.patch
+++ b/patches/api/0099-EndermanAttackPlayerEvent.patch
@@ -9,10 +9,10 @@ This allows you to override/extend the pumpkin/stare logic.
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..b261e0420002da3f94862e664edc65536cd05fc8
+index 0000000000000000000000000000000000000000..34adc77de2d1f06b2b10cc26b60240c6a3ef259c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
-@@ -0,0 +1,98 @@
+@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ *
@@ -103,6 +103,7 @@ index 0000000000000000000000000000000000000000..b261e0420002da3f94862e664edc6553
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0100-WitchConsumePotionEvent.patch b/patches/api/0100-WitchConsumePotionEvent.patch
index 3d69f2e148..3dd9e13cae 100644
--- a/patches/api/0100-WitchConsumePotionEvent.patch
+++ b/patches/api/0100-WitchConsumePotionEvent.patch
@@ -7,10 +7,10 @@ Fires when a witch consumes the potion in their hand
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..6476501ff3299686a059bb75a8ff2424db0cc7f8
+index 0000000000000000000000000000000000000000..43ee765dedf5001fadf1af317b6ab323fde34851
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
-@@ -0,0 +1,70 @@
+@@ -0,0 +1,71 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Witch;
@@ -73,6 +73,7 @@ index 0000000000000000000000000000000000000000..6476501ff3299686a059bb75a8ff2424
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0110-PlayerReadyArrowEvent.patch b/patches/api/0110-PlayerReadyArrowEvent.patch
index 95ee02ac10..3c432ede0a 100644
--- a/patches/api/0110-PlayerReadyArrowEvent.patch
+++ b/patches/api/0110-PlayerReadyArrowEvent.patch
@@ -8,10 +8,10 @@ Plugins can skip selection of certain arrows and control which is used.
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..f30c4c372c92a79fb6c3fe80c4b51b5c8c0d4d3b
+index 0000000000000000000000000000000000000000..3eadfae8860a4f6cde107cc3c7048368ade29d28
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
-@@ -0,0 +1,94 @@
+@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ *
@@ -42,21 +42,22 @@ index 0000000000000000000000000000000000000000..f30c4c372c92a79fb6c3fe80c4b51b5c
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player is firing a bow and the server is choosing an arrow to use.
+ */
++@NullMarked
+public class PlayerReadyArrowEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final ItemStack bow;
-+ @NotNull private final ItemStack arrow;
++ private final ItemStack bow;
++ private final ItemStack arrow;
+
+ private boolean cancelled;
+
-+ public PlayerReadyArrowEvent(@NotNull Player player, @NotNull ItemStack bow, @NotNull ItemStack arrow) {
++ public PlayerReadyArrowEvent(final Player player, final ItemStack bow, final ItemStack arrow) {
+ super(player);
+ this.bow = bow;
+ this.arrow = arrow;
@@ -65,7 +66,6 @@ index 0000000000000000000000000000000000000000..f30c4c372c92a79fb6c3fe80c4b51b5c
+ /**
+ * @return the player is using to fire the arrow
+ */
-+ @NotNull
+ public ItemStack getBow() {
+ return this.bow;
+ }
@@ -73,7 +73,6 @@ index 0000000000000000000000000000000000000000..f30c4c372c92a79fb6c3fe80c4b51b5c
+ /**
+ * @return the arrow that is attempting to be used
+ */
-+ @NotNull
+ public ItemStack getArrow() {
+ return this.arrow;
+ }
@@ -92,16 +91,15 @@ index 0000000000000000000000000000000000000000..f30c4c372c92a79fb6c3fe80c4b51b5c
+ * Cancel use of this arrow. On cancel, the server will try the next arrow available and fire another event.
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancelled = cancel;
++ public void setCancelled(final boolean cancel) {
++ this.cancelled = cancel;
+ }
+
-+ @NotNull
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0115-RangedEntity-API.patch b/patches/api/0115-RangedEntity-API.patch
index db1b32cc95..087c06057f 100644
--- a/patches/api/0115-RangedEntity-API.patch
+++ b/patches/api/0115-RangedEntity-API.patch
@@ -8,16 +8,17 @@ and to perform an attack.
diff --git a/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java
new file mode 100644
-index 0000000000000000000000000000000000000000..46e0e62d620def237dab44ad24708f1b93a8a1a7
+index 0000000000000000000000000000000000000000..09c82908f63233febfe1e07fe756f1c39d23d44f
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java
-@@ -0,0 +1,35 @@
+@@ -0,0 +1,36 @@
+package com.destroystokyo.paper.entity;
+
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Mob;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public interface RangedEntity extends Mob {
+ /**
+ * Attack the specified entity using a ranged attack.
@@ -26,7 +27,7 @@ index 0000000000000000000000000000000000000000..46e0e62d620def237dab44ad24708f1b
+ * @param charge How "charged" the attack is (how far back the bow was pulled for Bow attacks).
+ * This should be a value between 0 and 1, represented as targetDistance/maxDistance.
+ */
-+ void rangedAttack(@NotNull LivingEntity target, float charge);
++ void rangedAttack(LivingEntity target, float charge);
+
+ /**
+ * Sets that the Entity is "charging" up an attack, by raising its hands
@@ -44,7 +45,7 @@ index 0000000000000000000000000000000000000000..46e0e62d620def237dab44ad24708f1b
+ */
+ @Deprecated(since = "1.19.2")
+ default boolean isChargingAttack() {
-+ return isHandRaised();
++ return this.isHandRaised();
+ }
+}
diff --git a/src/main/java/org/bukkit/entity/AbstractSkeleton.java b/src/main/java/org/bukkit/entity/AbstractSkeleton.java
diff --git a/patches/api/0120-EnderDragon-Events.patch b/patches/api/0120-EnderDragon-Events.patch
index cb35387c0d..510edc18b9 100644
--- a/patches/api/0120-EnderDragon-Events.patch
+++ b/patches/api/0120-EnderDragon-Events.patch
@@ -86,10 +86,10 @@ index 0000000000000000000000000000000000000000..242eb9c07866365568c036819be2b4f8
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0d6409e3198e57dfa479abb6fee28d6028e13e2d
+index 0000000000000000000000000000000000000000..47cf33ef97ce1b92bc13c4d3a6c49d050e344eb1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
-@@ -0,0 +1,60 @@
+@@ -0,0 +1,61 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.AreaEffectCloud;
@@ -142,6 +142,7 @@ index 0000000000000000000000000000000000000000..0d6409e3198e57dfa479abb6fee28d60
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0121-PlayerElytraBoostEvent.patch b/patches/api/0121-PlayerElytraBoostEvent.patch
index fb24f9dbbf..b17cf589ac 100644
--- a/patches/api/0121-PlayerElytraBoostEvent.patch
+++ b/patches/api/0121-PlayerElytraBoostEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] PlayerElytraBoostEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a49cddca5
+index 0000000000000000000000000000000000000000..7d41a5c2dc6ca659bfad41e70cbeac2349c2b0f3
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java
-@@ -0,0 +1,104 @@
+@@ -0,0 +1,99 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.entity.Firework;
@@ -20,25 +20,25 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a player boosts elytra flight with a firework
+ */
++@NullMarked
+public class PlayerElytraBoostEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final ItemStack itemStack;
-+ @NotNull private final Firework firework;
++ private final ItemStack itemStack;
++ private final Firework firework;
+ private boolean consume = true;
-+ @NotNull
+ private final EquipmentSlot hand;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerElytraBoostEvent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull Firework firework, @NotNull EquipmentSlot hand) {
++ public PlayerElytraBoostEvent(final Player player, final ItemStack itemStack, final Firework firework, final EquipmentSlot hand) {
+ super(player);
+ this.itemStack = itemStack;
+ this.firework = firework;
@@ -50,7 +50,6 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+ *
+ * @return ItemStack of firework
+ */
-+ @NotNull
+ public ItemStack getItemStack() {
+ return this.itemStack;
+ }
@@ -60,7 +59,6 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+ *
+ * @return Firework entity
+ */
-+ @NotNull
+ public Firework getFirework() {
+ return this.firework;
+ }
@@ -79,7 +77,7 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+ *
+ * @param consume {@code true} to consume
+ */
-+ public void setShouldConsume(boolean consume) {
++ public void setShouldConsume(final boolean consume) {
+ this.consume = consume;
+ }
+
@@ -88,7 +86,6 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+ *
+ * @return interaction hand
+ */
-+ @NotNull
+ public EquipmentSlot getHand() {
+ return this.hand;
+ }
@@ -99,17 +96,15 @@ index 0000000000000000000000000000000000000000..9ebac41c22b8866df616020d409e5e1a
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0122-PlayerLaunchProjectileEvent.patch b/patches/api/0122-PlayerLaunchProjectileEvent.patch
index f284a611d1..9078e566ca 100644
--- a/patches/api/0122-PlayerLaunchProjectileEvent.patch
+++ b/patches/api/0122-PlayerLaunchProjectileEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] PlayerLaunchProjectileEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33e29020d7
+index 0000000000000000000000000000000000000000..a6d483e6be8b8527d7cfd676f6056179e8e9bf33
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java
-@@ -0,0 +1,95 @@
+@@ -0,0 +1,92 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.entity.Player;
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player shoots a projectile.
@@ -29,18 +29,19 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+ * of a bow or crossbow. A plugin may listen to {@link EntityShootBowEvent}
+ * for these actions instead.
+ */
++@NullMarked
+public class PlayerLaunchProjectileEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Projectile projectile;
-+ @NotNull private final ItemStack itemStack;
++ private final Projectile projectile;
++ private final ItemStack itemStack;
+ private boolean consumeItem = true;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerLaunchProjectileEvent(@NotNull Player shooter, @NotNull ItemStack itemStack, @NotNull Projectile projectile) {
++ public PlayerLaunchProjectileEvent(final Player shooter, final ItemStack itemStack, final Projectile projectile) {
+ super(shooter);
+ this.itemStack = itemStack;
+ this.projectile = projectile;
@@ -51,7 +52,6 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+ *
+ * @return the launched projectile
+ */
-+ @NotNull
+ public Projectile getProjectile() {
+ return this.projectile;
+ }
@@ -61,7 +61,6 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+ *
+ * @return The ItemStack used
+ */
-+ @NotNull
+ public ItemStack getItemStack() {
+ return this.itemStack;
+ }
@@ -80,7 +79,7 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+ *
+ * @param consumeItem {@code true} to consume
+ */
-+ public void setShouldConsume(boolean consumeItem) {
++ public void setShouldConsume(final boolean consumeItem) {
+ this.consumeItem = consumeItem;
+ }
+
@@ -90,17 +89,15 @@ index 0000000000000000000000000000000000000000..efd947eb0aa0633891d9c6a8bde66d33
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0127-AnvilDamageEvent.patch b/patches/api/0127-AnvilDamageEvent.patch
index 303e7bd6f1..2d984e06e6 100644
--- a/patches/api/0127-AnvilDamageEvent.patch
+++ b/patches/api/0127-AnvilDamageEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] AnvilDamageEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..456e2a638421b435ede4205d3eedfafeedb196c1
+index 0000000000000000000000000000000000000000..1472ecef11627d82f72911d86d579ad3bb365dca
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
-@@ -0,0 +1,148 @@
+@@ -0,0 +1,149 @@
+package com.destroystokyo.paper.event.block;
+
+import org.bukkit.Material;
@@ -95,6 +95,7 @@ index 0000000000000000000000000000000000000000..456e2a638421b435ede4205d3eedfafe
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0133-Slime-Pathfinder-Events.patch b/patches/api/0133-Slime-Pathfinder-Events.patch
index d1b62510b8..36e665a7d1 100644
--- a/patches/api/0133-Slime-Pathfinder-Events.patch
+++ b/patches/api/0133-Slime-Pathfinder-Events.patch
@@ -53,10 +53,10 @@ index 0000000000000000000000000000000000000000..a5d4442b53c4bd70165c3240c7dbd3d5
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SlimePathfindEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SlimePathfindEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..48963ce451c05f80ff13b4361e8aba196b629319
+index 0000000000000000000000000000000000000000..d481d116452fb5a702bc88a08da3c28cd0401a70
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimePathfindEvent.java
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,56 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Slime;
@@ -89,6 +89,7 @@ index 0000000000000000000000000000000000000000..48963ce451c05f80ff13b4361e8aba19
+ *
+ * @return The Slime that is pathfinding.
+ */
++ @Override
+ public Slime getEntity() {
+ return (Slime) super.getEntity();
+ }
@@ -103,6 +104,7 @@ index 0000000000000000000000000000000000000000..48963ce451c05f80ff13b4361e8aba19
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0135-Add-More-Creeper-API.patch b/patches/api/0135-Add-More-Creeper-API.patch
index 09a6c5d171..8e7c0d2ad1 100644
--- a/patches/api/0135-Add-More-Creeper-API.patch
+++ b/patches/api/0135-Add-More-Creeper-API.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add More Creeper API
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/CreeperIgniteEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/CreeperIgniteEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0c2f4f257b03d00c0ef1c50fdba6beb790fc808d
+index 0000000000000000000000000000000000000000..8b97cc830aa8bdb09dec3c4b8ebe4fb22d279f46
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/CreeperIgniteEvent.java
-@@ -0,0 +1,58 @@
+@@ -0,0 +1,60 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Creeper;
@@ -51,10 +51,12 @@ index 0000000000000000000000000000000000000000..0c2f4f257b03d00c0ef1c50fdba6beb7
+ this.ignited = ignited;
+ }
+
++ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
++ @Override
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
diff --git a/patches/api/0143-Mob-Pathfinding-API.patch b/patches/api/0143-Mob-Pathfinding-API.patch
index 1c0b6088a4..63c4c6770a 100644
--- a/patches/api/0143-Mob-Pathfinding-API.patch
+++ b/patches/api/0143-Mob-Pathfinding-API.patch
@@ -13,30 +13,28 @@ You can use EntityPathfindEvent to cancel new pathfinds from overriding your cur
diff --git a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
new file mode 100644
-index 0000000000000000000000000000000000000000..3c1e2c93d923a683cc0455af77c43784ef12270e
+index 0000000000000000000000000000000000000000..5f6d6e222f9f1ac1648a11b6d4a240371c4f07e9
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
-@@ -0,0 +1,220 @@
+@@ -0,0 +1,221 @@
+package com.destroystokyo.paper.entity;
+
++import java.util.List;
+import org.bukkit.Location;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Mob;
-+
-+import java.util.List;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Handles pathfinding operations for an Entity
+ */
++@NullMarked
+public interface Pathfinder {
+
+ /**
-+ *
+ * @return The entity that is controlled by this pathfinder
+ */
-+ @NotNull
+ Mob getEntity();
+
+ /**
@@ -46,6 +44,7 @@ index 0000000000000000000000000000000000000000..3c1e2c93d923a683cc0455af77c43784
+
+ /**
+ * If the entity is currently trying to navigate to a destination, this will return true
++ *
+ * @return true if the entity is navigating to a destination
+ */
+ boolean hasPath();
@@ -53,86 +52,88 @@ index 0000000000000000000000000000000000000000..3c1e2c93d923a683cc0455af77c43784
+ /**
+ * @return The location the entity is trying to navigate to, or null if there is no destination
+ */
-+ @Nullable
-+ PathResult getCurrentPath();
++ @Nullable PathResult getCurrentPath();
+
+ /**
+ * Calculates a destination for the Entity to navigate to, but does not set it
+ * as the current target. Useful for calculating what would happen before setting it.
++ *
+ * @param loc Location to navigate to
+ * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
+ */
-+ @Nullable PathResult findPath(@NotNull Location loc);
++ @Nullable PathResult findPath(Location loc);
+
+ /**
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
+ * but does not set it as the current target.
+ * Useful for calculating what would happen before setting it.
-+ *
++ * <p>
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
+ * result in the pathfinding automatically updating to follow the target Entity.
-+ *
++ * <p>
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
+ *
+ * @param target the Entity to navigate to
+ * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
+ */
-+ @Nullable PathResult findPath(@NotNull LivingEntity target);
++ @Nullable PathResult findPath(LivingEntity target);
+
+ /**
+ * Calculates a destination for the Entity to navigate to, and sets it with default speed
+ * as the current target.
++ *
+ * @param loc Location to navigate to
+ * @return If the pathfinding was successfully started
+ */
-+ default boolean moveTo(@NotNull Location loc) {
-+ return moveTo(loc, 1);
++ default boolean moveTo(Location loc) {
++ return this.moveTo(loc, 1);
+ }
+
+ /**
+ * Calculates a destination for the Entity to navigate to, with desired speed
+ * as the current target.
-+ * @param loc Location to navigate to
++ *
++ * @param loc Location to navigate to
+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
+ * @return If the pathfinding was successfully started
+ */
-+ default boolean moveTo(@NotNull Location loc, double speed) {
-+ PathResult path = findPath(loc);
-+ return path != null && moveTo(path, speed);
++ default boolean moveTo(Location loc, double speed) {
++ PathResult path = this.findPath(loc);
++ return path != null && this.moveTo(path, speed);
+ }
+
+ /**
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
+ * and sets it with default speed.
-+ *
++ * <p>
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
+ * result in the pathfinding automatically updating to follow the target Entity.
-+ *
++ * <p>
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
+ *
+ * @param target the Entity to navigate to
+ * @return If the pathfinding was successfully started
+ */
-+ default boolean moveTo(@NotNull LivingEntity target) {
-+ return moveTo(target, 1);
++ default boolean moveTo(LivingEntity target) {
++ return this.moveTo(target, 1);
+ }
+
+ /**
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
+ * and sets it with specified speed.
-+ *
++ * <p>
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
+ * result in the pathfinding automatically updating to follow the target Entity.
-+ *
++ * <p>
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
+ *
+ * @param target the Entity to navigate to
-+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
++ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
+ * @return If the pathfinding was successfully started
+ */
-+ default boolean moveTo(@NotNull LivingEntity target, double speed) {
-+ PathResult path = findPath(target);
-+ return path != null && moveTo(path, speed);
++ default boolean moveTo(LivingEntity target, double speed) {
++ PathResult path = this.findPath(target);
++ return path != null && this.moveTo(path, speed);
+ }
+
+ /**
@@ -142,19 +143,19 @@ index 0000000000000000000000000000000000000000..3c1e2c93d923a683cc0455af77c43784
+ * @param path The Path to start following
+ * @return If the pathfinding was successfully started
+ */
-+ default boolean moveTo(@NotNull PathResult path) {
-+ return moveTo(path, 1);
++ default boolean moveTo(PathResult path) {
++ return this.moveTo(path, 1);
+ }
+
+ /**
+ * Takes the result of a previous pathfinding calculation and sets it
+ * as the active pathfinding,
+ *
-+ * @param path The Path to start following
++ * @param path The Path to start following
+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
+ * @return If the pathfinding was successfully started
+ */
-+ boolean moveTo(@NotNull PathResult path, double speed);
++ boolean moveTo(PathResult path, double speed);
+
+ /**
+ * Checks if this pathfinder allows passing through closed doors.
@@ -205,11 +206,11 @@ index 0000000000000000000000000000000000000000..3c1e2c93d923a683cc0455af77c43784
+
+ /**
+ * All currently calculated points to follow along the path to reach the destination location
-+ *
++ * <p>
+ * Will return points the entity has already moved past, see {@link #getNextPointIndex()}
++ *
+ * @return List of points
+ */
-+ @NotNull
+ List<Location> getPoints();
+
+ /**
diff --git a/patches/api/0151-Turtle-API.patch b/patches/api/0151-Turtle-API.patch
index c15a3043f5..1d29a1055b 100644
--- a/patches/api/0151-Turtle-API.patch
+++ b/patches/api/0151-Turtle-API.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Turtle API
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/TurtleGoHomeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/TurtleGoHomeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..560b46b7b4fdd3394bc5e8fc917776a5838eba09
+index 0000000000000000000000000000000000000000..91cede0e53cf6f1089e549053ebc2e2b190a1aab
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleGoHomeEvent.java
-@@ -0,0 +1,51 @@
+@@ -0,0 +1,53 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Turtle;
@@ -39,6 +39,7 @@ index 0000000000000000000000000000000000000000..560b46b7b4fdd3394bc5e8fc917776a5
+ *
+ * @return The turtle
+ */
++ @Override
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@@ -53,6 +54,7 @@ index 0000000000000000000000000000000000000000..560b46b7b4fdd3394bc5e8fc917776a5
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
@@ -63,10 +65,10 @@ index 0000000000000000000000000000000000000000..560b46b7b4fdd3394bc5e8fc917776a5
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..d1b2bbb57280726690e704c5978d312d856243eb
+index 0000000000000000000000000000000000000000..1492d168aa1dc538b732b0ff262074cc7c9900e6
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java
-@@ -0,0 +1,88 @@
+@@ -0,0 +1,90 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@@ -102,6 +104,7 @@ index 0000000000000000000000000000000000000000..d1b2bbb57280726690e704c5978d312d
+ *
+ * @return The turtle
+ */
++ @Override
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@@ -147,6 +150,7 @@ index 0000000000000000000000000000000000000000..d1b2bbb57280726690e704c5978d312d
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
@@ -157,10 +161,10 @@ index 0000000000000000000000000000000000000000..d1b2bbb57280726690e704c5978d312d
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..4a53af5da307cd71e0e647917bec9be44136e6aa
+index 0000000000000000000000000000000000000000..a84101fb1b478f3018f283bc47d3e73a7ae5bbc8
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java
-@@ -0,0 +1,63 @@
+@@ -0,0 +1,65 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@@ -193,6 +197,7 @@ index 0000000000000000000000000000000000000000..4a53af5da307cd71e0e647917bec9be4
+ *
+ * @return The turtle
+ */
++ @Override
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@@ -216,6 +221,7 @@ index 0000000000000000000000000000000000000000..4a53af5da307cd71e0e647917bec9be4
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0152-Add-spectator-target-events.patch b/patches/api/0152-Add-spectator-target-events.patch
index 90f65b5fc8..ea32c2a4be 100644
--- a/patches/api/0152-Add-spectator-target-events.patch
+++ b/patches/api/0152-Add-spectator-target-events.patch
@@ -8,10 +8,10 @@ Subject: [PATCH] Add spectator target events
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerStartSpectatingEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerStartSpectatingEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208cce78e345
+index 0000000000000000000000000000000000000000..5ce2f30c094608cc547d2f2517f0ac2546bab85a
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerStartSpectatingEntityEvent.java
-@@ -0,0 +1,71 @@
+@@ -0,0 +1,68 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.entity.Entity;
@@ -20,22 +20,23 @@ index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208c
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Triggered when a player starts spectating an entity in spectator mode.
+ */
++@NullMarked
+public class PlayerStartSpectatingEntityEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Entity currentSpectatorTarget;
-+ @NotNull private final Entity newSpectatorTarget;
++ private final Entity currentSpectatorTarget;
++ private final Entity newSpectatorTarget;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerStartSpectatingEntityEvent(@NotNull Player player, @NotNull Entity currentSpectatorTarget, @NotNull Entity newSpectatorTarget) {
++ public PlayerStartSpectatingEntityEvent(final Player player, final Entity currentSpectatorTarget, final Entity newSpectatorTarget) {
+ super(player);
+ this.currentSpectatorTarget = currentSpectatorTarget;
+ this.newSpectatorTarget = newSpectatorTarget;
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208c
+ *
+ * @return The entity the player is currently spectating (before they start spectating the new target).
+ */
-+ @NotNull
+ public Entity getCurrentSpectatorTarget() {
+ return this.currentSpectatorTarget;
+ }
@@ -56,7 +56,6 @@ index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208c
+ *
+ * @return The entity the player is now going to be spectating.
+ */
-+ @NotNull
+ public Entity getNewSpectatorTarget() {
+ return this.newSpectatorTarget;
+ }
@@ -67,17 +66,15 @@ index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208c
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@@ -85,10 +82,10 @@ index 0000000000000000000000000000000000000000..a70a64d2273414d95d77e601a41a208c
+
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerStopSpectatingEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerStopSpectatingEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a6a5ebc534cc380740ba42790149c8b85f52aabb
+index 0000000000000000000000000000000000000000..ebda87b7914995a28abce844654ee4f5089c416e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerStopSpectatingEntityEvent.java
-@@ -0,0 +1,57 @@
+@@ -0,0 +1,55 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.entity.Entity;
@@ -97,20 +94,21 @@ index 0000000000000000000000000000000000000000..a6a5ebc534cc380740ba42790149c8b8
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Triggered when a player stops spectating an entity in spectator mode.
+ */
++@NullMarked
+public class PlayerStopSpectatingEntityEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Entity spectatorTarget;
++ private final Entity spectatorTarget;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerStopSpectatingEntityEvent(@NotNull Player player, @NotNull Entity spectatorTarget) {
++ public PlayerStopSpectatingEntityEvent(final Player player, final Entity spectatorTarget) {
+ super(player);
+ this.spectatorTarget = spectatorTarget;
+ }
@@ -120,7 +118,6 @@ index 0000000000000000000000000000000000000000..a6a5ebc534cc380740ba42790149c8b8
+ *
+ * @return The entity the player is currently spectating (before they will stop).
+ */
-+ @NotNull
+ public Entity getSpectatorTarget() {
+ return this.spectatorTarget;
+ }
@@ -131,17 +128,15 @@ index 0000000000000000000000000000000000000000..a6a5ebc534cc380740ba42790149c8b8
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0164-Add-PlayerPostRespawnEvent.patch b/patches/api/0164-Add-PlayerPostRespawnEvent.patch
index c261fc7375..90bb07b46a 100644
--- a/patches/api/0164-Add-PlayerPostRespawnEvent.patch
+++ b/patches/api/0164-Add-PlayerPostRespawnEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerPostRespawnEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..16961aac061e78fb84029f8435ab5f7c493b1362
+index 0000000000000000000000000000000000000000..e82446ec3d706c47ac9a544f70d0c19b658665d5
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java
-@@ -0,0 +1,56 @@
+@@ -0,0 +1,54 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.Location;
@@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..16961aac061e78fb84029f8435ab5f7c
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired after a player has respawned
+ */
++@NullMarked
+public class PlayerPostRespawnEvent extends PlayerEvent {
+
-+ private final static HandlerList HANDLER_LIST = new HandlerList();
++ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Location respawnedLocation;
+ private final boolean isBedSpawn;
+
+ @ApiStatus.Internal
-+ public PlayerPostRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnedLocation, final boolean isBedSpawn) {
++ public PlayerPostRespawnEvent(final Player respawnPlayer, final Location respawnedLocation, final boolean isBedSpawn) {
+ super(respawnPlayer);
+ this.respawnedLocation = respawnedLocation;
+ this.isBedSpawn = isBedSpawn;
@@ -41,7 +42,6 @@ index 0000000000000000000000000000000000000000..16961aac061e78fb84029f8435ab5f7c
+ *
+ * @return location of the respawned player
+ */
-+ @NotNull
+ public Location getRespawnedLocation() {
+ return this.respawnedLocation.clone();
+ }
@@ -56,12 +56,10 @@ index 0000000000000000000000000000000000000000..16961aac061e78fb84029f8435ab5f7c
+ }
+
+ @Override
-+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0167-Server-Tick-Events.patch b/patches/api/0167-Server-Tick-Events.patch
index fc84bb269f..dd0e4b3def 100644
--- a/patches/api/0167-Server-Tick-Events.patch
+++ b/patches/api/0167-Server-Tick-Events.patch
@@ -7,10 +7,10 @@ Fires event at start and end of a server tick
diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerTickEndEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerTickEndEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..15a177ce555ed329988d97a9f0b5d9c71aea18fb
+index 0000000000000000000000000000000000000000..c879588693c930226049e60393f2f23aad1588b9
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerTickEndEvent.java
-@@ -0,0 +1,61 @@
+@@ -0,0 +1,62 @@
+package com.destroystokyo.paper.event.server;
+
+import org.bukkit.event.Event;
@@ -64,6 +64,7 @@ index 0000000000000000000000000000000000000000..15a177ce555ed329988d97a9f0b5d9c7
+ return this.timeEnd - System.nanoTime();
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
@@ -74,10 +75,10 @@ index 0000000000000000000000000000000000000000..15a177ce555ed329988d97a9f0b5d9c7
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerTickStartEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerTickStartEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..7c15e6487e17b3255e2428d73aef344ee32a43fd
+index 0000000000000000000000000000000000000000..890153657ea5b756a8a3a038d6b53857e0d17fea
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerTickStartEvent.java
-@@ -0,0 +1,34 @@
+@@ -0,0 +1,35 @@
+package com.destroystokyo.paper.event.server;
+
+import org.bukkit.event.Event;
@@ -104,6 +105,7 @@ index 0000000000000000000000000000000000000000..7c15e6487e17b3255e2428d73aef344e
+ return this.tickNumber;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0178-Entity-Jump-API.patch b/patches/api/0178-Entity-Jump-API.patch
index 5fd295056d..6cd58f786f 100644
--- a/patches/api/0178-Entity-Jump-API.patch
+++ b/patches/api/0178-Entity-Jump-API.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Entity Jump API
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityJumpEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityJumpEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..1f1c159db2095733a585e102f34c2b657ca82dc2
+index 0000000000000000000000000000000000000000..b49b72608573ad5b98fc6e0070f6ef105bf177e4
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityJumpEvent.java
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,50 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.LivingEntity;
@@ -41,10 +41,12 @@ index 0000000000000000000000000000000000000000..1f1c159db2095733a585e102f34c2b65
+ return (LivingEntity) super.getEntity();
+ }
+
++ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
++ @Override
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
diff --git a/patches/api/0183-Add-Player-Client-Options-API.patch b/patches/api/0183-Add-Player-Client-Options-API.patch
index 485335d7ee..56be6b483b 100644
--- a/patches/api/0183-Add-Player-Client-Options-API.patch
+++ b/patches/api/0183-Add-Player-Client-Options-API.patch
@@ -6,18 +6,18 @@ Subject: [PATCH] Add Player Client Options API
diff --git a/src/main/java/com/destroystokyo/paper/ClientOption.java b/src/main/java/com/destroystokyo/paper/ClientOption.java
new file mode 100644
-index 0000000000000000000000000000000000000000..f89bfeba29e6988db849957a508ca97ff5322242
+index 0000000000000000000000000000000000000000..ed08f823e0620289392f7fc2ff0ac721cff60478
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/ClientOption.java
-@@ -0,0 +1,52 @@
+@@ -0,0 +1,51 @@
+package com.destroystokyo.paper;
+
+import net.kyori.adventure.translation.Translatable;
+import net.kyori.adventure.util.Index;
-+import org.jetbrains.annotations.NotNull;
-+
+import org.bukkit.inventory.MainHand;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public final class ClientOption<T> {
+
+ public static final ClientOption<SkinParts> SKIN_PARTS = new ClientOption<>(SkinParts.class);
@@ -31,13 +31,12 @@ index 0000000000000000000000000000000000000000..f89bfeba29e6988db849957a508ca97f
+
+ private final Class<T> type;
+
-+ private ClientOption(@NotNull Class<T> type) {
++ private ClientOption(final Class<T> type) {
+ this.type = type;
+ }
+
-+ @NotNull
+ public Class<T> getType() {
-+ return type;
++ return this.type;
+ }
+
+ public enum ChatVisibility implements Translatable {
@@ -46,15 +45,15 @@ index 0000000000000000000000000000000000000000..f89bfeba29e6988db849957a508ca97f
+ HIDDEN("hidden"),
+ UNKNOWN("unknown");
+
-+ public static Index<String, ChatVisibility> NAMES = Index.create(ChatVisibility.class, chatVisibility -> chatVisibility.name);
++ public static final Index<String, ChatVisibility> NAMES = Index.create(ChatVisibility.class, chatVisibility -> chatVisibility.name);
+ private final String name;
+
-+ ChatVisibility(String name) {
++ ChatVisibility(final String name) {
+ this.name = name;
+ }
+
+ @Override
-+ public @NotNull String translationKey() {
++ public String translationKey() {
+ if (this == UNKNOWN) {
+ throw new UnsupportedOperationException(this.name + " doesn't have a translation key");
+ }
@@ -90,27 +89,27 @@ index 0000000000000000000000000000000000000000..4a0c39405d4fbed457787e3c6ded4cc6
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6aea591ae5
+index 0000000000000000000000000000000000000000..6cf6aa876278d0d3e75148608951fc5865ad5aee
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java
-@@ -0,0 +1,136 @@
+@@ -0,0 +1,130 @@
+package com.destroystokyo.paper.event.player;
+
+import com.destroystokyo.paper.ClientOption;
+import com.destroystokyo.paper.ClientOption.ChatVisibility;
+import com.destroystokyo.paper.SkinParts;
++import java.util.Map;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.MainHand;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Map;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the player changes their client settings
+ */
++@NullMarked
+public class PlayerClientOptionsChangeEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -125,7 +124,7 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ private final boolean textFilteringEnabled;
+
+ @Deprecated
-+ public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull String locale, int viewDistance, @NotNull ChatVisibility chatVisibility, boolean chatColors, @NotNull SkinParts skinParts, @NotNull MainHand mainHand) {
++ public PlayerClientOptionsChangeEvent(final Player player, final String locale, final int viewDistance, final ChatVisibility chatVisibility, final boolean chatColors, final SkinParts skinParts, final MainHand mainHand) {
+ super(player);
+ this.locale = locale;
+ this.viewDistance = viewDistance;
@@ -138,7 +137,7 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ }
+
+ @ApiStatus.Internal
-+ public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull Map<ClientOption<?>, ?> options) {
++ public PlayerClientOptionsChangeEvent(final Player player, final Map<ClientOption<?>, ?> options) {
+ super(player);
+
+ this.locale = (String) options.get(ClientOption.LOCALE);
@@ -151,7 +150,6 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ this.textFilteringEnabled = (boolean) options.get(ClientOption.TEXT_FILTERING_ENABLED);
+ }
+
-+ @NotNull
+ public String getLocale() {
+ return this.locale;
+ }
@@ -168,7 +166,6 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ return this.viewDistance != this.player.getClientOption(ClientOption.VIEW_DISTANCE);
+ }
+
-+ @NotNull
+ public ChatVisibility getChatVisibility() {
+ return this.chatVisibility;
+ }
@@ -185,7 +182,6 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ return this.chatColors != this.player.getClientOption(ClientOption.CHAT_COLORS_ENABLED);
+ }
+
-+ @NotNull
+ public SkinParts getSkinParts() {
+ return this.skinparts;
+ }
@@ -194,7 +190,6 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ return this.skinparts.getRaw() != this.player.getClientOption(ClientOption.SKIN_PARTS).getRaw();
+ }
+
-+ @NotNull
+ public MainHand getMainHand() {
+ return this.mainHand;
+ }
@@ -220,12 +215,10 @@ index 0000000000000000000000000000000000000000..1757055d821d9ec7c728aa6c1b52fa6a
+ }
+
+ @Override
-+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0184-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/api/0184-Add-PlayerAttackEntityCooldownResetEvent.patch
index c3cfd0642b..3d2999a705 100644
--- a/patches/api/0184-Add-PlayerAttackEntityCooldownResetEvent.patch
+++ b/patches/api/0184-Add-PlayerAttackEntityCooldownResetEvent.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerAttackEntityCooldownResetEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerAttackEntityCooldownResetEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..5ceaff1a499d08575ddcdcbead8e2cef6cfbea47
+index 0000000000000000000000000000000000000000..2cd5c9c344cacbabe64dae8ec87babb506b5fb09
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerAttackEntityCooldownResetEvent.java
@@ -0,0 +1,77 @@
@@ -18,22 +18,23 @@ index 0000000000000000000000000000000000000000..5ceaff1a499d08575ddcdcbead8e2cef
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when processing a player's attack on an entity when the player's attack strength cooldown is reset
+ */
++@NullMarked
+public class PlayerAttackEntityCooldownResetEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final Entity attackedEntity;
++ private final Entity attackedEntity;
+ private final float cooledAttackStrength;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerAttackEntityCooldownResetEvent(@NotNull Player player, @NotNull Entity attackedEntity, float cooledAttackStrength) {
++ public PlayerAttackEntityCooldownResetEvent(final Player player, final Entity attackedEntity, final float cooledAttackStrength) {
+ super(player);
+ this.attackedEntity = attackedEntity;
+ this.cooledAttackStrength = cooledAttackStrength;
@@ -53,7 +54,6 @@ index 0000000000000000000000000000000000000000..5ceaff1a499d08575ddcdcbead8e2cef
+ *
+ * @return the entity attacked by the player
+ */
-+ @NotNull
+ public Entity getAttackedEntity() {
+ return this.attackedEntity;
+ }
@@ -74,16 +74,16 @@ index 0000000000000000000000000000000000000000..5ceaff1a499d08575ddcdcbead8e2cef
+ * Cancelling this event will prevent the target player from having their cooldown reset from attacking this entity
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ public static @NotNull HandlerList getHandlerList() {
++ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/patches/api/0187-Add-Mob-Goal-API.patch b/patches/api/0187-Add-Mob-Goal-API.patch
index 4cc271dda3..142c4e4f70 100644
--- a/patches/api/0187-Add-Mob-Goal-API.patch
+++ b/patches/api/0187-Add-Mob-Goal-API.patch
@@ -6,21 +6,20 @@ Subject: [PATCH] Add Mob Goal API
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java b/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c57c5416c88e2070a082403ab0dda9d7f08d2a57
+index 0000000000000000000000000000000000000000..88f64a84c6b81246a4936e37c9f0410eefc847fd
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/Goal.java
-@@ -0,0 +1,66 @@
+@@ -0,0 +1,63 @@
+package com.destroystokyo.paper.entity.ai;
+
-+import org.jetbrains.annotations.NotNull;
-+
+import java.util.EnumSet;
-+
+import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Represents an AI goal of an entity
+ */
++@NullMarked
+public interface Goal<T extends Mob> {
+
+ /**
@@ -36,7 +35,7 @@ index 0000000000000000000000000000000000000000..c57c5416c88e2070a082403ab0dda9d7
+ * @return if this goal should stay active
+ */
+ default boolean shouldStayActive() {
-+ return shouldActivate();
++ return this.shouldActivate();
+ }
+
+ /**
@@ -63,86 +62,79 @@ index 0000000000000000000000000000000000000000..c57c5416c88e2070a082403ab0dda9d7
+ *
+ * @return the goal key
+ */
-+ @NotNull
+ GoalKey<T> getKey();
+
+ /**
+ * Returns a list of all applicable flags for this goal.<br>
-+ *
++ * <p>
+ * This method is only called on construction.
+ *
+ * @return the subtypes.
+ */
-+ @NotNull
+ EnumSet<GoalType> getTypes();
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java b/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9cd98c6fcfa3eb439d9013ef76ef4661175a0e5a
+index 0000000000000000000000000000000000000000..fb626065c642a3f43075f2ae751419e23431763c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java
-@@ -0,0 +1,64 @@
+@@ -0,0 +1,59 @@
+package com.destroystokyo.paper.entity.ai;
+
+import com.google.common.base.Objects;
-+
-+import org.jetbrains.annotations.NotNull;
-+
+import java.util.StringJoiner;
-+
+import org.bukkit.NamespacedKey;
+import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
-+ *
+ * Used to identify a Goal. Consists of a {@link NamespacedKey} and the type of mob the goal can be applied to
+ *
+ * @param <T> the type of mob the goal can be applied to
+ */
-+public class GoalKey<T extends Mob> {
++@NullMarked
++public final class GoalKey<T extends Mob> {
+
+ private final Class<T> entityClass;
+ private final NamespacedKey namespacedKey;
+
-+ private GoalKey(@NotNull Class<T> entityClass, @NotNull NamespacedKey namespacedKey) {
++ private GoalKey(Class<T> entityClass, NamespacedKey namespacedKey) {
+ this.entityClass = entityClass;
+ this.namespacedKey = namespacedKey;
+ }
+
-+ @NotNull
+ public Class<T> getEntityClass() {
-+ return entityClass;
++ return this.entityClass;
+ }
+
-+ @NotNull
+ public NamespacedKey getNamespacedKey() {
-+ return namespacedKey;
++ return this.namespacedKey;
+ }
+
+ @Override
-+ public boolean equals(Object o) {
++ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
-+ if (o == null || getClass() != o.getClass()) return false;
++ if (o == null || this.getClass() != o.getClass()) return false;
+ GoalKey<?> goalKey = (GoalKey<?>) o;
-+ return Objects.equal(entityClass, goalKey.entityClass) &&
-+ Objects.equal(namespacedKey, goalKey.namespacedKey);
++ return Objects.equal(this.entityClass, goalKey.entityClass) &&
++ Objects.equal(this.namespacedKey, goalKey.namespacedKey);
+ }
+
+ @Override
+ public int hashCode() {
-+ return Objects.hashCode(entityClass, namespacedKey);
++ return Objects.hashCode(this.entityClass, this.namespacedKey);
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", GoalKey.class.getSimpleName() + "[", "]")
-+ .add("entityClass=" + entityClass)
-+ .add("namespacedKey=" + namespacedKey)
++ .add("entityClass=" + this.entityClass)
++ .add("namespacedKey=" + this.namespacedKey)
+ .toString();
+ }
+
-+ @NotNull
-+ public static <A extends Mob> GoalKey<A> of(@NotNull Class<A> entityClass, @NotNull NamespacedKey namespacedKey) {
++ public static <A extends Mob> GoalKey<A> of(Class<A> entityClass, NamespacedKey namespacedKey) {
+ return new GoalKey<>(entityClass, namespacedKey);
+ }
+}
@@ -171,59 +163,51 @@ index 0000000000000000000000000000000000000000..7024c8f484d2460abf3abfe65a29771d
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java
new file mode 100644
-index 0000000000000000000000000000000000000000..e21f7574763dd4f13794f91bbef192ef66a8f5e9
+index 0000000000000000000000000000000000000000..0203e7efbb8c729ed378c53c2630a523b697314f
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoals.java
-@@ -0,0 +1,50 @@
+@@ -0,0 +1,42 @@
+package com.destroystokyo.paper.entity.ai;
+
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
-+
+import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Represents a part of the "brain" of a mob. It tracks all tasks (running or not), allows adding and removing goals
+ */
++@NullMarked
+public interface MobGoals {
+
-+ <T extends Mob> void addGoal(@NotNull T mob, int priority, @NotNull Goal<T> goal);
++ <T extends Mob> void addGoal(T mob, int priority, Goal<T> goal);
+
-+ <T extends Mob> void removeGoal(@NotNull T mob, @NotNull Goal<T> goal);
++ <T extends Mob> void removeGoal(T mob, Goal<T> goal);
+
-+ <T extends Mob> void removeAllGoals(@NotNull T mob);
++ <T extends Mob> void removeAllGoals(T mob);
+
-+ <T extends Mob> void removeAllGoals(@NotNull T mob, @NotNull GoalType type);
++ <T extends Mob> void removeAllGoals(T mob, GoalType type);
+
-+ <T extends Mob> void removeGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++ <T extends Mob> void removeGoal(T mob, GoalKey<T> key);
+
-+ <T extends Mob> boolean hasGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++ <T extends Mob> boolean hasGoal(T mob, GoalKey<T> key);
+
-+ @Nullable
-+ <T extends Mob> Goal<T> getGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++ <T extends Mob> @Nullable Goal<T> getGoal(T mob, GoalKey<T> key);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getGoals(@NotNull T mob, @NotNull GoalKey<T> key);
++ <T extends Mob> Collection<Goal<T>> getGoals(T mob, GoalKey<T> key);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob);
++ <T extends Mob> Collection<Goal<T>> getAllGoals(T mob);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob, @NotNull GoalType type);
++ <T extends Mob> Collection<Goal<T>> getAllGoals(T mob, GoalType type);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getAllGoalsWithout(@NotNull T mob, @NotNull GoalType type);
++ <T extends Mob> Collection<Goal<T>> getAllGoalsWithout(T mob, GoalType type);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob);
++ <T extends Mob> Collection<Goal<T>> getRunningGoals(T mob);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob, @NotNull GoalType type);
++ <T extends Mob> Collection<Goal<T>> getRunningGoals(T mob, GoalType type);
+
-+ @NotNull
-+ <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(@NotNull T mob, @NotNull GoalType type);
++ <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(T mob, GoalType type);
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 54626b927444ab3fc6b7d9ac9e326ff368b0cd25..1a671331ec4ab21430d7d52e9a4f45510ef39944 100644
diff --git a/patches/api/0188-Add-villager-reputation-API.patch b/patches/api/0188-Add-villager-reputation-API.patch
index 407a8007aa..fc368610e2 100644
--- a/patches/api/0188-Add-villager-reputation-API.patch
+++ b/patches/api/0188-Add-villager-reputation-API.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add villager reputation API
diff --git a/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java b/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593f6fa74be
+index 0000000000000000000000000000000000000000..f16294ef3148f8671389fa097e3e369a046e48cf
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/villager/Reputation.java
-@@ -0,0 +1,57 @@
+@@ -0,0 +1,58 @@
+package com.destroystokyo.paper.entity.villager;
+
+import com.google.common.base.Preconditions;
@@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593
+import java.util.EnumMap;
+import java.util.Map;
+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * A reputation score for a player on a villager.
+ */
++@NullMarked
+public final class Reputation {
+
-+ @NotNull
+ private final Map<ReputationType, Integer> reputation;
+
+ public Reputation() {
+ this(new EnumMap<>(ReputationType.class));
+ }
+
-+ public Reputation(@NotNull Map<ReputationType, Integer> reputation) {
++ public Reputation(Map<ReputationType, Integer> reputation) {
+ Preconditions.checkNotNull(reputation, "reputation cannot be null");
+ this.reputation = reputation;
+ }
@@ -41,7 +42,7 @@ index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593
+ * @param type The {@link ReputationType type} of reputation to get.
+ * @return The value of the {@link ReputationType type}.
+ */
-+ public int getReputation(@NotNull ReputationType type) {
++ public int getReputation(ReputationType type) {
+ Preconditions.checkNotNull(type, "the reputation type cannot be null");
+ return this.reputation.getOrDefault(type, 0);
+ }
@@ -52,7 +53,7 @@ index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593
+ * @param type The {@link ReputationType type} of reputation to set.
+ * @param value The value of the {@link ReputationType type}.
+ */
-+ public void setReputation(@NotNull ReputationType type, int value) {
++ public void setReputation(ReputationType type, int value) {
+ Preconditions.checkNotNull(type, "the reputation type cannot be null");
+ this.reputation.put(type, value);
+ }
@@ -63,7 +64,7 @@ index 0000000000000000000000000000000000000000..0a69e21b0b3001c9cc50951b4b8bd593
+ * @param type The {@link ReputationType type} to check
+ * @return If there is a value for this {@link ReputationType type} set.
+ */
-+ public boolean hasReputationSet(@NotNull ReputationType type) {
++ public boolean hasReputationSet(ReputationType type) {
+ return this.reputation.containsKey(type);
+ }
+}
diff --git a/patches/api/0192-Add-and-implement-PlayerRecipeBookClickEvent.patch b/patches/api/0192-Add-and-implement-PlayerRecipeBookClickEvent.patch
index 4fe75c486c..f0a90f1200 100644
--- a/patches/api/0192-Add-and-implement-PlayerRecipeBookClickEvent.patch
+++ b/patches/api/0192-Add-and-implement-PlayerRecipeBookClickEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add and implement PlayerRecipeBookClickEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerRecipeBookClickEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerRecipeBookClickEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff34c9d192
+index 0000000000000000000000000000000000000000..a7becccb2cf3b72744fcac4efa52d7c61e607765
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerRecipeBookClickEvent.java
-@@ -0,0 +1,89 @@
+@@ -0,0 +1,87 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.NamespacedKey;
@@ -18,22 +18,23 @@ index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player clicks a recipe in the recipe book
+ */
++@NullMarked
+public class PlayerRecipeBookClickEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private NamespacedKey recipe;
++ private NamespacedKey recipe;
+ private boolean makeAll;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerRecipeBookClickEvent(@NotNull Player player, @NotNull NamespacedKey recipe, boolean makeAll) {
++ public PlayerRecipeBookClickEvent(final Player player, final NamespacedKey recipe, final boolean makeAll) {
+ super(player);
+ this.recipe = recipe;
+ this.makeAll = makeAll;
@@ -44,7 +45,6 @@ index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff
+ *
+ * @return The namespaced key of the recipe
+ */
-+ @NotNull
+ public NamespacedKey getRecipe() {
+ return this.recipe;
+ }
@@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff
+ *
+ * @param recipe The key of the recipe that should be requested
+ */
-+ public void setRecipe(@NotNull NamespacedKey recipe) {
++ public void setRecipe(final NamespacedKey recipe) {
+ this.recipe = recipe;
+ }
+
@@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff
+ *
+ * @param makeAll {@code true} if the request should attempt to make the maximum amount of results
+ */
-+ public void setMakeAll(boolean makeAll) {
++ public void setMakeAll(final boolean makeAll) {
+ this.makeAll = makeAll;
+ }
+
@@ -84,17 +84,15 @@ index 0000000000000000000000000000000000000000..c38ac6d0e0ac4ecbdc73d2bedd7731ff
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0196-Add-PrepareResultEvent-PrepareGrindstoneEvent.patch b/patches/api/0196-Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
index c16892f588..5bcc9f3d0b 100644
--- a/patches/api/0196-Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
+++ b/patches/api/0196-Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
@@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..f75933948cdf0aa0c9bb2f06da5418f1
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/inventory/PrepareResultEvent.java b/src/main/java/com/destroystokyo/paper/event/inventory/PrepareResultEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..5ae8b843f78b22e300de0202fb800fcae6ff49b0
+index 0000000000000000000000000000000000000000..8ca7858613bb78ee1f9453b55fc38e00414fefb5
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/inventory/PrepareResultEvent.java
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,42 @@
+package com.destroystokyo.paper.event.inventory;
+
+import org.bukkit.event.inventory.PrepareInventoryResultEvent;
@@ -79,6 +79,7 @@ index 0000000000000000000000000000000000000000..5ae8b843f78b22e300de0202fb800fca
+ *
+ * @return result item
+ */
++ @Override
+ public @Nullable ItemStack getResult() {
+ return super.getResult();
+ }
@@ -88,6 +89,7 @@ index 0000000000000000000000000000000000000000..5ae8b843f78b22e300de0202fb800fca
+ *
+ * @param result result item
+ */
++ @Override
+ public void setResult(final @Nullable ItemStack result) {
+ super.setResult(result);
+ }
diff --git a/patches/api/0216-Add-PlayerItemCooldownEvent.patch b/patches/api/0216-Add-PlayerItemCooldownEvent.patch
index ae5118c7da..32321693b6 100644
--- a/patches/api/0216-Add-PlayerItemCooldownEvent.patch
+++ b/patches/api/0216-Add-PlayerItemCooldownEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerItemCooldownEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerItemCooldownEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerItemCooldownEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c2764ffd51831351b934568e1301b2e4073dc0c4
+index 0000000000000000000000000000000000000000..07b3a93ea09f0ae7d0e7a5af3633a0c669d36fcf
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerItemCooldownEvent.java
-@@ -0,0 +1,82 @@
+@@ -0,0 +1,79 @@
+package io.papermc.paper.event.player;
+
+import com.google.common.base.Preconditions;
@@ -19,23 +19,23 @@ index 0000000000000000000000000000000000000000..c2764ffd51831351b934568e1301b2e4
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a player receives an item cooldown.
+ */
++@NullMarked
+public class PlayerItemCooldownEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull
+ private final Material type;
+ private int cooldown;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerItemCooldownEvent(@NotNull Player player, @NotNull Material type, int cooldown) {
++ public PlayerItemCooldownEvent(final Player player, final Material type, final int cooldown) {
+ super(player);
+ this.type = type;
+ this.cooldown = cooldown;
@@ -46,7 +46,6 @@ index 0000000000000000000000000000000000000000..c2764ffd51831351b934568e1301b2e4
+ *
+ * @return material affected by the cooldown
+ */
-+ @NotNull
+ public Material getType() {
+ return this.type;
+ }
@@ -66,7 +65,7 @@ index 0000000000000000000000000000000000000000..c2764ffd51831351b934568e1301b2e4
+ *
+ * @param cooldown cooldown in ticks, has to be a positive number
+ */
-+ public void setCooldown(int cooldown) {
++ public void setCooldown(final int cooldown) {
+ Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!");
+ this.cooldown = cooldown;
+ }
@@ -77,17 +76,15 @@ index 0000000000000000000000000000000000000000..c2764ffd51831351b934568e1301b2e4
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0219-Player-Chunk-Load-Unload-Events.patch b/patches/api/0219-Player-Chunk-Load-Unload-Events.patch
index c1779bb840..bbfe5bf169 100644
--- a/patches/api/0219-Player-Chunk-Load-Unload-Events.patch
+++ b/patches/api/0219-Player-Chunk-Load-Unload-Events.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Player Chunk Load/Unload Events
diff --git a/src/main/java/io/papermc/paper/event/packet/PlayerChunkLoadEvent.java b/src/main/java/io/papermc/paper/event/packet/PlayerChunkLoadEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..3ddbc099a13df939b3912f30b54e7635840ba5a4
+index 0000000000000000000000000000000000000000..2815c5802eb38e5a48f9db42b9247e24c27db134
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/packet/PlayerChunkLoadEvent.java
-@@ -0,0 +1,45 @@
+@@ -0,0 +1,43 @@
+package io.papermc.paper.event.packet;
+
+import org.bukkit.Chunk;
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..3ddbc099a13df939b3912f30b54e7635
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.world.ChunkEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when a {@link Player} receives a {@link Chunk}
@@ -27,6 +27,7 @@ index 0000000000000000000000000000000000000000..3ddbc099a13df939b3912f30b54e7635
+ * Should only be used for packet/clientside related stuff.
+ * Not intended for modifying server side state.
+ */
++@NullMarked
+public class PlayerChunkLoadEvent extends ChunkEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,33 +35,30 @@ index 0000000000000000000000000000000000000000..3ddbc099a13df939b3912f30b54e7635
+ private final Player player;
+
+ @ApiStatus.Internal
-+ public PlayerChunkLoadEvent(@NotNull Chunk chunk, @NotNull Player player) {
++ public PlayerChunkLoadEvent(final Chunk chunk, final Player player) {
+ super(chunk);
+ this.player = player;
+ }
+
-+ @NotNull
+ public Player getPlayer() {
+ return this.player;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/packet/PlayerChunkUnloadEvent.java b/src/main/java/io/papermc/paper/event/packet/PlayerChunkUnloadEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2cac7e27991c04a9ced261f2dd8ad8657ccddf6b
+index 0000000000000000000000000000000000000000..3ebb35b680193109cc751398675e935eed746750
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/packet/PlayerChunkUnloadEvent.java
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,41 @@
+package io.papermc.paper.event.packet;
+
+import org.bukkit.Chunk;
@@ -68,7 +66,7 @@ index 0000000000000000000000000000000000000000..2cac7e27991c04a9ced261f2dd8ad865
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.world.ChunkEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when a {@link Player} receives a chunk unload packet.
@@ -76,6 +74,7 @@ index 0000000000000000000000000000000000000000..2cac7e27991c04a9ced261f2dd8ad865
+ * Should only be used for packet/clientside related stuff.
+ * Not intended for modifying server side.
+ */
++@NullMarked
+public class PlayerChunkUnloadEvent extends ChunkEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -83,23 +82,20 @@ index 0000000000000000000000000000000000000000..2cac7e27991c04a9ced261f2dd8ad865
+ private final Player player;
+
+ @ApiStatus.Internal
-+ public PlayerChunkUnloadEvent(@NotNull Chunk chunk, @NotNull Player player) {
++ public PlayerChunkUnloadEvent(final Chunk chunk, final Player player) {
+ super(chunk);
+ this.player = player;
+ }
+
-+ @NotNull
+ public Player getPlayer() {
+ return this.player;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0222-Added-PlayerTradeEvent.patch b/patches/api/0222-Added-PlayerTradeEvent.patch
index 11ad019021..92c8312a01 100644
--- a/patches/api/0222-Added-PlayerTradeEvent.patch
+++ b/patches/api/0222-Added-PlayerTradeEvent.patch
@@ -13,10 +13,10 @@ event being about villager trades.
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43e9b50bfc
+index 0000000000000000000000000000000000000000..1691b53f157f17117116e841cbfc769ea0e14364
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerPurchaseEvent.java
-@@ -0,0 +1,109 @@
+@@ -0,0 +1,104 @@
+package io.papermc.paper.event.player;
+
+import com.google.common.base.Preconditions;
@@ -26,11 +26,12 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.MerchantRecipe;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player trades with a standalone merchant GUI.
+ */
++@NullMarked
+public class PlayerPurchaseEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -42,12 +43,9 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerPurchaseEvent(@NotNull Player player,
-+ @NotNull MerchantRecipe trade,
-+ boolean rewardExp,
-+ boolean increaseTradeUses) {
++ public PlayerPurchaseEvent(final Player player, final MerchantRecipe trade, final boolean rewardExp, final boolean increaseTradeUses) {
+ super(player);
-+ setTrade(trade);
++ this.trade = trade;
+ this.rewardExp = rewardExp;
+ this.increaseTradeUses = increaseTradeUses;
+ }
@@ -57,7 +55,6 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ *
+ * @return the trade
+ */
-+ @NotNull
+ public MerchantRecipe getTrade() {
+ return this.trade;
+ }
@@ -67,7 +64,7 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ *
+ * @param trade the trade to use
+ */
-+ public void setTrade(@NotNull MerchantRecipe trade) {
++ public void setTrade(final MerchantRecipe trade) {
+ Preconditions.checkArgument(trade != null, "Trade cannot be null!");
+ this.trade = trade;
+ }
@@ -84,7 +81,7 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ *
+ * @param rewardExp try to reward exp
+ */
-+ public void setRewardExp(boolean rewardExp) {
++ public void setRewardExp(final boolean rewardExp) {
+ this.rewardExp = rewardExp;
+ }
+
@@ -100,7 +97,7 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ *
+ * @param increaseTradeUses {@code true} to count, {@code false} otherwise
+ */
-+ public void setIncreaseTradeUses(boolean increaseTradeUses) {
++ public void setIncreaseTradeUses(final boolean increaseTradeUses) {
+ this.increaseTradeUses = increaseTradeUses;
+ }
+
@@ -110,17 +107,15 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@@ -128,7 +123,7 @@ index 0000000000000000000000000000000000000000..61c62877c38e27eacc20aa43ef02dc43
+}
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
new file mode 100755
-index 0000000000000000000000000000000000000000..559d1a3c783e6c726f48d1c88b2ff8c0888890ac
+index 0000000000000000000000000000000000000000..46bdc178c19feb7dbb71eebee6d0774cf16c1042
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerTradeEvent.java
@@ -0,0 +1,32 @@
@@ -138,17 +133,18 @@ index 0000000000000000000000000000000000000000..559d1a3c783e6c726f48d1c88b2ff8c0
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.MerchantRecipe;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player trades with a villager or wandering trader
+ */
++@NullMarked
+public class PlayerTradeEvent extends PlayerPurchaseEvent {
+
+ private final AbstractVillager villager;
+
+ @ApiStatus.Internal
-+ public PlayerTradeEvent(@NotNull Player player, @NotNull AbstractVillager villager, @NotNull MerchantRecipe trade, boolean rewardExp, boolean increaseTradeUses) {
++ public PlayerTradeEvent(final Player player, final AbstractVillager villager, final MerchantRecipe trade, final boolean rewardExp, final boolean increaseTradeUses) {
+ super(player, trade, rewardExp, increaseTradeUses);
+ this.villager = villager;
+ }
@@ -158,7 +154,6 @@ index 0000000000000000000000000000000000000000..559d1a3c783e6c726f48d1c88b2ff8c0
+ *
+ * @return the villager or wandering trader
+ */
-+ @NotNull
+ public AbstractVillager getVillager() {
+ return this.villager;
+ }
diff --git a/patches/api/0226-Add-PlayerFlowerPotManipulateEvent.patch b/patches/api/0226-Add-PlayerFlowerPotManipulateEvent.patch
index cb08fd1404..70a0b6ec31 100644
--- a/patches/api/0226-Add-PlayerFlowerPotManipulateEvent.patch
+++ b/patches/api/0226-Add-PlayerFlowerPotManipulateEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerFlowerPotManipulateEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerFlowerPotManipulateEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerFlowerPotManipulateEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..373a6ec68fb575b82b06bf250768c1a6909efe38
+index 0000000000000000000000000000000000000000..03881ae56b3dd68a0aa600382b4689f213ec05f3
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerFlowerPotManipulateEvent.java
-@@ -0,0 +1,85 @@
+@@ -0,0 +1,80 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.Block;
@@ -19,25 +19,24 @@ index 0000000000000000000000000000000000000000..373a6ec68fb575b82b06bf250768c1a6
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player places an item in or takes an item out of a flowerpot.
+ */
++@NullMarked
+public class PlayerFlowerPotManipulateEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull
+ private final Block flowerpot;
-+ @NotNull
+ private final ItemStack item;
+ private final boolean placing;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerFlowerPotManipulateEvent(@NotNull final Player player, @NotNull final Block flowerpot, @NotNull final ItemStack item, final boolean placing) {
++ public PlayerFlowerPotManipulateEvent(final Player player, final Block flowerpot, final ItemStack item, final boolean placing) {
+ super(player);
+ this.flowerpot = flowerpot;
+ this.item = item;
@@ -49,7 +48,6 @@ index 0000000000000000000000000000000000000000..373a6ec68fb575b82b06bf250768c1a6
+ *
+ * @return the flowerpot that is involved with this event
+ */
-+ @NotNull
+ public Block getFlowerpot() {
+ return this.flowerpot;
+ }
@@ -60,7 +58,6 @@ index 0000000000000000000000000000000000000000..373a6ec68fb575b82b06bf250768c1a6
+ *
+ * @return the item placed, or taken from, the flowerpot
+ */
-+ @NotNull
+ public ItemStack getItem() {
+ return this.item;
+ }
@@ -80,17 +77,15 @@ index 0000000000000000000000000000000000000000..373a6ec68fb575b82b06bf250768c1a6
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0229-Added-WorldGameRuleChangeEvent.patch b/patches/api/0229-Added-WorldGameRuleChangeEvent.patch
index 348efda0ca..92d081900f 100644
--- a/patches/api/0229-Added-WorldGameRuleChangeEvent.patch
+++ b/patches/api/0229-Added-WorldGameRuleChangeEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added WorldGameRuleChangeEvent
diff --git a/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java b/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba2432109f01
+index 0000000000000000000000000000000000000000..4d259e31c4b1bb01318c727d8e340b6b23084067
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java
-@@ -0,0 +1,92 @@
+@@ -0,0 +1,88 @@
+package io.papermc.paper.event.world;
+
+import org.bukkit.GameRule;
@@ -19,23 +19,24 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.world.WorldEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when a world's gamerule is changed, either by command or by api.
+ */
++@NullMarked
+public class WorldGameRuleChangeEvent extends WorldEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ private final CommandSender commandSender;
++ private final @Nullable CommandSender commandSender;
+ private final GameRule<?> gameRule;
+ private String value;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public WorldGameRuleChangeEvent(@NotNull World world, @Nullable CommandSender commandSender, @NotNull GameRule<?> gameRule, @NotNull String value) {
++ public WorldGameRuleChangeEvent(final World world, final @Nullable CommandSender commandSender, final GameRule<?> gameRule, final String value) {
+ super(world);
+ this.commandSender = commandSender;
+ this.gameRule = gameRule;
@@ -47,8 +48,7 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+ *
+ * @return {@code null} if the gamerule was changed via api, otherwise the {@link CommandSender}.
+ */
-+ @Nullable
-+ public CommandSender getCommandSender() {
++ public @Nullable CommandSender getCommandSender() {
+ return this.commandSender;
+ }
+
@@ -57,7 +57,6 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+ *
+ * @return the gamerule being changed.
+ */
-+ @NotNull
+ public GameRule<?> getGameRule() {
+ return this.gameRule;
+ }
@@ -67,7 +66,6 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+ *
+ * @return the new value of the gamerule.
+ */
-+ @NotNull
+ public String getValue() {
+ return this.value;
+ }
@@ -77,7 +75,7 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+ *
+ * @param value the new value of the gamerule.
+ */
-+ public void setValue(@NotNull String value) {
++ public void setValue(final String value) {
+ this.value = value;
+ }
+
@@ -87,17 +85,15 @@ index 0000000000000000000000000000000000000000..2831fb8ad22e457f85523f65be9cba24
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0231-Add-BlockFailedDispenseEvent.patch b/patches/api/0231-Add-BlockFailedDispenseEvent.patch
index 5b27cc5529..738d2b32c5 100644
--- a/patches/api/0231-Add-BlockFailedDispenseEvent.patch
+++ b/patches/api/0231-Add-BlockFailedDispenseEvent.patch
@@ -6,16 +6,15 @@ Subject: [PATCH] Add BlockFailedDispenseEvent
diff --git a/src/main/java/io/papermc/paper/event/block/BlockFailedDispenseEvent.java b/src/main/java/io/papermc/paper/event/block/BlockFailedDispenseEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..03f91644189e2d1c615f0a22ab0a7c38c803f6c4
+index 0000000000000000000000000000000000000000..483139950f80588ae13204a624b9d60c44fac730
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockFailedDispenseEvent.java
-@@ -0,0 +1,58 @@
+@@ -0,0 +1,57 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Block;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockEvent;
-+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
diff --git a/patches/api/0232-Added-PlayerLecternPageChangeEvent.patch b/patches/api/0232-Added-PlayerLecternPageChangeEvent.patch
index 3c9f223aa5..43e273dba1 100644
--- a/patches/api/0232-Added-PlayerLecternPageChangeEvent.patch
+++ b/patches/api/0232-Added-PlayerLecternPageChangeEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerLecternPageChangeEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerLecternPageChangeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerLecternPageChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b8112a98bb3
+index 0000000000000000000000000000000000000000..6126182db48dab1286924f9642fb259087efabb3
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerLecternPageChangeEvent.java
-@@ -0,0 +1,117 @@
+@@ -0,0 +1,113 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.Lectern;
@@ -19,8 +19,9 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class PlayerLecternPageChangeEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerLecternPageChangeEvent(@NotNull Player player, @NotNull Lectern lectern, @NotNull ItemStack book, @NotNull PageChangeDirection pageChangeDirection, int oldPage, int newPage) {
++ public PlayerLecternPageChangeEvent(final Player player, final Lectern lectern, final ItemStack book, final PageChangeDirection pageChangeDirection, final int oldPage, final int newPage) {
+ super(player);
+ this.lectern = lectern;
+ this.book = book;
@@ -48,7 +49,6 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ *
+ * @return the Lectern
+ */
-+ @NotNull
+ public Lectern getLectern() {
+ return this.lectern;
+ }
@@ -58,7 +58,6 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ *
+ * @return the ItemStack on the Lectern
+ */
-+ @NotNull
+ public ItemStack getBook() {
+ return this.book;
+ }
@@ -68,7 +67,6 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ *
+ * @return the page change direction
+ */
-+ @NotNull
+ public PageChangeDirection getPageChangeDirection() {
+ return this.pageChangeDirection;
+ }
@@ -97,7 +95,7 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ *
+ * @param newPage the new paged changed to
+ */
-+ public void setNewPage(int newPage) {
++ public void setNewPage(final int newPage) {
+ this.newPage = newPage;
+ }
+
@@ -107,17 +105,15 @@ index 0000000000000000000000000000000000000000..6ed2a6c8c033937d933b6d4834953b81
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0233-Added-PlayerLoomPatternSelectEvent.patch b/patches/api/0233-Added-PlayerLoomPatternSelectEvent.patch
index 766e838ec8..e5f19ed926 100644
--- a/patches/api/0233-Added-PlayerLoomPatternSelectEvent.patch
+++ b/patches/api/0233-Added-PlayerLoomPatternSelectEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerLoomPatternSelectEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerLoomPatternSelectEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerLoomPatternSelectEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c35d7411f6
+index 0000000000000000000000000000000000000000..5d4a334ba97cc0c17db8a157f2e2fd99dafbdbcc
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerLoomPatternSelectEvent.java
-@@ -0,0 +1,80 @@
+@@ -0,0 +1,77 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.banner.PatternType;
@@ -19,11 +19,12 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.LoomInventory;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player selects a banner patten in a loom inventory.
+ */
++@NullMarked
+public class PlayerLoomPatternSelectEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerLoomPatternSelectEvent(@NotNull Player player, @NotNull LoomInventory loomInventory, @NotNull PatternType patternType) {
++ public PlayerLoomPatternSelectEvent(final Player player, final LoomInventory loomInventory, final PatternType patternType) {
+ super(player);
+ this.loomInventory = loomInventory;
+ this.patternType = patternType;
@@ -45,7 +46,6 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+ *
+ * @return the loom inventory
+ */
-+ @NotNull
+ public LoomInventory getLoomInventory() {
+ return this.loomInventory;
+ }
@@ -55,7 +55,6 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+ *
+ * @return the pattern type
+ */
-+ @NotNull
+ public PatternType getPatternType() {
+ return this.patternType;
+ }
@@ -65,7 +64,7 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+ *
+ * @param patternType the pattern type
+ */
-+ public void setPatternType(@NotNull PatternType patternType) {
++ public void setPatternType(final PatternType patternType) {
+ this.patternType = patternType;
+ }
+
@@ -75,17 +74,15 @@ index 0000000000000000000000000000000000000000..c614bd1a725adee0c434a9331099d0c3
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0237-Add-StructuresLocateEvent.patch b/patches/api/0237-Add-StructuresLocateEvent.patch
index 4f5120e852..de27ef5473 100644
--- a/patches/api/0237-Add-StructuresLocateEvent.patch
+++ b/patches/api/0237-Add-StructuresLocateEvent.patch
@@ -7,10 +7,10 @@ Co-authored-by: Jake Potrebic <[email protected]>
diff --git a/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java b/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7e8d1edf7
+index 0000000000000000000000000000000000000000..d39b3dc48079fc83f1fd8e7ecde0d4ae77b635ce
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java
-@@ -0,0 +1,176 @@
+@@ -0,0 +1,177 @@
+package io.papermc.paper.event.world;
+
+import io.papermc.paper.math.Position;
@@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+import org.bukkit.generator.structure.Structure;
+import org.bukkit.generator.structure.StructureType;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.UnmodifiableView;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called <b>before</b> a set of configured structures is located.
@@ -41,12 +41,13 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ * <li>{@link World#locateNearestStructure(Location, Structure, int, boolean)} is invoked.</li>
+ * </ul>
+ */
++@NullMarked
+public class StructuresLocateEvent extends WorldEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Location origin;
-+ private Result result;
++ private @Nullable Result result;
+ private List<Structure> structures;
+ private int radius;
+ private boolean findUnexplored;
@@ -54,7 +55,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List<Structure> structures, int radius, boolean findUnexplored) {
++ public StructuresLocateEvent(final World world, final Location origin, final List<Structure> structures, final int radius, final boolean findUnexplored) {
+ super(world);
+ this.origin = origin;
+ this.structures = structures;
@@ -67,7 +68,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @return {@link Location} where search begins
+ */
-+ public @NotNull Location getOrigin() {
++ public Location getOrigin() {
+ return this.origin.clone();
+ }
+
@@ -90,7 +91,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @param result the {@link Location} and {@link Structure} of the search.
+ */
-+ public void setResult(@Nullable Result result) {
++ public void setResult(final @Nullable Result result) {
+ this.result = result;
+ }
+
@@ -99,7 +100,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @return an unmodifiable list of Structures
+ */
-+ public @NotNull @UnmodifiableView List<Structure> getStructures() {
++ public @UnmodifiableView List<Structure> getStructures() {
+ return Collections.unmodifiableList(this.structures);
+ }
+
@@ -108,7 +109,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @param structures a list of Structures targets
+ */
-+ public void setStructures(final @NotNull List<Structure> structures) {
++ public void setStructures(final List<Structure> structures) {
+ this.structures = structures;
+ }
+
@@ -130,7 +131,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @param radius the search radius (in chunks)
+ */
-+ public void setRadius(int radius) {
++ public void setRadius(final int radius) {
+ this.radius = radius;
+ }
+
@@ -152,7 +153,7 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ *
+ * @param findUnexplored Whether to search for only unexplored structures.
+ */
-+ public void setFindUnexplored(boolean findUnexplored) {
++ public void setFindUnexplored(final boolean findUnexplored) {
+ this.findUnexplored = findUnexplored;
+ }
+
@@ -162,26 +163,26 @@ index 0000000000000000000000000000000000000000..41ea65c9ecf6339bb50864a6d28e53c7
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ public static @NotNull HandlerList getHandlerList() {
++ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ /**
+ * Result for {@link StructuresLocateEvent}.
+ */
-+ public record Result(@NotNull Position pos, @NotNull Structure structure) {
++ public record Result(Position pos, Structure structure) {
+
+ @Deprecated(forRemoval = true)
-+ public @NotNull Location position() {
++ public Location position() {
+ //noinspection DataFlowIssue
+ return this.pos.toLocation(null);
+ }
diff --git a/patches/api/0238-Add-BlockPreDispenseEvent.patch b/patches/api/0238-Add-BlockPreDispenseEvent.patch
index 44fccdf619..0467ecd668 100644
--- a/patches/api/0238-Add-BlockPreDispenseEvent.patch
+++ b/patches/api/0238-Add-BlockPreDispenseEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add BlockPreDispenseEvent
diff --git a/src/main/java/io/papermc/paper/event/block/BlockPreDispenseEvent.java b/src/main/java/io/papermc/paper/event/block/BlockPreDispenseEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..fd10a34ec4e0731574cc7d69620e0b353ce8a21b
+index 0000000000000000000000000000000000000000..2e13e18e2b8411dfb7886663de7125330a65fa62
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockPreDispenseEvent.java
-@@ -0,0 +1,63 @@
+@@ -0,0 +1,64 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Block;
@@ -65,6 +65,7 @@ index 0000000000000000000000000000000000000000..fd10a34ec4e0731574cc7d69620e0b35
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0239-Added-PlayerChangeBeaconEffectEvent.patch b/patches/api/0239-Added-PlayerChangeBeaconEffectEvent.patch
index 4d84c9e1b1..64504b1293 100644
--- a/patches/api/0239-Added-PlayerChangeBeaconEffectEvent.patch
+++ b/patches/api/0239-Added-PlayerChangeBeaconEffectEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerChangeBeaconEffectEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerChangeBeaconEffectEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerChangeBeaconEffectEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6f4c2c4ff
+index 0000000000000000000000000000000000000000..580f01754ce082c926240b9bf4842cde1320f987
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerChangeBeaconEffectEvent.java
-@@ -0,0 +1,137 @@
+@@ -0,0 +1,136 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.Block;
@@ -19,25 +19,26 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.potion.PotionEffectType;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when a player sets the effect for a beacon
+ */
++@NullMarked
+public class PlayerChangeBeaconEffectEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Block beacon;
-+ private PotionEffectType primary;
-+ private PotionEffectType secondary;
++ private @Nullable PotionEffectType primary;
++ private @Nullable PotionEffectType secondary;
+ private boolean consumeItem = true;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerChangeBeaconEffectEvent(@NotNull Player player, @Nullable PotionEffectType primary, @Nullable PotionEffectType secondary, @NotNull Block beacon) {
++ public PlayerChangeBeaconEffectEvent(final Player player, final @Nullable PotionEffectType primary, final @Nullable PotionEffectType secondary, final Block beacon) {
+ super(player);
+ this.primary = primary;
+ this.secondary = secondary;
@@ -47,7 +48,7 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+ /**
+ * @return the primary effect
+ */
-+ @Nullable public PotionEffectType getPrimary() {
++ public @Nullable PotionEffectType getPrimary() {
+ return this.primary;
+ }
+
@@ -58,14 +59,14 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+ *
+ * @param primary the primary effect
+ */
-+ public void setPrimary(@Nullable PotionEffectType primary) {
++ public void setPrimary(final @Nullable PotionEffectType primary) {
+ this.primary = primary;
+ }
+
+ /**
+ * @return the secondary effect
+ */
-+ @Nullable public PotionEffectType getSecondary() {
++ public @Nullable PotionEffectType getSecondary() {
+ return this.secondary;
+ }
+
@@ -77,14 +78,13 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+ *
+ * @param secondary the secondary effect
+ */
-+ public void setSecondary(@Nullable PotionEffectType secondary) {
++ public void setSecondary(final @Nullable PotionEffectType secondary) {
+ this.secondary = secondary;
+ }
+
+ /**
+ * @return the beacon block associated with this event
+ */
-+ @NotNull
+ public Block getBeacon() {
+ return this.beacon;
+ }
@@ -109,7 +109,7 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+ *
+ * @param consumeItem {@code true} if item should be consumed
+ */
-+ public void setConsumeItem(boolean consumeItem) {
++ public void setConsumeItem(final boolean consumeItem) {
+ this.consumeItem = consumeItem;
+ }
+
@@ -133,16 +133,15 @@ index 0000000000000000000000000000000000000000..1cc5dfb6d31f312f07acb1d5fb4719d6
+ * or saved.
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0240-Added-PlayerStonecutterRecipeSelectEvent.patch b/patches/api/0240-Added-PlayerStonecutterRecipeSelectEvent.patch
index 46377a6798..ad38969864 100644
--- a/patches/api/0240-Added-PlayerStonecutterRecipeSelectEvent.patch
+++ b/patches/api/0240-Added-PlayerStonecutterRecipeSelectEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerStonecutterRecipeSelectEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerStonecutterRecipeSelectEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerStonecutterRecipeSelectEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..8a7e1cb49ace104af3f9571fbc36b80687141736
+index 0000000000000000000000000000000000000000..7f603310bff54b1c58334f21a6975bfe20812d72
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerStonecutterRecipeSelectEvent.java
-@@ -0,0 +1,60 @@
+@@ -0,0 +1,57 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Player;
@@ -18,8 +18,9 @@ index 0000000000000000000000000000000000000000..8a7e1cb49ace104af3f9571fbc36b806
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.StonecutterInventory;
+import org.bukkit.inventory.StonecuttingRecipe;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class PlayerStonecutterRecipeSelectEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -29,23 +30,21 @@ index 0000000000000000000000000000000000000000..8a7e1cb49ace104af3f9571fbc36b806
+
+ private boolean cancelled;
+
-+ public PlayerStonecutterRecipeSelectEvent(@NotNull Player player, @NotNull StonecutterInventory stonecutterInventory, @NotNull StonecuttingRecipe stonecuttingRecipe) {
++ public PlayerStonecutterRecipeSelectEvent(final Player player, final StonecutterInventory stonecutterInventory, final StonecuttingRecipe stonecuttingRecipe) {
+ super(player);
+ this.stonecutterInventory = stonecutterInventory;
+ this.stonecuttingRecipe = stonecuttingRecipe;
+ }
+
-+ @NotNull
+ public StonecutterInventory getStonecutterInventory() {
+ return this.stonecutterInventory;
+ }
+
-+ @NotNull
+ public StonecuttingRecipe getStonecuttingRecipe() {
+ return this.stonecuttingRecipe;
+ }
+
-+ public void setStonecuttingRecipe(@NotNull StonecuttingRecipe stonecuttingRecipe) {
++ public void setStonecuttingRecipe(final StonecuttingRecipe stonecuttingRecipe) {
+ this.stonecuttingRecipe = stonecuttingRecipe;
+ }
+
@@ -55,17 +54,15 @@ index 0000000000000000000000000000000000000000..8a7e1cb49ace104af3f9571fbc36b806
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0249-Add-worldborder-events.patch b/patches/api/0249-Add-worldborder-events.patch
index 9f3ae70435..f67333262d 100644
--- a/patches/api/0249-Add-worldborder-events.patch
+++ b/patches/api/0249-Add-worldborder-events.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add worldborder events
diff --git a/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeEvent.java b/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5a5d62928
+index 0000000000000000000000000000000000000000..3c168b3522c538c1576238738d48eaef6559450d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeEvent.java
-@@ -0,0 +1,117 @@
+@@ -0,0 +1,115 @@
+package io.papermc.paper.event.world.border;
+
+import org.bukkit.World;
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a world border changes its bounds, either over time, or instantly.
+ */
++@NullMarked
+public class WorldBorderBoundsChangeEvent extends WorldBorderEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,7 +34,7 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public WorldBorderBoundsChangeEvent(@NotNull World world, @NotNull WorldBorder worldBorder, @NotNull Type type, double oldSize, double newSize, long duration) {
++ public WorldBorderBoundsChangeEvent(final World world, final WorldBorder worldBorder, final Type type, final double oldSize, final double newSize, final long duration) {
+ super(world, worldBorder);
+ this.type = type;
+ this.oldSize = oldSize;
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+ *
+ * @return the change type
+ */
-+ @NotNull
+ public Type getType() {
+ return this.type;
+ }
@@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+ *
+ * @param newSize the new size
+ */
-+ public void setNewSize(double newSize) {
++ public void setNewSize(final double newSize) {
+ this.newSize = Math.min(this.worldBorder.getMaxSize(), Math.max(1.0D, newSize));
+ }
+
@@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+ *
+ * @param duration the time in milliseconds for the change
+ */
-+ public void setDuration(long duration) {
++ public void setDuration(final long duration) {
+ // PAIL: TODO: Magic Values
+ this.duration = Math.min(9223372036854775L, Math.max(0L, duration));
+ if (duration >= 0 && this.type == Type.INSTANT_MOVE) {
@@ -107,17 +107,15 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@@ -129,21 +127,22 @@ index 0000000000000000000000000000000000000000..02ac479840c137ca5afcec149ef884e5
+}
diff --git a/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeFinishEvent.java b/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeFinishEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a44964593b7f78c5086dc4928e75ad892e624671
+index 0000000000000000000000000000000000000000..6a264660897f0b621e3fb112e6056d98bb510f52
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeFinishEvent.java
-@@ -0,0 +1,67 @@
+@@ -0,0 +1,66 @@
+package io.papermc.paper.event.world.border;
+
+import org.bukkit.World;
+import org.bukkit.WorldBorder;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a moving world border has finished its move.
+ */
++@NullMarked
+public class WorldBorderBoundsChangeFinishEvent extends WorldBorderEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -153,7 +152,7 @@ index 0000000000000000000000000000000000000000..a44964593b7f78c5086dc4928e75ad89
+ private final double duration;
+
+ @ApiStatus.Internal
-+ public WorldBorderBoundsChangeFinishEvent(@NotNull World world, @NotNull WorldBorder worldBorder, double oldSize, double newSize, double duration) {
++ public WorldBorderBoundsChangeFinishEvent(final World world, final WorldBorder worldBorder, final double oldSize, final double newSize, final double duration) {
+ super(world, worldBorder);
+ this.oldSize = oldSize;
+ this.newSize = newSize;
@@ -189,23 +188,21 @@ index 0000000000000000000000000000000000000000..a44964593b7f78c5086dc4928e75ad89
+ return this.duration;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/world/border/WorldBorderCenterChangeEvent.java b/src/main/java/io/papermc/paper/event/world/border/WorldBorderCenterChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d434fb386
+index 0000000000000000000000000000000000000000..74fe5ad50517374631fa3009249833e2b99a55f0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/border/WorldBorderCenterChangeEvent.java
-@@ -0,0 +1,79 @@
+@@ -0,0 +1,76 @@
+package io.papermc.paper.event.world.border;
+
+import org.bukkit.Location;
@@ -214,11 +211,12 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a world border's center is changed.
+ */
++@NullMarked
+public class WorldBorderCenterChangeEvent extends WorldBorderEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -229,7 +227,7 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public WorldBorderCenterChangeEvent(@NotNull World world, @NotNull WorldBorder worldBorder, @NotNull Location oldCenter, @NotNull Location newCenter) {
++ public WorldBorderCenterChangeEvent(final World world, final WorldBorder worldBorder, final Location oldCenter, final Location newCenter) {
+ super(world, worldBorder);
+ this.oldCenter = oldCenter;
+ this.newCenter = newCenter;
@@ -240,7 +238,6 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+ *
+ * @return the old center
+ */
-+ @NotNull
+ public Location getOldCenter() {
+ return this.oldCenter.clone();
+ }
@@ -250,7 +247,6 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+ *
+ * @return the new center
+ */
-+ @NotNull
+ public Location getNewCenter() {
+ return this.newCenter;
+ }
@@ -260,7 +256,7 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+ *
+ * @param newCenter the new center
+ */
-+ public void setNewCenter(@NotNull Location newCenter) {
++ public void setNewCenter(final Location newCenter) {
+ this.newCenter = newCenter;
+ }
+
@@ -270,24 +266,22 @@ index 0000000000000000000000000000000000000000..dd96dcc0dd68d71bf27c758ed496153d
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/world/border/WorldBorderEvent.java b/src/main/java/io/papermc/paper/event/world/border/WorldBorderEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..adb244f9be35c43ff99dbc3a771e1fdfb21da68c
+index 0000000000000000000000000000000000000000..1f260e4d693903361d54c0af42144faa66adf4ea
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/world/border/WorldBorderEvent.java
@@ -0,0 +1,23 @@
@@ -297,19 +291,19 @@ index 0000000000000000000000000000000000000000..adb244f9be35c43ff99dbc3a771e1fdf
+import org.bukkit.WorldBorder;
+import org.bukkit.event.world.WorldEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public abstract class WorldBorderEvent extends WorldEvent {
+
+ protected final WorldBorder worldBorder;
+
+ @ApiStatus.Internal
-+ protected WorldBorderEvent(@NotNull World world, @NotNull WorldBorder worldBorder) {
++ protected WorldBorderEvent(final World world, final WorldBorder worldBorder) {
+ super(world);
+ this.worldBorder = worldBorder;
+ }
+
-+ @NotNull
+ public WorldBorder getWorldBorder() {
+ return this.worldBorder;
+ }
diff --git a/patches/api/0250-added-PlayerNameEntityEvent.patch b/patches/api/0250-added-PlayerNameEntityEvent.patch
index 69bd20d13e..d7b2294c6d 100644
--- a/patches/api/0250-added-PlayerNameEntityEvent.patch
+++ b/patches/api/0250-added-PlayerNameEntityEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] added PlayerNameEntityEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerNameEntityEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerNameEntityEvent.java
new file mode 100755
-index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b741cc39b61
+index 0000000000000000000000000000000000000000..fb990180d9958fe2bbe44e86aa360102f37be9ed
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerNameEntityEvent.java
-@@ -0,0 +1,110 @@
+@@ -0,0 +1,107 @@
+package io.papermc.paper.event.player;
+
+import net.kyori.adventure.text.Component;
@@ -19,24 +19,25 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when the player is attempting to rename a mob
+ */
++@NullMarked
+public class PlayerNameEntityEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private LivingEntity entity;
-+ private Component name;
++ private @Nullable Component name;
+ private boolean persistent;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerNameEntityEvent(@NotNull Player player, @NotNull LivingEntity entity, @NotNull Component name, boolean persistent) {
++ public PlayerNameEntityEvent(final Player player, final LivingEntity entity, final Component name, final boolean persistent) {
+ super(player);
+ this.entity = entity;
+ this.name = name;
@@ -48,8 +49,7 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ *
+ * @return the name
+ */
-+ @Nullable
-+ public Component getName() {
++ public @Nullable Component getName() {
+ return this.name;
+ }
+
@@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ *
+ * @param name the name
+ */
-+ public void setName(@Nullable Component name) {
++ public void setName(final @Nullable Component name) {
+ this.name = name;
+ }
+
@@ -67,7 +67,6 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ *
+ * @return the entity
+ */
-+ @NotNull
+ public LivingEntity getEntity() {
+ return this.entity;
+ }
@@ -77,7 +76,7 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ *
+ * @param entity the entity
+ */
-+ public void setEntity(@NotNull LivingEntity entity) {
++ public void setEntity(final LivingEntity entity) {
+ this.entity = entity;
+ }
+
@@ -95,7 +94,7 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ *
+ * @param persistent persistent
+ */
-+ public void setPersistent(boolean persistent) {
++ public void setPersistent(final boolean persistent) {
+ this.persistent = persistent;
+ }
+
@@ -105,17 +104,15 @@ index 0000000000000000000000000000000000000000..84736d4a438e9023fbdeac1aea4d8b74
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0259-Added-PlayerDeepSleepEvent.patch b/patches/api/0259-Added-PlayerDeepSleepEvent.patch
index b333894788..73c3ea9004 100644
--- a/patches/api/0259-Added-PlayerDeepSleepEvent.patch
+++ b/patches/api/0259-Added-PlayerDeepSleepEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerDeepSleepEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerDeepSleepEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerDeepSleepEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..54cf2ec5e025fac9a0c8f151ff4f8c83a62b8405
+index 0000000000000000000000000000000000000000..2d4b15ded1e9aa00f21ca0b412e6b6ac333e5e02
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerDeepSleepEvent.java
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,47 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Player;
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..54cf2ec5e025fac9a0c8f151ff4f8c83
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player has slept long enough
@@ -26,6 +26,7 @@ index 0000000000000000000000000000000000000000..54cf2ec5e025fac9a0c8f151ff4f8c83
+ * Cancelling this event will prevent the player from being counted as deeply sleeping
+ * unless they exit and re-enter the bed.
+ */
++@NullMarked
+public class PlayerDeepSleepEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,7 +34,7 @@ index 0000000000000000000000000000000000000000..54cf2ec5e025fac9a0c8f151ff4f8c83
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerDeepSleepEvent(@NotNull Player player) {
++ public PlayerDeepSleepEvent(final Player player) {
+ super(player);
+ }
+
@@ -43,17 +44,15 @@ index 0000000000000000000000000000000000000000..54cf2ec5e025fac9a0c8f151ff4f8c83
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0261-Added-PlayerBedFailEnterEvent.patch b/patches/api/0261-Added-PlayerBedFailEnterEvent.patch
index 6f9decf5fc..c324a7202b 100644
--- a/patches/api/0261-Added-PlayerBedFailEnterEvent.patch
+++ b/patches/api/0261-Added-PlayerBedFailEnterEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Added PlayerBedFailEnterEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerBedFailEnterEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerBedFailEnterEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450403ef729
+index 0000000000000000000000000000000000000000..393d127463a6b396f6bd953f538828da23572f33
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerBedFailEnterEvent.java
-@@ -0,0 +1,119 @@
+@@ -0,0 +1,115 @@
+package io.papermc.paper.event.player;
+
+import net.kyori.adventure.text.Component;
@@ -19,9 +19,10 @@ index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
++@NullMarked
+public class PlayerBedFailEnterEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -29,12 +30,12 @@ index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450
+ private final FailReason failReason;
+ private final Block bed;
+ private boolean willExplode;
-+ private Component message;
++ private @Nullable Component message;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerBedFailEnterEvent(@NotNull Player player, @NotNull FailReason failReason, @NotNull Block bed, boolean willExplode, @Nullable Component message) {
++ public PlayerBedFailEnterEvent(final Player player, final FailReason failReason, final Block bed, final boolean willExplode, final @Nullable Component message) {
+ super(player);
+ this.failReason = failReason;
+ this.bed = bed;
@@ -42,12 +43,10 @@ index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450
+ this.message = message;
+ }
+
-+ @NotNull
+ public FailReason getFailReason() {
+ return this.failReason;
+ }
+
-+ @NotNull
+ public Block getBed() {
+ return this.bed;
+ }
@@ -56,16 +55,15 @@ index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450
+ return this.willExplode;
+ }
+
-+ public void setWillExplode(boolean willExplode) {
++ public void setWillExplode(final boolean willExplode) {
+ this.willExplode = willExplode;
+ }
+
-+ @Nullable
-+ public Component getMessage() {
++ public @Nullable Component getMessage() {
+ return this.message;
+ }
+
-+ public void setMessage(@Nullable Component message) {
++ public void setMessage(final @Nullable Component message) {
+ this.message = message;
+ }
+
@@ -81,17 +79,15 @@ index 0000000000000000000000000000000000000000..6cd803e108dc2e6c0b8afda123123450
+ * that may occur because of the interaction.
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0283-Add-ElderGuardianAppearanceEvent.patch b/patches/api/0283-Add-ElderGuardianAppearanceEvent.patch
index b2a5a17547..ae955211a9 100644
--- a/patches/api/0283-Add-ElderGuardianAppearanceEvent.patch
+++ b/patches/api/0283-Add-ElderGuardianAppearanceEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add ElderGuardianAppearanceEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java b/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..272a4a06e766291aeee4f9e19a1ed26aa62e569a
+index 0000000000000000000000000000000000000000..027e70a1085a84669af0bb10e7f11ad3ca1ad299
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java
-@@ -0,0 +1,64 @@
+@@ -0,0 +1,65 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.ElderGuardian;
@@ -51,6 +51,7 @@ index 0000000000000000000000000000000000000000..272a4a06e766291aeee4f9e19a1ed26a
+ *
+ * @return The elder guardian
+ */
++ @Override
+ public ElderGuardian getEntity() {
+ return (ElderGuardian) super.getEntity();
+ }
diff --git a/patches/api/0288-Adds-PlayerArmSwingEvent.patch b/patches/api/0288-Adds-PlayerArmSwingEvent.patch
index 48e43517eb..5fb447f69b 100644
--- a/patches/api/0288-Adds-PlayerArmSwingEvent.patch
+++ b/patches/api/0288-Adds-PlayerArmSwingEvent.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Adds PlayerArmSwingEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..3e8cbd13eb16e0926130bb8b07e2101602b19565
+index 0000000000000000000000000000000000000000..84dfb8da90c5f21d0f8899eca57bcb8b58614ca9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerArmSwingEvent.java
@@ -0,0 +1,29 @@
@@ -17,14 +17,15 @@ index 0000000000000000000000000000000000000000..3e8cbd13eb16e0926130bb8b07e21016
+import org.bukkit.event.player.PlayerAnimationType;
+import org.bukkit.inventory.EquipmentSlot;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class PlayerArmSwingEvent extends PlayerAnimationEvent {
+
+ private final EquipmentSlot equipmentSlot;
+
+ @ApiStatus.Internal
-+ public PlayerArmSwingEvent(@NotNull Player player, @NotNull EquipmentSlot equipmentSlot) {
++ public PlayerArmSwingEvent(final Player player, final EquipmentSlot equipmentSlot) {
+ super(player, equipmentSlot == EquipmentSlot.HAND ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
+ this.equipmentSlot = equipmentSlot;
+ }
@@ -34,7 +35,6 @@ index 0000000000000000000000000000000000000000..3e8cbd13eb16e0926130bb8b07e21016
+ *
+ * @return the hand
+ */
-+ @NotNull
+ public EquipmentSlot getHand() {
+ return this.equipmentSlot;
+ }
diff --git a/patches/api/0289-Add-PlayerSignCommandPreprocessEvent.patch b/patches/api/0289-Add-PlayerSignCommandPreprocessEvent.patch
index 8882c35337..730b7af658 100644
--- a/patches/api/0289-Add-PlayerSignCommandPreprocessEvent.patch
+++ b/patches/api/0289-Add-PlayerSignCommandPreprocessEvent.patch
@@ -6,20 +6,19 @@ Subject: [PATCH] Add PlayerSignCommandPreprocessEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..dc774403749633a1bf8e8088b8c7b402b0e43863
+index 0000000000000000000000000000000000000000..220f950ab804d756e89760c341aafe868b2b6ad0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerSignCommandPreprocessEvent.java
@@ -0,0 +1,47 @@
+package io.papermc.paper.event.player;
+
++import java.util.Set;
+import org.bukkit.block.Sign;
+import org.bukkit.block.sign.Side;
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Set;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a {@link Player} clicks a side on a sign that causes a command to run.
@@ -27,13 +26,14 @@ index 0000000000000000000000000000000000000000..dc774403749633a1bf8e8088b8c7b402
+ * This command is run with elevated permissions which allows players to access commands on signs they wouldn't
+ * normally be able to run.
+ */
++@NullMarked
+public class PlayerSignCommandPreprocessEvent extends PlayerCommandPreprocessEvent {
+
+ private final Sign sign;
+ private final Side side;
+
+ @ApiStatus.Internal
-+ public PlayerSignCommandPreprocessEvent(@NotNull Player player, @NotNull String message, @NotNull Set<Player> recipients, @NotNull Sign sign, @NotNull Side side) {
++ public PlayerSignCommandPreprocessEvent(final Player player, final String message, final Set<Player> recipients, final Sign sign, final Side side) {
+ super(player, message, recipients);
+ this.sign = sign;
+ this.side = side;
@@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..dc774403749633a1bf8e8088b8c7b402
+ *
+ * @return the sign
+ */
-+ public @NotNull Sign getSign() {
++ public Sign getSign() {
+ return this.sign;
+ }
+
@@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..dc774403749633a1bf8e8088b8c7b402
+ *
+ * @return the sign side
+ */
-+ public @NotNull Side getSide() {
++ public Side getSide() {
+ return this.side;
+ }
+}
diff --git a/patches/api/0293-Add-PlayerSetSpawnEvent.patch b/patches/api/0293-Add-PlayerSetSpawnEvent.patch
index 69443add9f..a979a6b7fd 100644
--- a/patches/api/0293-Add-PlayerSetSpawnEvent.patch
+++ b/patches/api/0293-Add-PlayerSetSpawnEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerSetSpawnEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerSetSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerSetSpawnEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c15525acce
+index 0000000000000000000000000000000000000000..41d42d73cf65e9b8acac9d0b2dfd6537b532be74
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerSetSpawnEvent.java
-@@ -0,0 +1,178 @@
+@@ -0,0 +1,175 @@
+package com.destroystokyo.paper.event.player;
+
+import net.kyori.adventure.text.Component;
@@ -19,28 +19,29 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when a player's spawn is set, either by themselves or otherwise.
+ * <br>
+ * Cancelling this event will prevent the spawn from being set.
+ */
++@NullMarked
+public class PlayerSetSpawnEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Cause cause;
-+ private Location location;
++ private @Nullable Location location;
+ private boolean forced;
+ private boolean notifyPlayer;
-+ private Component notification;
++ private @Nullable Component notification;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerSetSpawnEvent(@NotNull Player player, @NotNull Cause cause, @Nullable Location location, boolean forced, boolean notifyPlayer, @Nullable Component notification) {
++ public PlayerSetSpawnEvent(final Player player, final Cause cause, final @Nullable Location location, final boolean forced, final boolean notifyPlayer, final @Nullable Component notification) {
+ super(player);
+ this.cause = cause;
+ this.location = location;
@@ -54,7 +55,6 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @return the cause
+ */
-+ @NotNull
+ public Cause getCause() {
+ return this.cause;
+ }
@@ -67,8 +67,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @return the spawn location, or {@code null} if removing the location
+ */
-+ @Nullable
-+ public Location getLocation() {
++ public @Nullable Location getLocation() {
+ return this.location;
+ }
+
@@ -78,7 +77,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @param location the spawn location, or {@code null} to remove the spawn location
+ */
-+ public void setLocation(@Nullable Location location) {
++ public void setLocation(final @Nullable Location location) {
+ this.location = location;
+ }
+
@@ -96,7 +95,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @param forced {@code true} to force
+ */
-+ public void setForced(boolean forced) {
++ public void setForced(final boolean forced) {
+ this.forced = forced;
+ }
+
@@ -116,7 +115,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @param notifyPlayer {@code true} to notify
+ */
-+ public void setNotifyPlayer(boolean notifyPlayer) {
++ public void setNotifyPlayer(final boolean notifyPlayer) {
+ this.notifyPlayer = notifyPlayer;
+ }
+
@@ -126,8 +125,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @return {@code null} if no notification
+ */
-+ @Nullable
-+ public Component getNotification() {
++ public @Nullable Component getNotification() {
+ return this.notification;
+ }
+
@@ -136,7 +134,7 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ *
+ * @param notification {@code null} to send no message
+ */
-+ public void setNotification(@Nullable Component notification) {
++ public void setNotification(final @Nullable Component notification) {
+ this.notification = notification;
+ }
+
@@ -146,16 +144,15 @@ index 0000000000000000000000000000000000000000..6a823008deaf26f751e598bc967f19c1
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ public @NotNull HandlerList getHandlers() {
++ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0313-Add-PlayerItemFrameChangeEvent.patch b/patches/api/0313-Add-PlayerItemFrameChangeEvent.patch
index b5d6cf7bd1..2231459fbb 100644
--- a/patches/api/0313-Add-PlayerItemFrameChangeEvent.patch
+++ b/patches/api/0313-Add-PlayerItemFrameChangeEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerItemFrameChangeEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerItemFrameChangeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerItemFrameChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f563552414488079e
+index 0000000000000000000000000000000000000000..f387477da45a44cc7788ed5342104f535cf3cb98
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerItemFrameChangeEvent.java
-@@ -0,0 +1,104 @@
+@@ -0,0 +1,99 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.ItemFrame;
@@ -19,12 +19,13 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when an {@link ItemFrame} is having an item rotated, added, or removed from it.
+ */
++@NullMarked
+public class PlayerItemFrameChangeEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -36,8 +37,7 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerItemFrameChangeEvent(@NotNull Player player, @NotNull ItemFrame itemFrame,
-+ @NotNull ItemStack itemStack, @NotNull ItemFrameChangeAction action) {
++ public PlayerItemFrameChangeEvent(final Player player, final ItemFrame itemFrame, final ItemStack itemStack, final ItemFrameChangeAction action) {
+ super(player);
+ this.itemFrame = itemFrame;
+ this.itemStack = itemStack;
@@ -49,7 +49,6 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ *
+ * @return the {@link ItemFrame}
+ */
-+ @NotNull
+ public ItemFrame getItemFrame() {
+ return this.itemFrame;
+ }
@@ -62,7 +61,6 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ *
+ * @return the {@link ItemStack} being added, rotated, or removed
+ */
-+ @NotNull
+ public ItemStack getItemStack() {
+ return this.itemStack;
+ }
@@ -73,7 +71,7 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ *
+ * @param itemStack {@link ItemFrame} item
+ */
-+ public void setItemStack(@Nullable ItemStack itemStack) {
++ public void setItemStack(final @Nullable ItemStack itemStack) {
+ this.itemStack = itemStack == null ? ItemStack.empty() : itemStack;
+ }
+
@@ -82,7 +80,6 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ *
+ * @return action performed on the item frame in this event
+ */
-+ @NotNull
+ public ItemFrameChangeAction getAction() {
+ return this.action;
+ }
@@ -93,17 +90,15 @@ index 0000000000000000000000000000000000000000..7bd61b66db42ecc8c9a3a16f56355241
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
-+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0347-Add-PlayerStopUsingItemEvent.patch b/patches/api/0347-Add-PlayerStopUsingItemEvent.patch
index c8de1f6ed0..c4f27c2925 100644
--- a/patches/api/0347-Add-PlayerStopUsingItemEvent.patch
+++ b/patches/api/0347-Add-PlayerStopUsingItemEvent.patch
@@ -6,30 +6,31 @@ Subject: [PATCH] Add PlayerStopUsingItemEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerStopUsingItemEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerStopUsingItemEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..bbe5f0543a567f1484ab700b1b2ceeb4a22b411b
+index 0000000000000000000000000000000000000000..d79b995292799853a0874d4e113e68b494167242
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerStopUsingItemEvent.java
-@@ -0,0 +1,55 @@
+@@ -0,0 +1,53 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the server detects a player stopping using an item.
+ * Examples of this are letting go of the interact button when holding a bow, an edible item, or a spyglass.
+ */
++@NullMarked
+public class PlayerStopUsingItemEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull private final ItemStack item;
++ private final ItemStack item;
+ private final int ticksHeldFor;
+
-+ public PlayerStopUsingItemEvent(@NotNull final Player player, @NotNull final ItemStack item, final int ticksHeldFor) {
++ public PlayerStopUsingItemEvent(final Player player, final ItemStack item, final int ticksHeldFor) {
+ super(player);
+ this.item = item;
+ this.ticksHeldFor = ticksHeldFor;
@@ -40,7 +41,6 @@ index 0000000000000000000000000000000000000000..bbe5f0543a567f1484ab700b1b2ceeb4
+ *
+ * @return ItemStack the exact item the player released
+ */
-+ @NotNull
+ public ItemStack getItem() {
+ return this.item;
+ }
@@ -54,13 +54,11 @@ index 0000000000000000000000000000000000000000..bbe5f0543a567f1484ab700b1b2ceeb4
+ return this.ticksHeldFor;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0363-Add-PlayerInventorySlotChangeEvent.patch b/patches/api/0363-Add-PlayerInventorySlotChangeEvent.patch
index d76df6d87d..d0cadabced 100644
--- a/patches/api/0363-Add-PlayerInventorySlotChangeEvent.patch
+++ b/patches/api/0363-Add-PlayerInventorySlotChangeEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerInventorySlotChangeEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerInventorySlotChangeEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerInventorySlotChangeEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9fa7457dbe
+index 0000000000000000000000000000000000000000..f3a54ed7efabaa0f6413e1598f14e2770a46440d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerInventorySlotChangeEvent.java
-@@ -0,0 +1,101 @@
+@@ -0,0 +1,98 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Player;
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9f
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a slot contents change in a player's inventory.
+ */
++@NullMarked
+public class PlayerInventorySlotChangeEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -32,7 +33,7 @@ index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9f
+ private final ItemStack newItemStack;
+ private boolean triggerAdvancements = true;
+
-+ public PlayerInventorySlotChangeEvent(@NotNull Player player, int rawSlot, @NotNull ItemStack oldItemStack, @NotNull ItemStack newItemStack) {
++ public PlayerInventorySlotChangeEvent(final Player player, final int rawSlot, final ItemStack oldItemStack, final ItemStack newItemStack) {
+ super(player);
+ this.rawSlot = rawSlot;
+ this.slot = player.getOpenInventory().convertSlot(rawSlot);
@@ -67,7 +68,6 @@ index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9f
+ *
+ * @return The old ItemStack in the slot.
+ */
-+ @NotNull
+ public ItemStack getOldItemStack() {
+ return this.oldItemStack;
+ }
@@ -77,7 +77,6 @@ index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9f
+ *
+ * @return The new ItemStack in the slot.
+ */
-+ @NotNull
+ public ItemStack getNewItemStack() {
+ return this.newItemStack;
+ }
@@ -96,17 +95,15 @@ index 0000000000000000000000000000000000000000..0be9708dbf84fa51a754474834406f9f
+ *
+ * @param triggerAdvancements Whether the slot change advancements will be triggered.
+ */
-+ public void setShouldTriggerAdvancements(boolean triggerAdvancements) {
++ public void setShouldTriggerAdvancements(final boolean triggerAdvancements) {
+ this.triggerAdvancements = triggerAdvancements;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0370-Add-PrePlayerAttackEntityEvent.patch b/patches/api/0370-Add-PrePlayerAttackEntityEvent.patch
index ac0ebedde7..1caf6f7696 100644
--- a/patches/api/0370-Add-PrePlayerAttackEntityEvent.patch
+++ b/patches/api/0370-Add-PrePlayerAttackEntityEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PrePlayerAttackEntityEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PrePlayerAttackEntityEvent.java b/src/main/java/io/papermc/paper/event/player/PrePlayerAttackEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9cad10e11
+index 0000000000000000000000000000000000000000..a6c5818bcdd8de5f2d0e9bf72d1e3816652e0199
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PrePlayerAttackEntityEvent.java
-@@ -0,0 +1,93 @@
+@@ -0,0 +1,90 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Entity;
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the player tries to attack an entity.
@@ -31,18 +31,18 @@ index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9
+ * <p>
+ * Note: there may be other factors (invulnerability, etc.) that will prevent this entity from being attacked that this event will not cover
+ */
++@NullMarked
+public class PrePlayerAttackEntityEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
-+ @NotNull
+ private final Entity attacked;
+ private final boolean willAttack;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PrePlayerAttackEntityEvent(@NotNull Player player, @NotNull Entity attacked, boolean willAttack) {
++ public PrePlayerAttackEntityEvent(final Player player, final Entity attacked, final boolean willAttack) {
+ super(player);
+ this.attacked = attacked;
+ this.willAttack = willAttack;
@@ -54,7 +54,6 @@ index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9
+ *
+ * @return entity that was attacked
+ */
-+ @NotNull
+ public Entity getAttacked() {
+ return this.attacked;
+ }
@@ -84,7 +83,7 @@ index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9
+ * @param cancel {@code true} if you wish to cancel this event
+ */
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ if (!this.willAttack) {
+ return;
+ }
@@ -92,13 +91,11 @@ index 0000000000000000000000000000000000000000..148f46f4572a778f090b461808b53cf9
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0373-Add-paper-dumplisteners-command.patch b/patches/api/0373-Add-paper-dumplisteners-command.patch
index 43d59a5c31..8ad550e4ee 100644
--- a/patches/api/0373-Add-paper-dumplisteners-command.patch
+++ b/patches/api/0373-Add-paper-dumplisteners-command.patch
@@ -20,68 +20,66 @@ index a3ad690691eb5537a565d7ba684354acfec5ee2d..157617933a772451f6c073d97afaf305
+ }
}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
-index 5b28e9b1daba7834af67dbc193dd656bedd9a994..fbebf649e893cf872be9b27091146a7c2f451aca 100644
+index 5a702481d28d90cb503faad0d9b9c3231bbff940..2a169d2f6fdada6c361ee4291abb38446d45d654 100644
--- a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
+++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
-@@ -14,10 +14,12 @@ import org.jetbrains.annotations.NotNull;
- public class MethodHandleEventExecutor implements EventExecutor {
+@@ -18,10 +18,12 @@ public class MethodHandleEventExecutor implements EventExecutor {
+
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
-+ private final Method method;
++ private final @Nullable Method method;
- public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
+ public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
this.eventClass = eventClass;
this.handle = handle;
+ this.method = null;
}
- public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
-@@ -28,6 +30,7 @@ public class MethodHandleEventExecutor implements EventExecutor {
- } catch (IllegalAccessException e) {
+ public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
+@@ -32,6 +34,7 @@ public class MethodHandleEventExecutor implements EventExecutor {
+ } catch (final IllegalAccessException e) {
throw new AssertionError("Unable to set accessible", e);
}
+ this.method = m;
}
@Override
-@@ -39,4 +42,10 @@ public class MethodHandleEventExecutor implements EventExecutor {
+@@ -43,4 +46,9 @@ public class MethodHandleEventExecutor implements EventExecutor {
SneakyThrow.sneaky(t);
}
}
+
+ @Override
-+ @NotNull
+ public String toString() {
+ return "MethodHandleEventExecutor['" + this.method + "']";
+ }
}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
-index 827f2b27f70a7ec0bc11d039305c3e58c02a4ef4..52da2d040e3b335f9e47bc5dc26e17d9c06d9569 100644
+index bbdb5b472df116b71c459bdc6cc4b74267ea0f5e..e98962b6c6651c580684d8580484de87b5ad65a5 100644
--- a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
-@@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull;
- public class StaticMethodHandleEventExecutor implements EventExecutor {
+@@ -19,6 +19,7 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
+
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
+ private final Method method;
- public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
+ public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
-@@ -28,6 +29,7 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
- } catch (IllegalAccessException e) {
+@@ -30,6 +31,7 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
+ } catch (final IllegalAccessException e) {
throw new AssertionError("Unable to set accessible", e);
}
+ this.method = m;
}
@Override
-@@ -39,4 +41,10 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
+@@ -41,4 +43,9 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
SneakyThrow.sneaky(throwable);
}
}
+
+ @Override
-+ @NotNull
+ public String toString() {
+ return "StaticMethodHandleEventExecutor['" + this.method + "']";
+ }
diff --git a/patches/api/0377-Player-Entity-Tracking-Events.patch b/patches/api/0377-Player-Entity-Tracking-Events.patch
index 3dfa72c922..ff550d451b 100644
--- a/patches/api/0377-Player-Entity-Tracking-Events.patch
+++ b/patches/api/0377-Player-Entity-Tracking-Events.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Player Entity Tracking Events
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerTrackEntityEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerTrackEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd085835c5
+index 0000000000000000000000000000000000000000..0e37c8c94a77f6f1c2c4f5290722ca02d76ab924
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerTrackEntityEvent.java
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,60 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Entity;
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when a {@link Player} tracks an {@link Entity}.
@@ -28,6 +28,7 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+ * Adding or removing entities from the world at the point in time this event is called is completely
+ * unsupported and should be avoided.
+ */
++@NullMarked
+public class PlayerTrackEntityEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerTrackEntityEvent(@NotNull Player player, @NotNull Entity entity) {
++ public PlayerTrackEntityEvent(final Player player, final Entity entity) {
+ super(player);
+ this.entity = entity;
+ }
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+ *
+ * @return the entity tracked
+ */
-+ @NotNull
+ public Entity getEntity() {
+ return this.entity;
+ }
@@ -57,16 +57,14 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
@@ -74,10 +72,10 @@ index 0000000000000000000000000000000000000000..356f8933a7715b4fc123e3a4879bb2cd
+}
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerUntrackEntityEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerUntrackEntityEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c573eeaeb599ca717b09f9fd3f106a4800e9c386
+index 0000000000000000000000000000000000000000..30e01ffc8b0d4a8e43a046d85f1903cc20e0e84d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerUntrackEntityEvent.java
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,46 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.entity.Entity;
@@ -85,7 +83,7 @@ index 0000000000000000000000000000000000000000..c573eeaeb599ca717b09f9fd3f106a48
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when a {@link Player} untracks an {@link Entity}.
@@ -93,6 +91,7 @@ index 0000000000000000000000000000000000000000..c573eeaeb599ca717b09f9fd3f106a48
+ * Adding or removing entities from the world at the point in time this event is called is completely
+ * unsupported and should be avoided.
+ */
++@NullMarked
+public class PlayerUntrackEntityEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -100,7 +99,7 @@ index 0000000000000000000000000000000000000000..c573eeaeb599ca717b09f9fd3f106a48
+ private final Entity entity;
+
+ @ApiStatus.Internal
-+ public PlayerUntrackEntityEvent(@NotNull Player player, @NotNull Entity entity) {
++ public PlayerUntrackEntityEvent(final Player player, final Entity entity) {
+ super(player);
+ this.entity = entity;
+ }
@@ -110,17 +109,14 @@ index 0000000000000000000000000000000000000000..c573eeaeb599ca717b09f9fd3f106a48
+ *
+ * @return the entity untracked
+ */
-+ @NotNull
+ public Entity getEntity() {
+ return this.entity;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
diff --git a/patches/api/0396-Add-event-for-player-editing-sign.patch b/patches/api/0396-Add-event-for-player-editing-sign.patch
index ec38bf008b..c0b95f9d58 100644
--- a/patches/api/0396-Add-event-for-player-editing-sign.patch
+++ b/patches/api/0396-Add-event-for-player-editing-sign.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add event for player editing sign
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d5fe361f5
+index 0000000000000000000000000000000000000000..0b905aafe5b228993944af1850c93c797f6eaf47
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java
-@@ -0,0 +1,108 @@
+@@ -0,0 +1,105 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.block.Sign;
@@ -20,13 +20,14 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player begins editing a sign's text.
+ * <p>
+ * Cancelling this event stops the sign editing menu from opening.
+ */
++@NullMarked
+public class PlayerOpenSignEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -38,7 +39,7 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerOpenSignEvent(final @NotNull Player editor, final @NotNull Sign sign, final @NotNull Side side, final @NotNull Cause cause) {
++ public PlayerOpenSignEvent(final Player editor, final Sign sign, final Side side, final Cause cause) {
+ super(editor);
+ this.sign = sign;
+ this.side = side;
@@ -50,7 +51,6 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+ *
+ * @return {@link Sign} that was clicked
+ */
-+ @NotNull
+ public Sign getSign() {
+ return this.sign;
+ }
@@ -61,7 +61,6 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+ * @return {@link Side} that was clicked
+ * @see Sign#getSide(Side)
+ */
-+ @NotNull
+ public Side getSide() {
+ return this.side;
+ }
@@ -71,7 +70,7 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+ *
+ * @return the cause
+ */
-+ public @NotNull Cause getCause() {
++ public Cause getCause() {
+ return this.cause;
+ }
+
@@ -81,17 +80,15 @@ index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0401-Add-PlayerFailMoveEvent.patch b/patches/api/0401-Add-PlayerFailMoveEvent.patch
index c0687e2ae0..e6903a2b56 100644
--- a/patches/api/0401-Add-PlayerFailMoveEvent.patch
+++ b/patches/api/0401-Add-PlayerFailMoveEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerFailMoveEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc2596b90aed
+index 0000000000000000000000000000000000000000..c7380874f99cd2aa28a24bbb0dd3375e8842dd0d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java
-@@ -0,0 +1,118 @@
+@@ -0,0 +1,113 @@
+package io.papermc.paper.event.player;
+
+import org.bukkit.Location;
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Runs when a player attempts to move, but is prevented from doing so by the server
+ */
++@NullMarked
+public class PlayerFailMoveEvent extends PlayerEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,8 +34,7 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ private boolean logWarning;
+
+ @ApiStatus.Internal
-+ public PlayerFailMoveEvent(@NotNull Player player, @NotNull FailReason failReason, boolean allowed,
-+ boolean logWarning, @NotNull Location from, @NotNull Location to) {
++ public PlayerFailMoveEvent(final Player player, final FailReason failReason, final boolean allowed, final boolean logWarning, final Location from, final Location to) {
+ super(player);
+ this.failReason = failReason;
+ this.allowed = allowed;
@@ -48,7 +48,6 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ *
+ * @return The reason the movement was prevented
+ */
-+ @NotNull
+ public FailReason getFailReason() {
+ return this.failReason;
+ }
@@ -58,7 +57,6 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ *
+ * @return Location the player moved from
+ */
-+ @NotNull
+ public Location getFrom() {
+ return this.from.clone();
+ }
@@ -68,7 +66,6 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ *
+ * @return Location the player tried to move to
+ */
-+ @NotNull
+ public Location getTo() {
+ return this.to.clone();
+ }
@@ -87,7 +84,7 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ *
+ * @param allowed whether to bypass the check
+ */
-+ public void setAllowed(boolean allowed) {
++ public void setAllowed(final boolean allowed) {
+ this.allowed = allowed;
+ }
+
@@ -105,17 +102,15 @@ index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc25
+ *
+ * @param logWarning whether to log warnings
+ */
-+ public void setLogWarning(boolean logWarning) {
++ public void setLogWarning(final boolean logWarning) {
+ this.logWarning = logWarning;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0412-Add-PlayerPickItemEvent.patch b/patches/api/0412-Add-PlayerPickItemEvent.patch
index 6dd0be80a8..0532447562 100644
--- a/patches/api/0412-Add-PlayerPickItemEvent.patch
+++ b/patches/api/0412-Add-PlayerPickItemEvent.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add PlayerPickItemEvent
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad1533b7b0ca6
+index 0000000000000000000000000000000000000000..d7e10652918e453838a3a983f089ef4727d0bfe2
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java
-@@ -0,0 +1,96 @@
+@@ -0,0 +1,93 @@
+package io.papermc.paper.event.player;
+
+import com.google.common.base.Preconditions;
@@ -18,8 +18,8 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Event that is fired when a player uses the pick item functionality (middle-clicking a block to get the appropriate
@@ -29,6 +29,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ * <p>
+ * Note: This event will not be fired for players in creative mode.
+ */
++@NullMarked
+public class PlayerPickItemEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -39,7 +40,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerPickItemEvent(@NotNull Player player, int targetSlot, int sourceSlot) {
++ public PlayerPickItemEvent(final Player player, final int targetSlot, final int sourceSlot) {
+ super(player);
+ this.targetSlot = targetSlot;
+ this.sourceSlot = sourceSlot;
@@ -50,8 +51,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ *
+ * @return hotbar slot (0-8 inclusive)
+ */
-+ @Range(from = 0, to = 8)
-+ public int getTargetSlot() {
++ public @Range(from = 0, to = 8) int getTargetSlot() {
+ return this.targetSlot;
+ }
+
@@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ *
+ * @param targetSlot hotbar slot (0-8 inclusive)
+ */
-+ public void setTargetSlot(@Range(from = 0, to = 8) int targetSlot) {
++ public void setTargetSlot(final @Range(from = 0, to = 8) int targetSlot) {
+ Preconditions.checkArgument(targetSlot >= 0 && targetSlot <= 8, "Target slot must be in range 0 - 8 (inclusive)");
+ this.targetSlot = targetSlot;
+ }
@@ -70,8 +70,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ *
+ * @return player inventory slot (0-35 inclusive)
+ */
-+ @Range(from = 0, to = 35)
-+ public int getSourceSlot() {
++ public @Range(from = 0, to = 35) int getSourceSlot() {
+ return this.sourceSlot;
+ }
+
@@ -80,7 +79,7 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ *
+ * @param sourceSlot player inventory slot (0-35 inclusive)
+ */
-+ public void setSourceSlot(@Range(from = 0, to = 35) int sourceSlot) {
++ public void setSourceSlot(final @Range(from = 0, to = 35) int sourceSlot) {
+ Preconditions.checkArgument(sourceSlot >= 0 && sourceSlot <= 35, "Source slot must be in range of the player's inventory slot");
+ this.sourceSlot = sourceSlot;
+ }
@@ -91,17 +90,15 @@ index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad153
+ }
+
+ @Override
-+ public void setCancelled(boolean cancel) {
++ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0435-Add-PlayerShieldDisableEvent.patch b/patches/api/0435-Add-PlayerShieldDisableEvent.patch
index 29c7daa0e3..ddc6deadf5 100644
--- a/patches/api/0435-Add-PlayerShieldDisableEvent.patch
+++ b/patches/api/0435-Add-PlayerShieldDisableEvent.patch
@@ -17,10 +17,10 @@ the cooldown event.
diff --git a/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779763e4e42
+index 0000000000000000000000000000000000000000..aa2fb7923b121cda547291d14cff60895361a4dd
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java
-@@ -0,0 +1,92 @@
+@@ -0,0 +1,90 @@
+package io.papermc.paper.event.player;
+
+import com.google.common.base.Preconditions;
@@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called whenever a players shield is disabled due to an attack from another entity that was capable of disabling the
@@ -41,6 +41,7 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+ * It follows that, if this event is cancelled, no {@link PlayerItemCooldownEvent} is called as the shield is never
+ * disabled in the first place.
+ */
++@NullMarked
+public class PlayerShieldDisableEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -51,7 +52,7 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+ private boolean cancelled;
+
+ @ApiStatus.Internal
-+ public PlayerShieldDisableEvent(@NotNull final Player player, @NotNull final Entity damager, final int cooldown) {
++ public PlayerShieldDisableEvent(final Player player, final Entity damager, final int cooldown) {
+ super(player);
+ this.damager = damager;
+ this.cooldown = cooldown;
@@ -62,7 +63,6 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+ *
+ * @return the entity instance that damaged the player in a way that caused the shield to be disabled.
+ */
-+ @NotNull
+ public Entity getDamager() {
+ return this.damager;
+ }
@@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+ *
+ * @param cooldown cooldown in ticks, has to be a positive number
+ */
-+ public void setCooldown(int cooldown) {
++ public void setCooldown(final int cooldown) {
+ Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!");
+ this.cooldown = cooldown;
+ }
@@ -102,13 +102,11 @@ index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779
+ this.cancelled = cancel;
+ }
+
-+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
-+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
diff --git a/patches/api/0455-Add-CartographyItemEvent.patch b/patches/api/0455-Add-CartographyItemEvent.patch
index 1f19663c9f..8bfd237e0c 100644
--- a/patches/api/0455-Add-CartographyItemEvent.patch
+++ b/patches/api/0455-Add-CartographyItemEvent.patch
@@ -7,36 +7,37 @@ Similar to SmithItemEvent, but for cartography tables.
diff --git a/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..659b620696e5cc0784ed707c70876e4348897c7f
+index 0000000000000000000000000000000000000000..d5c67f5462b9011683ce742a197959f9c4380d40
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java
-@@ -0,0 +1,31 @@
+@@ -0,0 +1,32 @@
+package io.papermc.paper.event.player;
+
-+import org.bukkit.inventory.InventoryView;
-+import org.bukkit.inventory.CartographyInventory;
+import org.bukkit.event.inventory.ClickType;
-+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.event.inventory.InventoryClickEvent;
-+import org.jetbrains.annotations.NotNull;
++import org.bukkit.event.inventory.InventoryType;
++import org.bukkit.inventory.CartographyInventory;
++import org.bukkit.inventory.InventoryView;
+import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the recipe of an Item is completed inside a cartography table.
+ */
++@NullMarked
+public class CartographyItemEvent extends InventoryClickEvent {
++
+ @ApiStatus.Internal
-+ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action) {
++ public CartographyItemEvent(final InventoryView view, final InventoryType.SlotType type, final int slot, final ClickType click, final InventoryAction action) {
+ super(view, type, slot, click, action);
+ }
+
+ @ApiStatus.Internal
-+ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action, int key) {
++ public CartographyItemEvent(final InventoryView view, final InventoryType.SlotType type, final int slot, final ClickType click, final InventoryAction action, final int key) {
+ super(view, type, slot, click, action, key);
+ }
+
-+ @NotNull
+ @Override
+ public CartographyInventory getInventory() {
+ return (CartographyInventory) super.getInventory();
diff --git a/patches/api/0466-Brigadier-based-command-API.patch b/patches/api/0466-Brigadier-based-command-API.patch
index 55f6b99973..34193bec69 100644
--- a/patches/api/0466-Brigadier-based-command-API.patch
+++ b/patches/api/0466-Brigadier-based-command-API.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Brigadier based command API
Co-authored-by: Jake Potrebic <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index 37ff4cb89dfb28eab6f836840ff1838d67895c1e..2074c9aee1affbce57571398f8519f0d425cf5e3 100644
+index 76aa23da778b0fe8a093429c56cb29b044359b40..ab84a1405acc1f0d5f267892243b82b8dab03e21 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -27,6 +27,7 @@ configurations.api {
@@ -102,10 +102,10 @@ index 0000000000000000000000000000000000000000..28b44789e3be586c4b680fff56e5d2ff
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..18e0618901eb6eec7677661b8448cb95926ee3ab
+index 0000000000000000000000000000000000000000..9e1b70d438c4341ec944503b5bbe6b1f08bc0478
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java
-@@ -0,0 +1,72 @@
+@@ -0,0 +1,73 @@
+package com.destroystokyo.paper.event.brigadier;
+
+import com.mojang.brigadier.tree.RootCommandNode;
@@ -141,7 +141,7 @@ index 0000000000000000000000000000000000000000..18e0618901eb6eec7677661b8448cb95
+@NullMarked
+public class AsyncPlayerSendCommandsEvent<S extends CommandSourceStack> extends PlayerEvent {
+
-+ private static final HandlerList handlers = new HandlerList();
++ private static final HandlerList HANDLER_LIST = new HandlerList();
+ private final RootCommandNode<S> node;
+ private final boolean hasFiredAsync;
+
@@ -170,20 +170,21 @@ index 0000000000000000000000000000000000000000..18e0618901eb6eec7677661b8448cb95
+ return this.hasFiredAsync;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
-+ return handlers;
++ return HANDLER_LIST;
+ }
+
+ public static HandlerList getHandlerList() {
-+ return handlers;
++ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java
new file mode 100644
-index 0000000000000000000000000000000000000000..f2ed3af699c2df92227693830c135d0b4718d41f
+index 0000000000000000000000000000000000000000..faade9d35514687f21a0e8b62fa2e392d4ad238a
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,85 @@
+package com.destroystokyo.paper.event.brigadier;
+
+import com.mojang.brigadier.suggestion.Suggestions;
@@ -203,7 +204,7 @@ index 0000000000000000000000000000000000000000..f2ed3af699c2df92227693830c135d0b
+@NullMarked
+public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable {
+
-+ private static final HandlerList handlers = new HandlerList();
++ private static final HandlerList HANDLER_LIST = new HandlerList();
+ private boolean cancelled = false;
+
+ private Suggestions suggestions;
@@ -260,12 +261,13 @@ index 0000000000000000000000000000000000000000..f2ed3af699c2df92227693830c135d0b
+ this.cancelled = cancel;
+ }
+
++ @Override
+ public HandlerList getHandlers() {
-+ return handlers;
++ return HANDLER_LIST;
+ }
+
+ public static HandlerList getHandlerList() {
-+ return handlers;
++ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java
diff --git a/patches/server/0353-Implement-Mob-Goal-API.patch b/patches/server/0353-Implement-Mob-Goal-API.patch
index 9382352103..a3f61fbfbf 100644
--- a/patches/server/0353-Implement-Mob-Goal-API.patch
+++ b/patches/server/0353-Implement-Mob-Goal-API.patch
@@ -460,10 +460,10 @@ index 0000000000000000000000000000000000000000..26c745dd9ccdfdd5c5039f2acc5201b9
+}
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java
new file mode 100644
-index 0000000000000000000000000000000000000000..24c30e8a462c59829ab2bd9ee52a1b248550d8ab
+index 0000000000000000000000000000000000000000..e8a427ea777af040d0e2b9cc0ba2a80b9176d026
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java
-@@ -0,0 +1,224 @@
+@@ -0,0 +1,226 @@
+package com.destroystokyo.paper.entity.ai;
+
+import java.util.Collection;
@@ -476,7 +476,9 @@ index 0000000000000000000000000000000000000000..24c30e8a462c59829ab2bd9ee52a1b24
+import net.minecraft.world.entity.ai.goal.WrappedGoal;
+import org.bukkit.craftbukkit.entity.CraftMob;
+import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
+
++@NullMarked
+public class PaperMobGoals implements MobGoals {
+
+ @Override