From 6f7af0038efe8e8f77825005e81f179c5954a9a2 Mon Sep 17 00:00:00 2001 From: MrPowerGamerBR Date: Tue, 27 Jul 2021 21:03:39 -0300 Subject: [PATCH] Update Tuinity, remove Airplane patches for now --- gradle.properties | 2 +- ...fork-who-dis-Rebrand-to-SparklyPaper.patch | 12 +- patches/server/0002-idk.patch | 4 +- ...cing-for-EntityLiving-hasLineOfSight.patch | 161 ------ ...pelessRecipes-comparison-for-Vanilla.patch | 84 --- ...0007-Reduce-projectile-chunk-loading.patch | 63 --- ...check-for-spooky-season-once-an-hour.patch | 49 -- ...timize-random-calls-in-chunk-ticking.patch | 109 ---- patches/server/0010-Cache-palette-array.patch | 77 --- .../0011-Reduce-chunk-loading-lookups.patch | 45 -- ...Skip-POI-finding-if-stuck-in-vehicle.patch | 33 -- ...ve-iterators-from-inventory-contains.patch | 38 -- ...turn-optimization-for-target-finding.patch | 31 -- ...-for-plugins-not-shutting-down-tasks.patch | 22 - ...0016-Improve-fluid-direction-caching.patch | 240 --------- ...-Cache-climbing-check-for-activation.patch | 52 -- .../0018-Use-array-for-gamerule-storage.patch | 66 --- ...llisionContext-a-live-representation.patch | 117 ----- ...ove-container-checking-with-a-bitset.patch | 491 ------------------ ...er-checking-for-useless-move-packets.patch | 26 - ...er-to-use-fast-item-merge-raytracing.patch | 27 - ...e-aging-cache-for-biome-temperatures.patch | 181 ------- ...ld-height-in-the-chunk-as-it-s-final.patch | 46 -- ...hread-unsafe-random-for-mob-spawning.patch | 40 -- ...reams-and-iterators-from-range-check.patch | 49 -- ...-streams-from-getting-nearby-players.patch | 60 --- .../0028-Skip-cloning-loot-parameters.patch | 27 - ...045-block-goal-shouldn-t-load-chunks.patch | 18 - ...-sequencing-of-futures-for-chunk-gen.patch | 30 -- ...031-Remove-lambda-from-ticking-guard.patch | 52 -- 30 files changed, 9 insertions(+), 2243 deletions(-) delete mode 100644 patches/server/0005-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch delete mode 100644 patches/server/0006-Simpler-ShapelessRecipes-comparison-for-Vanilla.patch delete mode 100644 patches/server/0007-Reduce-projectile-chunk-loading.patch delete mode 100644 patches/server/0008-Only-check-for-spooky-season-once-an-hour.patch delete mode 100644 patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch delete mode 100644 patches/server/0010-Cache-palette-array.patch delete mode 100644 patches/server/0011-Reduce-chunk-loading-lookups.patch delete mode 100644 patches/server/0012-Skip-POI-finding-if-stuck-in-vehicle.patch delete mode 100644 patches/server/0013-Remove-iterators-from-inventory-contains.patch delete mode 100644 patches/server/0014-Early-return-optimization-for-target-finding.patch delete mode 100644 patches/server/0015-More-debug-for-plugins-not-shutting-down-tasks.patch delete mode 100644 patches/server/0016-Improve-fluid-direction-caching.patch delete mode 100644 patches/server/0017-Cache-climbing-check-for-activation.patch delete mode 100644 patches/server/0018-Use-array-for-gamerule-storage.patch delete mode 100644 patches/server/0019-Make-EntityCollisionContext-a-live-representation.patch delete mode 100644 patches/server/0020-Improve-container-checking-with-a-bitset.patch delete mode 100644 patches/server/0021-Better-checking-for-useless-move-packets.patch delete mode 100644 patches/server/0022-Patch-Paper-to-use-fast-item-merge-raytracing.patch delete mode 100644 patches/server/0023-Use-aging-cache-for-biome-temperatures.patch delete mode 100644 patches/server/0024-Cache-world-height-in-the-chunk-as-it-s-final.patch delete mode 100644 patches/server/0025-Use-thread-unsafe-random-for-mob-spawning.patch delete mode 100644 patches/server/0026-Remove-streams-and-iterators-from-range-check.patch delete mode 100644 patches/server/0027-Remove-streams-from-getting-nearby-players.patch delete mode 100644 patches/server/0028-Skip-cloning-loot-parameters.patch delete mode 100644 patches/server/0029-Fix-Paper-6045-block-goal-shouldn-t-load-chunks.patch delete mode 100644 patches/server/0030-Quicker-sequencing-of-futures-for-chunk-gen.patch delete mode 100644 patches/server/0031-Remove-lambda-from-ticking-guard.patch diff --git a/gradle.properties b/gradle.properties index 1433574..23c927b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version = 1.17.1-R0.1-SNAPSHOT mcVersion = 1.17.1 packageVersion = 1_17_R1 -tuinityRef = ea43797d5aa099543c0111314ae08e09e6ce7329 +tuinityRef = e4b092272731f380727b0f69c32c03039cb429bb org.gradle.jvmargs=-Xmx2G diff --git a/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper.patch b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper.patch index e7e5471..7461bc1 100644 --- a/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper.patch +++ b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper.patch @@ -5,10 +5,10 @@ Subject: [PATCH] new fork who dis - Rebrand to SparklyPaper diff --git a/build.gradle.kts b/build.gradle.kts -index ab8de6c4e3c0bea2b9f498da00adf88e987d2364..8fc6315cf8afa10866f7a15c7a02f0d88f113007 100644 +index b7e5bdcfe04ab7d8d8d453a787849963640262a5..5df9abac33825f69fc181dd20be4522164cfe1c6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -36,7 +36,7 @@ repositories { +@@ -34,7 +34,7 @@ repositories { } dependencies { @@ -17,13 +17,13 @@ index ab8de6c4e3c0bea2b9f498da00adf88e987d2364..8fc6315cf8afa10866f7a15c7a02f0d8 implementation("com.destroystokyo.paper:paper-mojangapi:1.16.5-R0.1-SNAPSHOT") // Tuinity // Paper start implementation("org.jline:jline-terminal-jansi:3.12.1") -@@ -88,7 +88,7 @@ tasks.jar { +@@ -86,7 +86,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", - "Implementation-Version" to "git-Tuinity-$implementationVersion", // Tuinity + "Implementation-Version" to "git-SparklyPaper-$implementationVersion", // SparklyPaper - "Implementation-Vendor" to SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(Date()), // Paper + "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -40,10 +40,10 @@ index f25bb4214cffd0050241ea229b6acb0c16b2b0a5..c5390c532b62042c81103c750af6e88b public SystemReport fillSystemReport(SystemReport details) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 4342bc5aad49fe372d561296a6b63818a443d089..1250780c864052fe6b9876d74398121e38861346 100644 +index 1ec307d705087eec9d867f9f8e8858ac388f3846..ecbae283bc99fcba1e48dcebe4f970e0734e9467 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -230,7 +230,7 @@ import javax.annotation.Nullable; // Paper +@@ -239,7 +239,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { diff --git a/patches/server/0002-idk.patch b/patches/server/0002-idk.patch index ea581d2..2196ff3 100644 --- a/patches/server/0002-idk.patch +++ b/patches/server/0002-idk.patch @@ -5,10 +5,10 @@ Subject: [PATCH] idk diff --git a/build.gradle.kts b/build.gradle.kts -index ab8de6c4e3c0bea2b9f498da00adf88e987d2364..fbd71fc0d2619278565537cd565a99282d84f587 100644 +index 5df9abac33825f69fc181dd20be4522164cfe1c6..36fe79d2cbf1941c0b02b8de3c8070241bc5f68e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -184,7 +184,7 @@ abstract class IncludeMappings : BaseTask() { +@@ -182,7 +182,7 @@ abstract class IncludeMappings : BaseTask() { } val includeMappings = tasks.register("includeMappings") { diff --git a/patches/server/0005-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/server/0005-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch deleted file mode 100644 index 51ed206..0000000 --- a/patches/server/0005-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sat, 31 Oct 2020 18:43:02 -0500 -Subject: [PATCH] Strip raytracing for EntityLiving#hasLineOfSight - -The IBlockAccess#rayTrace method is very wasteful in both allocations, -and in logic. While EntityLiving#hasLineOfSight provides static -parameters for collisions with blocks and fluids, the method still does -a lot of dynamic checks for both of these, which result in extra work. -As well, since the fluid collision option is set to NONE, the entire -fluid collision system is completely unneeded, yet used anyways. - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index ed745776316c5346ee1b44c8f022c40359b7e642..402b785b5fd0e1c3c5c02505dca332990ec64e37 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3428,7 +3428,10 @@ public abstract class LivingEntity extends Entity { - Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ()); - - // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists -- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; -+ // Airplane start -+ //return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; -+ return this.level.rayTraceDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.BlockHitResult.Type.MISS; -+ // Airplane end - } - } - -diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java -index ec781ab232d12cedb5f0236860377c4917c576d7..ced4b354e83ad68f8f1aacdefe2f0ce0035bd4a7 100644 ---- a/src/main/java/net/minecraft/world/level/BlockGetter.java -+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java -@@ -73,6 +73,16 @@ public interface BlockGetter extends LevelHeightAccessor { - }); - } - -+ // Airplane start - broken down variant of below rayTraceBlock, used by World#rayTraceDirect -+ default net.minecraft.world.phys.BlockHitResult.Type rayTraceBlockDirect(Vec3 vec3d, Vec3 vec3d1, BlockPos blockposition, BlockState iblockdata, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) { -+ if (iblockdata.isAir()) return null; // Tuinity - optimise air cases -+ VoxelShape voxelshape = ClipContext.Block.COLLIDER.get(iblockdata, this, blockposition, voxelshapecoll); -+ net.minecraft.world.phys.BlockHitResult movingobjectpositionblock = this.clipWithInteractionOverride(vec3d, vec3d1, blockposition, voxelshape, iblockdata); -+ -+ return movingobjectpositionblock == null ? null : movingobjectpositionblock.getType(); -+ } -+ // Airplane end -+ - // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace - default BlockHitResult rayTraceBlock(ClipContext raytrace1, BlockPos blockposition) { - // Paper start - Prevent raytrace from loading chunks -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 61a4dea715689b0ce9247040db5dd2080ee2e167..a2bb8eee5ef4a5043026af20f78bb43a5006e6b4 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -453,6 +453,91 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return null; - } - -+ // Airplane start - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace) -+ public net.minecraft.world.phys.BlockHitResult.Type rayTraceDirect(net.minecraft.world.phys.Vec3 vec3d, net.minecraft.world.phys.Vec3 vec3d1, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) { -+ // most of this code comes from IBlockAccess#a(RayTrace, BiFunction, Function), but removes the needless functions -+ if (vec3d.equals(vec3d1)) { -+ return net.minecraft.world.phys.BlockHitResult.Type.MISS; -+ } -+ -+ double endX = Mth.lerp(-1.0E-7D, vec3d1.x, vec3d.x); -+ double endY = Mth.lerp(-1.0E-7D, vec3d1.y, vec3d.y); -+ double endZ = Mth.lerp(-1.0E-7D, vec3d1.z, vec3d.z); -+ -+ double startX = Mth.lerp(-1.0E-7D, vec3d.x, vec3d1.x); -+ double startY = Mth.lerp(-1.0E-7D, vec3d.y, vec3d1.y); -+ double startZ = Mth.lerp(-1.0E-7D, vec3d.z, vec3d1.z); -+ -+ int currentX = Mth.floor(startX); -+ int currentY = Mth.floor(startY); -+ int currentZ = Mth.floor(startZ); -+ -+ BlockPos.MutableBlockPos currentBlock = new BlockPos.MutableBlockPos(currentX, currentY, currentZ); -+ -+ LevelChunk chunk = this.getChunkIfLoaded(currentBlock); -+ if (chunk == null) { -+ return net.minecraft.world.phys.BlockHitResult.Type.MISS; -+ } -+ -+ net.minecraft.world.phys.BlockHitResult.Type initialCheck = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll); -+ -+ if (initialCheck != null) { -+ return initialCheck; -+ } -+ -+ double diffX = endX - startX; -+ double diffY = endY - startY; -+ double diffZ = endZ - startZ; -+ -+ int xDirection = Mth.sign(diffX); -+ int yDirection = Mth.sign(diffY); -+ int zDirection = Mth.sign(diffZ); -+ -+ double normalizedX = xDirection == 0 ? Double.MAX_VALUE : (double) xDirection / diffX; -+ double normalizedY = yDirection == 0 ? Double.MAX_VALUE : (double) yDirection / diffY; -+ double normalizedZ = zDirection == 0 ? Double.MAX_VALUE : (double) zDirection / diffZ; -+ -+ double normalizedXDirection = normalizedX * (xDirection > 0 ? 1.0D - Mth.frac(startX) : Mth.frac(startX)); -+ double normalizedYDirection = normalizedY * (yDirection > 0 ? 1.0D - Mth.frac(startY) : Mth.frac(startY)); -+ double normalizedZDirection = normalizedZ * (zDirection > 0 ? 1.0D - Mth.frac(startZ) : Mth.frac(startZ)); -+ -+ net.minecraft.world.phys.BlockHitResult.Type result; -+ -+ do { -+ if (normalizedXDirection > 1.0D && normalizedYDirection > 1.0D && normalizedZDirection > 1.0D) { -+ return net.minecraft.world.phys.BlockHitResult.Type.MISS; -+ } -+ -+ if (normalizedXDirection < normalizedYDirection) { -+ if (normalizedXDirection < normalizedZDirection) { -+ currentX += xDirection; -+ normalizedXDirection += normalizedX; -+ } else { -+ currentZ += zDirection; -+ normalizedZDirection += normalizedZ; -+ } -+ } else if (normalizedYDirection < normalizedZDirection) { -+ currentY += yDirection; -+ normalizedYDirection += normalizedY; -+ } else { -+ currentZ += zDirection; -+ normalizedZDirection += normalizedZ; -+ } -+ -+ currentBlock.set(currentX, currentY, currentZ); -+ if (chunk.getPos().x != currentBlock.getX() >> 4 || chunk.getPos().z != currentBlock.getZ() >> 4) { -+ chunk = this.getChunkIfLoaded(currentBlock); -+ if (chunk == null) { -+ return net.minecraft.world.phys.BlockHitResult.Type.MISS; -+ } -+ } -+ result = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll); -+ } while (result == null); -+ -+ return result; -+ } -+ // Airplane end -+ - public boolean isInWorldBounds(BlockPos pos) { - return pos.isValidLocation(this); // Paper - use better/optimized check - } diff --git a/patches/server/0006-Simpler-ShapelessRecipes-comparison-for-Vanilla.patch b/patches/server/0006-Simpler-ShapelessRecipes-comparison-for-Vanilla.patch deleted file mode 100644 index ab1025d..0000000 --- a/patches/server/0006-Simpler-ShapelessRecipes-comparison-for-Vanilla.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sat, 31 Oct 2020 18:51:38 -0500 -Subject: [PATCH] Simpler ShapelessRecipes comparison for Vanilla - -Paper added a fancy sorting comparison due to Bukkit recipes breaking -the vanilla one, however this is far more advanced than what you need -for all the vanilla recipes. - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -index 6b960f0a31175bcfd8d477ee5b3c4d783303cdd5..3a81d3a58b937c9800cd0be738439cff0ba28ce9 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -+++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java -@@ -25,8 +25,13 @@ public class ShapelessRecipe implements CraftingRecipe { - final String group; - final ItemStack result; - final NonNullList ingredients; -+ private final boolean isBukkit; // Airplane - -+ // Airplane start - public ShapelessRecipe(ResourceLocation id, String group, ItemStack output, NonNullList input) { -+ this(id, group, output, input, false); -+ } -+ public ShapelessRecipe(ResourceLocation id, String group, ItemStack output, NonNullList input, boolean isBukkit) { this.isBukkit = isBukkit; // Airplane end - this.id = id; - this.group = group; - this.result = output; -@@ -73,6 +78,28 @@ public class ShapelessRecipe implements CraftingRecipe { - } - - public boolean matches(CraftingContainer inventory, Level world) { -+ // Airplane start -+ if (!this.isBukkit) { -+ java.util.List ingredients = com.google.common.collect.Lists.newArrayList(this.ingredients.toArray(new Ingredient[0])); -+ -+ inventory: for (int index = 0; index < inventory.getContainerSize(); index++) { -+ ItemStack itemStack = inventory.getItem(index); -+ -+ if (!itemStack.isEmpty()) { -+ for (int i = 0; i < ingredients.size(); i++) { -+ if (ingredients.get(i).test(itemStack)) { -+ ingredients.remove(i); -+ continue inventory; -+ } -+ } -+ return false; -+ } -+ } -+ -+ return ingredients.isEmpty(); -+ } -+ // Airplane end -+ - StackedContents autorecipestackmanager = new StackedContents(); - int i = 0; - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java -index 0b3b46348ac9195bff1492ffc11fcbff7d3f5c6f..4010052c53f3a2831b4d5aa1c041d85897856acb 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java -@@ -43,6 +43,6 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe - data.set(i, toNMS(ingred.get(i), true)); - } - -- MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.ShapelessRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), CraftItemStack.asNMSCopy(this.getResult()), data)); -+ MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.ShapelessRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), CraftItemStack.asNMSCopy(this.getResult()), data, true)); - } - } diff --git a/patches/server/0007-Reduce-projectile-chunk-loading.patch b/patches/server/0007-Reduce-projectile-chunk-loading.patch deleted file mode 100644 index 71f68d6..0000000 --- a/patches/server/0007-Reduce-projectile-chunk-loading.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sun, 13 Dec 2020 17:52:35 -0600 -Subject: [PATCH] Reduce projectile chunk loading - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index 69f439851fe1ff07d827eaed274940a5783d5f6c..bfa2a1ad2bf8004d7545cd2175834fa00fcdb8bb 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -42,6 +42,37 @@ public abstract class Projectile extends Entity { - super(type, world); - } - -+ // Airplane start -+ private static int loadedThisTick = 0; -+ private static int loadedTick; -+ -+ private int buffered = 0; -+ @Override -+ public void setPos(double x, double y, double z) { -+ int currentTick = net.minecraft.server.MinecraftServer.currentTick; -+ if (loadedTick != currentTick) { -+ loadedTick = currentTick; -+ loadedThisTick = 0; -+ } -+ int previousX = Mth.floor(this.getX()) >> 4, previousZ = Mth.floor(this.getX()) >> 4; -+ int newX = Mth.floor(z) >> 4, newZ = Mth.floor(z) >> 4; -+ if (previousX != newX || previousZ != newZ) { -+ boolean isLoaded = ((net.minecraft.server.level.ServerChunkCache) this.level.getChunkSource()).getChunkAtIfLoadedMainThreadNoCache(newX, newZ) != null; -+ if (!isLoaded) { -+ if (loadedThisTick > 10) { // Airplane 10 = max chunks to load from projectiles in a tick todo config -+ if (++buffered > 20) { // Airplane 20 = max chunks a single projectile loads overall todo config -+ this.discard(); -+ } -+ return; -+ } -+ loadedThisTick++; -+ } -+ buffered = 0; -+ } -+ super.setPos(x, y, z); -+ } -+ // Airplane start -+ - public void setOwner(@Nullable Entity entity) { - if (entity != null) { - this.ownerUUID = entity.getUUID(); diff --git a/patches/server/0008-Only-check-for-spooky-season-once-an-hour.patch b/patches/server/0008-Only-check-for-spooky-season-once-an-hour.patch deleted file mode 100644 index 10aaaa1..0000000 --- a/patches/server/0008-Only-check-for-spooky-season-once-an-hour.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sun, 13 Dec 2020 17:53:08 -0600 -Subject: [PATCH] Only check for spooky season once an hour - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index 153194d937d210e2e4fd8864e4a3c000f85d7e2e..1d415a91b9c90603e8f738dbafe7a5ea57ef14cc 100644 ---- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java -+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -254,13 +254,22 @@ public class Bat extends AmbientCreature { - } - } - -+ // Airplane start - only check for spooky season once an hour -+ private static boolean isSpookySeason = false; -+ private static final int ONE_HOUR = 20 * 60 * 60; -+ private static int lastSpookyCheck = -ONE_HOUR; - private static boolean isHalloween() { -+ if (net.minecraft.server.MinecraftServer.currentTick - lastSpookyCheck > ONE_HOUR) { - LocalDate localdate = LocalDate.now(); - int i = localdate.get(ChronoField.DAY_OF_MONTH); - int j = localdate.get(ChronoField.MONTH_OF_YEAR); - -- return j == 10 && i >= 20 || j == 11 && i <= 3; -+ isSpookySeason = j == 10 && i >= 20 || j == 11 && i <= 3; -+ lastSpookyCheck = net.minecraft.server.MinecraftServer.currentTick; -+ } -+ return isSpookySeason; - } -+ // Airplane end - - @Override - protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { diff --git a/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch b/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch deleted file mode 100644 index df958d2..0000000 --- a/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Thu, 7 Jan 2021 11:49:36 -0600 -Subject: [PATCH] Optimize random calls in chunk ticking - -Especially at over 30,000 chunks these random calls are fairly heavy. We -use a different method here for checking lightning, and for checking -ice. - -Lightning: Each chunk now keeps an int of how many ticks until the -lightning should strike. This int is a random number from 0 to 100000 * 2, -the multiplication is required to keep the probability the same. - -Ice and snow: We just generate a single random number 0-16 and increment -it, while checking if it's 0 for the current chunk. - -Depending on configuration for things that tick in a chunk, this is a -5-10% improvement. - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index db39671881b622189961b39309a323a1b35d680e..5309e9060766c6f16bce6156c6d84e26b1dbb6b1 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -981,6 +981,7 @@ public class ServerChunkCache extends ChunkSource { - } - // Paper end - optimize isOutisdeRange - this.level.getProfiler().push("pollingChunks"); -+ this.level.resetIceAndSnowTick(); // Airplane - reset ice & snow tick random - int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); - boolean flag2 = level.ticksPerAnimalSpawns != 0L && worlddata.getGameTime() % level.ticksPerAnimalSpawns == 0L; // CraftBukkit - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 7642170bf5a0eaa11110238fa5cf1a7e1ff20a20..bb51d9c842a3b1bc517b378194c61a6c30b629c3 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -881,6 +881,8 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - private final com.tuinity.tuinity.util.math.ThreadUnsafeRandom randomTickRandom = new com.tuinity.tuinity.util.math.ThreadUnsafeRandom(); - // Paper end - -+ private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Airplane -+ - public void tickChunk(LevelChunk chunk, int randomTickSpeed) { - ChunkPos chunkcoordintpair = chunk.getPos(); - boolean flag = this.isRaining(); -@@ -891,7 +893,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - gameprofilerfiller.push("thunder"); - final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change - -- if (!this.paperConfig.disableThunder && flag && this.isThundering() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder -+ if (!this.paperConfig.disableThunder && flag && this.isThundering() && chunk.shouldDoLightning(this.random)) { // Paper - Disable thunder // Airplane - replace random with shouldDoLightning - blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper - if (this.isRainingAt(blockposition)) { - DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); -@@ -915,7 +917,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - } - - gameprofilerfiller.popPush("iceandsnow"); -- if (!this.paperConfig.disableIceAndSnow && this.randomTickRandom.nextInt(16) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking -+ if (!this.paperConfig.disableIceAndSnow && (this.currentIceAndSnowTick++ & 15) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking // Airplane - optimize further random ticking - // Paper start - optimise chunk ticking - this.getRandomBlockPosition(j, 0, k, 15, blockposition); - int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15) + 1; -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 54e23d303aad286ab46c3e5f9b17a5f9922e2942..4785cbd47e15f78c0302f1dc9bd904a4839ef8e4 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -172,6 +172,18 @@ public class LevelChunk implements ChunkAccess { - } - // Tuinity end - rewrite light engine - -+ // Airplane start - instead of using a random every time the chunk is ticked, define when lightning strikes preemptively -+ private int lightningTick; -+ // shouldDoLightning compiles down to 29 bytes, which with the default of 35 byte inlining should guarantee an inline -+ public final boolean shouldDoLightning(java.util.Random random) { -+ if (this.lightningTick-- <= 0) { -+ this.lightningTick = random.nextInt(100000) << 1; -+ return true; -+ } -+ return false; -+ } -+ // Airplane end -+ - public LevelChunk(Level world, ChunkPos pos, ChunkBiomeContainer biomes) { - this(world, pos, biomes, UpgradeData.EMPTY, EmptyTickList.empty(), EmptyTickList.empty(), 0L, (LevelChunkSection[]) null, (Consumer) null); - } -@@ -220,6 +232,7 @@ public class LevelChunk implements ChunkAccess { - this.postProcessing = new ShortList[world.getSectionsCount()]; - // CraftBukkit start - this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); -+ this.lightningTick = this.level.random.nextInt(100000) << 1; // Airplane - initialize lightning tick - } - - public org.bukkit.Chunk bukkitChunk; diff --git a/patches/server/0010-Cache-palette-array.patch b/patches/server/0010-Cache-palette-array.patch deleted file mode 100644 index d5e6118..0000000 --- a/patches/server/0010-Cache-palette-array.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Thu, 4 Feb 2021 23:28:46 -0600 -Subject: [PATCH] Cache palette array - -The reasoning for reusing it in ChunkRegionLoader is because ThreadLocal -lookups are fairly expensive, and if we put it in DataPaletteBlock the -ThreadLocal lookup would happen 18 times. - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index ebeb3e3b0619b034a9681da999e9ac33cc241718..5b5ada474cff54b424946fc628d30f25a6774684 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -263,13 +263,17 @@ public class PalettedContainer implements PaletteResize { - - } - -+ // Airplane start - allow reusing int array - public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey) { // Paper - synchronize -+ this.write(nbt, paletteKey, dataKey, new int[4096]); -+ } -+ public synchronized void write(CompoundTag nbt, String paletteKey, String dataKey, int[] is) { // Paper - synchronize // Airplane end - try { - this.acquire(); - HashMapPalette hashMapPalette = new HashMapPalette<>(this.registry, this.bits, this.dummyPaletteResize, this.reader, this.writer); - T object = this.defaultValue; - int i = hashMapPalette.idFor(this.defaultValue); -- int[] is = new int[4096]; -+ //int[] is = new int[4096]; // Airplane - - for(int j = 0; j < 4096; ++j) { - T object2 = this.get(j); -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 917fa5a3106259c01d6a01acf770890dbdf50f1a..b9d5785a5feccd905828e7f82264c3cb48c3c773 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -485,6 +485,7 @@ public class ChunkSerializer { - return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime()); - } - -+ private static final ThreadLocal paletteArray = ThreadLocal.withInitial(() -> new int[4096]); // Airplane - public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { - return saveChunk(world, chunk, null); - } -@@ -518,6 +519,7 @@ public class ChunkSerializer { - ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine(); - boolean flag = chunk.isLightCorrect(); - -+ int[] is = paletteArray.get(); // Airplane - use cached - for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) { - int finalI = i; // CraftBukkit - decompile errors - LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> { -@@ -532,7 +534,7 @@ public class ChunkSerializer { - - nbttagcompound2.putByte("Y", (byte) (i & 255)); - if (chunksection != LevelChunk.EMPTY_SECTION) { -- chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates"); -+ chunksection.getStates().write(nbttagcompound2, "Palette", "BlockStates", is); // Airplane - reuse array - } - - // Tuinity start - replace light engine diff --git a/patches/server/0011-Reduce-chunk-loading-lookups.patch b/patches/server/0011-Reduce-chunk-loading-lookups.patch deleted file mode 100644 index ba6fb99..0000000 --- a/patches/server/0011-Reduce-chunk-loading-lookups.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Thu, 4 Feb 2021 23:33:52 -0600 -Subject: [PATCH] Reduce chunk loading & lookups - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -index e1e220b3e4967590a2a77370e2a6ab919ad50eaa..5d371a3e94720e24058d007474355af6aeb7cbdd 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -312,11 +312,17 @@ public class EnderMan extends Monster implements NeutralMob { - private boolean teleport(double x, double y, double z) { - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z); - -- while (blockposition_mutableblockposition.getY() > this.level.getMinBuildHeight() && !this.level.getBlockState(blockposition_mutableblockposition).getMaterial().blocksMotion()) { -+ // Airplane start - single chunk lookup -+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkIfLoaded(blockposition_mutableblockposition); -+ if (chunk == null) { -+ return false; -+ } -+ // Airplane end -+ while (blockposition_mutableblockposition.getY() > this.level.getMinBuildHeight() && !chunk.getBlockState(blockposition_mutableblockposition).getMaterial().blocksMotion()) { // Airplane - blockposition_mutableblockposition.move(Direction.DOWN); - } - -- BlockState iblockdata = this.level.getBlockState(blockposition_mutableblockposition); -+ BlockState iblockdata = chunk.getBlockState(blockposition_mutableblockposition); // Airplane - boolean flag = iblockdata.getMaterial().blocksMotion(); - boolean flag1 = iblockdata.getFluidState().is((Tag) FluidTags.WATER); - diff --git a/patches/server/0012-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0012-Skip-POI-finding-if-stuck-in-vehicle.patch deleted file mode 100644 index 9fe6900..0000000 --- a/patches/server/0012-Skip-POI-finding-if-stuck-in-vehicle.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Thu, 18 Feb 2021 13:13:27 -0600 -Subject: [PATCH] Skip POI finding if stuck in vehicle - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index efe66264ad5717bf3aac0fbda07275fb5571acc1..68188f3322a9af8eac423afc5f87bc4f88f4a5bb 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -@@ -68,6 +68,7 @@ public class AcquirePoi extends Behavior { - @Override - protected void start(ServerLevel world, PathfinderMob entity, long time) { - this.nextScheduledStart = time + 20L + (long)world.getRandom().nextInt(20); -+ if (entity.getNavigation().isStuck()) this.nextScheduledStart += 200L; // Airplane - wait an additional 10s to check again if they're stuck - PoiManager poiManager = world.getPoiManager(); - this.batchCache.long2ObjectEntrySet().removeIf((entry) -> { - return !entry.getValue().isStillValid(time); diff --git a/patches/server/0013-Remove-iterators-from-inventory-contains.patch b/patches/server/0013-Remove-iterators-from-inventory-contains.patch deleted file mode 100644 index 5fd9196..0000000 --- a/patches/server/0013-Remove-iterators-from-inventory-contains.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sat, 13 Mar 2021 12:24:41 -0600 -Subject: [PATCH] Remove iterators from inventory contains - - -diff --git a/src/main/java/net/minecraft/world/entity/player/Inventory.java b/src/main/java/net/minecraft/world/entity/player/Inventory.java -index dace7d13787f6fb44af90792599fa16caad68052..8d414822894fc41460bb9ccc53d7b0dfd1204115 100644 ---- a/src/main/java/net/minecraft/world/entity/player/Inventory.java -+++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -688,6 +688,8 @@ public class Inventory implements Container, Nameable { - } - - public boolean contains(ItemStack stack) { -+ // Airplane start - don't allocate iterators -+ /* - Iterator iterator = this.compartments.iterator(); - - while (iterator.hasNext()) { -@@ -702,6 +704,18 @@ public class Inventory implements Container, Nameable { - } - } - } -+ */ -+ for (int i = 0; i < this.compartments.size(); i++) { -+ List list = this.compartments.get(i); -+ for (int j = 0; j < list.size(); j++) { -+ ItemStack itemstack1 = list.get(j); -+ -+ if (!itemstack1.isEmpty() && itemstack1.sameItem(stack)) { -+ return true; -+ } -+ } -+ } -+ // Airplane end - - return false; - } diff --git a/patches/server/0014-Early-return-optimization-for-target-finding.patch b/patches/server/0014-Early-return-optimization-for-target-finding.patch deleted file mode 100644 index f2d327b..0000000 --- a/patches/server/0014-Early-return-optimization-for-target-finding.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sat, 13 Mar 2021 15:05:28 -0600 -Subject: [PATCH] Early return optimization for target finding - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index 3ee691d4caccbc1b3e0f52decb41d436ac0d08ec..8a0aea6b28295e03aaac1768336b1bc36d9ad9e9 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -+++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -@@ -74,9 +74,18 @@ public class TargetingConditions { - } - - if (this.range > 0.0D) { -- double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D; -- double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper -+ // Airplane start - check range before getting visibility -+ // d = invisibility percent, e = follow range adjusted for invisibility, f = distance - double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); -+ double followRangeRaw = this.useFollowRange ? this.getFollowRange(baseEntity) : this.range; -+ -+ if (f > followRangeRaw * followRangeRaw) { // the actual follow range will always be this value or smaller, so if the distance is larger then it never will return true after getting invis -+ return false; -+ } -+ -+ double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D; -+ double e = Math.max((followRangeRaw) * d, 2.0D); // Paper -+ // Airplane end - if (f > e * e) { - return false; - } diff --git a/patches/server/0015-More-debug-for-plugins-not-shutting-down-tasks.patch b/patches/server/0015-More-debug-for-plugins-not-shutting-down-tasks.patch deleted file mode 100644 index 462a732..0000000 --- a/patches/server/0015-More-debug-for-plugins-not-shutting-down-tasks.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Wed, 17 Mar 2021 13:00:57 -0500 -Subject: [PATCH] More debug for plugins not shutting down tasks - - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 29eb6d5c43871ef7d6479864178e3b6e015903f8..b584d85bb61f2ffed81bb92520ffff0a5ccccb43 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -986,6 +986,11 @@ public final class CraftServer implements Server { - plugin.getDescription().getName(), - "This plugin is not properly shutting down its async tasks when it is being shut down. This task may throw errors during the final shutdown logs and might not complete before process dies." - )); -+ getLogger().log(Level.SEVERE, String.format("%s Stacktrace", worker.getThread().getName())); -+ StackTraceElement[] stackTrace = worker.getThread().getStackTrace(); -+ for (StackTraceElement element : stackTrace) { -+ getLogger().log(Level.SEVERE, " " + element.toString()); -+ } - } - } - // Paper end diff --git a/patches/server/0016-Improve-fluid-direction-caching.patch b/patches/server/0016-Improve-fluid-direction-caching.patch deleted file mode 100644 index 3e523c8..0000000 --- a/patches/server/0016-Improve-fluid-direction-caching.patch +++ /dev/null @@ -1,240 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Wed, 14 Apr 2021 22:58:15 -0500 -Subject: [PATCH] Improve fluid direction caching - -Implements a custom cache that better fits the needs of fluids -calculating whether a direction can be moved in or something. There's a -big javadoc on the FluidDirectionCache with some more information. - -diff --git a/src/main/java/gg/airplane/structs/FluidDirectionCache.java b/src/main/java/gg/airplane/structs/FluidDirectionCache.java -new file mode 100644 -index 0000000000000000000000000000000000000000..aa8467b9dda1f7707e41f50ac7b3e9d7343723ec ---- /dev/null -+++ b/src/main/java/gg/airplane/structs/FluidDirectionCache.java -@@ -0,0 +1,136 @@ -+package gg.airplane.structs; -+ -+import it.unimi.dsi.fastutil.HashCommon; -+ -+/** -+ * This is a replacement for the cache used in FluidTypeFlowing. -+ * The requirements for the previous cache were: -+ * - Store 200 entries -+ * - Look for the flag in the cache -+ * - If it exists, move to front of cache -+ * - If it doesn't exist, remove last entry in cache and insert in front -+ * -+ * This class accomplishes something similar, however has a few different -+ * requirements put into place to make this more optimize: -+ * -+ * - maxDistance is the most amount of entries to be checked, instead -+ * of having to check the entire list. -+ * - In combination with that, entries are all tracked by age and how -+ * frequently they're used. This enables us to remove old entries, -+ * without constantly shifting any around. -+ * -+ * Usage of the previous map would have to reset the head every single usage, -+ * shifting the entire map. Here, nothing happens except an increment when -+ * the cache is hit, and when it needs to replace an old element only a single -+ * element is modified. -+ */ -+public class FluidDirectionCache { -+ -+ private static class FluidDirectionEntry { -+ private final T data; -+ private final boolean flag; -+ private int uses = 0; -+ private int age = 0; -+ -+ private FluidDirectionEntry(T data, boolean flag) { -+ this.data = data; -+ this.flag = flag; -+ } -+ -+ public int getValue() { -+ return this.uses - (this.age >> 1); // age isn't as important as uses -+ } -+ -+ public void incrementUses() { -+ this.uses = this.uses + 1 & Integer.MAX_VALUE; -+ } -+ -+ public void incrementAge() { -+ this.age = this.age + 1 & Integer.MAX_VALUE; -+ } -+ } -+ -+ private final FluidDirectionEntry[] entries; -+ private final int mask; -+ private final int maxDistance; // the most amount of entries to check for a value -+ -+ public FluidDirectionCache(int size) { -+ int arraySize = HashCommon.nextPowerOfTwo(size); -+ this.entries = new FluidDirectionEntry[arraySize]; -+ this.mask = arraySize - 1; -+ this.maxDistance = Math.min(arraySize, 4); -+ } -+ -+ public Boolean getValue(T data) { -+ FluidDirectionEntry curr; -+ int pos; -+ -+ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) { -+ return null; -+ } else if (data.equals(curr.data)) { -+ curr.incrementUses(); -+ return curr.flag; -+ } -+ -+ int checked = 1; // start at 1 because we already checked the first spot above -+ -+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { -+ if (data.equals(curr.data)) { -+ curr.incrementUses(); -+ return curr.flag; -+ } else if (++checked >= this.maxDistance) { -+ break; -+ } -+ } -+ -+ return null; -+ } -+ -+ public void putValue(T data, boolean flag) { -+ FluidDirectionEntry curr; -+ int pos; -+ -+ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) { -+ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add -+ return; -+ } else if (data.equals(curr.data)) { -+ curr.incrementUses(); -+ return; -+ } -+ -+ int checked = 1; // start at 1 because we already checked the first spot above -+ -+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { -+ if (data.equals(curr.data)) { -+ curr.incrementUses(); -+ return; -+ } else if (++checked >= this.maxDistance) { -+ this.forceAdd(data, flag); -+ return; -+ } -+ } -+ -+ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add -+ } -+ -+ private void forceAdd(T data, boolean flag) { -+ int expectedPos = HashCommon.mix(data.hashCode()) & this.mask; -+ -+ int toRemovePos = expectedPos; -+ FluidDirectionEntry entryToRemove = this.entries[toRemovePos]; -+ -+ for (int i = expectedPos + 1; i < expectedPos + this.maxDistance; i++) { -+ int pos = i & this.mask; -+ FluidDirectionEntry entry = this.entries[pos]; -+ if (entry.getValue() < entryToRemove.getValue()) { -+ toRemovePos = pos; -+ entryToRemove = entry; -+ } -+ -+ entry.incrementAge(); // use this as a mechanism to age the other entries -+ } -+ -+ // remove the least used/oldest entry -+ this.entries[toRemovePos] = new FluidDirectionEntry(data, flag); -+ } -+} -diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -index 6e3e873efa1f50f53cb6503bde8a981f9cefd006..32d15354ceb46fb06b1c36049d3a8bfba718acaf 100644 ---- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -45,6 +45,8 @@ public abstract class FlowingFluid extends Fluid { - public static final BooleanProperty FALLING = BlockStateProperties.FALLING; - public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_FLOWING; - private static final int CACHE_SIZE = 200; -+ // Airplane start - use our own cache -+ /* - private static final ThreadLocal> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> { - Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { - protected void rehash(int i) {} -@@ -53,6 +55,14 @@ public abstract class FlowingFluid extends Fluid { - object2bytelinkedopenhashmap.defaultReturnValue((byte) 127); - return object2bytelinkedopenhashmap; - }); -+ */ -+ -+ private static final ThreadLocal> localFluidDirectionCache = ThreadLocal.withInitial(() -> { -+ // Airplane todo - mess with this number for performance -+ // with 2048 it seems very infrequent on a small world that it has to remove old entries -+ return new gg.airplane.structs.FluidDirectionCache<>(2048); -+ }); -+ // Airplane end - private final Map shapes = Maps.newIdentityHashMap(); - - public FlowingFluid() {} -@@ -240,6 +250,8 @@ public abstract class FlowingFluid extends Fluid { - } - - private boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) { -+ // Airplane start - modify to use our cache -+ /* - Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; - - if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -@@ -247,9 +259,16 @@ public abstract class FlowingFluid extends Fluid { - } else { - object2bytelinkedopenhashmap = null; - } -+ */ -+ gg.airplane.structs.FluidDirectionCache cache = null; -+ -+ if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { -+ cache = localFluidDirectionCache.get(); -+ } - - Block.BlockStatePairKey block_a; - -+ /* - if (object2bytelinkedopenhashmap != null) { - block_a = new Block.BlockStatePairKey(state, fromState, face); - byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); -@@ -260,11 +279,22 @@ public abstract class FlowingFluid extends Fluid { - } else { - block_a = null; - } -+ */ -+ if (cache != null) { -+ block_a = new Block.BlockStatePairKey(state, fromState, face); -+ Boolean flag = cache.getValue(block_a); -+ if (flag != null) { -+ return flag; -+ } -+ } else { -+ block_a = null; -+ } - - VoxelShape voxelshape = state.getCollisionShape(world, pos); - VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos); - boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face); - -+ /* - if (object2bytelinkedopenhashmap != null) { - if (object2bytelinkedopenhashmap.size() == 200) { - object2bytelinkedopenhashmap.removeLastByte(); -@@ -272,6 +302,11 @@ public abstract class FlowingFluid extends Fluid { - - object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); - } -+ */ -+ if (cache != null) { -+ cache.putValue(block_a, flag); -+ } -+ // Airplane end - - return flag; - } diff --git a/patches/server/0017-Cache-climbing-check-for-activation.patch b/patches/server/0017-Cache-climbing-check-for-activation.patch deleted file mode 100644 index 9b7a04d..0000000 --- a/patches/server/0017-Cache-climbing-check-for-activation.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Mon, 26 Apr 2021 10:52:56 -0500 -Subject: [PATCH] Cache climbing check for activation - - -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 402b785b5fd0e1c3c5c02505dca332990ec64e37..c22bf8f7df311ae3f2973667764e9768bcc9065d 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -142,7 +142,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; - import org.bukkit.event.player.PlayerItemConsumeEvent; - // CraftBukkit end - --import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class LivingEntity extends Entity { - -@@ -1824,6 +1823,20 @@ public abstract class LivingEntity extends Entity { - return this.lastClimbablePos; - } - -+ -+ // Airplane start -+ private boolean cachedOnClimable = false; -+ private BlockPos lastClimbingPosition = null; -+ -+ public boolean onClimableCached() { -+ if (!this.blockPosition().equals(this.lastClimbingPosition)) { -+ this.cachedOnClimable = this.onClimbable(); -+ this.lastClimbingPosition = this.blockPosition(); -+ } -+ return this.cachedOnClimable; -+ } -+ // Airplane end -+ - public boolean onClimbable() { - if (this.isSpectator()) { - return false; -diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 966639cc6ba6684bfb52e91ac047808cf4d003e4..6d1ed4bf941610fb9210a32f944a4b916527138f 100644 ---- a/src/main/java/org/spigotmc/ActivationRange.java -+++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -276,7 +276,7 @@ public class ActivationRange - if ( entity instanceof LivingEntity ) - { - LivingEntity living = (LivingEntity) entity; -- if ( living.onClimbable() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper -+ if ( living.onClimableCached() || living.jumping || living.hurtTime > 0 || living.activeEffects.size() > 0 ) // Paper // Airplane - use cached - { - return 1; // Paper - } diff --git a/patches/server/0018-Use-array-for-gamerule-storage.patch b/patches/server/0018-Use-array-for-gamerule-storage.patch deleted file mode 100644 index 6beca03..0000000 --- a/patches/server/0018-Use-array-for-gamerule-storage.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sun, 9 May 2021 16:49:49 -0500 -Subject: [PATCH] Use array for gamerule storage - - -diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java -index e7ca5d6fb8922e7e8065864f736b06056be080a0..833ad6fbedfc275b3fde640b0e873f23e61acc3b 100644 ---- a/src/main/java/net/minecraft/world/level/GameRules.java -+++ b/src/main/java/net/minecraft/world/level/GameRules.java -@@ -90,6 +90,7 @@ public class GameRules { - public static final GameRules.Key RULE_UNIVERSAL_ANGER = GameRules.register("universalAnger", GameRules.Category.MOBS, GameRules.BooleanValue.create(false)); - public static final GameRules.Key RULE_PLAYERS_SLEEPING_PERCENTAGE = GameRules.register("playersSleepingPercentage", GameRules.Category.PLAYER, GameRules.IntegerValue.create(100)); - private final Map, GameRules.Value> rules; -+ private final GameRules.Value[] gameruleArray; - - private static > GameRules.Key register(String name, GameRules.Category category, GameRules.Type type) { - GameRules.Key gamerules_gamerulekey = new GameRules.Key<>(name, category); -@@ -108,17 +109,33 @@ public class GameRules { - } - - public GameRules() { -- this.rules = (Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { -+ // Airplane start - use this to ensure gameruleArray is initialized -+ this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { - return ((GameRules.Type) entry.getValue()).createRule(); -- })); -+ }))); -+ // Airplane end - } - - private GameRules(Map, GameRules.Value> rules) { - this.rules = rules; -+ -+ // Airplane start -+ int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1; -+ GameRules.Value[] values = new GameRules.Value[arraySize]; -+ -+ for (Entry, GameRules.Value> entry : rules.entrySet()) { -+ values[entry.getKey().gameRuleIndex] = entry.getValue(); -+ } -+ -+ this.gameruleArray = values; -+ // Airplane end - } - - public > T getRule(GameRules.Key key) { -- return (T) this.rules.get(key); // CraftBukkit - decompile error -+ // Airplane start -+ return key == null ? null : (T) this.gameruleArray[key.gameRuleIndex]; -+ //return (T) this.rules.get(key); // CraftBukkit - decompile error -+ // Airplane end - } - - public CompoundTag createTag() { -@@ -177,6 +194,10 @@ public class GameRules { - } - - public static final class Key> { -+ // Airplane start -+ private static int lastGameRuleIndex = 0; -+ public final int gameRuleIndex = lastGameRuleIndex++; -+ // Airplane end - - final String id; - private final GameRules.Category category; diff --git a/patches/server/0019-Make-EntityCollisionContext-a-live-representation.patch b/patches/server/0019-Make-EntityCollisionContext-a-live-representation.patch deleted file mode 100644 index 0017132..0000000 --- a/patches/server/0019-Make-EntityCollisionContext-a-live-representation.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sun, 9 May 2021 18:35:05 -0500 -Subject: [PATCH] Make EntityCollisionContext a live representation - -While Context is in the name, it is not used as a context. Instead it is -always created, use temporarily, then thrown away. This means having a -lot of fields to initialize and make space for is useless. I cannot find -anywhere in the codebase where this is used as a context which may be -saved for later, so this should be safe assuming plugins don't use it -for some strange reason. - -diff --git a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java b/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java -index fcb7bd9f3b6b6ada0f2e5692bce32ab76b8798a7..61c2096f2c034dbc3ad33b193b058c7d0d05e909 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/EntityCollisionContext.java -@@ -22,55 +22,82 @@ public class EntityCollisionContext implements CollisionContext { - return defaultValue; - } - }; -- private final boolean descending; -- private final double entityBottom; -- private final ItemStack heldItem; -- private final ItemStack footItem; -- private final Predicate canStandOnFluid; -- private final Optional entity; -+ // Airplane start - remove these and pray no plugin uses them -+ //private final boolean descending; -+ //private final double entityBottom; -+ //private final ItemStack heldItem; -+ //private final ItemStack footItem; -+ //private final Predicate canStandOnFluid; -+ // Airplane end -+ private final @org.jetbrains.annotations.Nullable Entity entity; // Airplane - - protected EntityCollisionContext(boolean descending, double minY, ItemStack boots, ItemStack heldItem, Predicate walkOnFluidPredicate, Optional entity) { -- this.descending = descending; -- this.entityBottom = minY; -- this.footItem = boots; -- this.heldItem = heldItem; -- this.canStandOnFluid = walkOnFluidPredicate; -- this.entity = entity; -+ // Airplane start -+ //this.descending = descending; -+ //this.entityBottom = minY; -+ //this.footItem = boots; -+ //this.heldItem = heldItem; -+ ///this.canStandOnFluid = walkOnFluidPredicate; -+ this.entity = entity.orElse(null); -+ // Airplane end - } - - @Deprecated - protected EntityCollisionContext(Entity entity) { -+ // Airplane start - remove unneeded things -+ /* - this(entity.isDescending(), entity.getY(), entity instanceof LivingEntity ? ((LivingEntity)entity).getItemBySlot(EquipmentSlot.FEET) : ItemStack.EMPTY, entity instanceof LivingEntity ? ((LivingEntity)entity).getMainHandItem() : ItemStack.EMPTY, entity instanceof LivingEntity ? ((LivingEntity)entity)::canStandOnFluid : (fluid) -> { - return false; - }, Optional.of(entity)); -+ */ -+ this.entity = entity; -+ // Airplane end - } - - @Override - public boolean hasItemOnFeet(Item item) { -- return this.footItem.is(item); -+ // Airplane start -+ Entity entity = this.entity; -+ if (entity instanceof LivingEntity livingEntity) { -+ return livingEntity.getItemBySlot(EquipmentSlot.FEET).is(item); -+ } -+ return ItemStack.EMPTY.is(item); -+ // Airplane end - } - - @Override - public boolean isHoldingItem(Item item) { -- return this.heldItem.is(item); -+ // Airplane start -+ Entity entity = this.entity; -+ if (entity instanceof LivingEntity livingEntity) { -+ return livingEntity.getMainHandItem().is(item); -+ } -+ return ItemStack.EMPTY.is(item); -+ // Airplane end - } - - @Override - public boolean canStandOnFluid(FluidState state, FlowingFluid fluid) { -- return this.canStandOnFluid.test(fluid) && !state.getType().isSame(fluid); -+ // Airplane start -+ Entity entity = this.entity; -+ if (entity instanceof LivingEntity livingEntity) { -+ return livingEntity.canStandOnFluid(fluid) && !state.getType().isSame(fluid); -+ } -+ return false; -+ // Airplane end - } - - @Override - public boolean isDescending() { -- return this.descending; -+ return this.entity != null && this.entity.isDescending(); // Airplane - } - - @Override - public boolean isAbove(VoxelShape shape, BlockPos pos, boolean defaultValue) { -- return this.entityBottom > (double)pos.getY() + shape.max(Direction.Axis.Y) - (double)1.0E-5F; -+ return (this.entity == null ? -Double.MAX_VALUE : entity.getY()) > (double)pos.getY() + shape.max(Direction.Axis.Y) - (double)1.0E-5F; // Airplane - } - - public Optional getEntity() { -- return this.entity; -+ return Optional.ofNullable(this.entity); // Airplane - } - } diff --git a/patches/server/0020-Improve-container-checking-with-a-bitset.patch b/patches/server/0020-Improve-container-checking-with-a-bitset.patch deleted file mode 100644 index ec600c1..0000000 --- a/patches/server/0020-Improve-container-checking-with-a-bitset.patch +++ /dev/null @@ -1,491 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Wed, 19 May 2021 13:08:26 -0500 -Subject: [PATCH] Improve container checking with a bitset - - -diff --git a/src/main/java/gg/airplane/structs/ItemListWithBitset.java b/src/main/java/gg/airplane/structs/ItemListWithBitset.java -new file mode 100644 -index 0000000000000000000000000000000000000000..04565b596f7579eb22263ef844513aeba3437eb3 ---- /dev/null -+++ b/src/main/java/gg/airplane/structs/ItemListWithBitset.java -@@ -0,0 +1,105 @@ -+package gg.airplane.structs; -+ -+import net.minecraft.core.NonNullList; -+import net.minecraft.world.item.ItemStack; -+import org.apache.commons.lang.Validate; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.Arrays; -+ -+public class ItemListWithBitset extends NonNullList { -+ public static ItemListWithBitset fromNonNullList(NonNullList list) { -+ if (list instanceof ItemListWithBitset) { -+ return (ItemListWithBitset) list; -+ } -+ return new ItemListWithBitset(list); -+ } -+ -+ private static ItemStack[] createArray(int size) { -+ ItemStack[] array = new ItemStack[size]; -+ Arrays.fill(array, ItemStack.EMPTY); -+ return array; -+ } -+ -+ private final ItemStack[] items; -+ -+ private long bitSet = 0; -+ private final long allBits; -+ -+ private ItemListWithBitset(NonNullList list) { -+ this(list.size()); -+ -+ for (int i = 0; i < list.size(); i++) { -+ this.set(i, list.get(i)); -+ } -+ } -+ -+ public ItemListWithBitset(int size) { -+ super(null, ItemStack.EMPTY); -+ -+ Validate.isTrue(size < Long.BYTES * 8, "size is too large"); -+ -+ this.items = createArray(size); -+ this.allBits = ((1L << size) - 1); -+ } -+ -+ public boolean isCompletelyEmpty() { -+ return this.bitSet == 0; -+ } -+ -+ public boolean hasFullStacks() { -+ return (this.bitSet & this.allBits) == allBits; -+ } -+ -+ @Override -+ public ItemStack set(int index, @NotNull ItemStack itemStack) { -+ ItemStack existing = this.items[index]; -+ -+ this.items[index] = itemStack; -+ -+ if (itemStack == ItemStack.EMPTY) { -+ this.bitSet &= ~(1L << index); -+ } else { -+ this.bitSet |= 1L << index; -+ } -+ -+ return existing; -+ } -+ -+ @NotNull -+ @Override -+ public ItemStack get(int var0) { -+ return this.items[var0]; -+ } -+ -+ @Override -+ public int size() { -+ return this.items.length; -+ } -+ -+ @Override -+ public void clear() { -+ Arrays.fill(this.items, ItemStack.EMPTY); -+ } -+ -+ // these are unsupported for block inventories which have a static size -+ @Override -+ public void add(int var0, ItemStack var1) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public ItemStack remove(int var0) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public String toString() { -+ return "ItemListWithBitset{" + -+ "items=" + Arrays.toString(items) + -+ ", bitSet=" + Long.toString(bitSet, 2) + -+ ", allBits=" + Long.toString(allBits, 2) + -+ ", size=" + this.items.length + -+ '}'; -+ } -+} -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 937888b9c36a5bfaf661bfd740b12a634558f527..2ddd63954c98948602949ff53a7f8905c729da71 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -579,6 +579,21 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - return result; - } - -+ // Airplane start - skip type lookup if already completed, but still run check -+ public BlockEntity getAndCheckTileEntity(BlockState data, BlockPos pos) { -+ BlockEntity result = super.getTileEntity(pos, false); -+ -+ // copied from above -+ if (result != null && !data.isAir()) { -+ if (!result.getType().isValid(data)) { -+ result = fixTileEntity(pos, data, result); -+ } -+ } -+ -+ return result; -+ } -+ // Airplane end -+ - private BlockEntity fixTileEntity(BlockPos pos, BlockState type, BlockEntity found) { - this.getCraftServer().getLogger().log(Level.SEVERE, "Block at {0}, {1}, {2} is {3} but has {4}" + ". " - + "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), type, found}); -diff --git a/src/main/java/net/minecraft/world/CompoundContainer.java b/src/main/java/net/minecraft/world/CompoundContainer.java -index 087ae3a6b49872a3580eb1a572bdbc493711a77a..5ef8657197beea06c1dcad6a32968c56a823b182 100644 ---- a/src/main/java/net/minecraft/world/CompoundContainer.java -+++ b/src/main/java/net/minecraft/world/CompoundContainer.java -@@ -1,5 +1,6 @@ - package net.minecraft.world; - -+import net.minecraft.core.Direction; // Airplane - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.ItemStack; - -@@ -72,6 +73,23 @@ public class CompoundContainer implements Container { - this.container2 = second; - } - -+ // Airplane start -+ @Override -+ public boolean hasEmptySlot(Direction enumdirection) { -+ return this.container1.hasEmptySlot(null) || this.container2.hasEmptySlot(null); -+ } -+ -+ @Override -+ public boolean isCompletelyFull(Direction enumdirection) { -+ return this.container1.isCompletelyFull(null) && this.container2.isCompletelyFull(null); -+ } -+ -+ @Override -+ public boolean isCompletelyEmpty(Direction enumdirection) { -+ return this.container1.isCompletelyEmpty(null) && this.container2.isCompletelyEmpty(null); -+ } -+ // Airplane end -+ - @Override - public int getContainerSize() { - return this.container1.getContainerSize() + this.container2.getContainerSize(); -diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java -index 7437f01ca8f416e2c9150250e324af4725a4efb6..bdcd0e38a3ba904811112f41d8bfbfc0902ef190 100644 ---- a/src/main/java/net/minecraft/world/Container.java -+++ b/src/main/java/net/minecraft/world/Container.java -@@ -1,6 +1,8 @@ - package net.minecraft.world; - - import java.util.Set; -+ -+import net.minecraft.core.Direction; // Airplane - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.Item; - import net.minecraft.world.item.ItemStack; -@@ -9,6 +11,63 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity; - // CraftBukkit end - - public interface Container extends Clearable { -+ // Airplane start - allow the inventory to override and optimize these frequent calls -+ default boolean hasEmptySlot(@org.jetbrains.annotations.Nullable Direction enumdirection) { // there is a slot with 0 items in it -+ if (this instanceof WorldlyContainer worldlyContainer) { -+ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { -+ if (this.getItem(i).isEmpty()) { -+ return true; -+ } -+ } -+ } else { -+ int size = this.getContainerSize(); -+ for (int i = 0; i < size; i++) { -+ if (this.getItem(i).isEmpty()) { -+ return true; -+ } -+ } -+ } -+ return false; -+ } -+ -+ default boolean isCompletelyFull(@org.jetbrains.annotations.Nullable Direction enumdirection) { // every stack is maxed -+ if (this instanceof WorldlyContainer worldlyContainer) { -+ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { -+ ItemStack itemStack = this.getItem(i); -+ if (itemStack.getCount() < itemStack.getMaxStackSize()) { -+ return false; -+ } -+ } -+ } else { -+ int size = this.getContainerSize(); -+ for (int i = 0; i < size; i++) { -+ ItemStack itemStack = this.getItem(i); -+ if (itemStack.getCount() < itemStack.getMaxStackSize()) { -+ return false; -+ } -+ } -+ } -+ return true; -+ } -+ -+ default boolean isCompletelyEmpty(@org.jetbrains.annotations.Nullable Direction enumdirection) { -+ if (this instanceof WorldlyContainer worldlyContainer) { -+ for (int i : worldlyContainer.getSlotsForFace(enumdirection)) { -+ if (!this.getItem(i).isEmpty()) { -+ return false; -+ } -+ } -+ } else { -+ int size = this.getContainerSize(); -+ for (int i = 0; i < size; i++) { -+ if (!this.getItem(i).isEmpty()) { -+ return false; -+ } -+ } -+ } -+ return true; -+ } -+ // Airplane end - - int LARGE_MAX_STACK_SIZE = 64; - -diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -index f57864ce919ef4721cfb5913c636fe8903ce4cc1..4792d3d60e60202face2eb851c9f5b122dcfc19d 100644 ---- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -40,7 +40,7 @@ import org.bukkit.inventory.InventoryHolder; - - public abstract class AbstractMinecartContainer extends AbstractMinecart implements Container, MenuProvider { - -- private NonNullList itemStacks; -+ private gg.airplane.structs.ItemListWithBitset itemStacks; // Airplane - @Nullable - public ResourceLocation lootTable; - public long lootTableSeed; -@@ -89,12 +89,12 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme - - protected AbstractMinecartContainer(EntityType type, Level world) { - super(type, world); -- this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 -+ this.itemStacks = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // CraftBukkit - SPIGOT-3513 // Airplane - } - - protected AbstractMinecartContainer(EntityType type, double x, double y, double z, Level world) { - super(type, world, x, y, z); -- this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 -+ this.itemStacks = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // CraftBukkit - SPIGOT-3513 // Airplane - } - - @Override -@@ -217,7 +217,7 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme - protected void readAdditionalSaveData(CompoundTag nbt) { - super.readAdditionalSaveData(nbt); - this.lootableData.loadNbt(nbt); // Paper -- this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); -+ this.itemStacks = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // Airplane - if (nbt.contains("LootTable", 8)) { - this.lootTable = new ResourceLocation(nbt.getString("LootTable")); - this.lootTableSeed = nbt.getLong("LootTableSeed"); -diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -index 52de9852f87d346714a950b60a0004d386ac10f0..305a8f5ea917c7e242011fa98a3e161517afe9be 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java -@@ -32,7 +32,7 @@ import org.bukkit.entity.HumanEntity; - public class ChestBlockEntity extends RandomizableContainerBlockEntity implements LidBlockEntity { - - private static final int EVENT_SET_OPEN_COUNT = 1; -- private NonNullList items; -+ private gg.airplane.structs.ItemListWithBitset items; // Airplane - public final ContainerOpenersCounter openersCounter; - private final ChestLidController chestLidController; - -@@ -66,9 +66,10 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement - } - // CraftBukkit end - -+ private final boolean isNative = getClass().equals(ChestBlockEntity.class); // Airplane - protected ChestBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { - super(type, pos, state); -- this.items = NonNullList.withSize(27, ItemStack.EMPTY); -+ this.items = new gg.airplane.structs.ItemListWithBitset(27); // Airplane - use with bitset - this.openersCounter = new ContainerOpenersCounter() { - @Override - protected void onOpen(Level world, BlockPos pos, BlockState state) { -@@ -99,6 +100,23 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement - this.chestLidController = new ChestLidController(); - } - -+ // Airplane start -+ @Override -+ public boolean hasEmptySlot(Direction enumdirection) { -+ return isNative ? !this.items.hasFullStacks() : super.hasEmptySlot(enumdirection); -+ } -+ -+ @Override -+ public boolean isCompletelyFull(Direction enumdirection) { -+ return isNative ? this.items.hasFullStacks() && super.isCompletelyFull(enumdirection) : super.isCompletelyFull(enumdirection); -+ } -+ -+ @Override -+ public boolean isCompletelyEmpty(Direction enumdirection) { -+ return isNative && this.items.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection); -+ } -+ // Airplane end -+ - public ChestBlockEntity(BlockPos pos, BlockState state) { - this(BlockEntityType.CHEST, pos, state); - } -@@ -116,7 +134,7 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement - @Override - public void load(CompoundTag nbt) { - super.load(nbt); -- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); -+ this.items = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // Airplane - if (!this.tryLoadLootTable(nbt)) { - ContainerHelper.loadAllItems(nbt, this.items); - } -@@ -189,7 +207,7 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement - - @Override - protected void setItems(NonNullList list) { -- this.items = list; -+ this.items = gg.airplane.structs.ItemListWithBitset.fromNonNullList(list); // Airplane - } - - @Override -diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 3b1442bf4c83650369e925d76f07dc67c6cbbc83..80ae677938ad0ed79bc63974a1fec62e49506713 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -44,7 +44,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - public static final int MOVE_ITEM_SPEED = 8; - public static final int HOPPER_CONTAINER_SIZE = 5; -- private NonNullList items; -+ private gg.airplane.structs.ItemListWithBitset items; // Airplane - private int cooldownTime; - private long tickedGameTime; - -@@ -80,14 +80,31 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - public HopperBlockEntity(BlockPos pos, BlockState state) { - super(BlockEntityType.HOPPER, pos, state); -- this.items = NonNullList.withSize(5, ItemStack.EMPTY); -+ this.items = new gg.airplane.structs.ItemListWithBitset(5); // Airplane - this.cooldownTime = -1; - } - -+ // Airplane start -+ @Override -+ public boolean hasEmptySlot(Direction enumdirection) { -+ return !this.items.hasFullStacks(); -+ } -+ -+ @Override -+ public boolean isCompletelyFull(Direction enumdirection) { -+ return this.items.hasFullStacks() && super.isCompletelyFull(enumdirection); -+ } -+ -+ @Override -+ public boolean isCompletelyEmpty(Direction enumdirection) { -+ return this.items.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection); -+ } -+ // Airplane end -+ - @Override - public void load(CompoundTag nbt) { - super.load(nbt); -- this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); -+ this.items = new gg.airplane.structs.ItemListWithBitset(this.getContainerSize()); // Airplane - if (!this.tryLoadLootTable(nbt)) { - ContainerHelper.loadAllItems(nbt, this.items); - } -@@ -160,7 +177,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - flag = HopperBlockEntity.a(world, pos, state, (Container) blockEntity, blockEntity); // CraftBukkit - } - -- if (!blockEntity.inventoryFull()) { -+ if (!blockEntity.items.hasFullStacks() || !blockEntity.inventoryFull()) { // Airplane - use bitset first - flag |= booleansupplier.getAsBoolean(); - } - -@@ -199,7 +216,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - skipPushModeEventFire = skipHopperEvents; - boolean foundItem = false; - for (int i = 0; i < hopper.getContainerSize(); ++i) { -- ItemStack item = hopper.getItem(i); -+ ItemStack item = hopper.getItem(i); // Airplane - if (!item.isEmpty()) { - foundItem = true; - ItemStack origItemStack = item; -@@ -403,12 +420,18 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - } - - private static boolean isFullContainer(Container inventory, Direction direction) { -- return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams -+ // Airplane start - use bitsets -+ //return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams -+ return inventory.isCompletelyFull(direction); -+ // Airplane end - } - - private static boolean isEmptyContainer(Container inv, Direction facing) { - // Paper start -- return allMatch(inv, facing, IS_EMPTY_TEST); -+ // Airplane start - use bitsets -+ //return allMatch(inv, facing, IS_EMPTY_TEST); -+ return inv.isCompletelyEmpty(facing); -+ // Airplane end - } - private static boolean allMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate test) { - if (iinventory instanceof WorldlyContainer) { -@@ -585,7 +608,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - if (HopperBlockEntity.canPlaceItemInContainer(to, stack, slot, enumdirection)) { - boolean flag = false; -- boolean flag1 = to.isEmpty(); -+ boolean flag1 = to.isCompletelyEmpty(enumdirection); // Airplane - - if (itemstack1.isEmpty()) { - IGNORE_TILE_UPDATES = true; // Paper -@@ -667,7 +690,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - if (block instanceof WorldlyContainerHolder) { - object = ((WorldlyContainerHolder) block).getContainer(iblockdata, world, blockposition); - } else if (iblockdata.hasBlockEntity()) { -- BlockEntity tileentity = world.getBlockEntity(blockposition); -+ BlockEntity tileentity = ((net.minecraft.server.level.ServerLevel) world).getAndCheckTileEntity(iblockdata, blockposition); // Airplane - skip validation step, which does 2nd type lookup - - if (tileentity instanceof Container) { - object = (Container) tileentity; -@@ -726,7 +749,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - @Override - protected void setItems(NonNullList list) { -- this.items = list; -+ this.items = gg.airplane.structs.ItemListWithBitset.fromNonNullList(list); // Airplane - } - - public static void entityInside(Level world, BlockPos pos, BlockState state, Entity entity, HopperBlockEntity blockEntity) { -diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index ed3518fe7c841d9e1a9c97626acaa3d765a6d76f..ac564148956beb984650341c5c0994573f4f7225 100644 ---- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -@@ -96,13 +96,8 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc - public boolean isEmpty() { - this.unpackLootTable((Player)null); - // Paper start -- for (ItemStack itemStack : this.getItems()) { -- if (!itemStack.isEmpty()) { -- return false; -- } -- } -+ return this.isCompletelyEmpty(null); // Airplane - use super - // Paper end -- return true; - } - - @Override diff --git a/patches/server/0021-Better-checking-for-useless-move-packets.patch b/patches/server/0021-Better-checking-for-useless-move-packets.patch deleted file mode 100644 index b25108c..0000000 --- a/patches/server/0021-Better-checking-for-useless-move-packets.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Thu, 20 May 2021 12:05:47 -0500 -Subject: [PATCH] Better checking for useless move packets - - -diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index a00627e0fa38632449042f59c053b4dac13e58bf..d77a10c6ae7e1515085ff7a18db9e3e14ebb8012 100644 ---- a/src/main/java/net/minecraft/server/level/ServerEntity.java -+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -174,6 +174,7 @@ public class ServerEntity { - boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - - if (!flag4 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.isOnGround() && !(com.tuinity.tuinity.config.TuinityConfig.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Tuinity - send full pos for hard colliding entities to prevent collision problems due to desync -+ if (flag2 || flag3 || this.entity instanceof AbstractArrow) { // Airplane - if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) { - if (flag2) { - packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.isOnGround()); -@@ -183,6 +184,7 @@ public class ServerEntity { - } else { - packet1 = new ClientboundMoveEntityPacket.PosRot(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), (byte) i, (byte) j, this.entity.isOnGround()); - } -+ } // Airplane - } else { - this.wasOnGround = this.entity.isOnGround(); - this.teleportDelay = 0; diff --git a/patches/server/0022-Patch-Paper-to-use-fast-item-merge-raytracing.patch b/patches/server/0022-Patch-Paper-to-use-fast-item-merge-raytracing.patch deleted file mode 100644 index 1ddaae3..0000000 --- a/patches/server/0022-Patch-Paper-to-use-fast-item-merge-raytracing.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Tue, 1 Jun 2021 18:06:29 -0500 -Subject: [PATCH] Patch Paper to use fast item merge raytracing - - -diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 158719d46c96bb733a00e08c8285f41a48406abf..2dac4bc346eb1dde1f8d92c3e5b9648b2c433617 100644 ---- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -243,10 +243,16 @@ public class ItemEntity extends Entity { - if (entityitem.isMergable()) { - // Paper Start - Fix items merging through walls - if (this.level.paperConfig.fixItemsMergingThroughWalls) { -+ // Airplane start - skip the allocations -+ /* - net.minecraft.world.level.ClipContext rayTrace = new net.minecraft.world.level.ClipContext(this.position(), entityitem.position(), - net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, this); - net.minecraft.world.phys.BlockHitResult rayTraceResult = level.clip(rayTrace); - if (rayTraceResult.getType() == net.minecraft.world.phys.HitResult.Type.BLOCK) continue; -+ */ -+ if (level.rayTraceDirect(this.position(), entityitem.position(), net.minecraft.world.phys.shapes.CollisionContext.of(this)) == -+ net.minecraft.world.phys.HitResult.Type.BLOCK) continue; -+ // Airplane end - } - // Paper End - this.tryToMerge(entityitem); diff --git a/patches/server/0023-Use-aging-cache-for-biome-temperatures.patch b/patches/server/0023-Use-aging-cache-for-biome-temperatures.patch deleted file mode 100644 index 8be001f..0000000 --- a/patches/server/0023-Use-aging-cache-for-biome-temperatures.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Tue, 22 Jun 2021 14:49:50 -0500 -Subject: [PATCH] Use aging cache for biome temperatures - - -diff --git a/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java b/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a7f297ebb569f7c1f205e967ca485be70013a714 ---- /dev/null -+++ b/src/main/java/gg/airplane/structs/Long2FloatAgingCache.java -@@ -0,0 +1,119 @@ -+package gg.airplane.structs; -+ -+import it.unimi.dsi.fastutil.HashCommon; -+ -+/** -+ * A replacement for the cache used in Biome. -+ */ -+public class Long2FloatAgingCache { -+ -+ private static class AgingEntry { -+ private long data; -+ private float value; -+ private int uses = 0; -+ private int age = 0; -+ -+ private AgingEntry(long data, float value) { -+ this.data = data; -+ this.value = value; -+ } -+ -+ public void replace(long data, float flag) { -+ this.data = data; -+ this.value = flag; -+ } -+ -+ public int getValue() { -+ return this.uses - (this.age >> 1); // age isn't as important as uses -+ } -+ -+ public void incrementUses() { -+ this.uses = this.uses + 1 & Integer.MAX_VALUE; -+ } -+ -+ public void incrementAge() { -+ this.age = this.age + 1 & Integer.MAX_VALUE; -+ } -+ } -+ -+ private final AgingEntry[] entries; -+ private final int mask; -+ private final int maxDistance; // the most amount of entries to check for a value -+ -+ public Long2FloatAgingCache(int size) { -+ int arraySize = HashCommon.nextPowerOfTwo(size); -+ this.entries = new AgingEntry[arraySize]; -+ this.mask = arraySize - 1; -+ this.maxDistance = Math.min(arraySize, 4); -+ } -+ -+ public float getValue(long data) { -+ AgingEntry curr; -+ int pos; -+ -+ if ((curr = this.entries[pos = HashCommon.mix(HashCommon.long2int(data)) & this.mask]) == null) { -+ return Float.NaN; -+ } else if (data == curr.data) { -+ curr.incrementUses(); -+ return curr.value; -+ } -+ -+ int checked = 1; // start at 1 because we already checked the first spot above -+ -+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { -+ if (data == curr.data) { -+ curr.incrementUses(); -+ return curr.value; -+ } else if (++checked >= this.maxDistance) { -+ break; -+ } -+ } -+ -+ return Float.NaN; -+ } -+ -+ public void putValue(long data, float value) { -+ AgingEntry curr; -+ int pos; -+ -+ if ((curr = this.entries[pos = HashCommon.mix(HashCommon.long2int(data)) & this.mask]) == null) { -+ this.entries[pos] = new AgingEntry(data, value); // add -+ return; -+ } else if (data == curr.data) { -+ curr.incrementUses(); -+ return; -+ } -+ -+ int checked = 1; // start at 1 because we already checked the first spot above -+ -+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { -+ if (data == curr.data) { -+ curr.incrementUses(); -+ return; -+ } else if (++checked >= this.maxDistance) { -+ this.forceAdd(data, value); -+ return; -+ } -+ } -+ -+ this.entries[pos] = new AgingEntry(data, value); // add -+ } -+ -+ private void forceAdd(long data, float value) { -+ int expectedPos = HashCommon.mix(HashCommon.long2int(data)) & this.mask; -+ AgingEntry entryToRemove = this.entries[expectedPos]; -+ -+ for (int i = expectedPos + 1; i < expectedPos + this.maxDistance; i++) { -+ int pos = i & this.mask; -+ AgingEntry entry = this.entries[pos]; -+ if (entry.getValue() < entryToRemove.getValue()) { -+ entryToRemove = entry; -+ } -+ -+ entry.incrementAge(); // use this as a mechanism to age the other entries -+ } -+ -+ // remove the least used/oldest entry -+ entryToRemove.replace(data, value); -+ } -+} -diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java -index a7a7e6cd87270e64a92448f03f8b0b0c7e375ec7..0ea6fedf6e660bc133fd5eb34d3d9bac3e581f32 100644 ---- a/src/main/java/net/minecraft/world/level/biome/Biome.java -+++ b/src/main/java/net/minecraft/world/level/biome/Biome.java -@@ -104,8 +104,10 @@ public final class Biome { - private final float scale; - private final Biome.BiomeCategory biomeCategory; - private final BiomeSpecialEffects specialEffects; -- private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { -+ // Airplane start - use our cache -+ private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { - return Util.make(() -> { -+ /* - Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { - @Override - protected void rehash(int i) { -@@ -113,6 +115,10 @@ public final class Biome { - }; - long2FloatLinkedOpenHashMap.defaultReturnValue(Float.NaN); - return long2FloatLinkedOpenHashMap; -+ -+ */ -+ return new gg.airplane.structs.Long2FloatAgingCache(TEMPERATURE_CACHE_SIZE); -+ // Airplane end - }); - }); - -@@ -154,17 +160,15 @@ public final class Biome { - - public final float getTemperature(BlockPos blockPos) { - long l = blockPos.asLong(); -- Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get(); -- float f = long2FloatLinkedOpenHashMap.get(l); -+ // Airplane start -+ gg.airplane.structs.Long2FloatAgingCache cache = this.temperatureCache.get(); -+ float f = cache.getValue(l); - if (!Float.isNaN(f)) { - return f; - } else { - float g = this.getHeightAdjustedTemperature(blockPos); -- if (long2FloatLinkedOpenHashMap.size() == 1024) { -- long2FloatLinkedOpenHashMap.removeFirstFloat(); -- } -- -- long2FloatLinkedOpenHashMap.put(l, g); -+ cache.putValue(l, g); -+ // Airplane end - return g; - } - } diff --git a/patches/server/0024-Cache-world-height-in-the-chunk-as-it-s-final.patch b/patches/server/0024-Cache-world-height-in-the-chunk-as-it-s-final.patch deleted file mode 100644 index f731ded..0000000 --- a/patches/server/0024-Cache-world-height-in-the-chunk-as-it-s-final.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Tue, 22 Jun 2021 15:01:21 -0500 -Subject: [PATCH] Cache world height in the chunk, as it's final - - -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 4785cbd47e15f78c0302f1dc9bd904a4839ef8e4..ee2d00ccbe2d11324bb97fc43a213ed7ba1f111a 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -184,11 +184,13 @@ public class LevelChunk implements ChunkAccess { - } - // Airplane end - -+ private final int levelHeight; private final int minBuildHeight; // Airplane - public LevelChunk(Level world, ChunkPos pos, ChunkBiomeContainer biomes) { - this(world, pos, biomes, UpgradeData.EMPTY, EmptyTickList.empty(), EmptyTickList.empty(), 0L, (LevelChunkSection[]) null, (Consumer) null); - } - - public LevelChunk(Level world, ChunkPos pos, ChunkBiomeContainer biomes, UpgradeData upgradeData, TickList blockTickScheduler, TickList fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sections, @Nullable Consumer loadToWorldConsumer) { -+ this.levelHeight = world.getHeight(); this.minBuildHeight = world.getMinBuildHeight(); // Airplane - // Tuinity start - this.blockNibbles = StarLightEngine.getFilledEmptyLight(world); - this.skyNibbles = StarLightEngine.getFilledEmptyLight(world); -@@ -1303,13 +1305,17 @@ public class LevelChunk implements ChunkAccess { - } - - @Override -- public int getMinBuildHeight() { -- return this.level.getMinBuildHeight(); -+ // Airplane start -+ public final int getMinBuildHeight() { -+ return this.minBuildHeight; -+ // Airplane end - } - - @Override -- public int getHeight() { -- return this.level.getHeight(); -+ // Airplane start -+ public final int getHeight() { -+ return this.levelHeight; -+ // Airplane end - } - - @Override diff --git a/patches/server/0025-Use-thread-unsafe-random-for-mob-spawning.patch b/patches/server/0025-Use-thread-unsafe-random-for-mob-spawning.patch deleted file mode 100644 index 4960674..0000000 --- a/patches/server/0025-Use-thread-unsafe-random-for-mob-spawning.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Tue, 22 Jun 2021 15:04:37 -0500 -Subject: [PATCH] Use thread unsafe random for mob spawning - - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2ddd63954c98948602949ff53a7f8905c729da71..da4f0dc296c674e3ec393a724f6e2e595da536a0 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -893,7 +893,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - } - // Paper start - optimise random block ticking - private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); -- private final com.tuinity.tuinity.util.math.ThreadUnsafeRandom randomTickRandom = new com.tuinity.tuinity.util.math.ThreadUnsafeRandom(); -+ private final com.tuinity.tuinity.util.math.ThreadUnsafeRandom randomTickRandom = new com.tuinity.tuinity.util.math.ThreadUnsafeRandom(); public java.util.Random getThreadUnsafeRandom() { return this.randomTickRandom; } // Airplane - getter - // Paper end - - private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Airplane -diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 0059f0488acc22ebddc2faf4c5879f9f0c24fd14..074e25789152b8194797d6a3bae242e08f6be577 100644 ---- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java -+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -407,12 +407,12 @@ public final class NaturalSpawner { - return spawnGroup == MobCategory.MONSTER && world.getBlockState(pos.below()).is(Blocks.NETHER_BRICKS) && structureAccessor.getStructureAt(pos, false, StructureFeature.NETHER_BRIDGE).isValid() ? StructureFeature.NETHER_BRIDGE.getSpecialEnemies() : chunkGenerator.getMobsAt(biome != null ? biome : world.getBiome(pos), structureAccessor, spawnGroup, pos); - } - -- private static BlockPos getRandomPosWithin(Level world, LevelChunk chunk) { -+ private static BlockPos getRandomPosWithin(ServerLevel world, LevelChunk chunk) { // Airplane - accept serverlevel - ChunkPos chunkcoordintpair = chunk.getPos(); -- int i = chunkcoordintpair.getMinBlockX() + world.random.nextInt(16); -- int j = chunkcoordintpair.getMinBlockZ() + world.random.nextInt(16); -+ int i = chunkcoordintpair.getMinBlockX() + world.getThreadUnsafeRandom().nextInt(16); // Airplane - use thread unsafe random -+ int j = chunkcoordintpair.getMinBlockZ() + world.getThreadUnsafeRandom().nextInt(16); // Airplane - int k = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i, j) + 1; -- int l = Mth.randomBetweenInclusive(world.random, world.getMinBuildHeight(), k); -+ int l = Mth.randomBetweenInclusive(world.getThreadUnsafeRandom(), world.getMinBuildHeight(), k); // Airplane - - return new BlockPos(i, l, j); - } diff --git a/patches/server/0026-Remove-streams-and-iterators-from-range-check.patch b/patches/server/0026-Remove-streams-and-iterators-from-range-check.patch deleted file mode 100644 index 0a76d88..0000000 --- a/patches/server/0026-Remove-streams-and-iterators-from-range-check.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Tue, 22 Jun 2021 15:08:21 -0500 -Subject: [PATCH] Remove streams and iterators from range check - - -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b9b985268f5627a238c302f81400a05bfd7c592d..c82ae84190273609b0f5f533eb41a0e5363c16bf 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -2453,8 +2453,28 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially - return ChunkMap.this.level.getServer().getScaledTrackingDistance(initialDistance); - } - -+ private static int getHighestRange(Entity parent, int highest) { -+ List passengers = parent.getPassengers(); -+ -+ for (int i = 0, size = passengers.size(); i < size; i++) { -+ Entity entity = passengers.get(i); -+ int range = entity.getType().clientTrackingRange() * 16; -+ range = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, range); // Paper -+ -+ if (range > highest) { // Paper - we need the lowest range thanks to the fact that our tracker doesn't account for passenger logic // Tuinity - not anymore! -+ highest = range; -+ } -+ -+ highest = getHighestRange(entity, highest); -+ } -+ -+ return highest; -+ } -+ - private int getEffectiveRange() { - int i = this.range; -+ // Airplane start - remove iterators and streams -+ /* - Iterator iterator = this.entity.getIndirectPassengers().iterator(); - - while (iterator.hasNext()) { -@@ -2466,6 +2486,9 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially - i = j; - } - } -+ */ -+ i = getHighestRange(this.entity, i); -+ // Airplane end - - return this.scaledRange(i); - } diff --git a/patches/server/0027-Remove-streams-from-getting-nearby-players.patch b/patches/server/0027-Remove-streams-from-getting-nearby-players.patch deleted file mode 100644 index 26508c3..0000000 --- a/patches/server/0027-Remove-streams-from-getting-nearby-players.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul -Date: Tue, 29 Jun 2021 02:19:34 -0500 -Subject: [PATCH] Remove streams from getting nearby players - -This results in a 3% improvement at 20,000 entities, but more -importantly is the heaviest part of the entity tracker currently. - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ca7718053a6a2eb715ea3671bd4bc15304ede420..da267ed0ff0a4c4f18272e65ac055e48f7a17915 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -355,17 +355,36 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n - this.isLegacyTrackingEntity = isLegacyTrackingEntity; - } - -+ private org.spigotmc.TrackingRange.TrackingRangeType getFurthestEntity(Entity entity, net.minecraft.server.level.ChunkMap chunkMap, org.spigotmc.TrackingRange.TrackingRangeType type, int range) { -+ List passengers = entity.getPassengers(); -+ for (int i = 0, size = passengers.size(); i < size; i++) { -+ Entity passenger = passengers.get(i); -+ org.spigotmc.TrackingRange.TrackingRangeType passengerType = passenger.trackingRangeType; -+ int passengerRange = chunkMap.getEntityTrackerRange(passengerType.ordinal()); -+ if (passengerRange > range) { -+ type = passengerType; -+ range = passengerRange; -+ } -+ -+ type = this.getFurthestEntity(passenger, chunkMap, type, range); -+ } -+ -+ return type; -+ } -+ - public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getPlayersInTrackRange() { - // Tuinity start - determine highest range of passengers - if (this.passengers.isEmpty()) { - return ((ServerLevel)this.level).getChunkSource().chunkMap.playerEntityTrackerTrackMaps[this.trackingRangeType.ordinal()] - .getObjectsInRange(MCUtil.getCoordinateKey(this)); - } -- Iterable passengers = this.getIndirectPassengers(); -+ //Iterable passengers = this.getIndirectPassengers(); // Airplane - net.minecraft.server.level.ChunkMap chunkMap = ((ServerLevel)this.level).getChunkSource().chunkMap; - org.spigotmc.TrackingRange.TrackingRangeType type = this.trackingRangeType; - int range = chunkMap.getEntityTrackerRange(type.ordinal()); - -+ // Airplane start - use getFurthestEntity to skip getIndirectPassengers -+ /* - for (Entity passenger : passengers) { - org.spigotmc.TrackingRange.TrackingRangeType passengerType = passenger.trackingRangeType; - int passengerRange = chunkMap.getEntityTrackerRange(passengerType.ordinal()); -@@ -374,6 +393,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n - range = passengerRange; - } - } -+ */ -+ type = this.getFurthestEntity(this, chunkMap, type, range); -+ // Airplane end - - return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this)); - // Tuinity end - determine highest range of passengers diff --git a/patches/server/0028-Skip-cloning-loot-parameters.patch b/patches/server/0028-Skip-cloning-loot-parameters.patch deleted file mode 100644 index 9725f80..0000000 --- a/patches/server/0028-Skip-cloning-loot-parameters.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul -Date: Tue, 29 Jun 2021 02:24:23 -0500 -Subject: [PATCH] Skip cloning loot parameters - -Small improvement in CPU, much larger improvement in allocations. As a -new loot context is created every time a player moves (along with a lot -of other times) the constant cloning churns out a lot of useless -objects. - -diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -index 05b64f2730bfe836bd1d72dcfccd9f536908a099..39e941a6a315e2a9fc0f47eb39ef9d2b58069f90 100644 ---- a/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootContext.java -@@ -41,8 +41,10 @@ public class LootContext { - this.level = world; - this.lootTables = tableGetter; - this.conditions = conditionGetter; -- this.params = ImmutableMap.copyOf(parameters); -- this.dynamicDrops = ImmutableMap.copyOf(drops); -+ // Airplane start - use unmodifiable maps instead of immutable ones to skip the copy -+ this.params = java.util.Collections.unmodifiableMap(parameters); -+ this.dynamicDrops = java.util.Collections.unmodifiableMap(drops); -+ // Airplane end - } - - public boolean hasParam(LootContextParam parameter) { diff --git a/patches/server/0029-Fix-Paper-6045-block-goal-shouldn-t-load-chunks.patch b/patches/server/0029-Fix-Paper-6045-block-goal-shouldn-t-load-chunks.patch deleted file mode 100644 index e74d0d5..0000000 --- a/patches/server/0029-Fix-Paper-6045-block-goal-shouldn-t-load-chunks.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul -Date: Fri, 2 Jul 2021 14:18:27 -0500 -Subject: [PATCH] Fix Paper#6045, block goal shouldn't load chunks - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -index c28ade67f6a59146064a57bf016a646197f47ac4..419e6275a400f587f57e81684520072a93654aae 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -+++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -@@ -114,6 +114,7 @@ public abstract class MoveToBlockGoal extends Goal { - for(int m = 0; m <= l; m = m > 0 ? -m : 1 - m) { - for(int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) { - mutableBlockPos.setWithOffset(blockPos, m, k - 1, n); -+ if (!this.mob.level.hasChunkAt(mutableBlockPos)) continue; // Airplane - if this block isn't loaded, continue - if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level, mutableBlockPos)) { - this.blockPos = mutableBlockPos; - setTargetPosition(mutableBlockPos.immutable()); // Paper diff --git a/patches/server/0030-Quicker-sequencing-of-futures-for-chunk-gen.patch b/patches/server/0030-Quicker-sequencing-of-futures-for-chunk-gen.patch deleted file mode 100644 index fefa036..0000000 --- a/patches/server/0030-Quicker-sequencing-of-futures-for-chunk-gen.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul -Date: Fri, 2 Jul 2021 17:02:32 -0500 -Subject: [PATCH] Quicker sequencing of futures for chunk gen - - -diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 81f4f26a6b83079d36acd1fd86dede0eb1116c01..621c4b42185b3c65903408b6285ba56fa42e626a 100644 ---- a/src/main/java/net/minecraft/Util.java -+++ b/src/main/java/net/minecraft/Util.java -@@ -315,6 +315,10 @@ public class Util { - } - - public static CompletableFuture> sequence(List> futures) { -+ // Airplane start - faster sequencing without all of.. _that_ -+ return CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])) -+ .thenApply(unused -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList())); -+ /* - return futures.stream().reduce(CompletableFuture.completedFuture(Lists.newArrayList()), (completableFuture, completableFuture2) -> { - return completableFuture2.thenCombine(completableFuture, (object, list) -> { - List list2 = Lists.newArrayListWithCapacity(list.size() + 1); -@@ -330,6 +334,8 @@ public class Util { - return list3; - }); - }); -+ */ -+ // Airplane end - } - - public static CompletableFuture> sequenceFailFast(List> futures) { diff --git a/patches/server/0031-Remove-lambda-from-ticking-guard.patch b/patches/server/0031-Remove-lambda-from-ticking-guard.patch deleted file mode 100644 index 4d0dfab..0000000 --- a/patches/server/0031-Remove-lambda-from-ticking-guard.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul -Date: Fri, 2 Jul 2021 18:27:12 -0500 -Subject: [PATCH] Remove lambda from ticking guard - - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b714fd0ca551e6c98b351de6e9e6fc16b220be7c..6a1d9793d39eca96241bfd216745841a52b91e29 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -833,7 +833,20 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - } - - gameprofilerfiller.push("tick"); -- this.guardEntityTick(this::tickNonPassenger, entity); -+ // Airplane start - copied from this.guardEntityTick -+ try { -+ this.tickNonPassenger(entity); // Airplane - changed -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick -+ } catch (Throwable throwable) { -+ if (throwable instanceof ThreadDeath) throw throwable; // Paper -+ // Paper start - Prevent tile entity and entity crashes -+ final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); -+ MinecraftServer.LOGGER.error(msg, throwable); -+ getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); -+ entity.discard(); -+ // Paper end -+ } -+ // Airplane end - gameprofilerfiller.pop(); - } - } -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a2bb8eee5ef4a5043026af20f78bb43a5006e6b4..08973ad1d8699f4957957bbad4fdd4eb01ea3169 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1073,13 +1073,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - try { - tickConsumer.accept(entity); - MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick -- } catch (Throwable throwable) { -+ } catch (Throwable throwable) { // Airplane - diff on change ServerLevel.tick - if (throwable instanceof ThreadDeath) throw throwable; // Paper - // Paper start - Prevent tile entity and entity crashes - final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); - MinecraftServer.LOGGER.error(msg, throwable); - getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); -- entity.discard(); -+ entity.discard(); // Airplane - diff on change ServerLevel.tick - // Paper end - } - }