From 4423b4ba08c8aaa5cdad6a4f0c15c63ba47e9b84 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 12 Jun 2021 14:31:35 -0700
Subject: [PATCH] more patches

---
 build-data/mappings-patch.tiny                |   4 +-
 ...dd-an-asterisk-to-legacy-API-plugins.patch |   0
 .../Allow-setting-the-vex-s-summoner.patch    |   0
 .../EnderDragon-Events.patch                  |   0
 .../Entity-getChunk-API.patch                 |   5 +-
 .../PlayerElytraBoostEvent.patch              |   0
 .../PlayerLaunchProjectileEvent.patch         |   0
 ...ies-option-to-debug-dupe-uuid-issues.patch | 131 ---------
 .../Allow-setting-the-vex-s-summoner.patch    |  33 ---
 .../PlayerElytraBoostEvent.patch              |  31 --
 ...nilla-entity-warnings-for-duplicates.patch |  22 --
 ...ftMagicNumbers.isSupportedApiVersion.patch |   0
 ...e-if-stack-size-above-max-stack-size.patch |   0
 .../EnderDragon-Events.patch                  |  35 +--
 .../Improve-BlockPosition-inlining.patch      |  18 +-
 ...timize-IntIdentityHashBiMiap-nextId.patch} |  29 +-
 ...t-armor-stands-from-doing-entity-loo.patch |  10 +-
 patches/server/PlayerElytraBoostEvent.patch   |  33 +++
 .../PlayerLaunchProjectileEvent.patch         | 267 +++++++-----------
 ...nventory-when-cancelling-PlayerInter.patch |  14 +-
 .../Use-asynchronous-Log4j-2-loggers.patch    |  16 +-
 .../Vanished-players-don-t-have-rights.patch  |  89 +-----
 .../Vex-get-setSummoner-API.patch}            |  25 +-
 ...-more-information-to-Entity.toString.patch |   4 +-
 24 files changed, 207 insertions(+), 559 deletions(-)
 rename patches/{api-unmapped => api}/Add-an-asterisk-to-legacy-API-plugins.patch (100%)
 rename patches/{api-unmapped => api}/Allow-setting-the-vex-s-summoner.patch (100%)
 rename patches/{api-unmapped => api}/EnderDragon-Events.patch (100%)
 rename patches/{api-unmapped => api}/Entity-getChunk-API.patch (91%)
 rename patches/{api-unmapped => api}/PlayerElytraBoostEvent.patch (100%)
 rename patches/{api-unmapped => api}/PlayerLaunchProjectileEvent.patch (100%)
 delete mode 100644 patches/server-remapped/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
 delete mode 100644 patches/server-remapped/Allow-setting-the-vex-s-summoner.patch
 delete mode 100644 patches/server-remapped/PlayerElytraBoostEvent.patch
 delete mode 100644 patches/server-remapped/Re-add-vanilla-entity-warnings-for-duplicates.patch
 rename patches/{server-remapped => server}/Add-CraftMagicNumbers.isSupportedApiVersion.patch (100%)
 rename patches/{server-remapped => server}/Avoid-item-merge-if-stack-size-above-max-stack-size.patch (100%)
 rename patches/{server-remapped => server}/EnderDragon-Events.patch (72%)
 rename patches/{server-remapped => server}/Improve-BlockPosition-inlining.patch (74%)
 rename patches/{server-remapped/Optimize-RegistryID.c.patch => server/Optimize-IntIdentityHashBiMiap-nextId.patch} (73%)
 rename patches/{server-remapped => server}/Option-to-prevent-armor-stands-from-doing-entity-loo.patch (83%)
 create mode 100644 patches/server/PlayerElytraBoostEvent.patch
 rename patches/{server-remapped => server}/PlayerLaunchProjectileEvent.patch (51%)
 rename patches/{server-remapped => server}/Refresh-player-inventory-when-cancelling-PlayerInter.patch (77%)
 rename patches/{server-remapped => server}/Use-asynchronous-Log4j-2-loggers.patch (77%)
 rename patches/{server-remapped => server}/Vanished-players-don-t-have-rights.patch (53%)
 rename patches/{server-remapped/Vex-getSummoner-API.patch => server/Vex-get-setSummoner-API.patch} (61%)
 rename patches/{server-remapped => server}/add-more-information-to-Entity.toString.patch (69%)

diff --git a/build-data/mappings-patch.tiny b/build-data/mappings-patch.tiny
index b15b9e635c..b592b1991b 100644
--- a/build-data/mappings-patch.tiny
+++ b/build-data/mappings-patch.tiny
@@ -38,8 +38,8 @@ c	net/minecraft/world/entity/projectile/EntityTippedArrow	net/minecraft/world/en
 
 # CraftBukkit adds a new `a` method which allows passing the Entity parameter
 # It uses `a` to match the original method (with just 1 param), so this patch makes them match
-#c	net/minecraft/server/level/WorldServer	net/minecraft/server/level/ServerLevel
-#	m	(Lnet/minecraft/server/level/WorldServer;Lnet/minecraft/world/entity/Entity;)V	a	makeObsidianPlatform
+c	net/minecraft/server/level/WorldServer	net/minecraft/server/level/ServerLevel
+	m	(Lnet/minecraft/server/level/WorldServer;Lnet/minecraft/world/entity/Entity;)V	a	makeObsidianPlatform
 
 # CraftBukkit adds `getMinecraftWorld()` to `GeneratorAccess`, which matches `WorldAccess.getMinecraftWorld()`
 # But that method in `WorldAccess` is called `getLevel()` in Mojang mappings
diff --git a/patches/api-unmapped/Add-an-asterisk-to-legacy-API-plugins.patch b/patches/api/Add-an-asterisk-to-legacy-API-plugins.patch
similarity index 100%
rename from patches/api-unmapped/Add-an-asterisk-to-legacy-API-plugins.patch
rename to patches/api/Add-an-asterisk-to-legacy-API-plugins.patch
diff --git a/patches/api-unmapped/Allow-setting-the-vex-s-summoner.patch b/patches/api/Allow-setting-the-vex-s-summoner.patch
similarity index 100%
rename from patches/api-unmapped/Allow-setting-the-vex-s-summoner.patch
rename to patches/api/Allow-setting-the-vex-s-summoner.patch
diff --git a/patches/api-unmapped/EnderDragon-Events.patch b/patches/api/EnderDragon-Events.patch
similarity index 100%
rename from patches/api-unmapped/EnderDragon-Events.patch
rename to patches/api/EnderDragon-Events.patch
diff --git a/patches/api-unmapped/Entity-getChunk-API.patch b/patches/api/Entity-getChunk-API.patch
similarity index 91%
rename from patches/api-unmapped/Entity-getChunk-API.patch
rename to patches/api/Entity-getChunk-API.patch
index c222dca653..83994ab122 100644
--- a/patches/api-unmapped/Entity-getChunk-API.patch
+++ b/patches/api/Entity-getChunk-API.patch
@@ -28,6 +28,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return The current, or most recent chunk if the entity is invalid (which may load the chunk)
 +     */
 +    @NotNull
-+    Chunk getChunk();
++    default Chunk getChunk() {
++        // TODO remove impl here
++        return getLocation().getChunk();
++    }
      // Paper end
  }
diff --git a/patches/api-unmapped/PlayerElytraBoostEvent.patch b/patches/api/PlayerElytraBoostEvent.patch
similarity index 100%
rename from patches/api-unmapped/PlayerElytraBoostEvent.patch
rename to patches/api/PlayerElytraBoostEvent.patch
diff --git a/patches/api-unmapped/PlayerLaunchProjectileEvent.patch b/patches/api/PlayerLaunchProjectileEvent.patch
similarity index 100%
rename from patches/api-unmapped/PlayerLaunchProjectileEvent.patch
rename to patches/api/PlayerLaunchProjectileEvent.patch
diff --git a/patches/server-remapped/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/server-remapped/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
deleted file mode 100644
index 682974704d..0000000000
--- a/patches/server-remapped/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
+++ /dev/null
@@ -1,131 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <aikar@aikar.co>
-Date: Sat, 21 Jul 2018 08:25:40 -0400
-Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
-
-Add -Ddebug.entities=true to your JVM flags to gain more information
-
-diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-             } else {
-                 ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
- 
-+                entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
-                 this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
-                 playerchunkmap_entitytracker.updatePlayers(this.level.players());
-                 if (entity instanceof ServerPlayer) {
-@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-         if (playerchunkmap_entitytracker1 != null) {
-             playerchunkmap_entitytracker1.broadcastRemoved();
-         }
--
-+        entity.tracker = null; // Paper - We're no longer tracked
-     }
- 
-     protected void tick() {
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
-     public final LevelStorageSource.LevelStorageAccess convertable;
-     public final UUID uuid;
-     public boolean hasPhysicsEvent = true; // Paper
-+    private static Throwable getAddToWorldStackTrace(Entity entity) {
-+        return new Throwable(entity + " Added to world at " + new java.util.Date());
-+    }
- 
-     @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
-         return this.chunkSource.getChunk(x, z, false);
-@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
-     // CraftBukkit start
-     private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
-         org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
--        if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); return true; } // Paper
-+        // Paper start
-+        if (entity.valid) {
-+            MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
-+
-+            if (DEBUG_ENTITIES) {
-+                Throwable thr = entity.addedToWorldStack;
-+                if (thr == null) {
-+                    MinecraftServer.LOGGER.error("Double add entity has no add stacktrace");
-+                } else {
-+                    MinecraftServer.LOGGER.error("Double add stacktrace: ", thr);
-+                }
-+            }
-+            return true;
-+        }
-+        // Paper end
-         if (entity.removed) {
-+            // Paper start
-+            if (DEBUG_ENTITIES) {
-+                new Throwable("Tried to add entity " + entity + " but it was marked as removed already").printStackTrace(); // CraftBukkit
-+                getAddToWorldStackTrace(entity).printStackTrace();
-+            }
-+            // Paper end
-             // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit
-             return false;
-         } else if (this.isUUIDUsed(entity)) {
-@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
-                 }
-             }
- 
--            this.entitiesByUuid.put(entity.getUUID(), entity);
-+            if (DEBUG_ENTITIES) {
-+                entity.addedToWorldStack = getAddToWorldStackTrace(entity);
-+            }
-+
-+            Entity old = this.entitiesByUuid.put(entity.getUUID(), entity);
-+            if (old != null && old.getId() != entity.getId() && old.valid) {
-+                Logger logger = LogManager.getLogger();
-+                logger.error("Overwrote an existing entity " + old + " with " + entity);
-+                if (DEBUG_ENTITIES) {
-+                    if (old.addedToWorldStack != null) {
-+                        old.addedToWorldStack.printStackTrace();
-+                    } else {
-+                        logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
-+                    }
-+                    entity.addedToWorldStack.printStackTrace();
-+                }
-+            }
-+
-             this.getChunkSource().addEntity(entity);
-             // CraftBukkit start - SPIGOT-5278
-             if (entity instanceof Drowned) {
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -0,0 +0,0 @@ import net.minecraft.network.syncher.SynchedEntityData;
- import net.minecraft.resources.ResourceKey;
- import net.minecraft.resources.ResourceLocation;
- import net.minecraft.server.MinecraftServer;
-+import net.minecraft.server.level.ChunkMap;
- import net.minecraft.server.level.ServerLevel;
- import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.server.level.TicketType;
-@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
-     public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
-     private CraftEntity bukkitEntity;
- 
-+    ChunkMap.TrackedEntity tracker; // Paper
-+    public Throwable addedToWorldStack; // Paper - entity debug
-     public CraftEntity getBukkitEntity() {
-         if (bukkitEntity == null) {
-             bukkitEntity = CraftEntity.getEntity(level.getCraftServer(), this);
-diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/Level.java
-+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
-     public boolean pvpMode;
-     public boolean keepSpawnInMemory = true;
-     public org.bukkit.generator.ChunkGenerator generator;
-+    public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
- 
-     public boolean captureBlockStates = false;
-     public boolean captureTreeGeneration = false;
diff --git a/patches/server-remapped/Allow-setting-the-vex-s-summoner.patch b/patches/server-remapped/Allow-setting-the-vex-s-summoner.patch
deleted file mode 100644
index 77fbe6c4a2..0000000000
--- a/patches/server-remapped/Allow-setting-the-vex-s-summoner.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath <Blake.Galbreath@GMail.com>
-Date: Sat, 6 Oct 2018 21:47:44 -0500
-Subject: [PATCH] Allow setting the vex's summoner
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/monster/Vex.java
-+++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-@@ -0,0 +0,0 @@ public class Vex extends Monster {
-         this.setVexFlag(1, charging);
-     }
- 
-+    public void setOwner(Mob entityinsentient) { setOwner(entityinsentient); } // Paper - OBFHELPER
-     public void setOwner(Mob owner) {
-         this.owner = owner;
-     }
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
-@@ -0,0 +0,0 @@ public class CraftVex extends CraftMonster implements Vex {
-         net.minecraft.world.entity.Mob owner = getHandle().getOwner();
-         return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
-     }
-+
-+    public void setSummoner(org.bukkit.entity.Mob summoner) {
-+        getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
-+    }
-     // Paper end
- 
-     @Override
diff --git a/patches/server-remapped/PlayerElytraBoostEvent.patch b/patches/server-remapped/PlayerElytraBoostEvent.patch
deleted file mode 100644
index 34eec74c80..0000000000
--- a/patches/server-remapped/PlayerElytraBoostEvent.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: BillyGalbreath <Blake.Galbreath@GMail.com>
-Date: Sat, 21 Jul 2018 01:59:59 -0500
-Subject: [PATCH] PlayerElytraBoostEvent
-
-
-diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
-                 // Paper start
-                 final FireworkRocketEntity entityfireworks = new FireworkRocketEntity(world, itemstack, user);
-                 entityfireworks.spawningEntity = user.getUUID();
--                world.addFreshEntity(entityfireworks);
--                // Paper end
--                if (!user.abilities.instabuild) {
--                    itemstack.shrink(1);
-+                // Paper start
-+                com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Firework) entityfireworks.getBukkitEntity());
-+                if (event.callEvent() && world.addFreshEntity(entityfireworks)) {
-+                    if (event.shouldConsume() && !user.abilities.instabuild) {
-+                        itemstack.shrink(1);
-+                    } else ((EntityPlayer) user).getBukkitEntity().updateInventory();
-+                } else if (user instanceof EntityPlayer) {
-+                    ((EntityPlayer) user).getBukkitEntity().updateInventory();
-                 }
-+                // Paper end
-             }
- 
-             return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
diff --git a/patches/server-remapped/Re-add-vanilla-entity-warnings-for-duplicates.patch b/patches/server-remapped/Re-add-vanilla-entity-warnings-for-duplicates.patch
deleted file mode 100644
index 16db14b3f1..0000000000
--- a/patches/server-remapped/Re-add-vanilla-entity-warnings-for-duplicates.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <aikar@aikar.co>
-Date: Thu, 19 Jul 2018 01:08:05 -0400
-Subject: [PATCH] Re-add vanilla entity warnings for duplicates
-
-These are a critical sign that somethin went wrong, and you've lost some data....
-
-We should kind of know about these things you know.
-
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
-         if (entity1 == null) {
-             return false;
-         } else {
--            // WorldServer.LOGGER.warn("Trying to add entity with duplicated UUID {}. Existing {}#{}, new: {}#{}", uuid, EntityTypes.getName(entity1.getEntityType()), entity1.getId(), EntityTypes.getName(entity.getEntityType()), entity.getId()); // CraftBukkit
-+            ServerLevel.LOGGER.warn("Trying to add entity with duplicated UUID {}. Existing {}#{}, new: {}#{}", uuid, EntityType.getKey(entity1.getType()), entity1.getId(), EntityType.getKey(entity.getType()), entity.getId()); // CraftBukkit // Paper
-             return true;
-         }
-     }
diff --git a/patches/server-remapped/Add-CraftMagicNumbers.isSupportedApiVersion.patch b/patches/server/Add-CraftMagicNumbers.isSupportedApiVersion.patch
similarity index 100%
rename from patches/server-remapped/Add-CraftMagicNumbers.isSupportedApiVersion.patch
rename to patches/server/Add-CraftMagicNumbers.isSupportedApiVersion.patch
diff --git a/patches/server-remapped/Avoid-item-merge-if-stack-size-above-max-stack-size.patch b/patches/server/Avoid-item-merge-if-stack-size-above-max-stack-size.patch
similarity index 100%
rename from patches/server-remapped/Avoid-item-merge-if-stack-size-above-max-stack-size.patch
rename to patches/server/Avoid-item-merge-if-stack-size-above-max-stack-size.patch
diff --git a/patches/server-remapped/EnderDragon-Events.patch b/patches/server/EnderDragon-Events.patch
similarity index 72%
rename from patches/server-remapped/EnderDragon-Events.patch
rename to patches/server/EnderDragon-Events.patch
index 02158d4f22..663e89c73e 100644
--- a/patches/server-remapped/EnderDragon-Events.patch
+++ b/patches/server/EnderDragon-Events.patch
@@ -14,37 +14,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
              this.flame.addEffect(new MobEffectInstance(MobEffects.HARM));
 +            if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper
              this.dragon.level.addFreshEntity(this.flame);
++            // Paper start
 +            } else {
-+                this.removeAreaEffect();
++                this.end();
 +            }
++            // Paper end
          }
  
      }
-@@ -0,0 +0,0 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase {
-         ++this.flameCount;
-     }
- 
--    @Override
--    public void end() {
-+    public final void removeAreaEffect() { this.end(); } // Paper - OBFHELPER
-+    @Override public void end() {
-         if (this.flame != null) {
-             this.flame.remove();
-             this.flame = null;
 diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
 +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
 @@ -0,0 +0,0 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance {
-                         DragonFireball entitydragonfireball = new DragonFireball(this.dragon.level, this.dragon, d9, d10, d11);
  
-                         entitydragonfireball.moveTo(d6, d7, d8, 0.0F, 0.0F);
-+                        if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) entitydragonfireball.getBukkitEntity()).callEvent()) // Paper
-                         this.dragon.level.addFreshEntity(entitydragonfireball);
-+                        else entitydragonfireball.remove(); // Paper
+                         DragonFireball dragonFireball = new DragonFireball(this.dragon.level, this.dragon, r, s, t);
+                         dragonFireball.moveTo(o, p, q, 0.0F, 0.0F);
++                        if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper
+                         this.dragon.level.addFreshEntity(dragonFireball);
++                        else dragonFireball.discard(); // Paper
                          this.fireballCharge = 0;
                          if (this.currentPath != null) {
-                             while (!this.currentPath.isDone()) {
+                             while(!this.currentPath.isDone()) {
 diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
@@ -53,10 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                      }
                  }
  
-+                if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper
++                if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper
                  this.level.levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
-                 this.level.addFreshEntity(entityareaeffectcloud);
-+                } else entityareaeffectcloud.remove(); // Paper
-                 this.remove();
+                 this.level.addFreshEntity(areaEffectCloud);
++                } else areaEffectCloud.discard(); // Paper
+                 this.discard();
              }
  
diff --git a/patches/server-remapped/Improve-BlockPosition-inlining.patch b/patches/server/Improve-BlockPosition-inlining.patch
similarity index 74%
rename from patches/server-remapped/Improve-BlockPosition-inlining.patch
rename to patches/server/Improve-BlockPosition-inlining.patch
index f3efc2cdce..4653aaf6b2 100644
--- a/patches/server-remapped/Improve-BlockPosition-inlining.patch
+++ b/patches/server/Improve-BlockPosition-inlining.patch
@@ -20,42 +20,30 @@ This should result in an across the board speedup in anything that accesses bloc
 This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my microbenchmarks.
 They had 'callq' (invoke) instead of 'mov' (get from memory) instructions.
 
-diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/core/BlockPos.java
-+++ b/src/main/java/net/minecraft/core/BlockPos.java
-@@ -0,0 +0,0 @@ public class BlockPos extends Vec3i {
-         return asLong(this.getX(), this.getY(), this.getZ());
-     }
- 
-+    public static long asLong(int x, int y, int z) { return asLong(x, y, z); } // Paper - OBFHELPER
-     public static long asLong(int x, int y, int z) {
-         long l = 0L;
- 
 diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/core/Vec3i.java
 +++ b/src/main/java/net/minecraft/core/Vec3i.java
 @@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
-         this(Mth.floor(x), Mth.floor(y), Mth.floor(z));
      }
  
+     @Override
 -    public boolean equals(Object object) {
 +    public final boolean equals(Object object) { // Paper
          if (this == object) {
              return true;
          } else if (!(object instanceof Vec3i)) {
 @@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
-         }
      }
  
+     @Override
 -    public int hashCode() {
 +    public final int hashCode() { // Paper
          return (this.getY() + this.getZ() * 31) * 31 + this.getX();
      }
  
 @@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
-         return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY();
+         }
      }
  
 -    public int getX() {
diff --git a/patches/server-remapped/Optimize-RegistryID.c.patch b/patches/server/Optimize-IntIdentityHashBiMiap-nextId.patch
similarity index 73%
rename from patches/server-remapped/Optimize-RegistryID.c.patch
rename to patches/server/Optimize-IntIdentityHashBiMiap-nextId.patch
index ffe72c24ea..a6de08f3bb 100644
--- a/patches/server-remapped/Optimize-RegistryID.c.patch
+++ b/patches/server/Optimize-IntIdentityHashBiMiap-nextId.patch
@@ -1,7 +1,9 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Andrew Steinborn <git@steinborn.me>
 Date: Mon, 23 Jul 2018 13:08:19 -0400
-Subject: [PATCH] Optimize RegistryID.c()
+Subject: [PATCH] Optimize IntIdentityHashBiMiap#nextId()
+
+Optimizes CrudeIncrementalIntIdentityHashBiMap#nextId()
 
 This is a frequent hotspot for world loading/saving.
 
@@ -16,24 +18,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private java.util.BitSet usedIds; // Paper
  
      public CrudeIncrementalIntIdentityHashBiMap(int size) {
-         size = (int) ((float) size / 0.8F);
-         this.keys = (K[]) (new Object[size]); // Paper - decompile fix
+         size = (int)((float)size / 0.8F);
+         this.keys = (K[])(new Object[size]);
          this.values = new int[size];
-         this.byId = (K[]) (new Object[size]); // Paper - decompile fix
+         this.byId = (K[])(new Object[size]);
 +        this.usedIds = new java.util.BitSet(); // Paper
      }
  
-     // Paper start - decompile fix
+     @Override
 @@ -0,0 +0,0 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
      }
  
      private int nextId() {
--        while (this.nextId < this.byId.length && this.byId[this.nextId] != null) {
--            ++this.nextId;
-+        // Paper start
-+        /*
-+        while (this.e < this.d.length && this.d[this.e] != null) {
-+            ++this.e;
++        /* // Paper start
+         while(this.nextId < this.byId.length && this.byId[this.nextId] != null) {
+             ++this.nextId;
          }
 +        */
 +        this.nextId = this.usedIds.nextClearBit(0);
@@ -42,13 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          return this.nextId;
      }
 @@ -0,0 +0,0 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
-         this.byId = (K[]) (new Object[newSize]); // Paper - decompile fix
+         this.byId = (K[])(new Object[newSize]);
          this.nextId = 0;
          this.size = 0;
 +        this.usedIds.clear(); // Paper
  
-         for (int j = 0; j < ak.length; ++j) {
-             if (ak[j] != null) {
+         for(int i = 0; i < objects.length; ++i) {
+             if (objects[i] != null) {
 @@ -0,0 +0,0 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
          this.keys[k] = value;
          this.values[k] = id;
@@ -58,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          if (id == this.nextId) {
              ++this.nextId;
 @@ -0,0 +0,0 @@ public class CrudeIncrementalIntIdentityHashBiMap<K> implements IdMap<K> {
-         Arrays.fill(this.byId, (Object) null);
+         Arrays.fill(this.byId, (Object)null);
          this.nextId = 0;
          this.size = 0;
 +        this.usedIds.clear(); // Paper
diff --git a/patches/server-remapped/Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/server/Option-to-prevent-armor-stands-from-doing-entity-loo.patch
similarity index 83%
rename from patches/server-remapped/Option-to-prevent-armor-stands-from-doing-entity-loo.patch
rename to patches/server/Option-to-prevent-armor-stands-from-doing-entity-loo.patch
index c072430680..ae004d6811 100644
--- a/patches/server-remapped/Option-to-prevent-armor-stands-from-doing-entity-loo.patch
+++ b/patches/server/Option-to-prevent-armor-stands-from-doing-entity-loo.patch
@@ -34,14 +34,6 @@ diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/level/Level.java
 +++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -0,0 +0,0 @@ import net.minecraft.world.DifficultyInstance;
- import net.minecraft.world.damagesource.DamageSource;
- import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.EntityType;
-+import net.minecraft.world.entity.decoration.ArmorStand;
- import net.minecraft.world.entity.item.ItemEntity;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.item.ItemStack;
 @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
              // Paper end
          }
@@ -49,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    // Paper start - Prevent armor stands from doing entity lookups
 +    @Override
 +    public boolean noCollision(@Nullable Entity entity, AABB box) {
-+        if (entity instanceof ArmorStand && !entity.level.paperConfig.armorStandEntityLookups) return false;
++        if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level.paperConfig.armorStandEntityLookups) return false;
 +        return LevelAccessor.super.noCollision(entity, box);
 +    }
 +    // Paper end
diff --git a/patches/server/PlayerElytraBoostEvent.patch b/patches/server/PlayerElytraBoostEvent.patch
new file mode 100644
index 0000000000..5df337620d
--- /dev/null
+++ b/patches/server/PlayerElytraBoostEvent.patch
@@ -0,0 +1,33 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: BillyGalbreath <Blake.Galbreath@GMail.com>
+Date: Sat, 21 Jul 2018 01:59:59 -0500
+Subject: [PATCH] PlayerElytraBoostEvent
+
+
+diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
++++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
+             if (!world.isClientSide) {
+                 FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
+                 fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
+-                world.addFreshEntity(fireworkRocketEntity);
+-                if (!user.getAbilities().instabuild) {
++                // Paper start
++                com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
++                if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
++                    user.awardStat(Stats.ITEM_USED.get(this));
++                    if (event.shouldConsume() && !user.getAbilities().instabuild) {
+                     itemStack.shrink(1);
++                    } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++                    // Paper end
+                 }
+ 
+-                user.awardStat(Stats.ITEM_USED.get(this));
++                // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - move up
+             }
+ 
+             return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
diff --git a/patches/server-remapped/PlayerLaunchProjectileEvent.patch b/patches/server/PlayerLaunchProjectileEvent.patch
similarity index 51%
rename from patches/server-remapped/PlayerLaunchProjectileEvent.patch
rename to patches/server/PlayerLaunchProjectileEvent.patch
index b34b40084b..79bdf3f2f2 100644
--- a/patches/server-remapped/PlayerLaunchProjectileEvent.patch
+++ b/patches/server/PlayerLaunchProjectileEvent.patch
@@ -4,18 +4,6 @@ Date: Sat, 21 Jul 2018 03:11:03 -0500
 Subject: [PATCH] PlayerLaunchProjectileEvent
 
 
-diff --git a/src/main/java/net/minecraft/world/InteractionResultHolder.java b/src/main/java/net/minecraft/world/InteractionResultHolder.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/InteractionResultHolder.java
-+++ b/src/main/java/net/minecraft/world/InteractionResultHolder.java
-@@ -0,0 +0,0 @@ public class InteractionResultHolder<T> {
-         this.object = value;
-     }
- 
-+    public InteractionResult getResult() { return this.getResult(); } // Paper - OBFHELPER
-     public InteractionResult getResult() {
-         return this.result;
-     }
 diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/EggItem.java
@@ -23,41 +11,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class EggItem extends Item {
  
              entityegg.setItem(itemstack);
-             entityegg.shootFromRotation(user, user.xRot, user.yRot, 0.0F, 1.5F, 1.0F);
+             entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
 -            // CraftBukkit start
 -            if (!world.addFreshEntity(entityegg)) {
 +            // Paper start
 +            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
 +            if (event.callEvent() && world.addFreshEntity(entityegg)) {
-+                if (event.shouldConsume() && !user.abilities.instabuild) {
++                if (event.shouldConsume() && !user.getAbilities().instabuild) {
 +                    itemstack.shrink(1);
 +                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
 +                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +                }
 +
-+                world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
++                world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), net.minecraft.sounds.SoundEvents.EGG_THROW, net.minecraft.sounds.SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
 +                user.awardStat(Stats.ITEM_USED.get(this));
 +            } else {
                  if (user instanceof net.minecraft.server.level.ServerPlayer) {
                      ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
                  }
--                return InteractionResultHolder.fail(itemstack);
-+                return new InteractionResultHolder<ItemStack>(net.minecraft.world.InteractionResult.FAIL, itemstack);
+                 return InteractionResultHolder.fail(itemstack);
              }
 -            // CraftBukkit end
 +            // Paper end
-+
-+
          }
-         world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (EggItem.random.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
+         // world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
  
--        user.awardStat(Stats.ITEM_USED.get(this));
--        if (!user.abilities.instabuild) {
--            itemstack.shrink(1);
 +        /* // Paper start - moved up
-+        entityhuman.b(StatisticList.ITEM_USED.b(this));
-+        if (!entityhuman.abilities.canInstantlyBuild) {
-+            itemstack.subtract(1);
+         user.awardStat(Stats.ITEM_USED.get(this));
+         if (!user.getAbilities().instabuild) {
+             itemstack.shrink(1);
          }
 +        */ // Paper end
  
@@ -70,12 +52,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
  
              entityenderpearl.setItem(itemstack);
-             entityenderpearl.shootFromRotation(user, user.xRot, user.yRot, 0.0F, 1.5F, 1.0F);
+             entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
 -            if (!world.addFreshEntity(entityenderpearl)) {
 +            // Paper start
 +                com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity());
 +            if (event.callEvent() && world.addFreshEntity(entityenderpearl)) {
-+                if (event.shouldConsume() && !user.abilities.instabuild) {
++                if (event.shouldConsume() && !user.getAbilities().instabuild) {
 +                    itemstack.shrink(1);
 +                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
 +                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
@@ -89,29 +71,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  if (user instanceof net.minecraft.server.level.ServerPlayer) {
                      ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
                  }
--                return InteractionResultHolder.fail(itemstack);
-+                return new InteractionResultHolder<ItemStack>(net.minecraft.world.InteractionResult.FAIL, itemstack);
+@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
              }
          }
  
--        world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (EnderpearlItem.random.nextFloat() * 0.4F + 0.8F));
--        user.getCooldowns().addCooldown(this, 20);
--        // CraftBukkit end
--
--        user.awardStat(Stats.ITEM_USED.get(this));
--        if (!user.abilities.instabuild) {
--            itemstack.shrink(1);
--        }
-+        // Paper start - moved up
-+//        world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F));
-+//        entityhuman.getCooldownTracker().setCooldown(this, 20);
-+//        // CraftBukkit end
-+//
-+//        entityhuman.b(StatisticList.ITEM_USED.b(this));
-+//        if (!entityhuman.abilities.canInstantlyBuild) {
-+//            itemstack.subtract(1);
-+//        }
-+        // Paper end - moved up
++        /* // Paper start - moved up
+         world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+         user.getCooldowns().addCooldown(this, 20);
+         // CraftBukkit end
+@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
+         if (!user.getAbilities().instabuild) {
+             itemstack.shrink(1);
+         }
++        */ // Paper end - moved up
  
          return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
      }
@@ -119,126 +91,86 @@ diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
 +++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
-@@ -0,0 +0,0 @@
- package net.minecraft.world.item;
- 
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.sounds.SoundEvents;
- import net.minecraft.sounds.SoundSource;
- import net.minecraft.stats.Stats;
- import net.minecraft.world.InteractionHand;
-+import net.minecraft.world.InteractionResult;
- import net.minecraft.world.InteractionResultHolder;
-+import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
- import net.minecraft.world.level.Level;
 @@ -0,0 +0,0 @@ public class ExperienceBottleItem extends Item {
+     @Override
      public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
-         ItemStack itemstack = user.getItemInHand(hand);
- 
--        world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (ExperienceBottleItem.random.nextFloat() * 0.4F + 0.8F));
-+        //world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F));  // Paper - moved down
+         ItemStack itemStack = user.getItemInHand(hand);
+-        world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
++        // world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // Paper - moved down
          if (!world.isClientSide) {
-             ThrownExperienceBottle entitythrownexpbottle = new ThrownExperienceBottle(world, user);
- 
-             entitythrownexpbottle.setItem(itemstack);
-             entitythrownexpbottle.shootFromRotation(user, user.xRot, user.yRot, -20.0F, 0.7F, 1.0F);
--            world.addFreshEntity(entitythrownexpbottle);
+             ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user);
+             thrownExperienceBottle.setItem(itemStack);
+             thrownExperienceBottle.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.7F, 1.0F);
+-            world.addFreshEntity(thrownExperienceBottle);
 +            // Paper start
-+            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitythrownexpbottle.getBukkitEntity());
-+            if (event.callEvent() && world.addFreshEntity(entitythrownexpbottle)) {
-+                if (event.shouldConsume() && !user.abilities.instabuild) {
-+                    itemstack.shrink(1);
-+                } else if (user instanceof ServerPlayer) {
-+                    ((ServerPlayer) user).getBukkitEntity().updateInventory();
++            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.getBukkitEntity());
++            if (event.callEvent() && world.addFreshEntity(thrownExperienceBottle)) {
++                if (event.shouldConsume() && !user.getAbilities().instabuild) {
++                    itemStack.shrink(1);
++                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +                }
 +
-+                world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
++                world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
 +                user.awardStat(Stats.ITEM_USED.get(this));
 +            } else {
-+                if (user instanceof ServerPlayer) {
-+                    ((ServerPlayer) user).getBukkitEntity().updateInventory();
++                if (user instanceof net.minecraft.server.level.ServerPlayer) {
++                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +                }
-+                    return new InteractionResultHolder<ItemStack>(InteractionResult.FAIL, itemstack);
++                return InteractionResultHolder.fail(itemStack);
 +            }
 +            // Paper end
          }
  
--        user.awardStat(Stats.ITEM_USED.get(this));
--        if (!user.abilities.instabuild) {
--            itemstack.shrink(1);
 +        /* // Paper start - moved up
-+        entityhuman.b(StatisticList.ITEM_USED.b(this));
-+        if (!entityhuman.abilities.canInstantlyBuild) {
-+            itemstack.subtract(1);
+         user.awardStat(Stats.ITEM_USED.get(this));
+         if (!user.getAbilities().instabuild) {
+             itemStack.shrink(1);
          }
 +        */ // Paper end
  
-         return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
+         return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
      }
 diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
 +++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
-@@ -0,0 +0,0 @@ package net.minecraft.world.item;
- import java.util.Arrays;
- import java.util.Comparator;
- import net.minecraft.core.Direction;
+@@ -0,0 +0,0 @@ import net.minecraft.network.chat.Component;
+ import net.minecraft.network.chat.TextComponent;
+ import net.minecraft.network.chat.TranslatableComponent;
+ import net.minecraft.stats.Stats;
 +import net.minecraft.server.level.ServerPlayer;
  import net.minecraft.world.InteractionHand;
  import net.minecraft.world.InteractionResult;
  import net.minecraft.world.InteractionResultHolder;
 @@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
-             FireworkRocketEntity entityfireworks = new FireworkRocketEntity(world, context.getPlayer(), vec3d.x + (double) enumdirection.getStepX() * 0.15D, vec3d.y + (double) enumdirection.getStepY() * 0.15D, vec3d.z + (double) enumdirection.getStepZ() * 0.15D, itemstack);
-             entityfireworks.spawningEntity = context.getPlayer().getUUID(); // Paper
- 
--            world.addFreshEntity(entityfireworks);
--            itemstack.shrink(1);
+             Direction direction = context.getClickedFace();
+             FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack);
+             fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper
+-            level.addFreshEntity(fireworkRocketEntity);
+-            itemStack.shrink(1);
 +            // Paper start - PlayerLaunchProjectileEvent
-+            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Firework) entityfireworks.getBukkitEntity());
-+            if (!event.callEvent() || !world.addFreshEntity(entityfireworks)) return InteractionResult.PASS;
-+            if (event.shouldConsume() && !context.getPlayer().abilities.instabuild) itemstack.shrink(1);
++            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
++            if (!event.callEvent() || !level.addFreshEntity(fireworkRocketEntity)) return InteractionResult.PASS;
++            if (event.shouldConsume() && !context.getPlayer().getAbilities().instabuild) itemStack.shrink(1);
 +            else if (context.getPlayer() instanceof ServerPlayer) ((ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory();
 +            // Paper end
          }
  
-         return InteractionResult.sidedSuccess(world.isClientSide);
-@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
-                 if (event.callEvent() && world.addFreshEntity(entityfireworks)) {
-                     if (event.shouldConsume() && !user.abilities.instabuild) {
-                         itemstack.shrink(1);
--                    } else ((EntityPlayer) user).getBukkitEntity().updateInventory();
--                } else if (user instanceof EntityPlayer) {
--                    ((EntityPlayer) user).getBukkitEntity().updateInventory();
-+                    } else ((ServerPlayer) user).getBukkitEntity().updateInventory();
-+                } else if (user instanceof ServerPlayer) {
-+                    ((ServerPlayer) user).getBukkitEntity().updateInventory();
-                 }
-                 // Paper end
-             }
+         return InteractionResult.sidedSuccess(level.isClientSide);
 diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
 +++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
-@@ -0,0 +0,0 @@ package net.minecraft.world.item;
- import net.minecraft.sounds.SoundEvents;
- import net.minecraft.sounds.SoundSource;
- import net.minecraft.world.InteractionHand;
-+import net.minecraft.world.InteractionResult;
- import net.minecraft.world.InteractionResultHolder;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.level.Level;
 @@ -0,0 +0,0 @@ public class LingeringPotionItem extends ThrowablePotionItem {
  
      @Override
      public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
--        world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (LingeringPotionItem.random.nextFloat() * 0.4F + 0.8F));
--        return super.use(world, user, hand);
 +        // Paper start
 +        InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
-+        if (wrapper.getResult() != InteractionResult.FAIL) {
-+            world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (LingeringPotionItem.random.nextFloat() * 0.4F + 0.8F));
++        if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
+         world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+-        return super.use(world, user, hand);
 +        }
 +        return wrapper;
 +        // Paper end
@@ -251,48 +183,54 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@ public class SnowballItem extends Item {
  
              entitysnowball.setItem(itemstack);
-             entitysnowball.shootFromRotation(user, user.xRot, user.yRot, 0.0F, 1.5F, 1.0F);
+             entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
 -            if (world.addFreshEntity(entitysnowball)) {
--                if (!user.abilities.instabuild) {
+-                if (!user.getAbilities().instabuild) {
 +            // Paper start
 +            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
 +            if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
-+                if (event.shouldConsume() && !user.abilities.instabuild) {
++                user.awardStat(Stats.ITEM_USED.get(this));
++                if (event.shouldConsume() && !user.getAbilities().instabuild) {
 +                    // Paper end
                      itemstack.shrink(1);
 +                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {  // Paper
 +                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();  // Paper
                  }
  
-                 world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (SnowballItem.random.nextFloat() * 0.4F + 0.8F));
+                 world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
 -            } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
 -                ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +            } else { // Paper
 +                if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
-+                return new InteractionResultHolder<ItemStack>(net.minecraft.world.InteractionResult.FAIL, itemstack); // Paper
++                return InteractionResultHolder.fail(itemstack); // Paper
              }
          }
          // CraftBukkit end
+ 
++        /* // Paper tart - moved up
+         user.awardStat(Stats.ITEM_USED.get(this));
+         // CraftBukkit start - moved up
+         /*
+@@ -0,0 +0,0 @@ public class SnowballItem extends Item {
+             itemstack.subtract(1);
+         }
+         */
++        // Paper end
+ 
+         return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
+     }
 diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
 +++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
-@@ -0,0 +0,0 @@ package net.minecraft.world.item;
- import net.minecraft.sounds.SoundEvents;
- import net.minecraft.sounds.SoundSource;
- import net.minecraft.world.InteractionHand;
-+import net.minecraft.world.InteractionResult;
- import net.minecraft.world.InteractionResultHolder;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.level.Level;
 @@ -0,0 +0,0 @@ public class SplashPotionItem extends ThrowablePotionItem {
  
      @Override
      public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
 +        // Paper start
 +        InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
-+        if (wrapper.getResult() != InteractionResult.FAIL) {
-         world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (SplashPotionItem.random.nextFloat() * 0.4F + 0.8F));
++        if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
+         world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
 -        return super.use(world, user, hand);
 +        }
 +        return wrapper;
@@ -303,49 +241,36 @@ diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/s
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
 +++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
-@@ -0,0 +0,0 @@
- package net.minecraft.world.item;
- 
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.stats.Stats;
- import net.minecraft.world.InteractionHand;
-+import net.minecraft.world.InteractionResult;
- import net.minecraft.world.InteractionResultHolder;
- import net.minecraft.world.entity.player.Player;
- import net.minecraft.world.entity.projectile.ThrownPotion;
 @@ -0,0 +0,0 @@ public class ThrowablePotionItem extends PotionItem {
- 
-             entitypotion.setItem(itemstack);
-             entitypotion.shootFromRotation(user, user.xRot, user.yRot, -20.0F, 0.5F, 1.0F);
--            world.addFreshEntity(entitypotion);
+             ThrownPotion thrownPotion = new ThrownPotion(world, user);
+             thrownPotion.setItem(itemStack);
+             thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F);
+-            world.addFreshEntity(thrownPotion);
 +            // Paper start
-+            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitypotion.getBukkitEntity());
-+            if (event.callEvent() && world.addFreshEntity(entitypotion)) {
-+                if (event.shouldConsume() && !user.abilities.instabuild) {
-+                    itemstack.shrink(1);
-+                } else if (user instanceof ServerPlayer) {
-+                    ((ServerPlayer) user).getBukkitEntity().updateInventory();
++            com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
++            if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
++                if (event.shouldConsume() && !user.getAbilities().instabuild) {
++                    itemStack.shrink(1);
++                } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +                }
 +
 +                user.awardStat(Stats.ITEM_USED.get(this));
 +            } else {
-+                if (user instanceof ServerPlayer) {
-+                    ((ServerPlayer) user).getBukkitEntity().updateInventory();
++                if (user instanceof net.minecraft.server.level.ServerPlayer) {
++                    ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
 +                }
-+                    return new InteractionResultHolder<ItemStack>(InteractionResult.FAIL, itemstack);
++                return InteractionResultHolder.fail(itemStack);
 +            }
 +            // Paper end
          }
  
--        user.awardStat(Stats.ITEM_USED.get(this));
--        if (!user.abilities.instabuild) {
--            itemstack.shrink(1);
 +        /* // Paper start - moved up
-+        entityhuman.b(StatisticList.ITEM_USED.b(this));
-+        if (!entityhuman.abilities.canInstantlyBuild) {
-+            itemstack.subtract(1);
+         user.awardStat(Stats.ITEM_USED.get(this));
+         if (!user.getAbilities().instabuild) {
+             itemStack.shrink(1);
          }
 +        */ // Paper end
  
-         return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
+         return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
      }
diff --git a/patches/server-remapped/Refresh-player-inventory-when-cancelling-PlayerInter.patch b/patches/server/Refresh-player-inventory-when-cancelling-PlayerInter.patch
similarity index 77%
rename from patches/server-remapped/Refresh-player-inventory-when-cancelling-PlayerInter.patch
rename to patches/server/Refresh-player-inventory-when-cancelling-PlayerInter.patch
index 3f0ffb8e8d..801d74c634 100644
--- a/patches/server-remapped/Refresh-player-inventory-when-cancelling-PlayerInter.patch
+++ b/patches/server/Refresh-player-inventory-when-cancelling-PlayerInter.patch
@@ -19,11 +19,11 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
 +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
-                     }
+@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
+                         }
  
-                     if (event.isCancelled()) {
-+                        this.player.refreshContainer(this.player.containerMenu); // Paper - Refresh player inventory
-                         return;
-                     }
-                     // CraftBukkit end
+                         if (event.isCancelled()) {
++                            ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory
+                             return;
+                         }
+                         // CraftBukkit end
diff --git a/patches/server-remapped/Use-asynchronous-Log4j-2-loggers.patch b/patches/server/Use-asynchronous-Log4j-2-loggers.patch
similarity index 77%
rename from patches/server-remapped/Use-asynchronous-Log4j-2-loggers.patch
rename to patches/server/Use-asynchronous-Log4j-2-loggers.patch
index 56d85b045d..d884f4461e 100644
--- a/patches/server-remapped/Use-asynchronous-Log4j-2-loggers.patch
+++ b/patches/server/Use-asynchronous-Log4j-2-loggers.patch
@@ -4,13 +4,25 @@ Date: Tue, 17 Jul 2018 16:42:17 +0200
 Subject: [PATCH] Use asynchronous Log4j 2 loggers
 
 
+diff --git a/build.gradle.kts b/build.gradle.kts
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/build.gradle.kts
++++ b/build.gradle.kts
+@@ -0,0 +0,0 @@ dependencies {
+     }
+     runtimeOnly("org.xerial:sqlite-jdbc:3.34.0")
+     runtimeOnly("mysql:mysql-connector-java:8.0.23") // Paper
++    runtimeOnly("com.lmax:disruptor:3.4.2") // Paper
+ 
+     runtimeOnly("org.apache.maven:maven-resolver-provider:3.8.1")
+     runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.0")
 diff --git a/pom.xml b/pom.xml
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/pom.xml
 +++ b/pom.xml
 @@ -0,0 +0,0 @@
-             <artifactId>log4j-iostreams</artifactId>
-             <scope>compile</scope>
+                 </exclusion>
+             </exclusions>
          </dependency>
 +        <!-- Paper - Async loggers -->
 +        <dependency>
diff --git a/patches/server-remapped/Vanished-players-don-t-have-rights.patch b/patches/server/Vanished-players-don-t-have-rights.patch
similarity index 53%
rename from patches/server-remapped/Vanished-players-don-t-have-rights.patch
rename to patches/server/Vanished-players-don-t-have-rights.patch
index e67bf6e092..40aba05c43 100644
--- a/patches/server-remapped/Vanished-players-don-t-have-rights.patch
+++ b/patches/server/Vanished-players-don-t-have-rights.patch
@@ -4,38 +4,16 @@ Date: Mon, 23 Jul 2018 14:22:26 +0200
 Subject: [PATCH] Vanished players don't have rights
 
 
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
-     private static double viewScale = 1.0D;
-     private final EntityType<?> type;
-     private int id;
--    public boolean blocksBuilding;
-+    public boolean blocksBuilding; public final boolean blocksEntitySpawning() { return this.blocksBuilding; } // Paper - OBFHELPER
-     public final List<Entity> passengers;
-     protected int boardingCooldown;
-     @Nullable
 diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
 +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
-@@ -0,0 +0,0 @@ import java.util.UUID;
- import javax.annotation.Nullable;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.util.Mth;
- import net.minecraft.world.entity.Entity;
- import net.minecraft.world.entity.EntityType;
 @@ -0,0 +0,0 @@ public abstract class Projectile extends Entity {
-     protected boolean canHitEntity(Entity entity) {
          if (!entity.isSpectator() && entity.isAlive() && entity.isPickable()) {
              Entity entity1 = this.getOwner();
--
+ 
 +            // Paper start - Cancel hit for vanished players
-+            if (entity1 instanceof ServerPlayer && entity instanceof ServerPlayer) {
++            if (entity1 instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer) {
 +                org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity();
 +                org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity();
 +                if (!shooter.canSee(collided)) return false;
@@ -63,14 +41,6 @@ diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/level/Level.java
 +++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -0,0 +0,0 @@ import net.minecraft.resources.ResourceLocation;
- import net.minecraft.server.MinecraftServer;
- import net.minecraft.server.level.ChunkHolder;
- import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.sounds.SoundEvent;
- import net.minecraft.sounds.SoundSource;
- import net.minecraft.tags.TagContainer;
 @@ -0,0 +0,0 @@ import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
  import net.minecraft.world.level.storage.LevelData;
  import net.minecraft.world.level.storage.WritableLevelData;
@@ -96,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            return true;
 +        }
 +
-+        voxelshape = voxelshape.offset((double) position.getX(), (double) position.getY(), (double) position.getZ());
++        voxelshape = voxelshape.move((double) position.getX(), (double) position.getY(), (double) position.getZ());
 +        if (voxelshape.isEmpty()) {
 +            return true;
 +        }
@@ -105,19 +75,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        for (int i = 0, len = entities.size(); i < len; ++i) {
 +            Entity entity = entities.get(i);
 +
-+            if (checkCanSee && source instanceof ServerPlayer && entity instanceof ServerPlayer
-+                && !((ServerPlayer) source).getBukkitEntity().canSee(((ServerPlayer) entity).getBukkitEntity())) {
++            if (checkCanSee && source instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer
++                && !((net.minecraft.server.level.ServerPlayer) source).getBukkitEntity().canSee(((net.minecraft.server.level.ServerPlayer) entity).getBukkitEntity())) {
 +                continue;
 +            }
 +
 +            // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity));
 +            // elide the last check since vanilla calls with entity = null
 +            // only we care about the source for the canSee check
-+            if (entity.removed || !entity.blocksEntitySpawning()) {
++            if (entity.isRemoved() || !entity.blocksBuilding) {
 +                continue;
 +            }
 +
-+            if (Shapes.applyOperation(voxelshape, Shapes.of(entity.getBoundingBox()), BooleanOp.AND)) {
++            if (Shapes.joinIsNotEmpty(voxelshape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
 +                return false;
 +            }
 +        }
@@ -125,54 +95,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return true;
 +    }
 +    // Paper end
-+
      @Override
      public boolean isClientSide() {
          return this.isClientSide;
-diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
-+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
-@@ -0,0 +0,0 @@ public abstract class BlockBehaviour {
-             return this.cache != null ? this.cache.collisionShape : this.getCollisionShape(world, pos, CollisionContext.empty());
-         }
- 
-+        public final VoxelShape getCollisionShape(BlockGetter iblockaccess, BlockPos blockposition, CollisionContext voxelshapecollision) { return this.getCollisionShape(iblockaccess, blockposition, voxelshapecollision); } // Paper - OBFHELPER
-         public VoxelShape getCollisionShape(BlockGetter world, BlockPos pos, CollisionContext context) {
-             return this.getBlock().getCollisionShape(this.asState(), world, pos, context);
-         }
-diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
-+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
-@@ -0,0 +0,0 @@ public final class Shapes {
-         return create(new AABB(xMin, yMin, zMin, xMax, yMax, zMax));
-     }
- 
-+    public static final VoxelShape of(AABB axisAlignedbb) { return Shapes.create(axisAlignedbb); } // Paper - OBFHELPER
-     public static VoxelShape create(AABB box) {
-         int i = findBits(box.minX, box.maxX);
-         int j = findBits(box.minY, box.maxY);
-@@ -0,0 +0,0 @@ public final class Shapes {
-         }
-     }
- 
-+    public static final boolean applyOperation(VoxelShape voxelshape, VoxelShape voxelshape1, BooleanOp operatorboolean) { return Shapes.joinIsNotEmpty(voxelshape, voxelshape1, operatorboolean); } // Paper - OBFHELPER
-     public static boolean joinIsNotEmpty(VoxelShape shape1, VoxelShape shape2, BooleanOp predicate) {
-         if (predicate.apply(false, false)) {
-             throw (IllegalArgumentException) Util.pauseInIde((Throwable) (new IllegalArgumentException()));
-diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
-+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
-@@ -0,0 +0,0 @@ public abstract class VoxelShape {
-         return this.shape.isEmpty();
-     }
- 
-+    public final VoxelShape offset(double x, double y, double z) { return this.move(x, y, z); } // Paper - OBFHELPER
-     public VoxelShape move(double x, double y, double z) {
-         return (VoxelShape) (this.isEmpty() ? Shapes.empty() : new ArrayVoxelShape(this.shape, new OffsetDoubleList(this.getCoords(Direction.Axis.X), x), new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y), new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z)));
-     }
 diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
diff --git a/patches/server-remapped/Vex-getSummoner-API.patch b/patches/server/Vex-get-setSummoner-API.patch
similarity index 61%
rename from patches/server-remapped/Vex-getSummoner-API.patch
rename to patches/server/Vex-get-setSummoner-API.patch
index ec35aa9515..75e5f3a21d 100644
--- a/patches/server-remapped/Vex-getSummoner-API.patch
+++ b/patches/server/Vex-get-setSummoner-API.patch
@@ -1,22 +1,13 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Wed, 4 Jul 2018 15:30:22 -0400
-Subject: [PATCH] Vex#getSummoner API
+Subject: [PATCH] Vex#get/setSummoner API
 
-Get's the NPC that summoned this Vex
+Get's the NPC that summoned this Vex and
+Allow setting the vex's summoner
+
+Co-authored-by: BillyGalbreath <Blake.Galbreath@GMail.com>
 
-diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/monster/Vex.java
-+++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-@@ -0,0 +0,0 @@ public class Vex extends Monster {
- 
-     }
- 
-+    public Mob getOwner() { return getOwner(); } // Paper - OBFHELPER
-     public Mob getOwner() {
-         return this.owner;
-     }
 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
@@ -26,10 +17,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
  
 +    // Paper start
++    @Override
 +    public org.bukkit.entity.Mob getSummoner() {
 +        net.minecraft.world.entity.Mob owner = getHandle().getOwner();
 +        return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
 +    }
++
++    @Override
++    public void setSummoner(org.bukkit.entity.Mob summoner) {
++        getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
++    }
 +    // Paper end
 +
      @Override
diff --git a/patches/server-remapped/add-more-information-to-Entity.toString.patch b/patches/server/add-more-information-to-Entity.toString.patch
similarity index 69%
rename from patches/server-remapped/add-more-information-to-Entity.toString.patch
rename to patches/server/add-more-information-to-Entity.toString.patch
index 5996a95492..b0a1eeb914 100644
--- a/patches/server-remapped/add-more-information-to-Entity.toString.patch
+++ b/patches/server/add-more-information-to-Entity.toString.patch
@@ -9,12 +9,12 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/world/entity/Entity.java
 +++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
+@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
      }
  
      public String toString() {
 -        return String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.level == null ? "~NULL~" : this.level.toString(), this.getX(), this.getY(), this.getZ());
-+        return String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cx=%d, cz=%d, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getName().getString(), Integer.valueOf(this.id), this.uuid.toString(), this.level == null ? "~NULL~" : this.level.toString(), Double.valueOf(this.getX()), Double.valueOf(this.getY()), Double.valueOf(this.getZ()), xChunk, zChunk, this.tickCount, this.valid, this.removed}); // Paper - add more information
++        return String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b, rR=%s]", new Object[] { this.getClass().getSimpleName(), this.getName().getString(), Integer.valueOf(this.id), this.uuid.toString(), this.level == null ? "~NULL~" : this.level.toString(), Double.valueOf(this.getX()), Double.valueOf(this.getY()), Double.valueOf(this.getZ()), this.chunkPosition(), this.tickCount, this.valid, this.removalReason}); // Paper - add more information
      }
  
      public boolean isInvulnerableTo(DamageSource damageSource) {