From cecb38e6ed4531d2ebfee1087a89c51f35e7539f Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 28 Jun 2021 05:53:28 -0700
Subject: [PATCH] Improve horrible CraftChunk#getEntities performance (#5999)

Thanks Spigot, very cool.
---
 build-data/paper.at                           |  3 ++
 .../Improve-CraftChunk-getEntities.patch      | 29 +++++++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 patches/server/Improve-CraftChunk-getEntities.patch

diff --git a/build-data/paper.at b/build-data/paper.at
index bc8ecf325f..e90ed085ab 100644
--- a/build-data/paper.at
+++ b/build-data/paper.at
@@ -225,3 +225,6 @@ public net.minecraft.world.entity.animal.Fox setFaceplanted(Z)V
 
 # Cook speed multipler API
 public net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity recipeType
+
+# Improve CraftChunk#getEntities
+public net.minecraft.world.level.entity.PersistentEntitySectionManager sectionStorage
diff --git a/patches/server/Improve-CraftChunk-getEntities.patch b/patches/server/Improve-CraftChunk-getEntities.patch
new file mode 100644
index 0000000000..b944ddd1bb
--- /dev/null
+++ b/patches/server/Improve-CraftChunk-getEntities.patch
@@ -0,0 +1,29 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <jake.m.potrebic@gmail.com>
+Date: Fri, 25 Jun 2021 12:06:35 -0700
+Subject: [PATCH] Improve CraftChunk#getEntities
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
+             this.getWorld().getChunkAt(x, z); // Transient load for this tick
+         }
+ 
+-        Location location = new Location(null, 0, 0, 0);
+-        return this.getWorld().getEntities().stream().filter((entity) -> {
+-            entity.getLocation(location);
+-            return location.getBlockX() >> 4 == this.x && location.getBlockZ() >> 4 == this.z;
+-        }).toArray(Entity[]::new);
++        // Paper start - improve CraftChunk#getEntities
++        return this.worldServer.entityManager.sectionStorage.getExistingSectionsInChunk(ChunkPos.asLong(this.x, this.z))
++            .flatMap(net.minecraft.world.level.entity.EntitySection::getEntities)
++            .map(net.minecraft.world.entity.Entity::getBukkitEntity)
++            .filter(entity -> entity != null && entity.isValid())
++            .toArray(Entity[]::new);
++        // Paper end
+     }
+ 
+     @Override