Do not let projectiles travel into chunks not owned by current region

Otherwise, the thread checks for moving the entity into the new
entity chunk section would throw and cause the projectile to
be deleted.
This commit is contained in:
Spottedleaf 2023-03-08 20:15:22 -08:00
parent ef515cc6f5
commit 950216171d

View File

@ -9713,7 +9713,7 @@ index 6898c704e60d89d53c8ed114e5e12f73ed63605a..594ada3cdec25784c7bd6abb9ad42d3f
* Converts an NMS entity's current location to a Bukkit Location * Converts an NMS entity's current location to a Bukkit Location
* @param entity * @param entity
diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java
index fc57850b80303fcade89ca95794f63910404a407..911a4590e8c45b917c9245d7e719d79bbd3e5f3d 100644 index fc57850b80303fcade89ca95794f63910404a407..2e3b030aced80803a544a9c836b00086b767da7a 100644
--- a/src/main/java/io/papermc/paper/util/TickThread.java --- a/src/main/java/io/papermc/paper/util/TickThread.java
+++ b/src/main/java/io/papermc/paper/util/TickThread.java +++ b/src/main/java/io/papermc/paper/util/TickThread.java
@@ -1,8 +1,19 @@ @@ -1,8 +1,19 @@
@ -9757,7 +9757,7 @@ index fc57850b80303fcade89ca95794f63910404a407..911a4590e8c45b917c9245d7e719d79b
public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) { public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) {
if (!isTickThreadFor(world, chunkX, chunkZ)) { if (!isTickThreadFor(world, chunkX, chunkZ)) {
MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
@@ -77,11 +102,75 @@ public class TickThread extends Thread { @@ -77,11 +102,96 @@ public class TickThread extends Thread {
return Thread.currentThread() instanceof TickThread; return Thread.currentThread() instanceof TickThread;
} }
@ -9787,17 +9787,34 @@ index fc57850b80303fcade89ca95794f63910404a407..911a4590e8c45b917c9245d7e719d79b
+ return world.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ) == region; + return world.regioniser.getRegionAtUnsynchronised(chunkX, chunkZ) == region;
+ } + }
+ +
+ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) { + public static boolean isTickThreadFor(final ServerLevel world, final Vec3 position, final Vec3 deltaMovement, final int buffer) {
+ final int fromChunkX = CoordinateUtils.getChunkX(position);
+ final int fromChunkZ = CoordinateUtils.getChunkZ(position);
+
+ final int toChunkX = CoordinateUtils.getChunkCoordinate(position.x + deltaMovement.x);
+ final int toChunkZ = CoordinateUtils.getChunkCoordinate(position.z + deltaMovement.z);
+
+ // expect from < to, but that may not be the case
+ return isTickThreadFor(
+ world,
+ Math.min(fromChunkX, toChunkX) - buffer,
+ Math.min(fromChunkZ, toChunkZ) - buffer,
+ Math.max(fromChunkX, toChunkX) + buffer,
+ Math.max(fromChunkZ, toChunkZ) + buffer
+ );
+ }
+
+ public static boolean isTickThreadFor(final ServerLevel world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) {
+ final ThreadedRegioniser.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region = + final ThreadedRegioniser.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> region =
+ TickRegionScheduler.getCurrentRegion(); + TickRegionScheduler.getCurrentRegion();
+ if (region == null) { + if (region == null) {
+ return isShutdownThread(); + return isShutdownThread();
+ } + }
+ +
+ final int minSectionX = (chunkX - radius) >> world.regioniser.sectionChunkShift; + final int minSectionX = fromChunkX >> world.regioniser.sectionChunkShift;
+ final int maxSectionX = (chunkX + radius) >> world.regioniser.sectionChunkShift; + final int maxSectionX = toChunkX >> world.regioniser.sectionChunkShift;
+ final int minSectionZ = (chunkZ - radius) >> world.regioniser.sectionChunkShift; + final int minSectionZ = fromChunkZ >> world.regioniser.sectionChunkShift;
+ final int maxSectionZ = (chunkZ + radius) >> world.regioniser.sectionChunkShift; + final int maxSectionZ = toChunkZ >> world.regioniser.sectionChunkShift;
+ +
+ for (int secZ = minSectionZ; secZ <= maxSectionZ; ++secZ) { + for (int secZ = minSectionZ; secZ <= maxSectionZ; ++secZ) {
+ for (int secX = minSectionX; secX <= maxSectionX; ++secX) { + for (int secX = minSectionX; secX <= maxSectionX; ++secX) {
@ -9810,6 +9827,10 @@ index fc57850b80303fcade89ca95794f63910404a407..911a4590e8c45b917c9245d7e719d79b
+ } + }
+ +
+ return true; + return true;
+ }
+
+ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) {
+ return isTickThreadFor(world, chunkX - radius, chunkZ - radius, chunkX + radius, chunkZ + radius);
} }
public static boolean isTickThreadFor(final Entity entity) { public static boolean isTickThreadFor(final Entity entity) {
@ -13760,7 +13781,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..09a6a74f9bbcbbfba8bfc0424cde6000
} }
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1dd0a0381 100644 index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..80ff2f28521f3d6d00ff21fbe76ab4e932673e48 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -192,35 +192,34 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -192,35 +192,34 @@ public class ServerLevel extends Level implements WorldGenLevel {
@ -13808,16 +13829,21 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
public static Throwable getAddToWorldStackTrace(Entity entity) { public static Throwable getAddToWorldStackTrace(Entity entity) {
final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date());
@@ -258,7 +257,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -256,6 +255,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
ServerChunkCache chunkProvider = this.getChunkSource();
+ // Folia start - region threading
+ // don't let players move into regions not owned
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this, minChunkX, minChunkZ, maxChunkX, maxChunkZ)) {
+ return false;
+ }
+ // Folia end - region threading
+
for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
- if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null) { if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null) {
+ if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null || !io.papermc.paper.util.TickThread.isTickThreadFor(this, cx, cz)) { @@ -267,50 +273,64 @@ public class ServerLevel extends Level implements WorldGenLevel {
return false;
}
}
@@ -267,50 +266,64 @@ public class ServerLevel extends Level implements WorldGenLevel {
return true; return true;
} }
@ -13909,7 +13935,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
chunkProvider.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); chunkProvider.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos);
chunkProvider.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, holderIdentifier); chunkProvider.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, holderIdentifier);
@@ -322,11 +335,31 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -322,11 +342,31 @@ public class ServerLevel extends Level implements WorldGenLevel {
for (int cx = minChunkX; cx <= maxChunkX; ++cx) { for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(
@ -13942,7 +13968,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Paper start - rewrite chunk system // Paper start - rewrite chunk system
public final io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler chunkTaskScheduler; public final io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler chunkTaskScheduler;
@@ -446,81 +479,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -446,81 +486,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end // Paper end
// Paper start - optimise checkDespawn // Paper start - optimise checkDespawn
@ -13978,8 +14004,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
- closestDistanceSquared = distanceSquared; - closestDistanceSquared = distanceSquared;
- } - }
- } - }
+ // Folia - region threading -
- return closest; - return closest;
- } - }
- -
@ -14000,17 +14025,17 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
- double centerX = (axisalignedbb.maxX + axisalignedbb.minX) * 0.5; - double centerX = (axisalignedbb.maxX + axisalignedbb.minX) * 0.5;
- double centerZ = (axisalignedbb.maxZ + axisalignedbb.minZ) * 0.5; - double centerZ = (axisalignedbb.maxZ + axisalignedbb.minZ) * 0.5;
- nearby = this.getChunkSource().chunkMap.playerGeneralAreaMap.getObjectsInRange(Mth.floor(centerX) >> 4, Mth.floor(centerZ) >> 4); - nearby = this.getChunkSource().chunkMap.playerGeneralAreaMap.getObjectsInRange(Mth.floor(centerX) >> 4, Mth.floor(centerZ) >> 4);
- + // Folia - region threading
- List<Player> ret = new java.util.ArrayList<>(); - List<Player> ret = new java.util.ArrayList<>();
- + // Folia - region threading
- if (nearby == null) { - if (nearby == null) {
- return ret; - return ret;
- } - }
+ // Folia - region threading -
- Object[] backingSet = nearby.getBackingSet(); - Object[] backingSet = nearby.getBackingSet();
+ // Folia - region threading -
- for (int i = 0, len = backingSet.length; i < len; ++i) { - for (int i = 0, len = backingSet.length; i < len; ++i) {
- Object _player = backingSet[i]; - Object _player = backingSet[i];
- if (!(_player instanceof ServerPlayer)) { - if (!(_player instanceof ServerPlayer)) {
@ -14022,14 +14047,15 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
- ret.add(player); - ret.add(player);
- } - }
- } - }
- + // Folia - region threading
- return ret; - return ret;
- } - }
+ // Folia - region threading + // Folia - region threading
// Paper end - optimise get nearest players for entity AI // Paper end - optimise get nearest players for entity AI
public final io.papermc.paper.chunk.system.RegionisedPlayerChunkLoader playerChunkLoader = new io.papermc.paper.chunk.system.RegionisedPlayerChunkLoader(this); public final io.papermc.paper.chunk.system.RegionisedPlayerChunkLoader playerChunkLoader = new io.papermc.paper.chunk.system.RegionisedPlayerChunkLoader(this);
@@ -565,6 +533,59 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -565,6 +540,59 @@ public class ServerLevel extends Level implements WorldGenLevel {
}); });
} }
@ -14089,7 +14115,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer // Add env and gen to constructor, IWorldDataServer -> WorldDataServer
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
// Holder holder = worlddimension.type(); // CraftBukkit - decompile error // Holder holder = worlddimension.type(); // CraftBukkit - decompile error
@@ -574,13 +595,13 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -574,13 +602,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.convertable = convertable_conversionsession; this.convertable = convertable_conversionsession;
this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile());
// CraftBukkit end // CraftBukkit end
@ -14109,7 +14135,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
this.dragonParts = new Int2ObjectOpenHashMap(); this.dragonParts = new Int2ObjectOpenHashMap();
this.tickTime = flag1; this.tickTime = flag1;
this.server = minecraftserver; this.server = minecraftserver;
@@ -619,7 +640,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -619,7 +647,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}); });
this.chunkSource.getGeneratorState().ensureStructuresGenerated(); this.chunkSource.getGeneratorState().ensureStructuresGenerated();
this.portalForcer = new PortalForcer(this); this.portalForcer = new PortalForcer(this);
@ -14118,7 +14144,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
this.prepareWeather(); this.prepareWeather();
this.getWorldBorder().setAbsoluteMaxSize(minecraftserver.getAbsoluteMaxWorldSize()); this.getWorldBorder().setAbsoluteMaxSize(minecraftserver.getAbsoluteMaxWorldSize());
this.raids = (Raids) this.getDataStorage().computeIfAbsent((nbttagcompound) -> { this.raids = (Raids) this.getDataStorage().computeIfAbsent((nbttagcompound) -> {
@@ -647,7 +668,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -647,7 +675,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system
this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system
@ -14133,7 +14159,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) { public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) {
this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setClearWeatherTime(clearDuration);
@@ -666,55 +694,31 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -666,55 +701,31 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.structureManager; return this.structureManager;
} }
@ -14201,7 +14227,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
gameprofilerfiller.pop(); gameprofilerfiller.pop();
} }
timings.scheduledBlocks.stopTiming(); // Paper timings.scheduledBlocks.stopTiming(); // Paper
@@ -731,7 +735,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -731,7 +742,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
timings.doSounds.startTiming(); // Spigot timings.doSounds.startTiming(); // Spigot
this.runBlockEvents(); this.runBlockEvents();
timings.doSounds.stopTiming(); // Spigot timings.doSounds.stopTiming(); // Spigot
@ -14210,7 +14236,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
gameprofilerfiller.pop(); gameprofilerfiller.pop();
boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
@@ -743,20 +747,30 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -743,20 +754,30 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.push("entities"); gameprofilerfiller.push("entities");
timings.tickEntities.startTiming(); // Spigot timings.tickEntities.startTiming(); // Spigot
if (this.dragonFight != null) { if (this.dragonFight != null) {
@ -14242,7 +14268,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
gameprofilerfiller.pop(); gameprofilerfiller.pop();
if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list
Entity entity1 = entity.getVehicle(); Entity entity1 = entity.getVehicle();
@@ -787,6 +801,31 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -787,6 +808,31 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.pop(); gameprofilerfiller.pop();
} }
@ -14274,7 +14300,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
@Override @Override
public boolean shouldTickBlocksAt(long chunkPos) { public boolean shouldTickBlocksAt(long chunkPos) {
// Paper start - replace player chunk loader system // Paper start - replace player chunk loader system
@@ -797,11 +836,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -797,11 +843,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
protected void tickTime() { protected void tickTime() {
if (this.tickTime) { if (this.tickTime) {
@ -14291,7 +14317,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
this.setDayTime(this.levelData.getDayTime() + 1L); this.setDayTime(this.levelData.getDayTime() + 1L);
} }
@@ -830,15 +870,23 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -830,15 +877,23 @@ public class ServerLevel extends Level implements WorldGenLevel {
private void wakeUpAllPlayers() { private void wakeUpAllPlayers() {
this.sleepStatus.removeAllSleepers(); this.sleepStatus.removeAllSleepers();
(this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList())).forEach((entityplayer) -> { // CraftBukkit - decompile error (this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList())).forEach((entityplayer) -> { // CraftBukkit - decompile error
@ -14318,7 +14344,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
ChunkPos chunkcoordintpair = chunk.getPos(); ChunkPos chunkcoordintpair = chunk.getPos();
boolean flag = this.isRaining(); boolean flag = this.isRaining();
int j = chunkcoordintpair.getMinBlockX(); int j = chunkcoordintpair.getMinBlockX();
@@ -846,7 +894,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -846,7 +901,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
ProfilerFiller gameprofilerfiller = this.getProfiler(); ProfilerFiller gameprofilerfiller = this.getProfiler();
gameprofilerfiller.push("thunder"); gameprofilerfiller.push("thunder");
@ -14327,7 +14353,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder
blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
@@ -941,7 +989,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -941,7 +996,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
int yPos = (sectionIndex + minSection) << 4; int yPos = (sectionIndex + minSection) << 4;
for (int a = 0; a < randomTickSpeed; ++a) { for (int a = 0; a < randomTickSpeed; ++a) {
int tickingBlocks = section.tickingList.size(); int tickingBlocks = section.tickingList.size();
@ -14336,7 +14362,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
if (index >= tickingBlocks) { if (index >= tickingBlocks) {
continue; continue;
} }
@@ -955,7 +1003,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -955,7 +1010,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ); BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ);
BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw); BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
@ -14345,7 +14371,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock). // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock).
// TODO CHECK ON UPDATE (ping the Canadian) // TODO CHECK ON UPDATE (ping the Canadian)
} }
@@ -1009,7 +1057,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1009,7 +1064,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public boolean isHandlingTick() { public boolean isHandlingTick() {
@ -14354,7 +14380,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
public boolean canSleepThroughNights() { public boolean canSleepThroughNights() {
@@ -1041,6 +1089,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1041,6 +1096,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public void updateSleepingPlayerList() { public void updateSleepingPlayerList() {
@ -14369,7 +14395,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) { if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) {
this.announceSleepStatus(); this.announceSleepStatus();
} }
@@ -1052,7 +1108,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1052,7 +1115,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.server.getScoreboard(); return this.server.getScoreboard();
} }
@ -14378,7 +14404,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
boolean flag = this.isRaining(); boolean flag = this.isRaining();
if (this.dimensionType().hasSkyLight()) { if (this.dimensionType().hasSkyLight()) {
@@ -1138,23 +1194,24 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1138,23 +1201,24 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.THUNDER_LEVEL_CHANGE, this.thunderLevel)); this.server.getPlayerList().broadcastAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.THUNDER_LEVEL_CHANGE, this.thunderLevel));
} }
// */ // */
@ -14412,7 +14438,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
} }
// CraftBukkit end // CraftBukkit end
@@ -1218,7 +1275,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1218,7 +1282,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void tickNonPassenger(Entity entity) { public void tickNonPassenger(Entity entity) {
// Paper start - log detailed entity tick information // Paper start - log detailed entity tick information
@ -14421,7 +14447,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
try { try {
if (currentlyTickingEntity.get() == null) { if (currentlyTickingEntity.get() == null) {
currentlyTickingEntity.lazySet(entity); currentlyTickingEntity.lazySet(entity);
@@ -1251,7 +1308,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1251,7 +1315,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (isActive) { // Paper - EAR 2 if (isActive) { // Paper - EAR 2
TimingHistory.activatedEntityTicks++; TimingHistory.activatedEntityTicks++;
entity.tick(); entity.tick();
@ -14439,7 +14465,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} else { entity.inactiveTick(); } // Paper - EAR 2 } else { entity.inactiveTick(); } // Paper - EAR 2
this.getProfiler().pop(); this.getProfiler().pop();
} finally { timer.stopTiming(); } // Paper - timings } finally { timer.stopTiming(); } // Paper - timings
@@ -1274,7 +1340,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1274,7 +1347,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
private void tickPassenger(Entity vehicle, Entity passenger) { private void tickPassenger(Entity vehicle, Entity passenger) {
if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) {
@ -14448,7 +14474,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Paper - EAR 2 // Paper - EAR 2
final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger);
co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper
@@ -1291,7 +1357,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1291,7 +1364,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper start - EAR 2 // Paper start - EAR 2
if (isActive) { if (isActive) {
passenger.rideTick(); passenger.rideTick();
@ -14466,7 +14492,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} else { } else {
passenger.setDeltaMovement(Vec3.ZERO); passenger.setDeltaMovement(Vec3.ZERO);
passenger.inactiveTick(); passenger.inactiveTick();
@@ -1379,7 +1454,15 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1379,7 +1461,15 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper - rewrite chunk system - entity saving moved into ChunkHolder // Paper - rewrite chunk system - entity saving moved into ChunkHolder
} else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system
@ -14482,7 +14508,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// CraftBukkit start - moved from MinecraftServer.saveChunks // CraftBukkit start - moved from MinecraftServer.saveChunks
ServerLevel worldserver1 = this; ServerLevel worldserver1 = this;
@@ -1387,12 +1470,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1387,12 +1477,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save()); this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save());
this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData());
// CraftBukkit end // CraftBukkit end
@ -14496,7 +14522,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
this.getChunkSource().getDataStorage().save(); this.getChunkSource().getDataStorage().save();
} }
@@ -1447,6 +1525,19 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1447,6 +1532,19 @@ public class ServerLevel extends Level implements WorldGenLevel {
return list; return list;
} }
@ -14516,7 +14542,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
@Nullable @Nullable
public ServerPlayer getRandomPlayer() { public ServerPlayer getRandomPlayer() {
List<ServerPlayer> list = this.getPlayers(LivingEntity::isAlive); List<ServerPlayer> list = this.getPlayers(LivingEntity::isAlive);
@@ -1548,8 +1639,8 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1548,8 +1646,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
} else { } else {
if (entity instanceof net.minecraft.world.entity.item.ItemEntity itemEntity && itemEntity.getItem().isEmpty()) return false; // Paper - Prevent empty items from being added if (entity instanceof net.minecraft.world.entity.item.ItemEntity itemEntity && itemEntity.getItem().isEmpty()) return false; // Paper - Prevent empty items from being added
// Paper start - capture all item additions to the world // Paper start - capture all item additions to the world
@ -14527,7 +14553,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
return true; return true;
} }
// Paper end // Paper end
@@ -1688,7 +1779,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1688,7 +1786,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {
@ -14536,7 +14562,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
String s = "recursive call to sendBlockUpdated"; String s = "recursive call to sendBlockUpdated";
Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated")); Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated"));
@@ -1701,7 +1792,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1701,7 +1799,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) { if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
List<PathNavigation> list = new ObjectArrayList(); List<PathNavigation> list = new ObjectArrayList();
@ -14545,7 +14571,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
while (iterator.hasNext()) { while (iterator.hasNext()) {
// CraftBukkit start - fix SPIGOT-6362 // CraftBukkit start - fix SPIGOT-6362
@@ -1724,7 +1815,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1724,7 +1822,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
try { try {
@ -14554,7 +14580,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
iterator = list.iterator(); iterator = list.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@@ -1733,7 +1824,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1733,7 +1831,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
navigationabstract1.recomputePath(); navigationabstract1.recomputePath();
} }
} finally { } finally {
@ -14563,7 +14589,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
} }
@@ -1742,23 +1833,23 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1742,23 +1840,23 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { public void updateNeighborsAt(BlockPos pos, Block sourceBlock) {
@ -14592,7 +14618,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
@Override @Override
@@ -1784,7 +1875,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1784,7 +1882,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
explosion.clearToBlow(); explosion.clearToBlow();
} }
@ -14601,7 +14627,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
while (iterator.hasNext()) { while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next(); ServerPlayer entityplayer = (ServerPlayer) iterator.next();
@@ -1799,25 +1890,28 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1799,25 +1897,28 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public void blockEvent(BlockPos pos, Block block, int type, int data) { public void blockEvent(BlockPos pos, Block block, int type, int data) {
@ -14636,7 +14662,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
private boolean doBlockEvent(BlockEventData event) { private boolean doBlockEvent(BlockEventData event) {
@@ -1828,12 +1922,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1828,12 +1929,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public LevelTicks<Block> getBlockTicks() { public LevelTicks<Block> getBlockTicks() {
@ -14651,7 +14677,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
@Nonnull @Nonnull
@@ -1857,7 +1951,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1857,7 +1958,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
// Paper start - Particle API Expansion // Paper start - Particle API Expansion
@ -14660,7 +14686,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
public <T extends ParticleOptions> int sendParticles(List<ServerPlayer> receivers, ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { public <T extends ParticleOptions> int sendParticles(List<ServerPlayer> receivers, ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
// Paper end // Paper end
@@ -1910,7 +2004,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1910,7 +2011,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
public Entity getEntityOrPart(int id) { public Entity getEntityOrPart(int id) {
Entity entity = (Entity) this.getEntities().get(id); Entity entity = (Entity) this.getEntities().get(id);
@ -14676,7 +14702,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
@Nullable @Nullable
@@ -1918,6 +2019,61 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1918,6 +2026,61 @@ public class ServerLevel extends Level implements WorldGenLevel {
return (Entity) this.getEntities().get(uuid); return (Entity) this.getEntities().get(uuid);
} }
@ -14738,7 +14764,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
@Nullable @Nullable
public BlockPos findNearestMapStructure(TagKey<Structure> structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) { public BlockPos findNearestMapStructure(TagKey<Structure> structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) {
if (!this.serverLevelData.worldGenOptions().generateStructures()) { // CraftBukkit if (!this.serverLevelData.worldGenOptions().generateStructures()) { // CraftBukkit
@@ -2082,7 +2238,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2082,7 +2245,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (forced) { if (forced) {
flag1 = forcedchunk.getChunks().add(k); flag1 = forcedchunk.getChunks().add(k);
if (flag1) { if (flag1) {
@ -14747,7 +14773,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
} else { } else {
flag1 = forcedchunk.getChunks().remove(k); flag1 = forcedchunk.getChunks().remove(k);
@@ -2110,13 +2266,18 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2110,13 +2273,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
BlockPos blockposition1 = pos.immutable(); BlockPos blockposition1 = pos.immutable();
optional.ifPresent((holder) -> { optional.ifPresent((holder) -> {
@ -14769,7 +14795,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Paper start // Paper start
if (optional.isEmpty() && this.getPoiManager().exists(blockposition1, poiType -> true)) { if (optional.isEmpty() && this.getPoiManager().exists(blockposition1, poiType -> true)) {
this.getPoiManager().remove(blockposition1); this.getPoiManager().remove(blockposition1);
@@ -2124,7 +2285,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2124,7 +2292,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end // Paper end
this.getPoiManager().add(blockposition1, holder); this.getPoiManager().add(blockposition1, holder);
DebugPackets.sendPoiAddedPacket(this, blockposition1); DebugPackets.sendPoiAddedPacket(this, blockposition1);
@ -14783,7 +14809,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
}); });
} }
} }
@@ -2171,7 +2337,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2171,7 +2344,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
BufferedWriter bufferedwriter = Files.newBufferedWriter(path.resolve("stats.txt")); BufferedWriter bufferedwriter = Files.newBufferedWriter(path.resolve("stats.txt"));
try { try {
@ -14792,7 +14818,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState(); NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState();
if (spawnercreature_d != null) { if (spawnercreature_d != null) {
@@ -2185,7 +2351,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2185,7 +2358,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityLookup.getDebugInfo())); // Paper - rewrite chunk system bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityLookup.getDebugInfo())); // Paper - rewrite chunk system
@ -14801,7 +14827,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count()));
bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count()));
bufferedwriter.write("distance_manager: " + playerchunkmap.getDistanceManager().getDebugStatus() + "\n"); bufferedwriter.write("distance_manager: " + playerchunkmap.getDistanceManager().getDebugStatus() + "\n");
@@ -2331,7 +2497,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2331,7 +2504,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
private void dumpBlockEntityTickers(Writer writer) throws IOException { private void dumpBlockEntityTickers(Writer writer) throws IOException {
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(writer); CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(writer);
@ -14810,7 +14836,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
while (iterator.hasNext()) { while (iterator.hasNext()) {
TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next(); TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next();
@@ -2344,7 +2510,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2344,7 +2517,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@VisibleForTesting @VisibleForTesting
public void clearBlockEvents(BoundingBox box) { public void clearBlockEvents(BoundingBox box) {
@ -14819,7 +14845,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
return box.isInside(blockactiondata.pos()); return box.isInside(blockactiondata.pos());
}); });
} }
@@ -2353,7 +2519,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2353,7 +2526,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void blockUpdated(BlockPos pos, Block block) { public void blockUpdated(BlockPos pos, Block block) {
if (!this.isDebug()) { if (!this.isDebug()) {
// CraftBukkit start // CraftBukkit start
@ -14828,7 +14854,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
return; return;
} }
// CraftBukkit end // CraftBukkit end
@@ -2396,9 +2562,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2396,9 +2569,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@VisibleForTesting @VisibleForTesting
public String getWatchdogStats() { public String getWatchdogStats() {
@ -14839,7 +14865,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
private static <T> String getTypeCount(Iterable<T> items, Function<T, String> classifier) { private static <T> String getTypeCount(Iterable<T> items, Function<T, String> classifier) {
@@ -2431,6 +2595,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2431,6 +2602,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
public static void makeObsidianPlatform(ServerLevel worldserver, Entity entity) { public static void makeObsidianPlatform(ServerLevel worldserver, Entity entity) {
// CraftBukkit end // CraftBukkit end
BlockPos blockposition = ServerLevel.END_SPAWN_POINT; BlockPos blockposition = ServerLevel.END_SPAWN_POINT;
@ -14852,7 +14878,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
int i = blockposition.getX(); int i = blockposition.getX();
int j = blockposition.getY() - 2; int j = blockposition.getY() - 2;
int k = blockposition.getZ(); int k = blockposition.getZ();
@@ -2443,11 +2613,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2443,11 +2620,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
BlockPos.betweenClosed(i - 2, j, k - 2, i + 2, j, k + 2).forEach((blockposition1) -> { BlockPos.betweenClosed(i - 2, j, k - 2, i + 2, j, k + 2).forEach((blockposition1) -> {
blockList.setBlock(blockposition1, Blocks.OBSIDIAN.defaultBlockState(), 3); blockList.setBlock(blockposition1, Blocks.OBSIDIAN.defaultBlockState(), 3);
}); });
@ -14865,7 +14891,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
blockList.updateList(); blockList.updateList();
} }
// CraftBukkit end // CraftBukkit end
@@ -2468,13 +2634,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2468,13 +2641,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public void startTickingChunk(LevelChunk chunk) { public void startTickingChunk(LevelChunk chunk) {
@ -14884,7 +14910,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
@Override @Override
@@ -2496,7 +2663,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2496,7 +2670,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end - rewrite chunk system // Paper end - rewrite chunk system
} }
@ -14893,7 +14919,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Paper start - optimize is ticking ready type functions // Paper start - optimize is ticking ready type functions
io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkPos); io.papermc.paper.chunk.system.scheduling.NewChunkHolder chunkHolder = this.chunkTaskScheduler.chunkHolderManager.getChunkHolder(chunkPos);
// isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded // isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded
@@ -2544,16 +2711,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2544,16 +2718,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void onCreated(Entity entity) {} public void onCreated(Entity entity) {}
public void onDestroyed(Entity entity) { public void onDestroyed(Entity entity) {
@ -14913,7 +14939,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
// Paper start - Reset pearls when they stop being ticked // Paper start - Reset pearls when they stop being ticked
if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) {
pearl.cachedOwner = null; pearl.cachedOwner = null;
@@ -2581,7 +2748,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2581,7 +2755,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration"));
} }
@ -14922,7 +14948,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
if (entity instanceof EnderDragon) { if (entity instanceof EnderDragon) {
@@ -2592,7 +2759,9 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2592,7 +2766,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
for (int j = 0; j < i; ++j) { for (int j = 0; j < i; ++j) {
EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; EnderDragonPart entitycomplexpart = aentitycomplexpart[j];
@ -14932,7 +14958,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
} }
@@ -2618,11 +2787,18 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2618,11 +2794,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
{ {
com.google.common.collect.Streams.stream( ServerLevel.this.getServer().getAllLevels() ).map( ServerLevel::getDataStorage ).forEach( (worldData) -> com.google.common.collect.Streams.stream( ServerLevel.this.getServer().getAllLevels() ).map( ServerLevel::getDataStorage ).forEach( (worldData) ->
{ {
@ -14952,7 +14978,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
map.carriedByPlayers.remove( (Player) entity ); map.carriedByPlayers.remove( (Player) entity );
for ( Iterator<MapItemSavedData.HoldingPlayer> iter = (Iterator<MapItemSavedData.HoldingPlayer>) map.carriedBy.iterator(); iter.hasNext(); ) for ( Iterator<MapItemSavedData.HoldingPlayer> iter = (Iterator<MapItemSavedData.HoldingPlayer>) map.carriedBy.iterator(); iter.hasNext(); )
{ {
@@ -2632,6 +2808,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2632,6 +2815,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
iter.remove(); iter.remove();
} }
} }
@ -14960,7 +14986,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
} }
} ); } );
@@ -2666,7 +2843,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2666,7 +2850,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration"));
} }
@ -14969,7 +14995,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..440e39238560059d3c13a98c66fd7dd1
} }
if (entity instanceof EnderDragon) { if (entity instanceof EnderDragon) {
@@ -2677,13 +2854,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2677,13 +2861,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
for (int j = 0; j < i; ++j) { for (int j = 0; j < i; ++j) {
EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; EnderDragonPart entitycomplexpart = aentitycomplexpart[j];
@ -18565,6 +18591,38 @@ index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..d9d832b7978d03417912408564f6e21b
// entityvillagertrader.setDespawnDelay(48000); // CraftBukkit - moved to EntityVillagerTrader constructor. This lets the value be modified by plugins on CreatureSpawnEvent // entityvillagertrader.setDespawnDelay(48000); // CraftBukkit - moved to EntityVillagerTrader constructor. This lets the value be modified by plugins on CreatureSpawnEvent
entityvillagertrader.setWanderTarget(blockposition1); entityvillagertrader.setWanderTarget(blockposition1);
entityvillagertrader.restrictTo(blockposition1, 16); entityvillagertrader.restrictTo(blockposition1, 16);
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 9788e477ff1446ad2ea3669922cc7dfc09900ce8..b3ff974a8e77810b79b179e5f46d5b8b14cf1ae0 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -149,6 +149,11 @@ public abstract class AbstractArrow extends Projectile {
@Override
public void tick() {
super.tick();
+ // Folia start - region threading - make sure entities do not move into regions they do not own
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)this.getLevel(), this.position(), this.getDeltaMovement(), 1)) {
+ return;
+ }
+ // Folia end - region threading - make sure entities do not move into regions they do not own
boolean flag = this.isNoPhysics();
Vec3 vec3d = this.getDeltaMovement();
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
index 97231f7328f0eebffcacdae5469027be8aeec3ae..6c3d7118b08445a430e200688234d5d4230a94fd 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
@@ -77,6 +77,11 @@ public abstract class AbstractHurtingProjectile extends Projectile {
this.discard();
} else {
super.tick();
+ // Folia start - region threading - make sure entities do not move into regions they do not own
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)this.getLevel(), this.position(), this.getDeltaMovement(), 1)) {
+ return;
+ }
+ // Folia end - region threading - make sure entities do not move into regions they do not own
if (this.shouldBurn()) {
this.setSecondsOnFire(1);
}
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java diff --git a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java
index c7265a650a5d6bdc42d41c5c90cad401d7f1c99d..c95d80ee142dc056874af6baf2d058cc932985e9 100644 index c7265a650a5d6bdc42d41c5c90cad401d7f1c99d..c95d80ee142dc056874af6baf2d058cc932985e9 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java --- a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java
@ -18620,6 +18678,22 @@ index 5406925cd66f46ab8744123c670d72cea7bfc3a1..d0fa197283a3bf14ead356e832500430
} }
} }
} }
diff --git a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
index 4132c1113f5437a776e5e3c1cb306904775aed88..a756a7373985152eceaa03255e3f0fb39c53d081 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/LlamaSpit.java
@@ -31,6 +31,11 @@ public class LlamaSpit extends Projectile {
public void tick() {
super.tick();
Vec3 vec3d = this.getDeltaMovement();
+ // Folia start - region threading - make sure entities do not move into regions they do not own
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)this.getLevel(), this.position(), this.getDeltaMovement(), 1)) {
+ return;
+ }
+ // Folia end - region threading - make sure entities do not move into regions they do not own
HitResult movingobjectposition = ProjectileUtil.getHitResult(this, this::canHitEntity);
this.preOnHit(movingobjectposition); // CraftBukkit - projectile hit event
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java 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 66476b33cede1e44db5ec166a0cea81f82ffe47a..26a17e3098317f6f623cdcab59dceb9d213c7f63 100644 index 66476b33cede1e44db5ec166a0cea81f82ffe47a..26a17e3098317f6f623cdcab59dceb9d213c7f63 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@ -18665,6 +18739,22 @@ index 00ac1cdc4734cc57f15433c5c6e7a3a545739d33..39b0034b7c612759fed87b6a5fff1819
isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
} }
// CraftBukkit end // CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
index 88181c59e604ba3b132b9e695cef5eaf5b836029..0146b150b6cb70a7272e8d9781e100a012f93d9b 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
@@ -44,6 +44,11 @@ public abstract class ThrowableProjectile extends Projectile {
@Override
public void tick() {
super.tick();
+ // Folia start - region threading - make sure entities do not move into regions they do not own
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)this.getLevel(), this.position(), this.getDeltaMovement(), 1)) {
+ return;
+ }
+ // Folia end - region threading - make sure entities do not move into regions they do not own
HitResult movingobjectposition = ProjectileUtil.getHitResult(this, this::canHitEntity);
boolean flag = false;
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
index f224ebbc0efefddede43d87f0300c014077b9931..2627610b77e779722bb33eeb1096d862aa9639d2 100644 index f224ebbc0efefddede43d87f0300c014077b9931..2627610b77e779722bb33eeb1096d862aa9639d2 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java