From 1ebb4c1e79266e322cb0139fcef5d3509ba10297 Mon Sep 17 00:00:00 2001 From: Lexi Date: Thu, 21 Apr 2022 21:04:03 -0400 Subject: [PATCH] Overhaul SoundEvent --- patches/api/0003-Add-SoundEvent.patch | 548 +++++++++++++----- patches/server/0003-Add-SoundEvent.patch | 113 ++-- ...location-to-EntityDamageByBlockEvent.patch | 8 +- .../0011-Add-BlockDropResourcesEvent.patch | 8 +- 4 files changed, 451 insertions(+), 226 deletions(-) diff --git a/patches/api/0003-Add-SoundEvent.patch b/patches/api/0003-Add-SoundEvent.patch index 188017f..ee90024 100644 --- a/patches/api/0003-Add-SoundEvent.patch +++ b/patches/api/0003-Add-SoundEvent.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add SoundEvent diff --git a/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0f8f4f122 +index 0000000000000000000000000000000000000000..19c9f7af91402d5f966915ebc80d76ab9ac92872 --- /dev/null +++ b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,67 @@ +package me.lexikiq.event.sound; + +import org.apache.commons.lang.Validate; @@ -18,9 +18,15 @@ index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0 +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; ++import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + ++import java.util.List; ++import java.util.Objects; ++import java.util.function.Function; ++ +/** + * Called when an entity sound is sent to a player. + * Cancelling this event will prevent the packet from sending. @@ -28,46 +34,55 @@ index 0000000000000000000000000000000000000000..74109b772f3d38fdd58721ec1e491ff0 + * This type of sound represents one that will follow the {@link #getOrigin() originating} entity. + */ +public class EntitySoundEvent extends NamedSoundEvent { -+ private @NotNull Entity origin; ++ private @NotNull Entity origin; + -+ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { -+ super(except, sound, category, volume, pitch); -+ Validate.notNull(origin, "origin cannot be null"); -+ this.origin = origin; -+ } ++ @Deprecated ++ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { ++ this(except, origin, sound, category, volume, pitch, null, null); ++ } + -+ /** -+ * Gets the entity that the sound is originating from. ++ public EntitySoundEvent(@Nullable HumanEntity except, @NotNull Entity origin, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function distanceFunction, @Nullable Function> recipientsFunction) { ++ super(except, sound, category, volume, pitch, distanceFunction, recipientsFunction); ++ this.origin = Objects.requireNonNull(origin, "origin cannot be null"); ++ } ++ ++ /** ++ * Gets the entity that the sound is originating from. + * -+ * @return originating entity -+ */ -+ public @NotNull Entity getOrigin() { -+ return origin; -+ } ++ * @return originating entity ++ */ ++ public @NotNull Entity getOrigin() { ++ return origin; ++ } + -+ /** -+ * Sets the entity that the sound will originate from. ++ /** ++ * Sets the entity that the sound will originate from. + * -+ * @param origin originating entity -+ */ -+ public void setOrigin(@NotNull Entity origin) { -+ Validate.notNull(origin, "origin cannot be null"); -+ if (!this.origin.getWorld().equals(origin.getWorld())) -+ throw new IllegalArgumentException("Entity must be in same world as originating location"); -+ this.origin = origin; -+ } ++ * @param origin originating entity ++ */ ++ public void setOrigin(@NotNull Entity origin) { ++ Validate.notNull(origin, "origin cannot be null"); ++ if (!this.origin.getWorld().equals(origin.getWorld())) ++ throw new IllegalArgumentException("Entity must be in same world as originating location"); ++ this.origin = origin; ++ } + + @Override + public @NotNull World getWorld() { + return origin.getWorld(); + } ++ ++ @Override ++ public @NotNull Vector getPosition() { ++ return origin.getLocation().toVector(); ++ } +} diff --git a/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0dce9bcdd +index 0000000000000000000000000000000000000000..9d7f3656c55a0bb7a8258a0418954563f8730551 --- /dev/null +++ b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java -@@ -0,0 +1,126 @@ +@@ -0,0 +1,139 @@ +package me.lexikiq.event.sound; + +import me.lexikiq.HasLocation; @@ -78,10 +93,16 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0 +import org.bukkit.SoundCategory; +import org.bukkit.World; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + ++import java.util.List; ++import java.util.Objects; ++import java.util.function.Function; ++ +import static com.google.common.base.Preconditions.checkNotNull; + +/** @@ -89,57 +110,80 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0 + * {@link Location}. Cancelling this event will prevent the packet from sending. + */ +public class LocationCustomSoundEvent extends SoundEvent implements Keyed, HasLocation { -+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList(); -+ private @NotNull -+ final World world; ++ private @NotNull World world; + private @NotNull Vector vector; + private @NotNull NamespacedKey key; -+ private boolean cancelled; + -+ public LocationCustomSoundEvent(@Nullable HumanEntity except, @NotNull World world, @NotNull Vector vector, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) { -+ super(except, category, volume, pitch); -+ Validate.notNull(world, "world cannot be null"); -+ Validate.notNull(vector, "vector cannot be null"); -+ Validate.notNull(key, "key cannot be null"); -+ this.world = world; -+ this.vector = vector; -+ this.key = key; ++ @Deprecated ++ public LocationCustomSoundEvent(@Nullable HumanEntity except, ++ @NotNull World world, ++ @NotNull Vector vector, ++ @NotNull NamespacedKey key, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch) { ++ this(except, world, vector, key, category, volume, pitch, null, null); + } + -+ public LocationCustomSoundEvent(@Nullable HumanEntity except, @NotNull Location location, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) { -+ this(except, checkNotNull(location, "location").getWorld(), location.toVector(), key, category, volume, pitch); ++ @Deprecated ++ public LocationCustomSoundEvent(@Nullable HumanEntity except, ++ @NotNull Location location, ++ @NotNull NamespacedKey key, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch) { ++ this(except, location, key, category, volume, pitch, null, null); + } + -+ public LocationCustomSoundEvent(@NotNull HumanEntity except, @NotNull Vector vector, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) { -+ this(checkNotNull(except, "except"), except.getWorld(), vector, key, category, volume, pitch); ++ public LocationCustomSoundEvent(@Nullable HumanEntity except, ++ @NotNull World world, ++ @NotNull Vector vector, ++ @NotNull NamespacedKey key, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch, ++ @Nullable Function distanceFunction, ++ @Nullable Function> recipientsFunction) { ++ super(except, category, volume, pitch, distanceFunction, recipientsFunction); ++ this.world = Objects.requireNonNull(world, "world cannot be null"); ++ this.vector = Objects.requireNonNull(vector, "vector cannot be null"); ++ this.key = Objects.requireNonNull(key, "key cannot be null"); + } + -+ public LocationCustomSoundEvent(@NotNull HumanEntity except, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) { -+ this(checkNotNull(except, "except"), except.getLocation().toVector(), key, category, volume, pitch); ++ public LocationCustomSoundEvent(@Nullable HumanEntity except, ++ @NotNull Location location, ++ @NotNull NamespacedKey key, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch, ++ @Nullable Function distanceFunction, ++ @Nullable Function> recipientsFunction) { ++ this(except, checkNotNull(location, "location").getWorld(), location.toVector(), key, category, volume, pitch, distanceFunction, recipientsFunction); + } + -+ @NotNull -+ public static org.bukkit.event.HandlerList getHandlerList() { -+ return handlers; -+ } -+ -+ /** -+ * Gets the position of the sound. -+ * -+ * @return position in the world -+ */ -+ public @NotNull Vector getVector() { ++ @Override ++ public @NotNull Vector getPosition() { + return vector; + } + + /** + * Sets the position of the sound. + * -+ * @param vector position in the world ++ * @param position position in the world + */ ++ public void setPosition(@NotNull Vector position) { ++ this.vector = Objects.requireNonNull(position, "position cannot be null"); ++ } ++ ++ /** ++ * Sets the position of the sound. ++ * ++ * @param vector position in the world ++ * @deprecated use {@link #setPosition(Vector)} instead ++ */ ++ @Deprecated + public void setVector(@NotNull Vector vector) { -+ Validate.notNull(vector, "vector cannot be null"); -+ this.vector = vector; ++ setPosition(vector); + } + + /** @@ -159,8 +203,7 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0 + * @param key asset key + */ + public void setKey(@NotNull NamespacedKey key) { -+ Validate.notNull(key, "key cannot be null"); -+ this.key = key; ++ this.key = Objects.requireNonNull(key, "key cannot be null"); + } + + @Override @@ -169,96 +212,116 @@ index 0000000000000000000000000000000000000000..6a8d2e64a1a69b4dfeaab63fa93a32d0 + } + + /** -+ * Gets the location of the sound being played. ++ * Sets the world in which the sound is played. ++ *

++ * This may not have an effect if the {@link #getRecipientsFunction()} has been modified. + * -+ * @return copy of sound location -+ * @see #getVector() -+ * @see #setVector(Vector) ++ * @param world world to play the sound in + */ -+ public @NotNull Location getLocation() { -+ return new Location(world, vector.getX(), vector.getY(), vector.getZ()); -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancelled) { -+ this.cancelled = cancelled; -+ } -+ -+ @Override -+ public @NotNull org.bukkit.event.HandlerList getHandlers() { -+ return handlers; ++ public void setWorld(@NotNull World world) { ++ this.world = Objects.requireNonNull(world, "world cannot be null"); + } +} diff --git a/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..013472f40edbfea49785d48cc0f7ad7c5b69fe58 +index 0000000000000000000000000000000000000000..7f42c904362107c55cc5877eab1b513bcdf34571 --- /dev/null +++ b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java -@@ -0,0 +1,77 @@ +@@ -0,0 +1,112 @@ +package me.lexikiq.event.sound; + +import me.lexikiq.HasLocation; -+import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.World; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + -+import static com.google.common.base.Preconditions.checkNotNull; ++import java.util.List; ++import java.util.Objects; ++import java.util.function.Function; + +/** + * Called when a sound available in {@link Sound} is sent to a {@link Location}. + * Cancelling this event will prevent the packet from sending. + */ +public class LocationNamedSoundEvent extends NamedSoundEvent implements HasLocation { -+ private @NotNull -+ final World world; ++ private @NotNull World world; + private @NotNull Vector vector; + -+ public LocationNamedSoundEvent(@Nullable HumanEntity receiver, @NotNull World world, @NotNull Vector vector, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { -+ super(receiver, sound, category, volume, pitch); -+ this.world = checkNotNull(world, "world"); -+ this.vector = checkNotNull(vector, "vector"); ++ @Deprecated ++ public LocationNamedSoundEvent(@Nullable HumanEntity except, ++ @NotNull World world, ++ @NotNull Vector vector, ++ @NotNull Sound sound, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch) { ++ this(except, world, vector, sound, category, volume, pitch, null, null); + } + -+ public LocationNamedSoundEvent(@Nullable HumanEntity receiver, @NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { -+ this(receiver, checkNotNull(location, "location").getWorld(), location.toVector(), sound, category, volume, pitch); ++ @Deprecated ++ public LocationNamedSoundEvent(@Nullable HumanEntity except, ++ @NotNull Location location, ++ @NotNull Sound sound, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch) { ++ this(except, location, sound, category, volume, pitch, null, null); + } + -+ public LocationNamedSoundEvent(@NotNull HumanEntity receiver, @NotNull Vector vector, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { -+ this(checkNotNull(receiver, "receiver"), receiver.getWorld(), vector, sound, category, volume, pitch); ++ public LocationNamedSoundEvent(@Nullable HumanEntity except, ++ @NotNull World world, ++ @NotNull Vector vector, ++ @NotNull Sound sound, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch, ++ @Nullable Function distanceFunction, ++ @Nullable Function> recipientsFunction) { ++ super(except, sound, category, volume, pitch, distanceFunction, recipientsFunction); ++ this.world = Objects.requireNonNull(world, "world cannot be null"); ++ this.vector = Objects.requireNonNull(vector, "vector cannot be null"); + } + -+ public LocationNamedSoundEvent(@NotNull HumanEntity receiver, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { -+ this(checkNotNull(receiver, "receiver"), receiver.getLocation().toVector(), sound, category, volume, pitch); ++ public LocationNamedSoundEvent(@Nullable HumanEntity except, ++ @NotNull Location location, ++ @NotNull Sound sound, ++ @NotNull SoundCategory category, ++ float volume, ++ float pitch, ++ @Nullable Function distanceFunction, ++ @Nullable Function> recipientsFunction) { ++ this(except, Objects.requireNonNull(location, "location cannot be null").getWorld(), location.toVector(), sound, category, volume, pitch, distanceFunction, recipientsFunction); + } + -+ /** -+ * Gets the position of the sound. -+ * -+ * @return position in the world -+ */ -+ public @NotNull Vector getVector() { ++ @Override ++ public @NotNull Vector getPosition() { + return vector; + } + + /** + * Sets the position of the sound. + * -+ * @param vector position in the world ++ * @param position position in the world + */ ++ public void setPosition(@NotNull Vector position) { ++ this.vector = Objects.requireNonNull(position, "position cannot be null"); ++ } ++ ++ /** ++ * Sets the position of the sound. ++ * ++ * @param vector position in the world ++ * @deprecated use {@link #setPosition(Vector)} instead ++ */ ++ @Deprecated + public void setVector(@NotNull Vector vector) { -+ Validate.notNull(vector, "vector cannot be null"); -+ this.vector = vector; ++ setPosition(vector); + } + + @Override @@ -267,53 +330,58 @@ index 0000000000000000000000000000000000000000..013472f40edbfea49785d48cc0f7ad7c + } + + /** -+ * Gets the location of the sound being played. ++ * Sets the world in which the sound is played. ++ *

++ * This may not have an effect if the {@link #getRecipientsFunction()} has been modified. + * -+ * @return copy of sound location -+ * @see #getVector() -+ * @see #setVector(Vector) ++ * @param world world to play the sound in + */ -+ public @NotNull Location getLocation() { -+ return new Location(world, vector.getX(), vector.getY(), vector.getZ()); ++ public void setWorld(@NotNull World world) { ++ this.world = Objects.requireNonNull(world, "world cannot be null"); + } +} diff --git a/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..9256d75f5bb9ed8f42a7ff0613433bb1b7e37769 +index 0000000000000000000000000000000000000000..3ca767cfeb7fc0982830e49cde6bb0e87075c3f9 --- /dev/null +++ b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java -@@ -0,0 +1,65 @@ +@@ -0,0 +1,54 @@ +package me.lexikiq.event.sound; + +import org.apache.commons.lang.Validate; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + ++import java.util.List; ++import java.util.Objects; ++import java.util.function.Function; ++ +/** + * Called when a sound available in {@link Sound} is sent to a player. + * Cancelling this event will prevent the packet from sending. + */ +public abstract class NamedSoundEvent extends SoundEvent { -+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList(); + private @NotNull Sound sound; -+ private boolean cancelled; + -+ public NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { ++ ++ @Deprecated ++ protected NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { + super(except, category, volume, pitch); -+ Validate.notNull(sound, "sound cannot be null"); -+ this.sound = sound; ++ this.sound = Objects.requireNonNull(sound, "sound cannot be null"); ++ } ++ ++ public NamedSoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function distanceFunction, @Nullable Function> recipientsFunction) { ++ super(except, category, volume, pitch, distanceFunction, recipientsFunction); ++ this.sound = Objects.requireNonNull(sound, "sound cannot be null"); + } + + // boilerplate + -+ @NotNull -+ public static org.bukkit.event.HandlerList getHandlerList() { -+ return handlers; -+ } -+ + /** + * Gets the sound being played. + * @@ -329,60 +397,80 @@ index 0000000000000000000000000000000000000000..9256d75f5bb9ed8f42a7ff0613433bb1 + * @param sound sound to play + */ + public void setSound(@NotNull Sound sound) { -+ Validate.notNull(sound, "sound cannot be null"); -+ this.sound = sound; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancelled) { -+ this.cancelled = cancelled; -+ } -+ -+ @Override -+ public @NotNull org.bukkit.event.HandlerList getHandlers() { -+ return handlers; ++ this.sound = Objects.requireNonNull(sound, "sound cannot be null"); + } +} diff --git a/src/main/java/me/lexikiq/event/sound/SoundEvent.java b/src/main/java/me/lexikiq/event/sound/SoundEvent.java new file mode 100644 -index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc94aeae3ec +index 0000000000000000000000000000000000000000..6cc614b9e1b187f43433d13624d74672c97c2174 --- /dev/null +++ b/src/main/java/me/lexikiq/event/sound/SoundEvent.java -@@ -0,0 +1,117 @@ +@@ -0,0 +1,313 @@ +package me.lexikiq.event.sound; + +import me.lexikiq.OptionalHumanEntity; +import org.apache.commons.lang.Validate; ++import org.bukkit.Location; +import org.bukkit.SoundCategory; +import org.bukkit.World; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; ++import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + ++import java.util.ArrayList; ++import java.util.List; ++import java.util.Objects; ++import java.util.function.Function; ++ +/** + * Called when a sound is sent to a player. + * Cancelling this event will prevent the packet from sending. + */ ++// TODO 1.18: use sealed class +public abstract class SoundEvent extends Event implements Cancellable, OptionalHumanEntity { -+ private @Nullable final HumanEntity except; ++ ++ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList(); ++ public static final @NotNull Function DEFAULT_DISTANCE_FUNCTION = event -> event.getVolume() > 1.0F ? (double) (16.0F * event.getVolume()) : 16.0D; ++ public static final @NotNull Function> DEFAULT_RECIPIENTS_FUNCTION = new WrappedRecipientsFunction(event -> { ++ final double distance = event.calculateDistance(); ++ return event.getWorld().getPlayers().stream() ++ .filter(player -> { ++ Location pl = player.getLocation(); ++ Vector sv = event.getPosition(); ++ double x = sv.getX() - pl.getX(); ++ double y = sv.getY() - pl.getY(); ++ double z = sv.getZ() - pl.getZ(); ++ return x * x + y * y + z * z < distance * distance; ++ }) ++ .toList(); ++ }); ++ ++ private @Nullable HumanEntity except; ++ private @NotNull Function<@NotNull SoundEvent, @NotNull Double> distanceFunction; ++ private @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction; ++ // + private @NotNull SoundCategory category; + private float volume; + private float pitch; ++ private boolean cancelled; + -+ public SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch) { ++ @Deprecated ++ protected SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch) { ++ this(except, category, volume, pitch, null, null); ++ } ++ ++ protected SoundEvent(@Nullable HumanEntity except, @NotNull SoundCategory category, float volume, float pitch, @Nullable Function distanceFunction, @Nullable Function> recipientsFunction) { + super(true); -+ Validate.notNull(category, "category cannot be null"); + this.except = except; -+ this.category = category; ++ this.category = Objects.requireNonNull(category, "category cannot be null"); + this.volume = volume; + this.pitch = pitch; ++ this.distanceFunction = Objects.requireNonNullElse(distanceFunction, DEFAULT_DISTANCE_FUNCTION); ++ this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNullElse(recipientsFunction, DEFAULT_RECIPIENTS_FUNCTION)); + } + + /** @@ -407,6 +495,15 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9 + } + + /** ++ * Sets the player that won't be receiving this sound. ++ * ++ * @param except player excluded from receiving this sound ++ */ ++ public void setException(@Nullable HumanEntity except) { ++ this.except = except; ++ } ++ ++ /** + * Gets the category of sounds this will be played with. + * + * @return category of sounds @@ -421,8 +518,7 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9 + * @param category category of sounds + */ + public void setCategory(@NotNull SoundCategory category) { -+ Validate.notNull(category, "category cannot be null"); -+ this.category = category; ++ this.category = Objects.requireNonNull(category, "category cannot be null"); + } + + /** @@ -464,10 +560,162 @@ index 0000000000000000000000000000000000000000..48dac37d64561a890baca8d9fbd1bcc9 + } + + /** ++ * Calculates the distance of the sound. ++ *

++ * The distance value is dynamically calculated using a ++ * {@link Function Function<SoundEvent, Double>}. ++ * In vanilla Minecraft, the default function is {@link #DEFAULT_DISTANCE_FUNCTION} ++ * ({@code event -> event.getVolume() > 1.0F ? (double) (16.0F * event.getVolume()) : 16.0D}). ++ *

++ * This is used by the vanilla implementation of {@link #calculateRecipients()}, though custom ++ * implementations won't always use this method. ++ * ++ * @return calculated distance ++ * @see #getDistanceFunction() ++ * @see #setDistanceFunction(Function) ++ */ ++ public double calculateDistance() { ++ return distanceFunction.apply(this); ++ } ++ ++ /** ++ * Gets the function that calculates the distance of the sound. ++ * ++ * @return distance function ++ * @see #calculateDistance() ++ * @see #setDistanceFunction(Function) ++ */ ++ public @NotNull Function<@NotNull SoundEvent, @NotNull Double> getDistanceFunction() { ++ return distanceFunction; ++ } ++ ++ /** ++ * Sets the function that calculates the distance of the sound. ++ * ++ * @param distanceFunction distance function ++ * @see #calculateDistance() ++ * @see #getDistanceFunction() ++ */ ++ public void setDistanceFunction(@NotNull Function<@NotNull SoundEvent, @NotNull Double> distanceFunction) { ++ this.distanceFunction = Objects.requireNonNull(distanceFunction, "distanceFunction cannot be null"); ++ } ++ ++ /** ++ * Determines which players will receive this sound packet. ++ * ++ * @return immutable list of players ++ * @see #getRecipientsFunction() ++ * @see #setRecipientsFunction(Function) ++ */ ++ public @NotNull List calculateRecipients() { ++ return recipientsFunction.apply(this); ++ } ++ ++ /** ++ * Gets the function that determines which players will receive the sound packet. ++ * ++ * @return recipients function ++ * @see #calculateRecipients() ++ * @see #setRecipientsFunction(Function) ++ */ ++ public @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> getRecipientsFunction() { ++ return recipientsFunction; ++ } ++ ++ /** ++ * Sets the function that determines which players will receive the sound packet. ++ *

++ * This function does not need to query {@link #getException()} as this is done automatically. ++ * ++ * @param recipientsFunction recipients function ++ * @see #calculateRecipients() ++ * @see #getRecipientsFunction() ++ */ ++ public void setRecipientsFunction(@NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction) { ++ this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNull(recipientsFunction, "recipientsFunction cannot be null")); ++ } ++ ++ /** + * Gets the world in which the sound is being played. + * + * @return sound's world + */ + @NotNull + public abstract World getWorld(); ++ ++ /** ++ * Gets the position at which the sound is being played. ++ * ++ * @return sound's position ++ */ ++ @NotNull ++ public abstract Vector getPosition(); ++ ++ /** ++ * Gets the position at which the sound is being played. ++ * ++ * @return sound's position ++ * @deprecated use {@link #getPosition()} instead for clarity ++ */ ++ @Deprecated ++ @NotNull ++ public Vector getVector() { ++ return getPosition(); ++ } ++ ++ /** ++ * Gets the location of the sound being played. ++ * ++ * @return copy of sound location ++ * @see #getPosition() ++ */ ++ public @NotNull Location getLocation() { ++ Vector pos = getPosition(); ++ return new Location(getWorld(), pos.getX(), pos.getY(), pos.getZ()); ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancelled) { ++ this.cancelled = cancelled; ++ } ++ ++ @NotNull ++ public static org.bukkit.event.HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++ @Override ++ public @NotNull org.bukkit.event.HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ private record WrappedRecipientsFunction(@NotNull Function> wrapped) implements Function> { ++ @Override ++ public List apply(SoundEvent event) { ++ List recipients = wrapped.apply(event); ++ HumanEntity except = event.getException(); ++ if (except != null) { ++ List filteredRecipients = new ArrayList<>(recipients.size()); ++ for (Player player : recipients) { ++ if (!player.getUniqueId().equals(except.getUniqueId())) ++ filteredRecipients.add(player); ++ } ++ return filteredRecipients; ++ } ++ return recipients; ++ } ++ } ++ ++ @NotNull ++ private static Function> wrapRecipientsFunction(@NotNull Function> recipientsFunction) { ++ if (recipientsFunction instanceof WrappedRecipientsFunction) ++ return recipientsFunction; ++ else ++ return new WrappedRecipientsFunction(recipientsFunction); ++ } +} diff --git a/patches/server/0003-Add-SoundEvent.patch b/patches/server/0003-Add-SoundEvent.patch index dccfa18..eda96f3 100644 --- a/patches/server/0003-Add-SoundEvent.patch +++ b/patches/server/0003-Add-SoundEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add SoundEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a002713686e66faf0d18662586a7a236c27ca7d2..757dafc3150e52c5876679d8d121a69d6cd45b4e 100644 +index a002713686e66faf0d18662586a7a236c27ca7d2..14fc9abcba864620148dcdab921a5d95f98a9391 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1495,12 +1495,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -13,26 +13,32 @@ index a002713686e66faf0d18662586a7a236c27ca7d2..757dafc3150e52c5876679d8d121a69d @Override public void playSound(@Nullable Player except, double x, double y, double z, SoundEvent sound, SoundSource category, float volume, float pitch) { - this.server.getPlayerList().broadcast(except, x, y, z, volume > 1.0F ? (double) (16.0F * volume) : 16.0D, this.dimension(), new ClientboundSoundPacket(sound, category, x, y, z, volume, pitch)); -+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(except == null ? null : except.getBukkitEntity(), getWorld(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this.server, volume > 1.0F ? (double) (16.0F * volume) : 16.0D); // Parchment ++ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(except == null ? null : except.getBukkitEntity(), getWorld(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch, null, null)); // Parchment } @Override public void playSound(@Nullable Player except, Entity entity, SoundEvent sound, SoundSource category, float volume, float pitch) { - this.server.getPlayerList().broadcast(except, entity.getX(), entity.getY(), entity.getZ(), volume > 1.0F ? (double) (16.0F * volume) : 16.0D, this.dimension(), new ClientboundSoundEntityPacket(sound, category, entity, volume, pitch)); -+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.EntitySoundEvent(except == null ? null : except.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this.server, volume > 1.0F ? (double) (16.0F * volume) : 16.0D); // Parchment ++ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.EntitySoundEvent(except == null ? null : except.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(sound), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch, null, null)); // Parchment } @Override diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 78fda0c982810b8b881a87099f355247566e513a..24f59eb2899692302f5c5e39d96d0c5ed224a904 100644 +index 78fda0c982810b8b881a87099f355247566e513a..1ec20f19c8d6a606f608e0293eaf5f8f764b3b92 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2174,7 +2174,7 @@ public class ServerPlayer extends Player { +@@ -2174,7 +2174,13 @@ public class ServerPlayer extends Player { @Override public void playNotifySound(SoundEvent event, SoundSource category, float volume, float pitch) { - this.connection.send(new ClientboundSoundPacket(event, category, this.getX(), this.getY(), this.getZ(), volume, pitch)); -+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(event), org.bukkit.SoundCategory.valueOf(category.name()), volume, pitch), this); // Parchment ++ // Parchment start ++ List recipients = java.util.Collections.singletonList(getBukkitEntity()); ++ org.bukkit.Location location = getBukkitEntity().getLocation(); ++ org.bukkit.Sound sound = org.bukkit.craftbukkit.CraftSound.getBukkit(event); ++ org.bukkit.SoundCategory bukkitCategory = org.bukkit.SoundCategory.valueOf(category.name()); ++ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(null, location, sound, bukkitCategory, volume, pitch, $ -> 0d, $ -> recipients)); ++ // Parchment end } @Override @@ -50,15 +56,22 @@ index 46e6e68f78d07c04cd2f4d477dca7a06313c20e9..f7d9316645ba94089a867c6348caaf77 } // Added from changeDimension diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 94e76e295dbd0f3bac4b30a3e7338cd56a971207..4f55f1bd49137b60957a05faad0e0c2a9dec07dc 100644 +index 94e76e295dbd0f3bac4b30a3e7338cd56a971207..e951db59902fafa41832f73bab4086b63fe76f46 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1832,7 +1832,7 @@ public abstract class Player extends LivingEntity { +@@ -1832,7 +1832,14 @@ public abstract class Player extends LivingEntity { private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { fromEntity.level.playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself if (fromEntity instanceof ServerPlayer) { - ((ServerPlayer) fromEntity).connection.send(new ClientboundSoundPacket(soundEffect, soundCategory, x, y, z, volume, pitch)); -+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(fromEntity.getBukkitEntity(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect), org.bukkit.SoundCategory.valueOf(soundCategory.name()), volume, pitch), (ServerPlayer) fromEntity); // Parchment ++ // Parchment start ++ List recipients = java.util.Collections.singletonList(((net.minecraft.server.level.ServerPlayer) fromEntity).getBukkitEntity()); ++ org.bukkit.World world = fromEntity.level.getWorld(); ++ org.bukkit.util.Vector vector = new org.bukkit.util.Vector(x, y, z); ++ org.bukkit.Sound sound = org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect); ++ org.bukkit.SoundCategory category = org.bukkit.SoundCategory.valueOf(soundCategory.name()); ++ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(null, world, vector, sound, category, volume, pitch, event -> 0d, event -> recipients)); ++ // Parchment end } } // Paper end @@ -85,10 +98,10 @@ index a79ba23ecf887ecbb6e095140f019ebb6fd0a6f7..5112edc5e68a386e9bb16ac0ec9d998e } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index ea01507f96d81c6fbcfeb65902017bbc332de650..8e8b520ba2c8359bcf846e1977c1793122565d01 100644 +index ea01507f96d81c6fbcfeb65902017bbc332de650..b774a27eb4d11cd1bef807193a6df6012dde3794 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1888,4 +1888,77 @@ public class CraftEventFactory { +@@ -1888,4 +1888,41 @@ public class CraftEventFactory { return event.callEvent(); } // Paper end @@ -97,72 +110,36 @@ index ea01507f96d81c6fbcfeb65902017bbc332de650..8e8b520ba2c8359bcf846e1977c17931 + private static net.minecraft.network.protocol.Packet handleSoundEvent(me.lexikiq.event.sound.SoundEvent _event) { + if (!_event.callEvent()) { + return null; -+ } else { -+ float volume = _event.getVolume(); -+ float pitch = _event.getPitch(); -+ net.minecraft.sounds.SoundSource source = net.minecraft.sounds.SoundSource.valueOf(_event.getCategory().name()); ++ } ++ float volume = _event.getVolume(); ++ float pitch = _event.getPitch(); ++ net.minecraft.sounds.SoundSource source = net.minecraft.sounds.SoundSource.valueOf(_event.getCategory().name()); + -+ if (_event instanceof me.lexikiq.event.sound.NamedSoundEvent namedSoundEvent) { -+ net.minecraft.sounds.SoundEvent sound = org.bukkit.craftbukkit.CraftSound.getSoundEffect(namedSoundEvent.getSound()); ++ if (_event instanceof me.lexikiq.event.sound.NamedSoundEvent namedSoundEvent) { ++ net.minecraft.sounds.SoundEvent sound = org.bukkit.craftbukkit.CraftSound.getSoundEffect(namedSoundEvent.getSound()); + -+ if (_event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent event) { -+ org.bukkit.util.Vector pos = event.getVector(); -+ return new net.minecraft.network.protocol.game.ClientboundSoundPacket(sound, source, pos.getX(), pos.getY(), pos.getZ(), volume, pitch); -+ } else { -+ me.lexikiq.event.sound.EntitySoundEvent event = (me.lexikiq.event.sound.EntitySoundEvent) _event; -+ return new net.minecraft.network.protocol.game.ClientboundSoundEntityPacket(sound, source, ((CraftEntity) event.getOrigin()).getHandle(), volume, pitch); -+ } -+ } else { -+ me.lexikiq.event.sound.LocationCustomSoundEvent event = (me.lexikiq.event.sound.LocationCustomSoundEvent) _event; -+ org.bukkit.util.Vector pos = event.getVector(); -+ return new net.minecraft.network.protocol.game.ClientboundCustomSoundPacket(CraftNamespacedKey.toMinecraft(event.getKey()), source, org.bukkit.craftbukkit.util.CraftVector.toNMS(pos), volume, pitch); ++ if (_event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent event) { ++ org.bukkit.util.Vector pos = event.getPosition(); ++ return new net.minecraft.network.protocol.game.ClientboundSoundPacket(sound, source, pos.getX(), pos.getY(), pos.getZ(), volume, pitch); ++ } else if (_event instanceof me.lexikiq.event.sound.EntitySoundEvent event) { ++ return new net.minecraft.network.protocol.game.ClientboundSoundEntityPacket(sound, source, ((CraftEntity) event.getOrigin()).getHandle(), volume, pitch); + } ++ } else if (_event instanceof me.lexikiq.event.sound.LocationCustomSoundEvent event) { ++ org.bukkit.util.Vector pos = event.getPosition(); ++ return new net.minecraft.network.protocol.game.ClientboundCustomSoundPacket(CraftNamespacedKey.toMinecraft(event.getKey()), source, org.bukkit.craftbukkit.util.CraftVector.toNMS(pos), volume, pitch); + } ++ throw new IllegalArgumentException("Unknown sound event: " + _event.getClass().getName()); + } + -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, java.util.function.Consumer> soundPlayer) { ++ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event) { + org.apache.commons.lang3.Validate.notNull(event, "event"); -+ org.apache.commons.lang3.Validate.notNull(soundPlayer, "soundPlayer"); -+ if (!(event instanceof me.lexikiq.event.sound.LocationNamedSoundEvent || event instanceof me.lexikiq.event.sound.LocationCustomSoundEvent || event instanceof me.lexikiq.event.sound.EntitySoundEvent)) { -+ throw new IllegalArgumentException("Unknown sound event: " + event.getClass().getName()); -+ } -+ java.util.concurrent.CompletableFuture.supplyAsync(() -> handleSoundEvent(event), net.minecraft.server.MCUtil.asyncExecutor).thenAcceptAsync(packet -> { ++ java.util.concurrent.CompletableFuture.supplyAsync(() -> handleSoundEvent(event), net.minecraft.server.MCUtil.asyncExecutor).handleAsync((packet, throwable) -> { + if (packet != null) -+ soundPlayer.accept(packet); ++ event.calculateRecipients().forEach(recipient -> ((org.bukkit.craftbukkit.entity.CraftPlayer) recipient).getHandle().connection.send(packet)); ++ else if (throwable != null) ++ org.slf4j.LoggerFactory.getLogger("SoundEvent").error("Error while handling sound event", throwable); ++ return null; + }, net.minecraft.server.MCUtil.asyncExecutor); + } -+ -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, CraftPlayer sendTo) { -+ playSoundEvent(event, sendTo.getHandle()); -+ } -+ -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, ServerPlayer sendTo) { -+ playSoundEvent(event, sendTo.connection); -+ } -+ -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.network.ServerPlayerConnection sendTo) { -+ playSoundEvent(event, sendTo::send); -+ } -+ -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.MinecraftServer server, double radius) { -+ playSoundEvent(event, server.getPlayerList(), radius); -+ } -+ -+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, net.minecraft.server.players.PlayerList playerList, double radius) { -+ final net.minecraft.world.entity.player.Player player = event.getPlayer() == null ? null : ((org.bukkit.craftbukkit.entity.CraftHumanEntity) event.getPlayer()).getHandle(); -+ final net.minecraft.resources.ResourceKey world = ((CraftWorld) event.getWorld()).getHandle().dimension(); -+ final org.bukkit.util.Vector pos; -+ if (event instanceof me.lexikiq.HasLocation hasLoc) { -+ pos = hasLoc.getLocation().toVector(); -+ } else if (event instanceof me.lexikiq.event.sound.EntitySoundEvent entityEvent) { -+ pos = entityEvent.getOrigin().getLocation().toVector(); -+ } else { -+ throw new IllegalArgumentException("Could not determine location of sound event"); -+ } -+ final double posX = pos.getX(); -+ final double posY = pos.getY(); -+ final double posZ = pos.getZ(); -+ playSoundEvent(event, packet -> playerList.broadcast(player, posX, posY, posZ, radius, world, packet)); -+ } + // Parchment end } diff --git a/patches/server/0005-Add-origin-location-to-EntityDamageByBlockEvent.patch b/patches/server/0005-Add-origin-location-to-EntityDamageByBlockEvent.patch index 6ef53c9..2781282 100644 --- a/patches/server/0005-Add-origin-location-to-EntityDamageByBlockEvent.patch +++ b/patches/server/0005-Add-origin-location-to-EntityDamageByBlockEvent.patch @@ -146,10 +146,10 @@ index 88439b8f82a97a9763dadfc6c9dbaf0912ab3eb7..73a9b765b58bb547712c014c8b908653 public static boolean canSetSpawn(Level world) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901b1d41825 100644 +index b774a27eb4d11cd1bef807193a6df6012dde3794..911c0dd8a5863ae93dbd82fd3d6aafc267994081 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -955,7 +955,7 @@ public class CraftEventFactory { +@@ -961,7 +961,7 @@ public class CraftEventFactory { CraftEventFactory.entityDamage = null; EntityDamageEvent event; if (damager == null) { @@ -158,7 +158,7 @@ index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901 } else if (entity instanceof EnderDragon && /*PAIL FIXME ((EntityEnderDragon) entity).target == damager*/ false) { event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions); } else { -@@ -991,7 +991,7 @@ public class CraftEventFactory { +@@ -997,7 +997,7 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API } else if (source == DamageSource.OUT_OF_WORLD) { @@ -167,7 +167,7 @@ index b2f49ee945dae88c15a76e7ba5433b7ca150e9d6..a7679036d31f0262a68dd1bfb2871901 event.setCancelled(cancelled); CraftEventFactory.callEvent(event); if (!event.isCancelled()) { -@@ -999,7 +999,7 @@ public class CraftEventFactory { +@@ -1005,7 +1005,7 @@ public class CraftEventFactory { } return event; } else if (source == DamageSource.LAVA) { diff --git a/patches/server/0011-Add-BlockDropResourcesEvent.patch b/patches/server/0011-Add-BlockDropResourcesEvent.patch index da12380..afe3505 100644 --- a/patches/server/0011-Add-BlockDropResourcesEvent.patch +++ b/patches/server/0011-Add-BlockDropResourcesEvent.patch @@ -48,12 +48,12 @@ index 8c30e28b97ac7e8b54322c903e0b75ee8135620b..4ca85a02a1eb46b5958aae55946c67ce }); state.spawnAfterBreak((ServerLevel) world, pos, stack); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index a3245218525f538aaba00c72f3500880853dd9d0..760d35356591380a3e4a5cbd71ebe2ce13050dbc 100644 +index 911c0dd8a5863ae93dbd82fd3d6aafc267994081..7aafe7cd3a8dae6b8f7b662049bf48bc6d698789 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1954,5 +1954,11 @@ public class CraftEventFactory { - final double posZ = pos.getZ(); - playSoundEvent(event, packet -> playerList.broadcast(player, posX, posY, posZ, radius, world, packet)); +@@ -1924,5 +1924,11 @@ public class CraftEventFactory { + return null; + }, net.minecraft.server.MCUtil.asyncExecutor); } + + public static List callBlockDropResourcesEvent(LevelAccessor world, BlockPos pos, List items) {