diff --git a/Paper-MojangAPI/pom.xml b/Paper-MojangAPI/pom.xml index d0da7daf4e..4c7c62c787 100644 --- a/Paper-MojangAPI/pom.xml +++ b/Paper-MojangAPI/pom.xml @@ -10,7 +10,7 @@ <groupId>com.destroystokyo.paper</groupId> <artifactId>paper-mojangapi</artifactId> - <version>1.15.2-R0.1-SNAPSHOT</version> + <version>1.16.1-R0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>Paper-MojangAPI</name> diff --git a/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch b/Spigot-Server-Patches/Add-ProjectileCollideEvent.patch index bec046d55f..46d33f3603 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 f5aaed2731..ed9e673a98 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 5dd95643b7..0000000000 --- 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 <proximyst@proximyst.com> -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 d37d07d188..46409b3cdb 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 9f68c91343..11429dfed7 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<T> implements Comparable<Ticket<?>> { - 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 df47863da2..0000000000 --- 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 <aikar@aikar.co> -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 a28cbb2327..18a1927e0b 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 f350339dd9..1d08fe4d31 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<Entity> 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 89ac9db8d9..2daa038477 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 d08a9ac7a2..374b7dc20c 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 6226dbf047..0000000000 --- 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 <aikar@aikar.co> -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<DimensionManager> registry = (RegistryMaterials<DimensionManager>) 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<K> implements Registry<K> { - - 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<K> implements Registry<K> { - 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<T> extends IRegistryWritable<T> { - 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 extends T> 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 098b71e7c8..2fbdef8430 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 e854d69013..f986ea7e3c 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 2892b633b8..6001012c5c 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 4e5bd971a2..665a490241 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 df33fd65b8..d3df7489ae 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 582ad169ef..ee4cbb798c 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<Ticket<?>> arraysetsorted) { -+ AsyncCatcher.catchOp("ChunkMapDistance::getHighestTicketLevel"); // Paper + private static int getLowestTicketLevel(ArraySetSorted<Ticket<?>> 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<Ticket<?>> 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<Ticket<?>> 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<Runnable> executor; ++ final java.util.concurrent.Executor mainInvokingExecutor; // Paper + public final ChunkGenerator chunkGenerator; + private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> 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<Runnable> 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<T> tickettype, int i, T t0) { this.a = tickettype; +@@ -0,0 +0,0 @@ public final class Ticket<T> implements Comparable<Ticket<?>> { + 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 afa783e784..0000000000 --- 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 <jellysquid+atwork@protonmail.com> -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<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> 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<AxisAlignedBB> 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<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection); -+ List<VoxelShape> 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 3d44288fc9..731e33773e 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 2fa7eecbdf..b18c0d5013 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<Runnable> executor; -+ final java.util.concurrent.Executor mainInvokingExecutor; // Paper - public final ChunkGenerator<?> chunkGenerator; - private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> 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<Runnable> 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 8b6545fd60..0000000000 --- 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 <aikar@aikar.co> -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<Block> q; - private final ProtoChunkTickList<FluidType> r; - private long s; -- private final Map<WorldGenStage.Features, BitSet> t; -+ private final Map<WorldGenStage.Features, BitSet> 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 5dfc5efb24..5a84de14ae 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<BlockPosition> 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<BlockPosition> t() { +@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition { } public static Stream<SectionPosition> 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<SectionPosition> b(ChunkCoordIntPair chunkcoordintpair, int i) { diff --git a/Spigot-Server-Patches/Optimize-Light-Engine.patch b/Spigot-Server-Patches/Optimize-Light-Engine.patch index 6cf38f1f3d..fb85cb52b1 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<Block, IBlockData> 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<IBlockState<?>, Comparable<?>> immutablemap) { - super(block, immutablemap); -@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> 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<Block, IBlockData> 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<Block, IBlockData> 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<M extends LightEngineStorageArray<M>, 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<M extends LightEngineStorageArray<M>, S e return i == Long.MAX_VALUE ? 0 : 15 - this.c.i(i); } @@ -583,6 +537,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected final Long2ObjectMap<NibbleArray> 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<M extends LightEngineStorageArray<M>> 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<M extends LightEngineStorageArray<M>> 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<Long2ObjectMap.Entry<NibbleArray>> objectiterator = Long2ObjectMaps.fastIterator(this.i); // Paper - +@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> 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<M extends LightEngineStorageArray<M>> 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<M extends LightEngineStorageArray<M>> 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<M extends LightEngineStorageArray<M>> e - if (this.g(j)) { - objectiterator.remove(); - } -- } -+ }*/ -+ // Paper end - } - } + private void b(LightEngineLayer<M, ?> 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 807f67ee00..b3b2dca4eb 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<M extends LightEngineStorageArray<M>> 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<PacketListenerPlayOut> { - private List<byte[]> g; private List<byte[]> 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<PacketListenerPlayOut> { - 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 a4f5fc72c8..0000000000 --- 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 <aikar@aikar.co> -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<PathDestination, BlockPosition> 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.Entry<PathDestination, BlockPosition>> 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<PathDestination, BlockPosition> map, float f, int i, float f1) { -- Set<PathDestination> set = map.keySet(); -+ private PathEntity a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> list, float f, int i, float f1) { // Paper - list instead of set -+ //Set<PathDestination> 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<PathEntity> optional = stream.findFirst(); -- -- if (!optional.isPresent()) { -- return null; -+ List<PathEntity> candidates = new java.util.ArrayList<>(); -+ if (result) { -+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) { -+ Map.Entry<PathDestination, BlockPosition> 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<PathDestination, BlockPosition> 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<PathDestination> set) { -+ private float a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> 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 28c23761a5..0000000000 --- a/Spigot-Server-Patches/Optimize-Villagers.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar <aikar@aikar.co> -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<EntityCreature> { - - 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<VillagePlaceType> 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<VillagePlaceSection> section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v()); -+ if (section == null || !section.isPresent()) continue; -+ for (java.util.Map.Entry<VillagePlaceType, java.util.Set<VillagePlaceRecord>> 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<BlockPosition> predicate = (blockposition) -> { - long j = blockposition.asLong(); - -@@ -0,0 +0,0 @@ public class BehaviorFindPosition extends Behavior<EntityCreature> { - 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<R extends MinecraftSerializable> extends RegionFi - - @Nullable - protected Optional<R> c(long i) { -- return (Optional) this.c.get(i); -+ return this.c.getOrDefault(i, Optional.empty()); // Paper - } - -+ protected final Optional<R> getSection(long i) { return d(i); } // Paper - OBFHELPER - protected Optional<R> d(long i) { -- SectionPosition sectionposition = SectionPosition.a(i); -- -- if (this.b(sectionposition)) { -- return Optional.empty(); -- } else { -- Optional<R> 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<R extends MinecraftSerializable> extends RegionFi - private <T> void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps<T> 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<T> dynamic = new Dynamic(dynamicops, t0); -@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> 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<R extends MinecraftSerializable> 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<VillagePlaceRecord> b = new Short2ObjectOpenHashMap(); -- private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap(); -+ private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap(); public final Map<VillagePlaceType, Set<VillagePlaceRecord>> 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<VillagePlaceType> professionCache; // Paper - private static final Predicate<VillagePlaceType> 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<VillagePlaceType> a = (villageplacetype) -> { - return true; -@@ -0,0 +0,0 @@ public class VillagePlaceType { - } - - private static VillagePlaceType a(String s, Set<IBlockData> 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<IBlockData> set, int i, Predicate<VillagePlaceType> 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<Item> immutableset, ImmutableSet<Block> 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 a56e8b94c7..0000000000 --- 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 <Spottedleaf@users.noreply.github.com> -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<VoxelShape> stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape); -+ Stream<VoxelShape> stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Paper - Stream<VoxelShape> stream1 = this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of()); - StreamAccumulator<VoxelShape> 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 7ea3613afe..134174dfab 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<World> 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<EntityPlayer> 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 ee23f17e5b..6be7b50705 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 a7c6bebe2f..e99bfb9b92 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 53a56729a9..aaf34a5dd0 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 11e7c2b77b..a503eadde2 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 d5f31067f6..22866d1f23 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<Block, IBlockData> 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<Float> 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<Block, IBlockData> 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 b24552de12..7475f09739 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 0576b73640..0000000000 --- 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 <aikar@aikar.co> -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<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper - @Override - default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> 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<Entity> 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<VoxelShape> 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<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper - default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) { - return Stream.empty(); - } - - default Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) { -- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)}); -+ // Paper start - reduce stream usage -+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, false); -+ java.util.List<VoxelShape> entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false); -+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream()); -+ // Paper end - } - - default Stream<VoxelShape> b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) { -+ // Paper start - reduce stream usage -+ java.util.List<VoxelShape> collision = getBlockCollision(entity, axisalignedbb, false); -+ return !collision.isEmpty() ? collision.stream() : Stream.empty(); -+ } -+ -+ default java.util.List<VoxelShape> 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<VoxelShape>(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<VoxelShape> collisions = new java.util.ArrayList<>(); -+ if (true) {//return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(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<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) { - AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D); - List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection); - List<VoxelShape> 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 6b9f14f647..e0719937b4 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 0abc1fe615..da8315f553 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 dfda5c8dbb..0a4383c036 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 ed514bdb37..d522ba9bda 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 6f3c5f4a5a..8edeffe67d 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 6f3c5f4a5a0867ef265df9d58b48bdc43079e3dd +Subproject commit 8edeffe67d1821afd48d16cd0ec2572251f24ee8 diff --git a/work/CraftBukkit b/work/CraftBukkit index 3f0c333870..d1fb662ec5 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 3f0c333870ba74705e98d19322174d6f0c10c900 +Subproject commit d1fb662ec53c4fd8bc718039b76a3e9a11346371 diff --git a/work/Spigot b/work/Spigot index 758abbeee4..8fc58f10ab 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit 758abbeee4e12f5ff65470999dd9955d0ebb49cd +Subproject commit 8fc58f10ab171ca1979afa2065909214a0ffab32