Begin switching to JSpecify annotations (#11448)

* Begin switching to JSpecify annotations

* more

* fixes
This commit is contained in:
Jake Potrebic 2024-09-29 12:52:13 -07:00 committed by GitHub
parent 6d7a438fad
commit f9c7f2a5c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
66 changed files with 750 additions and 920 deletions

View file

@ -5,10 +5,10 @@ Subject: [PATCH] Build system changes
diff --git a/build.gradle.kts b/build.gradle.kts
index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..a918fd14c95e714e935758d60bccd72755e00b11 100644
index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..2e99ea99cfc96b3602ba26b20a402e7d30f0f05f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -18,15 +18,26 @@ dependencies {
@@ -18,15 +18,27 @@ dependencies {
api("net.md-5:bungeecord-chat:$bungeeCordChatVersion")
api("org.yaml:snakeyaml:2.2")
api("org.joml:joml:1.10.5")
@ -32,11 +32,12 @@ index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..a918fd14c95e714e935758d60bccd727
+ compileOnlyApi(checkerQual)
+ testCompileOnly(checkerQual)
+ // Paper end
+ api("org.jspecify:jspecify:1.0.0") // Paper - add jspecify
+
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 +80,12 @@ tasks.withType<Javadoc> {
@@ -69,8 +81,12 @@ tasks.withType<Javadoc> {
options.links(
"https://guava.dev/releases/32.1.2-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
@ -50,7 +51,7 @@ index 6271e2bad0ed937c2c46a8c8fdf186c46b0b620e..a918fd14c95e714e935758d60bccd727
)
options.tags("apiNote:a:API Note:")
@@ -89,3 +104,14 @@ tasks.withType<Javadoc> {
@@ -89,3 +105,14 @@ tasks.withType<Javadoc> {
tasks.test {
useJUnitPlatform()
}

View file

@ -12,10 +12,10 @@ Co-authored-by: Riley Park <rileysebastianpark@gmail.com>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/build.gradle.kts b/build.gradle.kts
index a918fd14c95e714e935758d60bccd72755e00b11..768024b2b4584fd7dd86f068c0e79c89ffc5faa1 100644
index 2e99ea99cfc96b3602ba26b20a402e7d30f0f05f..d91ce069b5fce4afb245691bd90f448d6dfdc492 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -105,6 +105,12 @@ tasks.test {
@@ -106,6 +106,12 @@ tasks.test {
useJUnitPlatform()
}
@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..77154095cfb8b259bdb318e8ff40cb6f
+ }
+}
diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9d6888609 100644
index 64e7aef6220097edefdff3b98a771b988365930d..7ff939ea41417bad3a436a87c89d5efa7ecefe86 100644
--- a/src/test/java/org/bukkit/AnnotationTest.java
+++ b/src/test/java/org/bukkit/AnnotationTest.java
@@ -29,7 +29,13 @@ public class AnnotationTest {
@ -103,7 +103,19 @@ index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9
};
@Test
@@ -67,14 +83,48 @@ public class AnnotationTest {
@@ -61,20 +77,60 @@ public class AnnotationTest {
continue;
}
+ // Paper start - skip class if it's @NullMarked
+ if (isClassNullMarked(clazz)) {
+ return;
+ }
+ // Paper end - skip class if it's @NullMarked
+
for (MethodNode method : clazz.methods) {
if (!isMethodIncluded(clazz, method, foundClasses)) {
continue;
}
if (mustBeAnnotated(Type.getReturnType(method.desc)) && !isWellAnnotated(method.invisibleAnnotations)) {
@ -152,7 +164,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9
ParameterNode paramNode = parameters == null ? null : parameters.get(i);
String paramName = paramNode == null ? null : paramNode.name;
@@ -91,13 +141,18 @@ public class AnnotationTest {
@@ -91,13 +147,18 @@ public class AnnotationTest {
Collections.sort(errors);
@ -175,7 +187,20 @@ index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9
}
private static void collectClasses(@NotNull File from, @NotNull Map<String, ClassNode> to) throws IOException {
@@ -140,6 +195,11 @@ public class AnnotationTest {
@@ -125,6 +186,12 @@ public class AnnotationTest {
}
}
+ // Paper start - skip class if it's @NullMarked
+ private static boolean isClassNullMarked(@NotNull ClassNode clazz) {
+ return clazz.visibleAnnotations != null && clazz.visibleAnnotations.stream().anyMatch(node -> "Lorg/jspecify/annotations/NullMarked;".equals(node.desc));
+ }
+ // Paper end - skip class if it's @NullMarked
+
private static boolean isClassIncluded(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) {
// Exclude private, synthetic or deprecated classes and annotations, since their members can't be null
if ((clazz.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED | Opcodes.ACC_ANNOTATION)) != 0) {
@@ -140,6 +207,11 @@ public class AnnotationTest {
// Exceptions are excluded
return false;
}
@ -187,7 +212,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9
for (String excludedClass : EXCLUDED_CLASSES) {
if (excludedClass.equals(clazz.name)) {
@@ -152,7 +212,7 @@ public class AnnotationTest {
@@ -152,7 +224,7 @@ public class AnnotationTest {
private static boolean isMethodIncluded(@NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull Map<String, ClassNode> allClasses) {
// Exclude private, synthetic and deprecated methods
@ -196,7 +221,7 @@ index 64e7aef6220097edefdff3b98a771b988365930d..d9091ba1e5a55e03adca98305233cce9
return false;
}
@@ -170,11 +230,30 @@ public class AnnotationTest {
@@ -170,11 +242,30 @@ public class AnnotationTest {
if ("<init>".equals(method.name) && isAnonymous(clazz)) {
return false;
}

View file

@ -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 768024b2b4584fd7dd86f068c0e79c89ffc5faa1..f11a22ab01e97e51619c96f2d8a78a99297efc59 100644
index d91ce069b5fce4afb245691bd90f448d6dfdc492..f715ae19c1e71d854a722130d3db447887fa2d2b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,6 +1,7 @@
@ -18,7 +18,7 @@ index 768024b2b4584fd7dd86f068c0e79c89ffc5faa1..f11a22ab01e97e51619c96f2d8a78a99
}
java {
@@ -45,6 +46,22 @@ dependencies {
@@ -46,6 +47,22 @@ dependencies {
testImplementation("org.ow2.asm:asm-tree:9.7")
}
@ -41,7 +41,7 @@ index 768024b2b4584fd7dd86f068c0e79c89ffc5faa1..f11a22ab01e97e51619c96f2d8a78a99
configure<PublishingExtension> {
publications.create<MavenPublication>("maven") {
from(components["java"])
@@ -121,3 +138,14 @@ tasks.check {
@@ -122,3 +139,14 @@ tasks.check {
dependsOn(scanJar)
}
// Paper end

View file

@ -8,7 +8,7 @@ Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Yannick Lamprecht <yannicklamprecht@live.de>
diff --git a/build.gradle.kts b/build.gradle.kts
index 2f266350a787a4cfdfda1b0e760bfb7604cac43c..af3514113abdf3f42c41f1e7ff0f930cc1a417f5 100644
index 7470f18dc36c5e4357ce3bb936c4842066df9114..7624069435a9be6c4249a444db0bf1bf54691caa 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,12 +11,28 @@ java {
@ -55,7 +55,7 @@ index 2f266350a787a4cfdfda1b0e760bfb7604cac43c..af3514113abdf3f42c41f1e7ff0f930c
// Paper end
compileOnly("org.apache.maven:maven-resolver-provider:3.9.6")
@@ -99,14 +122,31 @@ tasks.withType<Javadoc> {
@@ -100,14 +123,31 @@ 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

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Paper Plugins
diff --git a/build.gradle.kts b/build.gradle.kts
index ed0b67ac322aa22b191cd35502ae5b4f20af19f8..258d7010d24c529c9bbc76cc26adf226c641ee58 100644
index dd1e8d3fda7ae6e5f0dfc6a5293f1ac4eb5fd3f4..b88bf39df6fb920b2c802e7057468c1476d63778 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -52,7 +52,7 @@ dependencies {
@ -17,7 +17,7 @@ index ed0b67ac322aa22b191cd35502ae5b4f20af19f8..258d7010d24c529c9bbc76cc26adf226
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
@@ -139,6 +139,7 @@ tasks.withType<Javadoc> {
@@ -140,6 +140,7 @@ tasks.withType<Javadoc> {
"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
// Paper end

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add BeaconEffectEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1288f8f13
index 0000000000000000000000000000000000000000..741d0e73bc635a545c94c4b1254cee8f41ba8925
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
@@ -0,0 +1,91 @@
@@ -0,0 +1,88 @@
+package com.destroystokyo.paper.event.block;
+
+import org.bukkit.block.Block;
@ -19,11 +19,12 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+import org.bukkit.event.block.BlockEvent;
+import org.bukkit.potion.PotionEffect;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a beacon effect is being applied to a player.
+ */
+@NullMarked
+public class BeaconEffectEvent extends BlockEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -35,7 +36,7 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public BeaconEffectEvent(@NotNull Block block, @NotNull PotionEffect effect, @NotNull Player player, boolean primary) {
+ public BeaconEffectEvent(final Block block, final PotionEffect effect, final Player player, final boolean primary) {
+ super(block);
+ this.effect = effect;
+ this.player = player;
@ -47,7 +48,6 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+ *
+ * @return Potion effect
+ */
+ @NotNull
+ public PotionEffect getEffect() {
+ return this.effect;
+ }
@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+ *
+ * @param effect Potion effect
+ */
+ public void setEffect(@NotNull PotionEffect effect) {
+ public void setEffect(final PotionEffect effect) {
+ this.effect = effect;
+ }
+
@ -66,7 +66,6 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+ *
+ * @return Affected player
+ */
+ @NotNull
+ public Player getPlayer() {
+ return this.player;
+ }
@ -86,17 +85,15 @@ index 0000000000000000000000000000000000000000..7270c1feece2dc15a4a0503c4bca93a1
+ }
+
+ @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;
+ }

View file

@ -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..1d8e3c93a139bba11affca74b742269f24300d2c
index 0000000000000000000000000000000000000000..990b307801be996a4707d87e420b05ee25286d5b
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
@@ -0,0 +1,45 @@
@@ -0,0 +1,43 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.World;
@ -18,21 +18,22 @@ index 0000000000000000000000000000000000000000..1d8e3c93a139bba11affca74b742269f
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired any time an entity is being added to the world for any reason (including a chunk loading).
+ * <p>
+ * Not to be confused with {@link CreatureSpawnEvent}
+ */
+@NullMarked
+public class EntityAddToWorldEvent extends EntityEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final World world;
+ private final World world;
+
+ @ApiStatus.Internal
+ public EntityAddToWorldEvent(@NotNull Entity entity, @NotNull World world) {
+ public EntityAddToWorldEvent(final Entity entity, final World world) {
+ super(entity);
+ this.world = world;
+ }
@ -40,27 +41,24 @@ index 0000000000000000000000000000000000000000..1d8e3c93a139bba11affca74b742269f
+ /**
+ * @return The world that the entity is being added to
+ */
+ @NotNull
+ public World getWorld() {
+ return this.world;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
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..d75e6a8334c7408ea8c3f155414fc14dc427f190
index 0000000000000000000000000000000000000000..b7776c1e65c8140a1e800df56bda5bec5717b50e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
@@ -0,0 +1,43 @@
@@ -0,0 +1,41 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.World;
@ -68,20 +66,21 @@ index 0000000000000000000000000000000000000000..d75e6a8334c7408ea8c3f155414fc14d
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired any time an entity is being removed from a world for any reason (including a chunk unloading).
+ * Note: The entity is updated prior to this event being called, as such, the entity's world may not be equal to {@link #getWorld()}.
+ */
+@NullMarked
+public class EntityRemoveFromWorldEvent extends EntityEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final World world;
+ private final World world;
+
+ @ApiStatus.Internal
+ public EntityRemoveFromWorldEvent(@NotNull Entity entity, @NotNull World world) {
+ public EntityRemoveFromWorldEvent(final Entity entity, final World world) {
+ super(entity);
+ this.world = world;
+ }
@ -89,17 +88,14 @@ index 0000000000000000000000000000000000000000..d75e6a8334c7408ea8c3f155414fc14d
+ /**
+ * @return The world that the entity is being removed from
+ */
+ @NotNull
+ public World getWorld() {
+ return this.world;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -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..8267e8f1f0ade29a284831069e1268ee4b29e109
index 0000000000000000000000000000000000000000..2dd25136d81624025244a82de119fbecd0d7224c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
@@ -0,0 +1,87 @@
@@ -0,0 +1,83 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@ -19,8 +19,8 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+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;
+
+/**
+ * Fired when an Entity decides to start moving towards a location.
@ -28,16 +28,17 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+ * This event does not fire for the entities actual movement. Only when it
+ * is choosing to start moving to a location.
+ */
+@NullMarked
+public class EntityPathfindEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @Nullable private final Entity targetEntity;
+ @NotNull private final Location location;
+ private final @Nullable Entity targetEntity;
+ private final Location location;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityPathfindEvent(@NotNull Entity entity, @NotNull Location location, @Nullable Entity targetEntity) {
+ public EntityPathfindEvent(final Entity entity, final Location location, final @Nullable Entity targetEntity) {
+ super(entity);
+ this.targetEntity = targetEntity;
+ this.location = location;
@ -48,7 +49,6 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+ *
+ * @return The Entity that is pathfinding.
+ */
+ @NotNull
+ public Entity getEntity() {
+ return this.entity;
+ }
@ -56,12 +56,11 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+ /**
+ * If the Entity is trying to pathfind to an entity, this is the entity in relation.
+ * <br>
+ * Otherwise this will return {@code null}.
+ * Otherwise, this will return {@code null}.
+ *
+ * @return The entity target or {@code null}
+ */
+ @Nullable
+ public Entity getTargetEntity() {
+ public @Nullable Entity getTargetEntity() {
+ return this.targetEntity;
+ }
+
@ -72,7 +71,6 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+ *
+ * @return Location of where the entity is trying to pathfind to.
+ */
+ @NotNull
+ public Location getLoc() {
+ return this.location.clone();
+ }
@ -83,17 +81,15 @@ index 0000000000000000000000000000000000000000..8267e8f1f0ade29a284831069e1268ee
+ }
+
+ @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;
+ }

View file

@ -7,13 +7,14 @@ Subject: [PATCH] Add handshake event to allow plugins to handle client
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4ce03ef477
index 0000000000000000000000000000000000000000..aea04fb357f5728195fd9c9bdcd6304a0b953c45
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
@@ -0,0 +1,267 @@
@@ -0,0 +1,257 @@
+package com.destroystokyo.paper.event.player;
+
+import com.google.common.base.Preconditions;
+import java.util.UUID;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@ -21,10 +22,8 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+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 java.util.UUID;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * This event is fired during a player handshake.
@ -34,16 +33,17 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * <p>WARNING: TAMPERING WITH THIS EVENT CAN BE DANGEROUS</p>
+ */
+@NullMarked
+public class PlayerHandshakeEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final String originalHandshake;
+ @NotNull private final String originalSocketAddressHostname;
+ @Nullable private String serverHostname;
+ @Nullable private String socketAddressHostname;
+ @Nullable private UUID uniqueId;
+ @Nullable private String propertiesJson;
+ private final String originalHandshake;
+ private final String originalSocketAddressHostname;
+ private @Nullable String serverHostname;
+ private @Nullable String socketAddressHostname;
+ private @Nullable UUID uniqueId;
+ private @Nullable String propertiesJson;
+ private boolean failed;
+ private Component failMessage = Component.text("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!", NamedTextColor.YELLOW);
+
@ -51,12 +51,12 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+
+ @Deprecated
+ @ApiStatus.Internal
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, boolean cancelled) {
+ public PlayerHandshakeEvent(final String originalHandshake, final boolean cancelled) {
+ this(originalHandshake, "127.0.0.1", cancelled);
+ }
+
+ @ApiStatus.Internal
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, @NotNull String originalSocketAddressHostname, boolean cancelled) {
+ public PlayerHandshakeEvent(final String originalHandshake, final String originalSocketAddressHostname, final boolean cancelled) {
+ super(true);
+ this.originalHandshake = originalHandshake;
+ this.originalSocketAddressHostname = originalSocketAddressHostname;
@ -85,7 +85,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ * @param cancel {@code true} if this event is cancelled, {@code false} otherwise
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
@ -94,7 +94,6 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the original handshake string
+ */
+ @NotNull
+ public String getOriginalHandshake() {
+ return this.originalHandshake;
+ }
@ -107,7 +106,6 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the original socket address hostname
+ */
+ @NotNull
+ public String getOriginalSocketAddressHostname() {
+ return this.originalSocketAddressHostname;
+ }
@ -119,8 +117,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the server hostname string
+ */
+ @Nullable
+ public String getServerHostname() {
+ public @Nullable String getServerHostname() {
+ return this.serverHostname;
+ }
+
@ -131,7 +128,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param serverHostname the server hostname string
+ */
+ public void setServerHostname(@NotNull String serverHostname) {
+ public void setServerHostname(final String serverHostname) {
+ this.serverHostname = serverHostname;
+ }
+
@ -142,8 +139,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the socket address hostname string
+ */
+ @Nullable
+ public String getSocketAddressHostname() {
+ public @Nullable String getSocketAddressHostname() {
+ return this.socketAddressHostname;
+ }
+
@ -154,7 +150,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param socketAddressHostname the socket address hostname string
+ */
+ public void setSocketAddressHostname(@NotNull String socketAddressHostname) {
+ public void setSocketAddressHostname(final String socketAddressHostname) {
+ this.socketAddressHostname = socketAddressHostname;
+ }
+
@ -163,8 +159,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the unique id
+ */
+ @Nullable
+ public UUID getUniqueId() {
+ public @Nullable UUID getUniqueId() {
+ return this.uniqueId;
+ }
+
@ -173,7 +168,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param uniqueId the unique id
+ */
+ public void setUniqueId(@NotNull UUID uniqueId) {
+ public void setUniqueId(final UUID uniqueId) {
+ this.uniqueId = uniqueId;
+ }
+
@ -184,8 +179,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the profile properties, as JSON
+ */
+ @Nullable
+ public String getPropertiesJson() {
+ public @Nullable String getPropertiesJson() {
+ return this.propertiesJson;
+ }
+
@ -209,7 +203,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param failed {@code true} if authentication failed, {@code false} otherwise
+ */
+ public void setFailed(boolean failed) {
+ public void setFailed(final boolean failed) {
+ this.failed = failed;
+ }
+
@ -220,7 +214,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param propertiesJson the profile properties, as JSON
+ */
+ public void setPropertiesJson(@NotNull String propertiesJson) {
+ public void setPropertiesJson(final String propertiesJson) {
+ this.propertiesJson = propertiesJson;
+ }
+
@ -229,7 +223,6 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @return the message to display to the client
+ */
+ @NotNull
+ public Component failMessage() {
+ return this.failMessage;
+ }
@ -239,7 +232,7 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ *
+ * @param failMessage the message to display to the client
+ */
+ public void failMessage(@NotNull Component failMessage) {
+ public void failMessage(final Component failMessage) {
+ this.failMessage = failMessage;
+ }
+
@ -249,7 +242,6 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ * @return the message to display to the client
+ * @deprecated use {@link #failMessage()}
+ */
+ @NotNull
+ @Deprecated
+ public String getFailMessage() {
+ return LegacyComponentSerializer.legacySection().serialize(this.failMessage());
@ -262,18 +254,16 @@ index 0000000000000000000000000000000000000000..7c049bad187b94331f42f96833d1cf4c
+ * @deprecated use {@link #failMessage(Component)}
+ */
+ @Deprecated
+ public void setFailMessage(@NotNull String failMessage) {
+ public void setFailMessage(final String failMessage) {
+ Preconditions.checkArgument(failMessage != null && !failMessage.isEmpty(), "fail message cannot be null or empty");
+ this.failMessage(LegacyComponentSerializer.legacySection().deserialize(failMessage));
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,34 +6,34 @@ Subject: [PATCH] Add EntityZapEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc6d15975a47e68c5bd939e68ddd2773028a6ac8
index 0000000000000000000000000000000000000000..af2b1629f845ffe1559e7d580b482636cc6441d9
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
@@ -0,0 +1,69 @@
@@ -0,0 +1,65 @@
+package com.destroystokyo.paper.event.entity;
+
+import java.util.Collections;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LightningStrike;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityTransformEvent;
+
+import java.util.Collections;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when lightning strikes an entity
+ */
+@NullMarked
+public class EntityZapEvent extends EntityTransformEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final LightningStrike bolt;
+ private final LightningStrike bolt;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityZapEvent(@NotNull final Entity entity, @NotNull final LightningStrike bolt, @NotNull final Entity replacementEntity) {
+ public EntityZapEvent(final Entity entity, final LightningStrike bolt, final Entity replacementEntity) {
+ super(entity, Collections.singletonList(replacementEntity), TransformReason.LIGHTNING);
+ this.bolt = bolt;
+ }
@ -43,7 +43,6 @@ index 0000000000000000000000000000000000000000..dc6d15975a47e68c5bd939e68ddd2773
+ *
+ * @return The lightning bolt responsible for this event
+ */
+ @NotNull
+ public LightningStrike getBolt() {
+ return this.bolt;
+ }
@ -53,7 +52,6 @@ index 0000000000000000000000000000000000000000..dc6d15975a47e68c5bd939e68ddd2773
+ *
+ * @return The entity that will replace the struck entity
+ */
+ @NotNull
+ public Entity getReplacementEntity() {
+ return super.getTransformedEntity();
+ }
@ -64,17 +62,15 @@ index 0000000000000000000000000000000000000000..dc6d15975a47e68c5bd939e68ddd2773
+ }
+
+ @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;
+ }

View file

@ -8,19 +8,18 @@ profiles that had to be looked up.
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ad2782aafe76f8b10565c0f0419d6b9c665b267
index 0000000000000000000000000000000000000000..9e8ae0ab13cac9a260c9959eb6bf5b93a3c15018
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
@@ -0,0 +1,48 @@
@@ -0,0 +1,45 @@
+package com.destroystokyo.paper.event.profile;
+
+import com.destroystokyo.paper.profile.PlayerProfile;
+import org.bukkit.Bukkit;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Allows a plugin to be notified anytime AFTER a Profile has been looked up from the Mojang API
@ -29,14 +28,15 @@ index 0000000000000000000000000000000000000000..2ad2782aafe76f8b10565c0f0419d6b9
+ * No guarantees are made about thread execution context for this event. If you need to know, check
+ * {@link Event#isAsynchronous()}
+ */
+@NullMarked
+public class LookupProfileEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final PlayerProfile profile;
+ private final PlayerProfile profile;
+
+ @ApiStatus.Internal
+ public LookupProfileEvent(@NotNull PlayerProfile profile) {
+ public LookupProfileEvent(final PlayerProfile profile) {
+ super(!Bukkit.isPrimaryThread());
+ this.profile = profile;
+ }
@ -44,41 +44,37 @@ index 0000000000000000000000000000000000000000..2ad2782aafe76f8b10565c0f0419d6b9
+ /**
+ * @return The profile that was recently looked up. This profile can be mutated
+ */
+ @NotNull
+ public PlayerProfile getPlayerProfile() {
+ return this.profile;
+ }
+
+ @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/PreLookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533dfa474356
index 0000000000000000000000000000000000000000..07416cc9e2b8156be2cc92d6d974b881b427fd99
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
@@ -0,0 +1,112 @@
@@ -0,0 +1,107 @@
+package com.destroystokyo.paper.event.profile;
+
+import com.destroystokyo.paper.profile.ProfileProperty;
+import org.bukkit.Bukkit;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.Bukkit;
+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;
+
+/**
+ * Allows a plugin to intercept a Profile Lookup for a Profile by name
@ -90,17 +86,18 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ * No guarantees are made about thread execution context for this event. If you need to know, check
+ * {@link Event#isAsynchronous()}
+ */
+@NullMarked
+public class PreLookupProfileEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final String name;
+ private final String name;
+
+ private UUID uuid;
+ @NotNull private Set<ProfileProperty> properties = new HashSet<>();
+ private @Nullable UUID uuid;
+ private Set<ProfileProperty> properties = new HashSet<>();
+
+ @ApiStatus.Internal
+ public PreLookupProfileEvent(@NotNull String name) {
+ public PreLookupProfileEvent(final String name) {
+ super(!Bukkit.isPrimaryThread());
+ this.name = name;
+ }
@ -108,7 +105,6 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ /**
+ * @return Name of the profile
+ */
+ @NotNull
+ public String getName() {
+ return this.name;
+ }
@ -120,8 +116,7 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ *
+ * @return The UUID of the profile if it has already been provided by a plugin
+ */
+ @Nullable
+ public UUID getUUID() {
+ public @Nullable UUID getUUID() {
+ return this.uuid;
+ }
+
@ -132,7 +127,7 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ *
+ * @param uuid the UUID to set for the profile or {@code null} to reset
+ */
+ public void setUUID(@Nullable UUID uuid) {
+ public void setUUID(final @Nullable UUID uuid) {
+ this.uuid = uuid;
+ }
+
@ -140,7 +135,6 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ * @return The currently pending pre-populated properties.
+ * Any property in this Set will be automatically prefilled on this Profile
+ */
+ @NotNull
+ public Set<ProfileProperty> getProfileProperties() {
+ return this.properties;
+ }
@ -151,7 +145,7 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ *
+ * @param properties The properties to add
+ */
+ public void setProfileProperties(@NotNull Set<ProfileProperty> properties) {
+ public void setProfileProperties(final Set<ProfileProperty> properties) {
+ this.properties = new HashSet<>();
+ this.properties.addAll(properties);
+ }
@ -162,17 +156,15 @@ index 0000000000000000000000000000000000000000..3f73ec52f9b581001bef3a19a5f1533d
+ *
+ * @param properties The properties to add
+ */
+ public void addProfileProperties(@NotNull Set<ProfileProperty> properties) {
+ public void addProfileProperties(final Set<ProfileProperty> properties) {
+ this.properties.addAll(properties);
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -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 258d7010d24c529c9bbc76cc26adf226c641ee58..4da053d427f3f9c5e7fc144408836ebef80026c6 100644
index b88bf39df6fb920b2c802e7057468c1476d63778..37ff4cb89dfb28eab6f836840ff1838d67895c1e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,6 +12,8 @@ java {
@ -35,7 +35,7 @@ index 258d7010d24c529c9bbc76cc26adf226c641ee58..4da053d427f3f9c5e7fc144408836ebe
implementation("org.ow2.asm:asm:9.7")
implementation("org.ow2.asm:asm-commons:9.7")
@@ -138,6 +142,8 @@ tasks.withType<Javadoc> {
@@ -139,6 +143,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/",
@ -45,7 +45,7 @@ index 258d7010d24c529c9bbc76cc26adf226c641ee58..4da053d427f3f9c5e7fc144408836ebe
"https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3", // Paper
)
diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java
index 8c76716249e44ed8bf6be94c1f5c7b6d9bb35be2..4eb639fbb46a0848be207149ea433455550fae1c 100644
index 68a0ed5f0ed25e98f4ab4d1e482ec2ccfda9cd3a..46fc37a36403c8fbc4c0c9f863d4d57eb3896bd4 100644
--- a/src/main/java/org/bukkit/plugin/Plugin.java
+++ b/src/main/java/org/bukkit/plugin/Plugin.java
@@ -198,6 +198,22 @@ public interface Plugin extends TabExecutor {

View file

@ -17,10 +17,10 @@ Co-authored-by: Aikar <aikar@aikar.co>
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..8965974988ad20fbe1d45885f20a3a98d2e9595f
index 0000000000000000000000000000000000000000..e2bfd86c964ce5a75470fef1ea7e031a95735fb3
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
@@ -0,0 +1,339 @@
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
+ *
@ -48,6 +48,10 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+
+import com.google.common.base.Preconditions;
+import io.papermc.paper.util.TransformingRandomAccessList;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+import net.kyori.adventure.text.Component;
+import net.kyori.examination.Examinable;
+import net.kyori.examination.ExaminableProperty;
@ -58,14 +62,9 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+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;
+
+/**
+ * Allows plugins to compute tab completion results asynchronously.
@ -76,15 +75,15 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ * <p>
+ * Only 1 process will be allowed to provide completions, the Async Event, or the standard process.
+ */
+@NullMarked
+public class AsyncTabCompleteEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final CommandSender sender;
+ @NotNull private final String buffer;
+ private final CommandSender sender;
+ private final String buffer;
+ private final boolean isCommand;
+ @Nullable
+ private final Location location;
+ private final @Nullable Location location;
+ private final List<Completion> completions = new ArrayList<>();
+ private final List<String> stringCompletions = new TransformingRandomAccessList<>(
+ this.completions,
@ -95,7 +94,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public AsyncTabCompleteEvent(@NotNull CommandSender sender, @NotNull String buffer, boolean isCommand, @Nullable Location loc) {
+ public AsyncTabCompleteEvent(final CommandSender sender, final String buffer, final boolean isCommand, final @Nullable Location loc) {
+ super(true);
+ this.sender = sender;
+ this.buffer = buffer;
@ -105,7 +104,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+
+ @Deprecated
+ @ApiStatus.Internal
+ public AsyncTabCompleteEvent(@NotNull CommandSender sender, @NotNull List<String> completions, @NotNull String buffer, boolean isCommand, @Nullable Location loc) {
+ public AsyncTabCompleteEvent(final CommandSender sender, final List<String> completions, final String buffer, final boolean isCommand, final @Nullable Location loc) {
+ super(true);
+ this.sender = sender;
+ this.completions.addAll(fromStrings(completions));
@ -119,7 +118,6 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @return the {@link CommandSender} instance
+ */
+ @NotNull
+ public CommandSender getSender() {
+ return this.sender;
+ }
@ -134,7 +132,6 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @return a list of offered completions
+ */
+ @NotNull
+ public List<String> getCompletions() {
+ return this.stringCompletions;
+ }
@ -149,7 +146,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @param completions the new completions
+ */
+ public void setCompletions(@NotNull List<String> completions) {
+ public void setCompletions(final List<String> completions) {
+ Preconditions.checkArgument(completions != null, "Completions list cannot be null");
+ if (completions == this.stringCompletions) {
+ return;
@ -168,7 +165,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @return a list of offered completions
+ */
+ public @NotNull List<Completion> completions() {
+ public List<Completion> completions() {
+ return this.completions;
+ }
+
@ -182,7 +179,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @param newCompletions the new completions
+ */
+ public void completions(final @NotNull List<Completion> newCompletions) {
+ public void completions(final List<Completion> newCompletions) {
+ Preconditions.checkArgument(newCompletions != null, "new completions cannot be null");
+ this.completions.clear();
+ this.completions.addAll(newCompletions);
@ -193,7 +190,6 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @return command buffer, as entered
+ */
+ @NotNull
+ public String getBuffer() {
+ return this.buffer;
+ }
@ -208,8 +204,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ /**
+ * @return The position looked at by the sender, or {@code null} if none
+ */
+ @Nullable
+ public Location getLocation() {
+ public @Nullable Location getLocation() {
+ return this.location != null ? this.location.clone() : null;
+ }
+
@ -230,7 +225,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @param handled if this completion should be marked as being handled
+ */
+ public void setHandled(boolean handled) {
+ public void setHandled(final boolean handled) {
+ this.handled = handled;
+ }
+
@ -245,21 +240,19 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ * Will provide no completions, and will not fire the synchronous process
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ private static @NotNull List<Completion> fromStrings(final @NotNull List<String> suggestions) {
+ private static List<Completion> fromStrings(final List<String> suggestions) {
+ final List<Completion> list = new ArrayList<>(suggestions.size());
+ for (final String suggestion : suggestions) {
+ list.add(new CompletionImpl(suggestion, null));
@ -277,7 +270,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ *
+ * @return suggestion string
+ */
+ @NotNull String suggestion();
+ String suggestion();
+
+ /**
+ * Get the suggestion tooltip for this {@link Completion}.
@ -287,7 +280,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ @Nullable Component tooltip();
+
+ @Override
+ default @NotNull Stream<? extends ExaminableProperty> examinableProperties() {
+ default Stream<? extends ExaminableProperty> examinableProperties() {
+ return Stream.of(ExaminableProperty.of("suggestion", this.suggestion()), ExaminableProperty.of("tooltip", this.tooltip()));
+ }
+
@ -297,7 +290,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ * @param suggestion suggestion string
+ * @return new completion instance
+ */
+ static @NotNull Completion completion(final @NotNull String suggestion) {
+ static Completion completion(final String suggestion) {
+ return new CompletionImpl(suggestion, null);
+ }
+
@ -310,7 +303,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ * @param tooltip tooltip component, or {@code null}
+ * @return new completion instance
+ */
+ static @NotNull Completion completion(final @NotNull String suggestion, final @Nullable Component tooltip) {
+ static Completion completion(final String suggestion, final @Nullable Component tooltip) {
+ return new CompletionImpl(suggestion, tooltip);
+ }
+ }
@ -319,15 +312,15 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ static final class CompletionImpl implements Completion {
+
+ private final String suggestion;
+ private final Component tooltip;
+ private final @Nullable Component tooltip;
+
+ CompletionImpl(final @NotNull String suggestion, final @Nullable Component tooltip) {
+ CompletionImpl(final String suggestion, final @Nullable Component tooltip) {
+ this.suggestion = suggestion;
+ this.tooltip = tooltip;
+ }
+
+ @Override
+ public @NotNull String suggestion() {
+ public String suggestion() {
+ return this.suggestion;
+ }
+
@ -355,7 +348,7 @@ index 0000000000000000000000000000000000000000..8965974988ad20fbe1d45885f20a3a98
+ }
+
+ @Override
+ public @NotNull String toString() {
+ public String toString() {
+ return StringExaminer.simpleEscaping().examine(this);
+ }
+ }
@ -599,7 +592,7 @@ index 270e6d8ad4358baa256cee5f16cff281f063ce3b..6465e290c090d82986352d5ab7ba5dc6
@Override
diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
index d9091ba1e5a55e03adca98305233cce9d6888609..b82f07a2879412f6b30643ca93a97439aa49a98a 100644
index 65cca227207efb8177f3cdbcbff5fe0c3b8a563f..d3a2cb7cf1bc708002fa0b7a44c03ed53fc0c454 100644
--- a/src/test/java/org/bukkit/AnnotationTest.java
+++ b/src/test/java/org/bukkit/AnnotationTest.java
@@ -48,6 +48,8 @@ public class AnnotationTest {

View file

@ -12,10 +12,10 @@ Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..c520e5517861c4686806df233d1ef5e6bfb76ad3
index 0000000000000000000000000000000000000000..5902e6d6c0516a1249c72b405a49dfc5cc490e0e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
@@ -0,0 +1,91 @@
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
+ *
@ -46,22 +46,23 @@ index 0000000000000000000000000000000000000000..c520e5517861c4686806df233d1ef5e6
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired anytime the server is about to merge 2 experience orbs into one
+ */
+@NullMarked
+public class ExperienceOrbMergeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final ExperienceOrb mergeTarget;
+ @NotNull private final ExperienceOrb mergeSource;
+ private final ExperienceOrb mergeTarget;
+ private final ExperienceOrb mergeSource;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public ExperienceOrbMergeEvent(@NotNull ExperienceOrb mergeTarget, @NotNull ExperienceOrb mergeSource) {
+ public ExperienceOrbMergeEvent(final ExperienceOrb mergeTarget, final ExperienceOrb mergeSource) {
+ super(mergeTarget);
+ this.mergeTarget = mergeTarget;
+ this.mergeSource = mergeSource;
@ -70,7 +71,6 @@ index 0000000000000000000000000000000000000000..c520e5517861c4686806df233d1ef5e6
+ /**
+ * @return The orb that will absorb the other experience orb
+ */
+ @NotNull
+ public ExperienceOrb getMergeTarget() {
+ return this.mergeTarget;
+ }
@ -78,7 +78,6 @@ index 0000000000000000000000000000000000000000..c520e5517861c4686806df233d1ef5e6
+ /**
+ * @return The orb that is subject to being removed and merged into the target orb
+ */
+ @NotNull
+ public ExperienceOrb getMergeSource() {
+ return this.mergeSource;
+ }
@ -92,17 +91,15 @@ index 0000000000000000000000000000000000000000..c520e5517861c4686806df233d1ef5e6
+ * @param cancel {@code true} if you wish to cancel this event, and prevent the orbs from merging
+ */
+ @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;
+ }

View file

@ -16,10 +16,10 @@ See: https://github.com/PaperMC/Paper/issues/917
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f93ffc2a4
index 0000000000000000000000000000000000000000..c1c96f93a4a5450381cb5bdb198b056a37ba0fbe
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java
@@ -0,0 +1,109 @@
@@ -0,0 +1,105 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * WARNING: This event only fires for a limited number of cases, and not for every case that {@link CreatureSpawnEvent} does.
@ -41,19 +41,20 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ * Currently: NATURAL and SPAWNER based reasons. <!-- Please submit a Pull Request for future additions. -->
+ * Also, Plugins that replace Entity Registrations with their own custom entities might not fire this event.
+ */
+@NullMarked
+public class PreCreatureSpawnEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final Location location;
+ @NotNull private final EntityType type;
+ @NotNull private final CreatureSpawnEvent.SpawnReason reason;
+ private final Location location;
+ private final EntityType type;
+ private final CreatureSpawnEvent.SpawnReason reason;
+ private boolean shouldAbortSpawn;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public PreCreatureSpawnEvent(@NotNull Location location, @NotNull EntityType type, @NotNull CreatureSpawnEvent.SpawnReason reason) {
+ public PreCreatureSpawnEvent(final Location location, final EntityType type, final CreatureSpawnEvent.SpawnReason reason) {
+ this.location = location;
+ this.type = type;
+ this.reason = reason;
@ -62,7 +63,6 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ /**
+ * @return The location this creature is being spawned at
+ */
+ @NotNull
+ public Location getSpawnLocation() {
+ return this.location.clone();
+ }
@ -70,7 +70,6 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ /**
+ * @return The type of creature being spawned
+ */
+ @NotNull
+ public EntityType getType() {
+ return this.type;
+ }
@ -78,7 +77,6 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ /**
+ * @return Reason this creature is spawning (ie, NATURAL vs SPAWNER)
+ */
+ @NotNull
+ public CreatureSpawnEvent.SpawnReason getReason() {
+ return this.reason;
+ }
@ -96,7 +94,7 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ *
+ * @param shouldAbortSpawn Set if the spawn process should be aborted vs trying more attempts
+ */
+ public void setShouldAbortSpawn(boolean shouldAbortSpawn) {
+ public void setShouldAbortSpawn(final boolean shouldAbortSpawn) {
+ this.shouldAbortSpawn = shouldAbortSpawn;
+ }
+
@ -114,17 +112,15 @@ index 0000000000000000000000000000000000000000..633ef4dcc701916f2dbfefbbebd5994f
+ * @param cancel {@code true} if you wish to cancel this event, and abort the spawn of this creature
+ */
+ @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;
+ }

View file

@ -10,10 +10,10 @@ Also a highly more effecient way to blanket block spawns in a world
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fcee73d61347165cefef7b92f0e63e0bed8ad73
index 0000000000000000000000000000000000000000..a3267a283b39e8db1e9b7e5338d2909320f1421c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java
@@ -0,0 +1,66 @@
@@ -0,0 +1,65 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Player;
@ -21,11 +21,12 @@ index 0000000000000000000000000000000000000000..7fcee73d61347165cefef7b92f0e63e0
+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 the server is calculating what chunks to try to spawn monsters in every Monster Spawn Tick event
+ */
+@NullMarked
+public class PlayerNaturallySpawnCreaturesEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..7fcee73d61347165cefef7b92f0e63e0
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public PlayerNaturallySpawnCreaturesEvent(@NotNull Player player, byte radius) {
+ public PlayerNaturallySpawnCreaturesEvent(final Player player, final byte radius) {
+ super(player);
+ this.radius = radius;
+ }
@ -49,12 +50,12 @@ index 0000000000000000000000000000000000000000..7fcee73d61347165cefef7b92f0e63e0
+ /**
+ * @param radius The radius of chunks around this player to be included in natural spawn selection
+ */
+ public void setSpawnRadius(byte radius) {
+ public void setSpawnRadius(final byte radius) {
+ this.radius = radius;
+ }
+
+ /**
+ * @return If this players chunks will be excluded from natural spawns
+ * @return If this player's chunks will be excluded from natural spawns
+ */
+ @Override
+ public boolean isCancelled() {
@ -62,20 +63,18 @@ index 0000000000000000000000000000000000000000..7fcee73d61347165cefef7b92f0e63e0
+ }
+
+ /**
+ * @param cancel {@code true} if you wish to cancel this event, and not include this players chunks for natural spawning
+ * @param cancel {@code true} if you wish to cancel this event, and not include this player's chunks for natural spawning
+ */
+ @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;
+ }

View file

@ -9,10 +9,10 @@ You may cancel this, enabling ranged attacks to damage the enderman for example.
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6be848c44d5efaca3fbc03c3be7451411943c24
index 0000000000000000000000000000000000000000..ae72916972dbe86bfbca499eb7b6f97b1a6eae25
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
@@ -0,0 +1,86 @@
@@ -0,0 +1,83 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Enderman;
@ -20,22 +20,22 @@ index 0000000000000000000000000000000000000000..f6be848c44d5efaca3fbc03c3be74514
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+@NullMarked
+public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final Reason reason;
+ private final Reason reason;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EndermanEscapeEvent(@NotNull Enderman entity, @NotNull Reason reason) {
+ public EndermanEscapeEvent(final Enderman entity, final Reason reason) {
+ super(entity);
+ this.reason = reason;
+ }
+
+ @NotNull
+ @Override
+ public Enderman getEntity() {
+ return (Enderman) super.getEntity();
@ -44,7 +44,6 @@ index 0000000000000000000000000000000000000000..f6be848c44d5efaca3fbc03c3be74514
+ /**
+ * @return The reason the enderman is trying to escape
+ */
+ @NotNull
+ public Reason getReason() {
+ return this.reason;
+ }
@ -57,21 +56,19 @@ index 0000000000000000000000000000000000000000..f6be848c44d5efaca3fbc03c3be74514
+ /**
+ * Cancels the escape.
+ * <p>
+ * If this escape normally would of resulted in damage avoidance such as indirect,
+ * If this escape normally had resulted in damage avoidance such as indirect,
+ * the enderman will now take damage.
+ */
+ @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;
+ }

View file

@ -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..ae34e679723a2ef436da04c116038272743a8f35
index 0000000000000000000000000000000000000000..b261e0420002da3f94862e664edc65536cd05fc8
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
@@ -0,0 +1,101 @@
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ *
@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..ae34e679723a2ef436da04c116038272
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when an Enderman determines if it should attack a player or not.
@ -52,15 +52,16 @@ index 0000000000000000000000000000000000000000..ae34e679723a2ef436da04c116038272
+ * Starts off cancelled if the player is wearing a pumpkin head or is not looking
+ * at the Enderman, according to Vanilla rules.
+ */
+@NullMarked
+public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final Player player;
+ private final Player player;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EndermanAttackPlayerEvent(@NotNull Enderman entity, @NotNull Player player) {
+ public EndermanAttackPlayerEvent(final Enderman entity, final Player player) {
+ super(entity);
+ this.player = player;
+ }
@ -70,7 +71,6 @@ index 0000000000000000000000000000000000000000..ae34e679723a2ef436da04c116038272
+ *
+ * @return The enderman considering attacking
+ */
+ @NotNull
+ @Override
+ public Enderman getEntity() {
+ return (Enderman) super.getEntity();
@ -81,7 +81,6 @@ index 0000000000000000000000000000000000000000..ae34e679723a2ef436da04c116038272
+ *
+ * @return The player the Enderman is considering attacking
+ */
+ @NotNull
+ public Player getPlayer() {
+ return this.player;
+ }
@ -100,16 +99,14 @@ index 0000000000000000000000000000000000000000..ae34e679723a2ef436da04c116038272
+ * Cancels if the Enderman will attack this player
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -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..773079aa92280bb97e9b4c0e62d9ead08135610a
index 0000000000000000000000000000000000000000..6476501ff3299686a059bb75a8ff2424db0cc7f8
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
@@ -0,0 +1,73 @@
@@ -0,0 +1,70 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Witch;
@ -19,26 +19,26 @@ index 0000000000000000000000000000000000000000..773079aa92280bb97e9b4c0e62d9ead0
+import org.bukkit.event.entity.EntityEvent;
+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;
+
+/**
+ * Fired when a witch consumes the potion in their hand to buff themselves.
+ */
+@NullMarked
+public class WitchConsumePotionEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @Nullable private ItemStack potion;
+ private @Nullable ItemStack potion;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public WitchConsumePotionEvent(@NotNull Witch witch, @Nullable ItemStack potion) {
+ public WitchConsumePotionEvent(final Witch witch, final @Nullable ItemStack potion) {
+ super(witch);
+ this.potion = potion;
+ }
+
+ @NotNull
+ @Override
+ public Witch getEntity() {
+ return (Witch) super.getEntity();
@ -47,8 +47,7 @@ index 0000000000000000000000000000000000000000..773079aa92280bb97e9b4c0e62d9ead0
+ /**
+ * @return the potion the witch will consume and have the effects applied.
+ */
+ @Nullable
+ public ItemStack getPotion() {
+ public @Nullable ItemStack getPotion() {
+ return this.potion;
+ }
+
@ -57,7 +56,7 @@ index 0000000000000000000000000000000000000000..773079aa92280bb97e9b4c0e62d9ead0
+ *
+ * @param potion The potion
+ */
+ public void setPotion(@Nullable ItemStack potion) {
+ public void setPotion(final @Nullable ItemStack potion) {
+ this.potion = potion != null ? potion.clone() : null;
+ }
+
@ -70,16 +69,14 @@ index 0000000000000000000000000000000000000000..773079aa92280bb97e9b4c0e62d9ead0
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -7,10 +7,10 @@ Fired when a witch throws a potion at a player
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f621ea043a
index 0000000000000000000000000000000000000000..02395582b680f4baa3dc2251a8a79f41241b96ec
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
@@ -0,0 +1,85 @@
@@ -0,0 +1,81 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.LivingEntity;
@ -20,28 +20,28 @@ index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f6
+import org.bukkit.event.entity.EntityEvent;
+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;
+
+/**
+ * Fired when a witch throws a potion at a player
+ */
+@NullMarked
+public class WitchThrowPotionEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final LivingEntity target;
+ @Nullable private ItemStack potion;
+ private final LivingEntity target;
+ private @Nullable ItemStack potion;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public WitchThrowPotionEvent(@NotNull Witch witch, @NotNull LivingEntity target, @Nullable ItemStack potion) {
+ public WitchThrowPotionEvent(final Witch witch, final LivingEntity target, final @Nullable ItemStack potion) {
+ super(witch);
+ this.target = target;
+ this.potion = potion;
+ }
+
+ @NotNull
+ @Override
+ public Witch getEntity() {
+ return (Witch) super.getEntity();
@ -50,7 +50,6 @@ index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f6
+ /**
+ * @return The target of the potion
+ */
+ @NotNull
+ public LivingEntity getTarget() {
+ return this.target;
+ }
@ -58,8 +57,7 @@ index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f6
+ /**
+ * @return The potion the witch will throw at a player
+ */
+ @Nullable
+ public ItemStack getPotion() {
+ public @Nullable ItemStack getPotion() {
+ return this.potion;
+ }
+
@ -68,7 +66,7 @@ index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f6
+ *
+ * @param potion The potion
+ */
+ public void setPotion(@Nullable ItemStack potion) {
+ public void setPotion(final @Nullable ItemStack potion) {
+ this.potion = potion != null ? potion.clone() : null;
+ }
+
@ -81,17 +79,15 @@ index 0000000000000000000000000000000000000000..f1d546a3576a170ecb3608e07befa0f6
+ }
+
+ @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;
+ }

View file

@ -7,10 +7,10 @@ Control what potion the witch readies to use
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7feca06e72bd585bbfa219df38a2161b77e8d4c4
index 0000000000000000000000000000000000000000..bda48563cc9e00bd9a537ddec0c730b5e784c9a4
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java
@@ -0,0 +1,68 @@
@@ -0,0 +1,65 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Witch;
@ -19,23 +19,23 @@ index 0000000000000000000000000000000000000000..7feca06e72bd585bbfa219df38a2161b
+import org.bukkit.event.entity.EntityEvent;
+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;
+
+@NullMarked
+public class WitchReadyPotionEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private ItemStack potion;
+ private @Nullable ItemStack potion;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public WitchReadyPotionEvent(@NotNull Witch witch, @Nullable ItemStack potion) {
+ public WitchReadyPotionEvent(final Witch witch, final @Nullable ItemStack potion) {
+ super(witch);
+ this.potion = potion;
+ }
+
+ @NotNull
+ @Override
+ public Witch getEntity() {
+ return (Witch) super.getEntity();
@ -44,8 +44,7 @@ index 0000000000000000000000000000000000000000..7feca06e72bd585bbfa219df38a2161b
+ /**
+ * @return the potion the witch is readying to use
+ */
+ @Nullable
+ public ItemStack getPotion() {
+ public @Nullable ItemStack getPotion() {
+ return this.potion;
+ }
+
@ -54,7 +53,7 @@ index 0000000000000000000000000000000000000000..7feca06e72bd585bbfa219df38a2161b
+ *
+ * @param potion The potion
+ */
+ public void setPotion(@Nullable ItemStack potion) {
+ public void setPotion(final @Nullable ItemStack potion) {
+ this.potion = potion != null ? potion.clone() : null;
+ }
+
@ -64,17 +63,15 @@ index 0000000000000000000000000000000000000000..7feca06e72bd585bbfa219df38a2161b
+ }
+
+ @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;
+ }

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Add EntityTeleportEndGatewayEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..88b9c059f9d66877260c66496443ad0aefaf8f47
index 0000000000000000000000000000000000000000..cea029bfbd526d21509dee69bbfad44323107cf2
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java
@@ -0,0 +1,33 @@
@ -17,17 +17,18 @@ index 0000000000000000000000000000000000000000..88b9c059f9d66877260c66496443ad0a
+import org.bukkit.entity.Entity;
+import org.bukkit.event.entity.EntityTeleportEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired any time an entity attempts to teleport in an end gateway
+ */
+@NullMarked
+public class EntityTeleportEndGatewayEvent extends EntityTeleportEvent {
+
+ @NotNull private final EndGateway gateway;
+ private final EndGateway gateway;
+
+ @ApiStatus.Internal
+ public EntityTeleportEndGatewayEvent(@NotNull Entity entity, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
+ public EntityTeleportEndGatewayEvent(final Entity entity, final Location from, final Location to, final EndGateway gateway) {
+ super(entity, from, to);
+ this.gateway = gateway;
+ }
@ -37,7 +38,6 @@ index 0000000000000000000000000000000000000000..88b9c059f9d66877260c66496443ad0a
+ *
+ * @return EndGateway used
+ */
+ @NotNull
+ public EndGateway getGateway() {
+ return this.gateway;
+ }

View file

@ -12,10 +12,10 @@ Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..beb1715e30ec476e3031c247285d0d3219e8a8ea
index 0000000000000000000000000000000000000000..6f376e1ac0f2f44255993b3d5b144f5559d13cc3
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java
@@ -0,0 +1,51 @@
@@ -0,0 +1,52 @@
+package com.destroystokyo.paper.event.entity;
+
+import io.papermc.paper.event.entity.EntityKnockbackEvent;
@ -23,19 +23,20 @@ index 0000000000000000000000000000000000000000..beb1715e30ec476e3031c247285d0d32
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.util.Vector;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when an Entity is knocked back by the hit of another Entity. The acceleration
+ * vector can be modified. If this event is cancelled, the entity is not knocked back.
+ */
+@NullMarked
+public class EntityKnockbackByEntityEvent extends EntityPushedByEntityAttackEvent {
+
+ private final float knockbackStrength;
+
+ @ApiStatus.Internal
+ public EntityKnockbackByEntityEvent(final @NonNull LivingEntity entity, final @NonNull Entity hitBy, final EntityKnockbackEvent.@NonNull Cause cause, final float knockbackStrength, final @NonNull Vector knockback) {
+ public EntityKnockbackByEntityEvent(final LivingEntity entity, final Entity hitBy, final EntityKnockbackEvent.Cause cause, final float knockbackStrength, final Vector knockback) {
+ super(entity, cause, hitBy, knockback);
+ this.knockbackStrength = knockbackStrength;
+ }
@ -44,7 +45,7 @@ index 0000000000000000000000000000000000000000..beb1715e30ec476e3031c247285d0d32
+ * @return the entity which was knocked back
+ */
+ @Override
+ public @NonNull LivingEntity getEntity() {
+ public LivingEntity getEntity() {
+ return (LivingEntity) super.getEntity();
+ }
+
@ -62,17 +63,17 @@ index 0000000000000000000000000000000000000000..beb1715e30ec476e3031c247285d0d32
+ *
+ * @return the Entity which hit
+ */
+ public @NonNull Entity getHitBy() {
+ public Entity getHitBy() {
+ return super.getPushedBy();
+ }
+
+}
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityKnockbackEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityKnockbackEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b103e03a6
index 0000000000000000000000000000000000000000..bc120d4928dc41ea827e2a06f7d30d0e3d484ce0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityKnockbackEvent.java
@@ -0,0 +1,116 @@
@@ -0,0 +1,117 @@
+package io.papermc.paper.event.entity;
+
+import com.google.common.base.Preconditions;
@ -81,14 +82,15 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.bukkit.util.Vector;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an entity receives knockback.
+ * @see EntityPushedByEntityAttackEvent
+ * @see com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent
+ */
+@NullMarked
+public class EntityKnockbackEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -98,7 +100,7 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityKnockbackEvent(final @NonNull Entity entity, final EntityKnockbackEvent.@NonNull Cause cause, final @NonNull Vector knockback) {
+ public EntityKnockbackEvent(final Entity entity, final EntityKnockbackEvent.Cause cause, final Vector knockback) {
+ super(entity);
+ this.cause = cause;
+ this.knockback = knockback;
@ -109,7 +111,7 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+ *
+ * @return the cause of the knockback
+ */
+ public EntityKnockbackEvent.@NonNull Cause getCause() {
+ public EntityKnockbackEvent.Cause getCause() {
+ return this.cause;
+ }
+
@ -121,7 +123,7 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+ *
+ * @return the knockback
+ */
+ public @NonNull Vector getKnockback() {
+ public Vector getKnockback() {
+ return this.knockback.clone();
+ }
+
@ -130,7 +132,7 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+ *
+ * @param knockback the knockback
+ */
+ public void setKnockback(final @NonNull Vector knockback) {
+ public void setKnockback(final Vector knockback) {
+ Preconditions.checkArgument(knockback != null, "knockback");
+ this.knockback = knockback.clone();
+ }
@ -146,11 +148,11 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+ }
+
+ @Override
+ public @NonNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NonNull HandlerList getHandlerList() {
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
@ -191,17 +193,17 @@ index 0000000000000000000000000000000000000000..8aaafa4ea837f54b32497010d121f02b
+}
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityPushedByEntityAttackEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityPushedByEntityAttackEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9d2a7a5bc4e67d8c36047da616046cbedce1d4a
index 0000000000000000000000000000000000000000..7655c3694b9d6b37206fc46bf892004686e0a7dd
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityPushedByEntityAttackEvent.java
@@ -0,0 +1,66 @@
@@ -0,0 +1,67 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.Entity;
+import org.bukkit.event.Cancellable;
+import org.bukkit.util.Vector;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when an entity is pushed by another entity's attack. The acceleration vector can be
@ -210,12 +212,13 @@ index 0000000000000000000000000000000000000000..b9d2a7a5bc4e67d8c36047da616046cb
+ * Note: Some entities might trigger this multiple times on the same entity
+ * as multiple acceleration calculations are done.
+ */
+@NullMarked
+public class EntityPushedByEntityAttackEvent extends EntityKnockbackEvent implements Cancellable {
+
+ private final Entity pushedBy;
+
+ @ApiStatus.Internal
+ public EntityPushedByEntityAttackEvent(final @NonNull Entity entity, final EntityKnockbackEvent.@NonNull Cause cause, final @NonNull Entity pushedBy, final @NonNull Vector knockback) {
+ public EntityPushedByEntityAttackEvent(final Entity entity, final EntityKnockbackEvent.Cause cause, final Entity pushedBy, final Vector knockback) {
+ super(entity, cause, knockback);
+ this.pushedBy = pushedBy;
+ }
@ -225,7 +228,7 @@ index 0000000000000000000000000000000000000000..b9d2a7a5bc4e67d8c36047da616046cb
+ *
+ * @return the pushing entity
+ */
+ public @NonNull Entity getPushedBy() {
+ public Entity getPushedBy() {
+ return this.pushedBy;
+ }
+
@ -236,7 +239,7 @@ index 0000000000000000000000000000000000000000..b9d2a7a5bc4e67d8c36047da616046cb
+ * @deprecated use {@link #getKnockback()}
+ */
+ @Deprecated(since = "1.20.6", forRemoval = true)
+ public @NonNull Vector getAcceleration() {
+ public Vector getAcceleration() {
+ return this.knockback; // TODO Clone in 1.21 to not instantly break what was technically already modifiable (call super.getKnockback())
+ }
+
@ -247,7 +250,7 @@ index 0000000000000000000000000000000000000000..b9d2a7a5bc4e67d8c36047da616046cb
+ * @deprecated use {@link #setKnockback(Vector)}
+ */
+ @Deprecated(since = "1.20.6", forRemoval = true)
+ public void setAcceleration(final @NonNull Vector acceleration) {
+ public void setAcceleration(final Vector acceleration) {
+ super.setKnockback(acceleration);
+ }
+

View file

@ -6,36 +6,36 @@ Subject: [PATCH] EnderDragon Events
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf5f82c8ba36bd245e1536fd4f654487aa8f6e21
index 0000000000000000000000000000000000000000..242eb9c07866365568c036819be2b4f882319aa1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java
@@ -0,0 +1,79 @@
@@ -0,0 +1,74 @@
+package com.destroystokyo.paper.event.entity;
+
+import java.util.Collection;
+import org.bukkit.entity.AreaEffectCloud;
+import org.bukkit.entity.DragonFireball;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+
+import java.util.Collection;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a DragonFireball collides with a block/entity and spawns an AreaEffectCloud
+ */
+@NullMarked
+public class EnderDragonFireballHitEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final Collection<LivingEntity> targets;
+ @NotNull private final AreaEffectCloud areaEffectCloud;
+ private final Collection<LivingEntity> targets;
+ private final AreaEffectCloud areaEffectCloud;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EnderDragonFireballHitEvent(@NotNull DragonFireball fireball, @NotNull Collection<LivingEntity> targets, @NotNull AreaEffectCloud areaEffectCloud) {
+ public EnderDragonFireballHitEvent(final DragonFireball fireball, final Collection<LivingEntity> targets, final AreaEffectCloud areaEffectCloud) {
+ super(fireball);
+ this.targets = targets;
+ this.areaEffectCloud = areaEffectCloud;
@ -44,7 +44,6 @@ index 0000000000000000000000000000000000000000..bf5f82c8ba36bd245e1536fd4f654487
+ /**
+ * The fireball involved in this event
+ */
+ @NotNull
+ @Override
+ public DragonFireball getEntity() {
+ return (DragonFireball) super.getEntity();
@ -55,7 +54,6 @@ index 0000000000000000000000000000000000000000..bf5f82c8ba36bd245e1536fd4f654487
+ *
+ * @return the targets
+ */
+ @NotNull
+ public Collection<LivingEntity> getTargets() {
+ return this.targets;
+ }
@ -63,7 +61,6 @@ index 0000000000000000000000000000000000000000..bf5f82c8ba36bd245e1536fd4f654487
+ /**
+ * @return The area effect cloud spawned in this collision
+ */
+ @NotNull
+ public AreaEffectCloud getAreaEffectCloud() {
+ return this.areaEffectCloud;
+ }
@ -74,27 +71,25 @@ index 0000000000000000000000000000000000000000..bf5f82c8ba36bd245e1536fd4f654487
+ }
+
+ @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/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a61878152c95a07160f4216e78b042ca45d24b3
index 0000000000000000000000000000000000000000..0d6409e3198e57dfa479abb6fee28d6028e13e2d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
@@ -0,0 +1,63 @@
@@ -0,0 +1,60 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.AreaEffectCloud;
@ -103,20 +98,21 @@ index 0000000000000000000000000000000000000000..4a61878152c95a07160f4216e78b042c
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when an EnderDragon spawns an AreaEffectCloud by shooting flames
+ */
+@NullMarked
+public class EnderDragonFlameEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final AreaEffectCloud areaEffectCloud;
+ private final AreaEffectCloud areaEffectCloud;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EnderDragonFlameEvent(@NotNull EnderDragon enderDragon, @NotNull AreaEffectCloud areaEffectCloud) {
+ public EnderDragonFlameEvent(final EnderDragon enderDragon, final AreaEffectCloud areaEffectCloud) {
+ super(enderDragon);
+ this.areaEffectCloud = areaEffectCloud;
+ }
@ -124,7 +120,6 @@ index 0000000000000000000000000000000000000000..4a61878152c95a07160f4216e78b042c
+ /**
+ * The enderdragon involved in this event
+ */
+ @NotNull
+ @Override
+ public EnderDragon getEntity() {
+ return (EnderDragon) super.getEntity();
@ -133,7 +128,6 @@ index 0000000000000000000000000000000000000000..4a61878152c95a07160f4216e78b042c
+ /**
+ * @return The area effect cloud spawned in this collision
+ */
+ @NotNull
+ public AreaEffectCloud getAreaEffectCloud() {
+ return this.areaEffectCloud;
+ }
@ -144,26 +138,24 @@ index 0000000000000000000000000000000000000000..4a61878152c95a07160f4216e78b042c
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c6c3db37d91aad3638aef107a3bf8ca1d4f7085
index 0000000000000000000000000000000000000000..7dd6e17b648868cf5d549f1e779e5d92439751dd
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java
@@ -0,0 +1,64 @@
@@ -0,0 +1,61 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.DragonFireball;
@ -172,20 +164,21 @@ index 0000000000000000000000000000000000000000..3c6c3db37d91aad3638aef107a3bf8ca
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when an EnderDragon shoots a fireball
+ */
+@NullMarked
+public class EnderDragonShootFireballEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final DragonFireball fireball;
+ private final DragonFireball fireball;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EnderDragonShootFireballEvent(@NotNull EnderDragon entity, @NotNull DragonFireball fireball) {
+ public EnderDragonShootFireballEvent(final EnderDragon entity, final DragonFireball fireball) {
+ super(entity);
+ this.fireball = fireball;
+ }
@ -193,7 +186,6 @@ index 0000000000000000000000000000000000000000..3c6c3db37d91aad3638aef107a3bf8ca
+ /**
+ * The enderdragon shooting the fireball
+ */
+ @NotNull
+ @Override
+ public EnderDragon getEntity() {
+ return (EnderDragon) super.getEntity();
@ -202,7 +194,6 @@ index 0000000000000000000000000000000000000000..3c6c3db37d91aad3638aef107a3bf8ca
+ /**
+ * @return The fireball being shot
+ */
+ @NotNull
+ public DragonFireball getFireball() {
+ return this.fireball;
+ }
@ -213,17 +204,15 @@ index 0000000000000000000000000000000000000000..3c6c3db37d91aad3638aef107a3bf8ca
+ }
+
+ @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;
+ }

View file

@ -6,26 +6,26 @@ Subject: [PATCH] SkeletonHorse Additions
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6724e6e5754996ac10888aaa92baf2dcc6134d3
index 0000000000000000000000000000000000000000..a70f4972a012f955b45a91fe20ca5df7e2123528
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java
@@ -0,0 +1,68 @@
@@ -0,0 +1,64 @@
+package com.destroystokyo.paper.event.entity;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.SkeletonHorse;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Event called when a player gets close to a skeleton horse and triggers the lightning trap
+ */
+@NullMarked
+public class SkeletonHorseTrapEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -35,23 +35,21 @@ index 0000000000000000000000000000000000000000..f6724e6e5754996ac10888aaa92baf2d
+
+ @Deprecated
+ @ApiStatus.Internal
+ public SkeletonHorseTrapEvent(@NotNull SkeletonHorse horse) {
+ public SkeletonHorseTrapEvent(final SkeletonHorse horse) {
+ this(horse, ImmutableList.of());
+ }
+
+ @ApiStatus.Internal
+ public SkeletonHorseTrapEvent(@NotNull SkeletonHorse horse, @NotNull List<HumanEntity> eligibleHumans) {
+ public SkeletonHorseTrapEvent(final SkeletonHorse horse, final List<HumanEntity> eligibleHumans) {
+ super(horse);
+ this.eligibleHumans = eligibleHumans;
+ }
+
+ @NotNull
+ @Override
+ public SkeletonHorse getEntity() {
+ return (SkeletonHorse) super.getEntity();
+ }
+
+ @NotNull
+ public List<HumanEntity> getEligibleHumans() {
+ return this.eligibleHumans;
+ }
@ -62,17 +60,15 @@ index 0000000000000000000000000000000000000000..f6724e6e5754996ac10888aaa92baf2d
+ }
+
+ @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;
+ }

View file

@ -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..4f88c101d81e5c3a8a065260304d5816337666d7
index 0000000000000000000000000000000000000000..456e2a638421b435ede4205d3eedfafeedb196c1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
@@ -0,0 +1,154 @@
@@ -0,0 +1,148 @@
+package com.destroystokyo.paper.event.block;
+
+import org.bukkit.Material;
@ -20,12 +20,13 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+import org.bukkit.inventory.AnvilInventory;
+import org.bukkit.inventory.InventoryView;
+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 anvil is damaged from being used
+ */
+@NullMarked
+public class AnvilDamagedEvent extends InventoryEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -34,12 +35,11 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public AnvilDamagedEvent(@NotNull InventoryView inventory, @Nullable BlockData blockData) {
+ public AnvilDamagedEvent(final InventoryView inventory, final @Nullable BlockData blockData) {
+ super(inventory);
+ this.damageState = DamageState.getState(blockData);
+ }
+
+ @NotNull
+ @Override
+ public AnvilInventory getInventory() {
+ return (AnvilInventory) super.getInventory();
@ -50,7 +50,6 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ *
+ * @return Damage state
+ */
+ @NotNull
+ public DamageState getDamageState() {
+ return this.damageState;
+ }
@ -60,7 +59,7 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ *
+ * @param damageState Damage state
+ */
+ public void setDamageState(@NotNull DamageState damageState) {
+ public void setDamageState(final DamageState damageState) {
+ this.damageState = damageState;
+ }
+
@ -78,7 +77,7 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ *
+ * @param breaking {@code true} if breaking
+ */
+ public void setBreaking(boolean breaking) {
+ public void setBreaking(final boolean breaking) {
+ if (breaking) {
+ this.damageState = DamageState.BROKEN;
+ } else if (this.damageState == DamageState.BROKEN) {
@ -92,16 +91,14 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@ -117,7 +114,7 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+
+ private final Material material;
+
+ DamageState(@NotNull Material material) {
+ DamageState(final Material material) {
+ this.material = material;
+ }
+
@ -126,7 +123,6 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ *
+ * @return Material
+ */
+ @NotNull
+ public Material getMaterial() {
+ return this.material;
+ }
@ -138,8 +134,7 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ * @return DamageState
+ * @throws IllegalArgumentException If non anvil block data is given
+ */
+ @NotNull
+ public static DamageState getState(@Nullable BlockData blockData) {
+ public static DamageState getState(final @Nullable BlockData blockData) {
+ return blockData == null ? BROKEN : getState(blockData.getMaterial());
+ }
+
@ -150,12 +145,11 @@ index 0000000000000000000000000000000000000000..4f88c101d81e5c3a8a065260304d5816
+ * @return DamageState
+ * @throws IllegalArgumentException If non anvil material is given
+ */
+ @NotNull
+ public static DamageState getState(@Nullable Material material) {
+ public static DamageState getState(final @Nullable Material material) {
+ if (material == null) {
+ return BROKEN;
+ }
+ for (DamageState state : values()) {
+ for (final DamageState state : values()) {
+ if (state.getMaterial() == material) {
+ return state;
+ }

View file

@ -6,15 +6,15 @@ Subject: [PATCH] Slime Pathfinder Events
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SlimeChangeDirectionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SlimeChangeDirectionEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..30864539574e23bbe9e4c5dc73ad6614de782ac2
index 0000000000000000000000000000000000000000..a5d4442b53c4bd70165c3240c7dbd3d56b6bf0ae
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimeChangeDirectionEvent.java
@@ -0,0 +1,40 @@
@@ -0,0 +1,41 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Slime;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Slime decides to change its facing direction.
@ -22,12 +22,13 @@ index 0000000000000000000000000000000000000000..30864539574e23bbe9e4c5dc73ad6614
+ * This event does not fire for the entity's actual movement. Only when it
+ * is choosing to change direction.
+ */
+@NullMarked
+public class SlimeChangeDirectionEvent extends SlimePathfindEvent {
+
+ private float yaw;
+
+ @ApiStatus.Internal
+ public SlimeChangeDirectionEvent(@NotNull Slime slime, float yaw) {
+ public SlimeChangeDirectionEvent(final Slime slime, final float yaw) {
+ super(slime);
+ this.yaw = yaw;
+ }
@ -46,16 +47,16 @@ index 0000000000000000000000000000000000000000..30864539574e23bbe9e4c5dc73ad6614
+ *
+ * @param yaw Chosen yaw
+ */
+ public void setNewYaw(float yaw) {
+ public void setNewYaw(final float yaw) {
+ this.yaw = yaw;
+ }
+}
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..706ed85a5415d688aaa5f138cbf583b9e2bab27d
index 0000000000000000000000000000000000000000..48963ce451c05f80ff13b4361e8aba196b629319
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimePathfindEvent.java
@@ -0,0 +1,56 @@
@@ -0,0 +1,54 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Slime;
@ -63,7 +64,7 @@ index 0000000000000000000000000000000000000000..706ed85a5415d688aaa5f138cbf583b9
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Slime decides to start pathfinding.
@ -71,6 +72,7 @@ index 0000000000000000000000000000000000000000..706ed85a5415d688aaa5f138cbf583b9
+ * This event does not fire for the entity's actual movement. Only when it
+ * is choosing to start moving.
+ */
+@NullMarked
+public class SlimePathfindEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -78,7 +80,7 @@ index 0000000000000000000000000000000000000000..706ed85a5415d688aaa5f138cbf583b9
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public SlimePathfindEvent(@NotNull Slime slime) {
+ public SlimePathfindEvent(final Slime slime) {
+ super(slime);
+ }
+
@ -87,7 +89,6 @@ index 0000000000000000000000000000000000000000..706ed85a5415d688aaa5f138cbf583b9
+ *
+ * @return The Slime that is pathfinding.
+ */
+ @NotNull
+ public Slime getEntity() {
+ return (Slime) super.getEntity();
+ }
@ -98,31 +99,29 @@ index 0000000000000000000000000000000000000000..706ed85a5415d688aaa5f138cbf583b9
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SlimeSwimEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SlimeSwimEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..65e8a29751e338b0f0acda7bef9e014852a73e6e
index 0000000000000000000000000000000000000000..4233ea3012c03660c42e3ec93832a6e019440eba
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimeSwimEvent.java
@@ -0,0 +1,19 @@
@@ -0,0 +1,20 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Slime;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Slime decides to start jumping while swimming in water/lava.
@ -130,16 +129,17 @@ index 0000000000000000000000000000000000000000..65e8a29751e338b0f0acda7bef9e0148
+ * This event does not fire for the entity's actual movement. Only when it
+ * is choosing to start jumping.
+ */
+@NullMarked
+public class SlimeSwimEvent extends SlimeWanderEvent {
+
+ @ApiStatus.Internal
+ public SlimeSwimEvent(@NotNull Slime slime) {
+ public SlimeSwimEvent(final Slime slime) {
+ super(slime);
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SlimeTargetLivingEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SlimeTargetLivingEntityEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..87c64b04dfec232e98361c3ec29da7664498c65b
index 0000000000000000000000000000000000000000..ba7369aab0c257acafda7d3a43a41e409240bf1d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimeTargetLivingEntityEvent.java
@@ -0,0 +1,33 @@
@ -148,7 +148,7 @@ index 0000000000000000000000000000000000000000..87c64b04dfec232e98361c3ec29da766
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Slime;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Slime decides to change direction to target a LivingEntity.
@ -156,12 +156,13 @@ index 0000000000000000000000000000000000000000..87c64b04dfec232e98361c3ec29da766
+ * This event does not fire for the entity's actual movement. Only when it
+ * is choosing to start moving.
+ */
+@NullMarked
+public class SlimeTargetLivingEntityEvent extends SlimePathfindEvent {
+
+ @NotNull private final LivingEntity target;
+ private final LivingEntity target;
+
+ @ApiStatus.Internal
+ public SlimeTargetLivingEntityEvent(@NotNull Slime slime, @NotNull LivingEntity target) {
+ public SlimeTargetLivingEntityEvent(final Slime slime, final LivingEntity target) {
+ super(slime);
+ this.target = target;
+ }
@ -171,22 +172,21 @@ index 0000000000000000000000000000000000000000..87c64b04dfec232e98361c3ec29da766
+ *
+ * @return Targeted entity
+ */
+ @NotNull
+ public LivingEntity getTarget() {
+ return this.target;
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SlimeWanderEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SlimeWanderEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ad9cc1673ffbb8b48349e461d1154d1d4ec2874
index 0000000000000000000000000000000000000000..0ea085c4a1cf663e2333444cebda876db321164d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SlimeWanderEvent.java
@@ -0,0 +1,19 @@
@@ -0,0 +1,20 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Slime;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Slime decides to start wandering.
@ -194,10 +194,11 @@ index 0000000000000000000000000000000000000000..2ad9cc1673ffbb8b48349e461d1154d1
+ * This event does not fire for the entity's actual movement. Only when it
+ * is choosing to start moving.
+ */
+@NullMarked
+public class SlimeWanderEvent extends SlimePathfindEvent {
+
+ @ApiStatus.Internal
+ public SlimeWanderEvent(@NotNull Slime slime) {
+ public SlimeWanderEvent(final Slime slime) {
+ super(slime);
+ }
+}

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Add PhantomPreSpawnEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PhantomPreSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PhantomPreSpawnEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff7d9ff618ab821eeece6923a694a9a4eea8585d
index 0000000000000000000000000000000000000000..e465222aa8218a7fef85f2e1df1a919a88499eab
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PhantomPreSpawnEvent.java
@@ -0,0 +1,32 @@
@ -17,17 +17,18 @@ index 0000000000000000000000000000000000000000..ff7d9ff618ab821eeece6923a694a9a4
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a phantom is spawned for an exhausted player
+ */
+@NullMarked
+public class PhantomPreSpawnEvent extends PreCreatureSpawnEvent {
+
+ @NotNull private final Entity entity;
+ private final Entity entity;
+
+ @ApiStatus.Internal
+ public PhantomPreSpawnEvent(@NotNull Location location, @NotNull Entity entity, @NotNull CreatureSpawnEvent.SpawnReason reason) {
+ public PhantomPreSpawnEvent(final Location location, final Entity entity, final CreatureSpawnEvent.SpawnReason reason) {
+ super(location, EntityType.PHANTOM, reason);
+ this.entity = entity;
+ }
@ -37,7 +38,6 @@ index 0000000000000000000000000000000000000000..ff7d9ff618ab821eeece6923a694a9a4
+ *
+ * @return the Entity
+ */
+ @NotNull
+ public Entity getSpawningEntity() {
+ return this.entity;
+ }

View file

@ -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..e86500337f26fcb6bb04545c68c67df32021ce25
index 0000000000000000000000000000000000000000..0c2f4f257b03d00c0ef1c50fdba6beb790fc808d
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/CreeperIgniteEvent.java
@@ -0,0 +1,60 @@
@@ -0,0 +1,58 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Creeper;
@ -17,13 +17,14 @@ index 0000000000000000000000000000000000000000..e86500337f26fcb6bb04545c68c67df3
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a Creeper is ignited either by a
+ * flint and steel, {@link Creeper#ignite()} or
+ * {@link Creeper#setIgnited(boolean)}.
+ */
+@NullMarked
+public class CreeperIgniteEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -32,12 +33,11 @@ index 0000000000000000000000000000000000000000..e86500337f26fcb6bb04545c68c67df3
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public CreeperIgniteEvent(@NotNull Creeper creeper, boolean ignited) {
+ public CreeperIgniteEvent(final Creeper creeper, final boolean ignited) {
+ super(creeper);
+ this.ignited = ignited;
+ }
+
+ @NotNull
+ @Override
+ public Creeper getEntity() {
+ return (Creeper) super.getEntity();
@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..e86500337f26fcb6bb04545c68c67df3
+ return this.ignited;
+ }
+
+ public void setIgnited(boolean ignited) {
+ public void setIgnited(final boolean ignited) {
+ this.ignited = ignited;
+ }
+
@ -55,17 +55,15 @@ index 0000000000000000000000000000000000000000..e86500337f26fcb6bb04545c68c67df3
+ return this.cancelled;
+ }
+
+ 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;
+ }

View file

@ -12,7 +12,7 @@ Dropped as it does not apply due to the earlier PreCreatureSpawnEvent patch not
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PreSpawnerSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PreSpawnerSpawnEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..2910f0bf929d918c86510f29d9361bbc19411256
index 0000000000000000000000000000000000000000..679b37056be9515c69922285affbf0301f5335e3
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PreSpawnerSpawnEvent.java
@@ -0,0 +1,29 @@
@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..2910f0bf929d918c86510f29d9361bbc
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called before an entity is spawned into a world by a spawner.
@ -30,17 +30,17 @@ index 0000000000000000000000000000000000000000..2910f0bf929d918c86510f29d9361bbc
+ * This only includes the spawner's location and not the full BlockState snapshot for performance reasons.
+ * If you really need it you have to get the spawner yourself.
+ */
+@NullMarked
+public class PreSpawnerSpawnEvent extends PreCreatureSpawnEvent {
+
+ @NotNull private final Location spawnerLocation;
+ private final Location spawnerLocation;
+
+ @ApiStatus.Internal
+ public PreSpawnerSpawnEvent(@NotNull Location location, @NotNull EntityType type, @NotNull Location spawnerLocation) {
+ public PreSpawnerSpawnEvent(final Location location, final EntityType type, final Location spawnerLocation) {
+ super(location, type, CreatureSpawnEvent.SpawnReason.SPAWNER);
+ this.spawnerLocation = spawnerLocation;
+ }
+
+ @NotNull
+ public Location getSpawnerLocation() {
+ return this.spawnerLocation.clone();
+ }

View file

@ -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..cfbc8aaf862ac90e794ee38bf8a6cb9ea414b13e
index 0000000000000000000000000000000000000000..560b46b7b4fdd3394bc5e8fc917776a5838eba09
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleGoHomeEvent.java
@@ -0,0 +1,53 @@
@@ -0,0 +1,51 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.Turtle;
@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..cfbc8aaf862ac90e794ee38bf8a6cb9e
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Turtle decides to go home
+ */
+@NullMarked
+public class TurtleGoHomeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -29,7 +30,7 @@ index 0000000000000000000000000000000000000000..cfbc8aaf862ac90e794ee38bf8a6cb9e
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public TurtleGoHomeEvent(@NotNull Turtle turtle) {
+ public TurtleGoHomeEvent(final Turtle turtle) {
+ super(turtle);
+ }
+
@ -38,7 +39,6 @@ index 0000000000000000000000000000000000000000..cfbc8aaf862ac90e794ee38bf8a6cb9e
+ *
+ * @return The turtle
+ */
+ @NotNull
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@ -49,26 +49,24 @@ index 0000000000000000000000000000000000000000..cfbc8aaf862ac90e794ee38bf8a6cb9e
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
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..3029e406cd684efb5645e38711dff9c0bb7b01e4
index 0000000000000000000000000000000000000000..d1b2bbb57280726690e704c5978d312d856243eb
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java
@@ -0,0 +1,92 @@
@@ -0,0 +1,88 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@ -77,23 +75,23 @@ index 0000000000000000000000000000000000000000..3029e406cd684efb5645e38711dff9c0
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Turtle lays eggs
+ */
+@NullMarked
+public class TurtleLayEggEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull
+ private final Location location;
+ private int eggCount;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public TurtleLayEggEvent(@NotNull Turtle turtle, @NotNull Location location, int eggCount) {
+ public TurtleLayEggEvent(final Turtle turtle, final Location location, final int eggCount) {
+ super(turtle);
+ this.location = location;
+ this.eggCount = eggCount;
@ -104,7 +102,6 @@ index 0000000000000000000000000000000000000000..3029e406cd684efb5645e38711dff9c0
+ *
+ * @return The turtle
+ */
+ @NotNull
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@ -114,7 +111,6 @@ index 0000000000000000000000000000000000000000..3029e406cd684efb5645e38711dff9c0
+ *
+ * @return Location of eggs
+ */
+ @NotNull
+ public Location getLocation() {
+ return this.location.clone();
+ }
@ -133,7 +129,7 @@ index 0000000000000000000000000000000000000000..3029e406cd684efb5645e38711dff9c0
+ *
+ * @param eggCount Number of eggs
+ */
+ public void setEggCount(int eggCount) {
+ public void setEggCount(final int eggCount) {
+ if (eggCount < 1) {
+ this.cancelled = true;
+ return;
@ -147,26 +143,24 @@ index 0000000000000000000000000000000000000000..3029e406cd684efb5645e38711dff9c0
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
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..7a2fa4a11b47e4982d1644830d7e28f12b4378ec
index 0000000000000000000000000000000000000000..4a53af5da307cd71e0e647917bec9be44136e6aa
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java
@@ -0,0 +1,66 @@
@@ -0,0 +1,63 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.Location;
@ -175,20 +169,21 @@ index 0000000000000000000000000000000000000000..7a2fa4a11b47e4982d1644830d7e28f1
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a Turtle starts digging to lay eggs
+ */
+@NullMarked
+public class TurtleStartDiggingEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final Location location;
+ private final Location location;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public TurtleStartDiggingEvent(@NotNull Turtle turtle, @NotNull Location location) {
+ public TurtleStartDiggingEvent(final Turtle turtle, final Location location) {
+ super(turtle);
+ this.location = location;
+ }
@ -198,7 +193,6 @@ index 0000000000000000000000000000000000000000..7a2fa4a11b47e4982d1644830d7e28f1
+ *
+ * @return The turtle
+ */
+ @NotNull
+ public Turtle getEntity() {
+ return (Turtle) super.getEntity();
+ }
@ -208,7 +202,6 @@ index 0000000000000000000000000000000000000000..7a2fa4a11b47e4982d1644830d7e28f1
+ *
+ * @return Location where digging
+ */
+ @NotNull
+ public Location getLocation() {
+ return this.location.clone();
+ }
@ -219,16 +212,14 @@ index 0000000000000000000000000000000000000000..7a2fa4a11b47e4982d1644830d7e28f1
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -35,21 +35,20 @@ is undefined.
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0fb13adc140f1ca74d0c3448f92baa60684f3e2
index 0000000000000000000000000000000000000000..5f5afcdb3c9e669ed0e730c720ad91d16b95602c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java
@@ -0,0 +1,88 @@
@@ -0,0 +1,83 @@
+package com.destroystokyo.paper.event.player;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+
+import java.net.InetAddress;
+import java.util.UUID;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * <p>
@ -76,16 +75,17 @@ index 0000000000000000000000000000000000000000..d0fb13adc140f1ca74d0c3448f92baa6
+ * The event may be invoked asynchronously or synchronously. Plugins should check
+ * {@link Event#isAsynchronous()} and handle accordingly.
+ */
+@NullMarked
+public class PlayerConnectionCloseEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final UUID playerUniqueId;
+ @NotNull private final String playerName;
+ @NotNull private final InetAddress ipAddress;
+ private final UUID playerUniqueId;
+ private final String playerName;
+ private final InetAddress ipAddress;
+
+ @ApiStatus.Internal
+ public PlayerConnectionCloseEvent(@NotNull final UUID playerUniqueId, @NotNull final String playerName, @NotNull final InetAddress ipAddress, final boolean async) {
+ public PlayerConnectionCloseEvent(final UUID playerUniqueId, final String playerName, final InetAddress ipAddress, final boolean async) {
+ super(async);
+ this.playerUniqueId = playerUniqueId;
+ this.playerName = playerName;
@ -95,7 +95,6 @@ index 0000000000000000000000000000000000000000..d0fb13adc140f1ca74d0c3448f92baa6
+ /**
+ * Returns the {@code UUID} of the player disconnecting.
+ */
+ @NotNull
+ public UUID getPlayerUniqueId() {
+ return this.playerUniqueId;
+ }
@ -103,7 +102,6 @@ index 0000000000000000000000000000000000000000..d0fb13adc140f1ca74d0c3448f92baa6
+ /**
+ * Returns the name of the player disconnecting.
+ */
+ @NotNull
+ public String getPlayerName() {
+ return this.playerName;
+ }
@ -111,18 +109,15 @@ index 0000000000000000000000000000000000000000..d0fb13adc140f1ca74d0c3448f92baa6
+ /**
+ * Returns the player's IP address.
+ */
+ @NotNull
+ public InetAddress getIpAddress() {
+ return this.ipAddress;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -12,10 +12,10 @@ This can replace many uses of BlockPhysicsEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java b/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889ece1a9168
index 0000000000000000000000000000000000000000..122ccdef02c292c5705a6ac0a96e6095d28bd7bf
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/block/BlockDestroyEvent.java
@@ -0,0 +1,122 @@
@@ -0,0 +1,120 @@
+package com.destroystokyo.paper.event.block;
+
+import org.bukkit.block.Block;
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockExpEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired anytime the server intends to 'destroy' a block through some triggering reason.
@ -36,11 +36,12 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ * <p>
+ * Events such as leaves decaying, pistons retracting (where the block is moving), does NOT fire this event.
+ */
+@NullMarked
+public class BlockDestroyEvent extends BlockExpEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final BlockData newState;
+ private final BlockData newState;
+ private boolean willDrop;
+ private boolean playEffect = true;
+ private BlockData effectBlock;
@ -48,7 +49,7 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public BlockDestroyEvent(@NotNull Block block, @NotNull BlockData newState, @NotNull BlockData effectBlock, int xp, boolean willDrop) {
+ public BlockDestroyEvent(final Block block, final BlockData newState, final BlockData effectBlock, final int xp, final boolean willDrop) {
+ super(block, xp);
+ this.newState = newState;
+ this.effectBlock = effectBlock;
@ -60,7 +61,6 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ *
+ * @return block break effect
+ */
+ @NotNull
+ public BlockData getEffectBlock() {
+ return this.effectBlock;
+ }
@ -72,14 +72,14 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ *
+ * @param effectBlock block effect
+ */
+ public void setEffectBlock(@NotNull BlockData effectBlock) {
+ public void setEffectBlock(final BlockData effectBlock) {
+ this.effectBlock = effectBlock;
+ }
+
+ /**
+ * @return The new state of this block (Air, or a Fluid type)
+ */
+ public @NotNull BlockData getNewState() {
+ public BlockData getNewState() {
+ return this.newState.clone();
+ }
+
@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ /**
+ * @param willDrop If the server is going to drop the block in question with this destroy event
+ */
+ public void setWillDrop(boolean willDrop) {
+ public void setWillDrop(final boolean willDrop) {
+ this.willDrop = willDrop;
+ }
+
@ -107,7 +107,7 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ /**
+ * @param playEffect If the server should play the sound effect for this destruction
+ */
+ public void setPlayEffect(boolean playEffect) {
+ public void setPlayEffect(final boolean playEffect) {
+ this.playEffect = playEffect;
+ }
+
@ -123,17 +123,15 @@ index 0000000000000000000000000000000000000000..c0742b58ca2c098c27394915b624889e
+ * If the event is cancelled, the block will remain in its previous state.
+ */
+ @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;
+ }

View file

@ -6,22 +6,23 @@ Subject: [PATCH] Add WhitelistToggleEvent
diff --git a/src/main/java/com/destroystokyo/paper/event/server/WhitelistToggleEvent.java b/src/main/java/com/destroystokyo/paper/event/server/WhitelistToggleEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..22fa169c278639f31aec2695259963038de0af8a
index 0000000000000000000000000000000000000000..b9a59a28c1dec6c174885892ff40d3caaaf409a4
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/WhitelistToggleEvent.java
@@ -0,0 +1,43 @@
@@ -0,0 +1,42 @@
+package com.destroystokyo.paper.event.server;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * This event is fired when whitelist is toggled
+ *
+ * @author Mark Vainomaa
+ */
+@NullMarked
+public class WhitelistToggleEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -29,7 +30,7 @@ index 0000000000000000000000000000000000000000..22fa169c278639f31aec269525996303
+ private final boolean enabled;
+
+ @ApiStatus.Internal
+ public WhitelistToggleEvent(boolean enabled) {
+ public WhitelistToggleEvent(final boolean enabled) {
+ this.enabled = enabled;
+ }
+
@ -42,13 +43,11 @@ index 0000000000000000000000000000000000000000..22fa169c278639f31aec269525996303
+ return this.enabled;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,25 +6,25 @@ Subject: [PATCH] Add GS4 Query event
diff --git a/src/main/java/com/destroystokyo/paper/event/server/GS4QueryEvent.java b/src/main/java/com/destroystokyo/paper/event/server/GS4QueryEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097291978a6
index 0000000000000000000000000000000000000000..5a8813c80e56d17ccaa35a7eef2f6bd70c7a3d96
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/GS4QueryEvent.java
@@ -0,0 +1,424 @@
@@ -0,0 +1,395 @@
+package com.destroystokyo.paper.event.server;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import org.bukkit.Server;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.bukkit.Server;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * This event is fired if server is getting queried over GS4 Query protocol.
@ -33,6 +33,7 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @author Mark Vainomaa
+ */
+@NullMarked
+public final class GS4QueryEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -42,7 +43,7 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ private QueryResponse response;
+
+ @ApiStatus.Internal
+ public GS4QueryEvent(@NotNull QueryType queryType, @NotNull InetAddress querierAddress, @NotNull QueryResponse response) {
+ public GS4QueryEvent(final QueryType queryType, final InetAddress querierAddress, final QueryResponse response) {
+ super(true); // should always be called async
+ this.queryType = queryType;
+ this.querierAddress = querierAddress;
@ -54,7 +55,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return query type
+ */
+ @NotNull
+ public QueryType getQueryType() {
+ return this.queryType;
+ }
@ -64,7 +64,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return querier address
+ */
+ @NotNull
+ public InetAddress getQuerierAddress() {
+ return this.querierAddress;
+ }
@ -74,7 +73,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return query response
+ */
+ @NotNull
+ public QueryResponse getResponse() {
+ return this.response;
+ }
@ -84,17 +82,15 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @param response query response
+ */
+ public void setResponse(@NotNull QueryResponse response) {
+ public void setResponse(final QueryResponse response) {
+ this.response = Preconditions.checkNotNull(response, "response");
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@ -115,7 +111,7 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ FULL
+ }
+
+ public final static class QueryResponse {
+ public static final class QueryResponse {
+
+ private final String motd;
+ private final String gameVersion;
@ -128,7 +124,7 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ private final String serverVersion;
+ private final Collection<PluginInformation> plugins;
+
+ private QueryResponse(String motd, String gameVersion, String map, int currentPlayers, int maxPlayers, String hostname, int port, Collection<String> players, String serverVersion, Collection<PluginInformation> plugins) {
+ private QueryResponse(final String motd, final String gameVersion, final String map, final int currentPlayers, final int maxPlayers, final String hostname, final int port, final Collection<String> players, final String serverVersion, final Collection<PluginInformation> plugins) {
+ this.motd = motd;
+ this.gameVersion = gameVersion;
+ this.map = map;
@ -142,21 +138,19 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ }
+
+ /**
+ * Get motd which will be used to reply to the query. By default it is {@link Server#getMotd()}.
+ * Get motd which will be used to reply to the query. By default, it is {@link Server#getMotd()}.
+ *
+ * @return motd
+ */
+ @NotNull
+ public String getMotd() {
+ return this.motd;
+ }
+
+ /**
+ * Get game version which will be used to reply to the query. By default supported Minecraft versions range is sent.
+ * Get game version which will be used to reply to the query. By default, supported Minecraft versions range is sent.
+ *
+ * @return game version
+ */
+ @NotNull
+ public String getGameVersion() {
+ return this.gameVersion;
+ }
@ -166,7 +160,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return map name
+ */
+ @NotNull
+ public String getMap() {
+ return this.map;
+ }
@ -194,7 +187,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return server hostname
+ */
+ @NotNull
+ public String getHostname() {
+ return this.hostname;
+ }
@ -213,7 +205,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return collection of players
+ */
+ @NotNull
+ public Collection<String> getPlayers() {
+ return this.players;
+ }
@ -223,7 +214,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return server software
+ */
+ @NotNull
+ public String getServerVersion() {
+ return this.serverVersion;
+ }
@ -233,7 +223,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return collection of plugins
+ */
+ @NotNull
+ public Collection<PluginInformation> getPlugins() {
+ return this.plugins;
+ }
@ -243,19 +232,18 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return {@link QueryResponse} builder
+ */
+ @NotNull
+ public Builder toBuilder() {
+ return QueryResponse.builder()
+ .motd(getMotd())
+ .gameVersion(getGameVersion())
+ .map(getMap())
+ .currentPlayers(getCurrentPlayers())
+ .maxPlayers(getMaxPlayers())
+ .hostname(getHostname())
+ .port(getPort())
+ .players(getPlayers())
+ .serverVersion(getServerVersion())
+ .plugins(getPlugins());
+ .motd(this.getMotd())
+ .gameVersion(this.getGameVersion())
+ .map(this.getMap())
+ .currentPlayers(this.getCurrentPlayers())
+ .maxPlayers(this.getMaxPlayers())
+ .hostname(this.getHostname())
+ .port(this.getPort())
+ .players(this.getPlayers())
+ .serverVersion(this.getServerVersion())
+ .plugins(this.getPlugins());
+ }
+
+ /**
@ -263,7 +251,6 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return {@link QueryResponse} builder
+ */
+ @NotNull
+ public static Builder builder() {
+ return new Builder();
+ }
@ -272,11 +259,12 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ * A builder for {@link QueryResponse} objects.
+ */
+ public static final class Builder {
+ private String motd;
+ private String gameVersion;
+ private String map;
+ private String hostname;
+ private String serverVersion;
+
+ private @MonotonicNonNull String motd;
+ private @MonotonicNonNull String gameVersion;
+ private @MonotonicNonNull String map;
+ private @MonotonicNonNull String hostname;
+ private @MonotonicNonNull String serverVersion;
+
+ private int currentPlayers;
+ private int maxPlayers;
@ -285,90 +273,77 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ private final List<String> players = new ArrayList<>();
+ private final List<PluginInformation> plugins = new ArrayList<>();
+
+ private Builder() {}
+ private Builder() {
+ }
+
+ @NotNull
+ public Builder motd(@NotNull String motd) {
+ public Builder motd(final String motd) {
+ this.motd = Preconditions.checkNotNull(motd, "motd");
+ return this;
+ }
+
+ @NotNull
+ public Builder gameVersion(@NotNull String gameVersion) {
+ public Builder gameVersion(final String gameVersion) {
+ this.gameVersion = Preconditions.checkNotNull(gameVersion, "gameVersion");
+ return this;
+ }
+
+ @NotNull
+ public Builder map(@NotNull String map) {
+ public Builder map(final String map) {
+ this.map = Preconditions.checkNotNull(map, "map");
+ return this;
+ }
+
+ @NotNull
+ public Builder currentPlayers(int currentPlayers) {
+ public Builder currentPlayers(final int currentPlayers) {
+ Preconditions.checkArgument(currentPlayers >= 0, "currentPlayers cannot be negative");
+ this.currentPlayers = currentPlayers;
+ return this;
+ }
+
+ @NotNull
+ public Builder maxPlayers(int maxPlayers) {
+ public Builder maxPlayers(final int maxPlayers) {
+ Preconditions.checkArgument(maxPlayers >= 0, "maxPlayers cannot be negative");
+ this.maxPlayers = maxPlayers;
+ return this;
+ }
+
+ @NotNull
+ public Builder hostname(@NotNull String hostname) {
+ public Builder hostname(final String hostname) {
+ this.hostname = Preconditions.checkNotNull(hostname, "hostname");
+ return this;
+ }
+
+ @NotNull
+ public Builder port(int port) {
+ public Builder port(final int port) {
+ Preconditions.checkArgument(port >= 1 && port <= 65535, "port must be between 1-65535");
+ this.port = port;
+ return this;
+ }
+
+ @NotNull
+ public Builder players(@NotNull Collection<String> players) {
+ public Builder players(final Collection<String> players) {
+ this.players.addAll(Preconditions.checkNotNull(players, "players"));
+ return this;
+ }
+
+ @NotNull
+ public Builder players(@NotNull String... players) {
+ public Builder players(final String... players) {
+ this.players.addAll(Arrays.asList(Preconditions.checkNotNull(players, "players")));
+ return this;
+ }
+
+ @NotNull
+ public Builder clearPlayers() {
+ this.players.clear();
+ return this;
+ }
+
+ @NotNull
+ public Builder serverVersion(@NotNull String serverVersion) {
+ public Builder serverVersion(final String serverVersion) {
+ this.serverVersion = Preconditions.checkNotNull(serverVersion, "serverVersion");
+ return this;
+ }
+
+ @NotNull
+ public Builder plugins(@NotNull Collection<PluginInformation> plugins) {
+ public Builder plugins(final Collection<PluginInformation> plugins) {
+ this.plugins.addAll(Preconditions.checkNotNull(plugins, "plugins"));
+ return this;
+ }
+
+ @NotNull
+ public Builder plugins(@NotNull PluginInformation... plugins) {
+ public Builder plugins(final PluginInformation... plugins) {
+ this.plugins.addAll(Arrays.asList(Preconditions.checkNotNull(plugins, "plugins")));
+ return this;
+ }
+
+ @NotNull
+ public Builder clearPlugins() {
+ this.plugins.clear();
+ return this;
@ -379,19 +354,18 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ *
+ * @return response
+ */
+ @NotNull
+ public QueryResponse build() {
+ return new QueryResponse(
+ Preconditions.checkNotNull(motd, "motd"),
+ Preconditions.checkNotNull(gameVersion, "gameVersion"),
+ Preconditions.checkNotNull(map, "map"),
+ currentPlayers,
+ maxPlayers,
+ Preconditions.checkNotNull(hostname, "hostname"),
+ port,
+ ImmutableList.copyOf(players),
+ Preconditions.checkNotNull(serverVersion, "serverVersion"),
+ ImmutableList.copyOf(plugins)
+ Preconditions.checkNotNull(this.motd, "motd"),
+ Preconditions.checkNotNull(this.gameVersion, "gameVersion"),
+ Preconditions.checkNotNull(this.map, "map"),
+ this.currentPlayers,
+ this.maxPlayers,
+ Preconditions.checkNotNull(this.hostname, "hostname"),
+ this.port,
+ ImmutableList.copyOf(this.players),
+ Preconditions.checkNotNull(this.serverVersion, "serverVersion"),
+ ImmutableList.copyOf(this.plugins)
+ );
+ }
+ }
@ -404,31 +378,28 @@ index 0000000000000000000000000000000000000000..8edc33bde29e967cec488d0f5e2f1097
+ private String name;
+ private String version;
+
+ public PluginInformation(@NotNull String name, @NotNull String version) {
+ public PluginInformation(final String name, final String version) {
+ this.name = Preconditions.checkNotNull(name, "name");
+ this.version = Preconditions.checkNotNull(version, "version");
+ }
+
+ @NotNull
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(@NotNull String name) {
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public void setVersion(@NotNull String version) {
+ public void setVersion(final String version) {
+ this.version = version;
+ }
+
+ @NotNull
+ public String getVersion() {
+ return this.version;
+ }
+
+ @NotNull
+ public static PluginInformation of(@NotNull String name, @NotNull String version) {
+ public static PluginInformation of(final String name, final String version) {
+ return new PluginInformation(name, version);
+ }
+ }

View file

@ -7,20 +7,21 @@ 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..17e9f39ce1cc7489e936c96f95b8b0579528b222
index 0000000000000000000000000000000000000000..15a177ce555ed329988d97a9f0b5d9c71aea18fb
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerTickEndEvent.java
@@ -0,0 +1,62 @@
@@ -0,0 +1,61 @@
+package com.destroystokyo.paper.event.server;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the server has finished ticking the main loop
+ */
+@NullMarked
+public class ServerTickEndEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -30,7 +31,7 @@ index 0000000000000000000000000000000000000000..17e9f39ce1cc7489e936c96f95b8b057
+ private final long timeEnd;
+
+ @ApiStatus.Internal
+ public ServerTickEndEvent(int tickNumber, double tickDuration, long timeRemaining) {
+ public ServerTickEndEvent(final int tickNumber, final double tickDuration, final long timeRemaining) {
+ this.tickNumber = tickNumber;
+ this.tickDuration = tickDuration;
+ this.timeEnd = System.nanoTime() + timeRemaining;
@ -63,29 +64,28 @@ index 0000000000000000000000000000000000000000..17e9f39ce1cc7489e936c96f95b8b057
+ return this.timeEnd - System.nanoTime();
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
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..fb5bbfffea8b883e4c8769484a2b64dd895cb617
index 0000000000000000000000000000000000000000..7c15e6487e17b3255e2428d73aef344ee32a43fd
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerTickStartEvent.java
@@ -0,0 +1,35 @@
@@ -0,0 +1,34 @@
+package com.destroystokyo.paper.event.server;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+@NullMarked
+public class ServerTickStartEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..fb5bbfffea8b883e4c8769484a2b64dd
+ private final int tickNumber;
+
+ @ApiStatus.Internal
+ public ServerTickStartEvent(int tickNumber) {
+ public ServerTickStartEvent(final int tickNumber) {
+ this.tickNumber = tickNumber;
+ }
+
@ -104,12 +104,10 @@ index 0000000000000000000000000000000000000000..fb5bbfffea8b883e4c8769484a2b64dd
+ return this.tickNumber;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -8,10 +8,10 @@ Adds a new event similar to PlayerEggThrowEvent, but without the Player requirem
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ThrownEggHatchEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ThrownEggHatchEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b3510879169a0a125
index 0000000000000000000000000000000000000000..26526049a4c7f7ebe6bea27a9c5a638df3ef8854
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/ThrownEggHatchEvent.java
@@ -0,0 +1,120 @@
@@ -0,0 +1,117 @@
+package com.destroystokyo.paper.event.entity;
+
+import com.google.common.base.Preconditions;
@ -20,13 +20,14 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a thrown egg might hatch.
+ * <p>
+ * This event fires for all thrown eggs that may hatch, players, dispensers, etc.
+ */
+@NullMarked
+public class ThrownEggHatchEvent extends Event {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -37,7 +38,7 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ private EntityType hatchType;
+
+ @ApiStatus.Internal
+ public ThrownEggHatchEvent(@NotNull final Egg egg, final boolean hatching, final byte numHatches, @NotNull final EntityType hatchingType) {
+ public ThrownEggHatchEvent(final Egg egg, final boolean hatching, final byte numHatches, final EntityType hatchingType) {
+ this.egg = egg;
+ this.hatching = hatching;
+ this.numHatches = numHatches;
@ -49,7 +50,6 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ *
+ * @return the egg involved in this event
+ */
+ @NotNull
+ public Egg getEgg() {
+ return this.egg;
+ }
@ -68,9 +68,9 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ * Sets whether the egg will hatch or not.
+ *
+ * @param hatching {@code true} if you want the egg to hatch, {@code false} if you want it
+ * not to
+ * not to
+ */
+ public void setHatching(boolean hatching) {
+ public void setHatching(final boolean hatching) {
+ this.hatching = hatching;
+ }
+
@ -79,7 +79,6 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ *
+ * @return The type of the mob being hatched by the egg
+ */
+ @NotNull
+ public EntityType getHatchingType() {
+ return this.hatchType;
+ }
@ -89,13 +88,13 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ *
+ * @param hatchType The type of the mob being hatched by the egg
+ */
+ public void setHatchingType(@NotNull EntityType hatchType) {
+ public void setHatchingType(final EntityType hatchType) {
+ Preconditions.checkArgument(hatchType.isSpawnable(), "Can't spawn that entity type from an egg!");
+ this.hatchType = hatchType;
+ }
+
+ /**
+ * Get the number of mob hatches from the egg. By default the number will
+ * Get the number of mob hatches from the egg. By default, the number will
+ * be the number the server would've done
+ * <ul>
+ * <li>7/8 chance of being 0
@ -117,17 +116,15 @@ index 0000000000000000000000000000000000000000..092bab9be36acc0f04c7ea5b35108791
+ *
+ * @param numHatches The number of mobs coming out of the egg
+ */
+ public void setNumHatches(byte numHatches) {
+ public void setNumHatches(final byte numHatches) {
+ this.numHatches = numHatches;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -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..a6306c957fcacdcbcc8037b4ee33a167d21ff29e
index 0000000000000000000000000000000000000000..1f1c159db2095733a585e102f34c2b657ca82dc2
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityJumpEvent.java
@@ -0,0 +1,50 @@
@@ -0,0 +1,48 @@
+package com.destroystokyo.paper.event.entity;
+
+import org.bukkit.entity.LivingEntity;
@ -17,13 +17,14 @@ index 0000000000000000000000000000000000000000..a6306c957fcacdcbcc8037b4ee33a167
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an entity jumps
+ * <p>
+ * Cancelling the event will stop the entity from jumping
+ */
+@NullMarked
+public class EntityJumpEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -31,11 +32,10 @@ index 0000000000000000000000000000000000000000..a6306c957fcacdcbcc8037b4ee33a167
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityJumpEvent(@NotNull LivingEntity entity) {
+ public EntityJumpEvent(final LivingEntity entity) {
+ super(entity);
+ }
+
+ @NotNull
+ @Override
+ public LivingEntity getEntity() {
+ return (LivingEntity) super.getEntity();
@ -45,17 +45,15 @@ index 0000000000000000000000000000000000000000..a6306c957fcacdcbcc8037b4ee33a167
+ return this.cancelled;
+ }
+
+ 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;
+ }

View file

@ -48,7 +48,7 @@ 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..c305c606bef93866993095cec5f50e191c5a382a
index 0000000000000000000000000000000000000000..5ae8b843f78b22e300de0202fb800fcae6ff49b0
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/inventory/PrepareResultEvent.java
@@ -0,0 +1,40 @@
@ -58,18 +58,19 @@ index 0000000000000000000000000000000000000000..c305c606bef93866993095cec5f50e19
+import org.bukkit.inventory.InventoryView;
+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 item is put in an inventory containing a result slot
+ */
+@NullMarked
+public class PrepareResultEvent extends PrepareInventoryResultEvent {
+
+ // HandlerList on PrepareInventoryResultEvent to ensure api compat
+
+ @ApiStatus.Internal
+ public PrepareResultEvent(@NotNull InventoryView inventory, @Nullable ItemStack result) {
+ public PrepareResultEvent(final InventoryView inventory, final @Nullable ItemStack result) {
+ super(inventory, result);
+ }
+
@ -78,8 +79,7 @@ index 0000000000000000000000000000000000000000..c305c606bef93866993095cec5f50e19
+ *
+ * @return result item
+ */
+ @Nullable
+ public ItemStack getResult() {
+ public @Nullable ItemStack getResult() {
+ return super.getResult();
+ }
+
@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..c305c606bef93866993095cec5f50e19
+ *
+ * @param result result item
+ */
+ public void setResult(@Nullable ItemStack result) {
+ public void setResult(final @Nullable ItemStack result) {
+ super.setResult(result);
+ }
+}

View file

@ -6,12 +6,13 @@ Subject: [PATCH] Add PlayerShearBlockEvent
diff --git a/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java b/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a7e955a4f
index 0000000000000000000000000000000000000000..33c6e1868e1bad4802bcadecebc2b46633690fce
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java
@@ -0,0 +1,113 @@
@@ -0,0 +1,107 @@
+package io.papermc.paper.event.block;
+
+import java.util.List;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
@ -20,9 +21,7 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a player uses sheers on a block.
@ -32,6 +31,7 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ * <p>
+ * Examples include shearing a pumpkin to turn it into a carved pumpkin or shearing a beehive to get honeycomb.
+ */
+@NullMarked
+public class PlayerShearBlockEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public PlayerShearBlockEvent(@NotNull Player player, @NotNull Block block, @NotNull ItemStack item, @NotNull EquipmentSlot hand, @NotNull List<ItemStack> drops) {
+ public PlayerShearBlockEvent(final Player player, final Block block, final ItemStack item, final EquipmentSlot hand, final List<ItemStack> drops) {
+ super(player);
+ this.block = block;
+ this.item = item;
@ -57,7 +57,6 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ *
+ * @return The {@link Block} which block is being sheared in this event.
+ */
+ @NotNull
+ public Block getBlock() {
+ return this.block;
+ }
@ -67,7 +66,6 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ *
+ * @return The {@link ItemStack} of the shears.
+ */
+ @NotNull
+ public ItemStack getItem() {
+ return this.item;
+ }
@ -77,7 +75,6 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ *
+ * @return Either {@link EquipmentSlot#HAND} OR {@link EquipmentSlot#OFF_HAND}.
+ */
+ @NotNull
+ public EquipmentSlot getHand() {
+ return this.hand;
+ }
@ -85,9 +82,8 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ /**
+ * Gets the resulting drops of this event.
+ *
+ * @return A {@link List list} of {@link ItemStack items} that will be dropped as result of this event.
+ * @return A mutable {@link List list} of {@link ItemStack items} that will be dropped as result of this event.
+ */
+ @NotNull
+ public List<ItemStack> getDrops() {
+ return this.drops;
+ }
@ -108,17 +104,15 @@ index 0000000000000000000000000000000000000000..9bb4a79320eac7d662d9d04765664b6a
+ * @param cancel whether the shearing of the block should be cancelled or not.
+ */
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add TargetHitEvent API
diff --git a/src/main/java/io/papermc/paper/event/block/TargetHitEvent.java b/src/main/java/io/papermc/paper/event/block/TargetHitEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..5247e7f78e0076089c1e1bdea2afbb455c43732a
index 0000000000000000000000000000000000000000..6555bf7f4485eacd8d35113d5b21b73f0693a950
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/TargetHitEvent.java
@@ -0,0 +1,61 @@
@@ -0,0 +1,60 @@
+package io.papermc.paper.event.block;
+
+import com.google.common.base.Preconditions;
@ -19,8 +19,8 @@ index 0000000000000000000000000000000000000000..5247e7f78e0076089c1e1bdea2afbb45
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.ProjectileHitEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a Target Block is hit by a projectile.
@ -29,6 +29,7 @@ index 0000000000000000000000000000000000000000..5247e7f78e0076089c1e1bdea2afbb45
+ * and in the case that the shooter is a player, will stop them from receiving
+ * advancement criteria.
+ */
+@NullMarked
+public class TargetHitEvent extends ProjectileHitEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..5247e7f78e0076089c1e1bdea2afbb45
+ private int signalStrength;
+
+ @ApiStatus.Internal
+ public TargetHitEvent(@NotNull Projectile projectile, @NotNull Block block, @NotNull BlockFace blockFace, int signalStrength) {
+ public TargetHitEvent(final Projectile projectile, final Block block, final BlockFace blockFace, final int signalStrength) {
+ super(projectile, null, block, blockFace);
+ this.signalStrength = signalStrength;
+ }
@ -55,18 +56,16 @@ index 0000000000000000000000000000000000000000..5247e7f78e0076089c1e1bdea2afbb45
+ *
+ * @param signalStrength the strength of the redstone signal to be emitted
+ */
+ public void setSignalStrength(@Range(from = 0, to = 15) int signalStrength) {
+ public void setSignalStrength(final @Range(from = 0, to = 15) int signalStrength) {
+ Preconditions.checkArgument(signalStrength >= 0 && signalStrength <= 15, "Signal strength out of range (%s), must be in range [0,15]", signalStrength);
+ this.signalStrength = signalStrength;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add EntityLoadCrossbowEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityLoadCrossbowEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityLoadCrossbowEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb65c478a9
index 0000000000000000000000000000000000000000..f7631a5ac0f2ccfa6b81bea9ab54b30fbb3278dd
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityLoadCrossbowEvent.java
@@ -0,0 +1,96 @@
@@ -0,0 +1,92 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.LivingEntity;
@ -19,11 +19,12 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+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;
+
+/**
+ * Called when a LivingEntity loads a crossbow with a projectile.
+ */
+@NullMarked
+public class EntityLoadCrossbowEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -35,13 +36,12 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityLoadCrossbowEvent(@NotNull LivingEntity entity, @NotNull ItemStack crossbow, @NotNull EquipmentSlot hand) {
+ public EntityLoadCrossbowEvent(final LivingEntity entity, final ItemStack crossbow, final EquipmentSlot hand) {
+ super(entity);
+ this.crossbow = crossbow;
+ this.hand = hand;
+ }
+
+ @NotNull
+ @Override
+ public LivingEntity getEntity() {
+ return (LivingEntity) super.getEntity();
@ -52,7 +52,6 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+ *
+ * @return the crossbow involved in this event
+ */
+ @NotNull
+ public ItemStack getCrossbow() {
+ return this.crossbow;
+ }
@ -62,7 +61,6 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+ *
+ * @return the hand
+ */
+ @NotNull
+ public EquipmentSlot getHand() {
+ return this.hand;
+ }
@ -77,7 +75,7 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+ /**
+ * @param consume should the item be consumed
+ */
+ public void setConsumeItem(boolean consume) {
+ public void setConsumeItem(final boolean consume) {
+ this.consumeItem = consume;
+ }
+
@ -91,17 +89,15 @@ index 0000000000000000000000000000000000000000..8434ea803e3135380f9351c82a414ccb
+ * projectile that would be loaded into the crossbow will not be consumed.
+ */
+ @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;
+ }

View file

@ -6,22 +6,23 @@ Subject: [PATCH] Added ServerResourcesReloadedEvent
diff --git a/src/main/java/io/papermc/paper/event/server/ServerResourcesReloadedEvent.java b/src/main/java/io/papermc/paper/event/server/ServerResourcesReloadedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7ed7d6b6469e175d3949ffa9c502cbfde609215
index 0000000000000000000000000000000000000000..468bbfcaa3fed60dc73726f4e5ace93009f92507
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/server/ServerResourcesReloadedEvent.java
@@ -0,0 +1,49 @@
@@ -0,0 +1,47 @@
+package io.papermc.paper.event.server;
+
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when resources such as datapacks are reloaded (e.g. /minecraft:reload)
+ * <p>
+ * Intended for use to re-register custom recipes, advancements that may be lost during a reload like this.
+ */
+@NullMarked
+public class ServerResourcesReloadedEvent extends ServerEvent {
+
+ public static final HandlerList HANDLER_LIST = new HandlerList();
@ -29,7 +30,7 @@ index 0000000000000000000000000000000000000000..a7ed7d6b6469e175d3949ffa9c502cbf
+ private final Cause cause;
+
+ @ApiStatus.Internal
+ public ServerResourcesReloadedEvent(@NotNull Cause cause) {
+ public ServerResourcesReloadedEvent(final Cause cause) {
+ this.cause = cause;
+ }
+
@ -38,17 +39,14 @@ index 0000000000000000000000000000000000000000..a7ed7d6b6469e175d3949ffa9c502cbf
+ *
+ * @return the reload cause
+ */
+ @NotNull
+ public Cause getCause() {
+ return this.cause;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;

View file

@ -6,21 +6,23 @@ 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..d531b034b49b163e5095e840a5c9c4fe5eb73319
index 0000000000000000000000000000000000000000..03f91644189e2d1c615f0a22ab0a7c38c803f6c4
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockFailedDispenseEvent.java
@@ -0,0 +1,56 @@
@@ -0,0 +1,58 @@
+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.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a block tries to dispense an item, but its inventory is empty.
+ */
+@NullMarked
+public class BlockFailedDispenseEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -28,7 +30,7 @@ index 0000000000000000000000000000000000000000..d531b034b49b163e5095e840a5c9c4fe
+ private boolean shouldPlayEffect = true;
+
+ @ApiStatus.Internal
+ public BlockFailedDispenseEvent(@NotNull Block theBlock) {
+ public BlockFailedDispenseEvent(final Block theBlock) {
+ super(theBlock);
+ }
+
@ -44,7 +46,7 @@ index 0000000000000000000000000000000000000000..d531b034b49b163e5095e840a5c9c4fe
+ *
+ * @param playEffect if the effect should be played
+ */
+ public void shouldPlayEffect(boolean playEffect) {
+ public void shouldPlayEffect(final boolean playEffect) {
+ this.shouldPlayEffect = playEffect;
+ }
+
@ -58,11 +60,11 @@ index 0000000000000000000000000000000000000000..d531b034b49b163e5095e840a5c9c4fe
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NotNull HandlerList getHandlerList() {
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}

View file

@ -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..62547d5853e7355a805fa1e7f1e5f56d06fca4ba
index 0000000000000000000000000000000000000000..fd10a34ec4e0731574cc7d69620e0b353ce8a21b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockPreDispenseEvent.java
@@ -0,0 +1,65 @@
@@ -0,0 +1,63 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Block;
@ -18,8 +18,9 @@ index 0000000000000000000000000000000000000000..62547d5853e7355a805fa1e7f1e5f56d
+import org.bukkit.event.block.BlockEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+@NullMarked
+public class BlockPreDispenseEvent extends BlockEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -30,7 +31,7 @@ index 0000000000000000000000000000000000000000..62547d5853e7355a805fa1e7f1e5f56d
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public BlockPreDispenseEvent(@NotNull Block block, @NotNull ItemStack itemStack, int slot) {
+ public BlockPreDispenseEvent(final Block block, final ItemStack itemStack, final int slot) {
+ super(block);
+ this.itemStack = itemStack;
+ this.slot = slot;
@ -41,7 +42,6 @@ index 0000000000000000000000000000000000000000..62547d5853e7355a805fa1e7f1e5f56d
+ *
+ * @return The item to be dispensed
+ */
+ @NotNull
+ public ItemStack getItemStack() {
+ return this.itemStack;
+ }
@ -61,16 +61,14 @@ index 0000000000000000000000000000000000000000..62547d5853e7355a805fa1e7f1e5f56d
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] add DragonEggFormEvent
diff --git a/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java b/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..695c21a296c6d12e1204eba33b92c44e7c2d98b8
index 0000000000000000000000000000000000000000..d0549d95985ff08af1fc1e6291e0124b766bf99d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/DragonEggFormEvent.java
@@ -0,0 +1,55 @@
@@ -0,0 +1,53 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.Material;
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..695c21a296c6d12e1204eba33b92c44e
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockFormEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the {@link EnderDragon} is defeated (killed) in a {@link DragonBattle},
@ -30,6 +30,7 @@ index 0000000000000000000000000000000000000000..695c21a296c6d12e1204eba33b92c44e
+ * <b>This event might be cancelled by default depending on
+ * e.g. {@link DragonBattle#hasBeenPreviouslyKilled()} and server configuration.</b>
+ */
+@NullMarked
+public class DragonEggFormEvent extends BlockFormEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -37,7 +38,7 @@ index 0000000000000000000000000000000000000000..695c21a296c6d12e1204eba33b92c44e
+ private final DragonBattle dragonBattle;
+
+ @ApiStatus.Internal
+ public DragonEggFormEvent(@NotNull Block block, @NotNull BlockState newState, @NotNull DragonBattle dragonBattle) {
+ public DragonEggFormEvent(final Block block, final BlockState newState, final DragonBattle dragonBattle) {
+ super(block, newState);
+ this.dragonBattle = dragonBattle;
+ }
@ -49,18 +50,15 @@ index 0000000000000000000000000000000000000000..695c21a296c6d12e1204eba33b92c44e
+ *
+ * @return the dragon battle
+ */
+ @NotNull
+ public DragonBattle getDragonBattle() {
+ return this.dragonBattle;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] EntityMoveEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityMoveEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityMoveEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd46c2ad77c
index 0000000000000000000000000000000000000000..49ace395393839b3652a537207b4cf5b24beeac0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityMoveEvent.java
@@ -0,0 +1,150 @@
@@ -0,0 +1,146 @@
+package io.papermc.paper.event.entity;
+
+import com.google.common.base.Preconditions;
@ -20,13 +20,14 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+import org.bukkit.event.entity.EntityEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Holds information for living entity movement events
+ * <p>
+ * Does not fire for players; use {@link PlayerMoveEvent} for player movement.
+ */
+@NullMarked
+public class EntityMoveEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -37,14 +38,13 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityMoveEvent(@NotNull LivingEntity entity, @NotNull Location from, @NotNull Location to) {
+ public EntityMoveEvent(final LivingEntity entity, final Location from, final Location to) {
+ super(entity);
+ this.from = from;
+ this.to = to;
+ }
+
+ @Override
+ @NotNull
+ public LivingEntity getEntity() {
+ return (LivingEntity) super.getEntity();
+ }
@ -54,7 +54,6 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ *
+ * @return Location the entity moved from
+ */
+ @NotNull
+ public Location getFrom() {
+ return this.from;
+ }
@ -64,8 +63,8 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ *
+ * @param from New location to mark as the entity's previous location
+ */
+ public void setFrom(@NotNull Location from) {
+ validateLocation(from);
+ public void setFrom(final Location from) {
+ this.validateLocation(from);
+ this.from = from;
+ }
+
@ -74,7 +73,6 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ *
+ * @return Location the entity moved to
+ */
+ @NotNull
+ public Location getTo() {
+ return this.to;
+ }
@ -84,8 +82,8 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ *
+ * @param to New Location this entity will move to
+ */
+ public void setTo(@NotNull Location to) {
+ validateLocation(to);
+ public void setTo(final Location to) {
+ this.validateLocation(to);
+ this.to = to;
+ }
+
@ -95,7 +93,7 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ * @return whether the entity has changed position or not
+ */
+ public boolean hasChangedPosition() {
+ return hasExplicitlyChangedPosition() || !this.from.getWorld().equals(this.to.getWorld());
+ return this.hasExplicitlyChangedPosition() || !this.from.getWorld().equals(this.to.getWorld());
+ }
+
+ /**
@ -113,7 +111,7 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ * @return whether the entity has moved to a new block or not
+ */
+ public boolean hasChangedBlock() {
+ return hasExplicitlyChangedBlock() || !from.getWorld().equals(to.getWorld());
+ return this.hasExplicitlyChangedBlock() || !this.from.getWorld().equals(this.to.getWorld());
+ }
+
+ /**
@ -134,7 +132,7 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ return this.from.getPitch() != this.to.getPitch() || this.from.getYaw() != this.to.getYaw();
+ }
+
+ private void validateLocation(@NotNull Location loc) {
+ private void validateLocation(final Location loc) {
+ Preconditions.checkArgument(loc != null, "Cannot use null location!");
+ Preconditions.checkArgument(loc.getWorld() != null, "Cannot use null location with null world!");
+ }
@ -145,17 +143,15 @@ index 0000000000000000000000000000000000000000..46990a220f70b04218b14aec1e9efbd4
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Introduce beacon activation/deactivation events
diff --git a/src/main/java/io/papermc/paper/event/block/BeaconActivatedEvent.java b/src/main/java/io/papermc/paper/event/block/BeaconActivatedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..05609ec9df637c9aa53528218cbc8cda30f0aea1
index 0000000000000000000000000000000000000000..380538656e675fdfaf9077da8ff48dc5c427a657
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BeaconActivatedEvent.java
@@ -0,0 +1,43 @@
@@ -0,0 +1,41 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Beacon;
@ -17,18 +17,19 @@ index 0000000000000000000000000000000000000000..05609ec9df637c9aa53528218cbc8cda
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a beacon is activated.
+ * Activation occurs when the beacon beam becomes visible.
+ */
+@NullMarked
+public class BeaconActivatedEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
+ public BeaconActivatedEvent(@NotNull Block block) {
+ public BeaconActivatedEvent(final Block block) {
+ super(block);
+ }
+
@ -37,28 +38,25 @@ index 0000000000000000000000000000000000000000..05609ec9df637c9aa53528218cbc8cda
+ *
+ * @return the beacon that was activated.
+ */
+ @NotNull
+ public Beacon getBeacon() {
+ return (Beacon) this.block.getState();
+ }
+
+ @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/block/BeaconDeactivatedEvent.java b/src/main/java/io/papermc/paper/event/block/BeaconDeactivatedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc106d6bfbd9d0ab84b17597d71381a5c0b07d64
index 0000000000000000000000000000000000000000..4e5b2b2413e2aae03132ecd76123cd93dfbd77ce
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BeaconDeactivatedEvent.java
@@ -0,0 +1,46 @@
@@ -0,0 +1,44 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.Material;
@ -67,18 +65,19 @@ index 0000000000000000000000000000000000000000..dc106d6bfbd9d0ab84b17597d71381a5
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockEvent;
+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 beacon is deactivated, either because its base block(s) or itself were destroyed.
+ */
+@NullMarked
+public class BeaconDeactivatedEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
+ public BeaconDeactivatedEvent(@NotNull Block block) {
+ public BeaconDeactivatedEvent(final Block block) {
+ super(block);
+ }
+
@ -89,18 +88,15 @@ index 0000000000000000000000000000000000000000..dc106d6bfbd9d0ab84b17597d71381a5
+ *
+ * @return The beacon that got deactivated, or {@code null} if it does not exist.
+ */
+ @Nullable
+ public Beacon getBeacon() {
+ public @Nullable Beacon getBeacon() {
+ return this.block.getType() == Material.BEACON ? (Beacon) this.block.getState() : null;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add EntityInsideBlockEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityInsideBlockEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityInsideBlockEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae24471a16d622
index 0000000000000000000000000000000000000000..314aab3eb4c802e6ebbe5a4ee7d5fbbd3f504c1b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityInsideBlockEvent.java
@@ -0,0 +1,87 @@
@@ -0,0 +1,85 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.block.Block;
@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae2447
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an entity enters the hitbox of a block.
@ -53,6 +53,7 @@ index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae2447
+ * <li>Wither rose</li>
+ * </ul>
+ */
+@NullMarked
+public class EntityInsideBlockEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -61,7 +62,7 @@ index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae2447
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityInsideBlockEvent(@NotNull Entity entity, @NotNull Block block) {
+ public EntityInsideBlockEvent(final Entity entity, final Block block) {
+ super(entity);
+ this.block = block;
+ }
@ -71,7 +72,6 @@ index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae2447
+ *
+ * @return the block
+ */
+ @NotNull
+ public Block getBlock() {
+ return this.block;
+ }
@ -82,17 +82,15 @@ index 0000000000000000000000000000000000000000..b162d4b6f12c0d7d3542ada3bdae2447
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add PufferFishStateChangeEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/PufferFishStateChangeEvent.java b/src/main/java/io/papermc/paper/event/entity/PufferFishStateChangeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e04b49c1e2bc2a965c9be2388539d9ed5a58f89
index 0000000000000000000000000000000000000000..b4521d64eefd8f871f8ce78734e6626896e8b0d0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/PufferFishStateChangeEvent.java
@@ -0,0 +1,87 @@
@@ -0,0 +1,85 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.PufferFish;
@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..4e04b49c1e2bc2a965c9be2388539d9e
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called just before a {@link PufferFish} inflates or deflates.
+ */
+@NullMarked
+public class PufferFishStateChangeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -30,12 +31,11 @@ index 0000000000000000000000000000000000000000..4e04b49c1e2bc2a965c9be2388539d9e
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public PufferFishStateChangeEvent(@NotNull PufferFish entity, int newPuffState) {
+ public PufferFishStateChangeEvent(final PufferFish entity, final int newPuffState) {
+ super(entity);
+ this.newPuffState = newPuffState;
+ }
+
+ @NotNull
+ @Override
+ public PufferFish getEntity() {
+ return (PufferFish) super.getEntity();
@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..4e04b49c1e2bc2a965c9be2388539d9e
+ * @param cancel {@code true} if you wish to cancel the (in/de)flation
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
@ -86,13 +86,11 @@ index 0000000000000000000000000000000000000000..4e04b49c1e2bc2a965c9be2388539d9e
+ return this.cancelled;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -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..47eabdc8b1a3a3207f197eeca00f3ca5c9940b89
index 0000000000000000000000000000000000000000..272a4a06e766291aeee4f9e19a1ed26aa62e569a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/ElderGuardianAppearanceEvent.java
@@ -0,0 +1,67 @@
@@ -0,0 +1,64 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.ElderGuardian;
@ -18,11 +18,12 @@ index 0000000000000000000000000000000000000000..47eabdc8b1a3a3207f197eeca00f3ca5
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when an {@link ElderGuardian} appears in front of a {@link Player}.
+ */
+@NullMarked
+public class ElderGuardianAppearanceEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -31,7 +32,7 @@ index 0000000000000000000000000000000000000000..47eabdc8b1a3a3207f197eeca00f3ca5
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public ElderGuardianAppearanceEvent(@NotNull ElderGuardian guardian, @NotNull Player affectedPlayer) {
+ public ElderGuardianAppearanceEvent(final ElderGuardian guardian, final Player affectedPlayer) {
+ super(guardian);
+ this.affectedPlayer = affectedPlayer;
+ }
@ -41,7 +42,6 @@ index 0000000000000000000000000000000000000000..47eabdc8b1a3a3207f197eeca00f3ca5
+ *
+ * @return Player affected by the appearance
+ */
+ @NotNull
+ public Player getAffectedPlayer() {
+ return this.affectedPlayer;
+ }
@ -51,7 +51,6 @@ index 0000000000000000000000000000000000000000..47eabdc8b1a3a3207f197eeca00f3ca5
+ *
+ * @return The elder guardian
+ */
+ @NotNull
+ public ElderGuardian getEntity() {
+ return (ElderGuardian) super.getEntity();
+ }
@ -62,17 +61,15 @@ index 0000000000000000000000000000000000000000..47eabdc8b1a3a3207f197eeca00f3ca5
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add WaterBottleSplashEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/WaterBottleSplashEvent.java b/src/main/java/io/papermc/paper/event/entity/WaterBottleSplashEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405389f431a
index 0000000000000000000000000000000000000000..1f74ea11c726273c3c2a7fc6f381716e230ef5c9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/WaterBottleSplashEvent.java
@@ -0,0 +1,137 @@
@@ -0,0 +1,135 @@
+package io.papermc.paper.event.entity;
+
+import java.util.Collection;
@ -23,28 +23,29 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+import org.bukkit.entity.ThrownPotion;
+import org.bukkit.event.entity.PotionSplashEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Unmodifiable;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when a splash water potion "splashes" and affects
+ * different entities in different ways.
+ */
+@NullMarked
+public class WaterBottleSplashEvent extends PotionSplashEvent {
+
+ private final @NotNull Set<LivingEntity> rehydrate;
+ private final @NotNull Set<LivingEntity> extinguish;
+ private final Set<LivingEntity> rehydrate;
+ private final Set<LivingEntity> extinguish;
+
+ @ApiStatus.Internal
+ public WaterBottleSplashEvent(
+ final @NotNull ThrownPotion potion,
+ final ThrownPotion potion,
+ final @Nullable Entity hitEntity,
+ final @Nullable Block hitBlock,
+ final @Nullable BlockFace hitFace,
+ final @NotNull Map<LivingEntity, Double> affectedEntities,
+ final @NotNull Set<LivingEntity> rehydrate,
+ final @NotNull Set<LivingEntity> extinguish
+ final Map<LivingEntity, Double> affectedEntities,
+ final Set<LivingEntity> rehydrate,
+ final Set<LivingEntity> extinguish
+ ) {
+ super(potion, hitEntity, hitBlock, hitFace, affectedEntities);
+ this.rehydrate = rehydrate;
@ -61,7 +62,6 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ * @see #doNotDamageAsWaterSensitive(LivingEntity)
+ * @see #damageAsWaterSensitive(LivingEntity)
+ */
+ @NotNull
+ public @Unmodifiable Collection<LivingEntity> getToDamage() {
+ return this.affectedEntities.entrySet().stream().filter(entry -> entry.getValue() > 0).map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet());
+ }
@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ *
+ * @param entity entity to remove
+ */
+ public void doNotDamageAsWaterSensitive(final @NotNull LivingEntity entity) {
+ public void doNotDamageAsWaterSensitive(final LivingEntity entity) {
+ this.affectedEntities.remove(entity);
+ }
+
@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ *
+ * @param entity entity to add
+ */
+ public void damageAsWaterSensitive(final @NotNull LivingEntity entity) {
+ public void damageAsWaterSensitive(final LivingEntity entity) {
+ this.affectedEntities.put(entity, 1.0);
+ }
+
@ -96,7 +96,6 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ *
+ * @return the entities
+ */
+ @NotNull
+ public Collection<LivingEntity> getToRehydrate() {
+ return this.rehydrate;
+ }
@ -107,7 +106,6 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ *
+ * @return entities to be extinguished
+ */
+ @NotNull
+ public Collection<LivingEntity> getToExtinguish() {
+ return this.extinguish;
+ }
@ -118,7 +116,7 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ */
+ @Deprecated(since = "1.19.3")
+ @Override
+ public @NotNull Collection<LivingEntity> getAffectedEntities() {
+ public Collection<LivingEntity> getAffectedEntities() {
+ return super.getAffectedEntities();
+ }
+
@ -130,7 +128,7 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ */
+ @Deprecated(since = "1.19.3")
+ @Override
+ public double getIntensity(final @NotNull LivingEntity entity) {
+ public double getIntensity(final LivingEntity entity) {
+ return super.getIntensity(entity);
+ }
+
@ -143,7 +141,7 @@ index 0000000000000000000000000000000000000000..0c7725980d5a2f3652e53f75329ad405
+ */
+ @Deprecated(since = "1.19.3")
+ @Override
+ public void setIntensity(final @NotNull LivingEntity entity, final double intensity) {
+ public void setIntensity(final LivingEntity entity, final double intensity) {
+ super.setIntensity(entity, intensity);
+ }
+}

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Added EntityDamageItemEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityDamageItemEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityDamageItemEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be0620af2e
index 0000000000000000000000000000000000000000..c4cc0931892f949b7314d241dbe80caeceab4331
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityDamageItemEvent.java
@@ -0,0 +1,81 @@
@@ -0,0 +1,79 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.Entity;
@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+import org.bukkit.event.entity.EntityEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an item on or used by an entity takes durability damage as a result of being hit/used.
@ -26,6 +26,7 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+ * NOTE: default vanilla behaviour dictates that armor/tools picked up by
+ * mobs do not take damage (except via Thorns).
+ */
+@NullMarked
+public class EntityDamageItemEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityDamageItemEvent(@NotNull Entity entity, @NotNull ItemStack item, int damage) {
+ public EntityDamageItemEvent(final Entity entity, final ItemStack item, final int damage) {
+ super(entity);
+ this.item = item;
+ this.damage = damage;
@ -47,7 +48,6 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+ *
+ * @return the item
+ */
+ @NotNull
+ public ItemStack getItem() {
+ return this.item;
+ }
@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+ *
+ * @param damage the damage amount to cause
+ */
+ public void setDamage(int damage) {
+ public void setDamage(final int damage) {
+ this.damage = damage;
+ }
+
@ -76,17 +76,15 @@ index 0000000000000000000000000000000000000000..72ac972dea684a3ffac3bd48726746be
+ }
+
+ @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;
+ }

View file

@ -6,26 +6,26 @@ Subject: [PATCH] Add BlockBreakBlockEvent
diff --git a/src/main/java/io/papermc/paper/event/block/BlockBreakBlockEvent.java b/src/main/java/io/papermc/paper/event/block/BlockBreakBlockEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f7535daf0d9967fadb0c6f8afbd3993eace410d
index 0000000000000000000000000000000000000000..3b130d145f54939ad02e30b15c81120aac2078c2
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockBreakBlockEvent.java
@@ -0,0 +1,61 @@
@@ -0,0 +1,57 @@
+package io.papermc.paper.event.block;
+
+import java.util.List;
+import org.bukkit.block.Block;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockExpEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a block forces another block to break and drop items.
+ * <p>
+ * Currently called for piston's and liquid flows.
+ */
+@NullMarked
+public class BlockBreakBlockEvent extends BlockExpEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -34,18 +34,17 @@ index 0000000000000000000000000000000000000000..4f7535daf0d9967fadb0c6f8afbd3993
+ private final List<ItemStack> drops;
+
+ @ApiStatus.Internal
+ public BlockBreakBlockEvent(@NotNull Block block, @NotNull Block source, @NotNull List<ItemStack> drops) {
+ public BlockBreakBlockEvent(final Block block, final Block source, final List<ItemStack> drops) {
+ super(block, 0);
+ this.source = source;
+ this.drops = drops;
+ }
+
+ /**
+ * Gets the drops of this event
+ * Gets a mutable list of drops for this event
+ *
+ * @return the drops
+ */
+ @NotNull
+ public List<ItemStack> getDrops() {
+ return this.drops;
+ }
@ -55,18 +54,15 @@ index 0000000000000000000000000000000000000000..4f7535daf0d9967fadb0c6f8afbd3993
+ *
+ * @return the source
+ */
+ @NotNull
+ public Block getSource() {
+ return this.source;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add TameableDeathMessageEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/TameableDeathMessageEvent.java b/src/main/java/io/papermc/paper/event/entity/TameableDeathMessageEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8f99dc156
index 0000000000000000000000000000000000000000..b956ef8f95156c225741f53811b4a36963da6616
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/TameableDeathMessageEvent.java
@@ -0,0 +1,72 @@
@@ -0,0 +1,69 @@
+package io.papermc.paper.event.entity;
+
+import net.kyori.adventure.text.Component;
@ -18,11 +18,12 @@ index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a {@link Tameable} dies and sends a death message.
+ */
+@NullMarked
+public class TameableDeathMessageEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -31,7 +32,7 @@ index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public TameableDeathMessageEvent(@NotNull Tameable tameable, @NotNull Component deathMessage) {
+ public TameableDeathMessageEvent(final Tameable tameable, final Component deathMessage) {
+ super(tameable);
+ this.deathMessage = deathMessage;
+ }
@ -41,7 +42,7 @@ index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8
+ *
+ * @param deathMessage Death message to appear
+ */
+ public void deathMessage(@NotNull Component deathMessage) {
+ public void deathMessage(final Component deathMessage) {
+ this.deathMessage = deathMessage;
+ }
+
@ -50,12 +51,10 @@ index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8
+ *
+ * @return Death message to appear
+ */
+ @NotNull
+ public Component deathMessage() {
+ return this.deathMessage;
+ }
+
+ @NotNull
+ @Override
+ public Tameable getEntity() {
+ return (Tameable) super.getEntity();
@ -67,17 +66,15 @@ index 0000000000000000000000000000000000000000..5d449b90829bca7a6ff3060b637561d8
+ }
+
+ @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;
+ }

View file

@ -37,10 +37,10 @@ index 0000000000000000000000000000000000000000..bb68e6a2528eee81eb3f26f22b9c3550
+}
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..c43a3ad32902dbb13287e801375213745ce07b3c
index 0000000000000000000000000000000000000000..049471bac6c9b830fe7717c129173a723091963f
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityDyeEvent.java
@@ -0,0 +1,81 @@
@@ -0,0 +1,82 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.DyeColor;
@ -53,24 +53,25 @@ index 0000000000000000000000000000000000000000..c43a3ad32902dbb13287e80137521374
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+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 entity is dyed. Currently, this is called for {@link Sheep}
+ * being dyed, and {@link Wolf}/{@link Cat} collars being dyed.
+ */
+@NullMarked
+public class EntityDyeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Player player;
+ private final @Nullable Player player;
+ private DyeColor dyeColor;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityDyeEvent(@NotNull Entity entity, @NotNull DyeColor dyeColor, @Nullable Player player) {
+ public EntityDyeEvent(final Entity entity, final DyeColor dyeColor, final @Nullable Player player) {
+ super(entity);
+ this.dyeColor = dyeColor;
+ this.player = player;
@ -81,7 +82,7 @@ index 0000000000000000000000000000000000000000..c43a3ad32902dbb13287e80137521374
+ *
+ * @return the DyeColor the entity is being dyed
+ */
+ public @NotNull DyeColor getColor() {
+ public DyeColor getColor() {
+ return this.dyeColor;
+ }
+
@ -90,7 +91,7 @@ index 0000000000000000000000000000000000000000..c43a3ad32902dbb13287e80137521374
+ *
+ * @param dyeColor the DyeColor the entity will be dyed
+ */
+ public void setColor(@NotNull DyeColor dyeColor) {
+ public void setColor(final DyeColor dyeColor) {
+ this.dyeColor = dyeColor;
+ }
+
@ -109,16 +110,16 @@ index 0000000000000000000000000000000000000000..c43a3ad32902dbb13287e80137521374
+ }
+
+ @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;
+ }
+}

View file

@ -8,10 +8,10 @@ another entity.
diff --git a/src/main/java/io/papermc/paper/event/entity/WardenAngerChangeEvent.java b/src/main/java/io/papermc/paper/event/entity/WardenAngerChangeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2ab6c0244e
index 0000000000000000000000000000000000000000..7c06de67121f92f6e1e8890f250157721c78e627
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/WardenAngerChangeEvent.java
@@ -0,0 +1,108 @@
@@ -0,0 +1,103 @@
+package io.papermc.paper.event.entity;
+
+import com.google.common.base.Preconditions;
@ -21,14 +21,15 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when a Warden's anger level has changed due to another entity.
+ * <p>
+ * If the event is cancelled, the warden's anger level will not change.
+ */
+@NullMarked
+public class WardenAngerChangeEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -40,7 +41,7 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public WardenAngerChangeEvent(@NotNull final Warden warden, @NotNull final Entity target, final int oldAnger, final int newAnger) {
+ public WardenAngerChangeEvent(final Warden warden, final Entity target, final int oldAnger, final int newAnger) {
+ super(warden);
+ this.target = target;
+ this.oldAnger = oldAnger;
@ -52,7 +53,6 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ *
+ * @return triggering entity
+ */
+ @NotNull
+ public Entity getTarget() {
+ return this.target;
+ }
@ -63,8 +63,7 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ * @return old anger level
+ * @see Warden#getAnger(Entity)
+ */
+ @Range(from = 0, to = 150)
+ public int getOldAnger() {
+ public @Range(from = 0, to = 150) int getOldAnger() {
+ return this.oldAnger;
+ }
+
@ -74,8 +73,7 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ * @return new anger level
+ * @see Warden#getAnger(Entity)
+ */
+ @Range(from = 0, to = 150)
+ public int getNewAnger() {
+ public @Range(from = 0, to = 150) int getNewAnger() {
+ return this.newAnger;
+ }
+
@ -85,15 +83,14 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ * The anger of a warden is capped at 150.
+ *
+ * @param newAnger the new anger level, max 150
+ * @see Warden#setAnger(Entity, int)
+ * @throws IllegalArgumentException if newAnger is greater than 150
+ * @see Warden#setAnger(Entity, int)
+ */
+ public void setNewAnger(@Range(from = 0, to = 150) int newAnger) {
+ public void setNewAnger(final @Range(from = 0, to = 150) int newAnger) {
+ Preconditions.checkArgument(newAnger <= 150, "newAnger must not be greater than 150");
+ this.newAnger = newAnger;
+ }
+
+ @NotNull
+ @Override
+ public Warden getEntity() {
+ return (Warden) super.getEntity();
@ -105,17 +102,15 @@ index 0000000000000000000000000000000000000000..7f738c1116feae8e8571488d516fab2a
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add EntityPortalReadyEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityPortalReadyEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityPortalReadyEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..3450735c86a8af45491c010a796262ae892f14dc
index 0000000000000000000000000000000000000000..bc5f0ed43f5d341ec551e48eecf2614cdfd52d79
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityPortalReadyEvent.java
@@ -0,0 +1,94 @@
@@ -0,0 +1,95 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.PortalType;
@ -21,28 +21,29 @@ index 0000000000000000000000000000000000000000..3450735c86a8af45491c010a796262ae
+import org.bukkit.event.entity.EntityPortalEvent;
+import org.bukkit.event.player.PlayerPortalEvent;
+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 entity is ready to be teleported by a plugin.
+ * Currently this is only called after the required
+ * Currently, this is only called after the required
+ * ticks have passed for a Nether Portal.
+ * <p>
+ * Cancelling this event resets the entity's readiness
+ * regarding the current portal.
+ */
+@NullMarked
+public class EntityPortalReadyEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final PortalType portalType;
+ private World targetWorld;
+ private @Nullable World targetWorld;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityPortalReadyEvent(final @NotNull Entity entity, final @Nullable World targetWorld, final @NotNull PortalType portalType) {
+ public EntityPortalReadyEvent(final Entity entity, final @Nullable World targetWorld, final PortalType portalType) {
+ super(entity);
+ this.targetWorld = targetWorld;
+ this.portalType = portalType;
@ -81,7 +82,7 @@ index 0000000000000000000000000000000000000000..3450735c86a8af45491c010a796262ae
+ *
+ * @return the portal type
+ */
+ public @NotNull PortalType getPortalType() {
+ public PortalType getPortalType() {
+ return this.portalType;
+ }
+
@ -96,11 +97,11 @@ index 0000000000000000000000000000000000000000..3450735c86a8af45491c010a796262ae
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NotNull HandlerList getHandlerList() {
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Added EntityToggleSitEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityToggleSitEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityToggleSitEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..06222a8c7a19909582a00fd2e1553cc0be9d88e3
index 0000000000000000000000000000000000000000..ab1955bc61114798fe71cffa6fae3ee0beb3bd2a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityToggleSitEvent.java
@@ -0,0 +1,55 @@
@@ -0,0 +1,54 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.Entity;
@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..06222a8c7a19909582a00fd2e1553cc0
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Is called when an entity sits down or stands up.
+ */
+@NullMarked
+public class EntityToggleSitEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -30,7 +31,7 @@ index 0000000000000000000000000000000000000000..06222a8c7a19909582a00fd2e1553cc0
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityToggleSitEvent(@NotNull Entity entity, boolean isSitting) {
+ public EntityToggleSitEvent(final Entity entity, final boolean isSitting) {
+ super(entity);
+ this.isSitting = isSitting;
+ }
@ -50,17 +51,15 @@ index 0000000000000000000000000000000000000000..06222a8c7a19909582a00fd2e1553cc0
+ }
+
+ @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;
+ }

View file

@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..f309961e0e96b6baacc4fe6d80dabd6c
+}
diff --git a/src/main/java/io/papermc/paper/event/block/BlockLockCheckEvent.java b/src/main/java/io/papermc/paper/event/block/BlockLockCheckEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836e78d7b68
index 0000000000000000000000000000000000000000..f08d390f0ee9357dcc229d7a2520da602677d9ef
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockLockCheckEvent.java
@@ -0,0 +1,187 @@
@ -31,6 +31,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+
+import com.google.common.base.Preconditions;
+import io.papermc.paper.block.LockableTileState;
+import java.util.Objects;
+import net.kyori.adventure.sound.Sound;
+import net.kyori.adventure.text.Component;
+import org.bukkit.block.Block;
@ -40,28 +41,27 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+import org.bukkit.event.block.BlockEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Called when the server tries to check the lock on a lockable block entity.
+ * <br>
+ * See {@link #setResult(Result)} to change behavior
+ */
+@NullMarked
+public class BlockLockCheckEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Player player;
+ private Component lockedMessage;
+ private Sound lockedSound;
+ private ItemStack itemStack;
+ private @Nullable Component lockedMessage;
+ private @Nullable Sound lockedSound;
+ private @Nullable ItemStack itemStack;
+ private Result result = Result.DEFAULT;
+
+ @ApiStatus.Internal
+ public BlockLockCheckEvent(final @NotNull Block block, final @NotNull Player player, final @NotNull Component lockedMessage, final @NotNull Sound lockedSound) {
+ public BlockLockCheckEvent(final Block block, final Player player, final Component lockedMessage, final Sound lockedSound) {
+ super(block);
+ this.player = player;
+ this.lockedMessage = lockedMessage;
@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ *
+ * @return the snapshot block state.
+ */
+ public @NotNull LockableTileState getBlockState() {
+ public LockableTileState getBlockState() {
+ final BlockState blockState = this.getBlock().getState();
+ Preconditions.checkState(blockState instanceof LockableTileState, "Block state of lock-checked block is no longer a lockable tile state!");
+ return (LockableTileState) blockState;
@ -85,7 +85,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ *
+ * @return the player
+ */
+ public @NotNull Player getPlayer() {
+ public Player getPlayer() {
+ return this.player;
+ }
+
@ -98,7 +98,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ * @return the item being used as the key item
+ * @see #isUsingCustomKeyItemStack()
+ */
+ public @NotNull ItemStack getKeyItem() {
+ public ItemStack getKeyItem() {
+ return Objects.requireNonNullElseGet(this.itemStack, this.player.getInventory()::getItemInMainHand);
+ }
+
@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ * @param stack the stack to use as a key
+ * @see #resetKeyItem() to clear a custom key item
+ */
+ public void setKeyItem(@NotNull ItemStack stack) {
+ public void setKeyItem(final ItemStack stack) {
+ Preconditions.checkArgument(stack != null, "stack cannot be null");
+ this.itemStack = stack;
+ }
@ -135,7 +135,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ * @return the result
+ * @see #setResult(Result)
+ */
+ public @NotNull Result getResult() {
+ public Result getResult() {
+ return this.result;
+ }
+
@ -148,7 +148,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ *
+ * @param result the result of this event
+ */
+ public void setResult(@NotNull Result result) {
+ public void setResult(final Result result) {
+ this.result = result;
+ }
+
@ -157,9 +157,9 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ * the locked message and locked sound.
+ *
+ * @param lockedMessage the message to show if locked (or {@code null} for none)
+ * @param lockedSound the sound to play if locked (or {@code null} for none)
+ * @param lockedSound the sound to play if locked (or {@code null} for none)
+ */
+ public void denyWithMessageAndSound(@Nullable Component lockedMessage, @Nullable Sound lockedSound) {
+ public void denyWithMessageAndSound(final @Nullable Component lockedMessage, final @Nullable Sound lockedSound) {
+ this.result = Result.DENY;
+ this.lockedMessage = lockedMessage;
+ this.lockedSound = lockedSound;
@ -181,7 +181,7 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ *
+ * @param lockedMessage the locked message (or {@code null} for none)
+ */
+ public void setLockedMessage(@Nullable Component lockedMessage) {
+ public void setLockedMessage(final @Nullable Component lockedMessage) {
+ this.lockedMessage = lockedMessage;
+ }
+
@ -201,16 +201,16 @@ index 0000000000000000000000000000000000000000..5e2c8ad26dea2c8a84ae10f7da8cb836
+ *
+ * @param lockedSound the locked sound (or {@code null} for none)
+ */
+ public void setLockedSound(@Nullable Sound lockedSound) {
+ public void setLockedSound(final @Nullable Sound lockedSound) {
+ this.lockedSound = lockedSound;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NotNull HandlerList getHandlerList() {
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add EntityFertilizeEggEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityFertilizeEggEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityFertilizeEggEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9b87d7ae8
index 0000000000000000000000000000000000000000..a96c28678c5f6a52710ae287d3bbc25e180d058e
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityFertilizeEggEvent.java
@@ -0,0 +1,139 @@
@@ -0,0 +1,133 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.Material;
@ -21,8 +21,8 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+import org.bukkit.event.entity.EntityEvent;
+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 two entities mate and the mating process results in a fertilization.
@ -35,23 +35,24 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ * <li>Sniffers producing the {@link Material#SNIFFER_EGG} item, which needs to be placed before it can begin to hatch.</li>
+ * <li>A turtle being marked with "HasEgg" and laying a {@link Material#TURTLE_EGG} later.</li>
+ * </ul>
+ *
+ * <p>
+ * The event hence only exposes the two parent entities in the fertilization process and cannot provide the child entity, as it will only exist at a later point in time.
+ */
+@NullMarked
+public class EntityFertilizeEggEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final LivingEntity mother;
+ private final LivingEntity father;
+ private final Player breeder;
+ private final ItemStack bredWith;
+ private final @Nullable Player breeder;
+ private final @Nullable ItemStack bredWith;
+ private int experience;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityFertilizeEggEvent(@NotNull LivingEntity mother, @NotNull LivingEntity father, @Nullable Player breeder, @Nullable ItemStack bredWith, int experience) {
+ public EntityFertilizeEggEvent(final LivingEntity mother, final LivingEntity father, final @Nullable Player breeder, final @Nullable ItemStack bredWith, final int experience) {
+ super(mother);
+ this.mother = mother;
+ this.father = father;
@ -60,7 +61,6 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ this.experience = experience;
+ }
+
+ @NotNull
+ @Override
+ public LivingEntity getEntity() {
+ return (LivingEntity) super.getEntity();
@ -72,7 +72,6 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ *
+ * @return The "mother" entity.
+ */
+ @NotNull
+ public LivingEntity getMother() {
+ return this.mother;
+ }
@ -83,7 +82,6 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ *
+ * @return the other parent
+ */
+ @NotNull
+ public LivingEntity getFather() {
+ return this.father;
+ }
@ -94,8 +92,7 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ *
+ * @return The Entity who initiated fertilization.
+ */
+ @Nullable
+ public Player getBreeder() {
+ public @Nullable Player getBreeder() {
+ return this.breeder;
+ }
+
@ -104,8 +101,7 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ *
+ * @return ItemStack used to initiate fertilization.
+ */
+ @Nullable
+ public ItemStack getBredWith() {
+ public @Nullable ItemStack getBredWith() {
+ return this.bredWith;
+ }
+
@ -124,7 +120,7 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ *
+ * @param experience experience amount
+ */
+ public void setExperience(int experience) {
+ public void setExperience(final int experience) {
+ this.experience = experience;
+ }
+
@ -134,17 +130,15 @@ index 0000000000000000000000000000000000000000..35d54650c53bc64dd7c440240ad2f2b9
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add CompostItemEvent and EntityCompostItemEvent
diff --git a/src/main/java/io/papermc/paper/event/block/CompostItemEvent.java b/src/main/java/io/papermc/paper/event/block/CompostItemEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef43f45be9a
index 0000000000000000000000000000000000000000..03497ac2489b159716811f03ab68e345ff864fa6
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/CompostItemEvent.java
@@ -0,0 +1,67 @@
@@ -0,0 +1,66 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Block;
@ -18,12 +18,13 @@ index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef4
+import org.bukkit.event.inventory.InventoryMoveItemEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an item is about to be composted by a hopper.
+ * To prevent hoppers from moving items into composters, cancel the {@link InventoryMoveItemEvent}.
+ */
+@NullMarked
+public class CompostItemEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -32,7 +33,7 @@ index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef4
+ private boolean willRaiseLevel;
+
+ @ApiStatus.Internal
+ public CompostItemEvent(@NotNull Block composter, @NotNull ItemStack item, boolean willRaiseLevel) {
+ public CompostItemEvent(final Block composter, final ItemStack item, final boolean willRaiseLevel) {
+ super(composter);
+ this.item = item;
+ this.willRaiseLevel = willRaiseLevel;
@ -43,7 +44,6 @@ index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef4
+ *
+ * @return the item
+ */
+ @NotNull
+ public ItemStack getItem() {
+ return this.item;
+ }
@ -62,16 +62,15 @@ index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef4
+ *
+ * @param willRaiseLevel {@code true} if the composter should rise a level
+ */
+ public void setWillRaiseLevel(boolean willRaiseLevel) {
+ public void setWillRaiseLevel(final boolean willRaiseLevel) {
+ this.willRaiseLevel = willRaiseLevel;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
@ -79,7 +78,7 @@ index 0000000000000000000000000000000000000000..29f21c03cc063a279ca4ae0be00e9ef4
+}
diff --git a/src/main/java/io/papermc/paper/event/entity/EntityCompostItemEvent.java b/src/main/java/io/papermc/paper/event/entity/EntityCompostItemEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba8473ec936b1cea8b13b269283c377cb1b6da0b
index 0000000000000000000000000000000000000000..213d957fdc68aa32d77424c84c5cf3b244cd4314
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/EntityCompostItemEvent.java
@@ -0,0 +1,45 @@
@ -91,18 +90,19 @@ index 0000000000000000000000000000000000000000..ba8473ec936b1cea8b13b269283c377c
+import org.bukkit.event.Cancellable;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an item is about to be composted by an entity.
+ */
+@NullMarked
+public class EntityCompostItemEvent extends CompostItemEvent implements Cancellable {
+
+ private final Entity entity;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public EntityCompostItemEvent(@NotNull Entity entity, @NotNull Block composter, @NotNull ItemStack item, boolean willRaiseLevel) {
+ public EntityCompostItemEvent(final Entity entity, final Block composter, final ItemStack item, final boolean willRaiseLevel) {
+ super(composter, item, willRaiseLevel);
+ this.entity = entity;
+ }
@ -112,7 +112,6 @@ index 0000000000000000000000000000000000000000..ba8473ec936b1cea8b13b269283c377c
+ *
+ * @return the entity that composted an item.
+ */
+ @NotNull
+ public Entity getEntity() {
+ return this.entity;
+ }
@ -123,7 +122,7 @@ index 0000000000000000000000000000000000000000..ba8473ec936b1cea8b13b269283c377c
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add whitelist events
diff --git a/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73ccc8779f
index 0000000000000000000000000000000000000000..ff8c2c74fc68b1dd564e07c938b28b5950871533
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java
@@ -0,0 +1,87 @@
@@ -0,0 +1,83 @@
+package io.papermc.paper.event.server;
+
+import com.destroystokyo.paper.profile.PlayerProfile;
@ -19,22 +19,23 @@ index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * This event gets called when the whitelist status of a player is changed
+ */
+@NullMarked
+public class WhitelistStateUpdateEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @NotNull private final PlayerProfile playerProfile;
+ @NotNull private final WhitelistStatus status;
+ private final PlayerProfile playerProfile;
+ private final WhitelistStatus status;
+
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public WhitelistStateUpdateEvent(@NotNull PlayerProfile playerProfile, @NotNull WhitelistStatus status) {
+ public WhitelistStateUpdateEvent(final PlayerProfile playerProfile, final WhitelistStatus status) {
+ this.playerProfile = playerProfile;
+ this.status = status;
+ }
@ -44,7 +45,6 @@ index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73
+ *
+ * @return the player whose status is being changed
+ */
+ @NotNull
+ public OfflinePlayer getPlayer() {
+ return Bukkit.getOfflinePlayer(this.playerProfile.getId());
+ }
@ -54,7 +54,6 @@ index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73
+ *
+ * @return the player profile whose status is being changed
+ */
+ @NotNull
+ public PlayerProfile getPlayerProfile() {
+ return this.playerProfile;
+ }
@ -64,7 +63,6 @@ index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73
+ *
+ * @return the whitelist status
+ */
+ @NotNull
+ public WhitelistStatus getStatus() {
+ return this.status;
+ }
@ -75,17 +73,15 @@ index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add ShulkerDuplicateEvent
diff --git a/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4a59534e2
index 0000000000000000000000000000000000000000..d427a67a5c7e44aee78d21a7b344b8bb19235dc7
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java
@@ -0,0 +1,71 @@
@@ -0,0 +1,68 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.entity.Shulker;
@ -17,13 +17,14 @@ index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Fired when a shulker duplicates itself by spawning a new shulker.
+ * <p>
+ * The event is fired prior to the newly created shulker, accessible via {@link #getEntity()}, being added to the world.
+ */
+@NullMarked
+public class ShulkerDuplicateEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
@ -32,7 +33,7 @@ index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public ShulkerDuplicateEvent(@NotNull Shulker child, @NotNull Shulker parent) {
+ public ShulkerDuplicateEvent(final Shulker child, final Shulker parent) {
+ super(child);
+ this.parent = parent;
+ }
@ -44,7 +45,6 @@ index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4
+ * @return the newly duplicated shulker.
+ */
+ @Override
+ @NotNull
+ public Shulker getEntity() {
+ return (Shulker) super.getEntity();
+ }
@ -55,7 +55,6 @@ index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4
+ *
+ * @return the previously existing shulker which duplicated.
+ */
+ @NotNull
+ public Shulker getParent() {
+ return this.parent;
+ }
@ -66,17 +65,15 @@ index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4
+ }
+
+ @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;
+ }

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent
diff --git a/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b6dd93a09
index 0000000000000000000000000000000000000000..1820e9b12141f3798dac499e19f8337c6f89d671
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java
@@ -0,0 +1,56 @@
@@ -0,0 +1,57 @@
+package io.papermc.paper.event.block;
+
+import org.bukkit.block.Block;
@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.block.BlockEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Range;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when the progress of a block break is updated.
+ */
+@NullMarked
+public class BlockBreakProgressUpdateEvent extends BlockEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final float progress;
+ private final Entity entity;
+
+ @ApiStatus.Internal
+ public BlockBreakProgressUpdateEvent(@NotNull final Block block, final float progress, @NotNull final Entity entity) {
+ public BlockBreakProgressUpdateEvent(final Block block, final float progress, final Entity entity) {
+ super(block);
+ this.progress = progress;
+ this.entity = entity;
@ -45,7 +46,7 @@ index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b
+ * @return The progress of the block break
+ */
+ public float getProgress() {
+ return progress;
+ return this.progress;
+ }
+
+ /**
@ -53,16 +54,16 @@ index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b
+ *
+ * @return The entity breaking the block
+ */
+ @NotNull
+ public Entity getEntity() {
+ return entity;
+ return this.entity;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+ public static @NotNull HandlerList getHandlerList() {
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Brigadier based command API
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/build.gradle.kts b/build.gradle.kts
index 4da053d427f3f9c5e7fc144408836ebef80026c6..540fe7e2c110e79c3742f229b3ed8c54b101d260 100644
index 37ff4cb89dfb28eab6f836840ff1838d67895c1e..2074c9aee1affbce57571398f8519f0d425cf5e3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -27,6 +27,7 @@ configurations.api {
@ -17,7 +17,7 @@ index 4da053d427f3f9c5e7fc144408836ebef80026c6..540fe7e2c110e79c3742f229b3ed8c54
// api dependencies are listed transitively to API consumers
api("com.google.guava:guava:32.1.2-jre")
api("com.google.code.gson:gson:2.10.1")
@@ -92,9 +93,29 @@ sourceSets {
@@ -93,9 +94,29 @@ sourceSets {
}
}
// Paper end
@ -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..ba5472a068075f8f7fb5b9bce05e783ca9b4ffdf
index 0000000000000000000000000000000000000000..18e0618901eb6eec7677661b8448cb95926ee3ab
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java
@@ -0,0 +1,73 @@
@@ -0,0 +1,72 @@
+package com.destroystokyo.paper.event.brigadier;
+
+import com.mojang.brigadier.tree.RootCommandNode;
@ -115,7 +115,7 @@ index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783c
+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 any time a Brigadier RootCommandNode is generated for a player to inform the client of commands.
@ -138,6 +138,7 @@ index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783c
+ * <p>This is a draft/experimental API and is subject to change.</p>
+ */
+@ApiStatus.Experimental
+@NullMarked
+public class AsyncPlayerSendCommandsEvent<S extends CommandSourceStack> extends PlayerEvent {
+
+ private static final HandlerList handlers = new HandlerList();
@ -145,7 +146,7 @@ index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783c
+ private final boolean hasFiredAsync;
+
+ @ApiStatus.Internal
+ public AsyncPlayerSendCommandsEvent(@NotNull Player player, @NotNull RootCommandNode<S> node, boolean hasFiredAsync) {
+ public AsyncPlayerSendCommandsEvent(final Player player, final RootCommandNode<S> node, final boolean hasFiredAsync) {
+ super(player, !Bukkit.isPrimaryThread());
+ this.node = node;
+ this.hasFiredAsync = hasFiredAsync;
@ -156,8 +157,8 @@ index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783c
+ *
+ * @return the root command node
+ */
+ public @NotNull RootCommandNode<S> getCommandNode() {
+ return node;
+ public RootCommandNode<S> getCommandNode() {
+ return this.node;
+ }
+
+ /**
@ -166,25 +167,23 @@ index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783c
+ * @return whether this event has already fired asynchronously
+ */
+ public boolean hasFiredAsync() {
+ return hasFiredAsync;
+ return this.hasFiredAsync;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
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..6ac205de582983863bd5b3c0fa70d4375dd751c5
index 0000000000000000000000000000000000000000..f2ed3af699c2df92227693830c135d0b4718d41f
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java
@@ -0,0 +1,85 @@
@@ -0,0 +1,84 @@
+package com.destroystokyo.paper.event.brigadier;
+
+import com.mojang.brigadier.suggestion.Suggestions;
@ -194,13 +193,14 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+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 sending {@link Suggestions} to the client. Will be called asynchronously if a plugin
+ * marks the {@link com.destroystokyo.paper.event.server.AsyncTabCompleteEvent} event handled asynchronously,
+ * otherwise called synchronously.
+ */
+@NullMarked
+public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
@ -210,7 +210,7 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+ private final String buffer;
+
+ @ApiStatus.Internal
+ public AsyncPlayerSendSuggestionsEvent(@NotNull Player player, @NotNull Suggestions suggestions, @NotNull String buffer) {
+ public AsyncPlayerSendSuggestionsEvent(final Player player, final Suggestions suggestions, final String buffer) {
+ super(player, !Bukkit.isPrimaryThread());
+ this.suggestions = suggestions;
+ this.buffer = buffer;
@ -221,8 +221,8 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+ *
+ * @return the input buffer
+ */
+ public @NotNull String getBuffer() {
+ return buffer;
+ public String getBuffer() {
+ return this.buffer;
+ }
+
+ /**
@ -230,8 +230,8 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+ *
+ * @return the suggestions
+ */
+ public @NotNull Suggestions getSuggestions() {
+ return suggestions;
+ public Suggestions getSuggestions() {
+ return this.suggestions;
+ }
+
+ /**
@ -239,7 +239,7 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+ *
+ * @param suggestions suggestions
+ */
+ public void setSuggestions(@NotNull Suggestions suggestions) {
+ public void setSuggestions(final Suggestions suggestions) {
+ this.suggestions = suggestions;
+ }
+
@ -256,16 +256,14 @@ index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d437
+ * {@inheritDoc}
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }