diff --git a/patches/api/0003-Rework-Spigot-Deprecations.patch b/patches/api/0003-Rework-Spigot-Deprecations.patch
new file mode 100644
index 0000000..ce445c9
--- /dev/null
+++ b/patches/api/0003-Rework-Spigot-Deprecations.patch
@@ -0,0 +1,84 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
+Date: Fri, 31 Mar 2023 23:38:43 +0300
+Subject: [PATCH] Rework Spigot Deprecations
+
+
+diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
+index 3578ab0c3a413d56bc39af43b5d3201d20d7d13a..29ac48445c3b6d14b1b549d856c350df6712ccac 100644
+--- a/src/main/java/org/bukkit/OfflinePlayer.java
++++ b/src/main/java/org/bukkit/OfflinePlayer.java
+@@ -160,9 +160,11 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
+ * UTC.
+ *
+ * @return Date of last log-in for this player, or 0
+- * @deprecated The API contract is ambiguous and the implementation may or may not return the correct value given this API ambiguity. It is instead recommended use {@link #getLastLogin()} or {@link #getLastSeen()} depending on your needs.
++ * @see #hasPlayedBefore()
++ * @see #getLastLogin()
++ * @see #getLastSeen()
+ */
+- @Deprecated
++ // @Deprecated // DivineMC - remove deprecated
+ public long getLastPlayed();
+
+ /**
+diff --git a/src/main/java/org/bukkit/entity/Damageable.java b/src/main/java/org/bukkit/entity/Damageable.java
+index fc4d3bcd9b16097086fef7975274d825b65adb10..e485975dbb6973d2b21259c4e4d5d75191bacb60 100644
+--- a/src/main/java/org/bukkit/entity/Damageable.java
++++ b/src/main/java/org/bukkit/entity/Damageable.java
+@@ -60,9 +60,9 @@ public interface Damageable extends Entity {
+ * Gets the maximum health this entity has.
+ *
+ * @return Maximum health
+- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
++ * @see Attribute#GENERIC_MAX_HEALTH
+ */
+- @Deprecated
++ // @Deprecated // DivineMC
+ double getMaxHealth();
+
+ /**
+@@ -75,15 +75,15 @@ public interface Damageable extends Entity {
+ * {@link Wither}, etc...} will have their bar scaled accordingly.
+ *
+ * @param health amount of health to set the maximum to
+- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
++ * @see Attribute#GENERIC_MAX_HEALTH
+ */
+- @Deprecated
++ // @Deprecated // DivineMC
+ void setMaxHealth(double health);
+
+ /**
+ * Resets the max health to the original amount.
+- * @deprecated use {@link Attribute#GENERIC_MAX_HEALTH}.
++ * @see Attribute#GENERIC_MAX_HEALTH
+ */
+- @Deprecated
++ // @Deprecated // DivineMC
+ void resetMaxHealth();
+ }
+diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
+index 85c5987758b1d5145843705205dc99164c5f9f44..f427855ba2bdf8211a3b8b41129c22bf24a31bfb 100644
+--- a/src/main/java/org/bukkit/entity/Player.java
++++ b/src/main/java/org/bukkit/entity/Player.java
+@@ -278,14 +278,15 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
+ * Returns true if the entity is supported by a block.
+ *
+ * This value is a state updated by the client after each movement.
+- *
+- * @return True if entity is on ground.
+- * @deprecated This value is controlled only by the client and is therefore
++ *
++ * Note: This value is controlled only by the client and is therefore
+ * unreliable and vulnerable to spoofing and/or desync depending on the
+ * context/time which it is accessed
++ *
++ * @return True if entity is on ground.
+ */
+ @Override
+- @Deprecated
++ // @Deprecated // DivineMC
+ public boolean isOnGround();
+
+ /**
diff --git a/patches/api/0004-Paper-PR-Add-Movement-Direction-API.patch b/patches/api/0004-Paper-PR-Add-Movement-Direction-API.patch
new file mode 100644
index 0000000..dcf6228
--- /dev/null
+++ b/patches/api/0004-Paper-PR-Add-Movement-Direction-API.patch
@@ -0,0 +1,55 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
+Date: Sat, 11 Dec 2021 12:18:47 -0500
+Subject: [PATCH] Paper PR - Add Movement Direction API
+
+
+diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
+index 654dc0c6d98b29cf45d3826aece374726e3e9802..a1dfe9e1509a1b852e991e29c720fdfad596a2f8 100644
+--- a/src/main/java/org/bukkit/entity/LivingEntity.java
++++ b/src/main/java/org/bukkit/entity/LivingEntity.java
+@@ -1149,6 +1149,44 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
+ * @see Location#setYaw(float)
+ */
+ void setBodyYaw(float bodyYaw);
++
++ /**
++ * This number represents how much the entity is trying to move sideways.
++ *
++ * This number is ranges from -1 to 1,
++ * where positive 1 represents the left and -1 represents the right.
++ *
++ * Note that for {@link Player} entities only update this value when riding an entity, which may cause it
++ * to be inaccurate when dismounted.
++ *
++ * @return direction repesented as -1 to 1
++ */
++ float getSidewaysMotion();
++
++ /**
++ * This number represents how much the entity is trying to move
++ * in the upwards direction.
++ *
++ * This number is ranges from -1 to 1,
++ * where positive 1 represents the up and -1 represents the down.
++ *
++ * Note that for {@link Player} entities this value is never updated.
++ *
++ * @return direction repesented as -1 to 1
++ */
++ float getUpwardsMotion();
++
++ /**
++ * This number represents how much the entity is trying to move forward.
++ *
++ * This number is ranges from -1 to 1,
++ * where positive 1 represents the up and -1 represents the down.
++ *
++ * Note that for {@link Player} entities only update this value when riding an entity, so it may be inaccurate when dismounted.
++ *
++ * @return direction repesented as -1 to 1
++ */
++ float getForwardMotion();
+ // Paper end
+
+ // Purpur start
diff --git a/patches/api/0005-Paper-PR-BoneMeal-API.patch b/patches/api/0005-Paper-PR-BoneMeal-API.patch
new file mode 100644
index 0000000..d8f6caf
--- /dev/null
+++ b/patches/api/0005-Paper-PR-BoneMeal-API.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
+Date: Sun, 17 Oct 2021 14:53:28 -0400
+Subject: [PATCH] Paper PR - BoneMeal API
+
+
+diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
+index ad00e30379df52575bf2697ccb32abb176ecd47a..75f511532953d5074b22ef938874c65983a992e5 100644
+--- a/src/main/java/org/bukkit/World.java
++++ b/src/main/java/org/bukkit/World.java
+@@ -4146,4 +4146,20 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
+ }
+ }
+ }
++
++ // Paper start
++ /**
++ * Applies bonemeal at a specific location
++ *
++ * Modifications done in the predicate are respected
++ * and will not be applied if false is returned.
++ *
++ * @param location Location to apply
++ * @param face Blockface to apply as
++ * @param showParticles If particles should be shown on success
++ * @param predicate blockstate predicate
++ * @return true if the bonemeal was applied, false if not
++ */
++ boolean applyBoneMeal(@NotNull Location location, @NotNull org.bukkit.block.BlockFace face, boolean showParticles, @Nullable Predicate predicate);
++ // Paper end
+ }
diff --git a/patches/api/0006-Paper-PR-Add-sendTitleUpdate-for-inventories.patch b/patches/api/0006-Paper-PR-Add-sendTitleUpdate-for-inventories.patch
new file mode 100644
index 0000000..3cbd11c
--- /dev/null
+++ b/patches/api/0006-Paper-PR-Add-sendTitleUpdate-for-inventories.patch
@@ -0,0 +1,27 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: nopjar
+Date: Mon, 13 Jun 2022 11:29:42 +0200
+Subject: [PATCH] Paper PR - Add sendTitleUpdate for inventories
+
+
+diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java
+index daca40b63e95ea33178bcb54ad45911da591ca54..957e2d091e40ecc283343b7b07b813406d75e852 100644
+--- a/src/main/java/org/bukkit/inventory/InventoryView.java
++++ b/src/main/java/org/bukkit/inventory/InventoryView.java
+@@ -468,4 +468,16 @@ public abstract class InventoryView {
+ @Deprecated // Paper
+ @NotNull
+ public abstract String getTitle();
++
++ // Paper start
++ /**
++ * Sends a packet to the client to open a new inventory with the new title.
++ *
++ * The ID of the inventory and the contents stay the same. This does not affect the title on the
++ * server. Methods like {@link #title()} will still return the old title.
++ *
++ * @param title the new title
++ */
++ public abstract void sendTitleUpdate(@NotNull net.kyori.adventure.text.Component title);
++ // Paper end
+ }
diff --git a/patches/api/0007-Additional-pathfinding-API.patch b/patches/api/0007-Additional-pathfinding-API.patch
new file mode 100644
index 0000000..48f6e5c
--- /dev/null
+++ b/patches/api/0007-Additional-pathfinding-API.patch
@@ -0,0 +1,25 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
+Date: Sat, 1 Apr 2023 00:31:15 +0300
+Subject: [PATCH] Additional pathfinding API
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
+index 43f062257472a06e9e64c2feef6c3b1012aee00e..d3f12a2edeb5c0c548cfa1a13e93dbd1774b83a3 100644
+--- a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
++++ b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
+@@ -208,5 +208,14 @@ public interface Pathfinder {
+ * @return The closest point the path can get to the target location
+ */
+ @Nullable Location getFinalPoint();
++
++ // DivineMC start
++ /**
++ * Checks whether the final point if this path can be reached
++ *
++ * @return whether the final point if this path can be reached
++ */
++ boolean canReachFinalPoint();
++ // DivineMC end
+ }
+ }
diff --git a/patches/server/0015-Paper-PR-Add-Movement-Direction-API.patch b/patches/server/0015-Paper-PR-Add-Movement-Direction-API.patch
new file mode 100644
index 0000000..10befff
--- /dev/null
+++ b/patches/server/0015-Paper-PR-Add-Movement-Direction-API.patch
@@ -0,0 +1,35 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
+Date: Sat, 11 Dec 2021 12:18:42 -0500
+Subject: [PATCH] Paper PR - Add Movement Direction API
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+index cf7ba8724ab68f6955b5ebfa1ba46c4397da32b3..1a5fe70616873ab2fc3f60b788e6315d1156562d 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+@@ -979,6 +979,24 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
+ throw new UnsupportedOperationException("Cannot set the hurt direction on a non player");
+ }
+
++ // Paper start - Movement Direction API
++ @Override
++ public float getSidewaysMotion() {
++ return this.getHandle().xxa;
++ }
++
++ @Override
++ public float getUpwardsMotion() {
++ return this.getHandle().yya;
++ }
++
++ @Override
++ public float getForwardMotion() {
++ return this.getHandle().zza;
++ }
++ // Paper end - Movement Direction API
++
++
+ public static MobType fromBukkitEntityCategory(EntityCategory entityCategory) {
+ switch (entityCategory) {
+ case NONE:
diff --git a/patches/server/0016-Paper-PR-BoneMeal-API.patch b/patches/server/0016-Paper-PR-BoneMeal-API.patch
new file mode 100644
index 0000000..b560c34
--- /dev/null
+++ b/patches/server/0016-Paper-PR-BoneMeal-API.patch
@@ -0,0 +1,87 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
+Date: Sun, 17 Oct 2021 14:53:35 -0400
+Subject: [PATCH] Paper PR - BoneMeal API
+
+
+diff --git a/src/main/java/net/minecraft/world/item/BoneMealItem.java b/src/main/java/net/minecraft/world/item/BoneMealItem.java
+index c26665bc59c18c4da467fb6ae33e51a65ecf1de6..bf65490f0239fc6d9d9c101ebce5845dd278ee48 100644
+--- a/src/main/java/net/minecraft/world/item/BoneMealItem.java
++++ b/src/main/java/net/minecraft/world/item/BoneMealItem.java
+@@ -37,14 +37,16 @@ public class BoneMealItem extends Item {
+ return BoneMealItem.applyBonemeal(context);
+ }
+
+- public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) {
+- // CraftBukkit end
++ // Paper start - BoneMeal API
++ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) { return applyBonemeal(itemactioncontext, true); }
++ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext, boolean showParticles) {
++ // Paper end - BoneMeal API
+ Level world = itemactioncontext.getLevel();
+ BlockPos blockposition = itemactioncontext.getClickedPos();
+ BlockPos blockposition1 = blockposition.relative(itemactioncontext.getClickedFace());
+
+ if (BoneMealItem.growCrop(itemactioncontext.getItemInHand(), world, blockposition)) {
+- if (!world.isClientSide) {
++ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
+ world.levelEvent(1505, blockposition, 0);
+ }
+
+@@ -54,7 +56,7 @@ public class BoneMealItem extends Item {
+ boolean flag = iblockdata.isFaceSturdy(world, blockposition, itemactioncontext.getClickedFace());
+
+ if (flag && BoneMealItem.growWaterPlant(itemactioncontext.getItemInHand(), world, blockposition1, itemactioncontext.getClickedFace())) {
+- if (!world.isClientSide) {
++ if (showParticles && !world.isClientSide) { // Paper - BoneMeal API
+ world.levelEvent(1505, blockposition1, 0);
+ }
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index c6a3b59c65466f9f2b16cefe0059a6e5dd84044c..2f93d2fb806036ac3ba4a25fffdcb4ffcb423035 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -2436,5 +2436,43 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+ return this.adventure$pointers;
+ }
++
++ @Override
++ public boolean applyBoneMeal(@org.jetbrains.annotations.NotNull Location location, org.bukkit.block.BlockFace face, boolean showParticles, @org.jetbrains.annotations.Nullable Predicate predicate) {
++ BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
++ net.minecraft.world.item.context.UseOnContext context = new net.minecraft.world.item.context.UseOnContext(this.getHandle(), null, net.minecraft.world.InteractionHand.MAIN_HAND, net.minecraft.world.item.Items.BONE_MEAL.getDefaultInstance(), new net.minecraft.world.phys.BlockHitResult(Vec3.ZERO, CraftBlock.blockFaceToNotch(face), pos, false));
++
++ // Save old capturing state
++ boolean wasCapturingTrees = world.captureTreeGeneration;
++ boolean wasCapturingBlockStates = world.captureBlockStates;
++
++ Map capturedBlocks = world.capturedBlockStates;
++ Map capturedTileEntities = world.capturedTileEntities;
++
++ // Create new state, capture everything
++ world.capturedBlockStates = new java.util.LinkedHashMap<>();
++ world.capturedTileEntities = new java.util.LinkedHashMap<>();
++
++ world.captureTreeGeneration = true;
++ world.captureBlockStates = true;
++
++ net.minecraft.world.InteractionResult result = net.minecraft.world.item.BoneMealItem.applyBonemeal(context, showParticles);
++
++ // Revert back booleans
++ world.captureTreeGeneration = wasCapturingTrees;
++ world.captureBlockStates = wasCapturingBlockStates;
++
++ for (BlockState blockState : world.capturedBlockStates.values()) {
++ if (predicate != null && predicate.test(blockState)) {
++ blockState.update(true);
++ }
++ }
++
++ // Revertback maps
++ world.capturedBlockStates = capturedBlocks;
++ world.capturedTileEntities = capturedTileEntities;
++
++ return result == net.minecraft.world.InteractionResult.CONSUME;
++ }
+ // Paper end
+ }
diff --git a/patches/server/0017-Paper-PR-Add-sendTitleUpdate-for-inventories.patch b/patches/server/0017-Paper-PR-Add-sendTitleUpdate-for-inventories.patch
new file mode 100644
index 0000000..7a003e8
--- /dev/null
+++ b/patches/server/0017-Paper-PR-Add-sendTitleUpdate-for-inventories.patch
@@ -0,0 +1,45 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: nopjar
+Date: Mon, 13 Jun 2022 11:29:42 +0200
+Subject: [PATCH] Paper PR - Add sendTitleUpdate for inventories
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
+index 76e26542448d18750ce33d53d54c2a77c0590554..2ae43194ffb670f9145ffcc137fea29addec4e51 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
+@@ -79,6 +79,16 @@ public class CraftContainer extends AbstractContainerMenu {
+ public String getTitle() {
+ return inventory instanceof CraftInventoryCustom custom ? custom.getTitle() : inventory.getType().getDefaultTitle(); // Paper
+ }
++
++ // Paper start
++ @Override
++ public void sendTitleUpdate(@org.jetbrains.annotations.NotNull net.kyori.adventure.text.Component title) {
++ AbstractContainerMenu menu = ((org.bukkit.craftbukkit.entity.CraftHumanEntity) getPlayer()).getHandle().containerMenu;
++ var packet = new net.minecraft.network.protocol.game.ClientboundOpenScreenPacket(menu.containerId, menu.getType(), io.papermc.paper.adventure.PaperAdventure.asVanilla(title));
++ ((net.minecraft.server.level.ServerPlayer) player).connection.send(packet);
++ menu.sendAllDataToRemote();
++ }
++ // Paper end
+ }, player, id);
+ }
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java
+index 7d6b5fdb00a5c1614849735634262a36a4efbd66..68e11a13120d81eff511f2e6c6c08aeef4fd50ae 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java
+@@ -83,4 +83,13 @@ public class CraftInventoryView extends InventoryView {
+ public AbstractContainerMenu getHandle() {
+ return this.container;
+ }
++
++ // Paper start
++ @Override
++ public void sendTitleUpdate(@org.jetbrains.annotations.NotNull net.kyori.adventure.text.Component title) {
++ var packet = new net.minecraft.network.protocol.game.ClientboundOpenScreenPacket(this.container.containerId, this.container.getType(), io.papermc.paper.adventure.PaperAdventure.asVanilla(title));
++ ((org.bukkit.craftbukkit.entity.CraftPlayer) getPlayer()).getHandle().connection.send(packet);
++ container.sendAllDataToRemote();
++ }
++ // Paper end
+ }
diff --git a/patches/server/0018-Paper-PR-Deep-clone-unhandled-nbt-tags-inside-CraftM.patch b/patches/server/0018-Paper-PR-Deep-clone-unhandled-nbt-tags-inside-CraftM.patch
new file mode 100644
index 0000000..1cb6511
--- /dev/null
+++ b/patches/server/0018-Paper-PR-Deep-clone-unhandled-nbt-tags-inside-CraftM.patch
@@ -0,0 +1,20 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
+Date: Sat, 1 Apr 2023 00:05:45 +0300
+Subject: [PATCH] Paper PR - Deep clone unhandled nbt tags inside
+ CraftMetaItem's constuctor
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+index 7a4acbb32fbd600e629d0ec2e90868785320d822..7a0253782d8c699fcea929a7051fe3705e25ccc2 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+@@ -342,7 +342,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
+ this.destroyableKeys = new java.util.HashSet<>(meta.destroyableKeys);
+ }
+ // Paper end
+- this.unhandledTags.putAll(meta.unhandledTags);
++ meta.unhandledTags.forEach((key, tag) -> this.unhandledTags.put(key, tag.copy())); // Paper - Deep clone unhandled nbt tags
+ this.persistentDataContainer.putAll(meta.persistentDataContainer.getRaw());
+
+ this.internalTag = meta.internalTag;
diff --git a/patches/server/0019-Paper-PR-Fire-ServerListPingEvent-for-secondary-motd.patch b/patches/server/0019-Paper-PR-Fire-ServerListPingEvent-for-secondary-motd.patch
new file mode 100644
index 0000000..a66dd49
--- /dev/null
+++ b/patches/server/0019-Paper-PR-Fire-ServerListPingEvent-for-secondary-motd.patch
@@ -0,0 +1,74 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
+Date: Sat, 1 Apr 2023 00:13:31 +0300
+Subject: [PATCH] Paper PR - Fire ServerListPingEvent for secondary motd send
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
+index 6b0bdc266109cdfb874f08bf74323603921d2260..a355470f6b0e8286a178ad279ad93bcaf931cb51 100644
+--- a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
++++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
+@@ -75,13 +75,24 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
+ }
+
+ public static void processRequest(MinecraftServer server, Connection networkManager) {
++ ServerStatus ping = getEventResponse(server, networkManager);
++
++ if (ping == null) {
++ networkManager.disconnect(null);
++ return;
++ }
++
++ // Send response
++ networkManager.send(new ClientboundStatusResponsePacket(ping));
++ }
++
++ public static ServerStatus getEventResponse(MinecraftServer server, Connection networkManager) {
+ StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.getStatus());
+ server.server.getPluginManager().callEvent(event);
+
+ // Close connection immediately if event is cancelled
+ if (event.isCancelled()) {
+- networkManager.disconnect(null);
+- return;
++ return null;
+ }
+
+ // Setup response
+@@ -107,10 +118,6 @@ public final class StandardPaperServerListPingEventImpl extends PaperServerListP
+ } else {
+ favicon = Optional.empty();
+ }
+- final ServerStatus ping = new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
+-
+- // Send response
+- networkManager.send(new ClientboundStatusResponsePacket(ping));
++ return new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
+ }
+-
+-}
++}
+\ No newline at end of file
+diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
+index 1a288ebcaade0cc44c7d09478f4f2f8eee7a4269..9d96965d7940fdfe1087ce61c076001bf4d11b4a 100644
+--- a/src/main/java/net/minecraft/server/players/PlayerList.java
++++ b/src/main/java/net/minecraft/server/players/PlayerList.java
+@@ -297,11 +297,13 @@ public abstract class PlayerList {
+ Component joinMessage = ichatmutablecomponent; // Paper - Adventure
+
+ playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
+- ServerStatus serverping = this.server.getStatus();
+-
+- if (serverping != null) {
+- player.sendServerStatus(serverping);
+- }
++ // Paper start - fire ServerListPingEvent
++ io.papermc.paper.util.MCUtil.scheduleAsyncTask(() -> {
++ if (player.hasDisconnected()) return;
++ net.minecraft.network.protocol.status.ServerStatus status = com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.getEventResponse(this.server, player.connection.connection);
++ if (status != null) player.sendServerStatus(status);
++ });
++ // Paper end
+
+ // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // Paper
+ this.players.add(player);
diff --git a/patches/server/0020-Additional-pathfinding-API.patch b/patches/server/0020-Additional-pathfinding-API.patch
new file mode 100644
index 0000000..5bce44a
--- /dev/null
+++ b/patches/server/0020-Additional-pathfinding-API.patch
@@ -0,0 +1,126 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
+Date: Sat, 1 Apr 2023 00:35:19 +0300
+Subject: [PATCH] Additional pathfinding API
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
+index 2d799fec40afe7dade649a294761d272c83157f0..81753d128d71bc6495d84358e861e919f731f4d0 100644
+--- a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
++++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
+@@ -135,6 +135,13 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde
+ }
+ return toLoc(path.nodes.get(path.getNextNodeIndex()));
+ }
++
++ // DivineMC start
++ @Override
++ public boolean canReachFinalPoint() {
++ return path.canReach();
++ }
++ // DivineMC end
+ }
+
+ private Location toLoc(Node point) {
+diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
+index 3395bc1d9140ab5496ad998343a963ae12f630d6..43fbc659d1f789510d6aba3ea9b465e3ccde5a70 100644
+--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
++++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
+@@ -595,7 +595,7 @@ public class Rabbit extends Animal implements VariantHolder {
+ }
+ }
+
+- private static class RabbitPanicGoal extends PanicGoal {
++ public static class RabbitPanicGoal extends PanicGoal {
+
+ private final Rabbit rabbit;
+
+@@ -611,7 +611,7 @@ public class Rabbit extends Animal implements VariantHolder {
+ }
+ }
+
+- private static class RabbitAvoidEntityGoal extends AvoidEntityGoal {
++ public static class RabbitAvoidEntityGoal extends AvoidEntityGoal {
+
+ private final Rabbit rabbit;
+
+@@ -626,7 +626,7 @@ public class Rabbit extends Animal implements VariantHolder {
+ }
+ }
+
+- private static class RaidGardenGoal extends MoveToBlockGoal {
++ public static class RaidGardenGoal extends MoveToBlockGoal {
+
+ private final Rabbit rabbit;
+ private boolean wantsToRaid;
+@@ -744,7 +744,7 @@ public class Rabbit extends Animal implements VariantHolder {
+ }
+ }
+
+- private static class EvilRabbitAttackGoal extends MeleeAttackGoal {
++ public static class EvilRabbitAttackGoal extends MeleeAttackGoal {
+
+ public EvilRabbitAttackGoal(Rabbit rabbit) {
+ super(rabbit, 1.4D, true);
+diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
+index 89978fcb14362af2527693f3e6ec57e169080c9f..e1d591a33ee544011effaebd56bf5ade7681c899 100644
+--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
++++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
+@@ -554,7 +554,7 @@ public class Slime extends Mob implements Enemy {
+ }
+ }
+
+- private static class SlimeFloatGoal extends Goal {
++ public static class SlimeFloatGoal extends Goal {
+
+ private final Slime slime;
+
+@@ -591,7 +591,7 @@ public class Slime extends Mob implements Enemy {
+ }
+ }
+
+- private static class SlimeAttackGoal extends Goal {
++ public static class SlimeAttackGoal extends Goal {
+
+ private final Slime slime;
+ private int growTiredTimer;
+@@ -668,7 +668,7 @@ public class Slime extends Mob implements Enemy {
+ // Paper end
+ }
+
+- private static class SlimeRandomDirectionGoal extends Goal {
++ public static class SlimeRandomDirectionGoal extends Goal {
+
+ private final Slime slime;
+ private float chosenDegrees;
+@@ -707,7 +707,7 @@ public class Slime extends Mob implements Enemy {
+ }
+ }
+
+- private static class SlimeKeepOnJumpingGoal extends Goal {
++ public static class SlimeKeepOnJumpingGoal extends Goal {
+
+ private final Slime slime;
+
+diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
+index 8e071a0922164970e033029c12058db9e8da261a..c5464e61d1ae6abb6a44bcdae292e8d763f47bdd 100644
+--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
++++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
+@@ -226,7 +226,7 @@ public class Spider extends Monster {
+ return 0.65F;
+ }
+
+- private static class SpiderAttackGoal extends MeleeAttackGoal {
++ public static class SpiderAttackGoal extends MeleeAttackGoal {
+
+ public SpiderAttackGoal(Spider spider) {
+ super(spider, 1.0D, true);
+@@ -255,7 +255,7 @@ public class Spider extends Monster {
+ }
+ }
+
+- private static class SpiderTargetGoal extends NearestAttackableTargetGoal {
++ public static class SpiderTargetGoal extends NearestAttackableTargetGoal {
+
+ public SpiderTargetGoal(Spider spider, Class targetEntityClass) {
+ super(spider, targetEntityClass, true);
diff --git a/patches/server/0021-EMC-Allow-negative-Amplifier-values.patch b/patches/server/0021-EMC-Allow-negative-Amplifier-values.patch
new file mode 100644
index 0000000..3c169c7
--- /dev/null
+++ b/patches/server/0021-EMC-Allow-negative-Amplifier-values.patch
@@ -0,0 +1,19 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar
+Date: Sun, 17 Jun 2018 22:16:25 -0400
+Subject: [PATCH] EMC - Allow negative Amplifier values
+
+
+diff --git a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
+index 745e792482f61c571e2efbd4200dd1bdaef6e474..b8451c4b4d4038ffb6eea65a33d645d85101562b 100644
+--- a/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
++++ b/src/main/java/net/minecraft/world/effect/MobEffectInstance.java
+@@ -369,7 +369,7 @@ public class MobEffectInstance implements Comparable {
+ optional = Optional.empty();
+ }
+
+- return new MobEffectInstance(type, j, Math.max(i, 0), bl, bl2, bl3, mobEffectInstance, optional, key); // Purpur - add key
++ return new MobEffectInstance(type, j, i, bl, bl2, bl3, mobEffectInstance, optional, key); // Purpur - add key // EMC - always use Amplifier, don't check > 0
+ }
+
+ @Override