mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-31 04:13:51 -07:00
More more more more more more work
This commit is contained in:
@@ -26,11 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
@@ -0,0 +0,0 @@ public class Squid extends WaterAnimal {
|
||||
public void travel(Vec3 movementInput) {
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
}
|
||||
-
|
||||
+// 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Chunk.java
|
||||
+++ b/src/main/java/org/bukkit/Chunk.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityKnockbackByEntityEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityTeleportEndGatewayEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/TNTPrimeEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -0,0 +0,0 @@ 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>
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
@@ -0,0 +0,0 @@ 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,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Vex.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Vex.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
/**
|
||||
* Represents a Vex.
|
||||
*/
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/AnvilDamagedEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFireballHitEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonFlameEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EnderDragonShootFireballEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Enderman.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Enderman.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+/*
|
||||
+ * 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityTransformedEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Particle.java
|
||||
+++ b/src/main/java/org/bukkit/Particle.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/EnderDragon.java
|
||||
+++ b/src/main/java/org/bukkit/entity/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerElytraBoostEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerLaunchProjectileEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+/*
|
||||
+ * 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
+++ b/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/Chunk.java
|
||||
+++ b/src/main/java/org/bukkit/Chunk.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/RangedEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/AbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/entity/AbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Drowned.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Drowned.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Illusioner.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Illusioner.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Llama.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Llama.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Piglin.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Piglin.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Pillager.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Pillager.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Snowman.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Snowman.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Witch.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Witch.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Wither.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Wither.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -0,0 +0,0 @@ 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 {
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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.
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
+++ b/src/test/java/org/bukkit/plugin/PluginManagerTest.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ public class PluginManagerTest {
|
||||
if (store.value == null) {
|
||||
throw new IllegalStateException("No exception thrown");
|
||||
}
|
||||
- }
|
||||
+ } */ // Paper
|
||||
|
||||
@Test
|
||||
public void testRemovePermissionByNameLower() {
|
@@ -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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/entity/SkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/entity/SkeletonHorse.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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: 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchReadyPotionEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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,66 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 15 Aug 2018 01:16:34 -0400
|
||||
Subject: [PATCH] Ability to get Tile Entities from a chunk without snapshots
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import java.lang.ref.WeakReference;
|
||||
+import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
+import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.function.BooleanSupplier;
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public BlockState[] getTileEntities() {
|
||||
+ // Paper start
|
||||
+ return getTileEntities(true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockState[] getTileEntities(boolean useSnapshot) {
|
||||
+ // Paper end
|
||||
if (!this.isLoaded()) {
|
||||
this.getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
}
|
||||
|
||||
BlockPos position = (BlockPos) obj;
|
||||
- entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
|
||||
+ // Paper start
|
||||
+ entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot);
|
||||
+ }
|
||||
+
|
||||
+ return entities;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<BlockState> getTileEntities(Predicate<Block> blockPredicate, boolean useSnapshot) {
|
||||
+ Preconditions.checkNotNull(blockPredicate, "blockPredicate");
|
||||
+ if (!isLoaded()) {
|
||||
+ getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||
+ }
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = getHandle();
|
||||
+
|
||||
+ List<BlockState> entities = new ArrayList<>();
|
||||
+
|
||||
+ for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
+ Block block = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
+ if (blockPredicate.test(block)) {
|
||||
+ entities.add(block.getState(useSnapshot));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return entities;
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -0,0 +0,0 @@ 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,139 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 21 Jul 2018 08:25:40 -0400
|
||||
Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
|
||||
|
||||
Add -Ddebug.entities=true to your JVM flags to gain more information
|
||||
|
||||
1.17: Needs to be reworked for new entity storage system
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
} else {
|
||||
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
|
||||
|
||||
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
|
||||
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
|
||||
playerchunkmap_entitytracker.updatePlayers(this.level.players());
|
||||
if (entity instanceof ServerPlayer) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
if (playerchunkmap_entitytracker1 != null) {
|
||||
playerchunkmap_entitytracker1.broadcastRemoved();
|
||||
}
|
||||
-
|
||||
+ entity.tracker = null; // Paper - We're no longer tracked
|
||||
}
|
||||
|
||||
protected void tick() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
public boolean hasPhysicsEvent = true; // Paper
|
||||
+ public static Throwable getAddToWorldStackTrace(Entity entity) {
|
||||
+ return new Throwable(entity + " Added to world at " + new java.util.Date());
|
||||
+ }
|
||||
|
||||
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
||||
return this.chunkSource.getChunk(x, z, false);
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ // Paper start
|
||||
+ if (entity.valid) {
|
||||
+ MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
|
||||
+
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ Throwable thr = entity.addedToWorldStack;
|
||||
+ if (thr == null) {
|
||||
+ MinecraftServer.LOGGER.error("Double add entity has no add stacktrace");
|
||||
+ } else {
|
||||
+ MinecraftServer.LOGGER.error("Double add stacktrace: ", thr);
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entity.isRemoved()) {
|
||||
+ // Paper start
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ new Throwable("Tried to add entity " + entity + " but it was marked as removed already").printStackTrace(); // CraftBukkit
|
||||
+ getAddToWorldStackTrace(entity).printStackTrace();
|
||||
+ }
|
||||
+ // Paper end
|
||||
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit
|
||||
return false;
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
+ public net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper
|
||||
+ public Throwable addedToWorldStack; // Paper - entity debug
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (this.bukkitEntity == null) {
|
||||
this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean pvpMode;
|
||||
public boolean keepSpawnInMemory = true;
|
||||
public org.bukkit.generator.ChunkGenerator generator;
|
||||
+ public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
|
||||
|
||||
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
|
||||
public boolean captureBlockStates = false;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
@@ -0,0 +0,0 @@ public class EntityLookup<T extends EntityAccess> {
|
||||
for(T entityAccess : this.byId.values()) {
|
||||
U entityAccess2 = (U)((EntityAccess)filter.tryCast(entityAccess));
|
||||
if (entityAccess2 != null) {
|
||||
- action.accept((T)entityAccess2);
|
||||
+ action.accept(entityAccess2); // Paper - decompile fix
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class EntityLookup<T extends EntityAccess> {
|
||||
UUID uUID = entity.getUUID();
|
||||
if (this.byUuid.containsKey(uUID)) {
|
||||
LOGGER.warn("Duplicate entity UUID {}: {}", uUID, entity);
|
||||
+ // Paper start - extra debug info
|
||||
+ if (entity instanceof net.minecraft.world.entity.Entity) {
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ ((net.minecraft.world.entity.Entity) entity).addedToWorldStack = net.minecraft.server.level.ServerLevel.getAddToWorldStackTrace((net.minecraft.world.entity.Entity) entity);
|
||||
+ }
|
||||
+
|
||||
+ T old = this.byUuid.get(entity.getUUID());
|
||||
+ if (old instanceof net.minecraft.world.entity.Entity && old != null && old.getId() != entity.getId() && ((net.minecraft.world.entity.Entity) old).valid) {
|
||||
+ Logger logger = LogManager.getLogger();
|
||||
+ logger.error("Overwrote an existing entity " + old + " with " + entity);
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ if (((net.minecraft.world.entity.Entity) old).addedToWorldStack != null) {
|
||||
+ ((net.minecraft.world.entity.Entity) old).addedToWorldStack.printStackTrace();
|
||||
+ } else {
|
||||
+ logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
|
||||
+ }
|
||||
+ ((net.minecraft.world.entity.Entity) entity).addedToWorldStack.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.byUuid.put(uUID, entity);
|
||||
this.byId.put(entity.getId(), entity);
|
@@ -1,182 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Wed, 8 Aug 2018 15:30:52 -0400
|
||||
Subject: [PATCH] Add Early Warning Feature to WatchDog
|
||||
|
||||
Detect when the server has been hung for a long duration, and start printing
|
||||
thread dumps at an interval until the point of crash.
|
||||
|
||||
This will help diagnose what was going on in that time before the crash.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import co.aikar.timings.Timings;
|
||||
import co.aikar.timings.TimingsManager;
|
||||
import org.spigotmc.SpigotConfig;
|
||||
+import org.spigotmc.WatchdogThread;
|
||||
|
||||
public class PaperConfig {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class PaperConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public static int watchdogPrintEarlyWarningEvery = 5000;
|
||||
+ public static int watchdogPrintEarlyWarningDelay = 10000;
|
||||
+ private static void watchdogEarlyWarning() {
|
||||
+ watchdogPrintEarlyWarningEvery = getInt("settings.watchdog.early-warning-every", 5000);
|
||||
+ watchdogPrintEarlyWarningDelay = getInt("settings.watchdog.early-warning-delay", 10000);
|
||||
+ WatchdogThread.doStart(SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash );
|
||||
+ }
|
||||
+
|
||||
public static int tabSpamIncrement = 1;
|
||||
public static int tabSpamLimit = 500;
|
||||
private static void tabSpamLimiters() {
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.updateStatusIcon(this.status);
|
||||
|
||||
// Spigot start
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
||||
Arrays.fill( recentTps, 20 );
|
||||
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
lastTick = start - TICK_TIME; // Paper
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
this.reloadCount++;
|
||||
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
||||
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
this.enablePlugins(PluginLoadOrder.STARTUP);
|
||||
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
this.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotConfig
|
||||
SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript );
|
||||
SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) );
|
||||
SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) );
|
||||
- WatchdogThread.doStart( timeoutTime, restartOnCrash );
|
||||
+ //WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to PaperConfig
|
||||
}
|
||||
|
||||
public static boolean bungee;
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ import java.lang.management.MonitorInfo;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
+import com.destroystokyo.paper.PaperConfig;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
+ private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||
+ private final long earlyWarningDelay; // Paper
|
||||
+ public static volatile boolean hasStarted; // Paper
|
||||
+ private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
||||
private volatile long lastTick;
|
||||
private volatile boolean stopping;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
super( "Paper Watchdog Thread" );
|
||||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
+ earlyWarningEvery = Math.min(PaperConfig.watchdogPrintEarlyWarningEvery, timeoutTime); // Paper
|
||||
+ earlyWarningDelay = Math.min(PaperConfig.watchdogPrintEarlyWarningDelay, timeoutTime); // Paper
|
||||
}
|
||||
|
||||
private static long monotonicMillis()
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
+ // Paper start
|
||||
+ Logger log = Bukkit.getServer().getLogger();
|
||||
+ long currentTime = WatchdogThread.monotonicMillis();
|
||||
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
{
|
||||
- Logger log = Bukkit.getServer().getLogger();
|
||||
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||
+ // Don't spam early warning dumps
|
||||
+ if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
|
||||
+ if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
|
||||
+ lastEarlyWarning = currentTime;
|
||||
+ if (isLongTimeout) {
|
||||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
||||
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ } else
|
||||
+ {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---");
|
||||
+ log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump");
|
||||
+ }
|
||||
+ // Paper end - Different message for short timeout
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
+ // Paper start - Only print full dump on long timeouts
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
log.log( Level.SEVERE, "Entire Thread Dump:" );
|
||||
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
||||
for ( ThreadInfo thread : threads )
|
||||
{
|
||||
WatchdogThread.dumpThread( thread, log );
|
||||
}
|
||||
+ } else {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
|
||||
+ }
|
||||
+
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
if ( this.restart && !MinecraftServer.getServer().hasStopped() )
|
||||
{
|
||||
RestartCommand.restart();
|
||||
}
|
||||
break;
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
- sleep( 10000 );
|
||||
+ sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
||||
} catch ( InterruptedException ex )
|
||||
{
|
||||
interrupt();
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
@@ -0,0 +0,0 @@ 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)
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,160 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
|
||||
@@ -0,0 +0,0 @@ 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,75 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 29 Jul 2018 05:02:15 +0100
|
||||
Subject: [PATCH] Break up and make tab spam limits configurable
|
||||
|
||||
Due to the changes in 1.13, clients will send a tab completion request
|
||||
for all bukkit commands in order to factor in the lack of support for
|
||||
brigadier and provide backwards support in the API.
|
||||
|
||||
Craftbukkit, however; has moved the chat spam limiter to also interact
|
||||
with the tab completion request, which while good for avoiding abuse,
|
||||
causes 1.13 clients to easilly be kicked from a server in bukkit due
|
||||
to this. Removing the spam limit could cause issues for servers, however,
|
||||
there is no way for servers to manipulate this without blindly cancelling
|
||||
kick events, which only causes additional complications. This also causes
|
||||
issues in that the tab spam limit and chat share the same field but different
|
||||
limits, meaning that a player having typed a long command may be kicked from
|
||||
the server.
|
||||
|
||||
Splitting the field up and making it configurable allows for server owners
|
||||
to take the burden of this into their own hand without having to rely on
|
||||
plugins doing unsafe things.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperConfig {
|
||||
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");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public static int tabSpamIncrement = 1;
|
||||
+ public static int tabSpamLimit = 500;
|
||||
+ private static void tabSpamLimiters() {
|
||||
+ tabSpamIncrement = getInt("settings.spam-limiter.tab-spam-increment", tabSpamIncrement);
|
||||
+ // Older versions used a smaller limit, which is too low for 1.13, we'll bump this up if default
|
||||
+ if (version < 14) {
|
||||
+ if (tabSpamIncrement == 10) {
|
||||
+ set("settings.spam-limiter.tab-spam-increment", 2);
|
||||
+ tabSpamIncrement = 2;
|
||||
+ }
|
||||
+ }
|
||||
+ tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
private long keepAliveChallenge;
|
||||
// CraftBukkit start - multithreaded fields
|
||||
private AtomicInteger chatSpamTickCount = new AtomicInteger();
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
|
||||
// CraftBukkit end
|
||||
private int dropSpamTickCount;
|
||||
private double firstGoodX;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
this.server.getProfiler().pop();
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
|
||||
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatSpamTickCount > 0) {
|
||||
--this.chatSpamTickCount;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
// PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
- if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
|
||||
+ if (this.chatSpamTickCount.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
|
||||
server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
@@ -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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +0,0 @@ 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:
|
||||
@@ -0,0 +0,0 @@ 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:
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,118 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 22 Nov 2016 00:40:42 -0500
|
||||
Subject: [PATCH] Fix client rendering skulls from same user
|
||||
|
||||
See: https://github.com/PaperMC/Paper/issues/1304
|
||||
|
||||
Changes the UUID sent to client to be based on either
|
||||
the texture payload, or random.
|
||||
|
||||
This allows the client to render multiple skull textures from the same user,
|
||||
for when different skins were used when skull was made.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
|
||||
// Spigot start - filter
|
||||
stack = stack.copy();
|
||||
- CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack));
|
||||
+ // CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack)); // Paper - This is no longer needed due to NBT being supported
|
||||
// Spigot end
|
||||
nbttagcompound = stack.getTag();
|
||||
+ // Paper start
|
||||
+ if (nbttagcompound != null && nbttagcompound.contains("SkullOwner", 10)) {
|
||||
+ CompoundTag owner = nbttagcompound.getCompound("SkullOwner");
|
||||
+ if (owner.hasUUID("Id")) {
|
||||
+ nbttagcompound.putUUID("SkullOwnerOrig", owner.getUUID("Id"));
|
||||
+ net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeUUID(owner);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
this.writeNbt(nbttagcompound);
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
itemstack.setTag(this.readNbt());
|
||||
// CraftBukkit start
|
||||
if (itemstack.getTag() != null) {
|
||||
- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
+ // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client
|
||||
+ if (itemstack.tag.contains("SkullOwnerOrig")) {
|
||||
+ CompoundTag owner = itemstack.tag.getCompound("SkullOwner");
|
||||
+ if (itemstack.tag.contains("SkullOwnerOrig")) {
|
||||
+ owner.tags.put("Id", itemstack.tag.tags.get("SkullOwnerOrig"));
|
||||
+ itemstack.tag.remove("SkullOwnerOrig");
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
|
||||
}
|
||||
// CraftBukkit end
|
||||
return itemstack;
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
@@ -0,0 +0,0 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
|
||||
for(Entry<BlockPos, BlockEntity> entry2 : chunk.getBlockEntities().entrySet()) {
|
||||
BlockEntity blockEntity = entry2.getValue();
|
||||
CompoundTag compoundTag = blockEntity.getUpdateTag();
|
||||
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.SkullBlockEntity) { net.minecraft.world.level.block.entity.SkullBlockEntity.sanitizeTileEntityUUID(compoundTag); } // Paper
|
||||
this.blockEntitiesTags.add(compoundTag);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.server.players.GameProfileCache;
|
||||
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
||||
@Nullable
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
- return new ClientboundBlockEntityDataPacket(this.worldPosition, 4, this.getUpdateTag());
|
||||
+ return new ClientboundBlockEntityDataPacket(this.worldPosition, 4, sanitizeTileEntityUUID(this.getUpdateTag())); // Paper
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static CompoundTag sanitizeTileEntityUUID(CompoundTag cmp) {
|
||||
+ CompoundTag owner = cmp.getCompound("Owner");
|
||||
+ if (!owner.isEmpty()) {
|
||||
+ sanitizeUUID(owner);
|
||||
+ }
|
||||
+ return cmp;
|
||||
+ }
|
||||
+
|
||||
+ public static void sanitizeUUID(CompoundTag owner) {
|
||||
+ CompoundTag properties = owner.getCompound("Properties");
|
||||
+ ListTag list = null;
|
||||
+ if (!properties.isEmpty()) {
|
||||
+ list = properties.getList("textures", 10);
|
||||
+ }
|
||||
+
|
||||
+ if (list != null && !list.isEmpty()) {
|
||||
+ String textures = ((CompoundTag)list.get(0)).getString("Value");
|
||||
+ if (textures != null && textures.length() > 3) {
|
||||
+ UUID uuid = UUID.nameUUIDFromBytes(textures.getBytes());
|
||||
+ owner.putUUID("Id", uuid);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ owner.putUUID("Id", UUID.randomUUID());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
return this.save(new CompoundTag());
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ 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));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int hashCode() {
|
||||
+ public final int hashCode() { // Paper
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+/*
|
||||
+ * 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
pending.add(task);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ pending.addAll(this.asyncScheduler.getPendingTasks());
|
||||
+ }
|
||||
+ // Paper end
|
||||
return pending;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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)
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 3 Aug 2018 00:04:54 -0400
|
||||
Subject: [PATCH] MC-135506: Experience should save as Integers
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
nbt.putShort("Health", (short) this.health);
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
- nbt.putShort("Value", (short) this.value);
|
||||
+ nbt.putInt("Value", this.value); // Paper - save as Integer
|
||||
nbt.putInt("Count", this.count);
|
||||
this.savePaperNBT(nbt); // Paper
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.health = nbt.getShort("Health");
|
||||
this.age = nbt.getShort("Age");
|
||||
- this.value = nbt.getShort("Value");
|
||||
+ this.value = nbt.getInt("Value"); // Paper - load as Integer
|
||||
this.count = Math.max(nbt.getInt("Count"), 1);
|
||||
this.loadPaperNBT(nbt); // Paper
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 10 Aug 2018 22:11:49 -0400
|
||||
Subject: [PATCH] Make EnderDragon implement Mob
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
-import net.minecraft.world.entity.LivingEntity;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.ComplexLivingEntity;
|
||||
|
||||
-public abstract class CraftComplexLivingEntity extends CraftLivingEntity implements ComplexLivingEntity {
|
||||
- public CraftComplexLivingEntity(CraftServer server, LivingEntity entity) {
|
||||
+public abstract class CraftComplexLivingEntity extends CraftMob implements ComplexLivingEntity { // Paper
|
||||
+ public CraftComplexLivingEntity(CraftServer server, Mob entity) { // Paper
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public LivingEntity getHandle() {
|
||||
- return (LivingEntity) entity;
|
||||
+ public Mob getHandle() { // Paper
|
||||
+ return (Mob) entity; // Paper
|
||||
}
|
||||
|
||||
@Override
|
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
} finally {
|
||||
bytebuf1.release();
|
||||
}
|
||||
+ */ // Paper end - Replace with improved version below
|
||||
}
|
||||
|
||||
bytebuf.release();
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
|
||||
+++ b/src/main/java/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
/*
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ 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)) {
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -0,0 +0,0 @@ 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,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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/RangedAttackMob.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory
|
||||
return;
|
||||
}
|
||||
// CraftBukkit 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
+ }
|
||||
+ }
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user