-Date: Fri, 18 Oct 2019 22:50:05 -0500
-Subject: [PATCH] Llama API
-
-
-diff --git a/src/main/java/org/bukkit/entity/Llama.java b/src/main/java/org/bukkit/entity/Llama.java
-index bc84b892cae5fe7019a3ad481e9da79956efa1fe..48eb5b00c460cccde29d327cef1d63fc04d6a829 100644
---- a/src/main/java/org/bukkit/entity/Llama.java
-+++ b/src/main/java/org/bukkit/entity/Llama.java
-@@ -119,4 +119,20 @@ public interface Llama extends ChestedHorse, RangedEntity { // Paper
- @org.jetbrains.annotations.Nullable
- Llama getCaravanTail();
- // Paper end
-+
-+ // Purpur start
-+ /**
-+ * Check if this Llama should attempt to join a caravan
-+ *
-+ * @return True if Llama is allowed to join a caravan
-+ */
-+ boolean shouldJoinCaravan();
-+
-+ /**
-+ * Set if this Llama should attempt to join a caravan
-+ *
-+ * @param shouldJoinCaravan True to allow joining a caravan
-+ */
-+ void setShouldJoinCaravan(boolean shouldJoinCaravan);
-+ // Purpur end
- }
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/LlamaJoinCaravanEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/LlamaJoinCaravanEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..8849bb0becb16db907fa648cca2e98ab9d957c75
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/LlamaJoinCaravanEvent.java
-@@ -0,0 +1,61 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.entity.Llama;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a Llama tries to join a caravan.
-+ *
-+ * Cancelling the event will not let the Llama join. To prevent future attempts
-+ * at joining a caravan use {@link Llama#setShouldJoinCaravan(boolean)}.
-+ */
-+public class LlamaJoinCaravanEvent extends EntityEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private boolean canceled;
-+ private final Llama head;
-+
-+ public LlamaJoinCaravanEvent(@NotNull Llama llama, @NotNull Llama head) {
-+ super(llama);
-+ this.head = head;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Llama getEntity() {
-+ return (Llama) entity;
-+ }
-+
-+ /**
-+ * Get the Llama that this Llama is about to follow
-+ *
-+ * @return Llama about to be followed
-+ */
-+ @NotNull
-+ public Llama getHead() {
-+ return head;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return canceled;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ canceled = cancel;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/LlamaLeaveCaravanEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/LlamaLeaveCaravanEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c268c35b541a222d50875c29770c846a8ffcc4f8
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/LlamaLeaveCaravanEvent.java
-@@ -0,0 +1,34 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.entity.Llama;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a Llama leaves a caravan
-+ */
-+public class LlamaLeaveCaravanEvent extends EntityEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+
-+ public LlamaLeaveCaravanEvent(@NotNull Llama llama) {
-+ super(llama);
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Llama getEntity() {
-+ return (Llama) entity;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0010-AFK-API.patch b/patches/api/0010-AFK-API.patch
deleted file mode 100644
index ea7bab12e..000000000
--- a/patches/api/0010-AFK-API.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sat, 10 Aug 2019 22:19:56 -0500
-Subject: [PATCH] AFK API
-
-
-diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 9ee0d60775a00a99c8ac779e8602c619565e6a42..2ddacd7f74cba66f67ab6957e03522453de01117 100644
---- a/src/main/java/org/bukkit/entity/Player.java
-+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3279,5 +3279,24 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
- * @return True if Player uses Purpur Client
- */
- public boolean usesPurpurClient();
-+
-+ /**
-+ * Check if player is AFK
-+ *
-+ * @return True if AFK
-+ */
-+ boolean isAfk();
-+
-+ /**
-+ * Set player as AFK
-+ *
-+ * @param setAfk Whether to set AFK or not
-+ */
-+ void setAfk(boolean setAfk);
-+
-+ /**
-+ * Reset the idle timer back to 0
-+ */
-+ void resetIdleTimer();
- // Purpur end
- }
-diff --git a/src/main/java/org/purpurmc/purpur/event/PlayerAFKEvent.java b/src/main/java/org/purpurmc/purpur/event/PlayerAFKEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..25e92af7710316ed2afedf846a59dbd672869b51
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/PlayerAFKEvent.java
-@@ -0,0 +1,70 @@
-+package org.purpurmc.purpur.event;
-+
-+import org.bukkit.entity.Player;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.player.PlayerEvent;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+public class PlayerAFKEvent extends PlayerEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final boolean setAfk;
-+ private boolean shouldKick;
-+ private String broadcast;
-+ private boolean cancel;
-+
-+ public PlayerAFKEvent(@NotNull Player player, boolean setAfk, boolean shouldKick, @Nullable String broadcast, boolean async) {
-+ super(player, async);
-+ this.setAfk = setAfk;
-+ this.shouldKick = shouldKick;
-+ this.broadcast = broadcast;
-+ }
-+
-+ /**
-+ * Whether player is going afk or coming back
-+ *
-+ * @return True if going afk. False is coming back
-+ */
-+ public boolean isGoingAfk() {
-+ return setAfk;
-+ }
-+
-+ public boolean shouldKick() {
-+ return shouldKick;
-+ }
-+
-+ public void setShouldKick(boolean shouldKick) {
-+ this.shouldKick = shouldKick;
-+ }
-+
-+ @Nullable
-+ public String getBroadcastMsg() {
-+ return broadcast;
-+ }
-+
-+ public void setBroadcastMsg(@Nullable String broadcast) {
-+ this.broadcast = broadcast;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return cancel;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancel = cancel;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0011-Bring-back-server-name.patch b/patches/api/0011-Bring-back-server-name.patch
deleted file mode 100644
index 19d0443a9..000000000
--- a/patches/api/0011-Bring-back-server-name.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sun, 26 May 2019 15:18:40 -0500
-Subject: [PATCH] Bring back server name
-
-
-diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index f78b5fd3c3347d28da58777bff88903d2eb140f6..7338dad470cd75814cce5be40f82058554484607 100644
---- a/src/main/java/org/bukkit/Bukkit.java
-+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -2756,4 +2756,15 @@ public final class Bukkit {
- public static Server.Spigot spigot() {
- return server.spigot();
- }
-+
-+ // Purpur start
-+ /**
-+ * Get the name of this server
-+ * @return the name of the server
-+ */
-+ @NotNull
-+ public static String getServerName() {
-+ return server.getServerName();
-+ }
-+ // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index c71576fea7e0e7c3ad54912ed61d1ff20aaea4c2..fc2ff6fce4d7b4466cb7936b530c1c0d17f9f24f 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -2416,4 +2416,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
- */
- boolean isOwnedByCurrentRegion(@NotNull Entity entity);
- // Paper end - Folia region threading API
-+
-+ // Purpur start
-+ /**
-+ * Get the name of this server
-+ * @return the name of the server
-+ */
-+ @NotNull
-+ String getServerName();
-+ // Purpur end
- }
diff --git a/patches/api/0012-ExecuteCommandEvent.patch b/patches/api/0012-ExecuteCommandEvent.patch
deleted file mode 100644
index dd05e0eb9..000000000
--- a/patches/api/0012-ExecuteCommandEvent.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Fri, 31 May 2019 00:08:28 -0500
-Subject: [PATCH] ExecuteCommandEvent
-
-
-diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e842d13febca67ffa1c89fb2c1324d2609fb81fd 100644
---- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
-+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-@@ -143,6 +143,19 @@ public class SimpleCommandMap implements CommandMap {
- return false;
- }
-
-+ // Purpur start
-+ String[] parsedArgs = Arrays.copyOfRange(args, 1, args.length);
-+ org.purpurmc.purpur.event.ExecuteCommandEvent event = new org.purpurmc.purpur.event.ExecuteCommandEvent(sender, target, sentCommandLabel, parsedArgs);
-+ if (!event.callEvent()) {
-+ return true; // cancelled
-+ }
-+
-+ sender = event.getSender();
-+ target = event.getCommand();
-+ sentCommandLabel = event.getLabel();
-+ parsedArgs = event.getArgs();
-+ // Purpur end
-+
- // Paper start - Plugins do weird things to workaround normal registration
- if (target.timings == null) {
- target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
-@@ -152,7 +165,7 @@ public class SimpleCommandMap implements CommandMap {
- try {
- try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources
- // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
-- target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
-+ target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
- } // target.timings.stopTiming(); // Spigot // Paper
- } catch (CommandException ex) {
- server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
-diff --git a/src/main/java/org/purpurmc/purpur/event/ExecuteCommandEvent.java b/src/main/java/org/purpurmc/purpur/event/ExecuteCommandEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..bc590c4d49d32f4365a50ceb5785e798702a8179
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/ExecuteCommandEvent.java
-@@ -0,0 +1,130 @@
-+package org.purpurmc.purpur.event;
-+
-+import com.google.common.base.Preconditions;
-+import org.bukkit.command.Command;
-+import org.bukkit.command.CommandSender;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.Event;
-+import org.bukkit.event.HandlerList;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * This event is called whenever someone runs a command
-+ */
-+public class ExecuteCommandEvent extends Event implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private boolean cancel = false;
-+ private CommandSender sender;
-+ private Command command;
-+ private String label;
-+ private String[] args;
-+
-+ public ExecuteCommandEvent(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @Nullable String[] args) {
-+ this.sender = sender;
-+ this.command = command;
-+ this.label = label;
-+ this.args = args;
-+ }
-+
-+ /**
-+ * Gets the command that the player is attempting to execute.
-+ *
-+ * @return Command the player is attempting to execute
-+ */
-+ @NotNull
-+ public Command getCommand() {
-+ return command;
-+ }
-+
-+ /**
-+ * Sets the command that the player will execute.
-+ *
-+ * @param command New command that the player will execute
-+ * @throws IllegalArgumentException if command is null or empty
-+ */
-+ public void setCommand(@NotNull Command command) throws IllegalArgumentException {
-+ Preconditions.checkArgument(command != null, "Command cannot be null");
-+ this.command = command;
-+ }
-+
-+ /**
-+ * Gets the sender that this command will be executed as.
-+ *
-+ * @return Sender this command will be executed as
-+ */
-+ @NotNull
-+ public CommandSender getSender() {
-+ return sender;
-+ }
-+
-+ /**
-+ * Sets the sender that this command will be executed as.
-+ *
-+ * @param sender New sender which this event will execute as
-+ * @throws IllegalArgumentException if the sender provided is null
-+ */
-+ public void setSender(@NotNull final CommandSender sender) throws IllegalArgumentException {
-+ Preconditions.checkArgument(sender != null, "Sender cannot be null");
-+ this.sender = sender;
-+ }
-+
-+ /**
-+ * Get the label used to execute this command
-+ *
-+ * @return Label used to execute this command
-+ */
-+ @NotNull
-+ public String getLabel() {
-+ return label;
-+ }
-+
-+ /**
-+ * Set the label used to execute this command
-+ *
-+ * @param label Label used
-+ */
-+ public void setLabel(@NotNull String label) {
-+ this.label = label;
-+ }
-+
-+ /**
-+ * Get the args passed to the command
-+ *
-+ * @return Args passed to the command
-+ */
-+ @NotNull
-+ public String[] getArgs() {
-+ return args;
-+ }
-+
-+ /**
-+ * Set the args passed to the command
-+ *
-+ * @param args Args passed to the command
-+ */
-+ public void setArgs(@NotNull String[] args) {
-+ this.args = args;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return cancel;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancel = cancel;
-+ }
-+
-+ @NotNull
-+ @Override
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0014-Lagging-threshold.patch b/patches/api/0014-Lagging-threshold.patch
deleted file mode 100644
index 23b7d9905..000000000
--- a/patches/api/0014-Lagging-threshold.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Tue, 23 Jul 2019 10:07:24 -0500
-Subject: [PATCH] Lagging threshold
-
-
-diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index 7338dad470cd75814cce5be40f82058554484607..a32155e0cc63d4e4714a953edbae0b19544ff3ef 100644
---- a/src/main/java/org/bukkit/Bukkit.java
-+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -2766,5 +2766,14 @@ public final class Bukkit {
- public static String getServerName() {
- return server.getServerName();
- }
-+
-+ /**
-+ * Check if server is lagging according to laggy threshold setting
-+ *
-+ * @return True if lagging
-+ */
-+ public static boolean isLagging() {
-+ return server.isLagging();
-+ }
- // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index fc2ff6fce4d7b4466cb7936b530c1c0d17f9f24f..5b8ce8a5658021c6fdfeabca6c7bb31ebc58e71d 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -2424,5 +2424,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
- */
- @NotNull
- String getServerName();
-+
-+ /**
-+ * Check if server is lagging according to laggy threshold setting
-+ *
-+ * @return True if lagging
-+ */
-+ boolean isLagging();
- // Purpur end
- }
diff --git a/patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch b/patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch
deleted file mode 100644
index fa03a99a9..000000000
--- a/patches/api/0015-PlayerSetSpawnerTypeWithEggEvent.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Fri, 5 Jul 2019 18:21:15 -0500
-Subject: [PATCH] PlayerSetSpawnerTypeWithEggEvent
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java b/src/main/java/org/purpurmc/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..519809eab5d926dc7b0a7bad5d446d0defc099dc
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/PlayerSetSpawnerTypeWithEggEvent.java
-@@ -0,0 +1,85 @@
-+package org.purpurmc.purpur.event;
-+
-+import org.bukkit.block.Block;
-+import org.bukkit.block.CreatureSpawner;
-+import org.bukkit.entity.EntityType;
-+import org.bukkit.entity.Player;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.player.PlayerEvent;
-+import org.jetbrains.annotations.NotNull;
-+
-+public class PlayerSetSpawnerTypeWithEggEvent extends PlayerEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Block block;
-+ private final CreatureSpawner spawner;
-+ private EntityType type;
-+ private boolean cancel;
-+
-+ public PlayerSetSpawnerTypeWithEggEvent(@NotNull Player player, @NotNull Block block, @NotNull CreatureSpawner spawner, @NotNull EntityType type) {
-+ super(player);
-+ this.block = block;
-+ this.spawner = spawner;
-+ this.type = type;
-+ }
-+
-+ /**
-+ * Get the spawner Block in the world
-+ *
-+ * @return Spawner Block
-+ */
-+ @NotNull
-+ public Block getBlock() {
-+ return block;
-+ }
-+
-+ /**
-+ * Get the spawner state
-+ *
-+ * @return Spawner state
-+ */
-+ @NotNull
-+ public CreatureSpawner getSpawner() {
-+ return spawner;
-+ }
-+
-+ /**
-+ * Gets the EntityType being set on the spawner
-+ *
-+ * @return EntityType being set
-+ */
-+ @NotNull
-+ public EntityType getEntityType() {
-+ return type;
-+ }
-+
-+ /**
-+ * Sets the EntityType being set on the spawner
-+ *
-+ * @param type EntityType to set
-+ */
-+ public void setEntityType(@NotNull EntityType type) {
-+ this.type = type;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return cancel;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancel = cancel;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0016-Player-invulnerabilities.patch b/patches/api/0016-Player-invulnerabilities.patch
deleted file mode 100644
index 32920bcf2..000000000
--- a/patches/api/0016-Player-invulnerabilities.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sat, 2 May 2020 20:55:31 -0500
-Subject: [PATCH] Player invulnerabilities
-
-
-diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 2ddacd7f74cba66f67ab6957e03522453de01117..1994acf66919c92f59e2a9f2f873f50b73d76d1a 100644
---- a/src/main/java/org/bukkit/entity/Player.java
-+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3298,5 +3298,26 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
- * Reset the idle timer back to 0
- */
- void resetIdleTimer();
-+
-+ /**
-+ * Check if player is invulnerable from recently spawning or accepting a resource pack
-+ *
-+ * @return True if invulnerable
-+ */
-+ boolean isSpawnInvulnerable();
-+
-+ /**
-+ * Get invulnerable ticks remaining
-+ *
-+ * @return Invulnerable ticks
-+ */
-+ int getSpawnInvulnerableTicks();
-+
-+ /**
-+ * Set invulnerable ticks remaining
-+ *
-+ * @param invulnerableTicks Invulnerable ticks remaining
-+ */
-+ void setSpawnInvulnerableTicks(int invulnerableTicks);
- // Purpur end
- }
diff --git a/patches/api/0017-Anvil-API.patch b/patches/api/0017-Anvil-API.patch
deleted file mode 100644
index 5ed2626ed..000000000
--- a/patches/api/0017-Anvil-API.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sun, 19 Apr 2020 00:25:09 -0500
-Subject: [PATCH] Anvil API
-
-
-diff --git a/src/main/java/org/bukkit/inventory/AnvilInventory.java b/src/main/java/org/bukkit/inventory/AnvilInventory.java
-index c60be4fd24c7fdf65251dd6169e5e1ac3b588d95..569deccd2f1cf21da9b5906433ac493c1f2081be 100644
---- a/src/main/java/org/bukkit/inventory/AnvilInventory.java
-+++ b/src/main/java/org/bukkit/inventory/AnvilInventory.java
-@@ -123,4 +123,14 @@ public interface AnvilInventory extends Inventory {
- setItem(2, result);
- }
- // Paper end
-+
-+ // Purpur start
-+ boolean canBypassCost();
-+
-+ void setBypassCost(boolean bypassCost);
-+
-+ boolean canDoUnsafeEnchants();
-+
-+ void setDoUnsafeEnchants(boolean canDoUnsafeEnchants);
-+ // Purpur end
- }
-diff --git a/src/main/java/org/purpurmc/purpur/event/inventory/AnvilTakeResultEvent.java b/src/main/java/org/purpurmc/purpur/event/inventory/AnvilTakeResultEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..b363c91a29f826910db22f2643decf996a067ab5
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/inventory/AnvilTakeResultEvent.java
-@@ -0,0 +1,52 @@
-+package org.purpurmc.purpur.event.inventory;
-+
-+import org.bukkit.entity.HumanEntity;
-+import org.bukkit.entity.Player;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.inventory.InventoryEvent;
-+import org.bukkit.inventory.AnvilInventory;
-+import org.bukkit.inventory.InventoryView;
-+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a player takes the result item out of an anvil
-+ */
-+public class AnvilTakeResultEvent extends InventoryEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Player player;
-+ private final ItemStack result;
-+
-+ public AnvilTakeResultEvent(@NotNull HumanEntity player, @NotNull InventoryView view, @NotNull ItemStack result) {
-+ super(view);
-+ this.player = (Player) player;
-+ this.result = result;
-+ }
-+
-+ @NotNull
-+ public Player getPlayer() {
-+ return player;
-+ }
-+
-+ @NotNull
-+ public ItemStack getResult() {
-+ return result;
-+ }
-+
-+ @NotNull
-+ @Override
-+ public AnvilInventory getInventory() {
-+ return (AnvilInventory) super.getInventory();
-+ }
-+
-+ @NotNull
-+ @Override
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/inventory/AnvilUpdateResultEvent.java b/src/main/java/org/purpurmc/purpur/event/inventory/AnvilUpdateResultEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..fd6a5a3589d436c2aaf988fd305899695799d3bb
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/inventory/AnvilUpdateResultEvent.java
-@@ -0,0 +1,35 @@
-+package org.purpurmc.purpur.event.inventory;
-+
-+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;
-+
-+/**
-+ * Called when anvil slots change, triggering the result slot to be updated
-+ */
-+public class AnvilUpdateResultEvent extends InventoryEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+
-+ public AnvilUpdateResultEvent(@NotNull InventoryView view) {
-+ super(view);
-+ }
-+
-+ @NotNull
-+ @Override
-+ public AnvilInventory getInventory() {
-+ return (AnvilInventory) super.getInventory();
-+ }
-+
-+ @NotNull
-+ @Override
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/patches/api/0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch
deleted file mode 100644
index 44337b14f..000000000
--- a/patches/api/0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sun, 28 Jun 2020 21:50:55 -0500
-Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-index 6f55ccfff74b361854bf424fd93f0428e66a6bd7..038b990fcd72847e7ea43eda3c24c4ce1a3d5bc4 100644
---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-@@ -205,6 +205,8 @@ public interface VanillaGoal extends Goal {
- GoalKey MOB_HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider"));
- GoalKey HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider"));
- GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider"));
-+ GoalKey FIND_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal"));
-+ GoalKey ORBIT_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal"));
- // Purpur end
-
- /**
diff --git a/patches/api/0023-Add-option-to-disable-zombie-aggressiveness-towards-.patch b/patches/api/0023-Add-option-to-disable-zombie-aggressiveness-towards-.patch
deleted file mode 100644
index 60a235185..000000000
--- a/patches/api/0023-Add-option-to-disable-zombie-aggressiveness-towards-.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: nitricspace
-Date: Wed, 23 Sep 2020 22:14:38 +0100
-Subject: [PATCH] Add option to disable zombie aggressiveness towards villagers
- when lagging
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-index 038b990fcd72847e7ea43eda3c24c4ce1a3d5bc4..150aa7b0876b50e2e92bab18721c548b8e6d5515 100644
---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-@@ -207,6 +207,8 @@ public interface VanillaGoal extends Goal {
- GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider"));
- GoalKey FIND_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("find_crystal"));
- GoalKey ORBIT_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal"));
-+ GoalKey DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
-+ GoalKey ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
- // Purpur end
-
- /**
diff --git a/patches/api/0024-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch b/patches/api/0024-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch
deleted file mode 100644
index af1641fb8..000000000
--- a/patches/api/0024-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Fri, 2 Oct 2020 17:43:24 -0500
-Subject: [PATCH] Add predicate to recipe's ExactChoice ingredient
-
-
-diff --git a/src/main/java/org/bukkit/inventory/RecipeChoice.java b/src/main/java/org/bukkit/inventory/RecipeChoice.java
-index 523818cbb0d6c90481ec97123e7fe0e2ff4eea14..bfeb8171a723d84b94bfaacd8aaf7d4d48ecd051 100644
---- a/src/main/java/org/bukkit/inventory/RecipeChoice.java
-+++ b/src/main/java/org/bukkit/inventory/RecipeChoice.java
-@@ -10,6 +10,7 @@ import java.util.function.Predicate;
- import org.bukkit.Material;
- import org.bukkit.Tag;
- import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable; // Purpur
-
- /**
- * Represents a potential item match within a recipe. All choices within a
-@@ -150,6 +151,7 @@ public interface RecipeChoice extends Predicate, Cloneable {
- public static class ExactChoice implements RecipeChoice {
-
- private List choices;
-+ private Predicate predicate; // Purpur
-
- public ExactChoice(@NotNull ItemStack stack) {
- this(Arrays.asList(stack));
-@@ -194,6 +196,7 @@ public interface RecipeChoice extends Predicate, Cloneable {
-
- @Override
- public boolean test(@NotNull ItemStack t) {
-+ if (predicate != null) return predicate.test(t); // Purpur
- for (ItemStack match : choices) {
- if (t.isSimilar(match)) {
- return true;
-@@ -203,6 +206,17 @@ public interface RecipeChoice extends Predicate, Cloneable {
- return false;
- }
-
-+ // Purpur start
-+ @Nullable
-+ public Predicate getPredicate() {
-+ return predicate;
-+ }
-+
-+ public void setPredicate(@Nullable Predicate predicate) {
-+ this.predicate = predicate;
-+ }
-+ // Purpur end
-+
- @Override
- public int hashCode() {
- int hash = 7;
diff --git a/patches/api/0025-Rabid-Wolf-API.patch b/patches/api/0025-Rabid-Wolf-API.patch
deleted file mode 100644
index ae345b5d7..000000000
--- a/patches/api/0025-Rabid-Wolf-API.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Encode42
-Date: Tue, 8 Dec 2020 17:15:15 -0500
-Subject: [PATCH] Rabid Wolf API
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-index 150aa7b0876b50e2e92bab18721c548b8e6d5515..54ecf2998eb7ee711fb56e3d8ed3f49129db4147 100644
---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-@@ -209,6 +209,7 @@ public interface VanillaGoal extends Goal {
- GoalKey ORBIT_CRYSTAL = GoalKey.of(Phantom.class, NamespacedKey.minecraft("orbit_crystal"));
- GoalKey DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
- GoalKey ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
-+ GoalKey AVOID_RABID_WOLF = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolf"));
- // Purpur end
-
- /**
-diff --git a/src/main/java/org/bukkit/entity/Wolf.java b/src/main/java/org/bukkit/entity/Wolf.java
-index 84db38388bf7a58e66d6cd29620b4fe64b0a897e..82ebd99549ce9f9e6427a50cef424e9007735708 100644
---- a/src/main/java/org/bukkit/entity/Wolf.java
-+++ b/src/main/java/org/bukkit/entity/Wolf.java
-@@ -69,4 +69,20 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar
- * @param interested Whether the wolf is interested
- */
- public void setInterested(boolean interested);
-+
-+ // Purpur start
-+ /**
-+ * Checks if this wolf is rabid
-+ *
-+ * @return whether the wolf is rabid
-+ */
-+ public boolean isRabid();
-+
-+ /**
-+ * Sets this wolf to be rabid or not
-+ *
-+ * @param rabid whether the wolf should be rabid
-+ */
-+ public void setRabid(boolean rabid);
-+ // Purpur end
- }
diff --git a/patches/api/0026-PlayerBookTooLargeEvent.patch b/patches/api/0026-PlayerBookTooLargeEvent.patch
deleted file mode 100644
index 937bb73c4..000000000
--- a/patches/api/0026-PlayerBookTooLargeEvent.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Wed, 23 Dec 2020 00:43:27 -0600
-Subject: [PATCH] PlayerBookTooLargeEvent
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java b/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c88394336bc9ab0f66a2af24d393f4a176a234d5
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/player/PlayerBookTooLargeEvent.java
-@@ -0,0 +1,65 @@
-+package org.purpurmc.purpur.event.player;
-+
-+import org.bukkit.Bukkit;
-+import org.bukkit.entity.Player;
-+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 tries to bypass book limitations
-+ */
-+public class PlayerBookTooLargeEvent extends PlayerEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final ItemStack book;
-+ private boolean kickPlayer = true;
-+
-+ /**
-+ * @param player The player
-+ * @param book The book
-+ */
-+ public PlayerBookTooLargeEvent(@NotNull Player player, @NotNull ItemStack book) {
-+ super(player, !Bukkit.isPrimaryThread());
-+ this.book = book;
-+ }
-+
-+ /**
-+ * Get the book containing the wanted edits
-+ *
-+ * @return The book
-+ */
-+ @NotNull
-+ public ItemStack getBook() {
-+ return book;
-+ }
-+
-+ /**
-+ * Whether server should kick the player or not
-+ *
-+ * @return True to kick player
-+ */
-+ public boolean shouldKickPlayer() {
-+ return kickPlayer;
-+ }
-+
-+ /**
-+ * Whether server should kick the player or not
-+ *
-+ * @param kickPlayer True to kick player
-+ */
-+ public void setShouldKickPlayer(boolean kickPlayer) {
-+ this.kickPlayer = kickPlayer;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0027-Full-netherite-armor-grants-fire-resistance.patch b/patches/api/0027-Full-netherite-armor-grants-fire-resistance.patch
deleted file mode 100644
index 5082cfcd3..000000000
--- a/patches/api/0027-Full-netherite-armor-grants-fire-resistance.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Thu, 24 Dec 2020 11:00:04 -0600
-Subject: [PATCH] Full netherite armor grants fire resistance
-
-
-diff --git a/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java b/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
-index c9f395064656dd0126410eb3c6e197baa450c063..13156a12e5df50cdc1e465dc0bd9d94108275629 100644
---- a/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
-+++ b/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java
-@@ -217,6 +217,12 @@ public class EntityPotionEffectEvent extends EntityEvent implements Cancellable
- * When all effects are removed due to a bucket of milk.
- */
- MILK,
-+ // Purpur start
-+ /**
-+ * When a player wears full netherite armor
-+ */
-+ NETHERITE_ARMOR,
-+ // Purpur end
- /**
- * When a player gets bad omen after killing a patrol captain.
- */
diff --git a/patches/api/0028-Add-EntityTeleportHinderedEvent.patch b/patches/api/0028-Add-EntityTeleportHinderedEvent.patch
deleted file mode 100644
index a172c1de1..000000000
--- a/patches/api/0028-Add-EntityTeleportHinderedEvent.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mariell Hoversholm
-Date: Sat, 9 Jan 2021 15:26:04 +0100
-Subject: [PATCH] Add EntityTeleportHinderedEvent
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/EntityTeleportHinderedEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/EntityTeleportHinderedEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c66eb163877e872f234d86dc244cab7efeb818cd
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/EntityTeleportHinderedEvent.java
-@@ -0,0 +1,117 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.entity.Entity;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * Fired when an entity is hindered from teleporting.
-+ */
-+public class EntityTeleportHinderedEvent extends EntityEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+
-+ @NotNull
-+ private final Reason reason;
-+
-+ @Nullable
-+ private final TeleportCause teleportCause;
-+
-+ private boolean retry = false;
-+
-+ public EntityTeleportHinderedEvent(@NotNull Entity what, @NotNull Reason reason,
-+ @Nullable TeleportCause teleportCause) {
-+ super(what);
-+ this.reason = reason;
-+ this.teleportCause = teleportCause;
-+ }
-+
-+ /**
-+ * @return why the teleport was hindered.
-+ */
-+ @NotNull
-+ public Reason getReason() {
-+ return reason;
-+ }
-+
-+ /**
-+ * @return why the teleport occurred if cause was given, otherwise {@code null}.
-+ */
-+ @Nullable
-+ public TeleportCause getTeleportCause() {
-+ return teleportCause;
-+ }
-+
-+ /**
-+ * Whether the teleport should be retried.
-+ *
-+ * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
-+ * overflow. Do not retry more than necessary.
-+ *
-+ *
-+ * @return whether the teleport should be retried.
-+ */
-+ public boolean shouldRetry() {
-+ return retry;
-+ }
-+
-+ /**
-+ * Sets whether the teleport should be retried.
-+ *
-+ * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
-+ * overflow. Do not retry more than necessary.
-+ *
-+ *
-+ * @param retry whether the teleport should be retried.
-+ */
-+ public void setShouldRetry(boolean retry) {
-+ this.retry = retry;
-+ }
-+
-+ /**
-+ * Calls the event and tests if should retry.
-+ *
-+ * @return whether the teleport should be retried.
-+ */
-+ @Override
-+ public boolean callEvent() {
-+ super.callEvent();
-+ return shouldRetry();
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+
-+ /**
-+ * Reason for hindrance in teleports.
-+ */
-+ public enum Reason {
-+ /**
-+ * The teleported entity is a passenger of another entity.
-+ */
-+ IS_PASSENGER,
-+
-+ /**
-+ * The teleported entity has passengers.
-+ */
-+ IS_VEHICLE,
-+
-+ /**
-+ * The teleport event was cancelled.
-+ *
-+ * This is only caused by players teleporting.
-+ *
-+ */
-+ EVENT_CANCELLED,
-+ }
-+}
diff --git a/patches/api/0029-Add-enchantment-target-for-bows-and-crossbows.patch b/patches/api/0029-Add-enchantment-target-for-bows-and-crossbows.patch
deleted file mode 100644
index d9680f160..000000000
--- a/patches/api/0029-Add-enchantment-target-for-bows-and-crossbows.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Tue, 23 Mar 2021 15:01:03 -0500
-Subject: [PATCH] Add enchantment target for bows and crossbows
-
-
-diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-index 455ff52d90565838fe7640c3f045b27082a6c2f1..5831ffe24eed01311c71989dcb1830dbc395607b 100644
---- a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-+++ b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-@@ -227,6 +227,18 @@ public enum EnchantmentTarget {
- public boolean includes(@NotNull Material item) {
- return BREAKABLE.includes(item) || (WEARABLE.includes(item) && !item.equals(Material.ELYTRA)) || item.equals(Material.COMPASS);
- }
-+ // Purpur start
-+ },
-+
-+ /**
-+ * Allow the Enchantment to be placed on bows and crossbows.
-+ */
-+ BOW_AND_CROSSBOW {
-+ @Override
-+ public boolean includes(@NotNull Material item) {
-+ return item.equals(Material.BOW) || item.equals(Material.CROSSBOW);
-+ }
-+ // Purpur end
- };
-
- /**
diff --git a/patches/api/0030-Iron-golem-poppy-calms-anger.patch b/patches/api/0030-Iron-golem-poppy-calms-anger.patch
deleted file mode 100644
index 03f75e7c6..000000000
--- a/patches/api/0030-Iron-golem-poppy-calms-anger.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Thu, 13 May 2021 21:38:01 -0500
-Subject: [PATCH] Iron golem poppy calms anger
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-index 54ecf2998eb7ee711fb56e3d8ed3f49129db4147..b1f35c68373edfe666ca05b50f0ec022a1859ce9 100644
---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java
-@@ -210,6 +210,7 @@ public interface VanillaGoal extends Goal {
- GoalKey DROWNED_ATTACK_VILLAGER = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack_villager"));
- GoalKey ZOMBIE_ATTACK_VILLAGER = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_villager"));
- GoalKey AVOID_RABID_WOLF = GoalKey.of(Wolf.class, NamespacedKey.minecraft("avoid_rabid_wolf"));
-+ GoalKey RECEIVE_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("receive_flower"));
- // Purpur end
-
- /**
diff --git a/patches/api/0031-API-for-any-mob-to-burn-daylight.patch b/patches/api/0031-API-for-any-mob-to-burn-daylight.patch
deleted file mode 100644
index 38781b67f..000000000
--- a/patches/api/0031-API-for-any-mob-to-burn-daylight.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Ben Kerllenevich
-Date: Tue, 25 May 2021 16:30:30 -0400
-Subject: [PATCH] API for any mob to burn daylight
-
-Co-authored by: Encode42
-
-diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
-index de60e8773e58ef62c15d8f7e293313a62dff674b..52867495d0f746ff40e802c4f1018511e58fd03e 100644
---- a/src/main/java/org/bukkit/entity/Entity.java
-+++ b/src/main/java/org/bukkit/entity/Entity.java
-@@ -1079,5 +1079,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
- * @return True if ridable in water
- */
- boolean isRidableInWater();
-+
-+ /**
-+ * Checks if the entity is in daylight
-+ *
-+ * @return True if in daylight
-+ */
-+ boolean isInDaylight();
- // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
-index accefccca9993edd00f72b4e5779fce0b3ee628f..994e026d68fcda9a4c34a8b161a06623f4437dff 100644
---- a/src/main/java/org/bukkit/entity/LivingEntity.java
-+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
-@@ -1214,5 +1214,19 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
- * @param slot Equipment slot to play break animation for
- */
- void broadcastItemBreak(@NotNull org.bukkit.inventory.EquipmentSlot slot);
-+
-+ /**
-+ * If this mob will burn in the sunlight
-+ *
-+ * @return True if mob will burn in sunlight
-+ */
-+ boolean shouldBurnInDay();
-+
-+ /**
-+ * Set if this mob should burn in the sunlight
-+ *
-+ * @param shouldBurnInDay True to burn in sunlight
-+ */
-+ void setShouldBurnInDay(boolean shouldBurnInDay);
- // Purpur end
- }
diff --git a/patches/api/0033-Fix-default-permission-system.patch b/patches/api/0033-Fix-default-permission-system.patch
deleted file mode 100644
index 754c4e1e3..000000000
--- a/patches/api/0033-Fix-default-permission-system.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Wed, 30 Jun 2021 17:44:27 -0500
-Subject: [PATCH] Fix default permission system
-
-
-diff --git a/src/main/java/org/bukkit/permissions/PermissibleBase.java b/src/main/java/org/bukkit/permissions/PermissibleBase.java
-index cd3296fea01648592d2af89b3d80135acb6d0958..45797a6fbae1d8edc4211cb30def24ad4f59bd49 100644
---- a/src/main/java/org/bukkit/permissions/PermissibleBase.java
-+++ b/src/main/java/org/bukkit/permissions/PermissibleBase.java
-@@ -168,7 +168,7 @@ public class PermissibleBase implements Permissible {
-
- for (Permission perm : defaults) {
- String name = perm.getName().toLowerCase(java.util.Locale.ENGLISH);
-- permissions.put(name, new PermissionAttachmentInfo(parent, name, null, true));
-+ permissions.put(name, new PermissionAttachmentInfo(parent, name, null, perm.getDefault().getValue(isOp()))); // Purpur
- Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
- calculateChildPermissions(perm.getChildren(), false, null);
- }
-@@ -196,7 +196,7 @@ public class PermissibleBase implements Permissible {
- String name = entry.getKey();
-
- Permission perm = Bukkit.getServer().getPluginManager().getPermission(name);
-- boolean value = entry.getValue() ^ invert;
-+ boolean value = (entry.getValue() == null && perm != null ? perm.getDefault().getValue(isOp()) : entry.getValue()) ^ invert; // Purpur
- String lname = name.toLowerCase(java.util.Locale.ENGLISH);
-
- permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value));
-diff --git a/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java b/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
-index 8e481e3815f5645ee92f0d229e5ff25c8fc9a6c2..10627d2a11251a8cb01bbc3f6242d66f3505a16e 100644
---- a/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
-+++ b/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java
-@@ -31,7 +31,7 @@ public final class DefaultPermissions {
-
- if (withLegacy) {
- Permission legacy = new Permission(LEGACY_PREFIX + result.getName(), result.getDescription(), PermissionDefault.FALSE);
-- legacy.getChildren().put(result.getName(), true);
-+ legacy.getChildren().put(result.getName(), null); // Purpur
- registerPermission(perm, false);
- }
-
-@@ -40,7 +40,7 @@ public final class DefaultPermissions {
-
- @NotNull
- public static Permission registerPermission(@NotNull Permission perm, @NotNull Permission parent) {
-- parent.getChildren().put(perm.getName(), true);
-+ parent.getChildren().put(perm.getName(), null); // Purpur
- return registerPermission(perm);
- }
-
-@@ -53,7 +53,7 @@ public final class DefaultPermissions {
- @NotNull
- public static Permission registerPermission(@NotNull String name, @Nullable String desc, @NotNull Permission parent) {
- Permission perm = registerPermission(name, desc);
-- parent.getChildren().put(perm.getName(), true);
-+ parent.getChildren().put(perm.getName(), null); // Purpur
- return perm;
- }
-
-@@ -66,7 +66,7 @@ public final class DefaultPermissions {
- @NotNull
- public static Permission registerPermission(@NotNull String name, @Nullable String desc, @Nullable PermissionDefault def, @NotNull Permission parent) {
- Permission perm = registerPermission(name, desc, def);
-- parent.getChildren().put(perm.getName(), true);
-+ parent.getChildren().put(perm.getName(), null); // Purpur
- return perm;
- }
-
-@@ -79,7 +79,7 @@ public final class DefaultPermissions {
- @NotNull
- public static Permission registerPermission(@NotNull String name, @Nullable String desc, @Nullable PermissionDefault def, @Nullable Map children, @NotNull Permission parent) {
- Permission perm = registerPermission(name, desc, def, children);
-- parent.getChildren().put(perm.getName(), true);
-+ parent.getChildren().put(perm.getName(), null); // Purpur
- return perm;
- }
-
diff --git a/patches/api/0034-Summoner-API.patch b/patches/api/0034-Summoner-API.patch
deleted file mode 100644
index bc94bd07e..000000000
--- a/patches/api/0034-Summoner-API.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Sat, 3 Jul 2021 18:45:01 -0500
-Subject: [PATCH] Summoner API
-
-
-diff --git a/src/main/java/org/bukkit/entity/IronGolem.java b/src/main/java/org/bukkit/entity/IronGolem.java
-index 655e37cb3a09610a3f3df805d6dcad17d722da62..09fd716c8fc9ea34a1cbf87bcbe22df035422a51 100644
---- a/src/main/java/org/bukkit/entity/IronGolem.java
-+++ b/src/main/java/org/bukkit/entity/IronGolem.java
-@@ -19,4 +19,20 @@ public interface IronGolem extends Golem {
- * player created, false if you want it to be a natural village golem.
- */
- public void setPlayerCreated(boolean playerCreated);
-+
-+ // Purpur start
-+ /**
-+ * Get the player that summoned this iron golem
-+ *
-+ * @return UUID of summoner
-+ */
-+ @org.jetbrains.annotations.Nullable java.util.UUID getSummoner();
-+
-+ /**
-+ * Set the player that summoned this iron golem
-+ *
-+ * @param summoner UUID of summoner
-+ */
-+ void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner);
-+ // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java
-index 7fbfdb07585c7b28acea1f0c1f58ada0cc744441..21fcca092e2e31baa5ece0de9e44e3fade8c7123 100644
---- a/src/main/java/org/bukkit/entity/Snowman.java
-+++ b/src/main/java/org/bukkit/entity/Snowman.java
-@@ -23,4 +23,20 @@ public interface Snowman extends Golem, RangedEntity, io.papermc.paper.entity.Sh
- * @param derpMode True to remove the pumpkin, false to add a pumpkin
- */
- void setDerp(boolean derpMode);
-+
-+ // Purpur start
-+ /**
-+ * Get the player that summoned this snowman
-+ *
-+ * @return UUID of summoner
-+ */
-+ @org.jetbrains.annotations.Nullable java.util.UUID getSummoner();
-+
-+ /**
-+ * Set the player that summoned this snowman
-+ *
-+ * @param summoner UUID of summoner
-+ */
-+ void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner);
-+ // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/entity/Wither.java b/src/main/java/org/bukkit/entity/Wither.java
-index 14543c2238b45c526dd9aebea2aa5c22f5df54dc..5312daf33405704c74e2c9e109754285ea6cf734 100644
---- a/src/main/java/org/bukkit/entity/Wither.java
-+++ b/src/main/java/org/bukkit/entity/Wither.java
-@@ -107,4 +107,20 @@ public interface Wither extends Monster, Boss, com.destroystokyo.paper.entity.Ra
- */
- void enterInvulnerabilityPhase();
- // Paper end
-+
-+ // Purpur start
-+ /**
-+ * Get the player that summoned this wither
-+ *
-+ * @return UUID of summoner
-+ */
-+ @org.jetbrains.annotations.Nullable java.util.UUID getSummoner();
-+
-+ /**
-+ * Set the player that summoned this wither
-+ *
-+ * @param summoner UUID of summoner
-+ */
-+ void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner);
-+ // Purpur end
- }
diff --git a/patches/api/0035-Clean-up-version-command-output.patch b/patches/api/0035-Clean-up-version-command-output.patch
deleted file mode 100644
index 1bd0a28dd..000000000
--- a/patches/api/0035-Clean-up-version-command-output.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Thu, 15 Jul 2021 23:43:04 -0500
-Subject: [PATCH] Clean up version command output
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
-index a736d7bcdc5861a01b66ba36158db1c716339346..22fc165fd9c95f0f3ae1be7a0857e48cc50fad5b 100644
---- a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
-+++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
-@@ -26,6 +26,12 @@ public interface VersionFetcher {
- @NotNull
- Component getVersionMessage(@NotNull String serverVersion);
-
-+ // Purpur start
-+ default int distance() {
-+ return 0;
-+ }
-+ // Purpur end
-+
- class DummyVersionFetcher implements VersionFetcher {
-
- @Override
-diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
-index fd5d9881abfd930bb883120f018f76dc78b62b14..d3dadad49df09e85c724c93e8cc88da2c985e9b4 100644
---- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
-+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
-@@ -214,7 +214,7 @@ public class VersionCommand extends BukkitCommand {
- String version = Bukkit.getVersion();
- // Paper start
- if (version.startsWith("null")) { // running from ide?
-- setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW));
-+ setVersionMessage(Component.text("* Unknown version, custom build?", NamedTextColor.RED)); // Purpur
- return;
- }
- setVersionMessage(getVersionFetcher().getVersionMessage(version));
-@@ -255,9 +255,11 @@ public class VersionCommand extends BukkitCommand {
- // Paper start
- private void setVersionMessage(final @NotNull Component msg) {
- lastCheck = System.currentTimeMillis();
-- final Component message = Component.textOfChildren(
-- Component.text(Bukkit.getVersionMessage(), NamedTextColor.WHITE),
-- Component.newline(),
-+ // Purpur start
-+ int distance = getVersionFetcher().distance();
-+ final Component message = Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()),
-+ ChatColor.parseMM("Current: %s%s*", distance == 0 ? "" : distance > 0 ? "" : "", Bukkit.getVersion()),
-+ // Purpur end
- msg
- );
- this.versionMessage = Component.text()
diff --git a/patches/api/0037-Added-the-ability-to-add-combustible-items.patch b/patches/api/0037-Added-the-ability-to-add-combustible-items.patch
deleted file mode 100644
index 58ef1ffd8..000000000
--- a/patches/api/0037-Added-the-ability-to-add-combustible-items.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: DoctaEnkoda
-Date: Mon, 9 Aug 2021 13:22:03 +0200
-Subject: [PATCH] Added the ability to add combustible items
-
-
-diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index a32155e0cc63d4e4714a953edbae0b19544ff3ef..222dcb75a850d224ac22b2e06895233527cffc76 100644
---- a/src/main/java/org/bukkit/Bukkit.java
-+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -2775,5 +2775,24 @@ public final class Bukkit {
- public static boolean isLagging() {
- return server.isLagging();
- }
-+
-+ /**
-+ * Add an Item as fuel for furnaces
-+ *
-+ * @param material The material that will be the fuel
-+ * @param burnTime The time (in ticks) this item will burn for
-+ */
-+ public static void addFuel(@NotNull Material material, int burnTime) {
-+ server.addFuel(material, burnTime);
-+ }
-+
-+ /**
-+ * Remove an item as fuel for furnaces
-+ *
-+ * @param material The material that will no longer be a fuel
-+ */
-+ public static void removeFuel(@NotNull Material material) {
-+ server.removeFuel(material);
-+ }
- // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index 5b8ce8a5658021c6fdfeabca6c7bb31ebc58e71d..3bc9fa8b68b284516ddbf0ace0c1dc52768307cb 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -2431,5 +2431,20 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
- * @return True if lagging
- */
- boolean isLagging();
-+
-+ /**
-+ * Add an Item as fuel for furnaces
-+ *
-+ * @param material The material that will be the fuel
-+ * @param burnTime The time (in ticks) this item will burn for
-+ */
-+ public void addFuel(@NotNull Material material, int burnTime);
-+
-+ /**
-+ * Remove an item as fuel for furnaces
-+ *
-+ * @param material The material that will no longer be a fuel
-+ */
-+ public void removeFuel(@NotNull Material material);
- // Purpur end
- }
diff --git a/patches/api/0039-Grindstone-API.patch b/patches/api/0039-Grindstone-API.patch
deleted file mode 100644
index 5a699b1c1..000000000
--- a/patches/api/0039-Grindstone-API.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath
-Date: Mon, 27 Dec 2021 08:10:50 -0600
-Subject: [PATCH] Grindstone API
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/inventory/GrindstoneTakeResultEvent.java b/src/main/java/org/purpurmc/purpur/event/inventory/GrindstoneTakeResultEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..eebb5d124456b8209d1b8e8cc4cb772dd3714f04
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/inventory/GrindstoneTakeResultEvent.java
-@@ -0,0 +1,72 @@
-+package org.purpurmc.purpur.event.inventory;
-+
-+import org.bukkit.entity.HumanEntity;
-+import org.bukkit.entity.Player;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.inventory.InventoryEvent;
-+import org.bukkit.inventory.GrindstoneInventory;
-+import org.bukkit.inventory.InventoryView;
-+import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a player takes the result item out of a Grindstone
-+ */
-+public class GrindstoneTakeResultEvent extends InventoryEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Player player;
-+ private final ItemStack result;
-+ private int experienceAmount;
-+
-+ public GrindstoneTakeResultEvent(@NotNull HumanEntity player, @NotNull InventoryView view, @NotNull ItemStack result, int experienceAmount) {
-+ super(view);
-+ this.player = (Player) player;
-+ this.result = result;
-+ this.experienceAmount = experienceAmount;
-+ }
-+
-+ @NotNull
-+ public Player getPlayer() {
-+ return player;
-+ }
-+
-+ @NotNull
-+ public ItemStack getResult() {
-+ return result;
-+ }
-+
-+ @NotNull
-+ @Override
-+ public GrindstoneInventory getInventory() {
-+ return (GrindstoneInventory) super.getInventory();
-+ }
-+
-+ /**
-+ * Get the amount of experience this transaction will give
-+ *
-+ * @return Amount of experience to give
-+ */
-+ public int getExperienceAmount() {
-+ return this.experienceAmount;
-+ }
-+
-+ /**
-+ * Set the amount of experience this transaction will give
-+ *
-+ * @param experienceAmount Amount of experience to give
-+ */
-+ public void setExperienceAmount(int experienceAmount) {
-+ this.experienceAmount = experienceAmount;
-+ }
-+
-+ @NotNull
-+ @Override
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0040-Shears-can-have-looting-enchantment.patch b/patches/api/0040-Shears-can-have-looting-enchantment.patch
deleted file mode 100644
index 53f2a3f93..000000000
--- a/patches/api/0040-Shears-can-have-looting-enchantment.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath
-Date: Mon, 3 Jan 2022 02:00:50 -0600
-Subject: [PATCH] Shears can have looting enchantment
-
-
-diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-index 5831ffe24eed01311c71989dcb1830dbc395607b..45f5493eebfecf56b7c0ef4659c078dfc62c0612 100644
---- a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-+++ b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
-@@ -238,6 +238,16 @@ public enum EnchantmentTarget {
- public boolean includes(@NotNull Material item) {
- return item.equals(Material.BOW) || item.equals(Material.CROSSBOW);
- }
-+ },
-+
-+ /**
-+ * Allow the Enchantment to be placed on shears.
-+ */
-+ WEAPON_AND_SHEARS {
-+ @Override
-+ public boolean includes(@NotNull Material item) {
-+ return WEAPON.includes(item) || item.equals(Material.SHEARS);
-+ }
- // Purpur end
- };
-
diff --git a/patches/api/0041-Lobotomize-stuck-villagers.patch b/patches/api/0041-Lobotomize-stuck-villagers.patch
deleted file mode 100644
index 03b9bf50d..000000000
--- a/patches/api/0041-Lobotomize-stuck-villagers.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath
-Date: Mon, 24 Jan 2022 20:42:22 -0600
-Subject: [PATCH] Lobotomize stuck villagers
-
-
-diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java
-index 3bc24457d143449e6a338d79becf7c39b9f81054..4a5edf4e72e81b22c1abb2ade244f7f4292e993c 100644
---- a/src/main/java/org/bukkit/entity/Villager.java
-+++ b/src/main/java/org/bukkit/entity/Villager.java
-@@ -328,4 +328,14 @@ public interface Villager extends AbstractVillager {
- */
- public void clearReputations();
- // Paper end
-+
-+ // Purpur start
-+
-+ /**
-+ * Check if villager is currently lobotomized
-+ *
-+ * @return True if lobotomized
-+ */
-+ boolean isLobotomized();
-+ // Purpur end
- }
diff --git a/patches/api/0042-Add-local-difficulty-api.patch b/patches/api/0042-Add-local-difficulty-api.patch
deleted file mode 100644
index 3b9825738..000000000
--- a/patches/api/0042-Add-local-difficulty-api.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath
-Date: Sat, 9 Jul 2022 00:57:26 -0500
-Subject: [PATCH] Add local difficulty api
-
-
-diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
-index 6917931966377c51db88a3364997a110dd987970..1fba792419ea6b5e8c640a2599e4b2dd16ee87d0 100644
---- a/src/main/java/org/bukkit/World.java
-+++ b/src/main/java/org/bukkit/World.java
-@@ -3992,6 +3992,16 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
- @Nullable
- public DragonBattle getEnderDragonBattle();
-
-+ // Purpur start
-+ /**
-+ * Gets the local difficulty (based on inhabited time) at a location
-+ *
-+ * @param location Location to check
-+ * @return The local difficulty
-+ */
-+ public float getLocalDifficultyAt(@NotNull Location location);
-+ // Purpur end
-+
- /**
- * Get all {@link FeatureFlag} enabled in this world.
- *
diff --git a/patches/api/0043-Remove-Timings.patch b/patches/api/0043-Remove-Timings.patch
deleted file mode 100644
index 75f6b7465..000000000
--- a/patches/api/0043-Remove-Timings.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath
-Date: Fri, 1 Jul 2022 04:03:26 -0500
-Subject: [PATCH] Remove Timings
-
-
-diff --git a/src/main/java/co/aikar/timings/TimedEventExecutor.java b/src/main/java/co/aikar/timings/TimedEventExecutor.java
-index 8f29c1561ba5916cb5634392edd8bd2a5a294a51..6fbc64e0f214d0c8e5afcbe385e414a4e1fe1c72 100644
---- a/src/main/java/co/aikar/timings/TimedEventExecutor.java
-+++ b/src/main/java/co/aikar/timings/TimedEventExecutor.java
-@@ -77,9 +77,9 @@ public class TimedEventExecutor implements EventExecutor {
- executor.execute(listener, event);
- return;
- }
-- try (Timing ignored = timings.startTiming()){
-+ //try (Timing ignored = timings.startTiming()){ // Purpur
- executor.execute(listener, event);
-- }
-+ //} // Purpur
- }
-
- @Override
-diff --git a/src/main/java/co/aikar/timings/Timing.java b/src/main/java/co/aikar/timings/Timing.java
-index 7514fad26f955329f8bf17ff17db75f0c8301ee5..1d866e980abc542bdfee1ce082cd9cdd7761e9f7 100644
---- a/src/main/java/co/aikar/timings/Timing.java
-+++ b/src/main/java/co/aikar/timings/Timing.java
-@@ -39,6 +39,7 @@ public interface Timing extends AutoCloseable {
- * @return Timing
- */
- @NotNull
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- Timing startTiming();
-
- /**
-@@ -46,6 +47,7 @@ public interface Timing extends AutoCloseable {
- *
- * Will automatically be called when this Timing is used with try-with-resources
- */
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- void stopTiming();
-
- /**
-@@ -56,6 +58,7 @@ public interface Timing extends AutoCloseable {
- * @return Timing
- */
- @NotNull
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- Timing startTimingIfSync();
-
- /**
-@@ -65,12 +68,14 @@ public interface Timing extends AutoCloseable {
- *
- * But only if we are on the primary thread.
- */
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- void stopTimingIfSync();
-
- /**
- * @deprecated Doesn't do anything - Removed
- */
- @Deprecated
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- void abort();
-
- /**
-@@ -82,5 +87,6 @@ public interface Timing extends AutoCloseable {
- TimingHandler getTimingHandler();
-
- @Override
-+ @io.papermc.paper.annotation.DoNotUse // Purpur
- void close();
- }
-diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
-index 9812d668ad945aba486fbf6d5bf83c4292cb5d03..752d54830aa8baa1450bf72da03ae55ed30293c2 100644
---- a/src/main/java/co/aikar/timings/Timings.java
-+++ b/src/main/java/co/aikar/timings/Timings.java
-@@ -124,7 +124,7 @@ public final class Timings {
- @NotNull
- public static Timing ofStart(@NotNull Plugin plugin, @NotNull String name, @Nullable Timing groupHandler) {
- Timing timing = of(plugin, name, groupHandler);
-- timing.startTiming();
-+ //timing.startTiming(); // Purpur
- return timing;
- }
-
-@@ -145,9 +145,11 @@ public final class Timings {
- * @param enabled Should timings be reported
- */
- public static void setTimingsEnabled(boolean enabled) {
-- timingsEnabled = enabled;
-- warnAboutDeprecationOnEnable();
-- reset();
-+ // Purpur start - we don't do that here...
-+ timingsEnabled = false;
-+ //warnAboutDeprecationOnEnable();
-+ //reset();
-+ // Purpur end
- }
-
- private static void warnAboutDeprecationOnEnable() {
-diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java
-index e801e79fa57c44b2e5d359647c920f88064826f1..1abfcee0f6d632f4cd8d74b4994a90c9ea9d254c 100644
---- a/src/main/java/co/aikar/timings/TimingsCommand.java
-+++ b/src/main/java/co/aikar/timings/TimingsCommand.java
-@@ -45,7 +45,7 @@ public class TimingsCommand extends BukkitCommand {
- public TimingsCommand(@NotNull String name) {
- super(name);
- this.description = "Manages Spigot Timings data to see performance of the server.";
-- this.usageMessage = "/timings ";
-+ this.usageMessage = "/timings";// "; // Purpur
- this.setPermission("bukkit.command.timings");
- }
-
-@@ -54,8 +54,12 @@ public class TimingsCommand extends BukkitCommand {
- if (!testPermission(sender)) {
- return true;
- }
-- if (false) {
-- sender.sendMessage(Timings.deprecationMessage());
-+ if (true) {
-+ net.kyori.adventure.text.minimessage.MiniMessage mm = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage();
-+ sender.sendMessage(mm.deserialize("Purpur has removed timings to save your performance. Please use /spark instead"));
-+ sender.sendMessage(mm.deserialize("For more information, view its documentation at"));
-+ sender.sendMessage(mm.deserialize("https://spark.lucko.me/docs/Command-Usage"));
-+ return true;
- }
- if (args.length < 1) {
- sender.sendMessage(text("Usage: " + this.usageMessage, NamedTextColor.RED));
-@@ -115,7 +119,7 @@ public class TimingsCommand extends BukkitCommand {
- Preconditions.checkNotNull(args, "Arguments cannot be null");
- Preconditions.checkNotNull(alias, "Alias cannot be null");
-
-- if (args.length == 1) {
-+ if (false && args.length == 1) { // Purpur
- return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS,
- new ArrayList(TIMINGS_SUBCOMMANDS.size()));
- }
-diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-index e842d13febca67ffa1c89fb2c1324d2609fb81fd..5349f16136d9348c374a7dfe5b89a71dfcb0e66d 100644
---- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
-+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
-@@ -163,10 +163,10 @@ public class SimpleCommandMap implements CommandMap {
- // Paper end
-
- try {
-- try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources
-+ //try (co.aikar.timings.Timing ignored = target.timings.startTiming()) { // Paper - use try with resources // Purpur
- // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
- target.execute(sender, sentCommandLabel, parsedArgs); // Purpur
-- } // target.timings.stopTiming(); // Spigot // Paper
-+ //} // target.timings.stopTiming(); // Spigot // Paper // Purpur
- } catch (CommandException ex) {
- server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper
- //target.timings.stopTiming(); // Spigot // Paper
-diff --git a/src/main/java/org/spigotmc/CustomTimingsHandler.java b/src/main/java/org/spigotmc/CustomTimingsHandler.java
-index 12946bd55fcf7c40d39081779a7fa30049ee6165..9c2d605c50cbf9aefa56ec209df9f6cea1392e89 100644
---- a/src/main/java/org/spigotmc/CustomTimingsHandler.java
-+++ b/src/main/java/org/spigotmc/CustomTimingsHandler.java
-@@ -61,7 +61,7 @@ public final class CustomTimingsHandler {
- handler = timing;
- }
-
-- public void startTiming() { handler.startTiming(); }
-- public void stopTiming() { handler.stopTiming(); }
-+ public void startTiming() { /*handler.startTiming();*/ } // Purpur
-+ public void stopTiming() { /*handler.stopTiming();*/ } // Purpur
-
- }
diff --git a/patches/api/0044-Add-Bee-API.patch b/patches/api/0044-Add-Bee-API.patch
deleted file mode 100644
index 6efae8520..000000000
--- a/patches/api/0044-Add-Bee-API.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: SageSphinx63920
-Date: Mon, 25 Jul 2022 19:33:49 +0200
-Subject: [PATCH] Add Bee API
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/BeeFoundFlowerEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/BeeFoundFlowerEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..833f46d1941f377765132fc528c45567ee0290d2
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/BeeFoundFlowerEvent.java
-@@ -0,0 +1,48 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.Location;
-+import org.bukkit.entity.Bee;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * Called when a bee targets a flower
-+ */
-+public class BeeFoundFlowerEvent extends EntityEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Location location;
-+
-+ public BeeFoundFlowerEvent(@NotNull Bee bee, @Nullable Location location) {
-+ super(bee);
-+ this.location = location;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Bee getEntity() {
-+ return (Bee) super.getEntity();
-+ }
-+
-+ /**
-+ * Returns the location of the flower that the bee targets
-+ *
-+ * @return The location of the flower
-+ */
-+ @Nullable
-+ public Location getLocation() {
-+ return location;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/BeeStartedPollinatingEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/BeeStartedPollinatingEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..ae0bb654745724889c67fae9072ae90ea3778ba4
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/BeeStartedPollinatingEvent.java
-@@ -0,0 +1,47 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.Location;
-+import org.bukkit.entity.Bee;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a bee starts pollinating
-+ */
-+public class BeeStartedPollinatingEvent extends EntityEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Location location;
-+
-+ public BeeStartedPollinatingEvent(@NotNull Bee bee, @NotNull Location location) {
-+ super(bee);
-+ this.location = location;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Bee getEntity() {
-+ return (Bee) super.getEntity();
-+ }
-+
-+ /**
-+ * Returns the location of the flower that the bee pollinates
-+ *
-+ * @return The location of the flower
-+ */
-+ @NotNull
-+ public Location getLocation() {
-+ return this.location;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/BeeStopPollinatingEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/BeeStopPollinatingEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..ff3c9f075be2f624af8b0ce5fffc5ea69a41f32e
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/BeeStopPollinatingEvent.java
-@@ -0,0 +1,60 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.Location;
-+import org.bukkit.entity.Bee;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * Called when a bee stops pollinating
-+ */
-+public class BeeStopPollinatingEvent extends EntityEvent {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final Location location;
-+ private final boolean success;
-+
-+ public BeeStopPollinatingEvent(@NotNull Bee bee, @Nullable Location location, boolean success) {
-+ super(bee);
-+ this.location = location;
-+ this.success = success;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Bee getEntity() {
-+ return (Bee) super.getEntity();
-+ }
-+
-+ /**
-+ * Returns the location of the flower that the bee stopped pollinating
-+ *
-+ * @return The location of the flower
-+ */
-+ @Nullable
-+ public Location getLocation() {
-+ return location;
-+ }
-+
-+ /**
-+ * Returns whether the bee successfully pollinated the flower
-+ *
-+ * @return True if the pollination was successful
-+ */
-+ public boolean wasSuccessful() {
-+ return success;
-+ }
-+
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0045-Debug-Marker-API.patch b/patches/api/0045-Debug-Marker-API.patch
deleted file mode 100644
index f5194ac9e..000000000
--- a/patches/api/0045-Debug-Marker-API.patch
+++ /dev/null
@@ -1,341 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: YouHaveTrouble
-Date: Sat, 23 Jul 2022 14:40:17 +0200
-Subject: [PATCH] Debug Marker API
-
-
-diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
-index 222dcb75a850d224ac22b2e06895233527cffc76..584e3b08935f43beb27f478cc72229b6a5f40689 100644
---- a/src/main/java/org/bukkit/Bukkit.java
-+++ b/src/main/java/org/bukkit/Bukkit.java
-@@ -2794,5 +2794,89 @@ public final class Bukkit {
- public static void removeFuel(@NotNull Material material) {
- server.removeFuel(material);
- }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration) {
-+ server.sendBlockHighlight(location, duration);
-+ }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration, int argb) {
-+ server.sendBlockHighlight(location, duration, argb);
-+ }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text) {
-+ server.sendBlockHighlight(location, duration, text);
-+ }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb) {
-+ server.sendBlockHighlight(location, duration, text, argb);
-+ }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration, @NotNull org.bukkit.Color color, int transparency) {
-+ server.sendBlockHighlight(location, duration, color, transparency);
-+ }
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ public static void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, @NotNull org.bukkit.Color color, int transparency) {
-+ server.sendBlockHighlight(location, duration, text, color, transparency);
-+ }
-+
-+ /**
-+ * Clears all debug block highlights for all players on the server.
-+ */
-+ public static void clearBlockHighlights() {
-+ server.clearBlockHighlights();
-+ }
- // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index 3bc9fa8b68b284516ddbf0ace0c1dc52768307cb..aaef58468a3c31f35e5067ed4263e9dd3fbddddd 100644
---- a/src/main/java/org/bukkit/Server.java
-+++ b/src/main/java/org/bukkit/Server.java
-@@ -2446,5 +2446,75 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
- * @param material The material that will no longer be a fuel
- */
- public void removeFuel(@NotNull Material material);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on the server.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Clears all debug block highlights for all players on the server.
-+ */
-+ void clearBlockHighlights();
- // Purpur end
- }
-diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
-index 1fba792419ea6b5e8c640a2599e4b2dd16ee87d0..bf39c6602cfca70a6352519fa26059cd79143cdd 100644
---- a/src/main/java/org/bukkit/World.java
-+++ b/src/main/java/org/bukkit/World.java
-@@ -4000,6 +4000,76 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
- * @return The local difficulty
- */
- public float getLocalDifficultyAt(@NotNull Location location);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to all players on this world.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Clears all debug block highlights for all players on this world.
-+ */
-+ void clearBlockHighlights();
- // Purpur end
-
- /**
-diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index 1994acf66919c92f59e2a9f2f873f50b73d76d1a..b1a5baf12343f5db11ef58666bf6393b008c7dcf 100644
---- a/src/main/java/org/bukkit/entity/Player.java
-+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3319,5 +3319,75 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
- * @param invulnerableTicks Invulnerable ticks remaining
- */
- void setSpawnInvulnerableTicks(int invulnerableTicks);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param argb Color of the highlight. ARGB int. Will be ignored on some versions of vanilla client
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, int argb);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Creates debug block highlight on specified block location and show it to this player.
-+ *
-+ * Clients may be inconsistent in displaying it.
-+ * @param location Location to highlight
-+ * @param duration Duration for highlight to show in milliseconds
-+ * @param text Text to show above the highlight
-+ * @param color Color of the highlight. Will be ignored on some versions of vanilla client
-+ * @param transparency Transparency of the highlight
-+ * @throws IllegalArgumentException If transparency is outside 0-255 range
-+ */
-+ void sendBlockHighlight(@NotNull Location location, int duration, @NotNull String text, @NotNull org.bukkit.Color color, int transparency);
-+
-+ /**
-+ * Clears all debug block highlights
-+ */
-+ void clearBlockHighlights();
- // Purpur end
- }
diff --git a/patches/api/0046-Add-death-screen-API.patch b/patches/api/0046-Add-death-screen-API.patch
deleted file mode 100644
index 1256eaa99..000000000
--- a/patches/api/0046-Add-death-screen-API.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: MelnCat
-Date: Fri, 23 Sep 2022 18:35:28 -0700
-Subject: [PATCH] Add death screen API
-
-
-diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
-index b1a5baf12343f5db11ef58666bf6393b008c7dcf..9193288438671409cc3cf92033ef7cb60d798b69 100644
---- a/src/main/java/org/bukkit/entity/Player.java
-+++ b/src/main/java/org/bukkit/entity/Player.java
-@@ -3389,5 +3389,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
- * Clears all debug block highlights
- */
- void clearBlockHighlights();
-+
-+ /**
-+ * Sends a player the death screen with a specified death message.
-+ *
-+ * @param message The death message to show the player
-+ */
-+ void sendDeathScreen(@NotNull net.kyori.adventure.text.Component message);
-+
-+ /**
-+ * Sends a player the death screen with a specified death message,
-+ * along with the entity that caused the death.
-+ *
-+ * @param message The death message to show the player
-+ * @param killer The entity that killed the player
-+ * @deprecated Use {@link #sendDeathScreen(net.kyori.adventure.text.Component)} instead, as 1.20 removed the killer ID from the packet.
-+ */
-+ @Deprecated(since = "1.20")
-+ default void sendDeathScreen(@NotNull net.kyori.adventure.text.Component message, @Nullable Entity killer) {
-+ sendDeathScreen(message);
-+ }
- // Purpur end
- }
diff --git a/patches/api/0048-Language-API.patch b/patches/api/0048-Language-API.patch
deleted file mode 100644
index 1fbe2ebee..000000000
--- a/patches/api/0048-Language-API.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: MelnCat
-Date: Sat, 1 Oct 2022 17:08:23 -0700
-Subject: [PATCH] Language API
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/language/Language.java b/src/main/java/org/purpurmc/purpur/language/Language.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..38483d908ed830e97883733bee2370f87060f4c7
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/language/Language.java
-@@ -0,0 +1,60 @@
-+package org.purpurmc.purpur.language;
-+
-+import net.kyori.adventure.translation.Translatable;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Represents a language that can translate translation keys
-+ */
-+public abstract class Language {
-+ private static Language language;
-+
-+ /**
-+ * Returns the default language of the server
-+ */
-+ @NotNull
-+ public static Language getLanguage() {
-+ return language;
-+ }
-+
-+ public static void setLanguage(@NotNull Language language) {
-+ if (Language.language != null) {
-+ throw new UnsupportedOperationException("Cannot redefine singleton Language");
-+ }
-+ Language.language = language;
-+ }
-+
-+ /**
-+ * Checks if a certain translation key is translatable with this language
-+ * @param key The translation key
-+ * @return Whether this language can translate the key
-+ */
-+ abstract public boolean has(@NotNull String key);
-+
-+ /**
-+ * Checks if a certain translation key is translatable with this language
-+ * @param key The translation key
-+ * @return Whether this language can translate the key
-+ */
-+ public boolean has(@NotNull Translatable key) {
-+ return has(key.translationKey());
-+ }
-+
-+ /**
-+ * Translates a translation key to this language
-+ * @param key The translation key
-+ * @return The translated key, or the translation key if it couldn't be translated
-+ */
-+ @NotNull
-+ abstract public String getOrDefault(@NotNull String key);
-+
-+ /**
-+ * Translates a translation key to this language
-+ * @param key The translation key
-+ * @return The translated key, or the translation key if it couldn't be translated
-+ */
-+ @NotNull
-+ public String getOrDefault(@NotNull Translatable key) {
-+ return getOrDefault(key.translationKey());
-+ }
-+}
diff --git a/patches/api/0049-Add-log-suppression-for-LibraryLoader.patch b/patches/api/0049-Add-log-suppression-for-LibraryLoader.patch
deleted file mode 100644
index 95e4cd2ac..000000000
--- a/patches/api/0049-Add-log-suppression-for-LibraryLoader.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Krakenied
-Date: Fri, 14 Oct 2022 23:11:27 +0200
-Subject: [PATCH] Add log suppression for LibraryLoader
-
-
-diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
-index 301e82369603f3dd6e6c1bd380da4bacacd7ef6c..0c6ca7588fb3d6b6497ddf032fe75e5c6c9719e5 100644
---- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
-+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
-@@ -55,6 +55,7 @@ public final class JavaPluginLoader implements PluginLoader {
- private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$")};
- private final List loaders = new CopyOnWriteArrayList();
- private final LibraryLoader libraryLoader;
-+ public static boolean SuppressLibraryLoaderLogger = false; // Purpur
-
- /**
- * This class was not meant to be constructed explicitly
-diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-index e4b6f278a811acbb0070e311c5c3bdaff7b00474..ee83ecb054099cb85168a9499dfe967a0a9ec796 100644
---- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-@@ -65,6 +65,7 @@ public class LibraryLoader
- @Override
- public void transferStarted(@NotNull TransferEvent event) throws TransferCancelledException
- {
-+ if (!JavaPluginLoader.SuppressLibraryLoaderLogger) // Purpur
- logger.log( Level.INFO, "Downloading {0}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
- }
- } );
-@@ -80,6 +81,7 @@ public class LibraryLoader
- {
- return null;
- }
-+ if (!JavaPluginLoader.SuppressLibraryLoaderLogger) // Purpur
- logger.log( Level.INFO, "[{0}] Loading {1} libraries... please wait", new Object[]
- {
- java.util.Objects.requireNonNullElseGet(desc.getPrefix(), desc::getName), desc.getLibraries().size() // Paper - use configured log prefix
-@@ -118,6 +120,7 @@ public class LibraryLoader
- }
-
- jarFiles.add( url );
-+ if (!JavaPluginLoader.SuppressLibraryLoaderLogger) // Purpur
- logger.log( Level.INFO, "[{0}] Loaded library {1}", new Object[]
- {
- java.util.Objects.requireNonNullElseGet(desc.getPrefix(), desc::getName), file // Paper - use configured log prefix
diff --git a/patches/api/0050-Fire-Immunity-API.patch b/patches/api/0050-Fire-Immunity-API.patch
deleted file mode 100644
index e5622d4ca..000000000
--- a/patches/api/0050-Fire-Immunity-API.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Racci <90304606+DaRacci@users.noreply.github.com>
-Date: Fri, 4 Feb 2022 16:09:47 +1100
-Subject: [PATCH] Fire Immunity API
-
-
-diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
-index 52867495d0f746ff40e802c4f1018511e58fd03e..98de85d1382fe84cdc2e2c9db04bf1b4f157291c 100644
---- a/src/main/java/org/bukkit/entity/Entity.java
-+++ b/src/main/java/org/bukkit/entity/Entity.java
-@@ -1086,5 +1086,18 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
- * @return True if in daylight
- */
- boolean isInDaylight();
-+
-+ /**
-+ * Checks if the entity is fire immune
-+ *
-+ * @return True if fire immune
-+ */
-+ boolean isImmuneToFire();
-+
-+ /**
-+ * Sets if the entity is fire immune
-+ * Set this to null to restore the entity type default
-+ */
-+ void setImmuneToFire(@Nullable Boolean fireImmune);
- // Purpur end
- }
diff --git a/patches/api/0051-Added-goat-ram-event.patch b/patches/api/0051-Added-goat-ram-event.patch
deleted file mode 100644
index 7665c860d..000000000
--- a/patches/api/0051-Added-goat-ram-event.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: SageSphinx63920
-Date: Sat, 29 Oct 2022 00:06:05 +0200
-Subject: [PATCH] Added goat ram event
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..f62c14f3d4999e9112c1c73642aa337d97b94b5a
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/GoatRamEntityEvent.java
-@@ -0,0 +1,59 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.entity.Goat;
-+import org.bukkit.entity.LivingEntity;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityEvent;
-+import org.jetbrains.annotations.NotNull;
-+
-+/**
-+ * Called when a goat rams an entity
-+ */
-+public class GoatRamEntityEvent extends EntityEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private final LivingEntity rammedEntity;
-+ private boolean cancelled;
-+
-+ public GoatRamEntityEvent(@NotNull Goat goat, @NotNull LivingEntity rammedEntity) {
-+ super(goat);
-+ this.rammedEntity = rammedEntity;
-+ }
-+
-+ /**
-+ * Returns the entity that was rammed by the goat
-+ *
-+ * @return The rammed entity
-+ */
-+ @NotNull
-+ public LivingEntity getRammedEntity() {
-+ return this.rammedEntity;
-+ }
-+
-+ @Override
-+ @NotNull
-+ public Goat getEntity() {
-+ return (Goat) super.getEntity();
-+ }
-+
-+ @Override
-+ @NotNull
-+ public HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return this.cancelled;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancelled = cancel;
-+ }
-+}
diff --git a/patches/api/0052-Add-PreExplodeEvents.patch b/patches/api/0052-Add-PreExplodeEvents.patch
deleted file mode 100644
index 5ba7e435d..000000000
--- a/patches/api/0052-Add-PreExplodeEvents.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: SageSphinx63920
-Date: Mon, 26 Dec 2022 23:40:13 +0100
-Subject: [PATCH] Add PreExplodeEvents
-
-
-diff --git a/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..32602b398ede24a35ed8a996faa2b23455615a7b
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/PreBlockExplodeEvent.java
-@@ -0,0 +1,54 @@
-+package org.purpurmc.purpur.event;
-+
-+import org.bukkit.block.Block;
-+import org.bukkit.block.BlockState;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.block.BlockExplodeEvent;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+import java.util.Collections;
-+
-+/**
-+ * Called before a block's explosion is processed
-+ */
-+public class PreBlockExplodeEvent extends BlockExplodeEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private boolean cancelled;
-+ private final float yield;
-+
-+ public PreBlockExplodeEvent(@NotNull final Block what, final float yield, @Nullable BlockState explodedBlockState) {
-+ super(what, Collections.emptyList(), yield, explodedBlockState);
-+ this.yield = yield;
-+ this.cancelled = false;
-+ }
-+
-+ /**
-+ * Returns the percentage of blocks to drop from this explosion
-+ *
-+ * @return The yield.
-+ */
-+ public float getYield() {
-+ return yield;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return this.cancelled;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancelled = cancel;
-+ }
-+
-+ @Override
-+ public @NotNull HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
-diff --git a/src/main/java/org/purpurmc/purpur/event/entity/PreEntityExplodeEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/PreEntityExplodeEvent.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..2d4f68228861492baaea0bcc604dfef623b337ba
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/event/entity/PreEntityExplodeEvent.java
-@@ -0,0 +1,64 @@
-+package org.purpurmc.purpur.event.entity;
-+
-+import org.bukkit.Location;
-+import org.bukkit.event.Cancellable;
-+import org.bukkit.event.HandlerList;
-+import org.bukkit.event.entity.EntityExplodeEvent;
-+import org.jetbrains.annotations.NotNull;
-+import java.util.Collections;
-+
-+/**
-+ * Called before an entity's explosion is processed
-+ */
-+public class PreEntityExplodeEvent extends EntityExplodeEvent implements Cancellable {
-+ private static final HandlerList handlers = new HandlerList();
-+ private boolean cancelled;
-+ private final float yield;
-+ private final Location location;
-+
-+ public PreEntityExplodeEvent(@NotNull org.bukkit.entity.Entity what, @NotNull final Location location, final float yield) {
-+ super(what, location, Collections.emptyList(), yield);
-+ this.cancelled = false;
-+ this.yield = yield;
-+ this.location = location;
-+ }
-+
-+ /**
-+ * Returns the percentage of blocks to drop from this explosion
-+ *
-+ * @return The yield.
-+ */
-+ public float getYield() {
-+ return yield;
-+ }
-+
-+ /**
-+ * Returns the location where the explosion happened.
-+ *
-+ * @return The location of the explosion
-+ */
-+ @NotNull
-+ public Location getLocation() {
-+ return location;
-+ }
-+
-+ @Override
-+ public boolean isCancelled() {
-+ return this.cancelled;
-+ }
-+
-+ @Override
-+ public void setCancelled(boolean cancel) {
-+ this.cancelled = cancel;
-+ }
-+
-+ @Override
-+ public @NotNull HandlerList getHandlers() {
-+ return handlers;
-+ }
-+
-+ @NotNull
-+ public static HandlerList getHandlerList() {
-+ return handlers;
-+ }
-+}
diff --git a/patches/api/0053-Stored-Bee-API.patch b/patches/api/0053-Stored-Bee-API.patch
deleted file mode 100644
index e155a6a0f..000000000
--- a/patches/api/0053-Stored-Bee-API.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: EOT3000
-Date: Sat, 10 Jun 2023 20:27:14 -0400
-Subject: [PATCH] Stored Bee API
-
-
-diff --git a/src/main/java/org/bukkit/block/EntityBlockStorage.java b/src/main/java/org/bukkit/block/EntityBlockStorage.java
-index 739911cda33b373f99df627a3a378b37d7d461aa..51e78c22cd021722b963fe31d1d9175d141add1a 100644
---- a/src/main/java/org/bukkit/block/EntityBlockStorage.java
-+++ b/src/main/java/org/bukkit/block/EntityBlockStorage.java
-@@ -47,6 +47,24 @@ public interface EntityBlockStorage extends TileState {
- @NotNull
- List releaseEntities();
-
-+ // Purpur start
-+ /**
-+ * Releases a stored entity, and returns the entity in the world.
-+ *
-+ * @param entity Entity to release
-+ * @return The entity which was released, or null if the stored entity is not in the hive
-+ */
-+ @org.jetbrains.annotations.Nullable
-+ T releaseEntity(@NotNull org.purpurmc.purpur.entity.StoredEntity entity);
-+
-+ /**
-+ * Gets all the entities currently stored in the block.
-+ *
-+ * @return List of all entities which are stored in the block
-+ */
-+ @NotNull
-+ List> getEntities();
-+ //Purpur end
- /**
- * Add an entity to the block.
- *
-diff --git a/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java b/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..29540d55532197d2381a52ea9222b5785d224ef8
---- /dev/null
-+++ b/src/main/java/org/purpurmc/purpur/entity/StoredEntity.java
-@@ -0,0 +1,52 @@
-+package org.purpurmc.purpur.entity;
-+
-+import org.bukkit.Nameable;
-+import org.bukkit.block.EntityBlockStorage;
-+import org.bukkit.entity.Entity;
-+import org.bukkit.entity.EntityType;
-+import org.bukkit.persistence.PersistentDataHolder;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
-+
-+/**
-+ * Represents an entity stored in a block
-+ *
-+ * @see org.bukkit.block.EntityBlockStorage
-+ */
-+public interface StoredEntity extends PersistentDataHolder, Nameable {
-+ /**
-+ * Checks if this entity has been released yet
-+ *
-+ * @return if this entity has been released
-+ */
-+ boolean hasBeenReleased();
-+
-+ /**
-+ * Releases the entity from its stored block
-+ *
-+ * @return the released entity, or null if unsuccessful (including if this entity has already been released)
-+ */
-+ @Nullable
-+ T release();
-+
-+ /**
-+ * Returns the block in which this entity is stored
-+ *
-+ * @return the EntityBlockStorage in which this entity is stored, or null if it has been released
-+ */
-+ @Nullable
-+ EntityBlockStorage getBlockStorage();
-+
-+ /**
-+ * Gets the entity type of this stored entity
-+ *
-+ * @return the type of entity this stored entity represents
-+ */
-+ @NotNull
-+ EntityType getType();
-+
-+ /**
-+ * Writes data to the block entity snapshot. {@link EntityBlockStorage#update()} must be run in order to update the block in game.
-+ */
-+ void update();
-+}
diff --git a/patches/api/0054-Explorer-Map-API.patch b/patches/api/0054-Explorer-Map-API.patch
deleted file mode 100644
index 91241d8f1..000000000
--- a/patches/api/0054-Explorer-Map-API.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: William Blake Galbreath
-Date: Wed, 5 Jul 2023 12:48:08 -0500
-Subject: [PATCH] Explorer Map API
-
-
-diff --git a/src/main/java/org/bukkit/map/MapRenderer.java b/src/main/java/org/bukkit/map/MapRenderer.java
-index cb7040876a99a5a7e49b81684ef0f3b79584c376..22d8f31b1b8a5dbb5ab3275068642937c097abfe 100644
---- a/src/main/java/org/bukkit/map/MapRenderer.java
-+++ b/src/main/java/org/bukkit/map/MapRenderer.java
-@@ -54,4 +54,12 @@ public abstract class MapRenderer {
- */
- public abstract void render(@NotNull MapView map, @NotNull MapCanvas canvas, @NotNull Player player);
-
-+ // Purpur - start
-+ /**
-+ * Check if this is an explorer (aka treasure) map.
-+ *
-+ * @return True if explorer map
-+ */
-+ public abstract boolean isExplorerMap();
-+ // Purpur - end
- }
diff --git a/patches/server/0001-Pufferfish-Server-Changes.patch b/patches/server/0001-Pufferfish-Server-Changes.patch
deleted file mode 100644
index 176573ded..000000000
--- a/patches/server/0001-Pufferfish-Server-Changes.patch
+++ /dev/null
@@ -1,3628 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Kevin Raneri
-Date: Wed, 3 Feb 2021 23:02:38 -0600
-Subject: [PATCH] Pufferfish Server Changes
-
-Pufferfish
-Copyright (C) 2022 Pufferfish Studios LLC
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-diff --git a/build.gradle.kts b/build.gradle.kts
-index fb98936bb8a5488db75d676c5bcb4060597fbbf8..f6cd7b910ce41a254e71bf0fcfe93c38abbb1445 100644
---- a/build.gradle.kts
-+++ b/build.gradle.kts
-@@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
- val alsoShade: Configuration by configurations.creating
-
- dependencies {
-- implementation(project(":paper-api"))
-- implementation(project(":paper-mojangapi"))
-+ implementation(project(":pufferfish-api")) // Pufferfish // Paper
-+ // Pufferfish start
-+ implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") {
-+ exclude("io.papermc.paper", "paper-api")
-+ }
-+ // Pufferfish end
- // Paper start
- implementation("org.jline:jline-terminal-jansi:3.21.0")
- implementation("net.minecrell:terminalconsoleappender:1.3.0")
-@@ -52,6 +56,13 @@ dependencies {
- runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.3")
- runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.3")
-
-+ // Pufferfish start
-+ implementation("org.yaml:snakeyaml:1.32")
-+ implementation ("com.github.carleslc.Simple-YAML:Simple-Yaml:1.8.4") {
-+ exclude(group="org.yaml", module="snakeyaml")
-+ }
-+ // Pufferfish end
-+
- testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test
- testImplementation("junit:junit:4.13.2")
- testImplementation("org.hamcrest:hamcrest-library:1.3")
-@@ -60,6 +71,14 @@ dependencies {
- }
-
- val craftbukkitPackageVersion = "1_20_R1" // Paper
-+
-+// Pufferfish Start
-+tasks.withType {
-+ val compilerArgs = options.compilerArgs
-+ compilerArgs.add("--add-modules=jdk.incubator.vector")
-+}
-+// Pufferfish End
-+
- tasks.jar {
- archiveClassifier.set("dev")
-
-@@ -72,7 +91,7 @@ tasks.jar {
- attributes(
- "Main-Class" to "org.bukkit.craftbukkit.Main",
- "Implementation-Title" to "CraftBukkit",
-- "Implementation-Version" to "git-Paper-$implementationVersion",
-+ "Implementation-Version" to "git-Pufferfish-$implementationVersion", // Pufferfish
- "Implementation-Vendor" to date, // Paper
- "Specification-Title" to "Bukkit",
- "Specification-Version" to project.version,
-diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
-index a2f71a6d1a9e98133dff6cd0f625da9435a8af14..ff940e43ca35094bbcae6c7d471d3c4aeb7c1727 100644
---- a/src/main/java/co/aikar/timings/TimingsExport.java
-+++ b/src/main/java/co/aikar/timings/TimingsExport.java
-@@ -242,7 +242,8 @@ public class TimingsExport extends Thread {
- parent.put("config", createObject(
- pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
- pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
-- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null))
-+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Pufferfish
-+ pair("pufferfish", mapAsJSON(gg.pufferfish.pufferfish.PufferfishConfig.getConfigCopy(), null)) // Pufferfish
- ));
-
- new TimingsExport(listeners, parent, history).start();
-diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
-index 4b002e8b75d117b726b0de274a76d3596fce015b..692c962193cf9fcc6801fc93f3220bdc673d527b 100644
---- a/src/main/java/com/destroystokyo/paper/Metrics.java
-+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
-@@ -593,7 +593,7 @@ public class Metrics {
- boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
- // Only start Metrics, if it's enabled in the config
- if (config.getBoolean("enabled", true)) {
-- Metrics metrics = new Metrics("Paper", serverUUID, logFailedRequests, Bukkit.getLogger());
-+ Metrics metrics = new Metrics("Pufferfish", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish
-
- metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
- String minecraftVersion = Bukkit.getVersion();
-@@ -607,11 +607,11 @@ public class Metrics {
- final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion();
- if (implVersion != null) {
- final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1);
-- paperVersion = "git-Paper-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash);
-+ paperVersion = "git-Pufferfish-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Pufferfish
- } else {
- paperVersion = "unknown";
- }
-- metrics.addCustomChart(new Metrics.SimplePie("paper_version", () -> paperVersion));
-+ metrics.addCustomChart(new Metrics.SimplePie("pufferfish_version", () -> paperVersion)); // Pufferfish
-
- metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
- Map> map = new HashMap<>();
-diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
-index 41b9405d6759d865e0d14dd4f95163e9690e967d..091b1ae822e1c0517e59572e7a9bda11e998c0ee 100644
---- a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
-+++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
-@@ -26,7 +26,7 @@ public abstract class AreaMap {
-
- // we use linked for better iteration.
- // map of: coordinate to set of objects in coordinate
-- protected final Long2ObjectOpenHashMap> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f);
-+ protected Long2ObjectOpenHashMap> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f); // Pufferfish - not actually final
- protected final PooledLinkedHashSets pooledHashSets;
-
- protected final ChangeCallback