diff --git a/Paper-MojangAPI/pom.xml b/Paper-MojangAPI/pom.xml
index d0da7daf4..4c7c62c78 100644
--- a/Paper-MojangAPI/pom.xml
+++ b/Paper-MojangAPI/pom.xml
@@ -10,7 +10,7 @@
com.destroystokyo.paper
paper-mojangapi
- 1.15.2-R0.1-SNAPSHOT
+ 1.16.1-R0.1-SNAPSHOT
jar
Paper-MojangAPI
diff --git a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch
index bec046d55..46d33f360 100644
--- a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch
+++ b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch
@@ -66,11 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (movingobjectposition != null) {
+ // Paper end
this.a(movingobjectposition);
- // CraftBukkit start
- if (this.dead) {
- org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition);
- }
- // CraftBukkit end
+ } // Paper
}
diff --git a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch
index f5aaed273..ed9e673a9 100644
--- a/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch
+++ b/Spigot-Server-Patches/Add-configurable-portal-search-radius.patch
@@ -41,8 +41,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
Location enter = this.getBukkitEntity().getLocation();
Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), d0, d1, d2, f1, f);
-- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == World.THE_END ? 0 : 16);
-+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == World.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius);
+- PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == DimensionManager.THE_END ? 0 : 16);
++ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, worldserver.paperConfig.portalSearchRadius, true, resourcekey == DimensionManager.THE_END ? 0 : worldserver.paperConfig.portalCreateRadius);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null) {
return null;
diff --git a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch b/Spigot-Server-Patches/Add-permission-for-command-blocks.patch
deleted file mode 100644
index 5dd95643b..000000000
--- a/Spigot-Server-Patches/Add-permission-for-command-blocks.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Mariell Hoversholm
-Date: Sat, 16 May 2020 10:05:30 +0200
-Subject: [PATCH] Add permission for command blocks
-
-
-diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/BlockCommand.java
-+++ b/src/main/java/net/minecraft/server/BlockCommand.java
-@@ -0,0 +0,0 @@ public class BlockCommand extends BlockTileEntity {
- public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) {
- TileEntity tileentity = world.getTileEntity(blockposition);
-
-- if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) {
-+ if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
- entityhuman.a((TileEntityCommand) tileentity);
- return EnumInteractionResult.SUCCESS;
- } else {
-diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
-+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
-@@ -0,0 +0,0 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener {
- }
-
- public boolean a(EntityHuman entityhuman) {
-- if (!entityhuman.isCreativeAndOp()) {
-+ if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
- return false;
- } else {
- if (entityhuman.getWorld().isClientSide) {
-diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/PlayerConnection.java
-+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
-@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
- PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer());
- if (!this.minecraftServer.getEnableCommandBlock()) {
- this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
-- } else if (!this.player.isCreativeAndOp()) {
-+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
- this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
- } else {
- CommandBlockListenerAbstract commandblocklistenerabstract = null;
-@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
- PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer());
- if (!this.minecraftServer.getEnableCommandBlock()) {
- this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
-- } else if (!this.player.isCreativeAndOp()) {
-+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
- this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
- } else {
- CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world);
-diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
-+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
-@@ -0,0 +0,0 @@ public class PlayerInteractManager {
- TileEntity tileentity = this.world.getTileEntity(blockposition);
- Block block = iblockdata.getBlock();
-
-- if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) {
-+ if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
- this.world.notify(blockposition, iblockdata, iblockdata, 3);
- return false;
- } else if (this.player.a((World) this.world, blockposition, this.gamemode)) {
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
-@@ -0,0 +0,0 @@ public final class CraftDefaultPermissions {
- DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent);
- DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent);
- DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent);
-+ DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper
- // Spigot end
- parent.recalculatePermissibles();
- }
diff --git a/Spigot-Server-Patches/Add-villager-reputation-API.patch b/Spigot-Server-Patches/Add-villager-reputation-API.patch
index d37d07d18..46409b3cd 100644
--- a/Spigot-Server-Patches/Add-villager-reputation-API.patch
+++ b/Spigot-Server-Patches/Add-villager-reputation-API.patch
@@ -24,12 +24,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
- this.bL = 0;
+ this.bK = 0;
}
-+ public Reputation getReputation() { return this.eN(); } // Paper - OBFHELPER
- public Reputation eN() {
- return this.bG;
++ public Reputation getReputation() { return this.fj(); } // Paper - OBFHELPER
+ public Reputation fj() {
+ return this.bF;
}
diff --git a/src/main/java/net/minecraft/server/Reputation.java b/src/main/java/net/minecraft/server/Reputation.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
diff --git a/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch b/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch
index 9f68c9134..11429dfed 100644
--- a/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch
+++ b/Spigot-Server-Patches/Delay-Chunk-Unloads-based-on-Player-Movement.patch
@@ -85,12 +85,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int compareTo(Ticket> ticket) {
@@ -0,0 +0,0 @@ public final class Ticket implements Comparable> {
- return this.b;
- }
-
-+ protected void setCurrentTick(long i) { a(i); } // Paper - OBFHELPER
- protected void a(long i) {
- this.d = i;
}
protected boolean b(long i) {
diff --git a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch b/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch
deleted file mode 100644
index df47863da..000000000
--- a/Spigot-Server-Patches/Ensure-Entity-AABB-s-are-never-invalid.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Sun, 10 May 2020 22:12:46 -0400
-Subject: [PATCH] Ensure Entity AABB's are never invalid
-
-If anything used setPositionRaw, it left potential for an AABB
-to be left stale at their old location, which could cause massive
-AABB boxes if movement ever then got called on the new position.
-
-This guarantees any time we set the entities position, we also
-update their AABB.
-
-diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Entity.java
-+++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
-
- public void setPosition(double d0, double d1, double d2) {
- this.setPositionRaw(d0, d1, d2);
-- float f = this.size.width / 2.0F;
-- float f1 = this.size.height;
--
-- this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
-+ // Paper start - move into setPositionRaw
-+ //float f = this.size.width / 2.0F;
-+ //float f1 = this.size.height;
-+ //this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
-+ // Paper end
- if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit
- }
-
-@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
- return new AxisAlignedBB(vec3d, vec3d1);
- }
-
-+ public final void setBoundingBox(AxisAlignedBB axisalignedbb) { a(axisalignedbb); } // Paper - OBFHELPER
- public void a(AxisAlignedBB axisalignedbb) {
- // CraftBukkit start - block invalid bounding boxes
- double minX = axisalignedbb.minX,
-@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
- }
-
- public void setPositionRaw(double d0, double d1, double d2) {
-+ // Paper start - never allow AABB to become desynced from position
-+ // hanging has its own special logic
-+ if (!(this instanceof EntityHanging) && (locX != d0 || locY != d1 || locZ != d2)) {
-+ float f = this.size.width / 2.0F;
-+ float f1 = this.size.height;
-+ this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
-+ }
-+ // Paper end
- this.locX = d0;
- this.locY = d1;
- this.locZ = d2;
diff --git a/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
index a28cbb232..18a1927e0 100644
--- a/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
+++ b/Spigot-Server-Patches/Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
@@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public boolean a() {
+ if (!getRaider().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || !getRaider().canPickupLoot()) return false; // Paper - respect game and entity rules for picking up items
-+
- Raid raid = this.b.eE();
+ Raid raid = this.b.fb();
- if (this.b.eF() && !this.b.eE().a() && this.b.es() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) {
+ if (this.b.fc() && !this.b.fb().a() && this.b.eO() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) {
diff --git a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch
index f350339dd..1d08fe4d3 100644
--- a/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch
+++ b/Spigot-Server-Patches/Ensure-safe-gateway-teleport.patch
@@ -14,16 +14,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
List list = this.world.a(Entity.class, new AxisAlignedBB(this.getPosition()));
-
- if (!list.isEmpty()) {
-- this.a(((Entity) list.get(0)).getRootVehicle());
-- }
-+ // Paper start
-+ for (Entity entity : list) {
-+ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) {
-+ this.a(entity);
-+ break;
-+ }
+- this.a((Entity) list.get(this.world.random.nextInt(list.size())));
++ // Paper start
++ for (Entity entity : list) {
++ if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) {
++ this.a(entity);
++ break;
+ }
-+ // Paper end
+ }
++ // Paper end
if (this.age % 2400L == 0L) {
this.h();
diff --git a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch
index 89ac9db8d..2daa03847 100644
--- a/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch
+++ b/Spigot-Server-Patches/EntityShootBowEvent-consumeArrow-and-getArrowItem-AP.patch
@@ -75,14 +75,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -0,0 +0,0 @@ import net.minecraft.server.GeneratorAccess;
- import net.minecraft.server.IBlockData;
- import net.minecraft.server.IChatBaseComponent;
- import net.minecraft.server.IInventory;
-+import net.minecraft.server.IProjectile;
- import net.minecraft.server.ItemActionContext;
- import net.minecraft.server.ItemStack;
- import net.minecraft.server.Items;
@@ -0,0 +0,0 @@ public class CraftEventFactory {
/**
* EntityShootBowEvent
diff --git a/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch b/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch
index d08a9ac7a..374b7dc20 100644
--- a/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch
+++ b/Spigot-Server-Patches/Expose-Arrow-getItemStack.patch
@@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
-@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile {
+@@ -0,0 +0,0 @@ public abstract class EntityArrow extends IProjectile {
}
}
diff --git a/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch b/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch
deleted file mode 100644
index 6226dbf04..000000000
--- a/Spigot-Server-Patches/Fix-CraftServer.unloadWorld-Leak.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Fri, 8 May 2020 20:30:58 -0400
-Subject: [PATCH] Fix CraftServer.unloadWorld Leak
-
-The dimension manager was still registered which leaked the entire World
-
-diff --git a/src/main/java/net/minecraft/server/DimensionManager.java b/src/main/java/net/minecraft/server/DimensionManager.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/DimensionManager.java
-+++ b/src/main/java/net/minecraft/server/DimensionManager.java
-@@ -0,0 +0,0 @@ public class DimensionManager implements MinecraftSerializable {
- private final boolean hasSkyLight;
- private final GenLayerZoomer genLayerZoomer;
-
-+ // Paper start
-+ public static void unregister(String s, DimensionManager dimensionmanager) {
-+ if (dimensionmanager == OVERWORLD || dimensionmanager == NETHER || dimensionmanager == THE_END) { return; } // do not unregister the default worlds
-+ MCUtil.MAIN_EXECUTOR.execute(() -> {
-+ RegistryMaterials registry = (RegistryMaterials) IRegistry.DIMENSION_TYPE;
-+ registry.deleteValue(new MinecraftKey(s), dimensionmanager);
-+ });
-+ }
-+ // Paper end
- public static DimensionManager register(String s, DimensionManager dimensionmanager) {
- return (DimensionManager) IRegistry.a(IRegistry.DIMENSION_TYPE, dimensionmanager.id, s, dimensionmanager);
- }
-diff --git a/src/main/java/net/minecraft/server/RegistryID.java b/src/main/java/net/minecraft/server/RegistryID.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/RegistryID.java
-+++ b/src/main/java/net/minecraft/server/RegistryID.java
-@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
- public class RegistryID implements Registry {
-
- private static final Object a = null;
-- private K[] b;
-+ private K[] b; // Paper - diff below
- private int[] c;
-- private K[] d;
-+ private K[] d; // Paper - diff below
- private int e;
- private int f;
- private java.util.BitSet usedIds; // Paper
-+ // Paper start
-+ public void removeValue(K value) {
-+ removeValue(value, this.b);
-+ removeValue(value, this.d);
-+ rehash(this.b.length);
-+ }
-+ public void removeValue(K value, K[] arr) {
-+ for (int i = 0; i < arr.length; i++) {
-+ K k = arr[i];
-+ if (k == value) {
-+ arr[i] = null;
-+ }
-+ }
-+ }
-
- public RegistryID(int i) {
- i = (int) ((float) i / 0.8F);
-@@ -0,0 +0,0 @@ public class RegistryID implements Registry {
- return this.e;
- }
-
-+ private void rehash(int i) { d(i); } // Paper - OBFHELPER
- private void d(int i) {
- K[] ak = this.b;
- int[] aint = this.c;
-diff --git a/src/main/java/net/minecraft/server/RegistryMaterials.java b/src/main/java/net/minecraft/server/RegistryMaterials.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/RegistryMaterials.java
-+++ b/src/main/java/net/minecraft/server/RegistryMaterials.java
-@@ -0,0 +0,0 @@ public class RegistryMaterials extends IRegistryWritable {
- private int V;
-
- public RegistryMaterials() {}
-+ public T deleteValue(MinecraftKey minecraftkey, T value) {
-+ this.b.removeValue(value); // Diff 1
-+ this.d = null; // Diff 2
-+ return this.c.remove(minecraftkey); // Diff 3
-+ }
-
- @Override
- public V a(int i, MinecraftKey minecraftkey, V v0) {
-- this.b.a(v0, i);
-+ this.b.a(v0, i); // Paper - diff above 1
- Validate.notNull(minecraftkey);
- Validate.notNull(v0);
-- this.d = null;
-+ this.d = null; // Diff 2
- if (this.c.containsKey(minecraftkey)) {
- RegistryMaterials.LOGGER.debug("Adding duplicate key '{}' to registry", minecraftkey);
- }
-
-- this.c.put(minecraftkey, v0);
-+ this.c.put(minecraftkey, v0); // Paper - diff3
- if (this.V <= i) {
- this.V = i + 1;
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -0,0 +0,0 @@ import net.minecraft.server.EntityPlayer;
- import net.minecraft.server.EnumDifficulty;
- import net.minecraft.server.EnumGamemode;
- import net.minecraft.server.IRecipe;
-+import net.minecraft.server.IRegistry;
- import net.minecraft.server.Item;
- import net.minecraft.server.ItemWorldMap;
- import net.minecraft.server.Items;
-@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
- }
-
- worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH));
-- console.worldServer.remove(handle.getWorldProvider().getDimensionManager());
-+ // Paper start
-+ DimensionManager dimensionManager = handle.getWorldProvider().getDimensionManager();
-+ DimensionManager.unregister(world.getName().toLowerCase(java.util.Locale.ENGLISH), dimensionManager);
-+ console.worldServer.remove(dimensionManager);
-+ // Paper end
- return true;
- }
-
diff --git a/Spigot-Server-Patches/Fix-Light-Command.patch b/Spigot-Server-Patches/Fix-Light-Command.patch
index 098b71e7c..2fbdef843 100644
--- a/Spigot-Server-Patches/Fix-Light-Command.patch
+++ b/Spigot-Server-Patches/Fix-Light-Command.patch
@@ -161,6 +161,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.mailboxWorldGen = this.p.a(threadedmailbox, false);
this.mailboxMain = this.p.a(mailbox, false);
+ this.mailboxLight = this.p.a(lightthreaded, false);// Paper
- this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false));
+ this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper
this.l = supplier;
diff --git a/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch b/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch
index e854d6901..f986ea7e3 100644
--- a/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch
+++ b/Spigot-Server-Patches/Fix-enderdragon-exp-dupe.patch
@@ -11,27 +11,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
- public float bx;
- public float by;
- public boolean bz;
-- public int bA;
-+ public int bA; public final int getDeathTicks() { return this.bA; } public final void setDeathTicks(final int value) { this.bA = value; } // Paper
- public float bB;
- @Nullable
- public EntityEnderCrystal currentEnderCrystal;
-@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
- public void b(NBTTagCompound nbttagcompound) {
- super.b(nbttagcompound);
- nbttagcompound.setInt("DragonPhase", this.bO.a().getControllerPhase().b());
-+ nbttagcompound.setInt("Paper.DeathTick", this.getDeathTicks()); // Paper
+ public void saveData(NBTTagCompound nbttagcompound) {
+ super.saveData(nbttagcompound);
+ nbttagcompound.setInt("DragonPhase", this.bN.a().getControllerPhase().b());
++ nbttagcompound.setInt("Paper.DeathTick", this.deathAnimationTicks); // Paper
}
@Override
@@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
if (nbttagcompound.hasKey("DragonPhase")) {
- this.bO.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase")));
+ this.bN.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase")));
}
-+ this.setDeathTicks(nbttagcompound.getInt("Paper.DeathTick")); // Paper
++ this.deathAnimationTicks = nbttagcompound.getInt("Paper.DeathTick"); // Paper
}
diff --git a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch
index 2892b633b..6001012c5 100644
--- a/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch
+++ b/Spigot-Server-Patches/Fix-items-vanishing-through-end-portal.patch
@@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (blockposition == null) { // CraftBukkit
- if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) {
+ if (this.world.getTypeKey() == DimensionManager.THE_END && worldserver.getTypeKey() == DimensionManager.OVERWORLD) { // CraftBukkit
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
+ this.world.getChunkAtWorldCoords(this.world.getSpawn());
+ // Paper end
diff --git a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch
index 4e5bd971a..665a49024 100644
--- a/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch
+++ b/Spigot-Server-Patches/Fix-piston-physics-inconsistency-MC-188840.patch
@@ -63,20 +63,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
blockposition3 = blockposition3.shift(enumdirection1);
map.remove(blockposition3);
world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68);
-- world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false));
+ // Paper start - fix a variety of piston desync dupes
+ if (!allowDesync) {
+ iblockdata1 = world.getType(oldPos);
+ map.replace(oldPos, iblockdata1);
+ }
-+ world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false));
+ world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false));
+ if (!allowDesync) {
+ world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block
+ }
+ // Paper end - fix a variety of piston desync dupes
- --j;
- aiblockdata[j] = iblockdata1;
+ aiblockdata[j++] = iblockdata1;
}
+
diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/TileEntityPiston.java
@@ -89,4 +88,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.world.setTypeAndData(this.position, this.a, com.destroystokyo.paper.PaperConfig.allowPistonDuplication ? 84 : (84 | 2)); // Paper - force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
Block.a(this.a, iblockdata, this.world, this.position, 3);
} else {
- if (iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) {
+ if (iblockdata.b(BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) {
diff --git a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch
index df33fd65b..d3df7489a 100644
--- a/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch
+++ b/Spigot-Server-Patches/Fix-this-stupid-bullshit.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main {
Calendar deadline = Calendar.getInstance();
- deadline.add(Calendar.DAY_OF_YEAR, -3);
+ deadline.add(Calendar.DAY_OF_YEAR, -1);
if (buildDate.before(deadline.getTime())) {
- System.err.println("*** Error, this build is outdated ***");
+ // Paper start - This is some stupid bullshit
diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
index 582ad169e..ee4cbb798 100644
--- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
+++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
@@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public final BlockPosition asPosition() { return l(); } // Paper - OBFHELPER
public BlockPosition l() {
- return new BlockPosition(this.x << 4, 0, this.z << 4);
+ return new BlockPosition(this.d(), 0, this.e());
}
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@@ -113,8 +113,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
}
- private static int a(ArraySetSorted> arraysetsorted) {
-+ AsyncCatcher.catchOp("ChunkMapDistance::getHighestTicketLevel"); // Paper
+ private static int getLowestTicketLevel(ArraySetSorted> arraysetsorted) {
++ AsyncCatcher.catchOp("ChunkMapDistance::getLowestTicketLevel"); // Paper
return !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.b()).b() : PlayerChunkMap.GOLDEN_TICKET + 1;
}
@@ -122,9 +122,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean a(PlayerChunkMap playerchunkmap) {
//this.f.a(); // Paper - no longer used
-+ AsyncCatcher.catchOp("DistanceManagerTick");
++ AsyncCatcher.catchOp("DistanceManagerTick"); // Paper
this.g.a();
- int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE);
+ int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE);
boolean flag = i != 0;
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
@@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean addTicket(long i, Ticket> ticket) { // CraftBukkit - void -> boolean
+ AsyncCatcher.catchOp("ChunkMapDistance::addTicket"); // Paper
ArraySetSorted> arraysetsorted = this.e(i);
- int j = a(arraysetsorted);
+ int j = getLowestTicketLevel(arraysetsorted);
Ticket> ticket1 = (Ticket) arraysetsorted.a(ticket); // CraftBukkit - decompile error
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
}
@@ -157,18 +157,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean removeTicket(long i, Ticket> ticket) { // CraftBukkit - void -> boolean
+ AsyncCatcher.catchOp("ChunkMapDistance::removeTicket"); // Paper
ArraySetSorted> arraysetsorted = this.e(i);
-+ int oldLevel = a(arraysetsorted); // Paper
++ int oldLevel = getLowestTicketLevel(arraysetsorted); // Paper
boolean removed = false; // CraftBukkit
if (arraysetsorted.remove(ticket)) {
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
- if (arraysetsorted.isEmpty()) {
this.tickets.remove(i);
}
--
-- this.e.b(i, a(arraysetsorted), false);
-+ int newLevel = a(arraysetsorted); // Paper
-+ if (newLevel > oldLevel) this.e.b(i, newLevel, false); // Paper
+
+- this.ticketLevelTracker.update(i, getLowestTicketLevel(arraysetsorted), false);
++ int newLevel = getLowestTicketLevel(arraysetsorted); // Paper
++ if (newLevel > oldLevel) this.ticketLevelTracker.update(i, newLevel, false); // Paper
return removed; // CraftBukkit
}
@@ -317,6 +316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Ticket> ticket = new Ticket<>(TicketType.PLAYER, 33, coords); // Paper - no-tick view distance
if (flag1) {
+- ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> {
+ scheduleChunkLoad(i, MinecraftServer.currentTick, j, (priority) -> { // Paper - smarter ticket delay based on frustum and distance
+ // Paper start - recheck its still valid if not cancel
+ if (!isChunkInRange(i)) {
@@ -337,16 +337,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return;
+ }
+ // Paper end
- ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
++ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
ChunkMapDistance.this.m.execute(() -> {
- if (this.c(this.c(i))) {
+ if (isChunkInRange(i)) { if (!hasPlayerTicket(coords, 33)) { // Paper - high priority might of already added it
ChunkMapDistance.this.addTicket(i, ticket);
ChunkMapDistance.this.l.add(i);
- } else {
-+ }
-+ } else { // Paper
- ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
+- ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> {
++ }} else { // Paper
++ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
}, i, false));
}
@@ -357,7 +357,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}));
+ }); // Paper
} else {
- ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
+ ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> {
ChunkMapDistance.this.m.execute(() -> {
ChunkMapDistance.this.removeTicket(i, ticket);
+ ChunkMapDistance.this.clearPriorityTickets(coords); // Paper
@@ -562,11 +562,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean a(@Nullable PlayerChunk playerchunk, int i) {
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
- return this.serverThreadQueue.executeNext();
}
-- private boolean tickDistanceManager() {
-+ public boolean tickDistanceManager() { // Paper - public
+ public boolean tickDistanceManager() { // Paper - private -> public
+ if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper
boolean flag = this.chunkMapDistance.a(this.playerChunkMap);
boolean flag1 = this.playerChunkMap.b();
@@ -611,7 +609,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Yes, this doesn't match Vanilla, but it's the best we can do for now.
// If this is an issue, PRs are welcome
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
- if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
+ if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick();
}
+ if (valid && isAlive() && playerConnection != null) ((WorldServer)world).getChunkProvider().playerChunkMap.checkHighPriorityChunks(this); // Paper
@@ -844,11 +842,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// note: Here is a very good place to add callbacks to logic waiting on this.
Chunk entityTickingChunk = either.left().get();
@@ -0,0 +0,0 @@ public class PlayerChunk {
- this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
}
--
-- this.w.a(this.location, this::k, this.ticketLevel, this::d);
+
+- this.v.a(this.location, this::k, this.ticketLevel, this::d);
+ // Paper start - raise IO/load priority if priority changes, use our preferred priority
+ priorityBoost = chunkMap.chunkDistanceManager.getChunkPriority(location);
+ int priority = getDemandedPriority();
@@ -862,7 +859,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
+ }
+ if (getCurrentPriority() != priority) {
-+ this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
++ this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
+ int neighborsPriority = getNeighborsPriority();
+ this.neighbors.forEach((neighbor, neighborDesired) -> neighbor.setNeighborPriority(this, neighborsPriority));
+ }
@@ -896,6 +893,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+ public final WorldServer world;
+ private final LightEngineThreaded lightEngine;
+ private final IAsyncTaskHandler executor;
++ final java.util.concurrent.Executor mainInvokingExecutor; // Paper
+ public final ChunkGenerator chunkGenerator;
+ private final Supplier l; public final Supplier getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
+ private final VillagePlace m;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override
@@ -912,6 +917,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (queued == null) {
return;
}
+@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+ this.world = worldserver;
+ this.chunkGenerator = chunkgenerator;
+ this.executor = iasynctaskhandler;
++ // Paper start
++ this.mainInvokingExecutor = (run) -> {
++ if (MCUtil.isMainThread()) {
++ run.run();
++ } else {
++ iasynctaskhandler.execute(run);
++ }
++ };
++ // Paper end
+ ThreadedMailbox threadedmailbox = ThreadedMailbox.a(executor, "worldgen");
+
+ iasynctaskhandler.getClass();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.playerViewDistanceTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
(EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@@ -1105,8 +1126,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
long i = playerchunk.i().pair();
playerchunk.getClass();
-- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel)); // CraftBukkit - decompile error
-+ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // CraftBukkit - decompile error // Paper - final loads are always urgent!
+- mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel));
++ mailbox.a(ChunkTaskQueueSorter.a(runnable, i, () -> 1)); // Paper - final loads are always urgent!
});
}
@@ -1138,7 +1159,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (updatingChunk != null) {
return updatingChunk.getEntityTickingFuture();
@@ -0,0 +0,0 @@ public abstract class PlayerList {
- entityplayer, finalWorldserver, networkmanager, playerconnection,
+ entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection,
nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName
);
- //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair());
@@ -1148,7 +1169,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class PlayerList {
SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress();
- EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(DimensionManager.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD)));
+ EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(World.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(World.OVERWORLD)));
+ entity.isRealPlayer = true; // Paper
Player player = entity.getBukkitEntity();
PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress());
@@ -1158,7 +1179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
+ entityplayer1.forceCheckHighPriority(); // Player
- while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
+ while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ());
}
diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java
@@ -1173,6 +1194,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected Ticket(TicketType tickettype, int i, T t0) {
this.a = tickettype;
+@@ -0,0 +0,0 @@ public final class Ticket implements Comparable> {
+ return this.b;
+ }
+
++ public final void setCurrentTick(long i) { this.a(i); } // Paper - OBFHELPER
+ protected void a(long i) {
+ this.d = i;
+ }
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/TicketType.java
diff --git a/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch b/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch
deleted file mode 100644
index afa783e78..000000000
--- a/Spigot-Server-Patches/Implement-JellySquid-s-Entity-Collision-optimisation.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: JellySquid
-Date: Sat, 9 May 2020 16:25:21 -0400
-Subject: [PATCH] Implement JellySquid's Entity Collision optimisations patch
-
-Optimizes Full Block voxel collisions, and removes streams from Entity collisions
-
-Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
-you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.15.x/fabric (Yarn mappings)
-
-diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/ICollisionAccess.java
-+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
-
- if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
- VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
-- VoxelShape voxelshape3 = voxelshape2.a((double) k1, (double) l1, (double) i2);
-
-- if (VoxelShapes.c(voxelshape, voxelshape3, OperatorBoolean.AND)) {
-- consumer.accept(voxelshape3);
-- return true;
-+ // Paper start - Lithium Collision Optimizations
-+ if (voxelshape2 == VoxelShapes.empty()) {
-+ continue;
-+ }
-+
-+ if (voxelshape2 == VoxelShapes.fullCube()) {
-+ if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
-+ consumer.accept(voxelshape2.offset(x, y, z));
-+ return true;
-+ }
-+ } else {
-+ VoxelShape shape = voxelshape2.offset(x, y, z);
-+ if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
-+ consumer.accept(shape);
-+ return true;
-+ }
-+ // Paper end
- }
- }
- }
-diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/IEntityAccess.java
-+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
-@@ -0,0 +0,0 @@ public interface IEntityAccess {
- // Paper end - optimise hard collision
-
- default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) {
-- if (axisalignedbb.a() < 1.0E-7D) {
-+ // Paper start - remove streams from entity collision
-+ if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
- return Stream.empty();
-- } else {
-- AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D);
-- Stream stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision
-- return !set.contains(entity1);
-- }).filter((entity1) -> {
-- return entity == null || !entity.isSameVehicle(entity1);
-- }).flatMap((entity1) -> {
-- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override
-- }).filter(Objects::nonNull);
--
-- return stream.filter(axisalignedbb1::c).map(VoxelShapes::a);
-+
- }
-+ AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
-+ List entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
-+ List shapes = new java.util.ArrayList<>();
-+
-+ for (Entity otherEntity : entities) {
-+ if (!set.isEmpty() && set.contains(otherEntity)) {
-+ continue;
-+ }
-+
-+ if (entity != null && entity.isSameVehicle(otherEntity)) {
-+ continue;
-+ }
-+
-+ AxisAlignedBB otherEntityBox = otherEntity.getCollisionBox();
-+
-+ if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
-+ shapes.add(VoxelShapes.of(otherEntityBox));
-+ }
-+
-+ if (entity != null) {
-+ AxisAlignedBB otherEntityHardBox = entity.getHardCollisionBox(otherEntity);
-+
-+ if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
-+ shapes.add(VoxelShapes.of(otherEntityHardBox));
-+ }
-+ }
-+ }
-+
-+ return shapes.stream();
-+ // Paper end
- }
-
- @Nullable
diff --git a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch
index 3d44288fc..731e33773 100644
--- a/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch
+++ b/Spigot-Server-Patches/Implement-PlayerLocaleChangeEvent.patch
@@ -25,6 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.locale);
this.server.server.getPluginManager().callEvent(event);
}
+ this.locale = packetplayinsettings.locale;
this.clientViewDistance = packetplayinsettings.viewDistance;
// CraftBukkit end
+ // Paper start - add PlayerLocaleChangeEvent
diff --git a/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch b/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch
index 2fa7eecbd..b18c0d501 100644
--- a/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch
+++ b/Spigot-Server-Patches/Improve-Chunk-Status-Transition-Speed.patch
@@ -57,30 +57,6 @@ diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/j
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
- public final WorldServer world;
- private final LightEngineThreaded lightEngine;
- private final IAsyncTaskHandler executor;
-+ final java.util.concurrent.Executor mainInvokingExecutor; // Paper
- public final ChunkGenerator> chunkGenerator;
- private final Supplier l; public final Supplier getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
- private final VillagePlace m;
-@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
- this.world = worldserver;
- this.chunkGenerator = chunkgenerator;
- this.executor = iasynctaskhandler;
-+ // Paper start - optimize chunk status progression without jumping through thread pool
-+ this.mainInvokingExecutor = (run) -> {
-+ if (MCUtil.isMainThread()) {
-+ run.run();
-+ } else {
-+ iasynctaskhandler.execute(run);
-+ }
-+ };
-+ // Paper end
- ThreadedMailbox threadedmailbox = ThreadedMailbox.a(executor, "worldgen");
-
- iasynctaskhandler.getClass();
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return either.mapLeft((list) -> {
return (Chunk) list.get(list.size() / 2);
@@ -118,6 +94,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return;
+ }
+ // Paper end
- this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error
+ this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable));
});
}
diff --git a/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch b/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch
deleted file mode 100644
index 8b6545fd6..000000000
--- a/Spigot-Server-Patches/MC-183249-Don-t-generate-Carving-Masks-BitSet-unless.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Sat, 9 May 2020 12:11:47 -0400
-Subject: [PATCH] MC-183249: Don't generate Carving Masks BitSet unless needed
-
-This was using SIGNIFICANT amounts of memory allocating many
-long[]'s for BitSets for every ProtoChunk in the cache that had
-been unloaded and reloaded.
-
-This will result in a nice memory reduction.
-
-diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
-@@ -0,0 +0,0 @@ public class ChunkRegionLoader {
- for (int l = 0; l < k; ++l) {
- WorldGenStage.Features worldgenstage_features = aworldgenstage_features[l];
-
-- nbttagcompound3.setByteArray(worldgenstage_features.toString(), ichunkaccess.a(worldgenstage_features).toByteArray());
-+ // Paper start - don't create carving mask bitsets if not even at that chunk status yet
-+ BitSet mask = protochunk.getCarvingMaskIfSet(worldgenstage_features);
-+ if (mask != null) {
-+ nbttagcompound3.setByteArray(worldgenstage_features.toString(), mask.toByteArray());
-+ }
-+ // Paper end
- }
-
- nbttagcompound1.set("CarvingMasks", nbttagcompound3);
-diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/ProtoChunk.java
-+++ b/src/main/java/net/minecraft/server/ProtoChunk.java
-@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess {
- private final ProtoChunkTickList q;
- private final ProtoChunkTickList r;
- private long s;
-- private final Map t;
-+ private final Map t;public BitSet getCarvingMaskIfSet(WorldGenStage.Features worldgenstage_features) { return this.t.get(worldgenstage_features); } // Paper
-+ // Paper end
- private volatile boolean u;
- private final World world; // Paper - Anti-Xray - Add world
-
diff --git a/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch b/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch
index 5dfc5efb2..5a84de14a 100644
--- a/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch
+++ b/Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch
@@ -10,8 +10,8 @@ diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/ja
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockPosition.java
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
-@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
- return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()}));
+@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
+ this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
}
+ public static long getAdjacent(int baseX, int baseY, int baseZ, EnumDirection enumdirection) { return asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); } // Paper
@@ -25,17 +25,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static int b(long i) {
-- return (int) (i << 64 - BlockPosition.k - BlockPosition.c >> 64 - BlockPosition.c);
+- return (int) (i << 64 - BlockPosition.m - BlockPosition.f >> 64 - BlockPosition.f);
+ return (int) (i >> 38); // Paper - simplify/inline
}
public static int c(long i) {
-- return (int) (i << 64 - BlockPosition.f >> 64 - BlockPosition.f);
-+ return (int) ((i << 52) >> 52); // Paper - simplify/inline
+- return (int) (i << 64 - BlockPosition.h >> 64 - BlockPosition.h);
++ return (int) ((i << 26) >> 38); // Paper - simplify/inline
}
public static int d(long i) {
-- return (int) (i << 64 - BlockPosition.j - BlockPosition.d >> 64 - BlockPosition.d);
+- return (int) (i << 64 - BlockPosition.l - BlockPosition.g >> 64 - BlockPosition.g);
+ return (int) ((i << 26) >> 38); // Paper - simplify/inline
}
@@ -44,13 +44,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new BlockPosition((int) (i >> 38), (int) ((i << 52) >> 52), (int) ((i << 26) >> 38)); // Paper - simplify/inline
}
+ public long asLong() {
+@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
+
public static long asLong(int x, int y, int z) { return a(x, y, z); } // Paper - OBFHELPER
public static long a(int i, int j, int k) {
- long l = 0L;
-
-- l |= ((long) i & BlockPosition.g) << BlockPosition.k;
-- l |= ((long) j & BlockPosition.h) << 0;
-- l |= ((long) k & BlockPosition.i) << BlockPosition.j;
+- l |= ((long) i & BlockPosition.i) << BlockPosition.m;
+- l |= ((long) j & BlockPosition.j) << 0;
+- l |= ((long) k & BlockPosition.k) << BlockPosition.l;
- return l;
+ return (((long) i & (long) 67108863) << 38) | (((long) j & (long) 4095)) | (((long) k & (long) 67108863) << 12); // Paper - inline constants and simplify
}
@@ -104,75 +107,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int k = b(blockposition.getZ());
-
- return (short) (i << 8 | k << 4 | j);
-+ return (short) ((blockposition.x & 15) << 8 | (blockposition.z & 15) << 4 | blockposition.y & 15); // Paper - simplify/inline
++ return (short) ((blockposition.getX() & 15) << 8 | (blockposition.getZ() & 15) << 4 | blockposition.getY() & 15); // Paper - simplify/inline
}
public static int c(int i) {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
- }
-
- public static int b(long i) {
-- return (int) (i << 0 >> 42);
-+ return (int) (i >> 42); // Paper
- }
-
- public static int c(long i) {
-@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
- return (int) (i << 22 >> 42);
- }
-
-- public int a() {
-- return this.getX();
-+ public final int a() { // Paper
-+ return x; // Paper
- }
-
-- public int b() {
-- return this.getY();
-+ public final int b() { // Paper
-+ return y; // Paper
- }
-
-- public int c() {
-- return this.getZ();
-+ public final int c() { // Paper
-+ return z; // Paper
+ return this.getZ();
}
- public int d() {
- return this.a() << 4;
+ public final int d() { // Paper
-+ return x << 4; // Paper
++ return this.getX() << 4; // Paper
}
- public int e() {
- return this.b() << 4;
+ public final int e() { // Paper
-+ return y << 4; // Paper
++ return this.getY() << 4; // Paper
}
- public int f() {
- return this.c() << 4;
+ public final int f() { // Paper
-+ return z << 4; // Paper
++ return this.getZ() << 4; // Paper
}
-- public int g() {
-- return (this.a() << 4) + 15;
-+ public final int g() { // Paper
-+ return (x << 4) + 15; // Paper
- }
-
-- public int h() {
-- return (this.b() << 4) + 15;
-+ public final int h() { // Paper
-+ return (y << 4) + 15; // Paper
- }
-
-- public int r() {
-- return (this.c() << 4) + 15;
-+ public final int r() { // Paper
-+ return (z << 4) + 15; // Paper
+ public int g() {
+@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
+ return (this.c() << 4) + 15;
}
+ public static long blockToSection(long i) { return e(i); } // Paper - OBFHELPER
@@ -183,15 +146,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static long f(long i) {
-@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
- }
-
- public BlockPosition s() {
-- return new BlockPosition(c(this.a()), c(this.b()), c(this.c()));
-+ return new BlockPosition(x << 4, y << 4, z << 4); // Paper
- }
-
- public BlockPosition t() {
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
return new ChunkCoordIntPair(this.a(), this.c());
}
@@ -212,14 +166,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count
}
- public long v() {
+ public long s() {
- return b(this.a(), this.b(), this.c());
-+ return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count
++ return (((long) getX() & 4194303L) << 42) | (((long) getY() & 1048575L)) | (((long) getZ() & 4194303L) << 20); // Paper - Simplify to reduce instruction count
}
- public Stream w() {
-- return BlockPosition.a(this.d(), this.e(), this.f(), this.g(), this.h(), this.r());
-+ return BlockPosition.a(x << 4, y << 4, z << 4, (x << 4) + 15, (y << 4) + 15, (z << 4) + 15); // Paper - simplify/inline
+ public Stream t() {
+@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
}
public static Stream a(SectionPosition sectionposition, int i) {
@@ -228,7 +181,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int l = sectionposition.c();
-
- return a(j - i, k - i, l - i, j + i, k + i, l + i);
-+ return a(sectionposition.x - i, sectionposition.y - i, sectionposition.z - i, sectionposition.x + i, sectionposition.y + i, sectionposition.z + i); // Paper - simplify/inline
++ return a(sectionposition.getX() - i, sectionposition.getY() - i, sectionposition.getZ() - i, sectionposition.getX() + i, sectionposition.getY() + i, sectionposition.getZ() + i); // Paper - simplify/inline
}
public static Stream b(ChunkCoordIntPair chunkcoordintpair, int i) {
diff --git a/Spigot-Server-Patches/Optimize-Light-Engine.patch b/Spigot-Server-Patches/Optimize-Light-Engine.patch
index 6cf38f1f3..fb85cb52b 100644
--- a/Spigot-Server-Patches/Optimize-Light-Engine.patch
+++ b/Spigot-Server-Patches/Optimize-Light-Engine.patch
@@ -24,19 +24,6 @@ Massive update to light to improve performance and chunk loading/generation.
7) Buffer non urgent tasks even if queueUpdate is called multiple times to improve efficiency.
8) Fix NPE risk that crashes server in getting nibble data
-diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Block.java
-+++ b/src/main/java/net/minecraft/server/Block.java
-@@ -0,0 +0,0 @@ public class Block implements IMaterial {
- return false;
- }
-
-- @Deprecated
-+ public final boolean canOcclude(IBlockData blockData) { return n(blockData); } @Deprecated // Paper - OBFHELPER
- public final boolean n(IBlockData iblockdata) {
- return this.j;
- }
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -50,46 +37,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return super.executeNext() || execChunkTask; // Paper
}
} finally {
-diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/IBlockData.java
-+++ b/src/main/java/net/minecraft/server/IBlockData.java
-@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements
- private final boolean e;
- private final boolean isAir; // Paper
- private final boolean isTicking; // Paper
-+ private final boolean canOcclude; // Paper
-
- public IBlockData(Block block, ImmutableMap, Comparable>> immutablemap) {
- super(block, immutablemap);
-@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements
- this.e = block.o(this);
- this.isAir = this.getBlock().isAir(this); // Paper
- this.isTicking = this.getBlock().isTicking(this); // Paper
-+ this.canOcclude = this.getBlock().canOcclude(this); // Paper
- }
-
- public void c() {
-@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements
- return this.c == null || this.c.h;
- }
-
-- public boolean g() {
-+ public final boolean g() { // Paper
- return this.e;
- }
-
-@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements
- return this.c != null ? this.c.c : this.getBlock().k(this, iblockaccess, blockposition);
- }
-
-- public boolean o() {
-- return this.c != null ? this.c.b : this.getBlock().n(this);
-+ public final boolean o() { // Paper
-+ return canOcclude; // Paper
- }
-
- public VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/LightEngineBlock.java b/src/main/java/net/minecraft/server/LightEngineBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/LightEngineBlock.java
@@ -277,8 +224,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- private final IBlockAccess[] h = new IBlockAccess[2];
+ private final IChunkAccess[] h = new IChunkAccess[2]; // Paper
++ // Paper start - see fully commented out method below (look for Bedrock)
++ // optimized method with less branching for when scenarios arent needed.
++ // avoid using mutable version if can
++ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) {
++ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
++
++ if (iblockaccess == null) {
++ mutableint.setValue(16);
++ return Blocks.BEDROCK.getBlockData();
++ } else {
++ this.pos.setValues(x, y, z);
++ IBlockData iblockdata = iblockaccess.getType(x, y, z);
++ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos));
++ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData();
++ }
++ }
++ protected final IBlockData getBlockOptimized(int x, int y, int z) {
++ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
++
++ if (iblockaccess == null) {
++ return Blocks.BEDROCK.getBlockData();
++ } else {
++ IBlockData iblockdata = iblockaccess.getType(x, y, z);
++ return iblockdata.l() && iblockdata.e() ? iblockdata : Blocks.AIR.getBlockData();
++ }
++ }
++ // Paper end
public LightEngineLayer(ILightAccess ilightaccess, EnumSkyBlock enumskyblock, S s0) {
super(16, 256, 8192);
+ this.a = ilightaccess;
@@ -0,0 +0,0 @@ public abstract class LightEngineLayer, S e
}
@@ -308,7 +283,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- }
-
- return Blocks.AIR.getBlockData();
-+ // Paper start - unused, optimized versions below, comment out to detect changes
+- } else {
+- int j = SectionPosition.a(BlockPosition.b(i));
+- int k = SectionPosition.a(BlockPosition.d(i));
+- IBlockAccess iblockaccess = this.a(j, k);
+-
+- if (iblockaccess == null) {
+- if (mutableint != null) {
+- mutableint.setValue(16);
+- }
+-
+- return Blocks.BEDROCK.getBlockData();
+- } else {
+- this.d.g(i);
+- IBlockData iblockdata = iblockaccess.getType(this.d);
+- boolean flag = iblockdata.l() && iblockdata.e();
+-
+- if (mutableint != null) {
+- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
+- }
+-
+- return flag ? iblockdata : Blocks.AIR.getBlockData();
+- }
+- }
+- }
++ // Paper start - comment out, see getBlockOptimized
+// protected IBlockData a(long i, @Nullable MutableInt mutableint) {
+// if (i == Long.MAX_VALUE) {
+// if (mutableint != null) {
@@ -330,7 +329,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+// } else {
+// this.d.g(i);
+// IBlockData iblockdata = iblockaccess.getType(this.d);
-+// boolean flag = iblockdata.o() && iblockdata.g();
++// boolean flag = iblockdata.l() && iblockdata.e();
+//
+// if (mutableint != null) {
+// mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
@@ -340,55 +339,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+// }
+// }
+// }
-+ // optimized method with less branching for when scenarios arent needed.
-+ // avoid using mutable version if can
-+ protected final IBlockData getBlockOptimized(int x, int y, int z, MutableInt mutableint) {
-+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
-+
-+ if (iblockaccess == null) {
-+ mutableint.setValue(16);
-+ return Blocks.BEDROCK.getBlockData();
- } else {
-- int j = SectionPosition.a(BlockPosition.b(i));
-- int k = SectionPosition.a(BlockPosition.d(i));
-- IBlockAccess iblockaccess = this.a(j, k);
--
-- if (iblockaccess == null) {
-- if (mutableint != null) {
-- mutableint.setValue(16);
-- }
--
-- return Blocks.BEDROCK.getBlockData();
-- } else {
-- this.d.g(i);
-- IBlockData iblockdata = iblockaccess.getType(this.d);
-- boolean flag = iblockdata.o() && iblockdata.g();
--
-- if (mutableint != null) {
-- mutableint.setValue(iblockdata.b(this.a.getWorld(), (BlockPosition) this.d));
-- }
-+ this.pos.setValues(x, y, z);
-+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
-+ mutableint.setValue(iblockdata.b(this.a.getWorld(), this.pos));
-+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData();
-+ }
-+ }
-+ protected final IBlockData getBlockOptimized(int x, int y, int z) {
-+ IChunkAccess iblockaccess = this.a(x >> 4, z >> 4);
-
-- return flag ? iblockdata : Blocks.AIR.getBlockData();
-- }
-+ if (iblockaccess == null) {
-+ return Blocks.BEDROCK.getBlockData();
-+ } else {
-+ IBlockData iblockdata = iblockaccess.getType(x, y, z);
-+ return iblockdata.o() && iblockdata.g() ? iblockdata : Blocks.AIR.getBlockData();
- }
- }
+ // Paper end
protected VoxelShape a(IBlockData iblockdata, long i, EnumDirection enumdirection) {
- return iblockdata.o() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a();
+ return iblockdata.l() ? iblockdata.a(this.a.getWorld(), this.d.g(i), enumdirection) : VoxelShapes.a();
@@ -0,0 +0,0 @@ public abstract class LightEngineLayer, S e
return i == Long.MAX_VALUE ? 0 : 15 - this.c.i(i);
}
@@ -583,6 +537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected final Long2ObjectMap i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap());
private final LongSet n = new LongOpenHashSet();
private final LongSet o = new LongOpenHashSet();
+@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
protected volatile boolean j;
protected LightEngineStorage(EnumSkyBlock enumskyblock, ILightAccess ilightaccess, M m0) {
@@ -696,12 +651,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
if (k >= 2 && j != 2) {
-- if (this.o.contains(i)) {
-- this.o.remove(i);
+- if (this.p.contains(i)) {
+- this.p.remove(i);
- } else {
-+ if (!this.o.remove(i)) { // Paper - remove useless contains - credit to JellySquid
-+ //this.o.remove(i); // Paper
-+ //} else { // Pape
++ if (!this.p.remove(i)) { // Paper - remove useless contains - credit to JellySquid
++ //this.p.remove(i); // Paper
++ //} else { // Paper
this.f.a(i, this.j(i));
this.g.add(i);
this.k(i);
@@ -746,7 +701,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
NibbleArray nibblearray1 = (NibbleArray) this.i.remove(i);
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
- longiterator = this.o.iterator();
+ longiterator = this.p.iterator();
while (longiterator.hasNext()) {
- i = (Long) longiterator.next();
@@ -754,16 +709,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.l(i);
}
- this.o.clear();
- this.j = false;
-- ObjectIterator objectiterator = this.i.long2ObjectEntrySet().iterator();
-+ ObjectIterator> objectiterator = Long2ObjectMaps.fastIterator(this.i); // Paper
-
+@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
Entry entry;
long j;
+ NibbleArray test = null; // Paper
-+ LongSet propagating = new LongOpenHashSet(); // Paper - credit JellySquid for idea to move this up
while (objectiterator.hasNext()) {
entry = (Entry) objectiterator.next();
j = entry.getLongKey();
@@ -775,66 +725,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.a(lightenginelayer, j);
this.f.a(j, nibblearray);
this.g.add(j);
- }
-+ if (!flag1) propagating.add(j); // Paper
-+ objectiterator.remove(); // Paper
- }
- }
-
- this.f.c();
-- if (!flag1) {
-- longiterator = this.i.keySet().iterator();
-+ if (!flag1) {// Paper - diff on change, change propagating add a few lines up
-+ longiterator = propagating.iterator(); // Paper
+@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
+ longiterator = this.i.keySet().iterator();
while (longiterator.hasNext()) {
- i = (Long) longiterator.next();
-- if (this.g(i)) {
-- int k = SectionPosition.c(SectionPosition.b(i));
-- int l = SectionPosition.c(SectionPosition.c(i));
-- int i1 = SectionPosition.c(SectionPosition.d(i));
-+ // Paper start
-+ i = longiterator.nextLong();
-+ if (true) { // don't check hasLight, this iterator is filtered already
-+ int secX = (int) (i >> 42);
-+ int secY = (int) (i << 44 >> 44);
-+ int secZ = (int) (i << 22 >> 42);
-+ int k = secX << 4; // baseX
-+ int l = secY << 4; // baseY
-+ int i1 = secZ << 4; // baseZ
-+ // Paper end
- EnumDirection[] aenumdirection = LightEngineStorage.k;
- int j1 = aenumdirection.length;
++ i = longiterator.nextLong(); // Paper
+ this.b(lightenginelayer, i);
+ }
+ } else {
+ longiterator = this.n.iterator();
- for (int k1 = 0; k1 < j1; ++k1) {
- EnumDirection enumdirection = aenumdirection[k1];
-- long l1 = SectionPosition.a(i, enumdirection);
--
-- if (!this.i.containsKey(l1) && this.g(l1)) {
-+ long l1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking
-+ if (!propagating.contains(l1) && this.g(l1)) { // Paper - use propagating
- for (int i2 = 0; i2 < 16; ++i2) {
- for (int j2 = 0; j2 < 16; ++j2) {
- long k2;
-@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
+ while (longiterator.hasNext()) {
+- i = (Long) longiterator.next();
++ i = longiterator.nextLong(); // Paper
+ this.b(lightenginelayer, i);
}
}
-
-+ // Paper start - moved above - Credit JellySquid for idea
-+ /*
- objectiterator = this.i.long2ObjectEntrySet().iterator();
-
- while (objectiterator.hasNext()) {
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
- if (this.g(j)) {
- objectiterator.remove();
- }
-- }
-+ }*/
-+ // Paper end
- }
- }
+ private void b(LightEngineLayer lightenginelayer, long i) {
+ if (this.g(i)) {
+- int j = SectionPosition.c(SectionPosition.b(i));
+- int k = SectionPosition.c(SectionPosition.c(i));
+- int l = SectionPosition.c(SectionPosition.d(i));
++ // Paper start
++ int secX = (int) (i >> 42);
++ int secY = (int) (i << 44 >> 44);
++ int secZ = (int) (i << 22 >> 42);
++ int j = secX << 4; // baseX
++ int k = secY << 4; // baseY
++ int l = secZ << 4; // baseZ
++ // Paper end
+ EnumDirection[] aenumdirection = LightEngineStorage.k;
+ int i1 = aenumdirection.length;
+
+ for (int j1 = 0; j1 < i1; ++j1) {
+ EnumDirection enumdirection = aenumdirection[j1];
+- long k1 = SectionPosition.a(i, enumdirection);
++ long k1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking
+
+ if (!this.i.containsKey(k1) && this.g(k1)) {
+ for (int l1 = 0; l1 < 16; ++l1) {
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
@@ -1211,7 +1143,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
- this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
+ this.e.a(ChunkTaskQueueSorter.a(() -> {
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
- if (this.c.size() >= this.f) {
+ // Paper start
@@ -1347,7 +1279,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkMap.world.getChunkProvider().getLightEngine().changePriority(location.pair(), getCurrentPriority(), priority);
}
if (getCurrentPriority() != priority) {
- this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
+ this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1378,7 +1310,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
gameprofilerfiller.exit();
timings.chunkTicksBlocks.stopTiming(); // Paper
diff --git a/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch b/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch
index 807f67ee0..b3b2dca4e 100644
--- a/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch
+++ b/Spigot-Server-Patches/Optimize-NibbleArray-to-use-pooled-buffers.patch
@@ -41,10 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected void a(LightEngineLayer, ?> lightenginelayer, long i) {
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage> e
- protected void a(long i, @Nullable NibbleArray nibblearray) {
+ protected void a(long i, @Nullable NibbleArray nibblearray, boolean flag) {
if (nibblearray != null) {
- this.i.put(i, nibblearray);
+ NibbleArray remove = this.i.put(i, nibblearray); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
+ if (!flag) {
+ this.n.add(i);
+ }
} else {
- this.i.remove(i);
+ NibbleArray remove = this.i.remove(i); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
@@ -248,8 +251,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
@@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet {
- private List g;
private List h;
+ private boolean i;
+ // Paper start
+ java.lang.Runnable cleaner1;
@@ -282,9 +285,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
public PacketPlayOutLightUpdate() {}
- public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine) {
+ public PacketPlayOutLightUpdate(ChunkCoordIntPair chunkcoordintpair, LightEngine lightengine, boolean flag) {
this.a = chunkcoordintpair.x;
this.b = chunkcoordintpair.z;
+ this.i = flag;
- this.g = Lists.newArrayList();
- this.h = Lists.newArrayList();
+ this.g = Lists.newArrayList();cleaner1 = MCUtil.registerListCleaner(this, this.g, NibbleArray::releaseBytes); // Paper
@@ -311,7 +315,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
@@ -0,0 +0,0 @@ public class PacketPlayOutLightUpdate implements Packet {
- this.b = chunkcoordintpair.z;
+ this.i = flag;
this.c = i;
this.d = j;
- this.g = Lists.newArrayList();
diff --git a/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
deleted file mode 100644
index a4f5fc72c..000000000
--- a/Spigot-Server-Patches/Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Mon, 11 May 2020 04:18:54 -0400
-Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
-
-I utilized the IDE to convert streams to non streams code, so shouldn't
-be any risk of behavior change. Only did minor optimization of the
-generated code set to remove unnecessary things.
-
-I expect us to just drop this patch on next major update and re-apply
-it with the IDE again and re-apply the collections optimization.
-
-Optimize collection by creating a list instead of a set of the key and value.
-
-This lets us get faster foreach iteration, as well as avoids map lookups on
-the values when needed.
-
-diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Pathfinder.java
-+++ b/src/main/java/net/minecraft/server/Pathfinder.java
-@@ -0,0 +0,0 @@ public class Pathfinder {
- this.a.a();
- this.e.a(chunkcache, entityinsentient);
- PathPoint pathpoint = this.e.b();
-- Map map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> {
-- return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
-- }, Function.identity()));
-+ // Paper start - remove streams - and optimize collection
-+ List> map = new java.util.ArrayList<>();
-+ for (BlockPosition blockposition : set) {
-+ // cast is important
-+ //noinspection RedundantCast
-+ PathDestination path = this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
-+ map.add(new java.util.AbstractMap.SimpleEntry<>(path, blockposition));
-+ }
-+ // Paper end
- PathEntity pathentity = this.a(pathpoint, map, f, i, f1);
-
- this.e.a();
-@@ -0,0 +0,0 @@ public class Pathfinder {
- }
-
- @Nullable
-- private PathEntity a(PathPoint pathpoint, Map map, float f, int i, float f1) {
-- Set set = map.keySet();
-+ private PathEntity a(PathPoint pathpoint, java.util.List> list, float f, int i, float f1) { // Paper - list instead of set
-+ //Set set = map.keySet(); // Paper
-
- pathpoint.e = 0.0F;
-- pathpoint.f = this.a(pathpoint, set);
-+ pathpoint.f = this.a(pathpoint, list); // Paper - list instead of map
- pathpoint.g = pathpoint.f;
- this.a.a();
- this.b.clear();
-@@ -0,0 +0,0 @@ public class Pathfinder {
- PathPoint pathpoint1 = this.a.c();
-
- pathpoint1.i = true;
-- set.stream().filter((pathdestination) -> {
-- return pathpoint1.c((PathPoint) pathdestination) <= (float) i;
-- }).forEach(PathDestination::e);
-- if (set.stream().anyMatch(PathDestination::f)) {
-+ // Paper start - remove streams
-+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
-+ PathDestination pathdestination = list.get(i1).getKey();
-+ if (pathpoint1.c(pathdestination) <= (float) i) {
-+ pathdestination.e();
-+ }
-+ }
-+ boolean result = false;
-+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
-+ PathDestination pathdestination = list.get(i1).getKey();
-+ if (pathdestination.f()) {
-+ result = true;
-+ break;
-+ }
-+ }
-+ if (result) {
-+ // Paper end
- break;
- }
-
-@@ -0,0 +0,0 @@ public class Pathfinder {
- if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) {
- pathpoint2.h = pathpoint1;
- pathpoint2.e = f3;
-- pathpoint2.f = this.a(pathpoint2, set) * 1.5F;
-+ pathpoint2.f = this.a(pathpoint2, list) * 1.5F; // Paper - use list instead of map
- if (pathpoint2.c()) {
- this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f);
- } else {
-@@ -0,0 +0,0 @@ public class Pathfinder {
- }
- }
-
-- Stream stream;
-
-- if (set.stream().anyMatch(PathDestination::f)) {
-- stream = set.stream().filter(PathDestination::f).map((pathdestination) -> {
-- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true);
-- }).sorted(Comparator.comparingInt(PathEntity::e));
-- } else {
-- stream = set.stream().map((pathdestination) -> {
-- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false);
-- }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
-+ // Paper start - remove streams
-+ boolean result = false;
-+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
-+ PathDestination pathDestination = list.get(i1).getKey(); // Paper
-+ if (pathDestination.f()) {
-+ result = true;
-+ break;
-+ }
- }
--
-- Optional optional = stream.findFirst();
--
-- if (!optional.isPresent()) {
-- return null;
-+ List candidates = new java.util.ArrayList<>();
-+ if (result) {
-+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
-+ Map.Entry entry = list.get(i1);
-+ PathDestination pathdestination = entry.getKey();
-+ if (pathdestination.f()) {
-+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), true);
-+ candidates.add(pathEntity);
-+ }
-+ }
-+ if (candidates.isEmpty()) return null;
-+ candidates.sort(Comparator.comparingInt(PathEntity::e));
- } else {
-- PathEntity pathentity = (PathEntity) optional.get();
--
-- return pathentity;
-+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
-+ Map.Entry entry = list.get(i1);
-+ PathDestination pathdestination = entry.getKey();
-+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), false);
-+ candidates.add(pathEntity);
-+ }
-+ if (candidates.isEmpty()) return null;
-+ candidates.sort(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
- }
-+ return candidates.get(0);
-+ // Paper end
- }
-
-- private float a(PathPoint pathpoint, Set set) {
-+ private float a(PathPoint pathpoint, java.util.List> list) {
- float f = Float.MAX_VALUE;
-
- float f1;
-
-- for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
-- PathDestination pathdestination = (PathDestination) iterator.next();
-+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper
-+ PathDestination pathdestination = list.get(i).getKey(); // Paper
-
- f1 = pathpoint.a(pathdestination);
- pathdestination.a(f1, pathpoint);
diff --git a/Spigot-Server-Patches/Optimize-Villagers.patch b/Spigot-Server-Patches/Optimize-Villagers.patch
deleted file mode 100644
index 28c23761a..000000000
--- a/Spigot-Server-Patches/Optimize-Villagers.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Tue, 26 May 2020 21:32:05 -0400
-Subject: [PATCH] Optimize Villagers
-
-This change reimplements the entire BehaviorFindPosition method to
-get rid of all of the streams, and implement the logic in a more sane way.
-
-We keep vanilla behavior 100% the same with this change, just wrote more
-optimal, as we can abort iterating POI's as soon as we find a match....
-
-One slight change is that Minecraft adds a random delay before a POI is
-attempted again. I've increased the amount of that delay based on the distance
-to said POI, so farther POI's will not be attempted as often.
-
-Additionally, we spiral out, so we favor local POI's before we ever favor farther POI's.
-
-We also try to pathfind 1 POI at a time instead of collecting multiple POI's then tossing them
-all to the pathfinder, so that once we get a match we can return before even looking at other
-POI's.
-
-This benefits us in that ideally, a villager will constantly find the near POI's and
-not even try to pathfind to the farther POI. Trying to pathfind to distant POI's is
-what causes significant lag.
-
-Other improvements here is to stop spamming the POI manager with empty nullables.
-Vanilla used them to represent if they needed to load POI data off disk or not.
-
-Well, we load POI data async on chunk load, so we have it, and we surely do not ever
-want to load POI data sync either for unloaded chunks!
-
-So this massively reduces object count in the POI hashmaps, resulting in less hash collions,
-and also less memory use.
-
-Additionally, unemployed villagers were using significant time due to major ineffeciency in
-the code rebuilding data that is static every single invocation for every POI type...
-
-So we cache that and only rebuild it if professions change, which should be never unless
-a plugin manipulates and adds custom professions, which it will handle by rebuilding.
-
-diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java
-+++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
-@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior {
-
- protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) {
- this.f = 0;
-- this.d = worldserver.getTime() + (long) worldserver.getRandom().nextInt(20);
-+ this.d = worldserver.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper
- VillagePlace villageplace = worldserver.B();
-+
-+ // Paper start - replace implementation completely
-+ BlockPosition blockposition2 = new BlockPosition(entitycreature);
-+ int dist = 48;
-+ int requiredDist = dist * dist;
-+ int cdist = Math.floorDiv(dist, 16);
-+ Predicate predicate = this.a.c();
-+ int maxPoiAttempts = 4;
-+ int poiAttempts = 0;
-+ OUT:
-+ for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) {
-+ for (int i1 = 0; i1 < 16; i1++) {
-+ java.util.Optional section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v());
-+ if (section == null || !section.isPresent()) continue;
-+ for (java.util.Map.Entry> e : section.get().getRecords().entrySet()) {
-+ if (!predicate.test(e.getKey())) continue;
-+ for (VillagePlaceRecord record : e.getValue()) {
-+ if (!record.hasVacancy()) continue;
-+
-+ BlockPosition pos = record.getPosition();
-+ long key = pos.asLong();
-+ if (this.e.containsKey(key)) {
-+ continue;
-+ }
-+ double poiDist = pos.distanceSquared(blockposition2);
-+ if (poiDist <= (double) requiredDist) {
-+ this.e.put(key, (long) (this.d + Math.sqrt(poiDist) * 4)); // use dist instead of 40 to blacklist longer if farther distance
-+ ++poiAttempts;
-+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.a.d());
-+
-+ if (pathentity != null && pathentity.h()) {
-+ record.decreaseVacancy();
-+ GlobalPos globalPos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), pos);
-+ entitycreature.getBehaviorController().setMemory(this.b, globalPos);
-+ break OUT;
-+ }
-+ if (poiAttempts >= maxPoiAttempts) {
-+ break OUT;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ // Clean up - vanilla does this only when it runs out, but that would push it to try farther POI's...
-+ this.e.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.d);
-+ /*
- Predicate predicate = (blockposition) -> {
- long j = blockposition.asLong();
-
-@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior {
- return entry.getLongValue() < this.d;
- });
- }
--
-+ */ // Paper end
- }
- }
-diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/RegionFileSection.java
-+++ b/src/main/java/net/minecraft/server/RegionFileSection.java
-@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi
-
- @Nullable
- protected Optional c(long i) {
-- return (Optional) this.c.get(i);
-+ return this.c.getOrDefault(i, Optional.empty()); // Paper
- }
-
-+ protected final Optional getSection(long i) { return d(i); } // Paper - OBFHELPER
- protected Optional d(long i) {
-- SectionPosition sectionposition = SectionPosition.a(i);
--
-- if (this.b(sectionposition)) {
-- return Optional.empty();
-- } else {
-- Optional optional = this.c(i);
--
-- if (optional != null) {
-- return optional;
-- } else {
-- this.b(sectionposition.u());
-- optional = this.c(i);
-- if (optional == null) {
-- throw (IllegalStateException) SystemUtils.c(new IllegalStateException());
-- } else {
-- return optional;
-- }
-- }
-- }
-+ // Paper start - replace method - never load POI data sync, we load this in chunk load already, reduce ops
-+ // If it's an unloaded chunk, well too bad.
-+ return this.c(i);
-+ // Paper end
- }
-
- protected boolean b(SectionPosition sectionposition) {
-@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi
- private void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops, @Nullable T t0) {
- if (t0 == null) {
- for (int i = 0; i < 16; ++i) {
-- this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty());
-+ //this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); // Paper - NO!!!
- }
- } else {
- Dynamic dynamic = new Dynamic(dynamicops, t0);
-@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi
- }, dynamic2);
- });
-
-- this.c.put(i1, optional);
-+ if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!!
- optional.ifPresent((minecraftserializable) -> {
- this.b(i1);
- if (flag) {
-@@ -0,0 +0,0 @@ public class RegionFileSection extends RegionFi
- if (optional != null && optional.isPresent()) {
- this.d.add(i);
- } else {
-- RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i));
-+ //RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); // Paper - hush
- }
- }
-
-diff --git a/src/main/java/net/minecraft/server/VillagePlaceRecord.java b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java
-+++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
-@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
- return dynamicops.createMap(ImmutableMap.of(dynamicops.createString("pos"), this.a.a(dynamicops), dynamicops.createString("type"), dynamicops.createString(IRegistry.POINT_OF_INTEREST_TYPE.getKey(this.b).toString()), dynamicops.createString("free_tickets"), dynamicops.createInt(this.c)));
- }
-
-+ protected final boolean decreaseVacancy() { return b(); } // Paper - OBFHELPER
- protected boolean b() {
- if (this.c <= 0) {
- return false;
-@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
- }
- }
-
-+ protected final boolean increaseVacancy() { return c(); } // Paper - OBFHELPER
- protected boolean c() {
- if (this.c >= this.b.b()) {
- return false;
-@@ -0,0 +0,0 @@ public class VillagePlaceRecord implements MinecraftSerializable {
- }
- }
-
-+ public final boolean hasVacancy() { return d(); } // Paper - OBFHELPER
- public boolean d() {
- return this.c > 0;
- }
-
-+ public final boolean isOccupied() { return e(); } // Paper - OBFHELPER
- public boolean e() {
- return this.c != this.b.b();
- }
-
-+ public final BlockPosition getPosition() { return f(); } // Paper
- public BlockPosition f() {
- return this.a;
- }
-diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/VillagePlaceSection.java
-+++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java
-@@ -0,0 +0,0 @@ public class VillagePlaceSection implements MinecraftSerializable {
-
- private static final Logger LOGGER = LogManager.getLogger();
- private final Short2ObjectMap b = new Short2ObjectOpenHashMap();
-- private final Map> c = Maps.newHashMap();
-+ private final Map> c = Maps.newHashMap(); public final Map> getRecords() { return c; } // Paper - OBFHELPER
- private final Runnable d;
- private boolean e;
-
-diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/VillagePlaceType.java
-+++ b/src/main/java/net/minecraft/server/VillagePlaceType.java
-@@ -0,0 +0,0 @@ import java.util.stream.Stream;
-
- public class VillagePlaceType {
-
-+ static Set professionCache; // Paper
- private static final Predicate v = (villageplacetype) -> {
-- return ((Set) IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet())).contains(villageplacetype);
-+ // Paper start
-+ if (professionCache == null) {
-+ professionCache = IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet());
-+ }
-+ return professionCache.contains(villageplacetype);
-+ // Paper end
- };
- public static final Predicate a = (villageplacetype) -> {
- return true;
-@@ -0,0 +0,0 @@ public class VillagePlaceType {
- }
-
- private static VillagePlaceType a(String s, Set set, int i, int j) {
-- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, j))));
-+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, j)))); // Paper - decompile error
- }
-
- private static VillagePlaceType a(String s, Set set, int i, Predicate predicate, int j) {
-- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, predicate, j))));
-+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, predicate, j)))); // Paper - decompile error
- }
-
- private static VillagePlaceType a(VillagePlaceType villageplacetype) {
-diff --git a/src/main/java/net/minecraft/server/VillagerProfession.java b/src/main/java/net/minecraft/server/VillagerProfession.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/VillagerProfession.java
-+++ b/src/main/java/net/minecraft/server/VillagerProfession.java
-@@ -0,0 +0,0 @@ public class VillagerProfession {
- }
-
- static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet- immutableset, ImmutableSet immutableset1, @Nullable SoundEffect soundeffect) {
-+ VillagePlaceType.professionCache = null; // Paper
- return (VillagerProfession) IRegistry.a((IRegistry) IRegistry.VILLAGER_PROFESSION, new MinecraftKey(s), (Object) (new VillagerProfession(s, villageplacetype, immutableset, immutableset1, soundeffect)));
- }
- }
diff --git a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch b/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch
deleted file mode 100644
index a56e8b94c..000000000
--- a/Spigot-Server-Patches/Optimize-WorldBorder-collision-checks-and-air.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf
-Date: Sun, 10 May 2020 22:49:05 -0400
-Subject: [PATCH] Optimize WorldBorder collision checks and air
-
-
-diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Entity.java
-+++ b/src/main/java/net/minecraft/server/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
- AxisAlignedBB axisalignedbb = this.getBoundingBox();
- VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this);
- VoxelShape voxelshape = this.world.getWorldBorder().a();
-- Stream stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape);
-+ Stream stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Paper
- Stream stream1 = this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of());
- StreamAccumulator streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream));
- Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator);
-diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/ICollisionAccess.java
-+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
- if (true) { //public boolean tryAdvance(Consumer super VoxelShape> consumer) {*/ // Paper
- if (entity != null) {
- // Paper end
-- VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
-- boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
-- boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
-+ //VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); // Paper - only make if collides
-+ boolean flag = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().shrink(1.0E-7D)); // Paper
-+ boolean flag1 = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().g(1.0E-7D)); // Paper
-
- if (!flag && flag1) {
-- collisions.add(voxelshape1);// Paper
-+ collisions.add(ICollisionAccess.this.getWorldBorder().a());// Paper
- if (returnFast) return collisions;
- }
- }
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
- //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up
- // Paper end
-
-- if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
-+ if (!iblockdata.isAir() && (j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { // Paper - fast track air
- VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
-
- // Paper start - Lithium Collision Optimizations
-diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/WorldBorder.java
-+++ b/src/main/java/net/minecraft/server/WorldBorder.java
-@@ -0,0 +0,0 @@ public class WorldBorder {
- return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f();
- }
-
-+ public final boolean isInBounds(AxisAlignedBB aabb) { return this.a(aabb); } // Paper - OBFHELPER
- public boolean a(AxisAlignedBB axisalignedbb) {
- return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f();
- }
diff --git a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch
index 7ea3613af..134174dfa 100644
--- a/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch
+++ b/Spigot-Server-Patches/Optimize-sending-packets-to-nearby-locations-sounds-.patch
@@ -15,59 +15,49 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
- world = (WorldServer) entityhuman.world;
- }
+ }
-- List extends EntityHuman> players1 = world == null ? players : world.players;
-- for (int j = 0; j < players1.size(); ++j) {
-- EntityHuman entity = players1.get(j);
-- if (!(entity instanceof EntityPlayer)) continue;
-- EntityPlayer entityplayer = (EntityPlayer) entity;
+ public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, ResourceKey resourcekey, Packet> packet) {
+- for (int i = 0; i < this.players.size(); ++i) {
+- EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
++ WorldServer world = null;
++ if (entityhuman != null && entityhuman.world instanceof WorldServer) {
++ world = (WorldServer) entityhuman.world;
++ }
+
+- // CraftBukkit start - Test if player receiving packet can see the source of the packet
+- if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) {
+- continue;
+ // Paper start
-+ if ((world == null || world.chunkProvider == null) && dimensionmanager != null) {
-+ world = dimensionmanager.world;
-+ }
+ if (world == null) {
-+ LOGGER.error("Sending packet to invalid world" + entityhuman + " " + dimensionmanager + " - " + packet.getClass().getName(), new Throwable());
-+ return; // ??? shouldn't happen...
++ world = server.getWorldServer(resourcekey);
+ }
-+ PlayerChunkMap chunkMap = world.chunkMap;
++ PlayerChunkMap chunkMap = world != null ? world.getChunkProvider().playerChunkMap : null;
+ Object[] backingSet;
+ if (chunkMap == null) {
+ // Really shouldn't happen...
-+ backingSet = world.players.toArray();
++ backingSet = world != null ? world.players.toArray() : players.toArray();
+ } else {
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearbyPlayers = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(MCUtil.fastFloor(d0) >> 4, MCUtil.fastFloor(d2) >> 4);
+ if (nearbyPlayers == null) {
+ return;
-+ }
+ }
+ backingSet = nearbyPlayers.getBackingSet();
+ }
+
+ for (Object object : backingSet) {
+ if (!(object instanceof EntityPlayer)) continue;
+ EntityPlayer entityplayer = (EntityPlayer) object;
- // Paper end
++ // Paper end
++
++ // CraftBukkit start - Test if player receiving packet can see the source of the packet
++ //if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper
++ //continue; // Paper
++ //} // Paper
+ // CraftBukkit end
- // CraftBukkit start - Test if player receiving packet can see the source of the packet
-diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/WorldServer.java
-+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
- }
- }
- // Paper end
-+ public final PlayerChunkMap chunkMap; // Paper
- private final MinecraftServer server;
- private final WorldNBTStorage dataManager;
- public boolean savingDisabled;
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
- }, gameprofilerfiller, false, gen, env);
- this.pvpMode = minecraftserver.getPVP();
- worlddata.world = this;
-+ if (chunkProvider == null) { chunkMap = null; new Throwable("World created without a ChunkProvider!").printStackTrace(); } // Paper - figure out if something weird happened here
-+ else chunkMap = ((ChunkProviderServer) chunkProvider).playerChunkMap;
- // CraftBukkit end
- if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
- this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer
+- if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey) {
++ if (entityplayer != entityhuman && entityplayer.world.getDimensionKey() == resourcekey && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { // Paper
+ double d4 = d0 - entityplayer.locX();
+ double d5 = d1 - entityplayer.locY();
+ double d6 = d2 - entityplayer.locZ();
diff --git a/Spigot-Server-Patches/POM-Changes.patch b/Spigot-Server-Patches/POM-Changes.patch
index ee23f17e5..6be7b5070 100644
--- a/Spigot-Server-Patches/POM-Changes.patch
+++ b/Spigot-Server-Patches/POM-Changes.patch
@@ -201,7 +201,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper
Calendar deadline = Calendar.getInstance();
- deadline.add(Calendar.DAY_OF_YEAR, -3);
+ deadline.add(Calendar.DAY_OF_YEAR, -1);
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
diff --git a/Spigot-Server-Patches/Potential-bed-API.patch b/Spigot-Server-Patches/Potential-bed-API.patch
index a7c6bebe2..e99bfb9b9 100644
--- a/Spigot-Server-Patches/Potential-bed-API.patch
+++ b/Spigot-Server-Patches/Potential-bed-API.patch
@@ -12,20 +12,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
- return null;
+ return getHandle().sleepTicks;
}
+ // Paper start - Potential bed api
+ @Override
+ public Location getPotentialBedLocation() {
-+ BlockPosition bed = getHandle().getBed();
++ EntityPlayer handle = (EntityPlayer) getHandle();
++ BlockPosition bed = handle.getSpawn();
+ if (bed == null) {
+ return null;
+ }
-+ return new Location(getServer().getWorld(getHandle().spawnWorld), bed.getX(), bed.getY(), bed.getZ());
++
++ net.minecraft.server.WorldServer worldServer = handle.server.getWorldServer(handle.getSpawnDimension());
++ if (worldServer == null) {
++ return null;
++ }
++ return new Location(worldServer.getWorld(), bed.getX(), bed.getY(), bed.getZ());
+ }
+ // Paper end
-+
@Override
- public void setBedSpawnLocation(Location location) {
- setBedSpawnLocation(location, false);
+ public boolean sleep(Location location, boolean force) {
+ Preconditions.checkArgument(location != null, "Location cannot be null");
diff --git a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch
index 53a56729a..aaf34a5dd 100644
--- a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch
+++ b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch
@@ -43,8 +43,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
String title = container.getBukkitView().getTitle();
-- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
-+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper
+- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0]));
++ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper
getHandle().activeContainer = container;
getHandle().activeContainer.addSlotListener(player);
}
@@ -52,8 +52,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Now open the window
Containers> windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory());
String title = inventory.getTitle();
-- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title)));
-+ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); // Paper
+- player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0]));
++ if (!player.isFrozen()) player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper
player.activeContainer = container;
player.activeContainer.addSlotListener(player);
}
diff --git a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch
index 11e7c2b77..a503eadde 100644
--- a/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch
+++ b/Spigot-Server-Patches/Prevent-position-desync-in-playerconnection-causing-.patch
@@ -26,6 +26,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return; // ... thanks Mojang for letting move calls teleport across dimensions.
+ }
+ // Paper end - prevent position desync
- this.player.onGround = packetplayinflying.b();
double d12 = d8;
+ d7 = d4 - this.player.locX();
diff --git a/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
index d5f31067f..22866d1f2 100644
--- a/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
+++ b/Spigot-Server-Patches/Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
@@ -31,9 +31,9 @@ diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
-@@ -0,0 +0,0 @@ public class Block implements IMaterial {
- protected final SoundEffectType stepSound;
- protected final Material material;
+@@ -0,0 +0,0 @@ public class Block extends BlockBase implements IMaterial {
+ protected final BlockStateList blockStateList;
+ private IBlockData blockData;
// Paper start
+ public final boolean isDestroyable() {
+ return com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits ||
@@ -46,7 +46,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public co.aikar.timings.Timing timing;
public co.aikar.timings.Timing getTiming() {
if (timing == null) {
-@@ -0,0 +0,0 @@ public class Block implements IMaterial {
+diff --git a/src/main/java/net/minecraft/server/BlockBase.java b/src/main/java/net/minecraft/server/BlockBase.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BlockBase.java
++++ b/src/main/java/net/minecraft/server/BlockBase.java
+@@ -0,0 +0,0 @@ public abstract class BlockBase {
@Deprecated
public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) {
@@ -55,15 +59,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@Deprecated
-@@ -0,0 +0,0 @@ public class Block implements IMaterial {
+@@ -0,0 +0,0 @@ public abstract class BlockBase {
+ public Block getBlock() {
+ return (Block) this.c;
+ }
+-
++ // Paper start
++ public final boolean isDestroyable() {
++ return getBlock().isDestroyable();
++ }
++ // Paper end
+ public Material getMaterial() {
+ return this.g;
+ }
+@@ -0,0 +0,0 @@ public abstract class BlockBase {
+ }
- @Deprecated
- public EnumPistonReaction getPushReaction(IBlockData iblockdata) {
-- return this.material.getPushReaction();
-+ return !blockData.isDestroyable() ? EnumPistonReaction.BLOCK : this.material.getPushReaction(); // Paper
- }
+ public EnumPistonReaction getPushReaction() {
+- return this.getBlock().getPushReaction(this.p());
++ return !isDestroyable() ? EnumPistonReaction.BLOCK : this.getBlock().getPushReaction(this.p()); // Paper
+ }
- public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) {
+ public boolean i(IBlockAccess iblockaccess, BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockPiston.java
@@ -82,14 +99,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!world.isClientSide) {
boolean flag = this.a(world, blockposition, enumdirection);
@@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional {
- }
+ IBlockData iblockdata1 = (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT);
- world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3);
+ world.setTypeAndData(blockposition, iblockdata1, 20);
- world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true));
-+ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction
++ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction - copy this above
+ world.update(blockposition, iblockdata1.getBlock());
+ iblockdata1.a(world, blockposition, 2);
if (this.sticky) {
- BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2);
- IBlockData iblockdata1 = world.getType(blockposition1);
@@ -0,0 +0,0 @@ public class BlockPiston extends BlockDirectional {
}
}
@@ -116,8 +133,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
IBlockData iblockdata = this.world.getType(blockposition);
+ if (!iblockdata.isDestroyable()) continue; // Paper
Fluid fluid = iblockdata.getFluid(); // Paper
+ Optional optional = this.k.a(this, this.world, blockposition, iblockdata, fluid);
- if (!iblockdata.isAir() || !fluid.isEmpty()) {
@@ -0,0 +0,0 @@ public class Explosion {
IBlockData iblockdata = this.world.getType(blockposition);
Block block = iblockdata.getBlock();
@@ -127,28 +144,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPosition blockposition1 = blockposition.immutableCopy();
this.world.getMethodProfiler().enter("explosion_blocks");
-diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/IBlockData.java
-+++ b/src/main/java/net/minecraft/server/IBlockData.java
-@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract implements
- return (CraftBlockData) cachedCraftBlockData.clone();
- }
- // Paper end
-+ // Paper start
-+ public final boolean isDestroyable() {
-+ return getBlock().isDestroyable();
-+ }
-+ // Paper end
-
- public Material getMaterial() {
- return this.getBlock().k(this);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
- public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) {
+ public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
+ // Paper start
diff --git a/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch
index b24552de1..7475f0973 100644
--- a/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch
+++ b/Spigot-Server-Patches/Reduce-allocation-of-Vec3D-by-entity-tracker.patch
@@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove allocation of Vec3D here
boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L;
- if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) {
+ if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.isOnGround()) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
diff --git a/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch b/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch
deleted file mode 100644
index 0576b7364..000000000
--- a/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch
+++ /dev/null
@@ -1,178 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar
-Date: Sat, 9 May 2020 18:36:27 -0400
-Subject: [PATCH] Remove some Streams usage in Entity Collision
-
-While there is more down the collision system, remove some of the wrapping
-Spliterator stuff as even this wrapper stream has shown up in profiling.
-
-With other collision optimizations, we might also even avoid inner streams too.
-
-diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/GeneratorAccess.java
-+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
-@@ -0,0 +0,0 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev
- this.a((EntityHuman) null, i, blockposition, j);
- }
-
-+ @Override default java.util.List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper
- @Override
- default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) {
- return IEntityAccess.super.b(entity, axisalignedbb, set);
-diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/ICollisionAccess.java
-+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
-
- default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) {
- try { if (entity != null) entity.collisionLoadChunks = true; // Paper
-- return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty);
-+ // Paper start - reduce stream usage
-+ java.util.List blockCollisions = getBlockCollision(entity, axisalignedbb, true);
-+ for (int i = 0; i < blockCollisions.size(); i++) {
-+ VoxelShape blockCollision = blockCollisions.get(i);
-+ if (!blockCollision.isEmpty()) {
-+ return false;
-+ }
-+ }
-+ return getEntityCollisions(entity, axisalignedbb, set, true).isEmpty();
-+ // Paper end
- } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
- }
-
-+ default java.util.List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper
- default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) {
- return Stream.empty();
- }
-
- default Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) {
-- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)});
-+ // Paper start - reduce stream usage
-+ java.util.List blockCollisions = getBlockCollision(entity, axisalignedbb, false);
-+ java.util.List entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false);
-+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream());
-+ // Paper end
- }
-
- default Stream b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) {
-+ // Paper start - reduce stream usage
-+ java.util.List collision = getBlockCollision(entity, axisalignedbb, false);
-+ return !collision.isEmpty() ? collision.stream() : Stream.empty();
-+ }
-+
-+ default java.util.List getBlockCollision(@Nullable final Entity entity, AxisAlignedBB axisalignedbb, boolean returnFast) {
-+ // Paper end
- int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1;
- int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1;
- int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1;
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
- final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
- final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb);
-
-- return StreamSupport.stream(new AbstractSpliterator(Long.MAX_VALUE, 1280) {
-- boolean a = entity == null;
--
-- public boolean tryAdvance(Consumer super VoxelShape> consumer) {
-- if (!this.a) {
-- this.a = true;
-+ // Paper start - reduce stream usage (this part done by Aikar)
-+ java.util.List collisions = new java.util.ArrayList<>();
-+ if (true) {//return StreamSupport.stream(new AbstractSpliterator(Long.MAX_VALUE, 1280) {
-+ if (true) { //public boolean tryAdvance(Consumer super VoxelShape> consumer) {*/ // Paper
-+ if (entity != null) {
-+ // Paper end
- VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
- boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
- boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
-
- if (!flag && flag1) {
-- consumer.accept(voxelshape1);
-- return true;
-+ collisions.add(voxelshape1);// Paper
-+ if (returnFast) return collisions;
- }
- }
-
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
- );
- if (iblockdata == null) {
- if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
-- VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
-- consumer.accept(voxelshape3);
-- return true;
-+ collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))));
-+ if (returnFast) return collisions;
- }
- } else {
- //blockposition_mutableblockposition.d(k1, l1, i2); // moved up
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
-
- if (voxelshape2 == VoxelShapes.fullCube()) {
- if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
-- consumer.accept(voxelshape2.offset(x, y, z));
-- return true;
-+ collisions.add(voxelshape2.offset(x, y, z));
-+ if (returnFast) return collisions;
- }
- } else {
- VoxelShape shape = voxelshape2.offset(x, y, z);
- if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
-- consumer.accept(shape);
-- return true;
-+ collisions.add(shape);
-+ if (returnFast) return collisions;
- }
- // Paper end
- }
-@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
- }
- }
-
-- return false;
-+ //return false; // Paper
- }
-- }, false);
-+ } //}, false);
-+ return collisions; // Paper
- }
- }
-diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/IEntityAccess.java
-+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
-@@ -0,0 +0,0 @@ public interface IEntityAccess {
- // Paper start - remove streams from entity collision
- if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
- return Stream.empty();
--
- }
-+ return getEntityCollisions(entity, axisalignedbb, set, false).stream();
-+ }
-+ default List getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, boolean returnFast) {
- AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
- List entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
- List shapes = new java.util.ArrayList<>();
-@@ -0,0 +0,0 @@ public interface IEntityAccess {
-
- if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
- shapes.add(VoxelShapes.of(otherEntityBox));
-+ if (returnFast) return shapes;
- }
-
- if (entity != null) {
-@@ -0,0 +0,0 @@ public interface IEntityAccess {
-
- if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
- shapes.add(VoxelShapes.of(otherEntityHardBox));
-+ if (returnFast) return shapes;
- }
- }
- }
-
-- return shapes.stream();
-+ return shapes;
- // Paper end
- }
-
diff --git a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
index 6b9f14f64..e0719937b 100644
--- a/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
+++ b/Spigot-Server-Patches/Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
@@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main {
- deadline.add(Calendar.DAY_OF_YEAR, -3);
+ deadline.add(Calendar.DAY_OF_YEAR, -1);
if (buildDate.before(deadline.getTime())) {
System.err.println("*** Error, this build is outdated ***");
- System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***");
diff --git a/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
index 0abc1fe61..da8315f55 100644
--- a/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
+++ b/Spigot-Server-Patches/Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
@@ -22,13 +22,12 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
-@@ -0,0 +0,0 @@ public class WorldServer extends World {
+@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
+ this.worldDataServer.setThundering(flag1);
}
- // CraftBukkit end
- @Override
- public BiomeBase a(int i, int j, int k) {
-+
+ public BiomeBase getBiomeBySeed(int i, int j, int k) { return a(i, j, k); } // Paper - OBFHELPER
+ @Override public BiomeBase a(int i, int j, int k) {
return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k);
diff --git a/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch b/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch
index dfda5c8db..0a4383c03 100644
--- a/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch
+++ b/Spigot-Server-Patches/Wait-for-Async-Tasks-during-shutdown.patch
@@ -60,4 +60,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
@Override
public void reloadData() {
- console.reload();
+ CommandReload.reload(console);
diff --git a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch
index ed514bdb3..d522ba9bd 100644
--- a/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch
+++ b/Spigot-Server-Patches/Workaround-for-Client-Lag-Spikes-MC-162253.patch
@@ -102,8 +102,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ apacket = new Packet[10];
+ }
+ // Paper end
- apacket[0] = new PacketPlayOutMapChunk(chunk, 65535);
- apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine);
+ apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true);
+ apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine, true);
+
+ // Paper start - Fix MC-162253
+ final int lightMask = getLightMask(chunk);
@@ -127,7 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue;
+ }
+
-+ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0);
++ apacket[i] = new PacketPlayOutLightUpdate(new ChunkCoordIntPair(chunk.getPos().x + x, chunk.getPos().z + z), lightEngine, updateLightMask, 0, true);
+ }
+ }
+ }
diff --git a/work/Bukkit b/work/Bukkit
index 6f3c5f4a5..8edeffe67 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit 6f3c5f4a5a0867ef265df9d58b48bdc43079e3dd
+Subproject commit 8edeffe67d1821afd48d16cd0ec2572251f24ee8
diff --git a/work/CraftBukkit b/work/CraftBukkit
index 3f0c33387..d1fb662ec 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit 3f0c333870ba74705e98d19322174d6f0c10c900
+Subproject commit d1fb662ec53c4fd8bc718039b76a3e9a11346371
diff --git a/work/Spigot b/work/Spigot
index 758abbeee..8fc58f10a 160000
--- a/work/Spigot
+++ b/work/Spigot
@@ -1 +1 @@
-Subproject commit 758abbeee4e12f5ff65470999dd9955d0ebb49cd
+Subproject commit 8fc58f10ab171ca1979afa2065909214a0ffab32