Remap + cleanup patches

This commit is contained in:
lexikiq
2021-06-19 16:34:13 -04:00
parent 8e891a9716
commit 04d3cca53e
28 changed files with 3323 additions and 3278 deletions

View File

@@ -0,0 +1,6 @@
# You can use this file to import files from vanilla into the project
# both fully qualified and a file based syntax are accepted here:
# net.minecraft.world.level.entity.LevelEntityGetterAdapter
# net/minecraft/world/level/entity/LevelEntityGetter.java
net.minecraft.world.damagesource.BadRespawnPointDamage
net.minecraft.world.level.block.RespawnAnchorBlock

2
build-data/parchment.at Normal file
View File

@@ -0,0 +1,2 @@
# Add UnsafeValues#canPlaceItemOn
public net.minecraft.world.item.BlockItem canPlace(Lnet/minecraft/world/item/context/BlockPlaceContext;Lnet/minecraft/world/level/block/state/BlockState;)Z

View File

@@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Thu, 17 Jun 2021 14:38:59 -0400
Subject: [PATCH] Build changes
diff --git a/build.gradle.kts b/build.gradle.kts
index 6d04816e22f44a33c001d2b7e080402fba6af86c..8dea8af5898cfe89e6aa4a8d278eba32fc4214cf 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -27,6 +27,7 @@ dependencies {
api("org.ow2.asm:asm:9.0")
api("org.ow2.asm:asm-commons:9.0")
api("org.apache.logging.log4j:log4j-api:2.14.1") // Paper
+ api(project(":Parchment-Common")) // Parchment
compileOnly("org.apache.maven:maven-resolver-provider:3.8.1")
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.0")

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com> From: lexikiq <noellekiq@gmail.com>
Date: Tue, 1 Jun 2021 16:22:54 -0400 Date: Sat, 19 Jun 2021 16:17:40 -0400
Subject: [PATCH] Add SoundEvent 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 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 new file mode 100644
index 0000000000000000000000000000000000000000..bf7cd3b9183925cdeef2969cad045bf766a54742 index 0000000000000000000000000000000000000000..de8606c42022589ed8b3841e531e001aaa716bcf
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java +++ b/src/main/java/me/lexikiq/event/sound/EntitySoundEvent.java
@@ -0,0 +1,44 @@ @@ -0,0 +1,49 @@
+package me.lexikiq.event.sound; +package me.lexikiq.event.sound;
+ +
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.bukkit.Sound; +import org.bukkit.Sound;
+import org.bukkit.SoundCategory; +import org.bukkit.SoundCategory;
+import org.bukkit.World;
+import org.bukkit.entity.Entity; +import org.bukkit.entity.Entity;
+import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.HumanEntity;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
@@ -53,15 +54,20 @@ index 0000000000000000000000000000000000000000..bf7cd3b9183925cdeef2969cad045bf7
+ this.origin = origin; + this.origin = origin;
+ } + }
+ +
+ @Override
+ public World getWorld() {
+ return origin.getWorld();
+ }
+} +}
diff --git a/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java 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 new file mode 100644
index 0000000000000000000000000000000000000000..8ce556953dd175336ef887c508ad8e027b9df4a6 index 0000000000000000000000000000000000000000..f007bc326bea341735e7313789f5d110af5ac4ca
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java +++ b/src/main/java/me/lexikiq/event/sound/LocationCustomSoundEvent.java
@@ -0,0 +1,73 @@ @@ -0,0 +1,121 @@
+package me.lexikiq.event.sound; +package me.lexikiq.event.sound;
+ +
+import me.lexikiq.HasLocation;
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.bukkit.Keyed; +import org.bukkit.Keyed;
+import org.bukkit.Location; +import org.bukkit.Location;
@@ -73,10 +79,12 @@ index 0000000000000000000000000000000000000000..8ce556953dd175336ef887c508ad8e02
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable;
+ +
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/** +/**
+ * Called when a sound not available in {@link org.bukkit.Sound} is sent to a player from a {@link Location}. Cancelling this event will prevent the packet from sending. + * Called when a sound not available in {@link org.bukkit.Sound} is sent to a player from a {@link Location}. Cancelling this event will prevent the packet from sending.
+ */ + */
+public class LocationCustomSoundEvent extends SoundEvent implements Keyed { +public class LocationCustomSoundEvent extends SoundEvent implements Keyed, HasLocation {
+ private @NotNull Vector vector; + private @NotNull Vector vector;
+ private @NotNull NamespacedKey key; + private @NotNull NamespacedKey key;
+ private @NotNull final World world; + private @NotNull final World world;
@@ -91,6 +99,18 @@ index 0000000000000000000000000000000000000000..8ce556953dd175336ef887c508ad8e02
+ this.key = key; + this.key = key;
+ } + }
+ +
+ public LocationCustomSoundEvent(@Nullable HumanEntity receiver, @NotNull Location location, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(receiver, checkNotNull(location, "location").getWorld(), location.toVector(), key, category, volume, pitch);
+ }
+
+ public LocationCustomSoundEvent(@NotNull HumanEntity receiver, @NotNull Vector vector, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(receiver, "receiver"), receiver.getWorld(), vector, key, category, volume, pitch);
+ }
+
+ public LocationCustomSoundEvent(@NotNull HumanEntity receiver, @NotNull NamespacedKey key, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(receiver, "receiver"), receiver.getLocation().toVector(), key, category, volume, pitch);
+ }
+
+ /** + /**
+ * Gets the position in the world of the sound + * Gets the position in the world of the sound
+ * @return position in the world + * @return position in the world
@@ -107,15 +127,22 @@ index 0000000000000000000000000000000000000000..8ce556953dd175336ef887c508ad8e02
+ return key; + return key;
+ } + }
+ +
+ /** + @Override
+ * Gets the world in which the sound is being played
+ * @return sound's world
+ */
+ public @NotNull World getWorld() { + public @NotNull World getWorld() {
+ return world; + return world;
+ } + }
+ +
+ /** + /**
+ * Gets the location of the sound being played
+ * @return copy of sound location
+ * @see #getVector()
+ * @see #setVector(Vector)
+ */
+ public @NotNull Location getLocation() {
+ return new Location(world, vector.getX(), vector.getY(), vector.getZ());
+ }
+
+ /**
+ * Sets the position in the world of the sound + * Sets the position in the world of the sound
+ * @param vector position in the world + * @param vector position in the world
+ */ + */
@@ -132,15 +159,42 @@ index 0000000000000000000000000000000000000000..8ce556953dd175336ef887c508ad8e02
+ Validate.notNull(key, "key cannot be null"); + Validate.notNull(key, "key cannot be null");
+ this.key = key; + this.key = key;
+ } + }
+
+ // boilerplate
+
+ private boolean cancelled;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
+
+ @Override
+ public @NotNull org.bukkit.event.HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static org.bukkit.event.HandlerList getHandlerList() {
+ return handlers;
+ }
+} +}
diff --git a/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java 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 new file mode 100644
index 0000000000000000000000000000000000000000..242a7f3d4d6ab6ff7000e544605a69eac35f03a8 index 0000000000000000000000000000000000000000..81ba14fea8d04347a0fd3931b27188028c5ac859
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java +++ b/src/main/java/me/lexikiq/event/sound/LocationNamedSoundEvent.java
@@ -0,0 +1,52 @@ @@ -0,0 +1,72 @@
+package me.lexikiq.event.sound; +package me.lexikiq.event.sound;
+ +
+import me.lexikiq.HasLocation;
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.bukkit.Location; +import org.bukkit.Location;
+import org.bukkit.Sound; +import org.bukkit.Sound;
@@ -151,19 +205,31 @@ index 0000000000000000000000000000000000000000..242a7f3d4d6ab6ff7000e544605a69ea
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable;
+ +
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/** +/**
+ * Called when a sound available in {@link Sound} is sent to a player from a {@link Location}. Cancelling this event will prevent the packet from sending. + * Called when a sound available in {@link Sound} is sent to a player from a {@link Location}. Cancelling this event will prevent the packet from sending.
+ */ + */
+public class LocationNamedSoundEvent extends NamedSoundEvent { +public class LocationNamedSoundEvent extends NamedSoundEvent implements HasLocation {
+ private @NotNull Vector vector; + private @NotNull Vector vector;
+ private @NotNull final World world; + private @NotNull final World world;
+ +
+ public LocationNamedSoundEvent(@Nullable HumanEntity receiver, @NotNull World world, @NotNull Vector vector, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { + 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); + super(receiver, sound, category, volume, pitch);
+ Validate.notNull(world, "world cannot be null"); + this.world = checkNotNull(world, "world");
+ Validate.notNull(vector, "vector cannot be null"); + this.vector = checkNotNull(vector, "vector");
+ this.world = world; + }
+ this.vector = vector; +
+ 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);
+ }
+
+ 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(@NotNull HumanEntity receiver, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
+ this(checkNotNull(receiver, "receiver"), receiver.getLocation().toVector(), sound, category, volume, pitch);
+ } + }
+ +
+ /** + /**
@@ -174,15 +240,22 @@ index 0000000000000000000000000000000000000000..242a7f3d4d6ab6ff7000e544605a69ea
+ return vector; + return vector;
+ } + }
+ +
+ /** + @Override
+ * Gets the world in which the sound is being played
+ * @return sound's world
+ */
+ public @NotNull World getWorld() { + public @NotNull World getWorld() {
+ return world; + return world;
+ } + }
+ +
+ /** + /**
+ * Gets the location of the sound being played
+ * @return copy of sound location
+ * @see #getVector()
+ * @see #setVector(Vector)
+ */
+ public @NotNull Location getLocation() {
+ return new Location(world, vector.getX(), vector.getY(), vector.getZ());
+ }
+
+ /**
+ * Sets the position in the world of the sound + * Sets the position in the world of the sound
+ * @param vector position in the world + * @param vector position in the world
+ */ + */
@@ -193,10 +266,10 @@ index 0000000000000000000000000000000000000000..242a7f3d4d6ab6ff7000e544605a69ea
+} +}
diff --git a/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java 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 new file mode 100644
index 0000000000000000000000000000000000000000..516352ffb64fd025be018f5389a7c80e62743c9a index 0000000000000000000000000000000000000000..8623e03aa5ca094629bf6a20669ea8c5086d938c
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java +++ b/src/main/java/me/lexikiq/event/sound/NamedSoundEvent.java
@@ -0,0 +1,40 @@ @@ -0,0 +1,64 @@
+package me.lexikiq.event.sound; +package me.lexikiq.event.sound;
+ +
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
@@ -208,10 +281,8 @@ index 0000000000000000000000000000000000000000..516352ffb64fd025be018f5389a7c80e
+ +
+/** +/**
+ * Called when a sound available in {@link Sound} is sent to a player. Cancelling this event will prevent the packet from sending. + * Called when a sound available in {@link Sound} is sent to a player. Cancelling this event will prevent the packet from sending.
+ * <p>
+ * Note: this does not directly correspond to any given sound packet. It is provided for listening convenience.
+ */ + */
+public class NamedSoundEvent extends SoundEvent { +public abstract class NamedSoundEvent extends SoundEvent {
+ private @NotNull Sound sound; + private @NotNull Sound sound;
+ +
+ public NamedSoundEvent(@Nullable HumanEntity receiver, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { + public NamedSoundEvent(@Nullable HumanEntity receiver, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) {
@@ -236,36 +307,59 @@ index 0000000000000000000000000000000000000000..516352ffb64fd025be018f5389a7c80e
+ Validate.notNull(sound, "sound cannot be null"); + Validate.notNull(sound, "sound cannot be null");
+ this.sound = sound; + this.sound = sound;
+ } + }
+
+ // boilerplate
+
+ private boolean cancelled;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
+
+ @Override
+ public @NotNull org.bukkit.event.HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static org.bukkit.event.HandlerList getHandlerList() {
+ return handlers;
+ }
+} +}
diff --git a/src/main/java/me/lexikiq/event/sound/SoundEvent.java b/src/main/java/me/lexikiq/event/sound/SoundEvent.java 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 new file mode 100644
index 0000000000000000000000000000000000000000..05cd0148bec4770ce78fceda1fe57cf625b0bacf index 0000000000000000000000000000000000000000..77b17b76a5137b30d5f8f040c0bcfa5f143223cb
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/sound/SoundEvent.java +++ b/src/main/java/me/lexikiq/event/sound/SoundEvent.java
@@ -0,0 +1,115 @@ @@ -0,0 +1,96 @@
+package me.lexikiq.event.sound; +package me.lexikiq.event.sound;
+ +
+import me.lexikiq.OptionalHumanEntity; +import me.lexikiq.OptionalHumanEntity;
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.bukkit.SoundCategory; +import org.bukkit.SoundCategory;
+import org.bukkit.World;
+import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.HumanEntity;
+import org.bukkit.event.Cancellable; +import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event; +import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable;
+ +
+/** +/**
+ * Called when a sound is sent to a player. Cancelling this event will prevent the packet from sending. + * Called when a sound is sent to a player. Cancelling this event will prevent the packet from sending.
+ * <p>
+ * Note: this does not directly correspond to any given sound packet. It is provided for listening convenience.
+ */ + */
+public class SoundEvent extends Event implements Cancellable, OptionalHumanEntity { +public abstract class SoundEvent extends Event implements Cancellable, OptionalHumanEntity {
+ private @Nullable final HumanEntity receiver; + private @Nullable final HumanEntity receiver;
+ private @NotNull SoundCategory category; + private @NotNull SoundCategory category;
+ private float volume; + private float volume;
+ private float pitch; + private float pitch;
+ private boolean cancelled;
+ +
+ public SoundEvent(@Nullable HumanEntity receiver, @NotNull SoundCategory category, float volume, float pitch) { + public SoundEvent(@Nullable HumanEntity receiver, @NotNull SoundCategory category, float volume, float pitch) {
+ super(true); + super(true);
@@ -336,25 +430,9 @@ index 0000000000000000000000000000000000000000..05cd0148bec4770ce78fceda1fe57cf6
+ this.pitch = pitch; + this.pitch = pitch;
+ } + }
+ +
+ @Override + /**
+ public boolean isCancelled() { + * Gets the world in which the sound is being played
+ return cancelled; + * @return sound's world
+ } + */
+ + public abstract World getWorld();
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ private static final HandlerList handlers = new HandlerList();
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+} +}

View File

@@ -1,17 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com> From: lexikiq <noellekiq@gmail.com>
Date: Thu, 13 May 2021 23:55:02 -0400 Date: Thu, 13 May 2021 23:55:02 -0400
Subject: [PATCH] Create PlayerUseRespawnAnchorEvent Subject: [PATCH] Add PlayerUseRespawnAnchorEvent
diff --git a/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java b/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java diff --git a/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java b/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..96b552fe0bd6e6507c1c4f9380cab32e725cb129 index 0000000000000000000000000000000000000000..fcf552bb84a10794dda178b337768efe4781facd
--- /dev/null --- /dev/null
+++ b/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java +++ b/src/main/java/me/lexikiq/event/player/PlayerUseRespawnAnchorEvent.java
@@ -0,0 +1,102 @@ @@ -0,0 +1,117 @@
+package me.lexikiq.event.player; +package me.lexikiq.event.player;
+ +
+import com.google.common.base.Preconditions;
+import org.bukkit.block.Block; +import org.bukkit.block.Block;
+import org.bukkit.entity.Player; +import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable; +import org.bukkit.event.Cancellable;
@@ -20,7 +21,8 @@ index 0000000000000000000000000000000000000000..96b552fe0bd6e6507c1c4f9380cab32e
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+ +
+/** +/**
+ * This event is fired immediately before the result of using a respawn anchor is executed + * This event is fired after determining what action should result from a player interacting with
+ * a respawn anchor.
+ */ + */
+public class PlayerUseRespawnAnchorEvent extends PlayerEvent implements Cancellable { +public class PlayerUseRespawnAnchorEvent extends PlayerEvent implements Cancellable {
+ +
@@ -39,12 +41,16 @@ index 0000000000000000000000000000000000000000..96b552fe0bd6e6507c1c4f9380cab32e
+ /** + /**
+ * The player will charge the respawn anchor + * The player will charge the respawn anchor
+ */ + */
+ CHARGE + CHARGE,
+ /**
+ * The respawn anchor will do nothing
+ */
+ NOTHING
+ } + }
+ +
+ private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList();
+ private final Block respawnAnchor; + private final Block respawnAnchor;
+ private final RespawnAnchorResult respawnAnchorResult; + private RespawnAnchorResult respawnAnchorResult;
+ private boolean cancelled = false; + private boolean cancelled = false;
+ +
+ public PlayerUseRespawnAnchorEvent(@NotNull Player who, @NotNull Block respawnAnchor, @NotNull RespawnAnchorResult respawnAnchorResult) { + public PlayerUseRespawnAnchorEvent(@NotNull Player who, @NotNull Block respawnAnchor, @NotNull RespawnAnchorResult respawnAnchorResult) {
@@ -69,11 +75,20 @@ index 0000000000000000000000000000000000000000..96b552fe0bd6e6507c1c4f9380cab32e
+ * @return the respawn anchor result for the outcome of the event + * @return the respawn anchor result for the outcome of the event
+ */ + */
+ @NotNull + @NotNull
+ public RespawnAnchorResult getRespawnAnchorResult() { + public RespawnAnchorResult getResult() {
+ return this.respawnAnchorResult; + return this.respawnAnchorResult;
+ } + }
+ +
+ /** + /**
+ * Sets the outcome of the event.
+ *
+ * @param result event to set
+ */
+ public void setResult(@NotNull RespawnAnchorResult result) {
+ this.respawnAnchorResult = Preconditions.checkNotNull(result, "result");
+ }
+
+ /**
+ * Gets the cancellation state of this event. A cancelled event will not + * Gets the cancellation state of this event. A cancelled event will not
+ * be executed in the server, but will still pass to other plugins. + * be executed in the server, but will still pass to other plugins.
+ * <p> + * <p>

View File

@@ -1,14 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com> From: lexikiq <noellekiq@gmail.com>
Date: Mon, 10 May 2021 22:10:23 -0400 Date: Fri, 18 Jun 2021 14:06:43 -0400
Subject: [PATCH] Add origin location to EntityDamageByBlockEvent Subject: [PATCH] Add origin location to EntityDamageByBlockEvent
diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
index 461727dc7f06efb3550fc370e0db5bd04ba89711..cd3ad8ce0f3f22f1292ae81e3a974d0d464a388c 100644 index 461727dc7f06efb3550fc370e0db5bd04ba89711..f20ac2ba1921616f346c11ef60c53aba0080728b 100644
--- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java --- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
@@ -12,17 +12,38 @@ import org.jetbrains.annotations.Nullable; @@ -12,17 +12,43 @@ import org.jetbrains.annotations.Nullable;
*/ */
public class EntityDamageByBlockEvent extends EntityDamageEvent { public class EntityDamageByBlockEvent extends EntityDamageEvent {
private final Block damager; private final Block damager;
@@ -30,7 +30,12 @@ index 461727dc7f06efb3550fc370e0db5bd04ba89711..cd3ad8ce0f3f22f1292ae81e3a974d0d
+ public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @Nullable final org.bukkit.Location damageLocation, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) { + public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @Nullable final org.bukkit.Location damageLocation, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
+ super(damagee, cause, modifiers, modifierFunctions); + super(damagee, cause, modifiers, modifierFunctions);
+ this.damager = damager; + this.damager = damager;
+ if (damageLocation != null)
+ this.location = damageLocation; + this.location = damageLocation;
+ else if (damager != null)
+ this.location = damager.getLocation();
+ else
+ this.location = null;
+ } + }
+ +
+ /** + /**

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 18 Jun 2021 01:47:40 -0400
Subject: [PATCH] Adventure fixes
diff --git a/src/main/java/org/bukkit/Keyed.java b/src/main/java/org/bukkit/Keyed.java
index 32c92621c2c15eec14c50965f5ecda00c46e6c80..3876a03ab9df9a0aef7a5c05a38b39b07a6dd285 100644
--- a/src/main/java/org/bukkit/Keyed.java
+++ b/src/main/java/org/bukkit/Keyed.java
@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents an object which has a {@link NamespacedKey} attached to it.
*/
-public interface Keyed {
+public interface Keyed extends net.kyori.adventure.key.Keyed { // Parchment
/**
* Return the namespaced identifier for this object.
@@ -14,4 +14,11 @@ public interface Keyed {
*/
@NotNull
NamespacedKey getKey();
+
+ // Parchment start
+ @Override
+ default net.kyori.adventure.key.@org.checkerframework.checker.nullness.qual.NonNull Key key() {
+ return getKey();
+ }
+ // Parchment end
}

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 18 Jun 2021 03:18:47 -0400
Subject: [PATCH] Add UnsafeValues#canPlaceItemOn
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
index 379acee1b5f2d06e6a96f3444783f4a29ca24095..c4f81d9a642005e52eb3d88daf6da6caa48a3f0d 100644
--- a/src/main/java/org/bukkit/UnsafeValues.java
+++ b/src/main/java/org/bukkit/UnsafeValues.java
@@ -184,4 +184,17 @@ public interface UnsafeValues {
*/
int getProtocolVersion();
// Paper end
+
+ // Parchment start
+ /**
+ * Determines if this item can be placed on a block. Must be run synchronously.
+ * Factors in player location, blocking events, hitboxes, and more.
+ * @param item item to test
+ * @param player optional player placing the block
+ * @param block block that is being placed against
+ * @param face cardinal direction
+ * @return if the item can be placed
+ */
+ java.util.concurrent.CompletableFuture<Boolean> canPlaceItemOn(@org.jetbrains.annotations.NotNull ItemStack item, @org.jetbrains.annotations.Nullable me.lexikiq.OptionalHumanEntity player, @org.jetbrains.annotations.NotNull org.bukkit.block.Block block, @org.jetbrains.annotations.NotNull org.bukkit.block.BlockFace face);
+ // Parchment end
}

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 1 May 2021 14:27:26 -0400
Subject: [PATCH] Parchment POM Changes
diff --git a/pom.xml b/pom.xml
index 73fbd5d5a591871a3a386fb5c455cd96a3992e7a..1e182b441771c7159dd4323c2c72364efb971407 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,18 +3,18 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>com.destroystokyo.paper</groupId>
- <artifactId>paper-parent</artifactId>
+ <groupId>me.lexikiq</groupId>
+ <artifactId>parchment-parent</artifactId>
<version>dev-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <groupId>com.destroystokyo.paper</groupId>
- <artifactId>paper-api</artifactId>
+ <artifactId>parchment-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Paper-API</name>
- <url>https://github.com/PaperMC/Paper</url>
+ <name>Parchment-API</name>
+ <url>https://github.com/lexikiq/Parchment</url>
<description>An enhanced plugin API for Minecraft servers.</description>
<properties>

View File

@@ -1,83 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Mon, 3 May 2021 21:48:40 -0400
Subject: [PATCH] Add [Optional]PlayerLike interfaces
diff --git a/src/main/java/me/lexikiq/OptionalPlayerLike.java b/src/main/java/me/lexikiq/OptionalPlayerLike.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaa1879f9560ef6ff415e98a5fdf2403f0480a0b
--- /dev/null
+++ b/src/main/java/me/lexikiq/OptionalPlayerLike.java
@@ -0,0 +1,16 @@
+package me.lexikiq;
+
+import net.kyori.adventure.identity.Identified;
+import net.kyori.adventure.identity.Identity;
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * Class that may be like a {@link org.bukkit.entity.Player} in that it has a {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, {@link Identity}, and a nullable Player.
+ * @see me.lexikiq.PlayerLike
+ */
+public interface OptionalPlayerLike extends OptionalPlayer, HasUniqueId, HasOfflinePlayer, Identified {
+ @Override
+ default @NonNull Identity identity() {
+ return Identity.identity(getUniqueId());
+ }
+}
diff --git a/src/main/java/me/lexikiq/PlayerLike.java b/src/main/java/me/lexikiq/PlayerLike.java
new file mode 100644
index 0000000000000000000000000000000000000000..3184f585f9c6e59ce9297d6613749453ce5e6ab5
--- /dev/null
+++ b/src/main/java/me/lexikiq/PlayerLike.java
@@ -0,0 +1,7 @@
+package me.lexikiq;
+
+/**
+ * Class that is like a {@link org.bukkit.entity.Player} in that it has a Player, {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, and an {@link net.kyori.adventure.identity.Identity}.
+ * @see me.lexikiq.OptionalPlayerLike
+ */
+public interface PlayerLike extends HasPlayer, OptionalPlayerLike {}
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
index e2b4f86fc3825a77a5a0c1c29b428308eee54b16..95220ef8ad0602fae9f88c0231762ff50358d98f 100644
--- a/src/main/java/org/bukkit/OfflinePlayer.java
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
@@ -5,6 +5,7 @@ import java.util.UUID;
import me.lexikiq.HasOfflinePlayer;
import me.lexikiq.HasUniqueId;
import me.lexikiq.OptionalPlayer;
+import me.lexikiq.OptionalPlayerLike;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.EntityType;
@@ -13,7 +14,7 @@ import org.bukkit.permissions.ServerOperator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, OptionalPlayer, HasUniqueId, HasOfflinePlayer { // Parchment
+public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, OptionalPlayerLike { // Parchment
// Parchment start
@Override
@NotNull default OfflinePlayer getOfflinePlayer() {
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 54138dae452714e73549ad1c1512b68267cad443..2c9aa0cbce1450695b285a9e654b0e9f10e28c37 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -6,6 +6,7 @@ import java.util.UUID;
import com.destroystokyo.paper.ClientOption; // Paper
import com.destroystokyo.paper.Title; // Paper
import me.lexikiq.HasPlayer;
+import me.lexikiq.PlayerLike;
import net.kyori.adventure.text.Component;
import com.destroystokyo.paper.profile.PlayerProfile; // Paper
import java.util.Date; // Paper
@@ -40,7 +41,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a player, connected or not
*/
-public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, com.destroystokyo.paper.network.NetworkClient, HasPlayer { // Paper // Parchment
+public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, com.destroystokyo.paper.network.NetworkClient, PlayerLike { // Paper // Parchment
// Parchment start
/**

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sun, 9 May 2021 17:03:09 -0400
Subject: [PATCH] Update to Java 15
diff --git a/pom.xml b/pom.xml
index 6857042b3475925f426cbe9f4858438a02bebd23..a295e88e8c05306c0e5876608797d64df6dc1699 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,8 +19,10 @@
<properties>
<!-- <skipTests>true</skipTests> Paper - This [was] not going to end well -->
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
+ <!-- Parchment start -->
+ <maven.compiler.source>15</maven.compiler.source>
+ <maven.compiler.target>15</maven.compiler.target>
+ <!-- Parchment end -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<adventure.version>4.7.0</adventure.version> <!-- Paper - When updating this make sure to update the linked JavaDocs on the homepage as well! -->
</properties>
@@ -148,7 +150,7 @@
<!-- annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
- <artifactId>annotations-java5</artifactId>
+ <artifactId>annotations</artifactId> <!-- Parchment -->
<version>20.1.0</version>
<scope>provided</scope>
</dependency>
@@ -278,15 +280,38 @@
</properties>
</configuration>
</plugin>
+ <!-- Parchment start -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>3.2.0</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
<configuration>
+ <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
<links>
<link>https://guava.dev/releases/21.0/api/docs/</link>
<link>https://javadoc.io/doc/org.yaml/snakeyaml/1.27/</link>
- <link>https://javadoc.io/doc/org.jetbrains/annotations-java5/20.1.0/</link>
+ <link>https://javadoc.io/doc/org.jetbrains/annotations/20.1.0/</link> <!-- Parchment -->
<link>https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/</link>
<!-- Paper start -->
<link>https://jd.adventure.kyori.net/api/${adventure.version}/</link>
@@ -297,6 +322,7 @@
</links>
</configuration>
</plugin>
+ <!-- Parchment end -->
</plugins>
</build>

View File

@@ -1,308 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 14 May 2021 21:05:49 -0400
Subject: [PATCH] Make OptionalPlayerLike extend Audience
diff --git a/src/main/java/me/lexikiq/OptionalPlayer.java b/src/main/java/me/lexikiq/OptionalPlayer.java
index 70fcce84e8b42f3a2c3543b8365b25cc90addc8d..428e25fa82e276c473f3d96e56ac1539431a6674 100644
--- a/src/main/java/me/lexikiq/OptionalPlayer.java
+++ b/src/main/java/me/lexikiq/OptionalPlayer.java
@@ -13,4 +13,13 @@ public interface OptionalPlayer extends OptionalHumanEntity {
* @return player or null
*/
@Nullable Player getPlayer();
+
+ /**
+ * Tests if the {@link Player} represented by this object is online.
+ *
+ * @return true if online
+ */
+ default boolean isOnline() {
+ return getPlayer() != null;
+ }
}
diff --git a/src/main/java/me/lexikiq/OptionalPlayerLike.java b/src/main/java/me/lexikiq/OptionalPlayerLike.java
index aaa1879f9560ef6ff415e98a5fdf2403f0480a0b..d56c4612ac601fb43a277ee3102726e6547cfee8 100644
--- a/src/main/java/me/lexikiq/OptionalPlayerLike.java
+++ b/src/main/java/me/lexikiq/OptionalPlayerLike.java
@@ -1,16 +1,200 @@
package me.lexikiq;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.audience.MessageType;
+import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
-import org.checkerframework.checker.nullness.qual.NonNull;
+import net.kyori.adventure.inventory.Book;
+import net.kyori.adventure.sound.Sound;
+import net.kyori.adventure.sound.SoundStop;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.title.Title;
+import org.apache.commons.lang.Validate;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
/**
* Class that may be like a {@link org.bukkit.entity.Player} in that it has a {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, {@link Identity}, and a nullable Player.
+ * <p>
+ * This class extends the {@link Audience} interface and will silently fail if the player is not online.
* @see me.lexikiq.PlayerLike
*/
-public interface OptionalPlayerLike extends OptionalPlayer, HasUniqueId, HasOfflinePlayer, Identified {
+public interface OptionalPlayerLike extends OptionalPlayer, HasUniqueId, HasOfflinePlayer, Identified, Audience {
+ /**
+ * Gets the identity corresponding with this object.
+ *
+ * @return the identity
+ * @since 4.0.0
+ */
@Override
- default @NonNull Identity identity() {
+ default @NotNull Identity identity() {
return Identity.identity(getUniqueId());
}
+
+ /**
+ * Run a consumer with the {@link Player} associated with this object if the player is online.
+ * <p>
+ * Allows easily running a code on the player only if they are connected.
+ *
+ * @param consumer function that accepts a Player
+ */
+ default void consumeIfOnline(final @NotNull Consumer<@NotNull Player> consumer) {
+ Validate.notNull(consumer, "Consumer<Player> should not be null");
+
+ final Player player = getPlayer();
+ if (player != null)
+ consumer.accept(player);
+ }
+
+ /**
+ * Sends a chat message.
+ *
+ * @param source the identity of the source of the message
+ * @param message a message
+ * @param type the type
+ * @see Component
+ * @since 4.0.0
+ */
+ @Override
+ default void sendMessage(final @NotNull Identity source, final @NotNull Component message, final @NotNull MessageType type) {
+ consumeIfOnline(player -> player.sendMessage(source, message, type));
+ }
+
+ /**
+ * Sends a message on the action bar.
+ *
+ * @param message a message
+ * @see Component
+ * @since 4.0.0
+ */
+ @Override
+ default void sendActionBar(final @NotNull Component message) {
+ consumeIfOnline(player -> player.sendActionBar(message));
+ }
+
+ /**
+ * Sends the player list header and footer.
+ *
+ * @param header the header
+ * @param footer the footer
+ * @since 4.3.0
+ */
+ @Override
+ default void sendPlayerListHeaderAndFooter(final @NotNull Component header, final @NotNull Component footer) {
+ consumeIfOnline(player -> player.sendPlayerListHeaderAndFooter(header, footer));
+ }
+
+ /**
+ * Shows a title.
+ *
+ * @param title a title
+ * @see Title
+ * @since 4.0.0
+ */
+ @Override
+ default void showTitle(final @NotNull Title title) {
+ consumeIfOnline(player -> player.showTitle(title));
+ }
+
+ /**
+ * Clears the title, if one is being displayed.
+ *
+ * @see Title
+ * @since 4.0.0
+ */
+ @Override
+ default void clearTitle() {
+ consumeIfOnline(Audience::clearTitle);
+ }
+
+ /**
+ * Resets the title and timings back to their default.
+ *
+ * @see Title
+ * @since 4.0.0
+ */
+ @Override
+ default void resetTitle() {
+ consumeIfOnline(Audience::resetTitle);
+ }
+
+ /**
+ * Shows a boss bar.
+ *
+ * @param bar a boss bar
+ * @see BossBar
+ * @since 4.0.0
+ */
+ @Override
+ default void showBossBar(final @NotNull BossBar bar) {
+ consumeIfOnline(player -> player.showBossBar(bar));
+ }
+
+ /**
+ * Hides a boss bar.
+ *
+ * @param bar a boss bar
+ * @see BossBar
+ * @since 4.0.0
+ */
+ @Override
+ default void hideBossBar(final @NotNull BossBar bar) {
+ consumeIfOnline(player -> player.hideBossBar(bar));
+ }
+
+ /**
+ * Plays a sound.
+ *
+ * @param sound a sound
+ * @see Sound
+ * @since 4.0.0
+ */
+ @Override
+ default void playSound(final @NotNull Sound sound) {
+ consumeIfOnline(player -> player.playSound(sound));
+ }
+
+ /**
+ * Plays a sound at a location.
+ *
+ * @param sound a sound
+ * @param x x coordinate
+ * @param y y coordinate
+ * @param z z coordinate
+ * @see Sound
+ * @since 4.0.0
+ */
+ @Override
+ default void playSound(final @NotNull Sound sound, final double x, final double y, final double z) {
+ consumeIfOnline(player -> player.playSound(sound, x, y, z));
+ }
+
+ /**
+ * Stops a sound, or many sounds.
+ *
+ * @param stop a sound stop
+ * @see SoundStop
+ * @since 4.0.0
+ */
+ @Override
+ default void stopSound(final @NotNull SoundStop stop) {
+ consumeIfOnline(player -> player.stopSound(stop));
+ }
+
+ /**
+ * Opens a book.
+ *
+ * <p>When possible, no item should persist after closing the book.</p>
+ *
+ * @param book a book
+ * @see Book
+ * @since 4.0.0
+ */
+ @Override
+ default void openBook(final @NotNull Book book) {
+ consumeIfOnline(player -> player.openBook(book));
+ }
}
diff --git a/src/main/java/me/lexikiq/PlayerLike.java b/src/main/java/me/lexikiq/PlayerLike.java
index 3184f585f9c6e59ce9297d6613749453ce5e6ab5..d00a256c3a489d918c4d9bef1023e621d0faece3 100644
--- a/src/main/java/me/lexikiq/PlayerLike.java
+++ b/src/main/java/me/lexikiq/PlayerLike.java
@@ -1,7 +1,24 @@
package me.lexikiq;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
+
/**
* Class that is like a {@link org.bukkit.entity.Player} in that it has a Player, {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, and an {@link net.kyori.adventure.identity.Identity}.
* @see me.lexikiq.OptionalPlayerLike
*/
-public interface PlayerLike extends HasPlayer, OptionalPlayerLike {}
+public interface PlayerLike extends HasPlayer, OptionalPlayerLike {
+
+ /**
+ * Run a consumer with the {@link Player} associated with this object.
+ * Unlike the parent class {@link OptionalPlayerLike}, this will always run.
+ *
+ * @param consumer function that accepts a Player
+ */
+ @Override
+ default void consumeIfOnline(@NotNull Consumer<@NotNull Player> consumer) {
+ consumer.accept(getPlayer());
+ }
+}
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
index 95220ef8ad0602fae9f88c0231762ff50358d98f..27e837a0dbcf37fff9927deb1c34a3ca96a7a49f 100644
--- a/src/main/java/org/bukkit/OfflinePlayer.java
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
@@ -3,9 +3,7 @@ package org.bukkit;
import java.util.UUID;
import me.lexikiq.HasOfflinePlayer;
-import me.lexikiq.HasUniqueId;
import me.lexikiq.OptionalPlayer;
-import me.lexikiq.OptionalPlayerLike;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.EntityType;
@@ -14,7 +12,7 @@ import org.bukkit.permissions.ServerOperator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, OptionalPlayerLike { // Parchment
+public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, HasOfflinePlayer, OptionalPlayer { // Parchment
// Parchment start
@Override
@NotNull default OfflinePlayer getOfflinePlayer() {
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 2c9aa0cbce1450695b285a9e654b0e9f10e28c37..b7ce4b50a7f8f9488cb30a40f0e8acaf2b8d33e7 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -5,8 +5,8 @@ import java.util.Set; // Paper
import java.util.UUID;
import com.destroystokyo.paper.ClientOption; // Paper
import com.destroystokyo.paper.Title; // Paper
+import me.lexikiq.HasOfflinePlayer;
import me.lexikiq.HasPlayer;
-import me.lexikiq.PlayerLike;
import net.kyori.adventure.text.Component;
import com.destroystokyo.paper.profile.PlayerProfile; // Paper
import java.util.Date; // Paper
@@ -41,7 +41,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a player, connected or not
*/
-public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, com.destroystokyo.paper.network.NetworkClient, PlayerLike { // Paper // Parchment
+public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, com.destroystokyo.paper.network.NetworkClient, HasOfflinePlayer, HasPlayer { // Paper // Parchment
// Parchment start
/**

View File

@@ -1,78 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 1 May 2021 14:36:37 -0400
Subject: [PATCH] Parchment POM Changes
diff --git a/pom.xml b/pom.xml
index 1a9204c869dd36e80932b1366352db15ebd70723..e8c91265e5694676b6fb6a4b3ee022b88d1e5cf0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,11 +1,11 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <artifactId>paper</artifactId>
+ <artifactId>parchment</artifactId>
<packaging>jar</packaging>
<version>1.16.5-R0.1-SNAPSHOT</version>
- <name>Paper</name>
- <url>https://papermc.io</url>
+ <name>Parchment-Server</name>
+ <url>https://github.com/lexikiq/Parchment</url>
<properties>
<!-- <skipTests>true</skipTests> Paper - This [was] not going to end well -->
@@ -19,8 +19,8 @@
</properties>
<parent>
- <groupId>com.destroystokyo.paper</groupId>
- <artifactId>paper-parent</artifactId>
+ <groupId>me.lexikiq</groupId>
+ <artifactId>parchment-parent</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -39,8 +39,8 @@
<dependencies>
<dependency>
- <groupId>com.destroystokyo.paper</groupId>
- <artifactId>paper-api</artifactId>
+ <groupId>me.lexikiq</groupId>
+ <artifactId>parchment-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
@@ -187,7 +187,7 @@
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
<build>
- <finalName>paper-${minecraft.version}</finalName>
+ <finalName>parchment-${minecraft.version}</finalName>
<defaultGoal>clean install</defaultGoal> <!-- Paper -->
<plugins>
<plugin>
@@ -195,7 +195,7 @@
<artifactId>gitdescribe-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
- <outputPrefix>git-Paper-</outputPrefix>
+ <outputPrefix>git-Parchment-</outputPrefix>
<scmDirectory>..</scmDirectory>
</configuration>
<executions>
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 674096cab190d62622f9947853b056f57d43a2a5..fbba763d909c4636174e79c680745b83c41409bb 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() {
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.destroystokyo.paper/paper-api/pom.properties");
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/me.lexikiq/parchment-api/pom.properties");
Properties properties = new Properties();
if (stream != null) {

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 1 May 2021 14:44:37 -0400
Subject: [PATCH] Disable Metrics
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index dee00aac05f1acf050f05d4db557a08dd0f301c8..df2aefc163d9f932664e2ff0c8a8f9a5b09047e5 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -73,7 +73,7 @@ public class Metrics {
Metrics.logger = logger;
// Start submitting the data
- startSubmitting();
+ // startSubmitting();
}
/**

View File

@@ -1,683 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 1 May 2021 15:08:28 -0400
Subject: [PATCH] Parchment brand changes
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index bf80e870e6a2a6fe1d4ae1bea355bcd7a0735d3b..2b5c226789e807574af798f49d09ebc55db4b71d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1583,7 +1583,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
public String getServerModName() {
- return "Paper"; //Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
+ return "Parchment"; //Parchment - Parchment > //Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
}
public CrashReport b(CrashReport crashreport) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index cebecee640ed5a7fc2b978e00ff7eb012228267d..825a49819a4ff3302f1067d80654e698518506ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -230,7 +230,7 @@ import javax.annotation.Nullable; // Paper
import javax.annotation.Nonnull; // Paper
public final class CraftServer implements Server {
- private final String serverName = "Paper"; // Paper
+ private final String serverName = "Parchment"; // Paper // Parchment
private final String serverVersion;
private final String bukkitVersion = Versioning.getBukkitVersion();
private final Logger logger = Logger.getLogger("Minecraft");
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index 409fbeeb66fb8f58a72d94686bc9515299927b75..312225f15a864dc42df47f9911ba376ffb7b2c99 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -265,7 +265,7 @@ public class Main {
if (buildDate.before(deadline.getTime())) {
// Paper start - This is some stupid bullshit
System.err.println("*** Warning, you've not updated in a while! ***");
- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper
+ System.err.println("*** Please compile a new build ***"); // Paper
//System.err.println("*** Server will start in 20 seconds ***");
//Thread.sleep(TimeUnit.SECONDS.toMillis(20));
// Paper End
diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
index a7d785f60c884ee4ee487cc364402d66c3dc2ecc..0aea373d9f0b09a19a0ed781938bba9cda1a4a30 100644
GIT binary patch
literal 18477
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
literal 14310
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%0ABLt+m?son?j
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
WX&3$!%>|s_1IbA#OV)^+1pg1OmmZn`

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Tue, 4 May 2021 13:02:02 -0400
Subject: [PATCH] Bump to Java 15
diff --git a/pom.xml b/pom.xml
index afa475f33bad218e77e5a6f373615409b3eb5d60..e5c61b389ac022e59c3abb3aac1afeb45d384913 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,8 +14,8 @@
<bt.name>git</bt.name>
<minecraft.version>1.16.5</minecraft.version>
<minecraft_version>1_16_R3</minecraft_version>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
+ <maven.compiler.source>15</maven.compiler.source>
+ <maven.compiler.target>15</maven.compiler.target>
</properties>
<parent>

View File

@@ -1,135 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Mon, 10 May 2021 02:50:34 -0400
Subject: [PATCH] Add CraftItemStack#canPlaceOn
diff --git a/src/main/java/net/minecraft/world/item/ItemBlock.java b/src/main/java/net/minecraft/world/item/ItemBlock.java
index 59d52c252b2e59923b8e513dd4d2e1ec9ce34dc7..25326f1124773ca4956a72a9b2998513748f7b85 100644
--- a/src/main/java/net/minecraft/world/item/ItemBlock.java
+++ b/src/main/java/net/minecraft/world/item/ItemBlock.java
@@ -173,6 +173,7 @@ public class ItemBlock extends Item {
}).orElse(iblockdata);
}
+ public boolean canPlaceOn(BlockActionContext blockActionContext, IBlockData iBlockData) {return b(blockActionContext, iBlockData);} // Parchment - OBFHELPER
protected boolean b(BlockActionContext blockactioncontext, IBlockData iblockdata) {
EntityHuman entityhuman = blockactioncontext.getEntity();
VoxelShapeCollision voxelshapecollision = entityhuman == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a((Entity) entityhuman);
diff --git a/src/main/java/net/minecraft/world/item/context/BlockActionContext.java b/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
index 2cb451db6ca23290f700dc428a7622f64fb90b97..1763ada73e4ef422f95eb5c3f42f19d7600261a6 100644
--- a/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
+++ b/src/main/java/net/minecraft/world/item/context/BlockActionContext.java
@@ -24,7 +24,7 @@ public class BlockActionContext extends ItemActionContext {
this(itemactioncontext.getWorld(), itemactioncontext.getEntity(), itemactioncontext.getHand(), itemactioncontext.getItemStack(), itemactioncontext.i());
}
- protected BlockActionContext(World world, @Nullable EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack, MovingObjectPositionBlock movingobjectpositionblock) {
+ public BlockActionContext(World world, @Nullable EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack, MovingObjectPositionBlock movingobjectpositionblock) { // Parchment
super(world, entityhuman, enumhand, itemstack, movingobjectpositionblock);
this.a = true;
this.b = movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection());
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index 09d7a86b5f6cffdf6664ad657dd4f8dd8eabdd70..e709c910e3e9a09c26b44225a0d6c809502e4b67 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
@@ -3,21 +3,41 @@ package org.bukkit.craftbukkit.inventory;
import static org.bukkit.craftbukkit.inventory.CraftMetaItem.*;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
+import me.lexikiq.HasHumanEntity;
+import me.lexikiq.OptionalHumanEntity;
+import net.minecraft.core.EnumDirection;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
+import net.minecraft.world.EnumHand;
+import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.Item;
+import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.EnchantmentManager;
+import net.minecraft.world.item.ItemBlock;
+import net.minecraft.world.item.context.BlockActionContext;
+import net.minecraft.world.phys.MovingObjectPositionBlock;
+import net.minecraft.world.phys.Vec3D;
import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
import org.bukkit.configuration.serialization.DelegateDeserialization;
+import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.util.CraftLegacy;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.MaterialData;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
@DelegateDeserialization(ItemStack.class)
public final class CraftItemStack extends ItemStack {
@@ -105,6 +125,57 @@ public final class CraftItemStack extends ItemStack {
setItemMeta(itemMeta);
}
+ // Parchment start
+ /**
+ * Determines if this item can be placed on a block. Must be run synchronously. Factors in player location,
+ * nearby entities, and more.
+ * @param world world in which the block is being placed
+ * @param _player optional player placing the block
+ * @param block block to check against
+ * @param face cardinal direction
+ * @return if the item can be placed
+ */
+ public boolean canPlaceOn(World world, @Nullable OptionalHumanEntity _player, Block block, BlockFace face) {
+ Validate.notNull(world, "'world' must not be null");
+ Validate.notNull(block, "'block' must not be null");
+ Validate.notNull(face, "'face' must not be null");
+
+ if (block.getType().isEmpty() || block.isLiquid()) return false;
+ HumanEntity player = _player != null ? _player.getPlayer() : null;
+ if (!(world instanceof CraftWorld)) return false;
+ if (!face.isCartesian()) throw new IllegalArgumentException("Face must be cartesian");
+ if (!(block instanceof CraftBlock)) return false;
+ if (player != null && !(player instanceof CraftEntity)) return false;
+ EntityHuman human = player != null ? (EntityHuman) ((CraftEntity) player).getHandle() : null;
+ CraftBlock craftBlock = (CraftBlock) block;
+ CraftBlock relativeBlock = (CraftBlock) block.getRelative(face);
+ if (!relativeBlock.isReplaceable())
+ return false;
+ Location playerLoc = player != null ? player.getLocation() : relativeBlock.getLocation();
+ EnumDirection direction = EnumDirection.valueOf(face.name());
+
+ Item item = handle != null ? handle.getItem() : Items.AIR;
+ if (!(item instanceof ItemBlock)) return false;
+ ItemBlock itemBlock = (ItemBlock) item;
+
+ BlockActionContext context = new BlockActionContext(((CraftWorld) world).getHandle(), human, EnumHand.MAIN_HAND, asNMSCopy(this), new MovingObjectPositionBlock(new Vec3D(playerLoc.getX(), playerLoc.getY(), playerLoc.getZ()), direction, craftBlock.getPosition(), false));
+ return itemBlock.canPlaceOn(context, itemBlock.getBlock().getPlacedState(context));
+ }
+
+ /**
+ * Determines if this item can be placed on a block. Must be run synchronously. Factors in player location,
+ * nearby entities, and more.
+ * @param player player placing the block
+ * @param block block to check against
+ * @param face cardinal direction
+ * @return if the item can be placed
+ */
+ public boolean canPlaceOn(@NotNull HasHumanEntity player, Block block, BlockFace face) {
+ Validate.notNull(player, "'player' must not be null");
+ return canPlaceOn(player.getPlayer().getWorld(), player, block, face);
+ }
+ // Parchment end
+
@Override
public MaterialData getData() {
return handle != null ? CraftMagicNumbers.getMaterialData(handle.getItem()) : super.getData();

View File

@@ -1,124 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Mon, 10 May 2021 22:10:23 -0400
Subject: [PATCH] Add origin location to EntityDamageByBlockEvent
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
index e6bf78f46acc37d9515d58cec3587e236ac0733c..1cea7c5bf99e0c99e8160658df0eab065cca2841 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
@@ -46,6 +46,16 @@ public class DamageSource {
private boolean D;
private boolean E;
public final String translationIndex;
+ // Parchment start
+ private @Nullable org.bukkit.Location location;
+ public @Nullable org.bukkit.Location getLocation() {
+ return location;
+ }
+ public DamageSource location(@Nullable org.bukkit.Location location) {
+ this.location = location;
+ return this;
+ }
+ // Parchment end
// CraftBukkit start
private boolean sweep;
@@ -109,11 +119,11 @@ public class DamageSource {
}
public static DamageSource explosion(@Nullable Explosion explosion) {
- return d(explosion != null ? explosion.getSource() : null);
+ return d(explosion != null ? explosion.getSource() : null).location(explosion != null ? explosion.getBukkitLocation() : null); // Parchment
}
public static DamageSource d(@Nullable EntityLiving entityliving) {
- return entityliving != null ? (new EntityDamageSource("explosion.player", entityliving)).r().setExplosion() : (new DamageSource("explosion")).r().setExplosion();
+ return (entityliving != null ? (new EntityDamageSource("explosion.player", entityliving)) : (new DamageSource("explosion"))).r().setExplosion(); // Parchment
}
public static DamageSource a() {
@@ -234,8 +244,9 @@ public class DamageSource {
return entity instanceof EntityHuman && ((EntityHuman) entity).abilities.canInstantlyBuild;
}
+ public Vec3D getPosition() {return w();} // Parchment - OBFHELPER
@Nullable
public Vec3D w() {
- return null;
+ return location == null ? null : new Vec3D(location.getX(), location.getY(), location.getZ()); // Parchment
}
}
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index 79008bda42558ea7d28ccf51b66405a3bdb52da7..8fd81f4238416fd6a5d09e3307aebe785f8e28e1 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -85,6 +85,13 @@ public class Explosion {
this.l = explosiondamagecalculator == null ? this.a(entity) : explosiondamagecalculator;
}
+ // Parchment start
+ public @Nullable org.bukkit.Location getBukkitLocation() {
+ if (this.world == null) return null;
+ return new org.bukkit.Location(world.getWorld(), posX, posY, posZ);
+ }
+ // Parchment end
+
private ExplosionDamageCalculator a(@Nullable Entity entity) {
return (ExplosionDamageCalculator) (entity == null ? Explosion.a : new ExplosionDamageCalculatorEntity(entity));
}
diff --git a/src/main/java/net/minecraft/world/level/block/BlockBed.java b/src/main/java/net/minecraft/world/level/block/BlockBed.java
index 00a01a157deec004bcf2f8587723a0ecd0bfef85..ece4648bf133621b644291390f5743f9c48c750d 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockBed.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockBed.java
@@ -89,7 +89,12 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
world.a(blockposition1, false);
}
- world.createExplosion((Entity) null, DamageSource.a(), (ExplosionDamageCalculator) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment start
+ double posX = blockposition.getX() + 0.5D;
+ double posY = blockposition.getY() + 0.5D;
+ double posZ = blockposition.getZ() + 0.5D;
+ world.createExplosion((Entity) null, DamageSource.a().location(new org.bukkit.Location(world.getWorld(), posX, posY, posZ)), (ExplosionDamageCalculator) null, posX, posY, posZ, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment end
return EnumInteractionResult.SUCCESS;
} else if ((Boolean) iblockdata.get(BlockBed.OCCUPIED)) {
if (!this.a(world, blockposition)) {
@@ -138,7 +143,12 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
world.a(blockposition1, false);
}
- world.createExplosion((Entity) null, DamageSource.a(), (ExplosionDamageCalculator) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment start
+ double posX = blockposition.getX() + 0.5D;
+ double posY = blockposition.getY() + 0.5D;
+ double posZ = blockposition.getZ() + 0.5D;
+ world.createExplosion((Entity) null, DamageSource.a().location(new org.bukkit.Location(world.getWorld(), posX, posY, posZ)), (ExplosionDamageCalculator) null, posX, posY, posZ, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment end
return EnumInteractionResult.SUCCESS;
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index a678277416cd71e01cd6980bcfaf9a9803e7ea17..0df40bc18dcd66a367b82e435316851eb99d077c 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -941,7 +941,7 @@ public class CraftEventFactory {
entityDamage = null;
EntityDamageEvent event;
if (damager == null) {
- event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions);
+ event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, source.getLocation(), modifiers, modifierFunctions); // Parchment
} else if (entity instanceof EntityEnderDragon && /*PAIL FIXME ((EntityEnderDragon) entity).target == damager*/ false) {
event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions);
} else {
@@ -977,7 +977,7 @@ public class CraftEventFactory {
return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled);
} else if (source == DamageSource.OUT_OF_WORLD) {
- EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions);
+ EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, entity.getBukkitEntity().getLocation(), modifiers, modifierFunctions); // Parchment
event.setCancelled(cancelled);
callEvent(event);
if (!event.isCancelled()) {

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Thu, 13 May 2021 23:52:14 -0400
Subject: [PATCH] Create PlayerUseRespawnAnchorEvent
diff --git a/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java b/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
index 028e98decf8b0496b4ebcd1aad3aa474e5c4e7c1..1a3c66464947e16cc085a20ee1172cc51a3fc2f5 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.UnmodifiableIterator;
import java.util.Optional;
import java.util.stream.Stream;
+import me.lexikiq.event.player.PlayerUseRespawnAnchorEvent;
import net.minecraft.core.BaseBlockPosition;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.EnumDirection;
@@ -37,6 +38,8 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.pathfinder.PathMode;
import net.minecraft.world.phys.MovingObjectPositionBlock;
import net.minecraft.world.phys.Vec3D;
+import org.bukkit.craftbukkit.block.CraftBlock; // Parchment
+import org.bukkit.entity.Player; // Parchment
public class BlockRespawnAnchor extends Block {
@@ -53,6 +56,11 @@ public class BlockRespawnAnchor extends Block {
public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) {
ItemStack itemstack = entityhuman.b(enumhand);
+ // Parchment start -- PlayerUseRespawnAnchorEvent
+ Player player = entityhuman.getBukkitEntity() instanceof Player ? (Player) entityhuman.getBukkitEntity() : null;
+ org.bukkit.block.Block block = CraftBlock.at(world, blockposition);
+ // Parchment end
+
if (enumhand == EnumHand.MAIN_HAND && !a(itemstack) && a(entityhuman.b(EnumHand.OFF_HAND))) {
return EnumInteractionResult.PASS;
} else if (a(itemstack) && h(iblockdata)) {
@@ -61,16 +69,31 @@ public class BlockRespawnAnchor extends Block {
itemstack.subtract(1);
}
+ // Parchment start
+ if (player != null && !(new PlayerUseRespawnAnchorEvent(player, block, PlayerUseRespawnAnchorEvent.RespawnAnchorResult.CHARGE).callEvent()))
+ return EnumInteractionResult.PASS;
+ // Parchment end
+
return EnumInteractionResult.a(world.isClientSide);
} else if ((Integer) iblockdata.get(BlockRespawnAnchor.a) == 0) {
return EnumInteractionResult.PASS;
} else if (!a(world)) {
+ // Parchment start
+ if (player != null && !(new PlayerUseRespawnAnchorEvent(player, block, PlayerUseRespawnAnchorEvent.RespawnAnchorResult.EXPLODE).callEvent()))
+ return EnumInteractionResult.PASS;
+ // Parchment end
+
if (!world.isClientSide) {
this.d(iblockdata, world, blockposition);
}
return EnumInteractionResult.a(world.isClientSide);
} else {
+ // Parchment start
+ if (player != null && !(new PlayerUseRespawnAnchorEvent(player, block, PlayerUseRespawnAnchorEvent.RespawnAnchorResult.SET_SPAWN).callEvent()))
+ return EnumInteractionResult.PASS;
+ // Parchment end
+
if (!world.isClientSide) {
EntityPlayer entityplayer = (EntityPlayer) entityhuman;
@@ -115,7 +138,7 @@ public class BlockRespawnAnchor extends Block {
private void d(IBlockData iblockdata, World world, final BlockPosition blockposition) {
world.a(blockposition, false);
- Stream stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.a();
+ Stream<EnumDirection> stream = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(); // Parchment - Fix deobfuscation error
blockposition.getClass();
boolean flag = stream.map(blockposition::shift).anyMatch((blockposition1) -> {

View File

@@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 14 May 2021 23:41:14 -0400
Subject: [PATCH] Add respawn anchor damage location
diff --git a/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java b/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
index 1a3c66464947e16cc085a20ee1172cc51a3fc2f5..2f921f08de6a349f4582e8471f0f1ff3670f92ed 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockRespawnAnchor.java
@@ -38,6 +38,7 @@ import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.pathfinder.PathMode;
import net.minecraft.world.phys.MovingObjectPositionBlock;
import net.minecraft.world.phys.Vec3D;
+import org.bukkit.Location;
import org.bukkit.craftbukkit.block.CraftBlock; // Parchment
import org.bukkit.entity.Player; // Parchment
@@ -152,7 +153,12 @@ public class BlockRespawnAnchor extends Block {
}
};
- world.createExplosion((Entity) null, DamageSource.a(), explosiondamagecalculator, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment start
+ double posX = blockposition.getX() + 0.5D;
+ double posY = blockposition.getY() + 0.5D;
+ double posZ = blockposition.getZ() + 0.5D;
+ world.createExplosion((Entity) null, DamageSource.a().location(new Location(world.getWorld(), posX, posY, posZ)), explosiondamagecalculator, posX, posY, posZ, 5.0F, true, Explosion.Effect.DESTROY);
+ // Parchment end
}
public static boolean a(World world) {

View File

@@ -1,429 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Wed, 9 Jun 2021 18:39:18 -0400
Subject: [PATCH] Add SoundEvent
diff --git a/src/main/java/net/minecraft/server/commands/CommandPlaySound.java b/src/main/java/net/minecraft/server/commands/CommandPlaySound.java
index f896dd7447d8a8fbc6e3c1abad0c3da5448273c1..2ee039d18ddd98298586f1ace2e6b980cb3061e0 100644
--- a/src/main/java/net/minecraft/server/commands/CommandPlaySound.java
+++ b/src/main/java/net/minecraft/server/commands/CommandPlaySound.java
@@ -15,7 +15,6 @@ import net.minecraft.commands.arguments.ArgumentMinecraftKeyRegistered;
import net.minecraft.commands.arguments.coordinates.ArgumentVec3;
import net.minecraft.commands.synchronization.CompletionProviders;
import net.minecraft.network.chat.ChatMessage;
-import net.minecraft.network.protocol.game.PacketPlayOutCustomSoundEffect;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.sounds.SoundCategory;
@@ -81,7 +80,7 @@ public class CommandPlaySound {
f3 = f2;
}
- entityplayer.playerConnection.sendPacket(new PacketPlayOutCustomSoundEffect(minecraftkey, soundcategory, vec3d1, f3, f1));
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationCustomSoundEvent(entityplayer.getBukkitEntity(), entityplayer.getWorldServer().getWorld(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(vec3d1), org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(minecraftkey), org.bukkit.SoundCategory.valueOf(soundcategory.name()), f3, f1), entityplayer); // Parchment - sound event
++i;
}
diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
index 75bcfb3a2b4a104aeebb2fe3298714b2e5b569d2..703ae4aab9b47415a31245c2be641b6fa41502b7 100644
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
@@ -53,7 +53,6 @@ import net.minecraft.network.protocol.game.PacketPlayOutExperience;
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
import net.minecraft.network.protocol.game.PacketPlayOutLookAt;
import net.minecraft.network.protocol.game.PacketPlayOutNamedEntitySpawn;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutOpenBook;
import net.minecraft.network.protocol.game.PacketPlayOutOpenSignEditor;
import net.minecraft.network.protocol.game.PacketPlayOutOpenWindow;
@@ -2158,7 +2157,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@Override
public void a(SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {
- this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, this.locX(), this.locY(), this.locZ(), f, f1));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(this.getBukkitEntity(), this.getWorld().getWorld(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(this.getPositionVector()), org.bukkit.craftbukkit.CraftSound.getBukkit(soundeffect), org.bukkit.SoundCategory.valueOf(soundcategory.name()), f, f1), this); // Parchment - sound event
}
@Override
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index f68a252378a94c8fcab622d2d89d738aceab45a4..7a290adb13ed083db50f197fc2acf0007f6dd2d2 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -58,11 +58,9 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketDebug;
import net.minecraft.network.protocol.game.PacketPlayOutBlockAction;
import net.minecraft.network.protocol.game.PacketPlayOutBlockBreakAnimation;
-import net.minecraft.network.protocol.game.PacketPlayOutEntitySound;
import net.minecraft.network.protocol.game.PacketPlayOutEntityStatus;
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutSpawnPosition;
import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent;
import net.minecraft.network.protocol.game.PacketPlayOutWorldParticles;
@@ -168,6 +166,10 @@ import org.bukkit.event.server.MapInitializeEvent;
import org.bukkit.event.weather.LightningStrikeEvent;
import org.bukkit.event.world.TimeSkipEvent;
// CraftBukkit end
+// Parchment start
+import org.bukkit.craftbukkit.CraftSound;
+import org.bukkit.util.Vector;
+// Parchment end
public class WorldServer extends World implements GeneratorAccessSeed {
@@ -1663,12 +1665,20 @@ public class WorldServer extends World implements GeneratorAccessSeed {
@Override
public void playSound(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {
- this.server.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.getDimensionKey(), new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, d0, d1, d2, f, f1));
+ // Parchment start
+ CraftEventFactory.playSoundEvent(
+ new me.lexikiq.event.sound.LocationNamedSoundEvent(entityhuman == null ? null : entityhuman.getBukkitEntity(), getWorld(), new org.bukkit.util.Vector(d0, d1, d2), org.bukkit.craftbukkit.CraftSound.getBukkit(soundeffect), org.bukkit.SoundCategory.valueOf(soundcategory.name()), f, f1),
+ this.server, entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this);
+ // Parchment end
}
@Override
public void playSound(@Nullable EntityHuman entityhuman, Entity entity, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {
- this.server.getPlayerList().sendPacketNearby(entityhuman, entity.locX(), entity.locY(), entity.locZ(), f > 1.0F ? (double) (16.0F * f) : 16.0D, this.getDimensionKey(), new PacketPlayOutEntitySound(soundeffect, soundcategory, entity, f, f1));
+ // Parchment start
+ CraftEventFactory.playSoundEvent(
+ new me.lexikiq.event.sound.EntitySoundEvent(entityhuman == null ? null : entityhuman.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.craftbukkit.CraftSound.getBukkit(soundeffect), org.bukkit.SoundCategory.valueOf(soundcategory.name()), f, f1),
+ this.server, entityhuman, entity.locX(), entity.locY(), entity.locZ(), f > 1.0F ? (double) (16.0F * f) : 16.0D, this);
+ // Parchment end
}
@Override
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 90776231b1faffb11e4394f555f336ca248e3004..319226264b341fa04ab264087e243c8b87d8c012 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -43,7 +43,6 @@ import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
import net.minecraft.network.protocol.game.PacketPlayOutHeldItemSlot;
import net.minecraft.network.protocol.game.PacketPlayOutKickDisconnect;
import net.minecraft.network.protocol.game.PacketPlayOutLogin;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo;
import net.minecraft.network.protocol.game.PacketPlayOutRecipeUpdate;
import net.minecraft.network.protocol.game.PacketPlayOutRespawn;
@@ -67,8 +66,6 @@ import net.minecraft.server.level.PlayerInteractManager;
import net.minecraft.server.level.TicketType;
import net.minecraft.server.level.WorldServer;
import net.minecraft.server.network.PlayerConnection;
-import net.minecraft.sounds.SoundCategory;
-import net.minecraft.sounds.SoundEffects;
import net.minecraft.stats.ServerStatisticManager;
import net.minecraft.stats.StatisticList;
import net.minecraft.tags.Tag;
@@ -981,7 +978,7 @@ public abstract class PlayerList {
if (flag2 && !isLocAltered) {
IBlockData data = worldserver1.getType(blockposition);
worldserver1.setTypeAndData(blockposition, data.set(BlockRespawnAnchor.a, data.get(BlockRespawnAnchor.a) - 1), 3);
- entityplayer1.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.BLOCK_RESPAWN_ANCHOR_DEPLETE, SoundCategory.BLOCKS, (double) location.getX(), (double) location.getY(), (double) location.getZ(), 1.0F, 1.0F));
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(entityplayer1.getBukkitEntity(), entityplayer1.getWorld().getWorld(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(entityplayer1.getPositionVector()), org.bukkit.Sound.BLOCK_RESPAWN_ANCHOR_DEPLETE, org.bukkit.SoundCategory.BLOCKS, 1.0F, 1.0F), entityplayer1); // Parchment - sound event
// Paper end
}
// Added from changeDimension
diff --git a/src/main/java/net/minecraft/world/entity/EntityLightning.java b/src/main/java/net/minecraft/world/entity/EntityLightning.java
index 85f571a791bce63989890f277857bc7bdeec0cb5..fb7feb22c964cc6f2cfafa84ef3068d35d56cb04 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLightning.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLightning.java
@@ -12,9 +12,7 @@ import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.WorldServer;
import net.minecraft.sounds.SoundCategory;
-import net.minecraft.sounds.SoundEffects;
import net.minecraft.world.EnumDifficulty;
-import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.IBlockAccess;
import net.minecraft.world.level.World;
@@ -23,9 +21,13 @@ import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.phys.AxisAlignedBB;
// CraftBukkit start
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import org.bukkit.craftbukkit.event.CraftEventFactory;
// CraftBukkit end
+// Parchment start
+import org.bukkit.Sound;
+import org.bukkit.util.Vector;
+import me.lexikiq.event.sound.LocationNamedSoundEvent;
+// Parchment end
public class EntityLightning extends Entity {
@@ -88,8 +90,7 @@ public class EntityLightning extends Entity {
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
// Paper start - Limit lightning strike effect distance
if (distanceSquared <= this.world.paperConfig.sqrMaxLightningImpactSoundDistance) {
- player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT,
- SoundCategory.WEATHER, this.locX(), this.locY(), this.locZ(), 2.0f, 0.5F + this.random.nextFloat() * 0.2F));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(player.getBukkitEntity(), world.getWorld(), new org.bukkit.util.Vector(this.locX(), this.locY(), this.locZ()), org.bukkit.Sound.ENTITY_LIGHTNING_BOLT_IMPACT, org.bukkit.SoundCategory.WEATHER, 2f, 0.5F + this.random.nextFloat() * 0.2F), player); // Parchment - sound event
}
if (world.paperConfig.sqrMaxThunderDistance != -1 && distanceSquared >= world.paperConfig.sqrMaxThunderDistance) {
@@ -97,14 +98,14 @@ public class EntityLightning extends Entity {
}
// Paper end
+ double relativeX = this.locX(); // Parchment - sound event
+ double relativeZ = this.locZ(); // Parchment - sound event
if (distanceSquared > viewDistance * viewDistance) {
double deltaLength = Math.sqrt(distanceSquared);
- double relativeX = player.locX() + (deltaX / deltaLength) * viewDistance;
- double relativeZ = player.locZ() + (deltaZ / deltaLength) * viewDistance;
- player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, relativeX, this.locY(), relativeZ, 10000.0F, pitch));
- } else {
- player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, this.locX(), this.locY(), this.locZ(), 10000.0F, pitch));
+ relativeX = player.locX() + (deltaX / deltaLength) * viewDistance; // Parchment - sound event
+ relativeZ = player.locZ() + (deltaZ / deltaLength) * viewDistance; // Parchment - sound event
}
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(player.getBukkitEntity(), world.getWorld(), new org.bukkit.util.Vector(relativeX, this.locY(), relativeZ), org.bukkit.Sound.ENTITY_LIGHTNING_BOLT_THUNDER, org.bukkit.SoundCategory.WEATHER, 10000.0F, pitch), player); // Parchment - sound event
}
// CraftBukkit end
// this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F); // Paper - Limit lightning strike effect distance (the packet is now sent from inside the loop)
diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
index c39c50e53549e9cb9d3520bc7e8b7e89cfa20163..9c344b510bca742f31911fddeeb7c947c335e2e8 100644
--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
+++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
@@ -28,7 +28,6 @@ import net.minecraft.network.chat.ChatMessage;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.chat.IChatMutableComponent;
import net.minecraft.network.protocol.game.PacketPlayOutEntityVelocity;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.network.syncher.DataWatcherRegistry;
@@ -1755,7 +1754,7 @@ public abstract class EntityHuman extends EntityLiving {
private static void sendSoundEffect(EntityHuman fromEntity, double x, double y, double z, SoundEffect soundEffect, SoundCategory soundCategory, float volume, float pitch) {
fromEntity.world.playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
if (fromEntity instanceof EntityPlayer) {
- ((EntityPlayer) fromEntity).playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(soundEffect, soundCategory, x, y, z, volume, pitch));
+ CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(((EntityPlayer) fromEntity).getBukkitEntity(), fromEntity.getWorld().getWorld(), new org.bukkit.util.Vector(x, y, z), org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect), org.bukkit.SoundCategory.valueOf(soundCategory.name()), volume, pitch), ((EntityPlayer) fromEntity)); // Parchment - sound event
}
}
// Paper end
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index 457cbdab3fa96fdf7fad1b0206bec9c0aa7847d8..44d7231bb9901b84a1363e8bbbdf993d74f1744a 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -26,12 +26,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.chat.ChatMessage;
import net.minecraft.network.chat.IChatBaseComponent;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.server.level.BossBattleServer;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.WorldServer;
-import net.minecraft.sounds.SoundCategory;
-import net.minecraft.sounds.SoundEffects;
import net.minecraft.stats.StatisticList;
import net.minecraft.util.MathHelper;
import net.minecraft.world.BossBattle;
@@ -495,7 +492,7 @@ public class Raid {
double d1 = vec3d.z + (double) (13.0F / f1) * (vec3d1.z - vec3d.z);
if (f1 <= 64.0F || collection.contains(entityplayer)) {
- entityplayer.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.EVENT_RAID_HORN, SoundCategory.NEUTRAL, d0, entityplayer.locY(), d1, 64.0F, 1.0F));
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(entityplayer.getBukkitEntity(), world.getWorld(), new org.bukkit.util.Vector(d0, entityplayer.locY(), d1), org.bukkit.Sound.EVENT_RAID_HORN, org.bukkit.SoundCategory.NEUTRAL, 64.0F, 1.0F), entityplayer); // Parchment - sound event
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index c0b49a0eaeda06b89a4fb425eec3d5bfa9717379..21891dad5b799ef4dbebbd47487ddf7b366ed937 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -26,10 +26,8 @@ import net.minecraft.core.BlockPosition;
import net.minecraft.core.EnumDirection;
import net.minecraft.core.IRegistry;
import net.minecraft.data.worldgen.BiomeDecoratorGroups;
-import net.minecraft.network.protocol.game.PacketPlayOutCustomSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateTime;
import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent;
-import net.minecraft.resources.MinecraftKey;
import net.minecraft.server.MCUtil;
import net.minecraft.server.level.ChunkMapDistance;
import net.minecraft.server.level.PlayerChunk;
@@ -2326,8 +2324,11 @@ public class CraftWorld implements World {
double y = loc.getY();
double z = loc.getZ();
- PacketPlayOutCustomSoundEffect packet = new PacketPlayOutCustomSoundEffect(new MinecraftKey(sound), SoundCategory.valueOf(category.name()), new Vec3D(x, y, z), volume, pitch);
- world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world.getDimensionKey(), packet);
+ // Parchment start
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(
+ new me.lexikiq.event.sound.LocationCustomSoundEvent(null, this, new Vector(x, y, z), org.bukkit.craftbukkit.util.CraftNamespacedKey.fromString(sound), category, volume, pitch),
+ world.getMinecraftServer(), null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, world);
+ // Parchment end
}
private static Map<String, GameRules.GameRuleKey<?>> gamerules;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index cfe6898dc373fe55a08acf5c90e200061aa7d0fc..e43fe61c298acdb346beac81003b8591d11eddc7 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -41,10 +41,8 @@ import net.minecraft.network.protocol.game.PacketPlayOutBlockBreakAnimation;
import net.minecraft.network.protocol.game.PacketPlayOutBlockChange;
import net.minecraft.network.protocol.game.PacketPlayOutChat;
import net.minecraft.network.protocol.game.PacketPlayOutCustomPayload;
-import net.minecraft.network.protocol.game.PacketPlayOutCustomSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutExperience;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
-import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
import net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo;
import net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter;
import net.minecraft.network.protocol.game.PacketPlayOutSpawnPosition;
@@ -582,7 +580,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
float f = (float) Math.pow(2.0D, (note - 12.0D) / 12.0D);
- getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(CraftSound.getSoundEffect("block.note_block." + instrumentName), net.minecraft.sounds.SoundCategory.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f));
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(this, getWorld(), new org.bukkit.util.Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), Sound.valueOf("BLOCK_NOTE_BLOCK_" + instrumentName.toUpperCase()), org.bukkit.SoundCategory.RECORDS, 3f, f), this); // Parchment - sound event
}
@Override
@@ -644,7 +642,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
break;
}
float f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D);
- getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(CraftSound.getSoundEffect("block.note_block." + instrumentName), net.minecraft.sounds.SoundCategory.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f));
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(this, getWorld(), new org.bukkit.util.Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), Sound.valueOf("BLOCK_NOTE_BLOCK_" + instrumentName.toUpperCase()), org.bukkit.SoundCategory.RECORDS, 3f, f), this); // Parchment - sound event
}
@Override
@@ -660,17 +658,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void playSound(Location loc, Sound sound, org.bukkit.SoundCategory category, float volume, float pitch) {
if (loc == null || sound == null || category == null || getHandle().playerConnection == null) return;
-
- PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(CraftSound.getSoundEffect(sound), net.minecraft.sounds.SoundCategory.valueOf(category.name()), loc.getX(), loc.getY(), loc.getZ(), volume, pitch);
- getHandle().playerConnection.sendPacket(packet);
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationNamedSoundEvent(this, getWorld(), loc.toVector(), sound, category, volume, pitch), this); // Parchment - sound event
}
@Override
public void playSound(Location loc, String sound, org.bukkit.SoundCategory category, float volume, float pitch) {
if (loc == null || sound == null || category == null || getHandle().playerConnection == null) return;
-
- PacketPlayOutCustomSoundEffect packet = new PacketPlayOutCustomSoundEffect(new MinecraftKey(sound), net.minecraft.sounds.SoundCategory.valueOf(category.name()), new Vec3D(loc.getX(), loc.getY(), loc.getZ()), volume, pitch);
- getHandle().playerConnection.sendPacket(packet);
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(new me.lexikiq.event.sound.LocationCustomSoundEvent(this, getWorld(), loc.toVector(), CraftNamespacedKey.fromString(sound), category, volume, pitch), this); // Parchment - sound event
}
@Override
@@ -2216,11 +2210,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void playSound(final net.kyori.adventure.sound.Sound sound, final double x, final double y, final double z) {
final MinecraftKey name = io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.name());
final java.util.Optional<net.minecraft.sounds.SoundEffect> event = net.minecraft.core.IRegistry.SOUND_EVENT.getOptional(name);
+ // Parchment start
+ me.lexikiq.event.sound.SoundEvent soundEvent;
+ org.bukkit.util.Vector pos = new org.bukkit.util.Vector(x, y, z);
+ org.bukkit.SoundCategory category = org.bukkit.SoundCategory.valueOf(io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.source()).name());
if (event.isPresent()) {
- this.getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(event.get(), io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.source()), x, y, z, sound.volume(), sound.pitch()));
+ soundEvent = new me.lexikiq.event.sound.LocationNamedSoundEvent(this, getWorld(), pos, CraftSound.getBukkit(event.get()), category, sound.volume(), sound.pitch());
} else {
- this.getHandle().playerConnection.sendPacket(new PacketPlayOutCustomSoundEffect(name, io.papermc.paper.adventure.PaperAdventure.asVanilla(sound.source()), new Vec3D(x, y, z), sound.volume(), sound.pitch()));
+ soundEvent = new me.lexikiq.event.sound.LocationCustomSoundEvent(this, getWorld(), pos, CraftNamespacedKey.fromMinecraft(name), category, sound.volume(), sound.pitch());
}
+ org.bukkit.craftbukkit.event.CraftEventFactory.playSoundEvent(soundEvent, this);
+ // Parchment end
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 0df40bc18dcd66a367b82e435316851eb99d077c..375a51ce14fe0bd4ed0dac6f65167e9124307af1 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -231,6 +231,18 @@ import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.event.entity.SpawnerSpawnEvent; // Spigot
+// Parchment start
+import org.bukkit.util.Vector;
+import org.bukkit.craftbukkit.util.CraftVector;
+import org.bukkit.craftbukkit.CraftSound;
+import net.minecraft.network.protocol.game.PacketPlayOutCustomSoundEffect;
+import net.minecraft.network.protocol.game.PacketPlayOutEntitySound;
+import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect;
+import me.lexikiq.event.sound.EntitySoundEvent;
+import me.lexikiq.event.sound.LocationCustomSoundEvent;
+import me.lexikiq.event.sound.LocationNamedSoundEvent;
+import me.lexikiq.event.sound.SoundEvent;
+// Parchment end
public class CraftEventFactory {
public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN);
@@ -1841,4 +1853,69 @@ public class CraftEventFactory {
return event.callEvent();
}
// Paper end
+
+ // Parchment start
+ private static net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.PacketListenerPlayOut> handleSoundEvent(SoundEvent _event) {
+ if (!_event.callEvent())
+ return null;
+ else {
+ float volume = _event.getVolume();
+ float pitch = _event.getPitch();
+ if (_event instanceof LocationNamedSoundEvent) {
+ LocationNamedSoundEvent event = (LocationNamedSoundEvent) _event;
+ Vector pos = event.getVector();
+ return new PacketPlayOutNamedSoundEffect(CraftSound.getSoundEffect(event.getSound()), SoundCategory.valueOf(event.getCategory().name()), pos.getX(), pos.getY(), pos.getZ(), volume, pitch);
+ } else if (_event instanceof LocationCustomSoundEvent) {
+ LocationCustomSoundEvent event = (LocationCustomSoundEvent) _event;
+ Vector pos = event.getVector();
+ return new PacketPlayOutCustomSoundEffect(CraftNamespacedKey.toMinecraft(event.getKey()), SoundCategory.valueOf(event.getCategory().name()), CraftVector.toNMS(pos), volume, pitch);
+ } else { // EntitySoundEvent
+ EntitySoundEvent event = (EntitySoundEvent) _event;
+ return new PacketPlayOutEntitySound(CraftSound.getSoundEffect(event.getSound()), SoundCategory.valueOf(event.getCategory().name()), ((CraftEntity) event.getOrigin()).getHandle(), volume, pitch);
+ }
+ }
+ }
+
+ public static void playSoundEvent(SoundEvent event, java.util.function.Consumer<net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.PacketListenerPlayOut>> soundPlayer) {
+ org.apache.commons.lang.Validate.notNull(event, "Sound event cannot be null");
+ org.apache.commons.lang.Validate.notNull(soundPlayer, "Sound packet consumer cannot be null");
+
+ if (!(event instanceof LocationNamedSoundEvent || event instanceof LocationCustomSoundEvent || event instanceof EntitySoundEvent))
+ throw new IllegalArgumentException("Unknown sound event: " + event.getClass().getName());
+
+ java.util.concurrent.ThreadPoolExecutor executor = net.minecraft.server.MCUtil.asyncExecutor;
+ java.util.concurrent.CompletableFuture.supplyAsync(() -> handleSoundEvent(event), executor).thenAcceptAsync(packet -> {
+ if (packet != null)
+ soundPlayer.accept(packet);
+ }, executor);
+ }
+
+ public static void playSoundEvent(SoundEvent event, CraftPlayer sendTo) {
+ playSoundEvent(event, sendTo.getHandle());
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.level.EntityPlayer sendTo) {
+ playSoundEvent(event, sendTo.playerConnection);
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.network.PlayerConnection sendTo) {
+ playSoundEvent(event, sendTo::sendPacket);
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.MinecraftServer server, @Nullable EntityHuman human, double x, double y, double z, double radius, World world) {
+ playSoundEvent(event, server, human, x, y, z, radius, world.getDimensionKey());
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.MinecraftServer server, @Nullable EntityHuman human, double x, double y, double z, double radius, net.minecraft.resources.ResourceKey<World> world) {
+ playSoundEvent(event, server.getPlayerList(), human, x, y, z, radius, world);
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.players.PlayerList playerList, @Nullable EntityHuman human, double x, double y, double z, double radius, World world) {
+ playSoundEvent(event, playerList, human, x, y, z, radius, world.getDimensionKey());
+ }
+
+ public static void playSoundEvent(SoundEvent event, net.minecraft.server.players.PlayerList playerList, @Nullable EntityHuman human, double x, double y, double z, double radius, net.minecraft.resources.ResourceKey<World> world) {
+ playSoundEvent(event, packet -> playerList.sendPacketNearby(human, x, y, z, radius, world, packet));
+ }
+ // Parchment end
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,206 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 19 Jun 2021 16:30:39 -0400
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 f893d8ab74293feec6ef69c5a4ddec57b11ca751..d6dbd903316ec16088ce7022b173285cd2fe80cd 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -55,8 +55,8 @@ import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
import net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
+//import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket; // Parchment
+//import net.minecraft.network.protocol.game.ClientboundSoundPacket; // Parchment
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MCUtil;
@@ -1335,12 +1335,12 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
@Override
public void playSound(@Nullable Player player, double x, double y, double z, SoundEvent sound, SoundSource category, float volume, float pitch) {
- this.server.getPlayerList().broadcast(player, 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(player == null ? null : player.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
}
@Override
public void playSound(@Nullable Player player, Entity entity, SoundEvent sound, SoundSource category, float volume, float pitch) {
- this.server.getPlayerList().broadcast(player, 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(player == null ? null : player.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
}
@Override
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 53f6a45a505725c81ab15bd2daa1c61b024f1d68..bbe27b5334578e547eefd8eaca3d2ce23d3ff854 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -67,7 +67,7 @@ import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
import net.minecraft.network.protocol.game.ClientboundSetCameraPacket;
import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket;
import net.minecraft.network.protocol.game.ClientboundSetHealthPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
+//import net.minecraft.network.protocol.game.ClientboundSoundPacket; // Parchment
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.network.protocol.game.ServerboundClientInformationPacket;
import net.minecraft.resources.ResourceKey;
@@ -2134,7 +2134,7 @@ 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
}
@Override
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index bc3fe18dd32da2d381b9546aae675a475c073696..fae458c2ec53e8663536c183d2487a2a6041d24e 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -58,7 +58,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
+//import net.minecraft.network.protocol.game.ClientboundSoundPacket; // Parchment
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket;
@@ -951,7 +951,7 @@ public abstract class PlayerList {
if (flag2 && !isLocAltered) {
BlockState data = worldserver1.getBlockState(blockposition);
worldserver1.setBlock(blockposition, data.setValue(RespawnAnchorBlock.CHARGE, data.getValue(RespawnAnchorBlock.CHARGE) - 1), 3);
- entityplayer1.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) location.getX(), (double) location.getY(), (double) location.getZ(), 1.0F, 1.0F));
+ entityplayer1.playNotifySound(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, 1.0F, 1.0F); // Parchment
// Paper end
}
// 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 d286d88a3c3f93dbfa92de9421e320c92cd96350..eea377ccf09afd2c175041bdd8226e1009fe6914 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -30,7 +30,7 @@ import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
+//import net.minecraft.network.protocol.game.ClientboundSoundPacket; // Parchment
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
@@ -1824,7 +1824,7 @@ 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
}
}
// Paper end
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index a79ba23ecf887ecbb6e095140f019ebb6fd0a6f7..5112edc5e68a386e9bb16ac0ec9d998e7df06f3c 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -27,7 +27,7 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
+//import net.minecraft.network.protocol.game.ClientboundSoundPacket; // Parchment
import net.minecraft.server.level.ServerBossEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -537,7 +537,7 @@ public class Raid {
double d2 = vec3d.z + 13.0D / d0 * (vec3d1.z - vec3d.z);
if (d0 <= 64.0D || collection.contains(entityplayer)) {
- entityplayer.connection.send(new ClientboundSoundPacket(SoundEvents.RAID_HORN, SoundSource.NEUTRAL, d1, entityplayer.getY(), d2, 64.0F, 1.0F));
+ entityplayer.playNotifySound(SoundEvents.RAID_HORN, SoundSource.NEUTRAL, 64.0F, 1.0F); // Parchment
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 71571868090062f02579d50ae483d9f367de5016..e94fc60cd34678d7ce052e70728040f9999a9d00 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1835,4 +1835,77 @@ public class CraftEventFactory {
return event.callEvent();
}
// Paper end
+
+ // Parchment start
+ private static net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.ClientGamePacketListener> 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());
+
+ 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);
+ }
+ }
+ }
+
+ public static void playSoundEvent(me.lexikiq.event.sound.SoundEvent event, java.util.function.Consumer<net.minecraft.network.protocol.Packet<net.minecraft.network.protocol.game.ClientGamePacketListener>> soundPlayer) {
+ 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 -> {
+ if (packet != null)
+ soundPlayer.accept(packet);
+ }, 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<Level> 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
}

View File

@@ -0,0 +1,86 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Sat, 19 Jun 2021 01:14:13 -0400
Subject: [PATCH] Add PlayerUseRespawnAnchorEvent
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index af4eb4a8814491afef449a2874521636957d7557..93fae52a7531e1697e4fa63c82aef6ef24d0fb25 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import java.util.Optional;
import java.util.Random;
+import me.lexikiq.event.player.PlayerUseRespawnAnchorEvent; // Parchment
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
@@ -52,33 +53,51 @@ public class RespawnAnchorBlock extends Block {
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
ItemStack itemStack = player.getItemInHand(hand);
+
+ // Parchment start -- PlayerUseRespawnAnchorEvent
+ org.bukkit.entity.Player bukkitPlayer = player.getBukkitEntity() instanceof org.bukkit.entity.Player ? (org.bukkit.entity.Player) player.getBukkitEntity() : null;
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
+ PlayerUseRespawnAnchorEvent.RespawnAnchorResult result;
if (hand == InteractionHand.MAIN_HAND && !isRespawnFuel(itemStack) && isRespawnFuel(player.getItemInHand(InteractionHand.OFF_HAND))) {
return InteractionResult.PASS;
} else if (isRespawnFuel(itemStack) && canBeCharged(state)) {
+ result = PlayerUseRespawnAnchorEvent.RespawnAnchorResult.CHARGE;
+ } else if (state.getValue(CHARGE) == 0) {
+ result = PlayerUseRespawnAnchorEvent.RespawnAnchorResult.NOTHING;
+ } else if (!canSetSpawn(world) && !world.isClientSide) {
+ result = PlayerUseRespawnAnchorEvent.RespawnAnchorResult.EXPLODE;
+ } else if (!world.isClientSide) {
+ result = PlayerUseRespawnAnchorEvent.RespawnAnchorResult.SET_SPAWN;
+ } else {
+ return InteractionResult.SUCCESS;
+ }
+
+ if (bukkitPlayer != null) {
+ PlayerUseRespawnAnchorEvent event = new PlayerUseRespawnAnchorEvent(bukkitPlayer, block, result);
+ event.callEvent();
+ result = event.getResult();
+ }
+
+ if (result == PlayerUseRespawnAnchorEvent.RespawnAnchorResult.NOTHING) {
+ return InteractionResult.PASS;
+ } else if (result == PlayerUseRespawnAnchorEvent.RespawnAnchorResult.CHARGE) {
charge(world, pos, state);
if (!player.getAbilities().instabuild) {
itemStack.shrink(1);
}
return InteractionResult.sidedSuccess(world.isClientSide);
- } else if (state.getValue(CHARGE) == 0) {
- return InteractionResult.PASS;
- } else if (!canSetSpawn(world)) {
- if (!world.isClientSide) {
- this.explode(state, world, pos);
- }
-
- return InteractionResult.sidedSuccess(world.isClientSide);
+ } else if (result == PlayerUseRespawnAnchorEvent.RespawnAnchorResult.EXPLODE) {
+ this.explode(state, world, pos);
+ return InteractionResult.CONSUME;
} else {
- if (!world.isClientSide) {
- ServerPlayer serverPlayer = (ServerPlayer)player;
- if (serverPlayer.getRespawnDimension() != world.dimension() || !pos.equals(serverPlayer.getRespawnPosition())) {
- serverPlayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true);
- world.playSound((Player)null, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
- return InteractionResult.SUCCESS;
- }
+ ServerPlayer serverPlayer = (ServerPlayer)player;
+ if (serverPlayer.getRespawnDimension() != world.dimension() || !pos.equals(serverPlayer.getRespawnPosition())) {
+ serverPlayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true);
+ world.playSound((Player)null, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
+ return InteractionResult.SUCCESS;
}
-
+ // Parchment end
return InteractionResult.CONSUME;
}
}

View File

@@ -0,0 +1,178 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 18 Jun 2021 14:04:39 -0400
Subject: [PATCH] Add origin location to EntityDamageByBlockEvent
diff --git a/src/main/java/net/minecraft/world/damagesource/BadRespawnPointDamage.java b/src/main/java/net/minecraft/world/damagesource/BadRespawnPointDamage.java
index f5a18fb39eb69b2a9842d3f96aa1cd6a8dff6d9b..456d93305f524da6142bad320edb817b27c6c1e6 100644
--- a/src/main/java/net/minecraft/world/damagesource/BadRespawnPointDamage.java
+++ b/src/main/java/net/minecraft/world/damagesource/BadRespawnPointDamage.java
@@ -9,12 +9,20 @@ import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.LivingEntity;
public class BadRespawnPointDamage extends DamageSource {
+ @Deprecated // Parchment
protected BadRespawnPointDamage() {
super("badRespawnPoint");
this.setScalesWithDifficulty();
this.setExplosion();
}
+ // Parchment start
+ protected BadRespawnPointDamage(org.bukkit.Location location) {
+ this();
+ location(location);
+ }
+ // Parchment end
+
@Override
public Component getLocalizedDeathMessage(LivingEntity entity) {
Component component = ComponentUtils.wrapInSquareBrackets(new TranslatableComponent("death.attack.badRespawnPoint.link")).withStyle((style) -> {
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
index 80d19af2ad423bd3de0e039c5bb8f97af536aaa9..2cafb9edf4020c0b8d747dbb4ff91d7759bcd8c3 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
@@ -64,6 +64,18 @@ public class DamageSource {
return this;
}
// CraftBukkit end
+ // Parchment start
+ private @Nullable org.bukkit.Location location;
+
+ public @Nullable org.bukkit.Location getLocation() {
+ return location;
+ }
+
+ public DamageSource location(@Nullable org.bukkit.Location location) {
+ this.location = location;
+ return this;
+ }
+ // Parchment end
public static DamageSource sting(LivingEntity attacker) {
return new EntityDamageSource("sting", attacker);
@@ -114,17 +126,24 @@ public class DamageSource {
}
public static DamageSource explosion(@Nullable Explosion explosion) {
- return DamageSource.explosion(explosion != null ? explosion.getSourceMob() : null);
+ return DamageSource.explosion(explosion != null ? explosion.getSourceMob() : null).location(explosion != null ? explosion.getBukkitLocation() : null); // Parchment
}
public static DamageSource explosion(@Nullable LivingEntity attacker) {
return attacker != null ? (new EntityDamageSource("explosion.player", attacker)).setScalesWithDifficulty().setExplosion() : (new DamageSource("explosion")).setScalesWithDifficulty().setExplosion();
}
+ @Deprecated // Parchment
public static DamageSource badRespawnPointExplosion() {
return new BadRespawnPointDamage();
}
+ // Parchment start
+ public static DamageSource badRespawnPointExplosion(org.bukkit.Location location) {
+ return new BadRespawnPointDamage(location);
+ }
+ // Parchment end
+
public String toString() {
return "DamageSource (" + this.msgId + ")";
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index c98202092752a9015aaf95bd1471135b88e84425..3acdb4d8ab90af1919a190502d6295559c78e041 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -101,10 +101,11 @@ public class EnderDragon extends Mob implements Enemy {
private final Node[] nodes = new Node[24];
private final int[] nodeAdjacency = new int[24];
private final BinaryHeap openSet = new BinaryHeap();
- private Explosion explosionSource = new Explosion(null, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
+ private Explosion explosionSource; // Parchment - moved into constructor to fix null world
public EnderDragon(EntityType<? extends EnderDragon> entitytypes, Level world) {
super(EntityType.ENDER_DRAGON, world);
+ explosionSource = new Explosion(world, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() // Parchment - fix null world
this.subEntities = new EnderDragonPart[]{this.head, this.neck, this.body, this.tail1, this.tail2, this.tail3, this.wing1, this.wing2};
this.setHealth(this.getMaxHealth());
this.noPhysics = true;
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index 822a8dbfaea0a312c4eb2849f2386ecd401b13e9..e5632b4e763076730768fd627610ccdb90be7137 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -453,6 +453,13 @@ public class Explosion {
return this.toBlow;
}
+ // Parchment start
+ public @Nullable Location getBukkitLocation() {
+ if (this.level == null) return null;
+ return new Location(level.getWorld(), x, y, z);
+ }
+ // Parchment end
+
public static enum BlockInteraction {
NONE, BREAK, DESTROY;
diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
index 163a7861f987c3832aac51cc6df950c768546731..1bd2d982569c6cd8a65f1f4c58d41a0e4a14e686 100644
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
@@ -146,7 +146,10 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
world.removeBlock(blockposition1, false);
}
- world.explode((Entity) null, DamageSource.badRespawnPointExplosion(), (ExplosionDamageCalculator) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY);
+ // Parchment start
+ org.bukkit.Location location = new org.bukkit.Location(world.getWorld(), blockposition.getX() + 0.5D, blockposition.getY() + 0.5D, blockposition.getZ() + 0.5D);
+ world.explode((Entity) null, DamageSource.badRespawnPointExplosion(location), (ExplosionDamageCalculator) null, location.getX(), location.getY(), location.getZ(), 5.0F, true, Explosion.BlockInteraction.DESTROY);
+ // Parchment end
return InteractionResult.SUCCESS;
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index 93fae52a7531e1697e4fa63c82aef6ef24d0fb25..2620b42f7a6088aaecf3ccf8f05c5f4d5a4038f0 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -139,7 +139,10 @@ public class RespawnAnchorBlock extends Block {
return pos.equals(explodedPos) && bl2 ? Optional.of(Blocks.WATER.getExplosionResistance()) : super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState);
}
};
- world.explode((Entity)null, DamageSource.badRespawnPointExplosion(), explosionDamageCalculator, (double)explodedPos.getX() + 0.5D, (double)explodedPos.getY() + 0.5D, (double)explodedPos.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY);
+ // Parchment start
+ org.bukkit.Location location = new org.bukkit.Location(world.getWorld(), explodedPos.getX() + 0.5D, explodedPos.getY() + 0.5D, explodedPos.getZ() + 0.5D);
+ world.explode((Entity)null, DamageSource.badRespawnPointExplosion(location), explosionDamageCalculator, location.getX(), location.getY(), location.getZ(), 5.0F, true, Explosion.BlockInteraction.DESTROY);
+ // Parchment end
}
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 e94fc60cd34678d7ce052e70728040f9999a9d00..5f5836c69ad437c3fc801dab032aa0c27d76b71e 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -934,7 +934,7 @@ public class CraftEventFactory {
CraftEventFactory.entityDamage = null;
EntityDamageEvent event;
if (damager == null) {
- event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions);
+ event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, source.getLocation(), modifiers, modifierFunctions); // Parchment - add location
} else if (entity instanceof EnderDragon && /*PAIL FIXME ((EntityEnderDragon) entity).target == damager*/ false) {
event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions);
} else {
@@ -970,7 +970,7 @@ public class CraftEventFactory {
return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled);
} else if (source == DamageSource.OUT_OF_WORLD) {
- EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions);
+ EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, entity.getBukkitEntity().getLocation(), modifiers, modifierFunctions); // Parchment
event.setCancelled(cancelled);
CraftEventFactory.callEvent(event);
if (!event.isCancelled()) {
@@ -978,7 +978,7 @@ public class CraftEventFactory {
}
return event;
} else if (source == DamageSource.LAVA) {
- EntityDamageEvent event = (new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions));
+ EntityDamageEvent event = (new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, entity.getBukkitEntity().getLocation().toBlockLocation(), modifiers, modifierFunctions)); // Parchment
event.setCancelled(cancelled);
CraftEventFactory.callEvent(event);
if (!event.isCancelled()) {

View File

@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lexikiq <noellekiq@gmail.com>
Date: Fri, 18 Jun 2021 03:18:47 -0400
Subject: [PATCH] Add UnsafeValues#canPlaceItemOn
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index a2a62bfb747994c43b8b0b607af90d3be2836873..57ccac39c2c8b8a5c6d9a317ab514b337f7491ef 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -512,6 +512,55 @@ public final class CraftMagicNumbers implements UnsafeValues {
}
// Paper end
+ // Parchment start
+ @Override
+ public java.util.concurrent.CompletableFuture<Boolean> canPlaceItemOn(ItemStack item, me.lexikiq.OptionalHumanEntity player, org.bukkit.block.Block block, org.bukkit.block.BlockFace face) {
+ org.apache.commons.lang3.Validate.notNull(item, "item");
+ org.apache.commons.lang3.Validate.notNull(block, "block");
+ org.apache.commons.lang3.Validate.notNull(face, "face");
+ org.bukkit.entity.HumanEntity human = player == null ? null : player.getPlayer();
+ java.util.concurrent.CompletableFuture<Boolean> future = new java.util.concurrent.CompletableFuture<>();
+ if (block.getType().isEmpty() || block.isLiquid()) {
+ future.complete(false);
+ return future;
+ } else if (!face.isCartesian()) {
+ throw new IllegalArgumentException("face must be cartesian");
+ }
+
+
+ net.minecraft.world.entity.player.Player nmsPlayer = human == null ? null : ((org.bukkit.craftbukkit.entity.CraftHumanEntity) human).getHandle();
+ CraftBlock cBlock = (CraftBlock) block;
+ CraftBlock relativeBlock = (CraftBlock) block.getRelative(face);
+ if (!relativeBlock.isReplaceable()) {
+ future.complete(false);
+ return future;
+ }
+
+ org.bukkit.Location playerLoc = human != null ? human.getLocation() : relativeBlock.getLocation();
+ net.minecraft.core.Direction dir = net.minecraft.core.Direction.valueOf(face.name());
+ net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
+ Item nmsItem = nmsStack.getItem();
+ if (!(nmsItem instanceof net.minecraft.world.item.BlockItem blockItem)) {
+ future.complete(false);
+ return future;
+ }
+
+ net.minecraft.world.item.context.BlockPlaceContext context = new net.minecraft.world.item.context.BlockPlaceContext(new net.minecraft.world.item.context.UseOnContext(cBlock.getCraftWorld().getHandle(), nmsPlayer, net.minecraft.world.InteractionHand.MAIN_HAND, nmsStack, new net.minecraft.world.phys.BlockHitResult(CraftVector.toNMS(playerLoc.toVector()), dir, cBlock.getPosition(), false)));
+ context = blockItem.updatePlacementContext(context);
+ if (context == null) {
+ future.complete(false);
+ return future;
+ }
+ BlockState blockState = blockItem.getBlock().getStateForPlacement(context);
+ if (blockState == null) {
+ future.complete(false);
+ return future;
+ }
+ final net.minecraft.world.item.context.BlockPlaceContext ctx = context;
+ return future.completeAsync(() -> blockItem.canPlace(ctx, blockState), net.minecraft.server.MCUtil.MAIN_EXECUTOR);
+ }
+ // Parchment end
+
/**
* This helper class represents the different NBT Tags.
* <p>