From 00e5a6a51616545fa98f1db1b2cd6d326423a3f2 Mon Sep 17 00:00:00 2001 From: MrPowerGamerBR Date: Mon, 15 Mar 2021 08:05:40 -0300 Subject: [PATCH] Add more patches from Airplane --- .../0016-Reduce-memory-allocations.patch | 224 ++++++++++++++++++ ...Skip-copying-unloading-tile-entities.patch | 37 +++ ...ity-chunk-ticking-checks-from-3-to-1.patch | 62 +++++ ...ve-iterators-from-inventory-contains.patch | 40 ++++ .../0020-Cache-entityhuman-display-name.patch | 34 +++ ...turn-optimization-for-target-finding.patch | 30 +++ 6 files changed, 427 insertions(+) create mode 100644 patches/server/0016-Reduce-memory-allocations.patch create mode 100644 patches/server/0017-Skip-copying-unloading-tile-entities.patch create mode 100644 patches/server/0018-Reduce-entity-chunk-ticking-checks-from-3-to-1.patch create mode 100644 patches/server/0019-Remove-iterators-from-inventory-contains.patch create mode 100644 patches/server/0020-Cache-entityhuman-display-name.patch create mode 100644 patches/server/0021-Early-return-optimization-for-target-finding.patch diff --git a/patches/server/0016-Reduce-memory-allocations.patch b/patches/server/0016-Reduce-memory-allocations.patch new file mode 100644 index 0000000..7037e2e --- /dev/null +++ b/patches/server/0016-Reduce-memory-allocations.patch @@ -0,0 +1,224 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Sauve +Date: Tue, 9 Feb 2021 19:05:58 -0600 +Subject: [PATCH] Reduce memory allocations + +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/BlockDirtSnowSpreadable.java b/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java +index 7b29d47dfdef7611db58068af285f76d92a9f12a..6c5d96853d47850b81ce85e56a516c554819ef25 100644 +--- a/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java ++++ b/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java +@@ -43,8 +43,14 @@ public abstract class BlockDirtSnowSpreadable extends BlockDirtSnow { + if (worldserver.getLightLevel(blockposition.up()) >= 9) { + IBlockData iblockdata1 = this.getBlockData(); + ++ // Airplane start - use mutable position ++ BlockPosition.MutableBlockPosition blockposition1 = new BlockPosition.MutableBlockPosition(); + for (int i = 0; i < 4; ++i) { ++ blockposition1.setValues(blockposition).addValues(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); ++ /* + BlockPosition blockposition1 = blockposition.b(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); ++ */ ++ // Airplane end + + if (worldserver.getType(blockposition1).a(Blocks.DIRT) && c(iblockdata1, (IWorldReader) worldserver, blockposition1)) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(worldserver, blockposition, blockposition1, (IBlockData) iblockdata1.set(BlockDirtSnowSpreadable.a, worldserver.getType(blockposition1.up()).a(Blocks.SNOW))); // CraftBukkit +diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java +index 2291135eaef64c403183724cb6e413cd7e472672..72ee5fe0ca25844cbcd8f1bbbbd6a7f8ced24bc4 100644 +--- a/src/main/java/net/minecraft/server/BlockPosition.java ++++ b/src/main/java/net/minecraft/server/BlockPosition.java +@@ -432,6 +432,14 @@ public class BlockPosition extends BaseBlockPosition { + public BlockPosition b(int i, int j, int k) { + return super.b(i, j, k).immutableCopy(); + } ++ // Airplane start - version of b that doesn't copy ++ public BlockPosition addValues(int x, int y, int z) { ++ ((BaseBlockPosition)this).a += x; ++ ((BaseBlockPosition)this).b += y; ++ ((BaseBlockPosition)this).e += z; ++ return this; ++ } ++ // Airplane end + + @Override + public BlockPosition shift(EnumDirection enumdirection, int i) { +diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java +index 93b5a6471cde31739d2bd5f2a9fc0e0d974d0eb0..4410939423a75357cc2d16bc4a3b96a504942320 100644 +--- a/src/main/java/net/minecraft/server/EntityTypes.java ++++ b/src/main/java/net/minecraft/server/EntityTypes.java +@@ -139,6 +139,8 @@ public class EntityTypes { + private MinecraftKey bq; + private final EntitySize br; + ++ public java.util.function.Supplier getEntityName = () -> IRegistry.ENTITY_TYPE.getKey(this).toString(); // Airplane - create lambda ones ++ + private static EntityTypes a(String s, EntityTypes.Builder entitytypes_builder) { // CraftBukkit - decompile error + return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_builder.a(s)); + } +diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java +index 3e0bf6df7c4608a5b19024612db52558fd722f4b..3811ed82ef08f54af2f822a8b86a3838931dfab4 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +@@ -651,7 +651,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + return d2 * d2 + d3 * d3; + } + +- private static int b(ChunkCoordIntPair chunkcoordintpair, EntityPlayer entityplayer, boolean flag) { ++ // Airplane start - create copy that accepts x/z instead of allocating pair ++ private static int b(ChunkCoordIntPair chunkcoordintpair, EntityPlayer entityplayer, boolean flag) { return someDistanceCalculation(chunkcoordintpair.x, chunkcoordintpair.z, entityplayer, flag); } ++ private static int someDistanceCalculation(int x, int z, EntityPlayer entityplayer, boolean flag) { + int i; + int j; + +@@ -665,12 +667,16 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + j = MathHelper.floor(entityplayer.locZ() / 16.0D); + } + +- return a(chunkcoordintpair, i, j); ++ return someOtherDistanceCalculation(x, z, i, j); ++ // Airplane end + } + +- private static int a(ChunkCoordIntPair chunkcoordintpair, int i, int j) { +- int k = chunkcoordintpair.x - i; +- int l = chunkcoordintpair.z - j; ++ // Airplane start - create copy that accepts x/z instead of allocating pair ++ private static int a(ChunkCoordIntPair chunkcoordintpair, int i, int j) { return someOtherDistanceCalculation(chunkcoordintpair.x, chunkcoordintpair.z, i, j); } ++ private static int someOtherDistanceCalculation(int x, int z, int i, int j) { ++ int k = x - i; ++ int l = z - j; ++ // Airplane end + + return Math.max(Math.abs(k), Math.abs(l)); + } +@@ -2517,11 +2523,17 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially + boolean flag1 = this.tracker.attachedToPlayer; + + if (!flag1) { ++ // Airplane start - use int/longs instead of ChunkCoordIntPair ++ /* + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ); +- PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair()); ++ */ ++ int x = this.tracker.chunkX, z = this.tracker.chunkZ; ++ long chunkcoordintpair = ChunkCoordIntPair.pair(x, z); ++ PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair); + + if (playerchunk != null && playerchunk.getSendingChunk() != null && PlayerChunkMap.this.playerChunkManager.isChunkSent(entityplayer, MathHelper.floor(this.tracker.locX()) >> 4, MathHelper.floor(this.tracker.locZ()) >> 4)) { // Paper - no-tick view distance // Tuinity - don't broadcast in chunks the player hasn't received +- flag1 = PlayerChunkMap.b(chunkcoordintpair, entityplayer, false) <= PlayerChunkMap.this.viewDistance; ++ flag1 = PlayerChunkMap.someDistanceCalculation(x, z, entityplayer, false) <= PlayerChunkMap.this.viewDistance; ++ // Airplane end + } + } + +@@ -2551,8 +2563,10 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially + } + + private int b() { ++ // Airplane start ++ int i = this.trackingDistance; // move out of if statement ++ if (!this.tracker.passengers.isEmpty()) { + Collection collection = this.tracker.getAllPassengers(); +- int i = this.trackingDistance; + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { +@@ -2564,6 +2578,8 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially + i = j; + } + } ++ } ++ // Airplane end + + return this.a(i); + } +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index fbe9a9d9721daf78e77736080f0c319c80bd950f..30ff822fb0d1a973feb8fa0a34d024608cbabbcf 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1041,19 +1041,19 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + + public void a(Consumer consumer, Entity entity) { + try { +- consumer.accept(entity); ++ consumer.accept(entity); // Airplane - error on change + } catch (Throwable throwable) { + if (throwable instanceof ThreadDeath) throw throwable; // Paper + // Paper start - Prevent tile entity and entity crashes + String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX() + "," + entity.locY() + "," + entity.locZ(); + System.err.println(msg); + throwable.printStackTrace(); +- getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); ++ getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); // Airplane - error on change + entity.dead = true; + return; + // Paper end + } +- MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick ++ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick // Airplane - error on change + } + // Paper start - Prevent armor stands from doing entity lookups + @Override +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index eca550800e9b0a09421ad29cb6a8b16f61806703..55c1aa26cbdee13ace1109215a1df087bf3503e9 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -992,7 +992,28 @@ public class WorldServer extends World implements GeneratorAccessSeed { + + gameprofilerfiller.enter("tick"); + if (!entity.dead && !(entity instanceof EntityComplexPart)) { ++ // Airplane start - inline this.a to prevent creation of lambda ++ /* + this.a(this::entityJoinedWorld, entity); ++ */ ++ boolean doMidTick = false; // usually there's a returns in the catch, so treat it like that ++ try { ++ this.entityJoinedWorld(entity); ++ doMidTick = true; ++ } catch (Throwable throwable) { ++ if (throwable instanceof ThreadDeath) throw throwable; // Paper ++ // Paper start - Prevent tile entity and entity crashes ++ String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX() + "," + entity.locY() + "," + entity.locZ(); ++ System.err.println(msg); ++ throwable.printStackTrace(); ++ getServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable))); ++ entity.dead = true; ++ // Paper end ++ } ++ if (doMidTick) { ++ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick ++ } ++ // Airplane end + } + + gameprofilerfiller.exit(); +@@ -1337,9 +1358,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { + ++entity.ticksLived; + GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); + ++ // Airplane start - create debug lambda once, todo do we even WANT the method profiler? ++ /* + gameprofilerfiller.a(() -> { + return IRegistry.ENTITY_TYPE.getKey(entity.getEntityType()).toString(); + }); ++ */ ++ gameprofilerfiller.a(entity.getEntityType().getEntityName); ++ // Airplane end + gameprofilerfiller.c("tickNonPassenger"); + if (isActive) { // Paper - EAR 2 + TimingHistory.activatedEntityTicks++; // Paper diff --git a/patches/server/0017-Skip-copying-unloading-tile-entities.patch b/patches/server/0017-Skip-copying-unloading-tile-entities.patch new file mode 100644 index 0000000..5553461 --- /dev/null +++ b/patches/server/0017-Skip-copying-unloading-tile-entities.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Sauve +Date: Sat, 13 Mar 2021 10:19:15 -0600 +Subject: [PATCH] Skip copying unloading tile entities + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 30ff822fb0d1a973feb8fa0a34d024608cbabbcf..996fa5b4652f847f4e64d4cd191fe5a597471afe 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -44,7 +44,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + //public final List tileEntityList = Lists.newArrayList(); // Paper - remove unused list + public final List tileEntityListTick = Lists.newArrayList(); + protected final List tileEntityListPending = Lists.newArrayList(); +- protected final java.util.Set tileEntityListUnload = com.google.common.collect.Sets.newHashSet(); ++ protected final java.util.Set tileEntityListUnload = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); // Airplane - use set with faster contains + public final Thread serverThread; + private final boolean debugWorld; + private int d; +@@ -924,12 +924,17 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + gameprofilerfiller.enter("blockEntities"); + timings.tileEntityTick.startTiming(); // Spigot + if (!this.tileEntityListUnload.isEmpty()) { ++ // Airplane start - we just use the identitymap as the basis for the unload set now instead of copying ++ /* + // Paper start - Use alternate implementation with faster contains + java.util.Set toRemove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); + toRemove.addAll(tileEntityListUnload); + this.tileEntityListTick.removeAll(toRemove); + // Paper end + //this.tileEntityList.removeAll(this.tileEntityListUnload); // Paper - remove unused list ++ */ ++ this.tileEntityListTick.removeAll(this.tileEntityListUnload); ++ // Airplane end + this.tileEntityListUnload.clear(); + } + diff --git a/patches/server/0018-Reduce-entity-chunk-ticking-checks-from-3-to-1.patch b/patches/server/0018-Reduce-entity-chunk-ticking-checks-from-3-to-1.patch new file mode 100644 index 0000000..0c18104 --- /dev/null +++ b/patches/server/0018-Reduce-entity-chunk-ticking-checks-from-3-to-1.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Sauve +Date: Sat, 13 Mar 2021 10:40:22 -0600 +Subject: [PATCH] Reduce entity chunk ticking checks from 3 to 1 + + +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 55c1aa26cbdee13ace1109215a1df087bf3503e9..f4eb878f9a66fd3404ddde5a14924bb419a351db 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -968,11 +968,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { + // CraftBukkit end */ + + gameprofilerfiller.enter("checkDespawn"); ++ boolean entityTickingChunk = false; if (!entity.dead) entityTickingChunk = this.getChunkProvider().isInEntityTickingChunk(entity); // Airplane - check once, chunks won't unload ticking entities + if (!entity.dead) { + entity.checkDespawn(); + // Tuinity start - optimise notify() + if (entity.inChunk && entity.valid) { +- if (this.getChunkProvider().isInEntityTickingChunk(entity)) { ++ if (entityTickingChunk) { // Airplane - reuse + this.updateNavigatorsInRegion(entity); + } + } else { +@@ -998,7 +999,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + */ + boolean doMidTick = false; // usually there's a returns in the catch, so treat it like that + try { +- this.entityJoinedWorld(entity); ++ this.entityJoinedWorld(entity, entityTickingChunk); // Airplane - reuse + doMidTick = true; + } catch (Throwable throwable) { + if (throwable instanceof ThreadDeath) throw throwable; // Paper +@@ -1023,7 +1024,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + this.entitiesById.remove(entity.getId()); // Tuinity + this.unregisterEntity(entity); + } else if (entity.inChunk && entity.valid) { // Tuinity start - optimise notify() +- if (this.getChunkProvider().isInEntityTickingChunk(entity)) { ++ if (entityTickingChunk) { // Airplane - reuse + this.updateNavigatorsInRegion(entity); + } + } else { +@@ -1324,7 +1325,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { + } + // Tuinity end - log detailed entity tick information + +- public void entityJoinedWorld(Entity entity) { ++ // Airplane start - reuse check for in entity ticking chunk ++ public void entityJoinedWorld(Entity entity) { entityJoinedWorld(entity, this.getChunkProvider().isInEntityTickingChunk(entity)); } ++ public void entityJoinedWorld(Entity entity, boolean entityTickingChunk) { // Airplane end + // Tuinity start - log detailed entity tick information + com.tuinity.tuinity.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); + try { +@@ -1332,7 +1335,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + currentlyTickingEntity.lazySet(entity); + } + // Tuinity end - log detailed entity tick information +- if (!(entity instanceof EntityHuman) && !this.getChunkProvider().a(entity)) { ++ if (!(entity instanceof EntityHuman) && !entityTickingChunk) { // Airplane - reuse + this.chunkCheck(entity); + } else { + ++TimingHistory.entityTicks; // Paper - timings diff --git a/patches/server/0019-Remove-iterators-from-inventory-contains.patch b/patches/server/0019-Remove-iterators-from-inventory-contains.patch new file mode 100644 index 0000000..a8bafde --- /dev/null +++ b/patches/server/0019-Remove-iterators-from-inventory-contains.patch @@ -0,0 +1,40 @@ +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/server/PlayerInventory.java b/src/main/java/net/minecraft/server/PlayerInventory.java +index 3b65711b91c51ac7b4b5b2b0144ffd279fe60eeb..478f33dbbd0b5a9b81ee420f77c97fa8c40e27d6 100644 +--- a/src/main/java/net/minecraft/server/PlayerInventory.java ++++ b/src/main/java/net/minecraft/server/PlayerInventory.java +@@ -609,6 +609,8 @@ public class PlayerInventory implements IInventory, INamableTileEntity { + } + + public boolean h(ItemStack itemstack) { ++ // Airplane start - skip using abstract iterators and stuff, they're generic and slow and allocating them sucks ++ /* + Iterator iterator = this.f.iterator(); + + while (iterator.hasNext()) { +@@ -623,6 +625,20 @@ public class PlayerInventory implements IInventory, INamableTileEntity { + } + } + } ++ */ ++ List> components = this.getComponents(); ++ for (int i = 0; i < components.size(); i++) { ++ List list = components.get(i); ++ ++ for (int j = 0; j < list.size(); j++) { ++ ItemStack itemstack1 = list.get(j); ++ ++ if (!itemstack1.isEmpty() && itemstack1.doMaterialsMatch(itemstack)) { ++ return true; ++ } ++ } ++ } ++ // Airplane end + + return false; + } diff --git a/patches/server/0020-Cache-entityhuman-display-name.patch b/patches/server/0020-Cache-entityhuman-display-name.patch new file mode 100644 index 0000000..6758f2b --- /dev/null +++ b/patches/server/0020-Cache-entityhuman-display-name.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Sauve +Date: Sat, 13 Mar 2021 14:02:04 -0600 +Subject: [PATCH] Cache entityhuman display name + + +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index f034977f4666385d6e7c7288e453d058c270be01..48a820e34d45623432a3dc3b01d0bba8824c6414 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -65,7 +65,8 @@ public abstract class EntityHuman extends EntityLiving { + protected int bG; + protected final float bH = 0.02F; + private int g; +- private GameProfile bJ; public final void setProfile(final GameProfile profile) { this.bJ = profile; } // Paper - OBFHELPER ++ private IChatBaseComponent displayName; // Airplane - cache displayName ++ private GameProfile bJ; public final void setProfile(final GameProfile profile) { this.bJ = profile; this.displayName = null; } // Paper - OBFHELPER // Airplane - use to reset displayName + private ItemStack bL; + private final ItemCooldown bM; + @Nullable +@@ -1731,7 +1732,12 @@ public abstract class EntityHuman extends EntityLiving { + + @Override + public IChatBaseComponent getDisplayName() { +- return new ChatComponentText(this.bJ.getName()); ++ // Airplane start - cache display name ++ if (this.displayName == null) { ++ this.displayName = new ChatComponentText(this.getProfile().getName()); ++ } ++ return this.displayName; ++ // Airplane end + } + + public InventoryEnderChest getEnderChest() { diff --git a/patches/server/0021-Early-return-optimization-for-target-finding.patch b/patches/server/0021-Early-return-optimization-for-target-finding.patch new file mode 100644 index 0000000..6270db1 --- /dev/null +++ b/patches/server/0021-Early-return-optimization-for-target-finding.patch @@ -0,0 +1,30 @@ +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/server/PathfinderTargetCondition.java b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java +index 3ebe3d0dc4c2c6aee6ea349006a74cbe5aa8e78f..7b80f6f08f274fd1adff114a81919bf41bf2cd53 100644 +--- a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java ++++ b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java +@@ -80,9 +80,17 @@ public class PathfinderTargetCondition { + } + + if (this.b > 0.0D) { ++ // Airplane start - try to return early ++ double range = (useFollowRange ? getFollowRange(entityliving) : this.b); ++ double d2 = entityliving.h(entityliving1.locX(), entityliving1.locY(), entityliving1.locZ()); // move up here to use early ++ ++ if (d2 > range * range) { // if they're further than the absolute furthest allowed, they don't match ++ return false; ++ } ++ + double d0 = this.g ? entityliving1.A(entityliving) : 1.0D; +- double d1 = Math.max((useFollowRange ? getFollowRange(entityliving) : this.b) * d0, 2.0D); // Paper +- double d2 = entityliving.h(entityliving1.locX(), entityliving1.locY(), entityliving1.locZ()); ++ double d1 = Math.max(range * d0, 2.0D); // Paper // Airplane - reuse range calculated above ++ // Airplane end + + if (d2 > d1 * d1) { + return false;