More more more more more more work
This commit is contained in:
parent
6f3591fd6d
commit
105034367d
110 changed files with 252 additions and 246 deletions
|
@ -22,15 +22,16 @@ index e2894138d3efb32161087ad2a1093b8c15c56a65..5892823425055efb92bf635b035d6298
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
index 370513fbc39f178f903ce140ced1a97029dd39db..b195617c39c4b382a196a709c318904cd0598e0e 100644
|
||||
index 3ffc1ee8a9ae63c8678c12736fab5d6ba0a21a5b..4da560f6e4da0750bda78b900b2d916d58adfccb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
@@ -206,7 +206,7 @@ public class Squid extends WaterAnimal {
|
||||
public void travel(Vec3 movementInput) {
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
@@ -211,7 +211,8 @@ public class Squid extends WaterAnimal {
|
||||
}
|
||||
-
|
||||
+// AAA
|
||||
|
||||
public static boolean checkSquidSpawnRules(EntityType<Squid> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
|
||||
- return pos.getY() > world.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && pos.getY() < world.getSeaLevel(); // Spigot
|
||||
+ final double maxHeight = world.getMinecraftWorld().paperConfig.squidMaxSpawnHeight > 0 ? world.getMinecraftWorld().paperConfig.squidMaxSpawnHeight : world.getSeaLevel(); // Paper
|
||||
+ return pos.getY() > world.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && pos.getY() < maxHeight; // Spigot // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityEvent(byte status) {
|
||||
if (status == 19) {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 1 Apr 2018 02:28:43 +0300
|
||||
Subject: [PATCH] Add method to open already placed sign
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
index 396092fd249928ca01133eeeeb61f0ad90b2e332..5cc025b69c4f405be8f7098d0dcef40fa522b39f 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -476,6 +476,14 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
|
||||
*/
|
||||
@Deprecated
|
||||
public void setShoulderEntityRight(@Nullable Entity entity);
|
||||
+ // Paper start - Add method to open already placed sign
|
||||
+ /**
|
||||
+ * Opens an editor window for the specified sign
|
||||
+ *
|
||||
+ * @param sign The sign to open
|
||||
+ */
|
||||
+ void openSign(@NotNull org.bukkit.block.Sign sign);
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Make the entity drop the item in their hand.
|
|
@ -1,253 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 28 Apr 2018 10:28:50 -0400
|
||||
Subject: [PATCH] Add Ban Methods to Player Objects
|
||||
|
||||
Allows a more logical API for banning players.
|
||||
|
||||
player.banPlayer("Breaking the rules");
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
index 58313929f81509030216a0e5e3869da63e11108e..6cf05fed701c67a2c797a4e0839c795802a238a1 100644
|
||||
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
@@ -45,6 +45,61 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||
* @return true if banned, otherwise false
|
||||
*/
|
||||
public boolean isBanned();
|
||||
+ // Paper start
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans this player from the server
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason) {
|
||||
+ return banPlayer(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param source Source of the ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayer(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires) {
|
||||
+ return banPlayer(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the ban or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source) {
|
||||
+ return banPlayer(reason, expires, source, true);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source, boolean kickIfOnline) {
|
||||
+ BanEntry banEntry = Bukkit.getServer().getBanList(BanList.Type.NAME).addBan(getName(), reason, expires, source);
|
||||
+ if (kickIfOnline && isOnline()) {
|
||||
+ getPlayer().kickPlayer(reason);
|
||||
+ }
|
||||
+ return banEntry;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Checks if this player is whitelisted or not
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index b2fdf015b8a86ca96eb5c92aa85d7e36ee21aaad..83bd47744d3e056264e6bf024b45cc86fcd5ea42 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -5,6 +5,10 @@ import java.util.UUID;
|
||||
import com.destroystokyo.paper.Title; // Paper
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile; // Paper
|
||||
+import java.util.Date; // Paper
|
||||
+import org.bukkit.BanEntry; // Paper
|
||||
+import org.bukkit.BanList; // Paper
|
||||
+import org.bukkit.Bukkit; // Paper
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -711,6 +715,162 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
// Paper start
|
||||
+ /**
|
||||
+ * Permanently Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ // For reference, Bukkit defines this as nullable, while they impl isn't, we'll follow API.
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason) {
|
||||
+ return banPlayerFull(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayerFull(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable Date expires) {
|
||||
+ return banPlayerFull(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable Date expires, @Nullable String source) {
|
||||
+ banPlayer(reason, expires, source);
|
||||
+ return banPlayerIP(reason, expires, source, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, null, null, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable String source, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, null, source, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, expires, null, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason) {
|
||||
+ return banPlayerIP(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayerIP(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires) {
|
||||
+ return banPlayerIP(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the banm or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, @Nullable String source) {
|
||||
+ return banPlayerIP(reason, expires, source, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the banm or null for default
|
||||
+ * @param kickPlayer if the targeted player should be kicked
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer) {
|
||||
+ BanEntry banEntry = Bukkit.getServer().getBanList(BanList.Type.IP).addBan(getAddress().getAddress().getHostAddress(), reason, expires, source);
|
||||
+ if (kickPlayer && isOnline()) {
|
||||
+ getPlayer().kickPlayer(reason);
|
||||
+ }
|
||||
+
|
||||
+ return banEntry;
|
||||
+ }
|
||||
|
||||
/**
|
||||
* Sends an Action Bar message to the client.
|
|
@ -1,102 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:14:30 -0400
|
||||
Subject: [PATCH] EndermanEscapeEvent
|
||||
|
||||
Fires an event anytime an enderman intends to teleport away from the player
|
||||
|
||||
You may cancel this, enabling ranged attacks to damage the enderman for example.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..806112a8b5a7ce31166675f5b074ceaf42e364b6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
|
||||
@@ -0,0 +1,87 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Enderman;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Reason reason;
|
||||
+
|
||||
+ public EndermanEscapeEvent(@NotNull Enderman entity, @NotNull Reason reason) {
|
||||
+ super(entity);
|
||||
+ this.reason = reason;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Enderman getEntity() {
|
||||
+ return (Enderman) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The reason the enderman is trying to escape
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Reason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancels the escape.
|
||||
+ *
|
||||
+ * If this escape normally would of resulted in damage avoidance such as indirect,
|
||||
+ * the enderman will now take damage.
|
||||
+ *
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ public enum Reason {
|
||||
+ /**
|
||||
+ * The enderman has stopped attacking and ran away
|
||||
+ */
|
||||
+ RUNAWAY,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to indirect damage (ranged)
|
||||
+ */
|
||||
+ INDIRECT,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to a critical hit
|
||||
+ */
|
||||
+ CRITICAL_HIT,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to the player staring at it during combat
|
||||
+ */
|
||||
+ STARE,
|
||||
+ /**
|
||||
+ * Specific case for CRITICAL_HIT where the enderman is taking rain damage
|
||||
+ */
|
||||
+ DROWN
|
||||
+ }
|
||||
+}
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:29:15 -0400
|
||||
Subject: [PATCH] Enderman.teleportRandomly()
|
||||
|
||||
Ability to trigger the vanilla "teleport randomly" mechanic of an enderman.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Enderman.java b/src/main/java/org/bukkit/entity/Enderman.java
|
||||
index bb325d9c802e33431530bbccdcf5de5839e5fe68..821c690f8a32918bdb284ffec4af98f411f76ccc 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Enderman.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Enderman.java
|
||||
@@ -10,6 +10,17 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface Enderman extends Monster {
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Try to teleport the enderman to a random nearby location.
|
||||
+ *
|
||||
+ * May conditionally fail if the random location was not valid
|
||||
+ * @return If the enderman teleported successfully or not
|
||||
+ */
|
||||
+
|
||||
+ public boolean teleportRandomly();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the id and data of the block that the Enderman is carrying.
|
||||
*
|
|
@ -1,292 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 17:55:28 -0400
|
||||
Subject: [PATCH] Additional world.getNearbyEntities API's
|
||||
|
||||
Provides more methods to get nearby entities, and filter by types and predicates
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 98c74a6b4f126f2a3e65f95e55561f652c10c4b9..8e434b7048cd650245c6b522807e2f8a6dc497e9 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
+import org.bukkit.generator.ChunkGenerator;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -652,6 +655,256 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@NotNull
|
||||
public Collection<Entity> getEntitiesByClasses(@NotNull Class<?>... classes);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius Radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double radius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double radius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xRadius, yRadius, zRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double radius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends Entity> clazz, @NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<T> predicate) {
|
||||
+ if (clazz == null) {
|
||||
+ clazz = Entity.class;
|
||||
+ }
|
||||
+ List<T> nearby = new ArrayList<>();
|
||||
+ for (Entity bukkitEntity : getNearbyEntities(loc, xRadius, yRadius, zRadius)) {
|
||||
+ //noinspection unchecked
|
||||
+ if (clazz.isAssignableFrom(bukkitEntity.getClass()) && (predicate == null || predicate.test((T) bukkitEntity))) {
|
||||
+ //noinspection unchecked
|
||||
+ nearby.add((T) bukkitEntity);
|
||||
+ }
|
||||
+ }
|
||||
+ return nearby;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get a list of all players in this World
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
index 25e0d571710403c334bd73ce1b97109dd65c3244..033960f566861e303b9cb61aae4c02add501d93f 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
@@ -42,8 +42,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
return profile;
|
||||
}
|
||||
|
||||
- /**
|
||||
- * Changes the PlayerProfile the player will login as
|
||||
+ /* * Changes the PlayerProfile the player will login as
|
||||
* @param profile The profile to use
|
||||
*/
|
||||
public void setPlayerProfile(@NotNull PlayerProfile profile) {
|
|
@ -1,18 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 19:27:31 -0400
|
||||
Subject: [PATCH] Location.isChunkLoaded() API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index 7c4db051472fb6a6c6d24092dc6f75487356690a..3be91f6c9b355c9e8562796d719f5a6ce566d85a 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -533,6 +533,7 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
|
@ -1,586 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 29 Aug 2017 23:58:48 -0400
|
||||
Subject: [PATCH] Expand World.spawnParticle API and add Builder
|
||||
|
||||
Adds ability to control who receives it and who is the source/sender (vanish API)
|
||||
the standard API is to send the packet to everyone in the world, which is ineffecient.
|
||||
|
||||
This adds a new Builder API which is much friendlier to use.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/ParticleBuilder.java b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f45b8cfd1611345e8d81ecb8297a586f05eb5dc6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
|
||||
@@ -0,0 +1,485 @@
|
||||
+package com.destroystokyo.paper;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import org.bukkit.Color;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.Particle;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.util.NumberConversions;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Helps prepare a particle to be sent to players.
|
||||
+ *
|
||||
+ * Usage of the builder is preferred over the super long {@link World#spawnParticle(Particle, Location, int, double, double, double, double, Object)} API
|
||||
+ */
|
||||
+public class ParticleBuilder {
|
||||
+
|
||||
+ private Particle particle;
|
||||
+ private List<Player> receivers;
|
||||
+ private Player source;
|
||||
+ private Location location;
|
||||
+ private int count = 1;
|
||||
+ private double offsetX = 0, offsetY = 0, offsetZ = 0;
|
||||
+ private double extra = 1;
|
||||
+ private Object data;
|
||||
+ private boolean force = true;
|
||||
+
|
||||
+ public ParticleBuilder(@NotNull Particle particle) {
|
||||
+ this.particle = particle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the particle to all receiving players (or all). This method is safe to use
|
||||
+ * Asynchronously
|
||||
+ *
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder spawn() {
|
||||
+ if (this.location == null) {
|
||||
+ throw new IllegalStateException("Please specify location for this particle");
|
||||
+ }
|
||||
+ location.getWorld().spawnParticle(particle, receivers, source,
|
||||
+ location.getX(), location.getY(), location.getZ(),
|
||||
+ count, offsetX, offsetY, offsetZ, extra, data, force
|
||||
+ );
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The particle going to be sent
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Particle particle() {
|
||||
+ return particle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Changes what particle will be sent
|
||||
+ *
|
||||
+ * @param particle The particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder particle(@NotNull Particle particle) {
|
||||
+ this.particle = particle;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return List of players who will receive the particle, or null for all in world
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public List<Player> receivers() {
|
||||
+ return receivers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Example use:
|
||||
+ *
|
||||
+ * builder.receivers(16); if (builder.hasReceivers()) { sendParticleAsync(builder); }
|
||||
+ *
|
||||
+ * @return If this particle is going to be sent to someone
|
||||
+ */
|
||||
+ public boolean hasReceivers() {
|
||||
+ return (receivers == null && !location.getWorld().getPlayers().isEmpty()) || (
|
||||
+ receivers != null && !receivers.isEmpty());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends this particle to all players in the world. This is rather silly and you should likely not
|
||||
+ * be doing this.
|
||||
+ *
|
||||
+ * Just be a logical person and use receivers by radius or collection.
|
||||
+ *
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder allPlayers() {
|
||||
+ this.receivers = null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable List<Player> receivers) {
|
||||
+ // Had to keep this as we first made API List<> and not Collection, but removing this may break plugins compiled on older jars
|
||||
+ // TODO: deprecate?
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable Collection<Player> receivers) {
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to be receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable Player... receivers) {
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. If you want a more spherical check, see {@link #receivers(int,
|
||||
+ * boolean)}
|
||||
+ *
|
||||
+ * @param radius amount to add on all axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int radius) {
|
||||
+ return receivers(radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within the specified radius around the particle location. If byDistance is
|
||||
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
|
||||
+ * true, radius is tested by distance in a spherical shape
|
||||
+ *
|
||||
+ * @param radius amount to add on each axis
|
||||
+ * @param byDistance true to use a spherical radius, false to use a cuboid
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int radius, boolean byDistance) {
|
||||
+ if (!byDistance) {
|
||||
+ return receivers(radius, radius, radius);
|
||||
+ } else {
|
||||
+ this.receivers = Lists.newArrayList();
|
||||
+ for (Player nearbyPlayer : location.getWorld()
|
||||
+ .getNearbyPlayers(location, radius, radius, radius)) {
|
||||
+ Location loc = nearbyPlayer.getLocation();
|
||||
+ double x = NumberConversions.square(location.getX() - loc.getX());
|
||||
+ double y = NumberConversions.square(location.getY() - loc.getY());
|
||||
+ double z = NumberConversions.square(location.getZ() - loc.getZ());
|
||||
+ if (Math.sqrt(x + y + z) > radius) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ this.receivers.add(nearbyPlayer);
|
||||
+ }
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. Allows specifying a different Y size than X and Z If you want a more
|
||||
+ * cylinder check, see {@link #receivers(int, int, boolean)} If you want a more spherical check,
|
||||
+ * see {@link #receivers(int, boolean)}
|
||||
+ *
|
||||
+ * @param xzRadius amount to add on the x/z axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xzRadius, int yRadius) {
|
||||
+ return receivers(xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within the specified radius around the particle location. If byDistance is
|
||||
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
|
||||
+ * true, radius is tested by distance on the y plane and on the x/z plane, in a cylinder shape.
|
||||
+ *
|
||||
+ * @param xzRadius amount to add on the x/z axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @param byDistance true to use a cylinder shape, false to use cuboid
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xzRadius, int yRadius, boolean byDistance) {
|
||||
+ if (!byDistance) {
|
||||
+ return receivers(xzRadius, yRadius, xzRadius);
|
||||
+ } else {
|
||||
+ this.receivers = Lists.newArrayList();
|
||||
+ for (Player nearbyPlayer : location.getWorld()
|
||||
+ .getNearbyPlayers(location, xzRadius, yRadius, xzRadius)) {
|
||||
+ Location loc = nearbyPlayer.getLocation();
|
||||
+ if (Math.abs(loc.getY() - this.location.getY()) > yRadius) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ double x = NumberConversions.square(location.getX() - loc.getX());
|
||||
+ double z = NumberConversions.square(location.getZ() - loc.getZ());
|
||||
+ if (x + z > NumberConversions.square(xzRadius)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ this.receivers.add(nearbyPlayer);
|
||||
+ }
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. If you want a more cylinder check, see {@link #receivers(int, int,
|
||||
+ * boolean)} If you want a more spherical check, see {@link #receivers(int, boolean)}
|
||||
+ *
|
||||
+ * @param xRadius amount to add on the x axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @param zRadius amount to add on the z axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xRadius, int yRadius, int zRadius) {
|
||||
+ if (location == null) {
|
||||
+ throw new IllegalStateException("Please set location first");
|
||||
+ }
|
||||
+ return receivers(location.getWorld().getNearbyPlayers(location, xRadius, yRadius, zRadius));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The player considered the source of this particle (for Visibility concerns), or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Player source() {
|
||||
+ return source;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the source of this particle for visibility concerns (Vanish API)
|
||||
+ *
|
||||
+ * @param source The player who is considered the source
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder source(@Nullable Player source) {
|
||||
+ this.source = source;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Location of where the particle will spawn
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Location location() {
|
||||
+ return location;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location of where to spawn the particle
|
||||
+ *
|
||||
+ * @param location The location of the particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder location(@NotNull Location location) {
|
||||
+ this.location = location.clone();
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location of where to spawn the particle
|
||||
+ *
|
||||
+ * @param world World to spawn particle in
|
||||
+ * @param x X location
|
||||
+ * @param y Y location
|
||||
+ * @param z Z location
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder location(@NotNull World world, double x, double y, double z) {
|
||||
+ this.location = new Location(world, x, y, z);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Number of particles to spawn
|
||||
+ */
|
||||
+ public int count() {
|
||||
+ return count;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of particles to spawn
|
||||
+ *
|
||||
+ * @param count Number of particles
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder count(int count) {
|
||||
+ this.count = count;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset X. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset X.
|
||||
+ */
|
||||
+ public double offsetX() {
|
||||
+ return offsetX;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset Y. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset Y.
|
||||
+ */
|
||||
+ public double offsetY() {
|
||||
+ return offsetY;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset Z. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset Z.
|
||||
+ */
|
||||
+ public double offsetZ() {
|
||||
+ return offsetZ;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle offset. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param offsetX Particle offset X
|
||||
+ * @param offsetY Particle offset Y
|
||||
+ * @param offsetZ Particle offset Z
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder offset(double offsetX, double offsetY, double offsetZ) {
|
||||
+ this.offsetX = offsetX;
|
||||
+ this.offsetY = offsetY;
|
||||
+ this.offsetZ = offsetZ;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Particle extra data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return the extra particle data
|
||||
+ */
|
||||
+ public double extra() {
|
||||
+ return extra;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle extra data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param extra the extra particle data
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder extra(double extra) {
|
||||
+ this.extra = extra;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the particle custom data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param <T> The Particle data type
|
||||
+ * @return the ParticleData for this particle
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public <T> T data() {
|
||||
+ //noinspection unchecked
|
||||
+ return (T) data;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle custom data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param data The new particle data
|
||||
+ * @param <T> The Particle data type
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T> ParticleBuilder data(@Nullable T data) {
|
||||
+ this.data = data;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return whether the particle is forcefully shown to players.
|
||||
+ */
|
||||
+ public boolean force() {
|
||||
+ return force;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether the particle is forcefully shown to the player. If forced, the particle will show
|
||||
+ * faraway, as far as the player's view distance allows. If false, the particle will show
|
||||
+ * according to the client's particle settings.
|
||||
+ *
|
||||
+ * @param force true to force, false for normal
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder force(boolean force) {
|
||||
+ this.force = force;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color. Only valid for REDSTONE.
|
||||
+ *
|
||||
+ * @param color the new particle color
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(@Nullable Color color) {
|
||||
+ return color(color, 1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color and size. Only valid for REDSTONE.
|
||||
+ *
|
||||
+ * @param color the new particle color
|
||||
+ * @param size the size of the particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(@Nullable Color color, float size) {
|
||||
+ if (particle != Particle.REDSTONE && color != null) {
|
||||
+ throw new IllegalStateException("Color may only be set on REDSTONE");
|
||||
+ }
|
||||
+
|
||||
+ // We don't officially support reusing these objects, but here we go
|
||||
+ if (color == null) {
|
||||
+ if (data instanceof Particle.DustOptions) {
|
||||
+ return data(null);
|
||||
+ } else {
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return data(new Particle.DustOptions(color, size));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color.
|
||||
+ * Only valid for REDSTONE.
|
||||
+ * @param r red color component
|
||||
+ * @param g green color component
|
||||
+ * @param b blue color component
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(int r, int g, int b) {
|
||||
+ return color(Color.fromRGB(r, g, b));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java
|
||||
index dc5142460a711ee79aed30276382b92c82cbef00..40a3a54fc82252692fc8710cabb243d0984ccf4f 100644
|
||||
--- a/src/main/java/org/bukkit/Particle.java
|
||||
+++ b/src/main/java/org/bukkit/Particle.java
|
||||
@@ -122,6 +122,17 @@ public enum Particle {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
+ // Paper start - Particle API expansion
|
||||
+ /**
|
||||
+ * Creates a {@link com.destroystokyo.paper.ParticleBuilder}
|
||||
+ *
|
||||
+ * @return a {@link com.destroystokyo.paper.ParticleBuilder} for the particle
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public com.destroystokyo.paper.ParticleBuilder builder() {
|
||||
+ return new com.destroystokyo.paper.ParticleBuilder(this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
/**
|
||||
* Options which can be applied to redstone dust particles - a particle
|
||||
* color and size.
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index fbf8eb17630dfc43be8cf7ba92193e3da8aad1a4..73d0e05c7f8dbab81cdaacb8111fc4681a631ad3 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -2637,7 +2637,57 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* @param data the data to use for the particle or null,
|
||||
* the type of this depends on {@link Particle#getDataType()}
|
||||
*/
|
||||
- public <T> void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data);
|
||||
+ public default <T> void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data) { spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, true); }// Paper start - Expand Particle API
|
||||
+ /**
|
||||
+ * Spawns the particle (the number of times specified by count)
|
||||
+ * at the target location. The position of each particle will be
|
||||
+ * randomized positively and negatively by the offset parameters
|
||||
+ * on each axis.
|
||||
+ *
|
||||
+ * @param particle the particle to spawn
|
||||
+ * @param receivers List of players to receive the particles, or null for all in world
|
||||
+ * @param source Source of the particles to be used in visibility checks, or null if no player source
|
||||
+ * @param x the position on the x axis to spawn at
|
||||
+ * @param y the position on the y axis to spawn at
|
||||
+ * @param z the position on the z axis to spawn at
|
||||
+ * @param count the number of particles
|
||||
+ * @param offsetX the maximum random offset on the X axis
|
||||
+ * @param offsetY the maximum random offset on the Y axis
|
||||
+ * @param offsetZ the maximum random offset on the Z axis
|
||||
+ * @param extra the extra data for this particle, depends on the
|
||||
+ * particle used (normally speed)
|
||||
+ * @param data the data to use for the particle or null,
|
||||
+ * the type of this depends on {@link Particle#getDataType()}
|
||||
+ * @param <T> Type
|
||||
+ */
|
||||
+ public default <T> void spawnParticle(@NotNull Particle particle, @Nullable List<Player> receivers, @NotNull Player source, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data) { spawnParticle(particle, receivers, source, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, true); }
|
||||
+ /**
|
||||
+ * Spawns the particle (the number of times specified by count)
|
||||
+ * at the target location. The position of each particle will be
|
||||
+ * randomized positively and negatively by the offset parameters
|
||||
+ * on each axis.
|
||||
+ *
|
||||
+ * @param particle the particle to spawn
|
||||
+ * @param receivers List of players to receive the particles, or null for all in world
|
||||
+ * @param source Source of the particles to be used in visibility checks, or null if no player source
|
||||
+ * @param x the position on the x axis to spawn at
|
||||
+ * @param y the position on the y axis to spawn at
|
||||
+ * @param z the position on the z axis to spawn at
|
||||
+ * @param count the number of particles
|
||||
+ * @param offsetX the maximum random offset on the X axis
|
||||
+ * @param offsetY the maximum random offset on the Y axis
|
||||
+ * @param offsetZ the maximum random offset on the Z axis
|
||||
+ * @param extra the extra data for this particle, depends on the
|
||||
+ * particle used (normally speed)
|
||||
+ * @param data the data to use for the particle or null,
|
||||
+ * the type of this depends on {@link Particle#getDataType()}
|
||||
+ * @param <T> Type
|
||||
+ * @param force allows the particle to be seen further away from the player
|
||||
+ * and shows to players using any vanilla client particle settings
|
||||
+ */
|
||||
+ public <T> void spawnParticle(@NotNull Particle particle, @Nullable List<Player> receivers, @Nullable Player source, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force);
|
||||
+ // Paper end
|
||||
+
|
||||
|
||||
/**
|
||||
* Spawns the particle (the number of times specified by count)
|
|
@ -1,116 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 20:17:44 -0400
|
||||
Subject: [PATCH] EndermanAttackPlayerEvent
|
||||
|
||||
Allow control over whether or not an enderman aggros a player.
|
||||
|
||||
This allows you to override/extend the pumpkin/stare logic.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f530a3d9314e17d1da896cac633f6a422258d9a9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||
@@ -0,0 +1,101 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Enderman;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an Enderman determines if it should attack a player or not.
|
||||
+ * Starts off cancelled if the player is wearing a pumpkin head or is not looking
|
||||
+ * at the Enderman, according to Vanilla rules.
|
||||
+ *
|
||||
+ */
|
||||
+public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Player player;
|
||||
+
|
||||
+ public EndermanAttackPlayerEvent(@NotNull Enderman entity, @NotNull Player player) {
|
||||
+ super(entity);
|
||||
+ this.player = player;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The enderman considering attacking
|
||||
+ *
|
||||
+ * @return The enderman considering attacking
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Enderman getEntity() {
|
||||
+ return (Enderman) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The player the Enderman is considering attacking
|
||||
+ *
|
||||
+ * @return The player the Enderman is considering attacking
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ *
|
||||
+ * @return If cancelled, the enderman will not attack
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancels if the Enderman will attack this player
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,105 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 21:33:35 -0400
|
||||
Subject: [PATCH] Close Plugin Class Loaders on Disable
|
||||
|
||||
This should close more memory leaks from /reload and disabling plugins,
|
||||
by closing the class loader and the jar file.
|
||||
|
||||
Note: This patch is no longer necessary as upstream now also closes
|
||||
PluginClassLoaders on disable. This patch is now only to keep around
|
||||
API methods it previously added, and to add back the log message when a
|
||||
PluginClassLoader fails to disable, as upstream decided to ignore the
|
||||
exception.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
index a88733f1cd1ddb5d85ab1b0e6af4fd5b80bbc1c6..256e440e699942e3c9da4205bb964bdc10ec92c4 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
@@ -77,4 +77,21 @@ public interface PluginLoader {
|
||||
* @param plugin Plugin to disable
|
||||
*/
|
||||
public void disablePlugin(@NotNull Plugin plugin);
|
||||
+
|
||||
+ // Paper start - close Classloader on disable
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugin(Plugin)} instead.
|
||||
+ *
|
||||
+ * @param plugin Plugin to disable
|
||||
+ * @param closeClassloader unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ // provide default to allow other PluginLoader implementations to work
|
||||
+ default public void disablePlugin(@NotNull Plugin plugin, boolean closeClassloader) {
|
||||
+ disablePlugin(plugin);
|
||||
+ }
|
||||
+ // Paper end - close Classloader on disable
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
index 41e26451fe12d8e6e0ef73c85731b24b4e3f200c..0d1b20f2b5580ea5505ccc2f003925dbcee67199 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
@@ -161,6 +161,22 @@ public interface PluginManager {
|
||||
*/
|
||||
public void disablePlugin(@NotNull Plugin plugin);
|
||||
|
||||
+ // Paper start - close Classloader on disable
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugin(Plugin)} instead.
|
||||
+ *
|
||||
+ * @param plugin Plugin to disable
|
||||
+ * @param closeClassloader unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public default void disablePlugin(@NotNull Plugin plugin, boolean closeClassloader) {
|
||||
+ this.disablePlugin(plugin);
|
||||
+ }
|
||||
+ // Paper end - close Classloader on disable
|
||||
+
|
||||
/**
|
||||
* Gets a {@link Permission} from its fully qualified name
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 2d27dfb859c312d46a14d0356c7c3f227e965a67..7867243a8ed67416895cdcd949ac424f5d29d98b 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -498,6 +498,21 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugins()} instead.
|
||||
+ *
|
||||
+ * @param closeClassloaders unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public void disablePlugins(boolean closeClassloaders) {
|
||||
+ this.disablePlugins();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void disablePlugin(@NotNull final Plugin plugin) {
|
||||
if (plugin.isEnabled()) {
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index b7cd98f20de3421cd3b8a95cfa2155fa77afa8b1..7483ceff298cafa244bd99316a0338aa075267d4 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -366,6 +366,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
loader.close();
|
||||
} catch (IOException ex) {
|
||||
//
|
||||
+ this.server.getLogger().log(Level.WARNING, "Error closing the PluginClassLoader for '" + plugin.getDescription().getFullName() + "'", ex); // Paper - log exception
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:26:16 -0400
|
||||
Subject: [PATCH] WitchConsumePotionEvent
|
||||
|
||||
Fires when a witch consumes the potion in their hand
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fbbace36d69373046a7f3618ed5c1c1318b489b9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Witch;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a witch consumes the potion in their hand to buff themselves.
|
||||
+ */
|
||||
+public class WitchConsumePotionEvent extends EntityEvent implements Cancellable {
|
||||
+ @Nullable private ItemStack potion;
|
||||
+
|
||||
+ public WitchConsumePotionEvent(@NotNull Witch witch, @Nullable ItemStack potion) {
|
||||
+ super(witch);
|
||||
+ this.potion = potion;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Witch getEntity() {
|
||||
+ return (Witch) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the potion the witch will consume and have the effects applied.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getPotion() {
|
||||
+ return potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion to be consumed and applied to the witch.
|
||||
+ * @param potion The potion
|
||||
+ */
|
||||
+ public void setPotion(@Nullable ItemStack potion) {
|
||||
+ this.potion = potion != null ? potion.clone() : null;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ * @return Event was cancelled or potion was null
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled || potion == null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6ef6367b67261c2b653a97322b9703a9409b3499
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -0,0 +1,33 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+public class WitchThrowPotionEvent extends Event implements Cancellable {
|
||||
+ public WitchThrowPotionEvent() {
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,93 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:39:09 -0400
|
||||
Subject: [PATCH] WitchThrowPotionEvent
|
||||
|
||||
Fired when a witch throws a potion at a player
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
index 6ef6367b67261c2b653a97322b9703a9409b3499..688a596aa2b925651a92bf092e1ef4d77a47258c 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -1,29 +1,77 @@
|
||||
package com.destroystokyo.paper.event.entity;
|
||||
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Witch;
|
||||
import org.bukkit.event.Cancellable;
|
||||
-import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
|
||||
-public class WitchThrowPotionEvent extends Event implements Cancellable {
|
||||
- public WitchThrowPotionEvent() {
|
||||
+/**
|
||||
+ * Fired when a witch throws a potion at a player
|
||||
+ */
|
||||
+public class WitchThrowPotionEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final LivingEntity target;
|
||||
+ @Nullable private ItemStack potion;
|
||||
+
|
||||
+ public WitchThrowPotionEvent(@NotNull Witch witch, @NotNull LivingEntity target, @Nullable ItemStack potion) {
|
||||
+ super(witch);
|
||||
+ this.target = target;
|
||||
+ this.potion = potion;
|
||||
}
|
||||
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Witch getEntity() {
|
||||
+ return (Witch) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The target of the potion
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public LivingEntity getTarget() {
|
||||
+ return target;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The potion the witch will throw at a player
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getPotion() {
|
||||
+ return potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion to be thrown at a player
|
||||
+ * @param potion The potion
|
||||
+ */
|
||||
+ public void setPotion(@Nullable ItemStack potion) {
|
||||
+ this.potion = potion != null ? potion.clone() : null;
|
||||
+ }
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
+ @NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
+ @NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
+ /**
|
||||
+ * @return Event was cancelled or potion was null
|
||||
+ */
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
- return cancelled;
|
||||
+ return cancelled || potion == null;
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 24 May 2018 21:01:13 -0400
|
||||
Subject: [PATCH] Location.toBlockLocation/toCenterLocation()
|
||||
|
||||
Convert location objects to their block coordinates, or the center of the block
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index 3be91f6c9b355c9e8562796d719f5a6ce566d85a..a90010fea189c5ac9a59a0e6d04c0457243a3280 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -534,6 +534,31 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @return A new location where X/Y/Z are on the Block location (integer value of X/Y/Z)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location toBlockLocation() {
|
||||
+ Location blockLoc = clone();
|
||||
+ blockLoc.setX(getBlockX());
|
||||
+ blockLoc.setY(getBlockY());
|
||||
+ blockLoc.setZ(getBlockZ());
|
||||
+ return blockLoc;
|
||||
+ }
|
||||
+ /**
|
||||
+ * @return A new location where X/Y/Z are the center of the block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location toCenterLocation() {
|
||||
+ Location centerLoc = clone();
|
||||
+ centerLoc.setX(getBlockX() + 0.5);
|
||||
+ centerLoc.setY(getBlockY() + 0.5);
|
||||
+ centerLoc.setZ(getBlockZ() + 0.5);
|
||||
+ return centerLoc;
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 3 Jun 2018 04:10:13 -0400
|
||||
Subject: [PATCH] PotionEffect clone methods
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
index 60716c627d315b08c3fe03b1a945af60c350711f..74767751199bce03d63f2a9524712656193f850c 100644
|
||||
--- a/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
+++ b/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
@@ -101,6 +101,33 @@ public class PotionEffect implements ConfigurationSerializable {
|
||||
this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @NotNull
|
||||
+ public PotionEffect withType(@NotNull PotionEffectType type) {
|
||||
+ return new PotionEffect(type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withDuration(int duration) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withAmplifier(int amplifier) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withAmbient(boolean ambient) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withParticles(boolean particles) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withIcon(boolean icon) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
private static PotionEffectType getEffectType(@NotNull Map<?, ?> map) {
|
||||
int type = getInt(map, TYPE);
|
|
@ -1,93 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Jun 2018 22:47:08 -0400
|
||||
Subject: [PATCH] WitchReadyPotionEvent
|
||||
|
||||
Control what potion the witch readies to use
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5351b523defa054ba56ae3fb591029283ca7510d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java
|
||||
@@ -0,0 +1,80 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.entity.Witch;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class WitchReadyPotionEvent extends EntityEvent implements Cancellable {
|
||||
+ private ItemStack potion;
|
||||
+
|
||||
+ public WitchReadyPotionEvent(@NotNull Witch witch, @Nullable ItemStack potion) {
|
||||
+ super(witch);
|
||||
+ this.potion = potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Fires thee event, returning the desired potion, or air of cancelled
|
||||
+ * @param witch the witch whom is readying to use a potion
|
||||
+ * @param potion the potion to be used
|
||||
+ * @return The ItemStack to be used
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public static ItemStack process(@NotNull Witch witch, @Nullable ItemStack potion) {
|
||||
+ WitchReadyPotionEvent event = new WitchReadyPotionEvent(witch, potion);
|
||||
+ if (!event.callEvent() || event.getPotion() == null) {
|
||||
+ return new ItemStack(Material.AIR);
|
||||
+ }
|
||||
+ return event.getPotion();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Witch getEntity() {
|
||||
+ return (Witch) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the potion the witch is readying to use
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getPotion() {
|
||||
+ return potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion the which is going to hold and use
|
||||
+ * @param potion The potion
|
||||
+ */
|
||||
+ public void setPotion(@Nullable ItemStack potion) {
|
||||
+ this.potion = potion != null ? potion.clone() : null;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Jun 2018 22:59:50 -0400
|
||||
Subject: [PATCH] ItemStack#getMaxItemUseDuration
|
||||
|
||||
Allows you to determine how long it takes to use a usable/consumable item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
index e8783b0116f4efd5447a5f6f260506000983ffd2..9fee2f157ac5149cd65136bf8468deaca410fbf4 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -636,5 +636,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
public String getI18NDisplayName() {
|
||||
return Bukkit.getServer().getItemFactory().getI18NDisplayName(this);
|
||||
}
|
||||
+
|
||||
+ public int getMaxItemUseDuration() {
|
||||
+ if (type == null || type == Material.AIR || !type.isItem()) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ // Requires access to NMS
|
||||
+ return ensureServerConversions().getMaxItemUseDuration();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 9 Jun 2018 13:08:21 +0100
|
||||
Subject: [PATCH] Add EntityTeleportEndGatewayEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bfc69a43c291fbed91b9d0387e4ef18b0ed1b9de
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.block.EndGateway;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.entity.EntityTeleportEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired any time an entity attempts to teleport in an end gateway
|
||||
+ */
|
||||
+public class EntityTeleportEndGatewayEvent extends EntityTeleportEvent {
|
||||
+
|
||||
+ @NotNull private final EndGateway gateway;
|
||||
+
|
||||
+ public EntityTeleportEndGatewayEvent(@NotNull Entity what, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
|
||||
+ super(what, from, to);
|
||||
+ this.gateway = gateway;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The gateway triggering the teleport
|
||||
+ *
|
||||
+ * @return EndGateway used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EndGateway getGateway() {
|
||||
+ return gateway;
|
||||
+ }
|
||||
+
|
||||
+}
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 16 Jun 2018 01:17:39 -0500
|
||||
Subject: [PATCH] Make shield blocking delay configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index bfc90a3569abc717f37c064e3068c55ef323edab..588ad09a764236cf858a4e6689cf4ee5246e6f08 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -635,5 +635,19 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @param arrows Number of arrows to stick in this entity
|
||||
*/
|
||||
void setArrowsStuck(int arrows);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the delay (in ticks) before blocking is effective for this entity
|
||||
+ *
|
||||
+ * @return Delay in ticks
|
||||
+ */
|
||||
+ int getShieldBlockingDelay();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the delay (in ticks) before blocking is effective for this entity
|
||||
+ *
|
||||
+ * @param delay Delay in ticks
|
||||
+ */
|
||||
+ void setShieldBlockingDelay(int delay);
|
||||
// Paper end
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 15 Jun 2013 19:52:04 -0400
|
||||
Subject: [PATCH] EntityShootBowEvent consumeArrow and getArrowItem API
|
||||
|
||||
Adds ability to get what arrow was shot, and control if it should be consumed.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java b/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||
index d4d7ad9c3c953680342c121f39ddaef476549047..719d0d878320c1903b44076053989ba99fa0e92a 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||
@@ -22,7 +22,32 @@ public class EntityShootBowEvent extends EntityEvent implements Cancellable {
|
||||
private final float force;
|
||||
private boolean consumeItem;
|
||||
private boolean cancelled;
|
||||
+ // Paper start
|
||||
+ @Deprecated
|
||||
+ public void setConsumeArrow(boolean consumeArrow) {
|
||||
+ this.setConsumeItem(consumeArrow);
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public boolean getConsumeArrow() {
|
||||
+ return this.shouldConsumeItem();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull @Deprecated
|
||||
+ public ItemStack getArrowItem() {
|
||||
+ return this.getConsumable();
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @NotNull final Entity projectile, final float force) {
|
||||
+ this(shooter, bow, new ItemStack(org.bukkit.Material.AIR), projectile, force);
|
||||
+ }
|
||||
|
||||
+ @Deprecated
|
||||
+ public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @NotNull ItemStack arrowItem, @NotNull final Entity projectile, final float force) {
|
||||
+ this(shooter, bow, arrowItem, projectile, EquipmentSlot.HAND, force, true);
|
||||
+ }
|
||||
+ // Paper end
|
||||
public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @Nullable final ItemStack consumable, @NotNull final Entity projectile, @NotNull final EquipmentSlot hand, final float force, final boolean consumeItem) {
|
||||
super(shooter);
|
||||
this.bow = bow;
|
|
@ -1,275 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 18 Jun 2018 00:41:46 -0500
|
||||
Subject: [PATCH] Add "getNearbyXXX" methods to Location
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index a90010fea189c5ac9a59a0e6d04c0457243a3280..bbc636baef2e2b0586c7d517be428438ca26ab66 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -12,6 +12,15 @@ import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
+// Paper start
|
||||
+import java.util.Collection;
|
||||
+import java.util.Collections;
|
||||
+import java.util.function.Predicate;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Player;
|
||||
+// Paper end
|
||||
+
|
||||
/**
|
||||
* Represents a 3-dimensional position in a world.
|
||||
* <br>
|
||||
@@ -558,6 +567,248 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
centerLoc.setZ(getBlockZ() + 0.5);
|
||||
return centerLoc;
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a list of entities within a bounding box centered around a Location.
|
||||
+ *
|
||||
+ * Some implementations may impose artificial restrictions on the size of the search bounding box.
|
||||
+ *
|
||||
+ * @param x 1/2 the size of the box along x axis
|
||||
+ * @param y 1/2 the size of the box along y axis
|
||||
+ * @param z 1/2 the size of the box along z axis
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Entity> getNearbyEntities(double x, double y, double z) {
|
||||
+ World world = this.getWorld();
|
||||
+ if (world == null) {
|
||||
+ throw new IllegalArgumentException("Location has no world");
|
||||
+ }
|
||||
+ return world.getNearbyEntities(this, x, y, z);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param radius X Radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param radius Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double radius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double xzRadius, double yRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<LivingEntity> getNearbyLivingEntities(double xRadius, double yRadius, double zRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double radius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double xzRadius, double yRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Collection<Player> getNearbyPlayers(double xRadius, double yRadius, double zRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities of type clazz near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, double radius) {
|
||||
+ return getNearbyEntitiesByType(clazz, radius, radius, radius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, xzRadius, yRadius, xzRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, xRadius, yRadius, zRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, double radius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, double xzRadius, double yRadius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends Entity> clazz, double xRadius, double yRadius, double zRadius, @Nullable Predicate<T> predicate) {
|
||||
+ World world = this.getWorld();
|
||||
+ if (world == null) {
|
||||
+ throw new IllegalArgumentException("Location has no world");
|
||||
+ }
|
||||
+ return world.getNearbyEntitiesByType(clazz, this, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
// Paper end
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
|
@ -1,107 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 18 Jun 2018 01:09:27 -0400
|
||||
Subject: [PATCH] PlayerReadyArrowEvent
|
||||
|
||||
Called when a player is firing a bow and the server is choosing an arrow to use.
|
||||
Plugins can skip selection of certain arrows and control which is used.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5d04a22fd6964d8d44a2aa069c9629722893b1f4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
|
||||
@@ -0,0 +1,93 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a player is firing a bow and the server is choosing an arrow to use.
|
||||
+ */
|
||||
+public class PlayerReadyArrowEvent extends PlayerEvent implements Cancellable {
|
||||
+ @NotNull private final ItemStack bow;
|
||||
+ @NotNull private final ItemStack arrow;
|
||||
+
|
||||
+ public PlayerReadyArrowEvent(@NotNull Player player, @NotNull ItemStack bow, @NotNull ItemStack arrow) {
|
||||
+ super(player);
|
||||
+ this.bow = bow;
|
||||
+ this.arrow = arrow;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the player is using to fire the arrow
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack getBow() {
|
||||
+ return bow;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the arrow that is attempting to be used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack getArrow() {
|
||||
+ return arrow;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not use of this arrow is cancelled. On cancel, the server will try the next arrow available and fire another event.
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancel use of this arrow. On cancel, the server will try the next arrow available and fire another event.
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,94 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Mon, 18 Jun 2018 15:40:39 +0200
|
||||
Subject: [PATCH] Add EntityKnockbackByEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9efecabab813f575bb447a356e5e7e952d110f30
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java
|
||||
@@ -0,0 +1,82 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.util.Vector;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an Entity is knocked back by the hit of another Entity. The acceleration
|
||||
+ * vector can be modified. If this event is cancelled, the entity is not knocked back.
|
||||
+ *
|
||||
+ */
|
||||
+public class EntityKnockbackByEntityEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull private final Entity hitBy;
|
||||
+ private final float knockbackStrength;
|
||||
+ @NotNull private final Vector acceleration;
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ public EntityKnockbackByEntityEvent(@NotNull LivingEntity entity, @NotNull Entity hitBy, float knockbackStrength, @NotNull Vector acceleration) {
|
||||
+ super(entity);
|
||||
+ this.hitBy = hitBy;
|
||||
+ this.knockbackStrength = knockbackStrength;
|
||||
+ this.acceleration = acceleration;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the entity which was knocked back
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public LivingEntity getEntity() {
|
||||
+ return (LivingEntity) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the original knockback strength.
|
||||
+ */
|
||||
+ public float getKnockbackStrength() {
|
||||
+ return knockbackStrength;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the Entity which hit
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getHitBy() {
|
||||
+ return hitBy;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the acceleration that will be applied
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Vector getAcceleration() {
|
||||
+ return acceleration;
|
||||
+ }
|
||||
+}
|
|
@ -1,200 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 16:24:42 -0500
|
||||
Subject: [PATCH] Expand Explosions API
|
||||
|
||||
Add Entity as a Source capability, and add more API choices, and on Location.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index bbc636baef2e2b0586c7d517be428438ca26ab66..a8d4f7972d07ddde171b4a1ec470a4c616e02b2e 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -7,6 +7,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
+import org.bukkit.entity.Entity; // Paper
|
||||
import org.bukkit.util.NumberConversions;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -568,6 +569,87 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
return centerLoc;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power
|
||||
+ *
|
||||
+ * Will break blocks and ignite blocks on fire.
|
||||
+ *
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(float power) {
|
||||
+ return this.getWorld().createExplosion(this, power);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power and optionally
|
||||
+ * setting blocks on fire.
|
||||
+ *
|
||||
+ * Will break blocks.
|
||||
+ *
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(float power, boolean setFire) {
|
||||
+ return this.getWorld().createExplosion(this, power, setFire);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power and optionally
|
||||
+ * setting blocks on fire.
|
||||
+ *
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @param breakBlocks Whether or not to have blocks be destroyed
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return this.getWorld().createExplosion(this, power, setFire, breakBlocks);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power, with the specified entity as the source.
|
||||
+ *
|
||||
+ * Will break blocks and ignite blocks on fire.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(@Nullable Entity source, float power) {
|
||||
+ return this.getWorld().createExplosion(source, this, power, true, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * Will break blocks.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(@Nullable Entity source, float power, boolean setFire) {
|
||||
+ return this.getWorld().createExplosion(source, this, power, setFire, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at this location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @param breakBlocks Whether or not to have blocks be destroyed
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(@NotNull Entity source, float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return this.getWorld().createExplosion(source, this, power, setFire, breakBlocks);
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Returns a list of entities within a bounding box centered around a Location.
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 8ed7fadf1375b80b338e2493405a41957b104b8e..2bc0d5d6c81c21fd2c9318e968c3807f3e5474e0 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -1419,6 +1419,88 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
*/
|
||||
public boolean createExplosion(@NotNull Location loc, float power, boolean setFire);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Creates explosion at given location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param loc Location to blow up
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @param breakBlocks Whether or not to have blocks be destroyed
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power, boolean setFire, boolean breakBlocks);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at given location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * Will destroy other blocks
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param loc Location to blow up
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public default boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power, boolean setFire) {
|
||||
+ return createExplosion(source, loc, power, setFire, true);
|
||||
+ }
|
||||
+ /**
|
||||
+ * Creates explosion at given location with given power, with the specified entity as the source.
|
||||
+ * Will set blocks on fire and destroy blocks.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param loc Location to blow up
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public default boolean createExplosion(@Nullable Entity source, @NotNull Location loc, float power) {
|
||||
+ return createExplosion(source, loc, power, true, true);
|
||||
+ }
|
||||
+ /**
|
||||
+ * Creates explosion at given entities location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @param breakBlocks Whether or not to have blocks be destroyed
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public default boolean createExplosion(@NotNull Entity source, float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return createExplosion(source, source.getLocation(), power, setFire, breakBlocks);
|
||||
+ }
|
||||
+ /**
|
||||
+ * Creates explosion at given entities location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * Will destroy blocks.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @param setFire Whether or not to set blocks on fire
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public default boolean createExplosion(@NotNull Entity source, float power, boolean setFire) {
|
||||
+ return createExplosion(source, source.getLocation(), power, setFire, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates explosion at given entities location with given power and optionally
|
||||
+ * setting blocks on fire, with the specified entity as the source.
|
||||
+ *
|
||||
+ * @param source The source entity of the explosion
|
||||
+ * @param power The power of explosion, where 4F is TNT
|
||||
+ * @return false if explosion was canceled, otherwise true
|
||||
+ */
|
||||
+ public default boolean createExplosion(@NotNull Entity source, float power) {
|
||||
+ return createExplosion(source, source.getLocation(), power, true, true);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Creates explosion at given coordinates with given power and optionally
|
||||
* setting blocks on fire or breaking blocks.
|
|
@ -1,206 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 22 Jun 2018 22:59:18 -0400
|
||||
Subject: [PATCH] ItemStack API additions for quantity/flags/lore
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
index 9fee2f157ac5149cd65136bf8468deaca410fbf4..686e2a0b9fe061816b41435ef2337870dbdca8e5 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -2,7 +2,9 @@ package org.bukkit.inventory;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.LinkedHashMap;
|
||||
+import java.util.List; // Paper
|
||||
import java.util.Map;
|
||||
+import java.util.Set; // Paper
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@@ -644,5 +646,185 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
// Requires access to NMS
|
||||
return ensureServerConversions().getMaxItemUseDuration();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Clones the itemstack and returns it a single quantity.
|
||||
+ * @return The new itemstack with 1 quantity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack asOne() {
|
||||
+ return asQuantity(1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clones the itemstack and returns it as the specified quantity
|
||||
+ * @param qty The quantity of the cloned item
|
||||
+ * @return The new itemstack with specified quantity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack asQuantity(int qty) {
|
||||
+ ItemStack clone = clone();
|
||||
+ clone.setAmount(qty);
|
||||
+ return clone;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Adds 1 to this itemstack. Will not go over the items max stack size.
|
||||
+ * @return The same item (not a clone)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack add() {
|
||||
+ return add(1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Adds quantity to this itemstack. Will not go over the items max stack size.
|
||||
+ *
|
||||
+ * @param qty The amount to add
|
||||
+ * @return The same item (not a clone)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack add(int qty) {
|
||||
+ setAmount(Math.min(getMaxStackSize(), getAmount() + qty));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Subtracts 1 to this itemstack. Going to 0 or less will invalidate the item.
|
||||
+ * @return The same item (not a clone)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack subtract() {
|
||||
+ return subtract(1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Subtracts quantity to this itemstack. Going to 0 or less will invalidate the item.
|
||||
+ *
|
||||
+ * @param qty The amount to add
|
||||
+ * @return The same item (not a clone)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack subtract(int qty) {
|
||||
+ setAmount(Math.max(0, getAmount() - qty));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If the item has lore, returns it, else it will return null
|
||||
+ * @return The lore, or null
|
||||
+ * @deprecated in favor of {@link #lore()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public @Nullable List<String> getLore() {
|
||||
+ if (!hasItemMeta()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (!itemMeta.hasLore()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return itemMeta.getLore();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If the item has lore, returns it, else it will return null
|
||||
+ * @return The lore, or null
|
||||
+ */
|
||||
+ public @Nullable List<net.kyori.adventure.text.Component> lore() {
|
||||
+ if (!this.hasItemMeta()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ final ItemMeta itemMeta = getItemMeta();
|
||||
+ if (!itemMeta.hasLore()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return itemMeta.lore();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the lore for this item.
|
||||
+ * Removes lore when given null.
|
||||
+ *
|
||||
+ * @param lore the lore that will be set
|
||||
+ * @deprecated in favour of {@link #lore(List)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setLore(@Nullable List<String> lore) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (itemMeta == null) {
|
||||
+ throw new IllegalStateException("Cannot set lore on " + getType());
|
||||
+ }
|
||||
+ itemMeta.setLore(lore);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the lore for this item.
|
||||
+ * Removes lore when given null.
|
||||
+ *
|
||||
+ * @param lore the lore that will be set
|
||||
+ */
|
||||
+ public void lore(@Nullable List<net.kyori.adventure.text.Component> lore) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (itemMeta == null) {
|
||||
+ throw new IllegalStateException("Cannot set lore on " + getType());
|
||||
+ }
|
||||
+ itemMeta.lore(lore);
|
||||
+ this.setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set itemflags which should be ignored when rendering a ItemStack in the Client. This Method does silently ignore double set itemFlags.
|
||||
+ *
|
||||
+ * @param itemFlags The hideflags which shouldn't be rendered
|
||||
+ */
|
||||
+ public void addItemFlags(@NotNull ItemFlag... itemFlags) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (itemMeta == null) {
|
||||
+ throw new IllegalStateException("Cannot add flags on " + getType());
|
||||
+ }
|
||||
+ itemMeta.addItemFlags(itemFlags);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Remove specific set of itemFlags. This tells the Client it should render it again. This Method does silently ignore double removed itemFlags.
|
||||
+ *
|
||||
+ * @param itemFlags Hideflags which should be removed
|
||||
+ */
|
||||
+ public void removeItemFlags(@NotNull ItemFlag... itemFlags) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (itemMeta == null) {
|
||||
+ throw new IllegalStateException("Cannot remove flags on " + getType());
|
||||
+ }
|
||||
+ itemMeta.removeItemFlags(itemFlags);
|
||||
+ setItemMeta(itemMeta);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get current set itemFlags. The collection returned is unmodifiable.
|
||||
+ *
|
||||
+ * @return A set of all itemFlags set
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<ItemFlag> getItemFlags() {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ if (itemMeta == null) {
|
||||
+ return java.util.Collections.emptySet();
|
||||
+ }
|
||||
+ return itemMeta.getItemFlags();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Check if the specified flag is present on this item.
|
||||
+ *
|
||||
+ * @param flag the flag to check
|
||||
+ * @return if it is present
|
||||
+ */
|
||||
+ public boolean hasItemFlag(@NotNull ItemFlag flag) {
|
||||
+ ItemMeta itemMeta = getItemMeta();
|
||||
+ return itemMeta != null && itemMeta.hasItemFlag(flag);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 Jun 2018 00:19:19 -0400
|
||||
Subject: [PATCH] LivingEntity Hand Raised/Item Use API
|
||||
|
||||
How long an entity has raised hands to charge an attack or use an item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 588ad09a764236cf858a4e6689cf4ee5246e6f08..6d8d96976bcef4e176453fede81a529478f11234 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -12,6 +12,7 @@ import org.bukkit.attribute.Attributable;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.memory.MemoryKey;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
@@ -649,5 +650,42 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @param delay Delay in ticks
|
||||
*/
|
||||
void setShieldBlockingDelay(int delay);
|
||||
+
|
||||
+ /**
|
||||
+ * Get's the item being actively "used" or consumed.
|
||||
+ * @return The item. Will be null if no active item.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ ItemStack getActiveItem();
|
||||
+
|
||||
+ /**
|
||||
+ * Get's remaining time a player needs to keep hands raised with an item to finish using it.
|
||||
+ * @return Remaining ticks to use the item
|
||||
+ */
|
||||
+ int getItemUseRemainingTime();
|
||||
+
|
||||
+ /**
|
||||
+ * Get how long the players hands have been raised (Charging Bow attack, using a potion, etc)
|
||||
+ *
|
||||
+ * @return Get how long the players hands have been raised (Charging Bow attack, using a potion, etc)
|
||||
+ */
|
||||
+ int getHandRaisedTime();
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not this entity is using or charging an attack (Bow pulled back, drinking potion, eating food)
|
||||
+ *
|
||||
+ * @return Whether or not this entity is using or charging an attack (Bow pulled back, drinking potion, eating food)
|
||||
+ */
|
||||
+ boolean isHandRaised();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the hand raised by this living entity. Will be either
|
||||
+ * {@link org.bukkit.inventory.EquipmentSlot#HAND} or
|
||||
+ * {@link org.bukkit.inventory.EquipmentSlot#OFF_HAND}.
|
||||
+ *
|
||||
+ * @return the hand raised
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ org.bukkit.inventory.EquipmentSlot getHandRaised();
|
||||
// Paper end
|
||||
}
|
|
@ -1,183 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 26 Jun 2018 21:34:40 -0400
|
||||
Subject: [PATCH] RangedEntity API
|
||||
|
||||
Allows you to determine if an entity is capable of ranged attacks,
|
||||
and to perform an attack.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f2e3233a3d1744e32fb76d3731b9858ef0067e30
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Mob;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface RangedEntity extends Mob {
|
||||
+ /**
|
||||
+ * Attack the specified entity using a ranged attack.
|
||||
+ *
|
||||
+ * @param target the entity to target
|
||||
+ * @param charge How "charged" the attack is (how far back the bow was pulled for Bow attacks).
|
||||
+ * This should be a value between 0 and 1, represented as targetDistance/maxDistance.
|
||||
+ */
|
||||
+ void rangedAttack(@NotNull LivingEntity target, float charge);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that the Entity is "charging" up an attack, by raising its hands
|
||||
+ *
|
||||
+ * @param raiseHands Whether the entities hands are raised to charge attack
|
||||
+ */
|
||||
+ void setChargingAttack(boolean raiseHands);
|
||||
+
|
||||
+ /**
|
||||
+ * Alias to {@link LivingEntity#isHandRaised()}, if the entity is charging an attack
|
||||
+ * @return If entities hands are raised
|
||||
+ */
|
||||
+ default boolean isChargingAttack() {
|
||||
+ return isHandRaised();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/AbstractSkeleton.java b/src/main/java/org/bukkit/entity/AbstractSkeleton.java
|
||||
index e2fce218c6623b3c932c2782a66dea73dccd33f1..4f4f1e48cdaee0d845f60666569e48731be3fbb9 100644
|
||||
--- a/src/main/java/org/bukkit/entity/AbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/entity/AbstractSkeleton.java
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* of this type, instanceOf checks against the specific subtypes listed prior
|
||||
* are recommended.
|
||||
*/
|
||||
-public interface AbstractSkeleton extends Monster {
|
||||
+public interface AbstractSkeleton extends Monster, com.destroystokyo.paper.entity.RangedEntity { // Paper
|
||||
|
||||
/**
|
||||
* Gets the current type of this skeleton.
|
||||
diff --git a/src/main/java/org/bukkit/entity/Drowned.java b/src/main/java/org/bukkit/entity/Drowned.java
|
||||
index 1dee177ae6e21da000607dc8dd8fd76857f323b9..8d1ad9ef757cb1e8d72b145262df73612a76c746 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Drowned.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Drowned.java
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
+
|
||||
/**
|
||||
* Drowned zombie.
|
||||
*/
|
||||
-public interface Drowned extends Zombie { }
|
||||
+public interface Drowned extends Zombie, RangedEntity { } // Paper
|
||||
diff --git a/src/main/java/org/bukkit/entity/Illusioner.java b/src/main/java/org/bukkit/entity/Illusioner.java
|
||||
index 7c92c431b32754dca12b4d584bd6fa93ff73badf..14e6c5ee06ece3d1bbc1239afa67c847a479948f 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Illusioner.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Illusioner.java
|
||||
@@ -1,6 +1,10 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
+
|
||||
/**
|
||||
* Represents an Illusioner "Illager".
|
||||
*/
|
||||
-public interface Illusioner extends Spellcaster { }
|
||||
+public interface Illusioner extends Spellcaster, RangedEntity { // Paper
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Llama.java b/src/main/java/org/bukkit/entity/Llama.java
|
||||
index c43854298548391679c1d280bd42edbeed7759b9..d23226ccb0f6c25028f000ce31346cd0a8898e6a 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Llama.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Llama.java
|
||||
@@ -1,12 +1,13 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
import org.bukkit.inventory.LlamaInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a Llama.
|
||||
*/
|
||||
-public interface Llama extends ChestedHorse {
|
||||
+public interface Llama extends ChestedHorse, RangedEntity { // Paper
|
||||
|
||||
/**
|
||||
* Represents the base color that the llama has.
|
||||
diff --git a/src/main/java/org/bukkit/entity/Piglin.java b/src/main/java/org/bukkit/entity/Piglin.java
|
||||
index b96e57552245e2c6d452755d4227c572266fcec7..6fdc0e0bb62189dbf3cf9ce7a87b7fbb995956a3 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Piglin.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Piglin.java
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a Piglin.
|
||||
*/
|
||||
-public interface Piglin extends PiglinAbstract, InventoryHolder {
|
||||
+public interface Piglin extends PiglinAbstract, InventoryHolder, com.destroystokyo.paper.entity.RangedEntity { // Paper
|
||||
|
||||
/**
|
||||
* Get whether the piglin is able to hunt hoglins.
|
||||
diff --git a/src/main/java/org/bukkit/entity/Pillager.java b/src/main/java/org/bukkit/entity/Pillager.java
|
||||
index 9a2252fef56be1ed3ae2169aea46cb567e965c6c..11f38187fca830d974be01fea2966a31936184cb 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Pillager.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Pillager.java
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity; // Paper
|
||||
+
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Illager entity.
|
||||
*/
|
||||
-public interface Pillager extends Illager, InventoryHolder { }
|
||||
+public interface Pillager extends Illager, InventoryHolder, RangedEntity { } // Paper
|
||||
diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java
|
||||
index 818efe2a4d1ac0c4d8dca6c757850d99cdc2cb4b..10f8f6d45ae9280651c3ebddd1f90acbd7d6ff29 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Snowman.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Snowman.java
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
+
|
||||
/**
|
||||
* Represents a snowman entity
|
||||
*/
|
||||
-public interface Snowman extends Golem {
|
||||
+public interface Snowman extends Golem, RangedEntity { // Paper
|
||||
|
||||
/**
|
||||
* Gets whether this snowman is in "derp mode", meaning it is not wearing a
|
||||
diff --git a/src/main/java/org/bukkit/entity/Witch.java b/src/main/java/org/bukkit/entity/Witch.java
|
||||
index b4343903b66a7fb5250c1da2e09c9e5863c20daf..aa88aede6c4e66a608a63d07bc66d60357b0bee9 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Witch.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Witch.java
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
+
|
||||
/**
|
||||
* Represents a Witch
|
||||
*/
|
||||
-public interface Witch extends Raider {
|
||||
+public interface Witch extends Raider, RangedEntity { // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Wither.java b/src/main/java/org/bukkit/entity/Wither.java
|
||||
index 3bc332ee7f7d428bef6e2566ddded8b941858e2e..426d3693317cd303d35d8203026b528d87e401d5 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Wither.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Wither.java
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.RangedEntity;
|
||||
+
|
||||
/**
|
||||
* Represents a Wither boss
|
||||
*/
|
||||
-public interface Wither extends Monster, Boss {
|
||||
+public interface Wither extends Monster, Boss, RangedEntity { // Paper
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 3 Jul 2018 16:07:16 +0200
|
||||
Subject: [PATCH] Add World.getEntity(UUID) API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 2bc0d5d6c81c21fd2c9318e968c3807f3e5474e0..e0c2ce5ad528ee1dd6293d0ed5ac3d6474c6d106 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -939,6 +939,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@NotNull
|
||||
public Collection<Entity> getNearbyEntities(@NotNull Location location, double x, double y, double z);
|
||||
|
||||
+ // Paper start - getEntity by UUID API
|
||||
+ /**
|
||||
+ * Gets an entity in this world by its UUID
|
||||
+ *
|
||||
+ * @param uuid the UUID of the entity
|
||||
+ * @return the entity with the given UUID, or null if it isn't found
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getEntity(@NotNull java.util.UUID uuid);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Returns a list of entities within a bounding box centered around a
|
||||
* Location.
|
|
@ -1,93 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 3 Jul 2018 21:52:52 -0400
|
||||
Subject: [PATCH] InventoryCloseEvent Reason API
|
||||
|
||||
Allows you to determine why an inventory was closed, enabling plugin developers
|
||||
to "confirm" things based on if it was player triggered close or not.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
index 5cc025b69c4f405be8f7098d0dcef40fa522b39f..1d573d33304e9c15a9949af68dab0626ae04dce4 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -158,6 +158,15 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
|
||||
*/
|
||||
public void closeInventory();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Force-closes the currently open inventory view for this player, if any.
|
||||
+ *
|
||||
+ * @param reason why the inventory is closing
|
||||
+ */
|
||||
+ public void closeInventory(@NotNull org.bukkit.event.inventory.InventoryCloseEvent.Reason reason);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Returns the ItemStack currently in your hand, can be empty.
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||
index 5861247c1b8ee4fe2736fd5098e05a2ca9ab78ea..21ad8888c0e403bfc63518502577d651c02dda05 100644
|
||||
--- a/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||
@@ -11,9 +11,60 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class InventoryCloseEvent extends InventoryEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
+ // Paper start
|
||||
+ private final Reason reason;
|
||||
+ @NotNull
|
||||
+ public Reason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+ public enum Reason {
|
||||
+ /**
|
||||
+ * Unknown reason
|
||||
+ */
|
||||
+ UNKNOWN,
|
||||
+ /**
|
||||
+ * Player is teleporting
|
||||
+ */
|
||||
+ TELEPORT,
|
||||
+ /**
|
||||
+ * Player is no longer permitted to use this inventory
|
||||
+ */
|
||||
+ CANT_USE,
|
||||
+ /**
|
||||
+ * The chunk the inventory was in was unloaded
|
||||
+ */
|
||||
+ UNLOADED,
|
||||
+ /**
|
||||
+ * Opening new inventory instead
|
||||
+ */
|
||||
+ OPEN_NEW,
|
||||
+ /**
|
||||
+ * Closed
|
||||
+ */
|
||||
+ PLAYER,
|
||||
+ /**
|
||||
+ * Closed due to disconnect
|
||||
+ */
|
||||
+ DISCONNECT,
|
||||
+ /**
|
||||
+ * The player died
|
||||
+ */
|
||||
+ DEATH,
|
||||
+ /**
|
||||
+ * Closed by Bukkit API
|
||||
+ */
|
||||
+ PLUGIN,
|
||||
+ }
|
||||
|
||||
public InventoryCloseEvent(@NotNull InventoryView transaction) {
|
||||
+ this(transaction, Reason.UNKNOWN);
|
||||
+ }
|
||||
+
|
||||
+ public InventoryCloseEvent(@NotNull InventoryView transaction, @NotNull Reason reason) {
|
||||
super(transaction);
|
||||
+ this.reason = reason;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 6 Oct 2018 21:47:09 -0500
|
||||
Subject: [PATCH] Allow setting the vex's summoner
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Vex.java b/src/main/java/org/bukkit/entity/Vex.java
|
||||
index 6b61c4ab773c731fe5ae9577fd13e44707be9787..c34a3ea7b4d16817b4bee25d5c69787e22ec44d8 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Vex.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Vex.java
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
/**
|
||||
* Represents a Vex.
|
||||
*/
|
||||
@@ -22,4 +24,21 @@ public interface Vex extends Monster {
|
||||
* @param charging new state
|
||||
*/
|
||||
void setCharging(boolean charging);
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get the Mob that summoned this vex
|
||||
+ *
|
||||
+ * @return Mob that summoned this vex
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Mob getSummoner();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the summoner of this vex
|
||||
+ *
|
||||
+ * @param summoner New summoner
|
||||
+ */
|
||||
+ void setSummoner(@Nullable Mob summoner);
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 Jul 2018 02:25:48 -0400
|
||||
Subject: [PATCH] Entity#getChunk API
|
||||
|
||||
Get the chunk the entity is currently registered to
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index d794ed97bd14c67584af9190bad7d0cd07001b05..0f1e456c8b278d0fb45871e6f57baf2c6234ed51 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.entity;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
+import org.bukkit.Chunk; // Paper
|
||||
import org.bukkit.EntityEffect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Nameable;
|
||||
@@ -680,5 +681,16 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
* @return True if entity spawned from a mob spawner
|
||||
*/
|
||||
boolean fromMobSpawner();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the latest chunk an entity is currently or was in.
|
||||
+ *
|
||||
+ * @return The current, or most recent chunk if the entity is invalid (which may load the chunk)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ default Chunk getChunk() {
|
||||
+ // TODO remove impl here
|
||||
+ return getLocation().getChunk();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <max@themoep.de>
|
||||
Date: Tue, 1 Dec 2020 14:57:02 +0100
|
||||
Subject: [PATCH] Add an asterisk to legacy API plugins
|
||||
|
||||
Not here to name and shame, only so server admins can be aware of which
|
||||
plugins have and haven't been updated.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
index 195b6bb328de92c4d17d1cd14e13578226b1ac3c..d6897f43a0692e031bed8a212d9a637ef548cc60 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -91,5 +91,11 @@ public interface UnsafeValues {
|
||||
default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
||||
return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher();
|
||||
}
|
||||
+
|
||||
+ boolean isSupportedApiVersion(String apiVersion);
|
||||
+
|
||||
+ static boolean isLegacyPlugin(org.bukkit.plugin.Plugin plugin) {
|
||||
+ return !Bukkit.getUnsafe().isSupportedApiVersion(plugin.getDescription().getAPIVersion());
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
index 4de959bbd1270d7d6ea8e5e69521bcca6abe2138..1aa58c59e1e8738bbdc77752885ff3b18b29de42 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
@@ -52,9 +52,15 @@ public class PluginsCommand extends BukkitCommand {
|
||||
}
|
||||
|
||||
Plugin plugin = entry.getValue();
|
||||
-
|
||||
+
|
||||
pluginList.append(plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED);
|
||||
- pluginList.append(plugin.getDescription().getName());
|
||||
+ // Paper start - Add an asterisk to legacy plugins (so admins are aware)
|
||||
+ String pluginName = plugin.getDescription().getName();
|
||||
+ if (org.bukkit.UnsafeValues.isLegacyPlugin(plugin)) {
|
||||
+ pluginName += "*";
|
||||
+ }
|
||||
+ pluginList.append(pluginName);
|
||||
+ // Paper end
|
||||
|
||||
if (plugin.getDescription().getProvides().size() > 0) {
|
||||
pluginList.append(" (").append(String.join(", ", plugin.getDescription().getProvides())).append(")");
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index 816c2b1797447ab315ceb6eda89d25f27d2bce98..f26303315c9c93356f0b04440136855dd54d32b7 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -306,7 +306,14 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
Validate.isTrue(plugin instanceof JavaPlugin, "Plugin is not associated with this PluginLoader");
|
||||
|
||||
if (!plugin.isEnabled()) {
|
||||
- plugin.getLogger().info("Enabling " + plugin.getDescription().getFullName());
|
||||
+ // Paper start - Add an asterisk to legacy plugins (so admins are aware)
|
||||
+ String enableMsg = "Enabling " + plugin.getDescription().getFullName();
|
||||
+ if (org.bukkit.UnsafeValues.isLegacyPlugin(plugin)) {
|
||||
+ enableMsg += "*";
|
||||
+ }
|
||||
+
|
||||
+ plugin.getLogger().info(enableMsg);
|
||||
+ // Paper end
|
||||
|
||||
JavaPlugin jPlugin = (JavaPlugin) plugin;
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:51:05 -0500
|
||||
Subject: [PATCH] EnderDragon Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..118c7b6772a52c250649af2a9286f483f43da385
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java
|
||||
@@ -0,0 +1,79 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.AreaEffectCloud;
|
||||
+import org.bukkit.entity.DragonFireball;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a DragonFireball collides with a block/entity and spawns an AreaEffectCloud
|
||||
+ */
|
||||
+public class EnderDragonFireballHitEvent extends EntityEvent implements Cancellable {
|
||||
+ @Nullable private final Collection<LivingEntity> targets;
|
||||
+ @NotNull private final AreaEffectCloud areaEffectCloud;
|
||||
+
|
||||
+ public EnderDragonFireballHitEvent(@NotNull DragonFireball fireball, @Nullable Collection<LivingEntity> targets, @NotNull AreaEffectCloud areaEffectCloud) {
|
||||
+ super(fireball);
|
||||
+ this.targets = targets;
|
||||
+ this.areaEffectCloud = areaEffectCloud;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The fireball involved in this event
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public DragonFireball getEntity() {
|
||||
+ return (DragonFireball) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The living entities hit by fireball
|
||||
+ *
|
||||
+ * May be null if no entities were hit
|
||||
+ *
|
||||
+ * @return the targets
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Collection<LivingEntity> getTargets() {
|
||||
+ return targets;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The area effect cloud spawned in this collision
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public AreaEffectCloud getAreaEffectCloud() {
|
||||
+ return areaEffectCloud;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1915177f4b8f8013656fbdb41240f6c5c88f95d7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
|
||||
@@ -0,0 +1,61 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.AreaEffectCloud;
|
||||
+import org.bukkit.entity.EnderDragon;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an EnderDragon spawns an AreaEffectCloud by shooting flames
|
||||
+ */
|
||||
+public class EnderDragonFlameEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final AreaEffectCloud areaEffectCloud;
|
||||
+
|
||||
+ public EnderDragonFlameEvent(@NotNull EnderDragon enderDragon, @NotNull AreaEffectCloud areaEffectCloud) {
|
||||
+ super(enderDragon);
|
||||
+ this.areaEffectCloud = areaEffectCloud;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The enderdragon involved in this event
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public EnderDragon getEntity() {
|
||||
+ return (EnderDragon) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The area effect cloud spawned in this collision
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public AreaEffectCloud getAreaEffectCloud() {
|
||||
+ return areaEffectCloud;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8414bd805ec68d7b305fbf645c59f8d5b762c9ce
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java
|
||||
@@ -0,0 +1,61 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.DragonFireball;
|
||||
+import org.bukkit.entity.EnderDragon;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an EnderDragon shoots a fireball
|
||||
+ */
|
||||
+public class EnderDragonShootFireballEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final DragonFireball fireball;
|
||||
+
|
||||
+ public EnderDragonShootFireballEvent(@NotNull EnderDragon entity, @NotNull DragonFireball fireball) {
|
||||
+ super(entity);
|
||||
+ this.fireball = fireball;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The enderdragon shooting the fireball
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public EnderDragon getEntity() {
|
||||
+ return (EnderDragon) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The fireball being shot
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public DragonFireball getFireball() {
|
||||
+ return fireball;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,97 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:59:53 -0500
|
||||
Subject: [PATCH] PlayerElytraBoostEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e9a76a25fa5445905a09dbc2fd5b35bff56d80b3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java
|
||||
@@ -0,0 +1,85 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Firework;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a player boosts elytra flight with a firework
|
||||
+ */
|
||||
+public class PlayerElytraBoostEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled = false;
|
||||
+ @NotNull private final ItemStack itemStack;
|
||||
+ @NotNull private Firework firework;
|
||||
+ private boolean consume = true;
|
||||
+
|
||||
+ public PlayerElytraBoostEvent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull Firework firework) {
|
||||
+ super(player);
|
||||
+ this.itemStack = itemStack;
|
||||
+ this.firework = firework;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the firework itemstack used
|
||||
+ *
|
||||
+ * @return ItemStack of firework
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack getItemStack() {
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the firework entity that was spawned
|
||||
+ *
|
||||
+ * @return Firework entity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Firework getFirework() {
|
||||
+ return firework;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get whether to consume the firework or not
|
||||
+ *
|
||||
+ * @return True to consume
|
||||
+ */
|
||||
+ public boolean shouldConsume() {
|
||||
+ return consume;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether to consume the firework or not
|
||||
+ *
|
||||
+ * @param consume True to consume
|
||||
+ */
|
||||
+ public void setShouldConsume(boolean consume) {
|
||||
+ this.consume = consume;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -1,95 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 03:10:50 -0500
|
||||
Subject: [PATCH] PlayerLaunchProjectileEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9074b2ede01f76c0560e5318246382163cc91591
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java
|
||||
@@ -0,0 +1,83 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.entity.Projectile;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a player shoots a projectile
|
||||
+ */
|
||||
+public class PlayerLaunchProjectileEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final Projectile projectile;
|
||||
+ @NotNull private final ItemStack itemStack;
|
||||
+ private boolean consumeItem = true;
|
||||
+ private boolean cancelled;
|
||||
+
|
||||
+ public PlayerLaunchProjectileEvent(@NotNull Player shooter, @NotNull ItemStack itemStack, @NotNull Projectile projectile) {
|
||||
+ super(shooter);
|
||||
+ this.itemStack = itemStack;
|
||||
+ this.projectile = projectile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the projectile which will be launched by this event
|
||||
+ *
|
||||
+ * @return the launched projectile
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Projectile getProjectile() {
|
||||
+ return projectile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the ItemStack used to fire the projectile
|
||||
+ *
|
||||
+ * @return The ItemStack used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack getItemStack() {
|
||||
+ return itemStack;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get whether to consume the ItemStack or not
|
||||
+ *
|
||||
+ * @return True to consume
|
||||
+ */
|
||||
+ public boolean shouldConsume() {
|
||||
+ return consumeItem;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether to consume the ItemStack or not
|
||||
+ *
|
||||
+ * @param consumeItem True to consume
|
||||
+ */
|
||||
+ public void setShouldConsume(boolean consumeItem) {
|
||||
+ this.consumeItem = consumeItem;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
|
@ -1,104 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anthony MacAllister <anthonymmacallister@gmail.com>
|
||||
Date: Thu, 26 Jul 2018 15:28:53 -0400
|
||||
Subject: [PATCH] EntityTransformedEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityTransformedEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityTransformedEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..12194f1fc7f03ca6785904b6187b3dfd03b16461
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityTransformedEvent.java
|
||||
@@ -0,0 +1,92 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.event.entity.EntityTransformEvent;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an entity transforms into another entity
|
||||
+ * <p>
|
||||
+ * If the event is cancelled, the entity will not transform
|
||||
+ * @deprecated Bukkit has added {@link EntityTransformEvent}, you should start using that
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class EntityTransformedEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ private final Entity transformed;
|
||||
+ private final TransformedReason reason;
|
||||
+
|
||||
+ public EntityTransformedEvent(Entity entity, Entity transformed, TransformedReason reason) {
|
||||
+ super(entity);
|
||||
+ this.transformed = transformed;
|
||||
+ this.reason = reason;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The entity after it has transformed
|
||||
+ *
|
||||
+ * @return Transformed entity
|
||||
+ * @deprecated see {@link EntityTransformEvent#getTransformedEntity()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public Entity getTransformed() {
|
||||
+ return transformed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The reason for the transformation
|
||||
+ * @deprecated see {@link EntityTransformEvent#getTransformReason()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public TransformedReason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers(){
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static HandlerList getHandlerList(){
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled(){
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel){
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ public enum TransformedReason {
|
||||
+ /**
|
||||
+ * When a zombie drowns
|
||||
+ */
|
||||
+ DROWNED,
|
||||
+ /**
|
||||
+ * When a zombie villager is cured
|
||||
+ */
|
||||
+ CURED,
|
||||
+ /**
|
||||
+ * When a villager turns to a zombie villager
|
||||
+ */
|
||||
+ INFECTED,
|
||||
+ /**
|
||||
+ * When a mooshroom turns to a cow
|
||||
+ */
|
||||
+ SHEARED,
|
||||
+ /**
|
||||
+ * When a pig turns to a zombiepigman
|
||||
+ */
|
||||
+ LIGHTNING
|
||||
+
|
||||
+ }
|
||||
+}
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 15 Aug 2018 01:26:03 -0700
|
||||
Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ArmorStand.java b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
index 7dc631ebd009f5f5c3ac1699c3f3515c47609c05..2ee3814a52945f541e049b621b9552f8ae9e261d 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -363,5 +363,21 @@ public interface ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
org.bukkit.inventory.@NotNull EntityEquipment getEquipment();
|
||||
+
|
||||
+ /**
|
||||
+ * Tests if this armor stand can tick.
|
||||
+ *
|
||||
+ * <p>The default value is defined in {@code paper.yml}.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if this armour stand can tick, {@code false} otherwise
|
||||
+ */
|
||||
+ boolean canTick();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if this armor stand can tick.
|
||||
+ *
|
||||
+ * @param tick {@code true} if this armour stand can tick, {@code false} otherwise
|
||||
+ */
|
||||
+ void setCanTick(final boolean tick);
|
||||
// Paper end
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 27 Jul 2018 22:36:17 -0500
|
||||
Subject: [PATCH] SkeletonHorse Additions
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9ce2948dfaa56d0adf53fe9b6117a90d7773b771
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java
|
||||
@@ -0,0 +1,62 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+import org.bukkit.entity.SkeletonHorse;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+/**
|
||||
+ * Event called when a player gets close to a skeleton horse and triggers the lightning trap
|
||||
+ */
|
||||
+public class SkeletonHorseTrapEvent extends EntityEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ private final List<HumanEntity> eligibleHumans;
|
||||
+
|
||||
+ public SkeletonHorseTrapEvent(@NotNull SkeletonHorse horse) {
|
||||
+ this(horse, ImmutableList.of());
|
||||
+ }
|
||||
+
|
||||
+ public SkeletonHorseTrapEvent(@NotNull SkeletonHorse horse, @NotNull List<HumanEntity> eligibleHumans) {
|
||||
+ super(horse);
|
||||
+ this.eligibleHumans = eligibleHumans;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public SkeletonHorse getEntity() {
|
||||
+ return (SkeletonHorse) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public List<HumanEntity> getEligibleHumans() {
|
||||
+ return eligibleHumans;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/src/main/java/org/bukkit/entity/SkeletonHorse.java b/src/main/java/org/bukkit/entity/SkeletonHorse.java
|
||||
index b2c6b6a8689f6bd6ce784bbe6f571f756dd700c1..ba9983463263f77db3d3487bc12f01db4508a32b 100644
|
||||
--- a/src/main/java/org/bukkit/entity/SkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/entity/SkeletonHorse.java
|
||||
@@ -3,4 +3,12 @@ package org.bukkit.entity;
|
||||
/**
|
||||
* Represents a SkeletonHorse - variant of {@link AbstractHorse}.
|
||||
*/
|
||||
-public interface SkeletonHorse extends AbstractHorse { }
|
||||
+public interface SkeletonHorse extends AbstractHorse {
|
||||
+ // Paper start
|
||||
+ int getTrapTime();
|
||||
+
|
||||
+ boolean isTrap();
|
||||
+
|
||||
+ void setTrap(boolean trap);
|
||||
+ // Paper end
|
||||
+}
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 25 Jul 2018 01:36:07 -0400
|
||||
Subject: [PATCH] Expand Location Manipulation API
|
||||
|
||||
Adds set(x, y, z), add(base, x, y, z), subtract(base, x, y, z);
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index a8d4f7972d07ddde171b4a1ec470a4c616e02b2e..36ed248f0716f2cc465c08ab851b7d83d4c7c0a7 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -546,6 +546,54 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
|
||||
|
||||
// Paper start
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the position of this Location and returns itself
|
||||
+ *
|
||||
+ * This mutates this object, clone first.
|
||||
+ * @param x X coordinate
|
||||
+ * @param y Y coordinate
|
||||
+ * @param z Z coordinate
|
||||
+ * @return self (not cloned)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location set(double x, double y, double z) {
|
||||
+ this.x = x;
|
||||
+ this.y = y;
|
||||
+ this.z = z;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Takes the x/y/z from base and adds the specified x/y/z to it and returns self
|
||||
+ *
|
||||
+ * This mutates this object, clone first.
|
||||
+ * @param base The base coordinate to modify
|
||||
+ * @param x X coordinate to add to base
|
||||
+ * @param y Y coordinate to add to base
|
||||
+ * @param z Z coordinate to add to base
|
||||
+ * @return self (not cloned)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location add(@NotNull Location base, double x, double y, double z) {
|
||||
+ return this.set(base.x + x, base.y + y, base.z + z);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Takes the x/y/z from base and subtracts the specified x/y/z to it and returns self
|
||||
+ *
|
||||
+ * This mutates this object, clone first.
|
||||
+ * @param base The base coordinate to modify
|
||||
+ * @param x X coordinate to subtract from base
|
||||
+ * @param y Y coordinate to subtract from base
|
||||
+ * @param z Z coordinate to subtract from base
|
||||
+ * @return self (not cloned)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location subtract(@NotNull Location base, double x, double y, double z) {
|
||||
+ return this.set(base.x - x, base.y - y, base.z - z);
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* @return A new location where X/Y/Z are on the Block location (integer value of X/Y/Z)
|
||||
*/
|
|
@ -1,103 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 26 Jul 2018 02:22:44 -0400
|
||||
Subject: [PATCH] Expand ArmorStand API
|
||||
|
||||
Add the following:
|
||||
- Add proper methods for getting and setting items in both hands. Deprecates old methods
|
||||
- Enable/Disable slot interactions
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ArmorStand.java b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
index 2ee3814a52945f541e049b621b9552f8ae9e261d..707639096657f995cc812c7b50108eeed48e8181 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -14,7 +14,7 @@ public interface ArmorStand extends LivingEntity {
|
||||
*
|
||||
* @return the held item
|
||||
* @see #getEquipment()
|
||||
- * @deprecated prefer {@link EntityEquipment#getItemInHand()}
|
||||
+ * @deprecated prefer {@link ArmorStand#getItem(EquipmentSlot)} // Paper
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated
|
||||
@@ -26,7 +26,7 @@ public interface ArmorStand extends LivingEntity {
|
||||
* @param item the item to hold
|
||||
* @see #getEquipment()
|
||||
* @deprecated prefer
|
||||
- * {@link EntityEquipment#setItemInHand(org.bukkit.inventory.ItemStack)}
|
||||
+ * {@link ArmorStand#setItem(EquipmentSlot, ItemStack)} // Paper
|
||||
*/
|
||||
@Deprecated
|
||||
void setItemInHand(@Nullable ItemStack item);
|
||||
@@ -379,5 +379,71 @@ public interface ArmorStand extends LivingEntity {
|
||||
* @param tick {@code true} if this armour stand can tick, {@code false} otherwise
|
||||
*/
|
||||
void setCanTick(final boolean tick);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the item the armor stand has
|
||||
+ * equip in the given equipment slot
|
||||
+ *
|
||||
+ * @param slot the equipment slot to get
|
||||
+ * @return the ItemStack in the equipment slot
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ ItemStack getItem(@NotNull final org.bukkit.inventory.EquipmentSlot slot);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the item the armor stand has
|
||||
+ * equip in the given equipment slot
|
||||
+ *
|
||||
+ * @param slot the equipment slot to set
|
||||
+ * @param item the item to hold
|
||||
+ */
|
||||
+ void setItem(@NotNull final org.bukkit.inventory.EquipmentSlot slot, @Nullable final ItemStack item);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the list of disabled slots
|
||||
+ *
|
||||
+ * @return list of disabled slots
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> getDisabledSlots();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the disabled slots
|
||||
+ *
|
||||
+ * This makes it so a player is unable to interact with the Armor Stand to place, remove, or replace an item in the given slot(s)
|
||||
+ * Note: Once a slot is disabled, the only way to get an item back it to break the armor stand.
|
||||
+ *
|
||||
+ * @param slots var-arg array of slots to lock
|
||||
+ */
|
||||
+ void setDisabledSlots(@NotNull org.bukkit.inventory.EquipmentSlot... slots);
|
||||
+
|
||||
+ /**
|
||||
+ * Disable specific slots, adding them
|
||||
+ * to the currently disabled slots
|
||||
+ *
|
||||
+ * This makes it so a player is unable to interact with the Armor Stand to place, remove, or replace an item in the given slot(s)
|
||||
+ * Note: Once a slot is disabled, the only way to get an item back it to break the armor stand.
|
||||
+ *
|
||||
+ * @param slots var-arg array of slots to lock
|
||||
+ */
|
||||
+ void addDisabledSlots(@NotNull final org.bukkit.inventory.EquipmentSlot... slots);
|
||||
+
|
||||
+ /**
|
||||
+ * Remove the given slots from the disabled
|
||||
+ * slots list, enabling them.
|
||||
+ *
|
||||
+ * This makes it so a player is able to interact with the Armor Stand to place, remove, or replace an item in the given slot(s)
|
||||
+ *
|
||||
+ * @param slots var-arg array of slots to unlock
|
||||
+ */
|
||||
+ void removeDisabledSlots(@NotNull final org.bukkit.inventory.EquipmentSlot... slots);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if a specific slot is disabled
|
||||
+ *
|
||||
+ * @param slot The slot to check
|
||||
+ * @return {@code true} if the slot is disabled, else {@code false}.
|
||||
+ */
|
||||
+ boolean isSlotDisabled(@NotNull org.bukkit.inventory.EquipmentSlot slot);
|
||||
// Paper end
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 20 Jul 2018 23:36:55 -0500
|
||||
Subject: [PATCH] AnvilDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a83c286c1c11af25fc4d16af7a42b95ce90b9dee
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
|
||||
@@ -0,0 +1,148 @@
|
||||
+package com.destroystokyo.paper.event.block;
|
||||
+
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.block.data.BlockData;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.inventory.InventoryEvent;
|
||||
+import org.bukkit.inventory.AnvilInventory;
|
||||
+import org.bukkit.inventory.InventoryView;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Called when an anvil is damaged from being used
|
||||
+ */
|
||||
+public class AnvilDamagedEvent extends InventoryEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancel;
|
||||
+ private DamageState damageState;
|
||||
+
|
||||
+ public AnvilDamagedEvent(@NotNull InventoryView inventory, @NotNull BlockData blockData) {
|
||||
+ super(inventory);
|
||||
+ this.damageState = DamageState.getState(blockData);
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public AnvilInventory getInventory() {
|
||||
+ return (AnvilInventory) super.getInventory();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the new state of damage on the anvil
|
||||
+ *
|
||||
+ * @return Damage state
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public DamageState getDamageState() {
|
||||
+ return damageState;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the new state of damage on the anvil
|
||||
+ *
|
||||
+ * @param damageState Damage state
|
||||
+ */
|
||||
+ public void setDamageState(@NotNull DamageState damageState) {
|
||||
+ this.damageState = damageState;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets if anvil is breaking on this use
|
||||
+ *
|
||||
+ * @return True if breaking
|
||||
+ */
|
||||
+ public boolean isBreaking() {
|
||||
+ return damageState == DamageState.BROKEN;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if anvil is breaking on this use
|
||||
+ *
|
||||
+ * @param breaking True if breaking
|
||||
+ */
|
||||
+ public void setBreaking(boolean breaking) {
|
||||
+ if (breaking) {
|
||||
+ damageState = DamageState.BROKEN;
|
||||
+ } else if (damageState == DamageState.BROKEN) {
|
||||
+ damageState = DamageState.DAMAGED;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Represents the amount of damage on an anvil block
|
||||
+ */
|
||||
+ public enum DamageState {
|
||||
+ FULL(Material.ANVIL),
|
||||
+ CHIPPED(Material.CHIPPED_ANVIL),
|
||||
+ DAMAGED(Material.DAMAGED_ANVIL),
|
||||
+ BROKEN(Material.AIR);
|
||||
+
|
||||
+ private Material material;
|
||||
+
|
||||
+ DamageState(@NotNull Material material) {
|
||||
+ this.material = material;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get block material of this state
|
||||
+ *
|
||||
+ * @return Material
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Material getMaterial() {
|
||||
+ return material;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get damaged state by block data
|
||||
+ *
|
||||
+ * @param blockData Block data
|
||||
+ * @return DamageState
|
||||
+ * @throws IllegalArgumentException If non anvil block data is given
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static DamageState getState(@Nullable BlockData blockData) {
|
||||
+ return blockData == null ? BROKEN : getState(blockData.getMaterial());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get damaged state by block material
|
||||
+ *
|
||||
+ * @param material Block material
|
||||
+ * @return DamageState
|
||||
+ * @throws IllegalArgumentException If non anvil material is given
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static DamageState getState(@Nullable Material material) {
|
||||
+ if (material == null) {
|
||||
+ return BROKEN;
|
||||
+ }
|
||||
+ for (DamageState state : values()) {
|
||||
+ if (state.material == material) {
|
||||
+ return state;
|
||||
+ }
|
||||
+ }
|
||||
+ throw new IllegalArgumentException("Material not an anvil");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -1,124 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 9 Sep 2018 00:32:05 -0400
|
||||
Subject: [PATCH] Remove deadlock risk in firing async events
|
||||
|
||||
The PluginManager incorrectly used synchronization on firing any event
|
||||
that was marked as synchronous.
|
||||
|
||||
This synchronized did not even protect any concurrency risk as
|
||||
handlers were already thread safe in terms of mutations during event
|
||||
dispatch.
|
||||
|
||||
The way it was used, has commonly led to deadlocks on the server,
|
||||
which results in a hard crash.
|
||||
|
||||
This change removes the synchronize and adds some protection around enable/disable
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 7867243a8ed67416895cdcd949ac424f5d29d98b..a3027c1c6109bcb20d0468f6d0cd37182bb279ea 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -462,7 +462,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
* @return true if the plugin is enabled, otherwise false
|
||||
*/
|
||||
@Override
|
||||
- public boolean isPluginEnabled(@Nullable Plugin plugin) {
|
||||
+ public synchronized boolean isPluginEnabled(@Nullable Plugin plugin) { // Paper - synchronize
|
||||
if ((plugin != null) && (plugins.contains(plugin))) {
|
||||
return plugin.isEnabled();
|
||||
} else {
|
||||
@@ -471,7 +471,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void enablePlugin(@NotNull final Plugin plugin) {
|
||||
+ public synchronized void enablePlugin(@NotNull final Plugin plugin) { // Paper - synchronize
|
||||
if (!plugin.isEnabled()) {
|
||||
List<Command> pluginCommands = PluginCommandYamlParser.parse(plugin);
|
||||
|
||||
@@ -514,7 +514,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
- public void disablePlugin(@NotNull final Plugin plugin) {
|
||||
+ public synchronized void disablePlugin(@NotNull final Plugin plugin) { // Paper - synchronize
|
||||
if (plugin.isEnabled()) {
|
||||
try {
|
||||
plugin.getPluginLoader().disablePlugin(plugin);
|
||||
@@ -583,6 +583,7 @@ public final class SimplePluginManager implements PluginManager {
|
||||
defaultPerms.get(false).clear();
|
||||
}
|
||||
}
|
||||
+ private void fireEvent(Event event) { callEvent(event); } // Paper - support old method incase plugin uses reflection
|
||||
|
||||
/**
|
||||
* Calls an event with the given details.
|
||||
@@ -591,23 +592,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
*/
|
||||
@Override
|
||||
public void callEvent(@NotNull Event event) {
|
||||
- if (event.isAsynchronous()) {
|
||||
- if (Thread.holdsLock(this)) {
|
||||
- throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
|
||||
- }
|
||||
- if (server.isPrimaryThread()) {
|
||||
- throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
|
||||
- }
|
||||
- } else {
|
||||
- if (!server.isPrimaryThread()) {
|
||||
- throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from another thread.");
|
||||
- }
|
||||
+ // Paper - replace callEvent by merging to below method
|
||||
+ if (event.isAsynchronous() && server.isPrimaryThread()) {
|
||||
+ throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
|
||||
+ } else if (!event.isAsynchronous() && !server.isPrimaryThread()) {
|
||||
+ throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
|
||||
}
|
||||
|
||||
- fireEvent(event);
|
||||
- }
|
||||
-
|
||||
- private void fireEvent(@NotNull Event event) {
|
||||
HandlerList handlers = event.getHandlers();
|
||||
RegisteredListener[] listeners = handlers.getRegisteredListeners();
|
||||
|
||||
diff --git a/src/test/java/org/bukkit/plugin/PluginManagerTest.java b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
index f188cd4f3b07027c30d41f1162db77a506b7b6bb..1941c9f49e9514c1236c5f4ea9f7af47f7be85c5 100644
|
||||
--- a/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
+++ b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
@@ -17,7 +17,7 @@ public class PluginManagerTest {
|
||||
private static final PluginManager pm = TestServer.getInstance().getPluginManager();
|
||||
|
||||
private final MutableObject store = new MutableObject();
|
||||
-
|
||||
+/* // Paper start - remove unneeded test
|
||||
@Test
|
||||
public void testAsyncSameThread() {
|
||||
final Event event = new TestEvent(true);
|
||||
@@ -28,14 +28,14 @@ public class PluginManagerTest {
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("No exception thrown");
|
||||
- }
|
||||
+ }*/ // Paper end
|
||||
|
||||
@Test
|
||||
public void testSyncSameThread() {
|
||||
final Event event = new TestEvent(false);
|
||||
pm.callEvent(event);
|
||||
}
|
||||
-
|
||||
+/* // Paper start - remove unneeded test
|
||||
@Test
|
||||
public void testAsyncLocked() throws InterruptedException {
|
||||
final Event event = new TestEvent(true);
|
||||
@@ -129,7 +129,7 @@ public class PluginManagerTest {
|
||||
if (store.value == null) {
|
||||
throw new IllegalStateException("No exception thrown");
|
||||
}
|
||||
- }
|
||||
+ } */ // Paper
|
||||
|
||||
@Test
|
||||
public void testRemovePermissionByNameLower() {
|
|
@ -1,130 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Thu, 2 Aug 2018 08:44:20 -0500
|
||||
Subject: [PATCH] Add hand to bucket events
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
|
||||
index 7f225baa9fd3ff6f4f950ae70f9500141c674f66..25bd8153ef2ab7ab1052cf756bb599f1095732e7 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -22,6 +23,16 @@ public class PlayerBucketEmptyEvent extends PlayerBucketEvent {
|
||||
public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
|
||||
super(who, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
}
|
||||
+ // Paper start - add EquipmentSlot
|
||||
+ @Deprecated
|
||||
+ public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
|
||||
+ super(who, blockClicked, blockFace, bucket, itemInHand, hand);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
|
||||
+ super(who, block, blockClicked, blockFace, bucket, itemInHand, hand);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
|
||||
index 0e4fa04ea73baaf2f9ad86725d379b569d7d6381..1e0f7ee7d198c08ce421ce105be42c4d01dc924f 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -19,6 +20,7 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
|
||||
private final Block blockClicked;
|
||||
private final BlockFace blockFace;
|
||||
private final Material bucket;
|
||||
+ private final EquipmentSlot hand; // Paper - add EquipmentSlot
|
||||
|
||||
@Deprecated
|
||||
public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
|
||||
@@ -26,12 +28,24 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
|
||||
}
|
||||
|
||||
public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) {
|
||||
+ // Paper start - add EquipmentSlot
|
||||
+ this(who, block, blockClicked, blockFace, bucket, itemInHand, null);
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public PlayerBucketEvent(@NotNull final Player who,@NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @Nullable final EquipmentSlot hand) {
|
||||
+ this(who, null, blockClicked, blockFace, bucket, itemInHand, hand);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @Nullable final EquipmentSlot hand) {
|
||||
+ // Paper end
|
||||
super(who);
|
||||
this.block = block;
|
||||
this.blockClicked = blockClicked;
|
||||
this.blockFace = blockFace;
|
||||
this.itemStack = itemInHand;
|
||||
this.bucket = bucket;
|
||||
+ this.hand = hand == null ? player.getInventory().getItemInMainHand().equals(itemInHand) ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND : hand; // Paper - add EquipmentSlot
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,6 +107,18 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab
|
||||
return blockFace;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * The hand used to perform this action.
|
||||
+ *
|
||||
+ * @return the hand used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EquipmentSlot getHand() {
|
||||
+ return hand;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java b/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
|
||||
index 77c3a6e5c89ffde564d63b98b2d9e36c356d79fd..56f1cc2d773d2c58207ee291bac596692980a731 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -23,6 +24,18 @@ public class PlayerBucketFillEvent extends PlayerBucketEvent {
|
||||
super(who, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
}
|
||||
|
||||
+ // Paper start - add EquipmentSlot
|
||||
+ @Deprecated
|
||||
+ public PlayerBucketFillEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
|
||||
+ super(who, blockClicked, blockFace, bucket, itemInHand, hand);
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - add EquipmentSlot
|
||||
+ public PlayerBucketFillEvent(@NotNull final Player who, @NotNull Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @org.jetbrains.annotations.Nullable final EquipmentSlot hand) {
|
||||
+ super(who, block, blockClicked, blockFace, bucket, itemInHand, hand);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
|
@ -1,126 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 15 Jul 2018 22:17:55 +0300
|
||||
Subject: [PATCH] Add TNTPrimeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/block/TNTPrimeEvent.java b/src/main/java/com/destroystokyo/paper/event/block/TNTPrimeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..73dabb82c7fbea3f0cccade0a2944b11a80ede06
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/TNTPrimeEvent.java
|
||||
@@ -0,0 +1,114 @@
|
||||
+package com.destroystokyo.paper.event.block;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.block.BlockEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Called when TNT block is about to turn into {@link org.bukkit.entity.TNTPrimed}
|
||||
+ * <p>
|
||||
+ * Cancelling it won't turn TNT into {@link org.bukkit.entity.TNTPrimed} and leaves
|
||||
+ * the TNT block as-is
|
||||
+ *
|
||||
+ * @author Mark Vainomaa
|
||||
+ */
|
||||
+public class TNTPrimeEvent extends BlockEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ @NotNull private PrimeReason reason;
|
||||
+ @Nullable private Entity primerEntity;
|
||||
+
|
||||
+ public TNTPrimeEvent(@NotNull Block theBlock, @NotNull PrimeReason reason, @Nullable Entity primerEntity) {
|
||||
+ super(theBlock);
|
||||
+ this.reason = reason;
|
||||
+ this.primerEntity = primerEntity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the TNT prime reason
|
||||
+ *
|
||||
+ * @return Prime reason
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PrimeReason getReason() {
|
||||
+ return this.reason;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the TNT primer {@link Entity}.
|
||||
+ *
|
||||
+ * It's null if {@link #getReason()} is {@link PrimeReason#REDSTONE} or {@link PrimeReason#FIRE}.
|
||||
+ * It's not null if {@link #getReason()} is {@link PrimeReason#ITEM} or {@link PrimeReason#PROJECTILE}
|
||||
+ * It might be null if {@link #getReason()} is {@link PrimeReason#EXPLOSION}
|
||||
+ *
|
||||
+ * @return The {@link Entity} who primed the TNT
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getPrimerEntity() {
|
||||
+ return this.primerEntity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether spawning {@link org.bukkit.entity.TNTPrimed} should be cancelled or not
|
||||
+ *
|
||||
+ * @return Whether spawning {@link org.bukkit.entity.TNTPrimed} should be cancelled or not
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether to cancel spawning {@link org.bukkit.entity.TNTPrimed} or not
|
||||
+ *
|
||||
+ * @param cancel whether spawning {@link org.bukkit.entity.TNTPrimed} should be cancelled or not
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public enum PrimeReason {
|
||||
+ /**
|
||||
+ * When TNT prime was caused by other explosion (chain reaction)
|
||||
+ */
|
||||
+ EXPLOSION,
|
||||
+
|
||||
+ /**
|
||||
+ * When TNT prime was caused by fire
|
||||
+ */
|
||||
+ FIRE,
|
||||
+
|
||||
+ /**
|
||||
+ * When {@link org.bukkit.entity.Player} used {@link org.bukkit.Material#FLINT_AND_STEEL} or
|
||||
+ * {@link org.bukkit.Material#FIRE_CHARGE} on given TNT block
|
||||
+ */
|
||||
+ ITEM,
|
||||
+
|
||||
+ /**
|
||||
+ * When TNT prime was caused by an {@link Entity} shooting TNT
|
||||
+ * using a bow with {@link org.bukkit.enchantments.Enchantment#ARROW_FIRE} enchantment
|
||||
+ */
|
||||
+ PROJECTILE,
|
||||
+
|
||||
+ /**
|
||||
+ * When redstone power triggered the TNT prime
|
||||
+ */
|
||||
+ REDSTONE
|
||||
+ }
|
||||
+}
|
|
@ -1,72 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 4 Aug 2018 19:37:35 -0400
|
||||
Subject: [PATCH] Provide Chunk Coordinates as a Long API
|
||||
|
||||
Allows you to easily access the chunks X/z as a long, and a method
|
||||
to look up by the long key too.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
|
||||
index 5fd6030b2693d793951ed632ad4870e1a6f909aa..40ddeb7abd49eeece531a8e90b4508f3831cc3e9 100644
|
||||
--- a/src/main/java/org/bukkit/Chunk.java
|
||||
+++ b/src/main/java/org/bukkit/Chunk.java
|
||||
@@ -28,6 +28,32 @@ public interface Chunk extends PersistentDataHolder {
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @return The Chunks X and Z coordinates packed into a long
|
||||
+ */
|
||||
+ default long getChunkKey() {
|
||||
+ return getChunkKey(getX(), getZ());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param loc Location to get chunk key
|
||||
+ * @return Location's chunk coordinates packed into a long
|
||||
+ */
|
||||
+ static long getChunkKey(@NotNull Location loc) {
|
||||
+ return getChunkKey((int) Math.floor(loc.getX()) >> 4, (int) Math.floor(loc.getZ()) >> 4);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param x X Coordinate
|
||||
+ * @param z Z Coordinate
|
||||
+ * @return Chunk coordinates packed into a long
|
||||
+ */
|
||||
+ static long getChunkKey(int x, int z) {
|
||||
+ return (long) x & 0xffffffffL | ((long) z & 0xffffffffL) << 32;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the world containing this chunk
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index e0c2ce5ad528ee1dd6293d0ed5ac3d6474c6d106..33558b6acc861f8b9986122c7c553f9dde22a45d 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -207,6 +207,22 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@NotNull
|
||||
public Chunk getChunkAt(@NotNull Block block);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the chunk at the specified chunk key, which is the X and Z packed into a long.
|
||||
+ *
|
||||
+ * See {@link Chunk#getChunkKey()} for easy access to the key, or you may calculate it as:
|
||||
+ * long chunkKey = (long) chunkX & 0xffffffffL | ((long) chunkZ & 0xffffffffL) >> 32;
|
||||
+ *
|
||||
+ * @param chunkKey The Chunk Key to look up the chunk by
|
||||
+ * @return The chunk at the specified key
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Chunk getChunkAt(long chunkKey) {
|
||||
+ return getChunkAt((int) chunkKey, (int) (chunkKey >> 32));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Checks if the specified {@link Chunk} is loaded
|
||||
*
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 10 Aug 2018 22:08:34 -0400
|
||||
Subject: [PATCH] Make EnderDragon extend Mob
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/EnderDragon.java b/src/main/java/org/bukkit/entity/EnderDragon.java
|
||||
index c14278d2c99deedddfd9c8afdc900760b0331546..92da609fb2bdf7c6396ba868410a40725fda05f0 100644
|
||||
--- a/src/main/java/org/bukkit/entity/EnderDragon.java
|
||||
+++ b/src/main/java/org/bukkit/entity/EnderDragon.java
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents an Ender Dragon
|
||||
*/
|
||||
-public interface EnderDragon extends ComplexLivingEntity, Boss {
|
||||
+public interface EnderDragon extends ComplexLivingEntity, Boss, org.bukkit.entity.Mob { // Paper - add Mob
|
||||
|
||||
/**
|
||||
* Represents a phase or action that an Ender Dragon can perform.
|
|
@ -1,57 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 15 Aug 2018 01:04:58 -0400
|
||||
Subject: [PATCH] Ability to get Tile Entities from a chunk without snapshots
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
|
||||
index 40ddeb7abd49eeece531a8e90b4508f3831cc3e9..5a4884db36d448c885e49c965ae329a0638dd628 100644
|
||||
--- a/src/main/java/org/bukkit/Chunk.java
|
||||
+++ b/src/main/java/org/bukkit/Chunk.java
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Collection;
|
||||
+import java.util.function.Predicate;
|
||||
+
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -111,13 +113,36 @@ public interface Chunk extends PersistentDataHolder {
|
||||
@NotNull
|
||||
Entity[] getEntities();
|
||||
|
||||
+ // Paper start
|
||||
/**
|
||||
* Get a list of all tile entities in the chunk.
|
||||
*
|
||||
* @return The tile entities.
|
||||
*/
|
||||
@NotNull
|
||||
- BlockState[] getTileEntities();
|
||||
+ default BlockState[] getTileEntities() {
|
||||
+ return getTileEntities(true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get a list of all tile entities in the chunk.
|
||||
+ *
|
||||
+ * @param useSnapshot Take snapshots or direct references
|
||||
+ * @return The tile entities.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ BlockState[] getTileEntities(boolean useSnapshot);
|
||||
+
|
||||
+ /**
|
||||
+ * Get a list of all tile entities that match a given predicate in the chunk.
|
||||
+ *
|
||||
+ * @param blockPredicate The predicate of blocks to return tile entities for
|
||||
+ * @param useSnapshot Take snapshots or direct references
|
||||
+ * @return The tile entities.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Collection<BlockState> getTileEntities(@NotNull Predicate<Block> blockPredicate, boolean useSnapshot);
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Checks if the chunk is loaded.
|
|
@ -1,370 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 16 Mar 2018 22:59:43 -0400
|
||||
Subject: [PATCH] Improved Async Task Scheduler
|
||||
|
||||
The Craft Scheduler still uses the primary thread for task scheduling.
|
||||
This results in the main thread still having to do work as part of the
|
||||
dispatching of async tasks.
|
||||
|
||||
If plugins make use of lots of async tasks, such as particle emitters
|
||||
that want to keep the logic off the main thread, the main thread still
|
||||
receives quite a bit of load from processing all of these queued tasks.
|
||||
|
||||
Additionally, resizing and managing the pending entries for all of
|
||||
these asynchronous tasks takes up time on the main thread too.
|
||||
|
||||
This commit replaces the implementation of the scheduler when working
|
||||
with asynchronous tasks, by forwarding calls to the new scheduler.
|
||||
|
||||
The Async Scheduler uses a single thread executor for "management" tasks.
|
||||
The Management Thread is responsible for all adding and dispatching of
|
||||
scheduled tasks.
|
||||
|
||||
The mainThreadHeartbeat will send a heartbeat task to the management thread
|
||||
with the currentTick value, so that it can find which tasks to execute.
|
||||
|
||||
Scheduling of an async tasks also dispatches a management task, ensuring
|
||||
that any Queue resizing operation occurs off of the main thread.
|
||||
|
||||
The async queue uses a complete separate PriorityQueue, ensuring that resize
|
||||
operations are decoupled from the sync tasks queue.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3c1992e212a6d6f1db4d5b807b38d71913619fc0
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
|
||||
@@ -0,0 +1,122 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package org.bukkit.craftbukkit.scheduler;
|
||||
+
|
||||
+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Iterator;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.Executor;
|
||||
+import java.util.concurrent.Executors;
|
||||
+import java.util.concurrent.SynchronousQueue;
|
||||
+import java.util.concurrent.ThreadPoolExecutor;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+
|
||||
+public class CraftAsyncScheduler extends CraftScheduler {
|
||||
+
|
||||
+ private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
|
||||
+ 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(),
|
||||
+ new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build());
|
||||
+ private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
|
||||
+ .setNameFormat("Craft Async Scheduler Management Thread").build());
|
||||
+ private final List<CraftTask> temp = new ArrayList<>();
|
||||
+
|
||||
+ CraftAsyncScheduler() {
|
||||
+ super(true);
|
||||
+ executor.allowCoreThreadTimeOut(true);
|
||||
+ executor.prestartAllCoreThreads();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void cancelTask(int taskId) {
|
||||
+ this.management.execute(() -> this.removeTask(taskId));
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void removeTask(int taskId) {
|
||||
+ parsePending();
|
||||
+ this.pending.removeIf((task) -> {
|
||||
+ if (task.getTaskId() == taskId) {
|
||||
+ task.cancel0();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void mainThreadHeartbeat(int currentTick) {
|
||||
+ this.currentTick = currentTick;
|
||||
+ this.management.execute(() -> this.runTasks(currentTick));
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void runTasks(int currentTick) {
|
||||
+ parsePending();
|
||||
+ while (!this.pending.isEmpty() && this.pending.peek().getNextRun() <= currentTick) {
|
||||
+ CraftTask task = this.pending.remove();
|
||||
+ if (executeTask(task)) {
|
||||
+ final long period = task.getPeriod();
|
||||
+ if (period > 0) {
|
||||
+ task.setNextRun(currentTick + period);
|
||||
+ temp.add(task);
|
||||
+ }
|
||||
+ }
|
||||
+ parsePending();
|
||||
+ }
|
||||
+ this.pending.addAll(temp);
|
||||
+ temp.clear();
|
||||
+ }
|
||||
+
|
||||
+ private boolean executeTask(CraftTask task) {
|
||||
+ if (isValid(task)) {
|
||||
+ this.runners.put(task.getTaskId(), task);
|
||||
+ this.executor.execute(new ServerSchedulerReportingWrapper(task));
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public synchronized void cancelTasks(Plugin plugin) {
|
||||
+ parsePending();
|
||||
+ for (Iterator<CraftTask> iterator = this.pending.iterator(); iterator.hasNext(); ) {
|
||||
+ CraftTask task = iterator.next();
|
||||
+ if (task.getTaskId() != -1 && (plugin == null || task.getOwner().equals(plugin))) {
|
||||
+ task.cancel0();
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Task is not cancelled
|
||||
+ * @param runningTask
|
||||
+ * @return
|
||||
+ */
|
||||
+ static boolean isValid(CraftTask runningTask) {
|
||||
+ return runningTask.getPeriod() >= CraftTask.NO_REPEATING;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
index d96292052633941102c052894bef747817b2998f..ea7ebbc2674df727cf44856f172731ee083b8800 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -78,7 +78,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
/**
|
||||
* Main thread logic only
|
||||
*/
|
||||
- private final PriorityQueue<CraftTask> pending = new PriorityQueue<CraftTask>(10,
|
||||
+ final PriorityQueue<CraftTask> pending = new PriorityQueue<CraftTask>(10, // Paper
|
||||
new Comparator<CraftTask>() {
|
||||
@Override
|
||||
public int compare(final CraftTask o1, final CraftTask o2) {
|
||||
@@ -95,12 +95,13 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
/**
|
||||
* These are tasks that are currently active. It's provided for 'viewing' the current state.
|
||||
*/
|
||||
- private final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>();
|
||||
+ final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>(); // Paper
|
||||
/**
|
||||
* The sync task that is currently running on the main thread.
|
||||
*/
|
||||
private volatile CraftTask currentTask = null;
|
||||
- private volatile int currentTick = -1;
|
||||
+ // Paper start - Improved Async Task Scheduler
|
||||
+ volatile int currentTick = -1;/*
|
||||
private final Executor executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %d").build());
|
||||
private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {
|
||||
@Override
|
||||
@@ -109,12 +110,31 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
}
|
||||
};
|
||||
private CraftAsyncDebugger debugTail = this.debugHead;
|
||||
+
|
||||
+ */ // Paper end
|
||||
private static final int RECENT_TICKS;
|
||||
|
||||
static {
|
||||
RECENT_TICKS = 30;
|
||||
}
|
||||
|
||||
+
|
||||
+ // Paper start
|
||||
+ private final CraftScheduler asyncScheduler;
|
||||
+ private final boolean isAsyncScheduler;
|
||||
+ public CraftScheduler() {
|
||||
+ this(false);
|
||||
+ }
|
||||
+
|
||||
+ public CraftScheduler(boolean isAsync) {
|
||||
+ this.isAsyncScheduler = isAsync;
|
||||
+ if (isAsync) {
|
||||
+ this.asyncScheduler = this;
|
||||
+ } else {
|
||||
+ this.asyncScheduler = new CraftAsyncScheduler();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) {
|
||||
return this.scheduleSyncDelayedTask(plugin, task, 0L);
|
||||
@@ -237,7 +257,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
} else if (period < CraftTask.NO_REPEATING) {
|
||||
period = CraftTask.NO_REPEATING;
|
||||
}
|
||||
- return this.handle(new CraftAsyncTask(this.runners, plugin, runnable, this.nextId(), period), delay);
|
||||
+ return this.handle(new CraftAsyncTask(this.asyncScheduler.runners, plugin, runnable, this.nextId(), period), delay); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,6 +273,11 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
if (taskId <= 0) {
|
||||
return;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.cancelTask(taskId);
|
||||
+ }
|
||||
+ // Paper end
|
||||
CraftTask task = this.runners.get(taskId);
|
||||
if (task != null) {
|
||||
task.cancel0();
|
||||
@@ -295,6 +320,11 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
@Override
|
||||
public void cancelTasks(final Plugin plugin) {
|
||||
Validate.notNull(plugin, "Cannot cancel tasks of null plugin");
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.cancelTasks(plugin);
|
||||
+ }
|
||||
+ // Paper end
|
||||
final CraftTask task = new CraftTask(
|
||||
new Runnable() {
|
||||
@Override
|
||||
@@ -334,6 +364,13 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
@Override
|
||||
public boolean isCurrentlyRunning(final int taskId) {
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ if (this.asyncScheduler.isCurrentlyRunning(taskId)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
final CraftTask task = this.runners.get(taskId);
|
||||
if (task == null) {
|
||||
return false;
|
||||
@@ -352,6 +389,11 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
if (taskId <= 0) {
|
||||
return false;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler && this.asyncScheduler.isQueued(taskId)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
for (CraftTask task = this.head.getNext(); task != null; task = task.getNext()) {
|
||||
if (task.getTaskId() == taskId) {
|
||||
return task.getPeriod() >= CraftTask.NO_REPEATING; // The task will run
|
||||
@@ -363,6 +405,12 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
@Override
|
||||
public List<BukkitWorker> getActiveWorkers() {
|
||||
+ // Paper start
|
||||
+ if (!isAsyncScheduler) {
|
||||
+ //noinspection TailRecursion
|
||||
+ return this.asyncScheduler.getActiveWorkers();
|
||||
+ }
|
||||
+ // Paper end
|
||||
final ArrayList<BukkitWorker> workers = new ArrayList<BukkitWorker>();
|
||||
for (final CraftTask taskObj : this.runners.values()) {
|
||||
// Iterator will be a best-effort (may fail to grab very new values) if called from an async thread
|
||||
@@ -400,6 +448,11 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
pending.add(task);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ pending.addAll(this.asyncScheduler.getPendingTasks());
|
||||
+ }
|
||||
+ // Paper end
|
||||
return pending;
|
||||
}
|
||||
|
||||
@@ -407,6 +460,11 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
* This method is designed to never block or wait for locks; an immediate execution of all current tasks.
|
||||
*/
|
||||
public void mainThreadHeartbeat(final int currentTick) {
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.mainThreadHeartbeat(currentTick);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.currentTick = currentTick;
|
||||
final List<CraftTask> temp = this.temp;
|
||||
this.parsePending();
|
||||
@@ -446,7 +504,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
this.parsePending();
|
||||
} else {
|
||||
//this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
|
||||
- this.executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
|
||||
+ task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Paper"); // Paper
|
||||
// We don't need to parse pending
|
||||
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
|
||||
}
|
||||
@@ -465,7 +523,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
//this.debugHead = this.debugHead.getNextHead(currentTick); // Paper
|
||||
}
|
||||
|
||||
- private void addTask(final CraftTask task) {
|
||||
+ protected void addTask(final CraftTask task) {
|
||||
final AtomicReference<CraftTask> tail = this.tail;
|
||||
CraftTask tailTask = tail.get();
|
||||
while (!tail.compareAndSet(tailTask, task)) {
|
||||
@@ -474,7 +532,13 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
tailTask.setNext(task);
|
||||
}
|
||||
|
||||
- private CraftTask handle(final CraftTask task, final long delay) {
|
||||
+ protected CraftTask handle(final CraftTask task, final long delay) { // Paper
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler && !task.isSync()) {
|
||||
+ this.asyncScheduler.handle(task, delay);
|
||||
+ return task;
|
||||
+ }
|
||||
+ // Paper end
|
||||
task.setNextRun(this.currentTick + delay);
|
||||
this.addTask(task);
|
||||
return task;
|
||||
@@ -498,8 +562,8 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
return id;
|
||||
}
|
||||
|
||||
- private void parsePending() {
|
||||
- MinecraftTimings.bukkitSchedulerPendingTimer.startTiming();
|
||||
+ void parsePending() { // Paper
|
||||
+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper
|
||||
CraftTask head = this.head;
|
||||
CraftTask task = head.getNext();
|
||||
CraftTask lastTask = head;
|
||||
@@ -518,7 +582,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
task.setNext(null);
|
||||
}
|
||||
this.head = lastTask;
|
||||
- MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming();
|
||||
+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper
|
||||
}
|
||||
|
||||
private boolean isReady(final int currentTick) {
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Mon, 26 Mar 2018 18:30:53 +0300
|
||||
Subject: [PATCH] Upstream config migrations
|
||||
|
||||
This patch contains config migrations for when upstream adds options
|
||||
which Paper already had.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index f4735cc330822183e098a67f2c0f00f21db9e137..c5c82496524705a0ce85df5508ec730c19246ec7 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -291,4 +291,22 @@ public class PaperConfig {
|
||||
private static void authenticationServersDownKickMessage() {
|
||||
authenticationServersDownKickMessage = Strings.emptyToNull(getString("messages.kick.authentication-servers-down", authenticationServersDownKickMessage));
|
||||
}
|
||||
+
|
||||
+ private static void savePlayerData() {
|
||||
+ Object val = config.get("settings.save-player-data");
|
||||
+ if (val instanceof Boolean) {
|
||||
+ SpigotConfig.disablePlayerDataSaving = !(Boolean) val;
|
||||
+ SpigotConfig.config.set("players.disable-saving", SpigotConfig.disableAdvancementSaving);
|
||||
+ SpigotConfig.save();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static void namedEntityDeaths() {
|
||||
+ Object val = config.get("settings.log-named-entity-deaths");
|
||||
+ if (val instanceof Boolean bool && !bool) {
|
||||
+ SpigotConfig.logNamedDeaths = false;
|
||||
+ SpigotConfig.config.set("settings.log-named-deaths", false);
|
||||
+ SpigotConfig.save();
|
||||
+ }
|
||||
+ }
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 18:22:50 +0200
|
||||
Subject: [PATCH] Make legacy ping handler more reliable
|
||||
|
||||
The Minecraft server often fails to respond to old ("legacy") pings
|
||||
from old Minecraft versions using the protocol used before the switch
|
||||
to Netty in Minecraft 1.7.
|
||||
|
||||
Due to packet fragmentation[1], we might not have all needed bytes
|
||||
available when the LegacyPingHandler is called. In this case, it will
|
||||
run into an error, remove the handler and continue using the modern
|
||||
protocol.
|
||||
|
||||
This is unlikely to happen for the first two revisions of the legacy
|
||||
ping protocol (used in Minecraft 1.5.x and older) since the request
|
||||
consists of only one or two bytes, but happens frequently for the
|
||||
last/third revision introduced in Minecraft 1.6.
|
||||
|
||||
It has much larger, variable packet sizes due to the inclusion of
|
||||
the virtual host (the hostname/port used to connect to the server).
|
||||
|
||||
The solution[2] is simple: If we find more than two matching bytes,
|
||||
we buffer the remaining bytes until we have enough to fully read and
|
||||
respond to the request.
|
||||
|
||||
[1]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-11
|
||||
[2]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h4-13
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index a2b0237a27379d05e8ca15cb033ee3fd2a5bb29b..6a759cfd0c2df4daaf126d12d20ac8d701e41f9d 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -16,6 +16,7 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final int FAKE_PROTOCOL_VERSION = 127;
|
||||
private final ServerConnectionListener serverConnectionListener;
|
||||
+ private ByteBuf buf; // Paper
|
||||
|
||||
public LegacyQueryHandler(ServerConnectionListener networkIo) {
|
||||
this.serverConnectionListener = networkIo;
|
||||
@@ -24,6 +25,16 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
public void channelRead(ChannelHandlerContext channelhandlercontext, Object object) {
|
||||
ByteBuf bytebuf = (ByteBuf) object;
|
||||
|
||||
+ // Paper start - Make legacy ping handler more reliable
|
||||
+ if (this.buf != null) {
|
||||
+ try {
|
||||
+ readLegacy1_6(channelhandlercontext, bytebuf);
|
||||
+ } finally {
|
||||
+ bytebuf.release();
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
bytebuf.markReaderIndex();
|
||||
boolean flag = true;
|
||||
|
||||
@@ -54,6 +65,10 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
|
||||
break;
|
||||
default:
|
||||
+ // Paper start - Replace with improved version below
|
||||
+ if (bytebuf.readUnsignedByte() != 0x01 || bytebuf.readUnsignedByte() != 0xFA) return;
|
||||
+ readLegacy1_6(channelhandlercontext, bytebuf);
|
||||
+ /*
|
||||
boolean flag1 = bytebuf.readUnsignedByte() == 1;
|
||||
|
||||
flag1 &= bytebuf.readUnsignedByte() == 250;
|
||||
@@ -77,6 +92,7 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
} finally {
|
||||
bytebuf1.release();
|
||||
}
|
||||
+ */ // Paper end - Replace with improved version below
|
||||
}
|
||||
|
||||
bytebuf.release();
|
||||
@@ -94,6 +110,90 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private static String readLegacyString(ByteBuf buf) {
|
||||
+ int size = buf.readShort() * Character.BYTES;
|
||||
+ if (!buf.isReadable(size)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ String result = buf.toString(buf.readerIndex(), size, StandardCharsets.UTF_16BE);
|
||||
+ buf.skipBytes(size); // toString doesn't increase readerIndex automatically
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ private void readLegacy1_6(ChannelHandlerContext ctx, ByteBuf part) {
|
||||
+ ByteBuf buf = this.buf;
|
||||
+
|
||||
+ if (buf == null) {
|
||||
+ this.buf = buf = ctx.alloc().buffer();
|
||||
+ buf.markReaderIndex();
|
||||
+ } else {
|
||||
+ buf.resetReaderIndex();
|
||||
+ }
|
||||
+
|
||||
+ buf.writeBytes(part);
|
||||
+
|
||||
+ if (!buf.isReadable(Short.BYTES + Short.BYTES + Byte.BYTES + Short.BYTES + Integer.BYTES)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ String s = readLegacyString(buf);
|
||||
+ if (s == null) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!s.equals("MC|PingHost")) {
|
||||
+ removeHandler(ctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!buf.isReadable(Short.BYTES) || !buf.isReadable(buf.readShort())) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ MinecraftServer server = this.serverConnectionListener.getServer();
|
||||
+ int protocolVersion = buf.readByte();
|
||||
+ String host = readLegacyString(buf);
|
||||
+ if (host == null) {
|
||||
+ removeHandler(ctx);
|
||||
+ return;
|
||||
+ }
|
||||
+ int port = buf.readInt();
|
||||
+
|
||||
+ if (buf.isReadable()) {
|
||||
+ removeHandler(ctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ buf.release();
|
||||
+ this.buf = null;
|
||||
+
|
||||
+ LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
+
|
||||
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
|
||||
+ Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
|
||||
+ this.sendFlushAndClose(ctx, this.createReply(response));
|
||||
+ }
|
||||
+
|
||||
+ private void removeHandler(ChannelHandlerContext ctx) {
|
||||
+ ByteBuf buf = this.buf;
|
||||
+ this.buf = null;
|
||||
+
|
||||
+ buf.resetReaderIndex();
|
||||
+ ctx.pipeline().remove(this);
|
||||
+ ctx.fireChannelRead(buf);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void handlerRemoved(ChannelHandlerContext ctx) {
|
||||
+ if (this.buf != null) {
|
||||
+ this.buf.release();
|
||||
+ this.buf = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private void sendFlushAndClose(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||
ctx.pipeline().firstContext().writeAndFlush(buf).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 19:30:51 +0200
|
||||
Subject: [PATCH] Call PaperServerListPingEvent for legacy pings
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..74c012fd40491f1d870fbc1aa8c318a2197eb106
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
|
||||
@@ -0,0 +1,73 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.apache.commons.lang3.StringUtils;
|
||||
+import org.bukkit.ChatColor;
|
||||
+
|
||||
+import java.net.InetSocketAddress;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+public final class PaperLegacyStatusClient implements StatusClient {
|
||||
+
|
||||
+ private final InetSocketAddress address;
|
||||
+ private final int protocolVersion;
|
||||
+ @Nullable private final InetSocketAddress virtualHost;
|
||||
+
|
||||
+ private PaperLegacyStatusClient(InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
|
||||
+ this.address = address;
|
||||
+ this.protocolVersion = protocolVersion;
|
||||
+ this.virtualHost = virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getAddress() {
|
||||
+ return this.address;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ return this.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ return this.virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isLegacy() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public static PaperServerListPingEvent processRequest(MinecraftServer server,
|
||||
+ InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
|
||||
+
|
||||
+ PaperServerListPingEvent event = new PaperServerListPingEventImpl(server,
|
||||
+ new PaperLegacyStatusClient(address, protocolVersion, virtualHost), Byte.MAX_VALUE, null);
|
||||
+ server.server.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return event;
|
||||
+ }
|
||||
+
|
||||
+ public static String getMotd(PaperServerListPingEvent event) {
|
||||
+ return getFirstLine(event.getMotd());
|
||||
+ }
|
||||
+
|
||||
+ public static String getUnformattedMotd(PaperServerListPingEvent event) {
|
||||
+ // Strip color codes and all other occurrences of the color char (because it's used as delimiter)
|
||||
+ return getFirstLine(StringUtils.remove(ChatColor.stripColor(event.getMotd()), ChatColor.COLOR_CHAR));
|
||||
+ }
|
||||
+
|
||||
+ private static String getFirstLine(String s) {
|
||||
+ int pos = s.indexOf('\n');
|
||||
+ return pos >= 0 ? s.substring(0, pos) : s;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index 6a759cfd0c2df4daaf126d12d20ac8d701e41f9d..3962e82d4e4c5f792a37e825891e6960e737452d 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.minecraft.server.network;
|
||||
|
||||
+import com.destroystokyo.paper.network.PaperLegacyStatusClient;
|
||||
+
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
@@ -47,12 +49,19 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
MinecraftServer minecraftserver = this.serverConnectionListener.getServer();
|
||||
int i = bytebuf.readableBytes();
|
||||
String s;
|
||||
- org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(minecraftserver.server, inetsocketaddress.getAddress(), minecraftserver.getMotd(), minecraftserver.getPlayerCount(), minecraftserver.getMaxPlayers()); // CraftBukkit
|
||||
+ //org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(minecraftserver.server, inetsocketaddress.getAddress(), minecraftserver.getMotd(), minecraftserver.getPlayerCount(), minecraftserver.getMaxPlayers()); // CraftBukkit // Paper
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
|
||||
- s = String.format("%s\u00a7%d\u00a7%d", event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 39, null);
|
||||
+ if (event == null) {
|
||||
+ channelhandlercontext.close();
|
||||
+ break;
|
||||
+ }
|
||||
+ s = String.format("%s\u00a7%d\u00a7%d", PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers());
|
||||
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
|
||||
break;
|
||||
case 1:
|
||||
@@ -61,7 +70,14 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort());
|
||||
- s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 127, null); // Paper
|
||||
+ if (event == null) {
|
||||
+ channelhandlercontext.close();
|
||||
+ break;
|
||||
+ }
|
||||
+ s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", new Object[] { event.getProtocolVersion(), minecraftserver.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()}); // CraftBukkit
|
||||
+ // Paper end
|
||||
this.sendFlushAndClose(channelhandlercontext, this.createReply(s));
|
||||
break;
|
||||
default:
|
||||
@@ -171,8 +187,16 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
|
||||
- String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
|
||||
- Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
|
||||
+ InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = PaperLegacyStatusClient.processRequest(
|
||||
+ server, (InetSocketAddress) ctx.channel().remoteAddress(), protocolVersion, virtualHost);
|
||||
+ if (event == null) {
|
||||
+ ctx.close();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), event.getVersion(),
|
||||
+ PaperLegacyStatusClient.getMotd(event), event.getNumPlayers(), event.getMaxPlayers());
|
||||
this.sendFlushAndClose(ctx, this.createReply(response));
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 31 Mar 2018 17:04:26 +0100
|
||||
Subject: [PATCH] Flag to disable the channel limit
|
||||
|
||||
In some enviroments, the channel limit set by spigot can cause issues,
|
||||
e.g. servers which allow and support the usage of mod packs.
|
||||
|
||||
provide an optional flag to disable this check, at your own risk.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 95a1d83fb7cb9947beb56b951b0081e4db2de6c9..c07916e07e09f1491c9bad7d13b127960dd167a6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -150,6 +150,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
// Paper start
|
||||
private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
|
||||
private String resourcePackHash;
|
||||
+ private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||
// Paper end
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
@@ -1616,7 +1617,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void addChannel(String channel) {
|
||||
- Preconditions.checkState(this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel);
|
||||
+ Preconditions.checkState(DISABLE_CHANNEL_LIMIT || this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel); // Paper - flag to disable channel limit
|
||||
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
||||
if (this.channels.add(channel)) {
|
||||
server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel));
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 1 Apr 2018 02:29:37 +0300
|
||||
Subject: [PATCH] Add method to open already placed sign
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 54947f02f29dd3dc546ee0d0f4600630242f003d..f1b1d1881d0598503a7ec1022ef5e00f848fb247 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -610,6 +610,17 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Add method to open already placed sign
|
||||
+ @Override
|
||||
+ public void openSign(org.bukkit.block.Sign sign) {
|
||||
+ org.apache.commons.lang.Validate.isTrue(sign.getWorld().equals(this.getWorld()), "Sign must be in the same world as player is in");
|
||||
+ org.bukkit.craftbukkit.block.CraftSign craftSign = (org.bukkit.craftbukkit.block.CraftSign) sign;
|
||||
+ net.minecraft.world.level.block.entity.SignBlockEntity teSign = craftSign.getTileEntity();
|
||||
+ // Make sign editable temporarily, will be set back to false in PlayerConnection later
|
||||
+ teSign.isEditable = true;
|
||||
+ this.getHandle().openTextEdit(teSign);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean dropItem(boolean dropAll) {
|
||||
if (!(this.getHandle() instanceof ServerPlayer)) return false;
|
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Sat, 14 Apr 2018 20:20:46 +0200
|
||||
Subject: [PATCH] Configurable sprint interruption on attack
|
||||
|
||||
If the sprint interruption is disabled players continue sprinting when they attack entities.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0e08f6e566d1c93cc89a179583d0b0939127de8b..4e0f61179e3b2ae91811746d32b24998173a922c 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -393,4 +393,9 @@ public class PaperWorldConfig {
|
||||
private void squidMaxSpawnHeight() {
|
||||
squidMaxSpawnHeight = getDouble("squid-spawn-height.maximum", 0.0D);
|
||||
}
|
||||
+
|
||||
+ public boolean disableSprintInterruptionOnAttack;
|
||||
+ private void disableSprintInterruptionOnAttack() {
|
||||
+ disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
||||
+ }
|
||||
}
|
||||
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 0ef9c95d40cd0cdff0d150121511e6f9efd65f4d..f7ee9ce075720ed59cf761463bae997a141a7be8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1238,7 +1238,11 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
- this.setSprinting(false);
|
||||
+ // Paper start - Configuration option to disable automatic sprint interruption
|
||||
+ if (!level.paperConfig.disableSprintInterruptionOnAttack) {
|
||||
+ this.setSprinting(false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
if (flag3) {
|
|
@ -1,22 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: 0x22 <0x22@futureclient.net>
|
||||
Date: Thu, 26 Apr 2018 04:41:11 -0400
|
||||
Subject: [PATCH] Fix exploit that allowed colored signs to be created
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 25ea7a94407dfdb613ee15de4eb2a9c3252c6b27..e83232f18871a04fadbc053b1e1e7f94d2492159 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2777,9 +2777,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
TextFilter.FilteredText currentLine = signText.get(i);
|
||||
|
||||
if (this.player.isTextFilteringEnabled()) {
|
||||
- lines.add(net.kyori.adventure.text.Component.text(currentLine.getFiltered()));
|
||||
+ lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(currentLine.getFiltered())));
|
||||
} else {
|
||||
- lines.add(net.kyori.adventure.text.Component.text(currentLine.getRaw()));
|
||||
+ lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(currentLine.getRaw())));
|
||||
}
|
||||
}
|
||||
SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.player.getBukkitEntity(), lines);
|
|
@ -1,65 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:15:55 -0400
|
||||
Subject: [PATCH] EndermanEscapeEvent
|
||||
|
||||
Fires an event anytime an enderman intends to teleport away from the player
|
||||
|
||||
You may cancel this, enabling ranged attacks to damage the enderman for example.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 568c3a43a41c6bde521580b3890aa21d28e03036..d2c64a3909e77ed3f9d5fb5d4c47a756eab82eee 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -109,6 +109,12 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
this.setGoalTarget(target, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, true);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private boolean tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason reason) {
|
||||
+ return new com.destroystokyo.paper.event.entity.EndermanEscapeEvent((org.bukkit.craftbukkit.entity.CraftEnderman) this.getBukkitEntity(), reason).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean setGoalTarget(LivingEntity entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fireEvent) {
|
||||
if (!super.setGoalTarget(entityliving, reason, fireEvent)) {
|
||||
@@ -262,7 +268,7 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
if (this.level.isDay() && this.tickCount >= this.targetChangeTime + 600) {
|
||||
float f = this.getBrightness();
|
||||
|
||||
- if (f > 0.5F && this.level.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
|
||||
+ if (f > 0.5F && this.level.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper
|
||||
this.setTarget((LivingEntity) null);
|
||||
this.teleport();
|
||||
}
|
||||
@@ -360,17 +366,19 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
if (this.isInvulnerableTo(source)) {
|
||||
return false;
|
||||
} else if (source instanceof IndirectEntityDamageSource) {
|
||||
+ if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
if (this.teleport()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+ } // Paper end
|
||||
|
||||
return false;
|
||||
} else {
|
||||
boolean flag = super.hurt(source, amount);
|
||||
|
||||
- if (!this.level.isClientSide() && !(source.getEntity() instanceof LivingEntity) && this.random.nextInt(10) != 0) {
|
||||
+ if (!this.level.isClientSide() && !(source.getEntity() instanceof LivingEntity) && this.random.nextInt(10) != 0 && this.tryEscape(source == DamageSource.DROWN ? com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.DROWN : com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - use to be critical hits as else, but mojang removed critical hits in 1.16.2 due to MC-185684
|
||||
this.teleport();
|
||||
}
|
||||
|
||||
@@ -579,7 +587,7 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
} else {
|
||||
if (this.target != null && !this.enderman.isPassenger()) {
|
||||
if (this.enderman.isLookingAtMe((Player) this.target)) {
|
||||
- if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D) {
|
||||
+ if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.enderman.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.STARE)) { // Paper
|
||||
this.enderman.teleport();
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:29:44 -0400
|
||||
Subject: [PATCH] Enderman.teleportRandomly()
|
||||
|
||||
Ability to trigger the vanilla "teleport randomly" mechanic of an enderman.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index d2c64a3909e77ed3f9d5fb5d4c47a756eab82eee..02f691a2217bea2df23b7b412eba90ee99c3b8c9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -277,7 +277,7 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
super.customServerAiStep();
|
||||
}
|
||||
|
||||
- protected boolean teleport() {
|
||||
+ public boolean teleport() { // Paper - protected->public
|
||||
if (!this.level.isClientSide() && this.isAlive()) {
|
||||
double d0 = this.getX() + (this.random.nextDouble() - 0.5D) * 64.0D;
|
||||
double d1 = this.getY() + (double) (this.random.nextInt(64) - 32);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
index b72d7ade10075a13a617a370e2b8021326c9478d..ae669a970aa1f17ed786640de8a481364543c58e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
@@ -16,6 +16,7 @@ public class CraftEnderman extends CraftMonster implements Enderman {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
+ @Override public boolean teleportRandomly() { return getHandle().teleport(); } // Paper
|
||||
@Override
|
||||
public MaterialData getCarriedMaterial() {
|
||||
BlockState blockData = this.getHandle().getCarriedBlock();
|
|
@ -1,61 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 17:15:26 -0400
|
||||
Subject: [PATCH] Block Enderpearl Travel Exploit
|
||||
|
||||
Players are able to use alt accounts and enderpearls to travel
|
||||
long distances utilizing the pearls in unloaded chunks and loading
|
||||
the chunk later when convenient.
|
||||
|
||||
This disables that by not saving the thrower when the chunk is unloaded.
|
||||
|
||||
This is mainly useful for survival servers that do not allow freeform teleporting.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 4e0f61179e3b2ae91811746d32b24998173a922c..a0937dd52e4a2aa1bfadcbd1ac0dc2cb26d59cf0 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -398,4 +398,10 @@ public class PaperWorldConfig {
|
||||
private void disableSprintInterruptionOnAttack() {
|
||||
disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
||||
}
|
||||
+
|
||||
+ public boolean disableEnderpearlExploit = true;
|
||||
+ private void disableEnderpearlExploit() {
|
||||
+ disableEnderpearlExploit = getBoolean("game-mechanics.disable-unloaded-chunk-enderpearl-exploit", disableEnderpearlExploit);
|
||||
+ log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled"));
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index 4306db7db2c5b4eb1529dc3e9f0659ead2688fa5..8af1571c614a39c9673e0dc90e3aa9a89a367e34 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -88,6 +88,7 @@ public abstract class Projectile extends Entity {
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
if (nbt.hasUUID("Owner")) {
|
||||
this.ownerUUID = nbt.getUUID("Owner");
|
||||
+ if (this instanceof ThrownEnderpearl && this.level != null && this.level.paperConfig.disableEnderpearlExploit) { this.ownerUUID = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit
|
||||
}
|
||||
|
||||
this.leftOwner = nbt.getBoolean("LeftOwner");
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
index 541ca82405d0b4d1457dcd63b58dc61eb67482d6..1b2ada3663cc0739782ac591f2ee1f6d0fb94841 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
@@ -108,6 +108,16 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
|
||||
super.tick();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.level.paperConfig.disableEnderpearlExploit) {
|
||||
+ final net.minecraft.server.level.ChunkHolder chunkHolder = ((net.minecraft.server.level.ServerChunkCache) this.level.getChunkSource()).chunkMap.getVisibleChunkIfPresent(net.minecraft.world.level.ChunkPos.asLong(this.blockPosition()));
|
||||
+ if (chunkHolder == null || !net.minecraft.server.level.ChunkHolder.getFullChunkStatus(chunkHolder.getTicketLevel()).isOrAfter(net.minecraft.server.level.ChunkHolder.FullChunkStatus.ENTITY_TICKING)) {
|
||||
+ this.cachedOwner = null;
|
||||
+ this.ownerUUID = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
}
|
||||
|
||||
@Nullable
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 15 Aug 2017 22:29:12 -0400
|
||||
Subject: [PATCH] Expand World.spawnParticle API and add Builder
|
||||
|
||||
Adds ability to control who receives it and who is the source/sender (vanish API)
|
||||
the standard API is to send the packet to everyone in the world, which is ineffecient.
|
||||
Adds an option to control the force mode of the particle.
|
||||
|
||||
This adds a new Builder API which is much friendlier to use.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 26c25b103f08a2e66179d1ed8f450778aa2e539a..86a5a4456be65b94b0c27a0355c3844cbd296a20 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1333,12 +1333,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
|
||||
+ // Paper start - Particle API Expansion
|
||||
+ return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force);
|
||||
+ }
|
||||
+ public <T extends ParticleOptions> int sendParticles(List<ServerPlayer> receivers, ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
|
||||
+ // Paper end
|
||||
ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(t0, force, d0, d1, d2, (float) d3, (float) d4, (float) d5, (float) d6, i);
|
||||
// CraftBukkit end
|
||||
int j = 0;
|
||||
|
||||
- for (int k = 0; k < this.players.size(); ++k) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) this.players.get(k);
|
||||
+ for (Player entityhuman : receivers) { // Paper - Particle API Expansion
|
||||
+ ServerPlayer entityplayer = (ServerPlayer) entityhuman; // Paper - Particle API Expansion
|
||||
if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit
|
||||
|
||||
if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 1f4880cd6abc68731abd5943619a9bf7e7ddb02f..7fbd068cbf96332b6ea45411f45e9e0910693c57 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1748,11 +1748,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
||||
+ // Paper start - Particle API Expansion
|
||||
+ spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, force);
|
||||
+ }
|
||||
+ public <T> void spawnParticle(Particle particle, List<Player> receivers, Player sender, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
||||
+ // Paper end
|
||||
if (data != null && !particle.getDataType().isInstance(data)) {
|
||||
throw new IllegalArgumentException("data should be " + particle.getDataType() + " got " + data.getClass());
|
||||
}
|
||||
this.getHandle().sendParticles(
|
||||
- null, // Sender
|
||||
+ receivers == null ? getHandle().players() : receivers.stream().map(player -> ((CraftPlayer) player).getHandle()).collect(java.util.stream.Collectors.toList()), // Paper - Particle API Expansion
|
||||
+ sender != null ? ((CraftPlayer) sender).getHandle() : null, // Sender // Paper - Particle API Expansion
|
||||
CraftParticle.toNMS(particle, data), // Particle
|
||||
x, y, z, // Position
|
||||
count, // Count
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Mar 2018 16:33:15 -0500
|
||||
Subject: [PATCH] Prevent Frosted Ice from loading/holding chunks
|
||||
|
||||
1.17: Shouldn't be needed as blocks no longer tick without at least 1 radius chunk loaded.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
index 54eb7ba0265bb155dd1c753661242fa9d299ff80..5b5d606a794c885267b6f5e2bbfe9b0a318ad767 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
@@ -38,7 +38,8 @@ public class FrostedIceBlock extends IceBlock {
|
||||
|
||||
for(Direction direction : Direction.values()) {
|
||||
mutableBlockPos.setWithOffset(pos, direction);
|
||||
- BlockState blockState = world.getBlockState(mutableBlockPos);
|
||||
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos); // Paper
|
||||
+ if (blockState == null) { continue; } // Paper
|
||||
if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) {
|
||||
world.getBlockTicks().scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig.frostedIceDelayMin, world.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay
|
||||
}
|
||||
@@ -75,7 +76,10 @@ public class FrostedIceBlock extends IceBlock {
|
||||
|
||||
for(Direction direction : Direction.values()) {
|
||||
mutableBlockPos.setWithOffset(pos, direction);
|
||||
- if (world.getBlockState(mutableBlockPos).is(this)) {
|
||||
+ // Paper start
|
||||
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos);
|
||||
+ if (blockState != null && blockState.is(this)) {
|
||||
+ // Paper end
|
||||
++i;
|
||||
if (i >= maxNeighbors) {
|
||||
return false;
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 20:18:54 -0400
|
||||
Subject: [PATCH] EndermanAttackPlayerEvent
|
||||
|
||||
Allow control over whether or not an enderman aggros a player.
|
||||
|
||||
This allows you to override/extend the pumpkin/stare logic.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 02f691a2217bea2df23b7b412eba90ee99c3b8c9..de167655a556a700bdc7d92fa54b802924b2a61a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -220,7 +220,15 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
this.readPersistentAngerSaveData(this.level, nbt);
|
||||
}
|
||||
|
||||
- boolean isLookingAtMe(Player player) {
|
||||
+ // Paper start - EndermanAttackPlayerEvent
|
||||
+ private boolean isLookingAtMe(Player player) {
|
||||
+ boolean shouldAttack = isLookingAtMe_check(player);
|
||||
+ com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity());
|
||||
+ event.setCancelled(!shouldAttack);
|
||||
+ return event.callEvent();
|
||||
+ }
|
||||
+ private boolean isLookingAtMe_check(Player player) {
|
||||
+ // Paper end
|
||||
ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3);
|
||||
|
||||
if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) {
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:35:16 -0400
|
||||
Subject: [PATCH] WitchConsumePotionEvent
|
||||
|
||||
Fires when a witch consumes the potion in their hand
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
index d3cb46250d3f72a3d0f0e42eddee3ea30e8cabcc..fcfa4d3b0cb257804500864847f35650f4cb7602 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
@@ -124,7 +124,11 @@ public class Witch extends Raider implements RangedAttackMob {
|
||||
|
||||
this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
if (itemstack.is(Items.POTION)) {
|
||||
- List<MobEffectInstance> list = PotionUtils.getMobEffects(itemstack);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.WitchConsumePotionEvent event = new com.destroystokyo.paper.event.entity.WitchConsumePotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack));
|
||||
+
|
||||
+ List<MobEffectInstance> list = event.callEvent() ? PotionUtils.getMobEffects(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion())) : null;
|
||||
+ // Paper end
|
||||
|
||||
if (list != null) {
|
||||
Iterator iterator = list.iterator();
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:44:58 -0400
|
||||
Subject: [PATCH] WitchThrowPotionEvent
|
||||
|
||||
Fired when a witch throws a potion at a player
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
index fcfa4d3b0cb257804500864847f35650f4cb7602..4bb000af5964adec59741de56eb3bbd7b38ad237 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
@@ -236,9 +236,16 @@ public class Witch extends Raider implements RangedAttackMob {
|
||||
potionregistry = Potions.WEAKNESS;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ ItemStack potion = PotionUtils.setPotion(new ItemStack(Items.SPLASH_POTION), potionregistry);
|
||||
+ com.destroystokyo.paper.event.entity.WitchThrowPotionEvent event = new com.destroystokyo.paper.event.entity.WitchThrowPotionEvent((org.bukkit.entity.Witch) this.getBukkitEntity(), (org.bukkit.entity.LivingEntity) target.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ potion = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion());
|
||||
ThrownPotion entitypotion = new ThrownPotion(this.level, this);
|
||||
-
|
||||
- entitypotion.setItem(PotionUtils.setPotion(new ItemStack(Items.SPLASH_POTION), potionregistry));
|
||||
+ entitypotion.setItem(potion);
|
||||
+ // Paper end
|
||||
entitypotion.setXRot(entitypotion.getXRot() - -20.0F);
|
||||
entitypotion.shoot(d0, d1 + d3 * 0.2D, d2, 0.75F, 8.0F);
|
||||
if (!this.isSilent()) {
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 4 Jun 2018 20:39:20 -0400
|
||||
Subject: [PATCH] Allow spawning Item entities with World.spawnEntity
|
||||
|
||||
This API has more capabilities than .dropItem with the Consumer function
|
||||
|
||||
Item can be set inside of the Consumer pre spawn function.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index d0873200aa8f66648e23fc2954a27a83289e748c..0d1421555a98b97c30dbb4d95491308e433a81a3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -530,6 +530,10 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
if (Boat.class.isAssignableFrom(clazz)) {
|
||||
entity = new net.minecraft.world.entity.vehicle.Boat(world, x, y, z);
|
||||
entity.moveTo(x, y, z, yaw, pitch);
|
||||
+ // Paper start
|
||||
+ } else if (org.bukkit.entity.Item.class.isAssignableFrom(clazz)) {
|
||||
+ entity = new net.minecraft.world.entity.item.ItemEntity(world, x, y, z, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Item.byBlock(net.minecraft.world.level.block.Blocks.DIRT)));
|
||||
+ // Paper end
|
||||
} else if (FallingBlock.class.isAssignableFrom(clazz)) {
|
||||
entity = new FallingBlockEntity(world, x, y, z, this.getHandle().getBlockState(new BlockPos(x, y, z)));
|
||||
} else if (Projectile.class.isAssignableFrom(clazz)) {
|
|
@ -1,23 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Jun 2018 22:47:26 -0400
|
||||
Subject: [PATCH] WitchReadyPotionEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
index 4bb000af5964adec59741de56eb3bbd7b38ad237..94bd20db7ffea00579225e6887b8c78a3da3ff1a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
@@ -157,7 +157,11 @@ public class Witch extends Raider implements RangedAttackMob {
|
||||
}
|
||||
|
||||
if (potionregistry != null) {
|
||||
- this.setItemSlot(EquipmentSlot.MAINHAND, PotionUtils.setPotion(new ItemStack(Items.POTION), potionregistry));
|
||||
+ // Paper start
|
||||
+ ItemStack potion = PotionUtils.setPotion(new ItemStack(Items.POTION), potionregistry);
|
||||
+ org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion));
|
||||
+ this.setItemSlot(EquipmentSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack));
|
||||
+ // Paper end
|
||||
this.usingTime = this.getMainHandItem().getUseDuration();
|
||||
this.setUsingItem(true);
|
||||
if (!this.isSilent()) {
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Jun 2018 23:00:29 -0400
|
||||
Subject: [PATCH] ItemStack#getMaxItemUseDuration
|
||||
|
||||
Allows you to determine how long it takes to use a usable/consumable item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 84f11780a22b3369519fc8f80d6c274360045df7..4b43e6a1b628e2060d1095dab892efd9d1dfc485 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -173,6 +173,13 @@ public final class CraftItemStack extends ItemStack {
|
||||
return (this.handle == null) ? Material.AIR.getMaxStackSize() : this.handle.getItem().getMaxStackSize();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMaxItemUseDuration() {
|
||||
+ return handle == null ? 0 : handle.getUseDuration();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addUnsafeEnchantment(Enchantment ench, int level) {
|
||||
Validate.notNull(ench, "Cannot add null enchantment");
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 9 Jun 2018 14:08:39 +0200
|
||||
Subject: [PATCH] Implement EntityTeleportEndGatewayEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
index d6f67a87c46c95bd4c2dfad4c1c13cbfd263ef30..f41dfe8bff59d17000f3eb17670c524102adb276 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
@@ -225,9 +225,20 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
|
||||
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - EntityTeleportEndGatewayEvent - replicated from above
|
||||
+ org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity = entity.getBukkitEntity();
|
||||
+ org.bukkit.Location location = new Location(world.getWorld(), (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D);
|
||||
+ location.setPitch(bukkitEntity.getLocation().getPitch());
|
||||
+ location.setYaw(bukkitEntity.getLocation().getYaw());
|
||||
+
|
||||
+ com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent event = new com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent(bukkitEntity, bukkitEntity.getLocation(), location, new org.bukkit.craftbukkit.block.CraftEndGateway(world.getWorld(), blockEntity));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
entity1.setPortalCooldown();
|
||||
- entity1.teleportToWithTicket((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D);
|
||||
+ entity1.teleportToWithTicket(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); // Paper
|
||||
}
|
||||
|
||||
TheEndGatewayBlockEntity.triggerCooldown(world, pos, state, blockEntity);
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 01:18:49 -0400
|
||||
Subject: [PATCH] Unset Ignited flag on cancel of Explosion Event
|
||||
|
||||
Otherwise the creeper infinite explodes
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index aa16a81ee447e8bae274668f2240627d060398ba..dc7ad6f2a1ae71c411fb39460b52cd1129c928c4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -272,6 +272,7 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
this.spawnLingeringCloud();
|
||||
} else {
|
||||
this.swell = 0;
|
||||
+ this.entityData.set(DATA_IS_IGNITED, Boolean.valueOf(false)); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 20:20:15 -0400
|
||||
Subject: [PATCH] Fix CraftEntity hashCode
|
||||
|
||||
hashCodes are not allowed to change, however bukkit used a value
|
||||
that does change, the entityId.
|
||||
|
||||
When an entity is teleported dimensions, the entity reference is
|
||||
replaced with a new one with a new entity ID.
|
||||
|
||||
For hashCode, we can simply use the UUID's hashCode to keep
|
||||
the hashCode from changing.
|
||||
|
||||
equals() is ok to use getEntityId() because equals() should only
|
||||
be true if both the left and right are the same reference.
|
||||
|
||||
Since entity ids can not duplicate during runtime, this
|
||||
check is essentially the same as this.getHandle() == other.getHandle()
|
||||
|
||||
However, replaced it too to make it clearer of intent.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 21edae1b8d91341621155897d4da36bc06d2b2e5..473dc5e5ee3458e605ecf5e2b2dadb3573fd685b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -792,14 +792,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return false;
|
||||
}
|
||||
final CraftEntity other = (CraftEntity) obj;
|
||||
- return (this.getEntityId() == other.getEntityId());
|
||||
+ return (this.getHandle() == other.getHandle()); // Paper - while logically the same, this is clearer
|
||||
}
|
||||
|
||||
+ // Paper - Fix hashCode. entity ID's are not static.
|
||||
+ // A CraftEntity can change reference to a new entity with a new ID, and hash codes should never change
|
||||
@Override
|
||||
public int hashCode() {
|
||||
- int hash = 7;
|
||||
- hash = 29 * hash + this.getEntityId();
|
||||
- return hash;
|
||||
+ return getUniqueId().hashCode();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,95 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 00:30:32 -0400
|
||||
Subject: [PATCH] Configurable Alternative LootPool Luck Formula
|
||||
|
||||
Rewrites the Vanilla luck application formula so that luck can be
|
||||
applied to items that do not have any quality defined.
|
||||
|
||||
See: https://luckformula.emc.gs for data and details
|
||||
-----------
|
||||
|
||||
The rough summary is:
|
||||
My goal was that in a pool, when luck was applied, the pool
|
||||
rebalances so the percentages for bigger items is
|
||||
lowered and smaller items is boosted.
|
||||
|
||||
Do this by boosting and then reducing the weight value,
|
||||
so that larger numbers are penalized more than smaller numbers.
|
||||
resulting in a larger reduction of entries for more common
|
||||
items than the reduction on small weights,
|
||||
giving smaller weights more of a chance
|
||||
|
||||
-----------
|
||||
|
||||
This work kind of obsoletes quality, but quality would be useful
|
||||
for 2 items with same weight that you want luck to impact
|
||||
in varying directions.
|
||||
|
||||
Fishing still falls into that as the weights are closer, so luck
|
||||
will invalidate junk more.
|
||||
|
||||
This change will result in some major changes to fishing formulas.
|
||||
|
||||
-----------
|
||||
|
||||
I would love to see this change in Vanilla, so Mojang please pull :)
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index c5c82496524705a0ce85df5508ec730c19246ec7..8ecd1e851cc2168c538947623e1c328e463b52d9 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -309,4 +309,12 @@ public class PaperConfig {
|
||||
SpigotConfig.save();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public static boolean useAlternativeLuckFormula = false;
|
||||
+ private static void useAlternativeLuckFormula() {
|
||||
+ useAlternativeLuckFormula = getBoolean("settings.use-alternative-luck-formula", false);
|
||||
+ if (useAlternativeLuckFormula) {
|
||||
+ Bukkit.getLogger().log(Level.INFO, "Using Aikar's Alternative Luck Formula to apply Luck attribute to all loot pool calculations. See https://luckformula.emc.gs");
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
index 710a66e9aafe8bd622f9f37789c281aba98d030e..558f43580d976d7bde32779e47e24c9ad388892d 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
@@ -113,9 +113,35 @@ public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer
|
||||
protected abstract class EntryBase implements LootPoolEntry {
|
||||
@Override
|
||||
public int getWeight(float luck) {
|
||||
- return Math.max(Mth.floor((float)LootPoolSingletonContainer.this.weight + (float)LootPoolSingletonContainer.this.quality * luck), 0);
|
||||
+ // Paper start - Offer an alternative loot formula to refactor how luck bonus applies
|
||||
+ // SEE: https://luckformula.emc.gs for details and data
|
||||
+ if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) {
|
||||
+ return lastWeight;
|
||||
+ }
|
||||
+ // This is vanilla
|
||||
+ float qualityModifer = (float) LootPoolSingletonContainer.this.quality * luck;
|
||||
+ double baseWeight = (LootPoolSingletonContainer.this.weight + qualityModifer);
|
||||
+ if (com.destroystokyo.paper.PaperConfig.useAlternativeLuckFormula) {
|
||||
+ // Random boost to avoid losing precision in the final int cast on return
|
||||
+ final int weightBoost = 100;
|
||||
+ baseWeight *= weightBoost;
|
||||
+ // If we have vanilla 1, bump that down to 0 so nothing is is impacted
|
||||
+ // vanilla 3 = 300, 200 basis = impact 2%
|
||||
+ // =($B2*(($B2-100)/100/100))
|
||||
+ double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100);
|
||||
+ // =($B$7/100)
|
||||
+ float luckModifier = Math.min(100, luck * 10) / 100;
|
||||
+ // =B2 - (C2 *($B$7/100))
|
||||
+ baseWeight = Math.ceil(baseWeight - (impacted * luckModifier));
|
||||
+ }
|
||||
+ LootPoolSingletonContainer.this.lastLuck = luck;
|
||||
+ LootPoolSingletonContainer.this.lastWeight = (int) Math.max(Math.floor(baseWeight), 0);
|
||||
+ return lastWeight;
|
||||
}
|
||||
}
|
||||
+ private Float lastLuck = null;
|
||||
+ private int lastWeight = 0;
|
||||
+ // Paper end
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface EntryConstructor {
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 20:37:03 -0400
|
||||
Subject: [PATCH] Print Error details when failing to save player data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index 7b367e273c2a6869f8d8929c24ee45efdf6d4b1e..6727468946ea5f60bd80549f827a7c2b9a42b98b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -43,7 +43,7 @@ public class PlayerDataStorage {
|
||||
|
||||
Util.safeReplaceFile(file1, file, file2);
|
||||
} catch (Exception exception) {
|
||||
- PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getName().getString());
|
||||
+ PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper
|
||||
}
|
||||
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 16 Jun 2018 01:18:16 -0500
|
||||
Subject: [PATCH] Make shield blocking delay configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index a0937dd52e4a2aa1bfadcbd1ac0dc2cb26d59cf0..4dce401da0e0fdf985ecb90f37b92e16cf210d25 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -404,4 +404,9 @@ public class PaperWorldConfig {
|
||||
disableEnderpearlExploit = getBoolean("game-mechanics.disable-unloaded-chunk-enderpearl-exploit", disableEnderpearlExploit);
|
||||
log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled"));
|
||||
}
|
||||
+
|
||||
+ public int shieldBlockingDelay = 5;
|
||||
+ private void shieldBlockingDelay() {
|
||||
+ shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 669e621fdb0d05ee61dea5f212eb228f8be008ae..d1d3c11e105b65a4b7d300ef3c08d4f4f5b3dbfc 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3669,12 +3669,24 @@ public abstract class LivingEntity extends Entity {
|
||||
if (this.isUsingItem() && !this.useItem.isEmpty()) {
|
||||
Item item = this.useItem.getItem();
|
||||
|
||||
- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= 5;
|
||||
+ return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public int shieldBlockingDelay = level.paperConfig.shieldBlockingDelay;
|
||||
+
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return shieldBlockingDelay;
|
||||
+ }
|
||||
+
|
||||
+ public void setShieldBlockingDelay(int shieldBlockingDelay) {
|
||||
+ this.shieldBlockingDelay = shieldBlockingDelay;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public boolean isSuppressingSlidingDownLadder() {
|
||||
return this.isShiftKeyDown();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 3977069ccc96114ddae8d2f8f6578f74d8854127..a6e1edad4acd20b25f5e27afbbf580482efe29af 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -739,5 +739,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void setArrowsStuck(int arrows) {
|
||||
getHandle().setArrowCount(arrows);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return getHandle().getShieldBlockingDelay();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShieldBlockingDelay(int delay) {
|
||||
+ getHandle().setShieldBlockingDelay(delay);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 15 Jun 2013 19:51:17 -0400
|
||||
Subject: [PATCH] Improve EntityShootBowEvent
|
||||
|
||||
Adds missing call to Illagers and also adds Arrow ItemStack to skeltons
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
index d7bca8fa71e325ba1967537d4102ccb207c4d717..3d8f3e22223e4effeaf52cb18c14c60276d4689c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -196,7 +196,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level.getDifficulty().getId() * 4));
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true);
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper
|
||||
if (event.isCancelled()) {
|
||||
event.getProjectile().remove();
|
||||
return;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
index 73dbf08002e6b90e6dfc01369de7c53531dae43b..e1b8d9c0acfc248b9a24efc21aefc88e3caeb605 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
@@ -196,8 +196,18 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
|
||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level.getDifficulty().getId() * 4));
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, target.getUsedItemHand(), 0.8F, true);
|
||||
+ if (event.isCancelled()) {
|
||||
+ event.getProjectile().remove();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getProjectile() == entityarrow.getBukkitEntity()) {
|
||||
+ this.level.addFreshEntity(entityarrow);
|
||||
+ }
|
||||
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- this.level.addFreshEntity(entityarrow);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 18 Jun 2018 01:12:53 -0400
|
||||
Subject: [PATCH] PlayerReadyArrowEvent
|
||||
|
||||
Called when a player is firing a bow and the server is choosing an arrow to use.
|
||||
Plugins can skip selection of certain arrows and control which is used.
|
||||
|
||||
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 f7ee9ce075720ed59cf761463bae997a141a7be8..ea4e8680fc85d6c88078667b96e4412503713a37 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -2184,6 +2184,17 @@ public abstract class Player extends LivingEntity {
|
||||
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) {
|
||||
+ return !(this instanceof ServerPlayer) ||
|
||||
+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
|
||||
+ ((ServerPlayer) this).getBukkitEntity(),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
|
||||
+ ).callEvent();
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public ItemStack getProjectile(ItemStack stack) {
|
||||
if (!(stack.getItem() instanceof ProjectileWeaponItem)) {
|
||||
@@ -2200,7 +2211,7 @@ public abstract class Player extends LivingEntity {
|
||||
for (int i = 0; i < this.inventory.getContainerSize(); ++i) {
|
||||
ItemStack itemstack2 = this.inventory.getItem(i);
|
||||
|
||||
- if (predicate.test(itemstack2)) {
|
||||
+ if (predicate.test(itemstack2) && tryReadyArrow(stack, itemstack2)) { // Paper
|
||||
return itemstack2;
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Mon, 18 Jun 2018 15:46:23 +0200
|
||||
Subject: [PATCH] Implement EntityKnockbackByEntityEvent
|
||||
|
||||
This event is called when an entity receives knockback by another entity.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index a7f6127aae3c35d3570cba31cbf7a9be34e303b2..85aae87d03219a53e5aec2b9983dac2831aff82e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1437,7 +1437,7 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
this.hurtDir = (float) (Mth.atan2(d1, d0) * 57.2957763671875D - (double) this.getYRot());
|
||||
- this.knockback(0.4000000059604645D, d0, d1);
|
||||
+ this.knockback(0.4000000059604645D, d0, d1, entity1);
|
||||
} else {
|
||||
this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180);
|
||||
}
|
||||
@@ -1485,7 +1485,7 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
protected void blockedByShield(LivingEntity target) {
|
||||
- target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ());
|
||||
+ target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), this);
|
||||
}
|
||||
|
||||
private boolean checkTotemDeathProtection(DamageSource source) {
|
||||
@@ -1738,6 +1738,11 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
public void knockback(double strength, double x, double z) {
|
||||
+ // Paper start - add knockbacking entity parameter
|
||||
+ this.knockback(strength, x, z, null);
|
||||
+ }
|
||||
+ public void knockback(double strength, double x, double z, Entity knockingBackEntity) {
|
||||
+ // Paper end - add knockbacking entity parameter
|
||||
strength *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
|
||||
if (strength > 0.0D) {
|
||||
this.hasImpulse = true;
|
||||
@@ -1745,6 +1750,15 @@ public abstract class LivingEntity extends Entity {
|
||||
Vec3 vec3d1 = (new Vec3(x, 0.0D, z)).normalize().scale(strength);
|
||||
|
||||
this.setDeltaMovement(vec3d.x / 2.0D - vec3d1.x, this.onGround ? Math.min(0.4D, vec3d.y / 2.0D + strength) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
|
||||
+ // Paper start - call EntityKnockbackByEntityEvent
|
||||
+ Vec3 currentMovement = this.getDeltaMovement();
|
||||
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(currentMovement.x - vec3d.x, currentMovement.y - vec3d.y, currentMovement.z - vec3d.z);
|
||||
+ // Restore old velocity to be able to access it in the event
|
||||
+ this.setDeltaMovement(vec3d);
|
||||
+ if (knockingBackEntity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((org.bukkit.entity.LivingEntity) getBukkitEntity(), knockingBackEntity.getBukkitEntity(), (float) strength, delta).callEvent()) {
|
||||
+ this.setDeltaMovement(vec3d.x + delta.getX(), vec3d.y + delta.getY(), vec3d.z + delta.getZ());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 4f3613e8232df3b4d9e10970b9faf9fbdd3b34a2..6e5682fed08a41c7e573e6611fca93bf85019b9f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -1537,7 +1537,7 @@ public abstract class Mob extends LivingEntity {
|
||||
|
||||
if (flag) {
|
||||
if (f1 > 0.0F && target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
index f6fd39823f04f8071c616d40a838b01e7159c5a1..e1cdf3ce38404d3f40be59e4cd3ad2b997d63310 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
@@ -75,7 +75,7 @@ public class RamTarget<E extends PathfinderMob> extends Behavior<E> {
|
||||
float f = 0.25F * (float)(i - j);
|
||||
float g = Mth.clamp(pathfinderMob.getSpeed() * 1.65F, 0.2F, 3.0F) + f;
|
||||
float h = livingEntity.isDamageSourceBlocked(DamageSource.mobAttack(pathfinderMob)) ? 0.5F : 1.0F;
|
||||
- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(pathfinderMob), this.ramDirection.x(), this.ramDirection.z());
|
||||
+ livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(pathfinderMob), this.ramDirection.x(), this.ramDirection.z(), pathfinderMob); // Paper
|
||||
this.finishRam(serverLevel, pathfinderMob);
|
||||
serverLevel.playSound((Player)null, pathfinderMob, this.getImpactSound.apply(pathfinderMob), SoundSource.HOSTILE, 1.0F, 1.0F);
|
||||
} else {
|
||||
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 ea4e8680fc85d6c88078667b96e4412503713a37..7d09d12fe4d8a01ae5849f967afcef1dcc773a04 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1232,7 +1232,7 @@ public abstract class Player extends LivingEntity {
|
||||
if (flag5) {
|
||||
if (i > 0) {
|
||||
if (target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper
|
||||
} else {
|
||||
target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F));
|
||||
}
|
||||
@@ -1256,7 +1256,7 @@ public abstract class Player extends LivingEntity {
|
||||
if (entityliving != this && entityliving != target && !this.isAlliedTo(entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) {
|
||||
// CraftBukkit start - Only apply knockback if the damage hits
|
||||
if (entityliving.hurt(DamageSource.playerAttack(this).sweep(), f4)) {
|
||||
- entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 20 Jun 2018 23:17:24 -0400
|
||||
Subject: [PATCH] Expand Explosions API
|
||||
|
||||
Add Entity as a Source capability, and add more API choices, and on Location.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 7fbd068cbf96332b6ea45411f45e9e0910693c57..4f9487ac3535b2609ad57f7c1d9504801e8aa2a6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -688,6 +688,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
|
||||
return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean createExplosion(Location loc, float power) {
|
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 Jun 2018 00:21:28 -0400
|
||||
Subject: [PATCH] LivingEntity Hand Raised/Item Use API
|
||||
|
||||
How long an entity has raised hands to charge an attack or use an item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index a6e1edad4acd20b25f5e27afbbf580482efe29af..db3123b4a6582ad1667b24b9ff03caf671287857 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -749,5 +749,30 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void setShieldBlockingDelay(int delay) {
|
||||
getHandle().setShieldBlockingDelay(delay);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack getActiveItem() {
|
||||
+ return getHandle().getUseItem().asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getItemUseRemainingTime() {
|
||||
+ return getHandle().getUseItemRemainingTicks();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getHandRaisedTime() {
|
||||
+ return getHandle().getTicksUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isHandRaised() {
|
||||
+ return getHandle().isUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.EquipmentSlot getHandRaised() {
|
||||
+ return getHandle().getUsedItemHand() == net.minecraft.world.InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 26 Jun 2018 22:00:49 -0400
|
||||
Subject: [PATCH] RangedEntity API
|
||||
|
||||
Allows you to determine if an entity is capable of ranged attacks,
|
||||
and to perform an attack.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e75e1d0d833c96af139fd955b2585ec24281b294
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
@@ -0,0 +1,19 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import net.minecraft.world.entity.monster.RangedAttackMob;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+
|
||||
+public interface CraftRangedEntity<T extends RangedAttackMob> extends RangedEntity {
|
||||
+ T getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default void rangedAttack(LivingEntity target, float charge) {
|
||||
+ getHandle().rangedAttack(((CraftLivingEntity) target).getHandle(), charge);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void setChargingAttack(boolean raiseHands) {
|
||||
+ getHandle().setChargingAttack(raiseHands);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java b/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
|
||||
index 6c3162606ccf799e99d591da33fd649847db54b8..ad9a8198cec21ab766ad8a274937ecbbed56bef6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
|
||||
@@ -3,5 +3,8 @@ package net.minecraft.world.entity.monster;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public interface RangedAttackMob {
|
||||
- void performRangedAttack(LivingEntity target, float pullProgress);
|
||||
+ void performRangedAttack(LivingEntity target, float pullProgress); @Deprecated default void rangedAttack(LivingEntity entityliving, float f) { performRangedAttack(entityliving, f); } // Paper - OBFHELPER
|
||||
+
|
||||
+ // - see EntitySkeletonAbstract melee goal
|
||||
+ void setAggressive(boolean flag); default void setChargingAttack(boolean charging) { setAggressive(charging); }; // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
index db6ad6eea8fa6f2755bbb0e1325df8bda98e708a..5ff566186431440c25a26900aba14e4adb642031 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.AbstractSkeleton;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
-public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton {
|
||||
+public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.AbstractSkeleton> { // Paper
|
||||
|
||||
public CraftAbstractSkeleton(CraftServer server, net.minecraft.world.entity.monster.AbstractSkeleton entity) {
|
||||
super(server, entity);
|
||||
@@ -14,4 +14,10 @@ public abstract class CraftAbstractSkeleton extends CraftMonster implements Abst
|
||||
public void setSkeletonType(Skeleton.SkeletonType type) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.monster.AbstractSkeleton getHandle() {
|
||||
+ return (net.minecraft.world.entity.monster.AbstractSkeleton) super.getHandle();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
index 34cb8062168258bfd168826ceeb2fde669f6d1a8..03e2acd4829da449a471b0fa1a311e74aee114d3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Drowned;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
-public class CraftDrowned extends CraftZombie implements Drowned {
|
||||
+public class CraftDrowned extends CraftZombie implements Drowned, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Drowned> { // Paper
|
||||
|
||||
public CraftDrowned(CraftServer server, net.minecraft.world.entity.monster.Drowned entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
index 59b866e54e0d7e1dd8815ffa85275e36271113da..bbf7189a0fc9921e7a6007494f91229d9fba0846 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Illusioner;
|
||||
|
||||
-public class CraftIllusioner extends CraftSpellcaster implements Illusioner {
|
||||
+public class CraftIllusioner extends CraftSpellcaster implements Illusioner, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Illusioner> { // Paper
|
||||
|
||||
public CraftIllusioner(CraftServer server, net.minecraft.world.entity.monster.Illusioner entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
index bda998c9e621bd9bca6642bfa86befed08f4902b..6ad12711a82d7be42ba41c0428779f86536fd900 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
@@ -9,7 +9,7 @@ import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.Llama.Color;
|
||||
import org.bukkit.inventory.LlamaInventory;
|
||||
|
||||
-public class CraftLlama extends CraftChestedHorse implements Llama {
|
||||
+public class CraftLlama extends CraftChestedHorse implements Llama, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.animal.horse.Llama> { // Paper
|
||||
|
||||
public CraftLlama(CraftServer server, net.minecraft.world.entity.animal.horse.Llama entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
index 27763d1eca832abda76c8b3c22595cbaf9b1fe45..aeda5fc001fe4ce55ee467240b275b6050a29f98 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
@@ -13,7 +13,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Piglin;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPiglin extends CraftPiglinAbstract implements Piglin {
|
||||
+public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.piglin.Piglin> { // Paper
|
||||
|
||||
public CraftPiglin(CraftServer server, net.minecraft.world.entity.monster.piglin.Piglin entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
index 06786fba1fef36e8fc3d0f5650160123f728a6d1..beea227855f0b978e655efc298024120df8f4945 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
@@ -6,7 +6,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Pillager;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPillager extends CraftIllager implements Pillager {
|
||||
+public class CraftPillager extends CraftIllager implements Pillager, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Pillager> { // Paper
|
||||
|
||||
public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
index 6a82d567d96a42bfea0e38afb4e8de13eb3ad5a2..659e2959c5330e4764ea1edc7f8de9f464f9ff52 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -5,7 +5,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Snowman;
|
||||
|
||||
-public class CraftSnowman extends CraftGolem implements Snowman {
|
||||
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
|
||||
public CraftSnowman(CraftServer server, SnowGolem entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
index 60e00e539d214eb8854a53364c92c3cf55ca1062..d4eeb071dbbfca3ecea256228853bcb5c11f49ee 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
@@ -4,7 +4,7 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Witch;
|
||||
|
||||
-public class CraftWitch extends CraftRaider implements Witch {
|
||||
+public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Witch> { // Paper
|
||||
public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
index 54a7defa85542765f3dd0d7ccb770dafd9c7d484..640b0860fbe3412da32d03187e6f355ba8f099ea 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.boss.CraftBossBar;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Wither;
|
||||
|
||||
-public class CraftWither extends CraftMonster implements Wither {
|
||||
+public class CraftWither extends CraftMonster implements Wither, com.destroystokyo.paper.entity.CraftRangedEntity<WitherBoss> { // Paper
|
||||
|
||||
private BossBar bossBar;
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 22 Jun 2018 10:38:31 -0500
|
||||
Subject: [PATCH] Add config to disable ender dragon legacy check
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 4dce401da0e0fdf985ecb90f37b92e16cf210d25..35c6978eaf25ed505f99e42a58d388c62fde8319 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -409,4 +409,9 @@ public class PaperWorldConfig {
|
||||
private void shieldBlockingDelay() {
|
||||
shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5);
|
||||
}
|
||||
+
|
||||
+ public boolean scanForLegacyEnderDragon = true;
|
||||
+ private void scanForLegacyEnderDragon() {
|
||||
+ scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 758af2c2d66073aeaee766adb672c465d2993eab..711be01abe9d47bdc9bfe8b09a2719d666b986fb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -84,6 +84,10 @@ public class EndDragonFight {
|
||||
private List<EndCrystal> respawnCrystals;
|
||||
|
||||
public EndDragonFight(ServerLevel world, long gatewaysSeed, CompoundTag nbt) {
|
||||
+ // Paper start
|
||||
+ this.needsStateScanning = world.paperConfig.scanForLegacyEnderDragon;
|
||||
+ if (!this.needsStateScanning) this.dragonKilled = true;
|
||||
+ // Paper end
|
||||
this.level = world;
|
||||
if (nbt.contains("NeedsStateScanning")) {
|
||||
this.needsStateScanning = nbt.getBoolean("NeedsStateScanning");
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 3 Jul 2018 16:08:14 +0200
|
||||
Subject: [PATCH] Implement World.getEntity(UUID) API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 4f9487ac3535b2609ad57f7c1d9504801e8aa2a6..375c3adac2dc80f15d06e8acb11c8c451ec579e5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1022,6 +1022,15 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return list;
|
||||
}
|
||||
|
||||
+ // Paper start - getEntity by UUID API
|
||||
+ @Override
|
||||
+ public Entity getEntity(UUID uuid) {
|
||||
+ Validate.notNull(uuid, "UUID cannot be null");
|
||||
+ net.minecraft.world.entity.Entity entity = world.getEntity(uuid);
|
||||
+ return entity == null ? null : entity.getBukkitEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void save() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot
|
|
@ -1,221 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 3 Jul 2018 21:56:23 -0400
|
||||
Subject: [PATCH] InventoryCloseEvent Reason API
|
||||
|
||||
Allows you to determine why an inventory was closed, enabling plugin developers
|
||||
to "confirm" things based on if it was player triggered close or not.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index d09556a6559a6984a7aec341eb5678222ed67da3..b524db142fdc9596e9a10bf0208877c556c5ecbe 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1107,7 +1107,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
|
||||
if (tileentity instanceof net.minecraft.world.Container) {
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1993,7 +1993,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// Spigot Start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder) {
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
|
||||
}
|
||||
}
|
||||
// Spigot End
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 3bcb8ae7391f405c11cf1c117848eeb9aae7bcaa..3d5db5ce2e60ca72ad202caebe49f3fc80d1af37 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -597,7 +597,7 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// Paper end
|
||||
if (!this.level.isClientSide && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
// SPIGOT-943 - only call if they have an inventory open
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper
|
||||
}
|
||||
|
||||
net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
|
||||
@@ -1402,7 +1402,7 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
|
||||
// this.nextContainerCounter(); // CraftBukkit - moved up
|
||||
@@ -1431,7 +1431,13 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
|
||||
+ // Paper start
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
|
||||
+ // Paper end
|
||||
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
this.doCloseContainer();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 23bd778a4b784c93115924afdd97852ca27cbdd5..e1123f0523fbf1e07cdc44d029c7837ada31194b 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -187,6 +187,7 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
+import org.bukkit.event.inventory.InventoryCloseEvent; // Paper
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.inventory.SmithItemEvent;
|
||||
@@ -2320,10 +2321,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
|
||||
@Override
|
||||
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
|
||||
+ // Paper start
|
||||
+ handleContainerClose(packet, InventoryCloseEvent.Reason.PLAYER);
|
||||
+ }
|
||||
+ public void handleContainerClose(ServerboundContainerClosePacket packetplayinclosewindow, InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end
|
||||
+ PacketUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel());
|
||||
|
||||
if (this.player.isImmobile()) return; // CraftBukkit
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
|
||||
|
||||
this.player.doCloseContainer();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 17f56157d60d33695c4eac0e4fc94120a2101214..c4940b2538e8adfe5f19cb5f1a5373319a1cb89b 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -502,7 +502,7 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
// See SPIGOT-5799, SPIGOT-6145
|
||||
if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
|
||||
- entityplayer.closeContainer();
|
||||
+ entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
|
||||
}
|
||||
|
||||
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
|
||||
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 7d09d12fe4d8a01ae5849f967afcef1dcc773a04..f5bc151aae4f8335994507c89a094177347dfce1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -264,7 +264,7 @@ public abstract class Player extends LivingEntity {
|
||||
this.updateIsUnderwater();
|
||||
super.tick();
|
||||
if (!this.level.isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -487,6 +487,13 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - unused code, but to keep signatures aligned
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ closeContainer();
|
||||
+ this.containerMenu = this.inventoryMenu;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void closeContainer() {
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index f1b1d1881d0598503a7ec1022ef5e00f848fb247..460828d29583ee21a7c5b716f9687a8243911a7e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -373,7 +373,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
if (((ServerPlayer) this.getHandle()).connection == null) return;
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
// fire INVENTORY_CLOSE if one already open
|
||||
- ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId));
|
||||
+ ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
ServerPlayer player = (ServerPlayer) this.getHandle();
|
||||
AbstractContainerMenu container;
|
||||
@@ -443,8 +443,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void closeInventory() {
|
||||
- this.getHandle().closeContainer();
|
||||
+ // Paper start
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN);
|
||||
}
|
||||
+ @Override
|
||||
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ getHandle().closeContainer(reason);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index c07916e07e09f1491c9bad7d13b127960dd167a6..7d87be1eb79045226cad3b7e62ff5d265160b866 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -935,7 +935,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
// Close any foreign inventory
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
- this.getHandle().closeContainer();
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper
|
||||
}
|
||||
|
||||
// Check if the fromWorld and toWorld are the same.
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index b370bbad550d6efda1fe391fb5d093a99f2a5532..8e0b6910c97789b4d03ae62723dceb962487fc5a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1193,7 +1193,7 @@ public class CraftEventFactory {
|
||||
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
|
||||
- player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId));
|
||||
+ player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
|
||||
CraftServer server = player.level.getCraftServer();
|
||||
@@ -1359,8 +1359,18 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Incase plugins hooked into this or Spigot adds a new inventory close event. Prefer to pass a reason
|
||||
+ * @param human
|
||||
+ */
|
||||
+ @Deprecated
|
||||
public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human) {
|
||||
- InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView());
|
||||
+ handleInventoryCloseEvent(human, org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end
|
||||
+ InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView(), reason); // Paper
|
||||
human.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity());
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 Jul 2018 15:30:22 -0400
|
||||
Subject: [PATCH] Vex#get/setSummoner API
|
||||
|
||||
Get's the NPC that summoned this Vex and
|
||||
Allow setting the vex's summoner
|
||||
|
||||
Co-authored-by: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
index d07d956e727483bb0b85dce618acb2adc8d89872..0f5c81c0d599d3b58f7864d1527391ad50983c4e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
@@ -15,6 +15,19 @@ public class CraftVex extends CraftMonster implements Vex {
|
||||
return (net.minecraft.world.entity.monster.Vex) super.getHandle();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Mob getSummoner() {
|
||||
+ net.minecraft.world.entity.Mob owner = getHandle().getOwner();
|
||||
+ return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSummoner(org.bukkit.entity.Mob summoner) {
|
||||
+ getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftVex";
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Fri, 13 Jul 2018 14:54:43 +0200
|
||||
Subject: [PATCH] Refresh player inventory when cancelling
|
||||
PlayerInteractEntityEvent
|
||||
|
||||
When interacting with entities with an item, the client will assume
|
||||
the interaction is successful, and update the held item on the
|
||||
client. However, if the interaction is cancelled on the server side,
|
||||
the client will still mistakenly remove/replace the item in hand.
|
||||
|
||||
Examples for this are milking cows with a bucket or dyeing sheep.
|
||||
The bucket is replaced with milk and the dye removed from inventory.
|
||||
|
||||
Refresh the player inventory when PlayerInteractEntityEvent is
|
||||
cancelled to avoid this problem.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 897a950a5a0b669aff05387efb9c403764a0e8ea..857fa3a4f2d5afd27df7ce943359705b3ea131d3 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2205,6 +2205,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
|
@ -1,21 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 16 Jul 2018 12:42:20 +0200
|
||||
Subject: [PATCH] Avoid item merge if stack size above max stack size
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 54025e401eb02fceb47afb182f0ede620ca23a8d..0741dcbd06395b4696eb6083128a5d9b679cb3fb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -223,6 +223,10 @@ public class ItemEntity extends Entity {
|
||||
|
||||
private void mergeWithNeighbours() {
|
||||
if (this.isMergable()) {
|
||||
+ // Paper start - avoid item merge if stack size above max stack size
|
||||
+ ItemStack stack = getItem();
|
||||
+ if (stack.getCount() >= stack.getMaxStackSize()) return;
|
||||
+ // Paper end
|
||||
// Spigot start
|
||||
double radius = level.spigotConfig.itemMerge;
|
||||
List<ItemEntity> list = this.level.getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, radius, radius), (entityitem) -> {
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Thu, 12 Aug 2021 04:46:41 -0700
|
||||
Subject: [PATCH] Use AsyncAppender to keep logging IO off main thread
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index fc8ffeea3e808eb1381f85972adffc614937ef6d..c981944f4a5d40ec14ade9aaa22041887a317e1f 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -37,6 +37,7 @@ dependencies {
|
||||
}
|
||||
runtimeOnly("org.xerial:sqlite-jdbc:3.34.0")
|
||||
runtimeOnly("mysql:mysql-connector-java:8.0.23") // Paper
|
||||
+ runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
|
||||
|
||||
runtimeOnly("org.apache.maven:maven-resolver-provider:3.8.1")
|
||||
runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.0")
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 476f4a5cbe664ddd05474cb88553018bd334a5b8..3dc317e466e1b93dff030794dd7f29ca1b266778 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -29,15 +29,18 @@
|
||||
</Policies>
|
||||
<DefaultRolloverStrategy max="1000"/>
|
||||
</RollingRandomAccessFile>
|
||||
+ <Async name="Async">
|
||||
+ <AppenderRef ref="File"/>
|
||||
+ <AppenderRef ref="TerminalConsole" level="info"/>
|
||||
+ <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
+ </Async>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||
</filters>
|
||||
- <AppenderRef ref="File"/>
|
||||
- <AppenderRef ref="TerminalConsole" level="info"/>
|
||||
- <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
+ <AppenderRef ref="Async"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 19 Jul 2018 01:13:28 -0400
|
||||
Subject: [PATCH] add more information to Entity.toString()
|
||||
|
||||
UUID, ticks lived, valid, dead
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 3b2334e9ba44205a4e0ec12045eab4fad91bb15a..2a6954e3c9ff82d68647bf8f4c4803184fab0bbe 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2815,7 +2815,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
- return String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.level == null ? "~NULL~" : this.level.toString(), this.getX(), this.getY(), this.getZ());
|
||||
+ return String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b, rR=%s]", new Object[] { this.getClass().getSimpleName(), this.getName().getString(), Integer.valueOf(this.id), this.uuid.toString(), this.level == null ? "~NULL~" : this.level.toString(), Double.valueOf(this.getX()), Double.valueOf(this.getY()), Double.valueOf(this.getZ()), this.chunkPosition(), this.tickCount, this.valid, this.removalReason}); // Paper - add more information
|
||||
}
|
||||
|
||||
public boolean isInvulnerableTo(DamageSource damageSource) {
|
|
@ -1,22 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BlackHole <black-hole@live.com>
|
||||
Date: Sun, 15 Dec 2019 19:12:39 +0100
|
||||
Subject: [PATCH] Add CraftMagicNumbers.isSupportedApiVersion()
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 2b54c6980166cb7378e3db42d3a68005ebf451a1..f8cb210390958ddba9f9685f2ec1f8bb91690162 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -373,6 +373,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
||||
return new com.destroystokyo.paper.PaperVersionFetcher();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSupportedApiVersion(String apiVersion) {
|
||||
+ return apiVersion != null && SUPPORTED_API.contains(apiVersion);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
/**
|
|
@ -1,53 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:51:27 -0500
|
||||
Subject: [PATCH] EnderDragon Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
index df44bfce8cc492cd901dfa86331b9be7f1e13837..7490674d59d152a70e24a790bdbc717998ed2c52 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
@@ -81,7 +81,13 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase {
|
||||
this.flame.setDuration(200);
|
||||
this.flame.setParticle(ParticleTypes.DRAGON_BREATH);
|
||||
this.flame.addEffect(new MobEffectInstance(MobEffects.HARM));
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.dragon.level.addFreshEntity(this.flame);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.end();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
index 974895ef23e9d2b8c520abd262a2e80d28be5860..318a288a9170254b682955d96a150e99ca89b345 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
@@ -71,7 +71,9 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance {
|
||||
|
||||
DragonFireball dragonFireball = new DragonFireball(this.dragon.level, this.dragon, r, s, t);
|
||||
dragonFireball.moveTo(o, p, q, 0.0F, 0.0F);
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper
|
||||
this.dragon.level.addFreshEntity(dragonFireball);
|
||||
+ else dragonFireball.discard(); // Paper
|
||||
this.fireballCharge = 0;
|
||||
if (this.currentPath != null) {
|
||||
while(!this.currentPath.isDone()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
index a7935042497a108a21814c28b01a0ab27aefbbc4..6afe37e42d88701af38df5793a9ea9d7d2cda5c5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -52,8 +52,10 @@ public class DragonFireball extends AbstractHurtingProjectile {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.level.levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
this.level.addFreshEntity(areaEffectCloud);
|
||||
+ } else areaEffectCloud.discard(); // Paper
|
||||
this.discard();
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:59:59 -0500
|
||||
Subject: [PATCH] PlayerElytraBoostEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 10385dcb851bb435821afba322ed11f59e7ad3e6..561f98b442788814cbc6cbb7e144207d14f67ff8 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -61,12 +61,19 @@ public class FireworkRocketItem extends Item {
|
||||
if (!world.isClientSide) {
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
|
||||
fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
|
||||
- world.addFreshEntity(fireworkRocketEntity);
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
+ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - move up
|
||||
}
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
|
|
@ -1,276 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 03:11:03 -0500
|
||||
Subject: [PATCH] PlayerLaunchProjectileEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
index c33210c18445a93ca6445812471aaf1e55bcc44d..98b353f5cc05da5ee5a6c6110a08e43e819fe6d2 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
@@ -25,21 +25,33 @@ public class EggItem extends Item {
|
||||
|
||||
entityegg.setItem(itemstack);
|
||||
entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- // CraftBukkit start
|
||||
- if (!world.addFreshEntity(entityegg)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityegg)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), net.minecraft.sounds.SoundEvents.EGG_THROW, net.minecraft.sounds.SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return InteractionResultHolder.fail(itemstack);
|
||||
}
|
||||
- // CraftBukkit end
|
||||
+ // Paper end
|
||||
}
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
index c7d4745aed77b23562cde7c68b8870fa239428d4..749ab72edc0d2e9c6f1161415ab8d59d3d6ca976 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
@@ -25,7 +25,20 @@ public class EnderpearlItem extends Item {
|
||||
|
||||
entityenderpearl.setItem(itemstack);
|
||||
entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (!world.addFreshEntity(entityenderpearl)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityenderpearl)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ user.getCooldowns().addCooldown(this, 20);
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
@@ -33,6 +46,7 @@ public class EnderpearlItem extends Item {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
user.getCooldowns().addCooldown(this, 20);
|
||||
// CraftBukkit end
|
||||
@@ -41,6 +55,7 @@ public class EnderpearlItem extends Item {
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end - moved up
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
index 72dfb7b652f515bf9df201d524a851ab56706544..b80bedb5f27b474d7f66e9e1cc38ca3b692fc92b 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
@@ -22,18 +22,37 @@ public class ExperienceBottleItem extends Item {
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
ItemStack itemStack = user.getItemInHand(hand);
|
||||
- world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
+ // world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // Paper - moved down
|
||||
if (!world.isClientSide) {
|
||||
ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user);
|
||||
thrownExperienceBottle.setItem(itemStack);
|
||||
thrownExperienceBottle.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.7F, 1.0F);
|
||||
- world.addFreshEntity(thrownExperienceBottle);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownExperienceBottle)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 561f98b442788814cbc6cbb7e144207d14f67ff8..543a08f920319a2547258640bafebb1e70af65c4 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -13,6 +13,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.stats.Stats;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
@@ -47,8 +48,12 @@ public class FireworkRocketItem extends Item {
|
||||
Direction direction = context.getClickedFace();
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack);
|
||||
fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper
|
||||
- level.addFreshEntity(fireworkRocketEntity);
|
||||
- itemStack.shrink(1);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (!event.callEvent() || !level.addFreshEntity(fireworkRocketEntity)) return InteractionResult.PASS;
|
||||
+ if (event.shouldConsume() && !context.getPlayer().getAbilities().instabuild) itemStack.shrink(1);
|
||||
+ else if (context.getPlayer() instanceof ServerPlayer) ((ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
index db0492f6337de562210ef062f46e98992c908200..f2d1b4e3fc08f6a06beb391bc6e60f62a9bf82b9 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
@@ -23,7 +23,12 @@ public class LingeringPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
index 516afa893035539a879a71eb327eed0596c31d48..717f90a2ca41734f7ee09401f21474820fa1cf48 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
@@ -26,18 +26,26 @@ public class SnowballItem extends Item {
|
||||
|
||||
entitysnowball.setItem(itemstack);
|
||||
entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (world.addFreshEntity(entitysnowball)) {
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ // Paper end
|
||||
itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
}
|
||||
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
- ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else { // Paper
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
+ return InteractionResultHolder.fail(itemstack); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ /* // Paper tart - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
// CraftBukkit start - moved up
|
||||
/*
|
||||
@@ -45,6 +53,7 @@ public class SnowballItem extends Item {
|
||||
itemstack.subtract(1);
|
||||
}
|
||||
*/
|
||||
+ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
index 317e20052bcac9118e1adeb619bedaacc6fcd690..ece19f30064e9f59d4df077683e1f894455a84b7 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
@@ -14,7 +14,12 @@ public class SplashPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
index 0673f62f25532955f3552b64f122e644d42027e4..de5bdceb4c8578fb972a2fd5ee0dfdae509e46dc 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
@@ -19,13 +19,31 @@ public class ThrowablePotionItem extends PotionItem {
|
||||
ThrownPotion thrownPotion = new ThrownPotion(world, user);
|
||||
thrownPotion.setItem(itemStack);
|
||||
thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F);
|
||||
- world.addFreshEntity(thrownPotion);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Wed, 30 Nov 2016 20:56:58 -0600
|
||||
Subject: [PATCH] Improve BlockPosition inlining
|
||||
|
||||
Normally the JVM can inline virtual getters by having two sets of code, one is the 'optimized' code and the other is the 'deoptimized' code.
|
||||
If a single type is used 99% of the time, then its worth it to inline, and to revert to 'deoptimized' the 1% of the time we encounter other types.
|
||||
But if two types are encountered commonly, then the JVM can't inline them both, and the call overhead remains.
|
||||
|
||||
This scenario also occurs with BlockPos and MutableBlockPos.
|
||||
The variables in BlockPos are final, so MutableBlockPos can't modify them.
|
||||
MutableBlockPos fixes this by adding custom mutable variables, and overriding the getters to access them.
|
||||
|
||||
This approach with utility methods that operate on MutableBlockPos and BlockPos.
|
||||
Specific examples are BlockPosition.up(), and World.isValidLocation().
|
||||
It makes these simple methods much slower than they need to be.
|
||||
|
||||
This should result in an across the board speedup in anything that accesses blocks or does logic with positions.
|
||||
|
||||
This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my microbenchmarks.
|
||||
They had 'callq' (invoke) instead of 'mov' (get from memory) instructions.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
index f924f2b20800dfde93eeafea3614203661d35389..dc7598a011c2b290a42df35593de0b6689c99c57 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -41,7 +41,7 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public final boolean equals(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (!(object instanceof Vec3i)) {
|
||||
@@ -59,7 +59,7 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int hashCode() {
|
||||
+ public final int hashCode() { // Paper
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -72,15 +72,15 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
}
|
||||
|
||||
- public int getX() {
|
||||
+ public final int getX() { // Paper
|
||||
return this.x;
|
||||
}
|
||||
|
||||
- public int getY() {
|
||||
+ public final int getY() { // Paper
|
||||
return this.y;
|
||||
}
|
||||
|
||||
- public int getZ() {
|
||||
+ public final int getZ() { // Paper
|
||||
return this.z;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Steinborn <git@steinborn.me>
|
||||
Date: Mon, 23 Jul 2018 13:08:19 -0400
|
||||
Subject: [PATCH] Optimize IntIdentityHashBiMiap#nextId()
|
||||
|
||||
Optimizes CrudeIncrementalIntIdentityHashBiMap#nextId()
|
||||
|
||||
This is a frequent hotspot for world loading/saving.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
|
||||
index feaa9572a450b88a26659d850a269d09465259ee..62440dbb35263cddc90ba594c3d5777d7643e527 100644
|
||||
--- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
|
||||
+++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
|
||||
@@ -16,12 +16,14 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
|
||||
private K[] byId;
|
||||
private int nextId;
|
||||
private int size;
|
||||
+ private java.util.BitSet usedIds; // Paper
|
||||
|
||||
public CrudeIncrementalIntIdentityHashBiMap(int size) {
|
||||
size = (int)((float)size / 0.8F);
|
||||
this.keys = (K[])(new Object[size]);
|
||||
this.values = new int[size];
|
||||
this.byId = (K[])(new Object[size]);
|
||||
+ this.usedIds = new java.util.BitSet(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,9 +56,13 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
|
||||
}
|
||||
|
||||
private int nextId() {
|
||||
+ /* // Paper start
|
||||
while(this.nextId < this.byId.length && this.byId[this.nextId] != null) {
|
||||
++this.nextId;
|
||||
}
|
||||
+ */
|
||||
+ this.nextId = this.usedIds.nextClearBit(0);
|
||||
+ // Paper end
|
||||
|
||||
return this.nextId;
|
||||
}
|
||||
@@ -69,6 +75,7 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
|
||||
this.byId = (K[])(new Object[newSize]);
|
||||
this.nextId = 0;
|
||||
this.size = 0;
|
||||
+ this.usedIds.clear(); // Paper
|
||||
|
||||
for(int i = 0; i < objects.length; ++i) {
|
||||
if (objects[i] != null) {
|
||||
@@ -92,6 +99,7 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
|
||||
this.keys[k] = value;
|
||||
this.values[k] = id;
|
||||
this.byId[id] = value;
|
||||
+ this.usedIds.set(id); // Paper
|
||||
++this.size;
|
||||
if (id == this.nextId) {
|
||||
++this.nextId;
|
||||
@@ -153,6 +161,7 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
|
||||
Arrays.fill(this.byId, (Object)null);
|
||||
this.nextId = 0;
|
||||
this.size = 0;
|
||||
+ this.usedIds.clear(); // Paper
|
||||
}
|
||||
|
||||
public int size() {
|
|
@ -1,50 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 23 Jul 2018 12:57:39 +0200
|
||||
Subject: [PATCH] Option to prevent armor stands from doing entity lookups
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 35c6978eaf25ed505f99e42a58d388c62fde8319..0fd29d5854d9d6155ea590f86d4492d86afab433 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -414,4 +414,9 @@ public class PaperWorldConfig {
|
||||
private void scanForLegacyEnderDragon() {
|
||||
scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
|
||||
}
|
||||
+
|
||||
+ public boolean armorStandEntityLookups = true;
|
||||
+ private void armorStandEntityLookups() {
|
||||
+ armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 04ee36326b16e2aa070fd3318bd4a30bce67e49a..9a63260b20903eb4600f098c81ae660029f7c345 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -339,6 +339,7 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
protected void pushEntities() {
|
||||
+ if (!level.paperConfig.armorStandEntityLookups) return; // Paper
|
||||
List<Entity> list = this.level.getEntities(this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 233a8fcfae4ac568ad1f73cc61d8ae5b66a01ac2..e8d1a17b8e65e1af03ad36afd98b3e6ebab2592a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -774,6 +774,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
+ // Paper start - Prevent armor stands from doing entity lookups
|
||||
+ @Override
|
||||
+ public boolean noCollision(@Nullable Entity entity, AABB box) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level.paperConfig.armorStandEntityLookups) return false;
|
||||
+ return LevelAccessor.super.noCollision(entity, box);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public Explosion explode(@Nullable Entity entity, double x, double y, double z, float power, Explosion.BlockInteraction destructionType) {
|
||||
return this.explode(entity, (DamageSource) null, (ExplosionDamageCalculator) null, x, y, z, power, false, destructionType);
|
|
@ -1,119 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 23 Jul 2018 14:22:26 +0200
|
||||
Subject: [PATCH] Vanished players don't have rights
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index 8af1571c614a39c9673e0dc90e3aa9a89a367e34..daa55eed9cf385c7e2cdd0a5dceaf0a719652213 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -209,7 +209,14 @@ public abstract class Projectile extends Entity {
|
||||
if (!entity.isSpectator() && entity.isAlive() && entity.isPickable()) {
|
||||
Entity entity1 = this.getOwner();
|
||||
|
||||
+ // Paper start - Cancel hit for vanished players
|
||||
+ if (entity1 instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity();
|
||||
+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity();
|
||||
+ if (!shooter.canSee(collided)) return false;
|
||||
+ }
|
||||
return entity1 == null || this.leftOwner || !entity1.isPassengerOfSameVehicle(entity);
|
||||
+ // Paper end
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 8cf2dc21bcc2547b5af5501e60be39ca18a0e9f2..d36e73cfab79960bf4d778ea01a684b9b6af39d7 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -195,7 +195,8 @@ public class BlockItem extends Item {
|
||||
Player entityhuman = context.getPlayer();
|
||||
CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of((Entity) entityhuman);
|
||||
// CraftBukkit start - store default return
|
||||
- boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().isUnobstructed(state, context.getClickedPos(), voxelshapecollision);
|
||||
+ Level world = context.getLevel(); // Paper
|
||||
+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper
|
||||
org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
||||
|
||||
BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index e8d1a17b8e65e1af03ad36afd98b3e6ebab2592a..b5aa61cecf15e38105cf4bef92b6859aaa450dbd 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -71,6 +71,10 @@ import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
+import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
+import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
+import net.minecraft.world.phys.shapes.Shapes;
|
||||
+import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -251,6 +255,45 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ // ret true if no collision
|
||||
+ public final boolean checkEntityCollision(BlockState data, Entity source, CollisionContext voxelshapedcollision,
|
||||
+ BlockPos position, boolean checkCanSee) {
|
||||
+ // Copied from IWorldReader#a(IBlockData, BlockPosition, VoxelShapeCollision) & EntityAccess#a(Entity, VoxelShape)
|
||||
+ VoxelShape voxelshape = data.getCollisionShape(this, position, voxelshapedcollision);
|
||||
+ if (voxelshape.isEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ voxelshape = voxelshape.move((double) position.getX(), (double) position.getY(), (double) position.getZ());
|
||||
+ if (voxelshape.isEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ List<Entity> entities = this.getEntities(null, voxelshape.bounds());
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ Entity entity = entities.get(i);
|
||||
+
|
||||
+ if (checkCanSee && source instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer
|
||||
+ && !((net.minecraft.server.level.ServerPlayer) source).getBukkitEntity().canSee(((net.minecraft.server.level.ServerPlayer) entity).getBukkitEntity())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity));
|
||||
+ // elide the last check since vanilla calls with entity = null
|
||||
+ // only we care about the source for the canSee check
|
||||
+ if (entity.isRemoved() || !entity.blocksBuilding) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (Shapes.joinIsNotEmpty(voxelshape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean isClientSide() {
|
||||
return this.isClientSide;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 8e0b6910c97789b4d03ae62723dceb962487fc5a..4faf98079a6a6af662e11050a0088578ba65a5eb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1229,6 +1229,14 @@ public class CraftEventFactory {
|
||||
Projectile projectile = (Projectile) entity.getBukkitEntity();
|
||||
org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity();
|
||||
com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided);
|
||||
+
|
||||
+ if (projectile.getShooter() instanceof Player && collided instanceof Player) {
|
||||
+ if (!((Player) projectile.getShooter()).canSee((Player) collided)) {
|
||||
+ event.setCancelled(true);
|
||||
+ return event;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 15 Aug 2018 01:26:09 -0700
|
||||
Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0fd29d5854d9d6155ea590f86d4492d86afab433..ff6cf94dec708c6d3cac837ca03be2fe12d5e05f 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -419,4 +419,10 @@ public class PaperWorldConfig {
|
||||
private void armorStandEntityLookups() {
|
||||
armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true);
|
||||
}
|
||||
+
|
||||
+ public boolean armorStandTick = true;
|
||||
+ private void armorStandTick() {
|
||||
+ this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
|
||||
+ log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 9a63260b20903eb4600f098c81ae660029f7c345..f9375dbbeda6fdc92406fe5d93df0467e6e70672 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -93,9 +93,16 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
public boolean canMove = true; // Paper
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ public boolean canTick = true;
|
||||
+ public boolean canTickSetByAPI = false;
|
||||
+ private boolean noTickPoseDirty = false;
|
||||
+ private boolean noTickEquipmentDirty = false;
|
||||
+ // Paper end
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
+ if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking
|
||||
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
|
||||
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
|
||||
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
|
||||
@@ -192,6 +199,7 @@ public class ArmorStand extends LivingEntity {
|
||||
this.armorItems.set(enumitemslot.getIndex(), itemstack);
|
||||
}
|
||||
|
||||
+ this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,6 +250,7 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
nbt.put("Pose", this.writePose());
|
||||
+ if (this.canTickSetByAPI) nbt.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,6 +282,12 @@ public class ArmorStand extends LivingEntity {
|
||||
this.setNoBasePlate(nbt.getBoolean("NoBasePlate"));
|
||||
this.setMarker(nbt.getBoolean("Marker"));
|
||||
this.noPhysics = !this.hasPhysics();
|
||||
+ // Paper start - persist no tick
|
||||
+ if (nbt.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
CompoundTag nbttagcompound1 = nbt.getCompound("Pose");
|
||||
|
||||
this.readPose(nbttagcompound1);
|
||||
@@ -654,7 +669,29 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start
|
||||
+ if (!this.canTick) {
|
||||
+ if (this.noTickPoseDirty) {
|
||||
+ this.noTickPoseDirty = false;
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ if (this.noTickEquipmentDirty) {
|
||||
+ this.noTickEquipmentDirty = false;
|
||||
+ this.detectEquipmentUpdates();
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
super.tick();
|
||||
+ // Paper start - Split into separate method
|
||||
+ updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end
|
||||
Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE);
|
||||
|
||||
if (!this.headPose.equals(vector3f)) {
|
||||
@@ -777,31 +814,37 @@ public class ArmorStand extends LivingEntity {
|
||||
public void setHeadPose(Rotations angle) {
|
||||
this.headPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setBodyPose(Rotations angle) {
|
||||
this.bodyPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_BODY_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftArmPose(Rotations angle) {
|
||||
this.leftArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightArmPose(Rotations angle) {
|
||||
this.rightArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftLegPose(Rotations angle) {
|
||||
this.leftLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightLegPose(Rotations angle) {
|
||||
this.rightLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public Rotations getHeadPose() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 06cedeea447f53d100e32a6eba6f83b4719cb231..82b9ee993b0d2e7e0685231f7bad2b85756ec959 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -238,5 +238,16 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public void setCanMove(boolean move) {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canTick() {
|
||||
+ return this.getHandle().canTick;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanTick(final boolean tick) {
|
||||
+ this.getHandle().canTick = tick;
|
||||
+ this.getHandle().canTickSetByAPI = true;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 27 Jul 2018 22:36:31 -0500
|
||||
Subject: [PATCH] SkeletonHorse Additions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
index 67afaab789041f49407233ca8a856a3b0131fcf6..1b874f8a72f5b1ac64dd66621b039295f5dc1f18 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
@@ -18,6 +18,7 @@ import net.minecraft.world.level.Level;
|
||||
public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
private final SkeletonHorse horse;
|
||||
+ private java.util.List<org.bukkit.entity.HumanEntity> eligiblePlayers; // Paper
|
||||
|
||||
public SkeletonTrapGoal(SkeletonHorse skeletonHorse) {
|
||||
this.horse = skeletonHorse;
|
||||
@@ -25,12 +26,13 @@ public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.horse.level.hasNearbyAlivePlayer(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D);
|
||||
+ return !(eligiblePlayers = this.horse.level.findNearbyBukkitPlayers(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D, false)).isEmpty(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ServerLevel worldserver = (ServerLevel) this.horse.level;
|
||||
+ if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.horse.getBukkitEntity(), eligiblePlayers).callEvent()) return; // Paper
|
||||
DifficultyInstance difficultydamagescaler = worldserver.getCurrentDifficultyAt(this.horse.blockPosition());
|
||||
|
||||
this.horse.setTrap(false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 849616d9ad140285f7aa4d2ffafd6371f3904bd5..325e244c46ec208a2e7e18d71ccbbfcc25fc1bce 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -89,6 +89,28 @@ public interface EntityGetter {
|
||||
return player;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
|
||||
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.NO_SPECTATORS : net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR);
|
||||
+ }
|
||||
+
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
|
||||
+ com.google.common.collect.ImmutableList.Builder<org.bukkit.entity.HumanEntity> builder = com.google.common.collect.ImmutableList.builder();
|
||||
+
|
||||
+ for (Player human : this.players()) {
|
||||
+ if (predicate == null || predicate.test(human)) {
|
||||
+ double distanceSquared = human.distanceToSqr(x, y, z);
|
||||
+
|
||||
+ if (radius < 0.0D || distanceSquared < radius * radius) {
|
||||
+ builder.add(human.getBukkitEntity());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return builder.build();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
default Player getNearestPlayer(Entity entity, double maxDistance) {
|
||||
return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, false);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
index b52ca4a612e30542ef4029cb1340f616bc4c36e6..90a61d1472afea12637814256f91dbd2f5acb42e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
@@ -25,4 +25,26 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo
|
||||
public Variant getVariant() {
|
||||
return Variant.SKELETON_HORSE;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.animal.horse.SkeletonHorse getHandle() {
|
||||
+ return (net.minecraft.world.entity.animal.horse.SkeletonHorse) super.getHandle();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTrapTime() {
|
||||
+ return getHandle().trapTime;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isTrap() {
|
||||
+ return getHandle().isTrap();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTrap(boolean trap) {
|
||||
+ getHandle().setTrap(trap);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Thu, 26 Jul 2018 14:10:23 +0200
|
||||
Subject: [PATCH] Don't call getItemMeta on hasItemMeta
|
||||
|
||||
Spigot 1.13 checks if any field (which are manually copied from the ItemStack's "tag" NBT tag) on the ItemMeta class of an ItemStack is set.
|
||||
|
||||
We could just check if the "tag" NBT tag is empty, albeit that would break some plugins. The only general tag added on 1.13 is "Damage", and we can just check if the "tag" NBT tag contains any other tag that's not "Damage" (https://minecraft.gamepedia.com/Player.dat_format#Item_structure) making the `hasItemStack` method behave as before.
|
||||
|
||||
Returns true if getDamage() == 0 or has damage tag or other tag is set.
|
||||
Check the `ItemMetaTest#testTaggedButNotMeta` method to see how this method behaves.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 967555b6a3ef833ca75215391b20744ab6f04359..14da2997b5fff4434b1fe8d5a1b3109dde143740 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -580,7 +580,7 @@ public final class CraftItemStack extends ItemStack {
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta() {
|
||||
- return CraftItemStack.hasItemMeta(this.handle) && !CraftItemFactory.instance().equals(this.getItemMeta(), null);
|
||||
+ return CraftItemStack.hasItemMeta(this.handle) && (this.handle.getDamageValue() != 0 || (this.handle.getTag() != null && this.handle.getTag().tags.size() >= (this.handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
|
||||
}
|
||||
|
||||
static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) {
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index f3a0578f53863dd0866b4c2cb957a30fa3bc6cc5..44bc92bea0fa0742ef861e16eba3e57d9c6e49ce 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -99,6 +99,34 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
assertThat(itemMeta.hasConflictingEnchant(null), is(false));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void testItemMeta(ItemStack stack) {
|
||||
+ assertThat("Should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with zero durability should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 2);
|
||||
+ assertThat("ItemStack with non-zero durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(java.util.Collections.singletonList("Lore"));
|
||||
+ assertThat("ItemStack with lore and durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with lore should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(null);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHasItemMeta() {
|
||||
+ ItemStack itemStack = new ItemStack(Material.SHEARS);
|
||||
+
|
||||
+ testItemMeta(itemStack);
|
||||
+ testItemMeta(CraftItemStack.asCraftCopy(itemStack));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Test
|
||||
public void testConflictingStoredEnchantment() {
|
||||
EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK);
|
|
@ -1,93 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 26 Jul 2018 02:25:46 -0400
|
||||
Subject: [PATCH] Implement Expanded ArmorStand API
|
||||
|
||||
Add the following:
|
||||
- Add proper methods for getting and setting items in both hands. Deprecates old methods
|
||||
- Enable/Disable slot interactions
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 82b9ee993b0d2e7e0685231f7bad2b85756ec959..f4065938bbfd04519d1363ee8781c316aca468ab 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -239,6 +239,79 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public ItemStack getItem(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ return getHandle().getItemBySlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)).asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(org.bukkit.inventory.EquipmentSlot slot, ItemStack item) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ switch (slot) {
|
||||
+ case HAND:
|
||||
+ getEquipment().setItemInMainHand(item);
|
||||
+ return;
|
||||
+ case OFF_HAND:
|
||||
+ getEquipment().setItemInOffHand(item);
|
||||
+ return;
|
||||
+ case FEET:
|
||||
+ setBoots(item);
|
||||
+ return;
|
||||
+ case LEGS:
|
||||
+ setLeggings(item);
|
||||
+ return;
|
||||
+ case CHEST:
|
||||
+ setChestplate(item);
|
||||
+ return;
|
||||
+ case HEAD:
|
||||
+ setHelmet(item);
|
||||
+ return;
|
||||
+ }
|
||||
+ throw new UnsupportedOperationException(slot.name());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Set<org.bukkit.inventory.EquipmentSlot> getDisabledSlots() {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = new java.util.HashSet<>();
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : org.bukkit.inventory.EquipmentSlot.values()) {
|
||||
+ if (this.isSlotDisabled(slot)) {
|
||||
+ disabled.add(slot);
|
||||
+ }
|
||||
+ }
|
||||
+ return disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ int disabled = 0;
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : slots) {
|
||||
+ if (slot == org.bukkit.inventory.EquipmentSlot.OFF_HAND) continue;
|
||||
+ net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
|
||||
+ disabled += (1 << nmsSlot.getFilterFlag()) + (1 << (nmsSlot.getFilterFlag() + 8)) + (1 << (nmsSlot.getFilterFlag() + 16));
|
||||
+ }
|
||||
+ getHandle().disabledSlots = disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ java.util.Collections.addAll(disabled, slots);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ for (final org.bukkit.inventory.EquipmentSlot slot : slots) disabled.remove(slot);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ return getHandle().isDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public boolean canTick() {
|
||||
return this.getHandle().canTick;
|
|
@ -1,27 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 20 Jul 2018 23:37:03 -0500
|
||||
Subject: [PATCH] AnvilDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index 6acd18521bde95183bf3910328559a2a5829c03d..2ed4930648411ccd52fc970b069e57eba9bceef8 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -90,6 +90,16 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
if (!player.getAbilities().instabuild && iblockdata.is((Tag) BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
|
||||
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) {
|
||||
+ iblockdata1 = null;
|
||||
+ } else {
|
||||
+ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().setValue(AnvilBlock.FACING, iblockdata.getValue(AnvilBlock.FACING));
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (iblockdata1 == null) {
|
||||
world.removeBlock(blockposition, false);
|
||||
world.levelEvent(1029, blockposition, 0);
|
|
@ -1,125 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Thu, 2 Aug 2018 08:44:35 -0500
|
||||
Subject: [PATCH] Add hand to bucket events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
index 0cf990f220fad6e945bda590263b78ea2e5a3b03..a43349c47292154dfc56c72c58ba9f29f6765d83 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
@@ -87,7 +87,7 @@ public class Cow extends Animal {
|
||||
|
||||
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
|
||||
// CraftBukkit start - Got milk?
|
||||
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
|
||||
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return InteractionResult.PASS;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
index 68b116697d6cf3dbb1fa25d6e9ca9bbb10f346a3..32d0387b6c66462ca965add78a562dec3c4b95a9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
@@ -180,7 +180,7 @@ public class Goat extends Animal {
|
||||
|
||||
if (itemstack.is(Items.BUCKET) && !this.isBaby()) {
|
||||
// CraftBukkit start - Got milk?
|
||||
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
|
||||
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return InteractionResult.PASS;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
index 5870023250ed2dba16b2fa5c6a8be6f36cebc640..650b59b69eb12112bc71e5ff164767e3118e1c2a 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
@@ -72,7 +72,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
// CraftBukkit start
|
||||
ItemStack dummyFluid = ifluidsource.pickupBlock(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata);
|
||||
if (dummyFluid.isEmpty()) return InteractionResultHolder.fail(itemstack); // Don't fire event if the bucket won't be filled.
|
||||
- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem());
|
||||
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand); // Paper - add enumhand
|
||||
|
||||
if (event.isCancelled()) {
|
||||
((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
|
||||
@@ -103,7 +103,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
iblockdata = world.getBlockState(blockposition);
|
||||
BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1;
|
||||
|
||||
- if (this.a(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack)) { // CraftBukkit
|
||||
+ if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit // Paper - add enumhand
|
||||
this.checkExtraContent(user, world, itemstack, blockposition2);
|
||||
if (user instanceof ServerPlayer) {
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack);
|
||||
@@ -130,10 +130,12 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
|
||||
@Override
|
||||
public boolean emptyContents(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult hitResult) {
|
||||
- return this.a(player, world, pos, hitResult, null, null, null);
|
||||
+ // Paper start - add enumHand
|
||||
+ return emptyContents(player, world, pos, hitResult, null, null, null, null);
|
||||
}
|
||||
|
||||
- public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack) {
|
||||
+ public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
if (!(this.content instanceof FlowingFluid)) {
|
||||
return false;
|
||||
@@ -146,7 +148,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
|
||||
// CraftBukkit start
|
||||
if (flag1 && entityhuman != null) {
|
||||
- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack);
|
||||
+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand
|
||||
if (event.isCancelled()) {
|
||||
((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
|
||||
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
@@ -155,7 +157,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (!flag1) {
|
||||
- return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack); // CraftBukkit
|
||||
+ return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand
|
||||
} else if (world.dimensionType().ultraWarm() && this.content.is((Tag) FluidTags.WATER)) {
|
||||
int i = blockposition.getX();
|
||||
int j = blockposition.getY();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 4faf98079a6a6af662e11050a0088578ba65a5eb..0d1c6f609a5198c21c895e8f6ace467355b0f166 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -421,6 +421,20 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item) {
|
||||
+ // Paper start - add enumHand
|
||||
+ return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null);
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, InteractionHand enumHand) {
|
||||
+ return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand);
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerBucketFillEvent callPlayerBucketFillEvent(ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemInHand, net.minecraft.world.item.Item bucket, InteractionHand enumHand) {
|
||||
+ return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand);
|
||||
+ }
|
||||
+
|
||||
+ private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item, InteractionHand enumHand) {
|
||||
+ // Paper end
|
||||
Player player = (Player) who.getBukkitEntity();
|
||||
CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item);
|
||||
Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem());
|
||||
@@ -433,10 +447,10 @@ public class CraftEventFactory {
|
||||
|
||||
PlayerEvent event;
|
||||
if (isFilling) {
|
||||
- event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
+ event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
|
||||
((PlayerBucketFillEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
|
||||
} else {
|
||||
- event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
+ event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
|
||||
((PlayerBucketEmptyEvent) event).setCancelled(!CraftEventFactory.canBuild(world, player, changed.getX(), changed.getZ()));
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Mon, 16 Jul 2018 00:05:05 +0300
|
||||
Subject: [PATCH] Add TNTPrimeEvent
|
||||
|
||||
|
||||
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 3a01ffffcc37a93866b8b6774874959dfcabba26..29aa428e019681af8d6b0020c12b18660ff6af6c 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
|
||||
@@ -536,6 +536,11 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
});
|
||||
craftBlock.getNMS().spawnAfterBreak((ServerLevel) level, blockposition, ItemStack.EMPTY);
|
||||
}
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = level.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSourceMob().getBukkitEntity()).callEvent())
|
||||
+ continue;
|
||||
+ // Paper end
|
||||
nmsBlock.wasExploded(level, blockposition, explosionSource);
|
||||
|
||||
this.level.removeBlock(blockposition, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 2703afdd101092c92da2eb619757271c2a5f9305..8ce3dea66a1f45bb3f416bca1765c563394ad8ed 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -291,7 +291,7 @@ public class FireBlock extends BaseFireBlock {
|
||||
|
||||
world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3);
|
||||
} else {
|
||||
- world.removeBlock(blockposition, false);
|
||||
+ if(iblockdata.getBlock() != Blocks.TNT) world.removeBlock(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down
|
||||
}
|
||||
|
||||
Block block = iblockdata.getBlock();
|
||||
@@ -299,6 +299,13 @@ public class FireBlock extends BaseFireBlock {
|
||||
if (block instanceof TntBlock) {
|
||||
TntBlock blocktnt = (TntBlock) block;
|
||||
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ world.removeBlock(blockposition, false);
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
index 390dfe9d2a148468b9ed3e3fb39fc944e7aa4d5c..151d412df2fce6e51d0297dc1c070056c31ec196 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -38,6 +38,11 @@ public class TntBlock extends Block {
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
if (world.hasNeighborSignal(pos)) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -48,6 +53,11 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
if (world.hasNeighborSignal(pos)) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -66,6 +76,12 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void wasExploded(Level world, BlockPos pos, Explosion explosion) {
|
||||
if (!world.isClientSide) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
|
||||
+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null;
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getSourceMob());
|
||||
int i = entitytntprimed.getFuse();
|
||||
|
||||
@@ -95,6 +111,11 @@ public class TntBlock extends Block {
|
||||
if (!itemstack.is(Items.FLINT_AND_STEEL) && !itemstack.is(Items.FIRE_CHARGE)) {
|
||||
return super.use(state, world, pos, player, hand, hit);
|
||||
} else {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent())
|
||||
+ return InteractionResult.FAIL;
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos, (LivingEntity) player);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
|
||||
Item item = itemstack.getItem();
|
||||
@@ -126,6 +147,12 @@ public class TntBlock extends Block {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
|
||||
world.removeBlock(blockposition, false);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue