Rewrite spawn selection algorithm

The new spawn selection algorithm attempts to search the area
around a selected point, in an effort to reduce the total number
of chunk loads required to select a spawn point.

Additionally, the new spawn selection algorithm does not perform
recursion when the selected area is already loaded and owned by
the current region. This fixes https://github.com/PaperMC/Folia/issues/138
This commit is contained in:
Spottedleaf 2023-07-25 11:52:46 -07:00
parent daacd42550
commit 57983f77f7
3 changed files with 240 additions and 136 deletions

View File

@ -13611,7 +13611,7 @@ index 488a253e218409b5f0b4a872cee0928578fa7582..af35fd63b090aa3d89bc60cb9cb7694b
} }
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 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e3218238f74ff67 100644 index 18aac3da3c88f33b1a71a5920a8daa27e9723913..bb07ad1bb895297356b88dfc4cd17e5e93795c38 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,36 +192,35 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -192,36 +192,35 @@ public class ServerLevel extends Level implements WorldGenLevel {
@ -13660,7 +13660,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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());
@@ -257,6 +256,13 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -257,6 +256,37 @@ public class ServerLevel extends Level implements WorldGenLevel {
ServerChunkCache chunkProvider = this.getChunkSource(); ServerChunkCache chunkProvider = this.getChunkSource();
@ -13670,11 +13670,43 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
+ return false; + return false;
+ } + }
+ // Folia end - region threading + // Folia end - region threading
+
+ for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
+ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
+ if (chunkProvider.getChunkAtIfLoadedImmediately(cx, cz) == null) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // Folia start - region threading
+ public final boolean isAreaLoaded(final BlockPos center, final int radius) {
+ int minX = (center.getX() - radius) >> 4;
+ int minZ = (center.getZ() - radius) >> 4;
+ int maxX = (center.getX() + radius) >> 4;
+ int maxZ = (center.getZ() + radius) >> 4;
+
+ return this.isAreaLoaded(minX, minZ, maxX, maxZ);
+ }
+
+ public final boolean isAreaLoaded(final int minChunkX, final int minChunkZ, final int maxChunkX, final int maxChunkZ) {
+ ServerChunkCache chunkProvider = this.getChunkSource();
+ +
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) {
@@ -563,83 +569,60 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -267,6 +297,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return true;
}
+ // Folia end - region threading
public final void loadChunksAsync(BlockPos pos, int radiusBlocks,
ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority,
@@ -563,83 +594,60 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
// Paper end // Paper end
@ -13770,16 +13802,16 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
+ } + }
- Object[] backingSet = nearby.getBackingSet(); - Object[] backingSet = nearby.getBackingSet();
+ public List<PendingTeleport> removeAllRegionTeleports() { -
+ final List<PendingTeleport> ret = new ArrayList<>();
- 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)) {
- continue; - continue;
- } - }
- ServerPlayer player = (ServerPlayer)_player; - ServerPlayer player = (ServerPlayer)_player;
- + public List<PendingTeleport> removeAllRegionTeleports() {
+ final List<PendingTeleport> ret = new ArrayList<>();
- if (axisalignedbb.contains(player.getX(), player.getY(), player.getZ()) && condition.test(source, player)) { - if (axisalignedbb.contains(player.getX(), player.getY(), player.getZ()) && condition.test(source, player)) {
- ret.add(player); - ret.add(player);
+ synchronized (this.pendingTeleports) { + synchronized (this.pendingTeleports) {
@ -13799,7 +13831,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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, @Nullable RandomSequences randomsequences, 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, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
@@ -652,13 +635,13 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -652,13 +660,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
@ -13819,7 +13851,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
this.dragonParts = new Int2ObjectOpenHashMap(); this.dragonParts = new Int2ObjectOpenHashMap();
this.tickTime = flag1; this.tickTime = flag1;
this.server = minecraftserver; this.server = minecraftserver;
@@ -697,7 +680,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -697,7 +705,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);
@ -13828,7 +13860,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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) -> {
@@ -732,7 +715,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -732,7 +740,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
@ -13843,7 +13875,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// Paper start // Paper start
@Override @Override
@@ -765,55 +755,31 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -765,55 +780,31 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.structureManager; return this.structureManager;
} }
@ -13883,7 +13915,8 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
- this.setDayTime(this.getDayTime() + event.getSkipAmount()); - this.setDayTime(this.getDayTime() + event.getSkipAmount());
- } - }
- } - }
- + if (region == null) this.tickSleep(); // Folia - region threading
- if (!event.isCancelled()) { - if (!event.isCancelled()) {
- this.wakeUpAllPlayers(); - this.wakeUpAllPlayers();
- } - }
@ -13892,8 +13925,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
- this.resetWeatherCycle(); - this.resetWeatherCycle();
- } - }
- } - }
+ if (region == null) this.tickSleep(); // Folia - region threading -
- this.updateSkyBrightness(); - this.updateSkyBrightness();
+ if (region == null) this.updateSkyBrightness(); // Folia - region threading + if (region == null) this.updateSkyBrightness(); // Folia - region threading
this.tickTime(); this.tickTime();
@ -13911,7 +13943,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
gameprofilerfiller.pop(); gameprofilerfiller.pop();
} }
timings.scheduledBlocks.stopTiming(); // Paper timings.scheduledBlocks.stopTiming(); // Paper
@@ -830,7 +796,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -830,7 +821,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
@ -13920,7 +13952,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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
@@ -842,20 +808,30 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -842,20 +833,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) {
@ -13952,7 +13984,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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();
@@ -886,6 +862,31 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -886,6 +887,31 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.pop(); gameprofilerfiller.pop();
} }
@ -13984,7 +14016,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
@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
@@ -896,11 +897,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -896,11 +922,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
protected void tickTime() { protected void tickTime() {
if (this.tickTime) { if (this.tickTime) {
@ -14001,7 +14033,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
this.setDayTime(this.levelData.getDayTime() + 1L); this.setDayTime(this.levelData.getDayTime() + 1L);
} }
@@ -929,15 +931,23 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -929,15 +956,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
@ -14028,7 +14060,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
ChunkPos chunkcoordintpair = chunk.getPos(); ChunkPos chunkcoordintpair = chunk.getPos();
boolean flag = this.isRaining(); boolean flag = this.isRaining();
int j = chunkcoordintpair.getMinBlockX(); int j = chunkcoordintpair.getMinBlockX();
@@ -945,7 +955,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -945,7 +980,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
ProfilerFiller gameprofilerfiller = this.getProfiler(); ProfilerFiller gameprofilerfiller = this.getProfiler();
gameprofilerfiller.push("thunder"); gameprofilerfiller.push("thunder");
@ -14037,7 +14069,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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
@@ -1040,7 +1050,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1040,7 +1075,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();
@ -14046,7 +14078,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
if (index >= tickingBlocks) { if (index >= tickingBlocks) {
continue; continue;
} }
@@ -1054,7 +1064,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1054,7 +1089,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);
@ -14055,7 +14087,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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)
} }
@@ -1108,7 +1118,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1108,7 +1143,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public boolean isHandlingTick() { public boolean isHandlingTick() {
@ -14064,7 +14096,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
public boolean canSleepThroughNights() { public boolean canSleepThroughNights() {
@@ -1140,6 +1150,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1140,6 +1175,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public void updateSleepingPlayerList() { public void updateSleepingPlayerList() {
@ -14079,7 +14111,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) { if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) {
this.announceSleepStatus(); this.announceSleepStatus();
} }
@@ -1151,7 +1169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1151,7 +1194,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.server.getScoreboard(); return this.server.getScoreboard();
} }
@ -14088,7 +14120,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
boolean flag = this.isRaining(); boolean flag = this.isRaining();
if (this.dimensionType().hasSkyLight()) { if (this.dimensionType().hasSkyLight()) {
@@ -1237,23 +1255,24 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1237,23 +1280,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));
} }
// */ // */
@ -14122,7 +14154,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
} }
// CraftBukkit end // CraftBukkit end
@@ -1317,7 +1336,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1317,7 +1361,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
@ -14131,7 +14163,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
try { try {
if (currentlyTickingEntity.get() == null) { if (currentlyTickingEntity.get() == null) {
currentlyTickingEntity.lazySet(entity); currentlyTickingEntity.lazySet(entity);
@@ -1350,7 +1369,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1350,7 +1394,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();
@ -14149,7 +14181,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} 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
@@ -1373,7 +1401,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1373,7 +1426,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) {
@ -14158,7 +14190,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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
@@ -1390,7 +1418,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1390,7 +1443,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper start - EAR 2 // Paper start - EAR 2
if (isActive) { if (isActive) {
passenger.rideTick(); passenger.rideTick();
@ -14176,7 +14208,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} else { } else {
passenger.setDeltaMovement(Vec3.ZERO); passenger.setDeltaMovement(Vec3.ZERO);
passenger.inactiveTick(); passenger.inactiveTick();
@@ -1478,7 +1515,15 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1478,7 +1540,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
@ -14192,7 +14224,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// CraftBukkit start - moved from MinecraftServer.saveChunks // CraftBukkit start - moved from MinecraftServer.saveChunks
ServerLevel worldserver1 = this; ServerLevel worldserver1 = this;
@@ -1486,12 +1531,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1486,12 +1556,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
@ -14206,7 +14238,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
this.getChunkSource().getDataStorage().save(); this.getChunkSource().getDataStorage().save();
} }
@@ -1546,6 +1586,19 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1546,6 +1611,19 @@ public class ServerLevel extends Level implements WorldGenLevel {
return list; return list;
} }
@ -14226,7 +14258,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
@Nullable @Nullable
public ServerPlayer getRandomPlayer() { public ServerPlayer getRandomPlayer() {
List<ServerPlayer> list = this.getPlayers(LivingEntity::isAlive); List<ServerPlayer> list = this.getPlayers(LivingEntity::isAlive);
@@ -1647,8 +1700,8 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1647,8 +1725,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
@ -14237,7 +14269,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
return true; return true;
} }
// Paper end // Paper end
@@ -1792,7 +1845,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1792,7 +1870,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) {
@ -14246,7 +14278,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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"));
@@ -1805,7 +1858,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1805,7 +1883,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();
@ -14255,7 +14287,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
while (iterator.hasNext()) { while (iterator.hasNext()) {
// CraftBukkit start - fix SPIGOT-6362 // CraftBukkit start - fix SPIGOT-6362
@@ -1828,7 +1881,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1828,7 +1906,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
try { try {
@ -14264,7 +14296,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
iterator = list.iterator(); iterator = list.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@@ -1837,7 +1890,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1837,7 +1915,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
navigationabstract1.recomputePath(); navigationabstract1.recomputePath();
} }
} finally { } finally {
@ -14273,7 +14305,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
} }
@@ -1846,23 +1899,23 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1846,23 +1924,23 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { public void updateNeighborsAt(BlockPos pos, Block sourceBlock) {
@ -14302,7 +14334,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
@Override @Override
@@ -1893,7 +1946,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1893,7 +1971,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
explosion.clearToBlow(); explosion.clearToBlow();
} }
@ -14311,7 +14343,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
while (iterator.hasNext()) { while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next(); ServerPlayer entityplayer = (ServerPlayer) iterator.next();
@@ -1908,25 +1961,28 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1908,25 +1986,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) {
@ -14346,7 +14378,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
private boolean doBlockEvent(BlockEventData event) { private boolean doBlockEvent(BlockEventData event) {
@@ -1937,12 +1993,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1937,12 +2018,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override @Override
public LevelTicks<Block> getBlockTicks() { public LevelTicks<Block> getBlockTicks() {
@ -14361,7 +14393,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
@Nonnull @Nonnull
@@ -1966,7 +2022,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1966,7 +2047,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
@ -14370,7 +14402,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
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
@@ -2019,7 +2075,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2019,7 +2100,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);
@ -14386,7 +14418,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
@Nullable @Nullable
@@ -2179,6 +2242,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2179,6 +2267,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public boolean setChunkForced(int x, int z, boolean forced) { public boolean setChunkForced(int x, int z, boolean forced) {
@ -14394,7 +14426,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
ForcedChunksSavedData forcedchunk = (ForcedChunksSavedData) this.getDataStorage().computeIfAbsent(ForcedChunksSavedData::load, ForcedChunksSavedData::new, "chunks"); ForcedChunksSavedData forcedchunk = (ForcedChunksSavedData) this.getDataStorage().computeIfAbsent(ForcedChunksSavedData::load, ForcedChunksSavedData::new, "chunks");
ChunkPos chunkcoordintpair = new ChunkPos(x, z); ChunkPos chunkcoordintpair = new ChunkPos(x, z);
long k = chunkcoordintpair.toLong(); long k = chunkcoordintpair.toLong();
@@ -2187,7 +2251,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2187,7 +2276,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) {
@ -14403,7 +14435,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
} else { } else {
flag1 = forcedchunk.getChunks().remove(k); flag1 = forcedchunk.getChunks().remove(k);
@@ -2215,13 +2279,18 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2215,13 +2304,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
BlockPos blockposition1 = pos.immutable(); BlockPos blockposition1 = pos.immutable();
optional.ifPresent((holder) -> { optional.ifPresent((holder) -> {
@ -14425,7 +14457,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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);
@@ -2229,7 +2298,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2229,7 +2323,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);
@ -14439,7 +14471,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
}); });
} }
} }
@@ -2276,7 +2350,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2276,7 +2375,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 {
@ -14448,7 +14480,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState(); NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState();
if (spawnercreature_d != null) { if (spawnercreature_d != null) {
@@ -2290,7 +2364,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2290,7 +2389,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
@ -14457,7 +14489,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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");
@@ -2436,7 +2510,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2436,7 +2535,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);
@ -14466,7 +14498,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
while (iterator.hasNext()) { while (iterator.hasNext()) {
TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next(); TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next();
@@ -2449,7 +2523,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2449,7 +2548,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@VisibleForTesting @VisibleForTesting
public void clearBlockEvents(BoundingBox box) { public void clearBlockEvents(BoundingBox box) {
@ -14475,7 +14507,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
return box.isInside(blockactiondata.pos()); return box.isInside(blockactiondata.pos());
}); });
} }
@@ -2458,7 +2532,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2458,7 +2557,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
@ -14484,7 +14516,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
return; return;
} }
// CraftBukkit end // CraftBukkit end
@@ -2501,9 +2575,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2501,9 +2600,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@VisibleForTesting @VisibleForTesting
public String getWatchdogStats() { public String getWatchdogStats() {
@ -14495,7 +14527,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
private static <T> String getTypeCount(Iterable<T> items, Function<T, String> classifier) { private static <T> String getTypeCount(Iterable<T> items, Function<T, String> classifier) {
@@ -2536,6 +2608,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2536,6 +2633,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;
@ -14508,7 +14540,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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();
@@ -2548,11 +2626,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2548,11 +2651,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);
}); });
@ -14521,7 +14553,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
blockList.updateList(); blockList.updateList();
} }
// CraftBukkit end // CraftBukkit end
@@ -2573,13 +2647,14 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2573,13 +2672,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
} }
public void startTickingChunk(LevelChunk chunk) { public void startTickingChunk(LevelChunk chunk) {
@ -14540,7 +14572,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
@Override @Override
@@ -2601,7 +2676,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2601,7 +2701,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end - rewrite chunk system // Paper end - rewrite chunk system
} }
@ -14549,7 +14581,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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
@@ -2657,16 +2732,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2657,16 +2757,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) {
@ -14569,7 +14601,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
// 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;
@@ -2694,7 +2769,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2694,7 +2794,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"));
} }
@ -14578,7 +14610,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
if (entity instanceof EnderDragon) { if (entity instanceof EnderDragon) {
@@ -2705,7 +2780,9 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2705,7 +2805,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];
@ -14588,7 +14620,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
} }
@@ -2731,11 +2808,18 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2731,11 +2833,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) ->
{ {
@ -14608,7 +14640,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
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(); )
{ {
@@ -2745,6 +2829,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2745,6 +2854,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
iter.remove(); iter.remove();
} }
} }
@ -14616,7 +14648,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
} }
} ); } );
@@ -2779,7 +2864,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2779,7 +2889,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"));
} }
@ -14625,7 +14657,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
} }
if (entity instanceof EnderDragon) { if (entity instanceof EnderDragon) {
@@ -2790,13 +2875,16 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2790,13 +2900,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];
@ -14643,7 +14675,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..f95f1d1bc08b3c8f331a4f760e321823
for (ServerPlayer player : ServerLevel.this.players) { for (ServerPlayer player : ServerLevel.this.players) {
player.getBukkitEntity().onEntityRemove(entity); player.getBukkitEntity().onEntityRemove(entity);
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa1137b9363f9 100644 index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af8a9e8791 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -190,7 +190,7 @@ import org.bukkit.inventory.MainHand; @@ -190,7 +190,7 @@ import org.bukkit.inventory.MainHand;
@ -14677,92 +14709,164 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
} }
// Yes, this doesn't match Vanilla, but it's the best we can do for now. // Yes, this doesn't match Vanilla, but it's the best we can do for now.
@@ -458,11 +454,11 @@ public class ServerPlayer extends Player { @@ -458,51 +454,152 @@ public class ServerPlayer extends Player {
} }
// CraftBukkit end // CraftBukkit end
- public void fudgeSpawnLocation(ServerLevel world) { - public void fudgeSpawnLocation(ServerLevel world) {
- BlockPos blockposition = world.getSharedSpawnPos(); - BlockPos blockposition = world.getSharedSpawnPos();
+ public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.Completable<Location> toComplete) { // Folia - region threading + // Folia start - region threading
+ BlockPos blockposition = world.getSharedSpawnPos(); final BlockPos spawnPos = blockposition; // Folia - region threading + private static final int SPAWN_RADIUS_SELECTION_SEARCH = 5;
if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit - if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
- int i = Math.max(0, this.server.getSpawnRadius(world)); - int i = Math.max(0, this.server.getSpawnRadius(world));
+ int i = Math.max(0, MinecraftServer.getServer().getSpawnRadius(world)); // Folia - region threading - int j = Mth.floor(world.getWorldBorder().getDistanceToBorder((double) blockposition.getX(), (double) blockposition.getZ()));
int j = Mth.floor(world.getWorldBorder().getDistanceToBorder((double) blockposition.getX(), (double) blockposition.getZ())); + private static BlockPos getRandomSpawn(ServerLevel world, RandomSource random) {
+ BlockPos spawn = world.getSharedSpawnPos();
+ double radius = (double)Math.max(0, world.getGameRules().getInt(GameRules.RULE_SPAWN_RADIUS));
if (j < i) { - if (j < i) {
@@ -476,33 +472,76 @@ public class ServerPlayer extends Player { - i = j;
long k = (long) (i * 2 + 1); - }
long l = k * k; + double spawnX = (double)spawn.getX() + 0.5;
int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; + double spawnZ = (double)spawn.getZ() + 0.5;
- if (j <= 1) {
- i = 1;
+ WorldBorder worldBorder = world.getWorldBorder();
+
+ double selectMinX = Math.max(worldBorder.getMinX() + 1.0, spawnX - radius);
+ double selectMinZ = Math.max(worldBorder.getMinZ() + 1.0, spawnZ - radius);
+ double selectMaxX = Math.min(worldBorder.getMaxX() - 1.0, spawnX + radius);
+ double selectMaxZ = Math.min(worldBorder.getMaxZ() - 1.0, spawnZ + radius);
+
+ double amountX = selectMaxX - selectMinX;
+ double amountZ = selectMaxZ - selectMinZ;
+
+ int selectX = amountX < 1.0 ? Mth.floor(worldBorder.getCenterX()) : (int)Mth.floor((amountX + 1.0) * random.nextDouble() + selectMinX);
+ int selectZ = amountZ < 1.0 ? Mth.floor(worldBorder.getCenterZ()) : (int)Mth.floor((amountZ + 1.0) * random.nextDouble() + selectMinZ);
+
+ return new BlockPos(selectX, 0, selectZ);
+ }
+
+ private static void completeSpawn(ServerLevel world, BlockPos selected,
+ ca.spottedleaf.concurrentutil.completable.Completable<Location> toComplete) {
+ toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(selected), world.levelData.getSpawnAngle(), 0.0f));
+ }
+
+ private static BlockPos findSpawnAround(ServerLevel world, ServerPlayer player, BlockPos selected) {
+ // try hard to find, so that we don't attempt another chunk load
+ for (int dz = -SPAWN_RADIUS_SELECTION_SEARCH; dz <= SPAWN_RADIUS_SELECTION_SEARCH; ++dz) {
+ for (int dx = -SPAWN_RADIUS_SELECTION_SEARCH; dx <= SPAWN_RADIUS_SELECTION_SEARCH; ++dx) {
+ BlockPos inChunk = PlayerRespawnLogic.getOverworldRespawnPos(world, selected.getX(), selected.getZ());
+ if (inChunk == null) {
+ continue;
+ }
+
+ AABB checkVolume = player.getBoundingBoxAt((double)inChunk.getX() + 0.5, (double)inChunk.getY(), (double)inChunk.getZ() + 0.5);
+
+ if (!world.noCollision(player, checkVolume, true)) {
+ continue;
+ }
+
+ return inChunk;
}
+ }
- long k = (long) (i * 2 + 1);
- long l = k * k;
- int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l;
- int j1 = this.getCoprime(i1); - int j1 = this.getCoprime(i1);
+ int j1 = getCoprime(i1); // Folia - region threading - int k1 = RandomSource.create().nextInt(i1);
int k1 = RandomSource.create().nextInt(i1); + return null;
+ }
- for (int l1 = 0; l1 < i1; ++l1) { - for (int l1 = 0; l1 < i1; ++l1) {
- int i2 = (k1 + j1 * l1) % i1; - int i2 = (k1 + j1 * l1) % i1;
- int j2 = i2 % (i * 2 + 1); - int j2 = i2 % (i * 2 + 1);
- int k2 = i2 / (i * 2 + 1); - int k2 = i2 / (i * 2 + 1);
- BlockPos blockposition1 = PlayerRespawnLogic.getOverworldRespawnPos(world, blockposition.getX() + j2 - i, blockposition.getZ() + k2 - i); - BlockPos blockposition1 = PlayerRespawnLogic.getOverworldRespawnPos(world, blockposition.getX() + j2 - i, blockposition.getZ() + k2 - i);
- + // rets false when another attempt is required
+ private static boolean trySpawnOrSchedule(ServerLevel world, ServerPlayer player, RandomSource random, int[] attemptCount, int maxAttempts,
+ ca.spottedleaf.concurrentutil.completable.Completable<Location> toComplete) {
+ ++attemptCount[0];
- if (blockposition1 != null) { - if (blockposition1 != null) {
- this.moveTo(blockposition1, 0.0F, 0.0F); - this.moveTo(blockposition1, 0.0F, 0.0F);
- if (world.noCollision(this, this.getBoundingBox(), true)) { // Paper - make sure this loads chunks, we default to NOT loading now - if (world.noCollision(this, this.getBoundingBox(), true)) { // Paper - make sure this loads chunks, we default to NOT loading now
- break; - break;
- } + BlockPos rough = getRandomSpawn(world, random);
+ // Folia start - region threading
+ int[] l1 = new int[1];
+ final int finalI = i;
+ Runnable attempt = new Runnable() {
+ @Override
+ public void run() {
+ int i2 = (k1 + j1 * l1[0]) % i1;
+ int j2 = i2 % (finalI * 2 + 1);
+ int k2 = i2 / (finalI * 2 + 1);
+ int x = blockposition.getX() + j2 - finalI;
+ int z = blockposition.getZ() + k2 - finalI;
+ +
+ world.loadChunksForMoveAsync(player.getBoundingBoxAt(x + 0.5, 0, z + 0.5), + int minX = (rough.getX() - SPAWN_RADIUS_SELECTION_SEARCH) >> 4;
+ int minZ = (rough.getZ() - SPAWN_RADIUS_SELECTION_SEARCH) >> 4;
+ int maxX = (rough.getX() + SPAWN_RADIUS_SELECTION_SEARCH) >> 4;
+ int maxZ = (rough.getZ() + SPAWN_RADIUS_SELECTION_SEARCH) >> 4;
+
+ // we could short circuit this check, but it would possibly recurse. Then, it could end up causing a stack overflow
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(world, minX, minZ, maxX, maxZ) || !world.isAreaLoaded(minX, minZ, maxX, maxZ)) {
+ world.loadChunksAsync(minX, maxX, minZ, maxZ,
+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER,
+ (c) -> { + (unused) -> {
+ BlockPos blockposition1 = PlayerRespawnLogic.getOverworldRespawnPos(world, x, z); + BlockPos selected = findSpawnAround(world, player, rough);
+ if (blockposition1 != null) { + if (selected == null) {
+ AABB aabb = player.getBoundingBoxAt(blockposition1.getX() + 0.5, blockposition1.getY(), blockposition1.getZ() + 0.5); + // run more spawn attempts
+ if (world.noCollision(player, aabb, true)) { // Paper - make sure this loads chunks, we default to NOT loading now + selectSpawn(world, player, random, attemptCount, maxAttempts, toComplete);
+ toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(blockposition1), world.levelData.getSpawnAngle(), 0.0f));
+ return; + return;
+ } }
+ } +
+ if (++l1[0] >= i1) { + completeSpawn(world, selected, toComplete);
+ LOGGER.warn("Found no spawn in radius for player " + player.getName() + ", selecting set spawn point " + spawnPos + " in world '" + world.getWorld().getKey() + "'");
+ // if we return null, then no chunks may be loaded. but this call requires to return a location with
+ // loaded chunks, so we need to return something (vanilla does not do this logic, it assumes
+ // something is returned always)
+ // we can just return the set spawn position
+ world.loadChunksForMoveAsync(player.getBoundingBoxAt(spawnPos.getX() + 0.5, spawnPos.getY(), spawnPos.getZ() + 0.5),
+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER,
+ (c0) -> {
+ toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(spawnPos), world.levelData.getSpawnAngle(), 0.0f));
+ }
+ );
+ return; + return;
+ } else {
+ this.run();
+ }
+ }
+ );
} }
- } - }
+ }; - } else {
+ attempt.run();
+ // Folia end - region threading
} else {
- this.moveTo(blockposition, 0.0F, 0.0F); - this.moveTo(blockposition, 0.0F, 0.0F);
- + );
+ return true;
+ }
+
+ BlockPos selected = findSpawnAround(world, player, rough);
+ if (selected == null) {
+ return false;
+ }
+
+ completeSpawn(world, selected, toComplete);
+ return true;
+ }
+
+ private static void selectSpawn(ServerLevel world, ServerPlayer player, RandomSource random, int[] attemptCount, int maxAttempts,
+ ca.spottedleaf.concurrentutil.completable.Completable<Location> toComplete) {
+ do {
+ if (attemptCount[0] >= maxAttempts) {
+ BlockPos sharedSpawn = world.getSharedSpawnPos();
+ BlockPos selected = world.getWorldBorder().clampToBounds((double)sharedSpawn.getX(), (double)sharedSpawn.getY(), (double)sharedSpawn.getZ());
- while (!world.noCollision(this, this.getBoundingBox(), true) && this.getY() < (double) (world.getMaxBuildHeight() - 1)) { // Paper - make sure this loads chunks, we default to NOT loading now - while (!world.noCollision(this, this.getBoundingBox(), true) && this.getY() < (double) (world.getMaxBuildHeight() - 1)) { // Paper - make sure this loads chunks, we default to NOT loading now
- this.setPos(this.getX(), this.getY() + 1.0D, this.getZ()); - this.setPos(this.getX(), this.getY() + 1.0D, this.getZ());
- } + LOGGER.warn("Found no spawn in radius for player '" + player.getName() + "', ignoring radius");
+
+ // this call requires to return a location with loaded chunks, so we need to schedule a load here
+ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(
+ world, selected.getX() >> 4, selected.getZ() >> 4, net.minecraft.world.level.chunk.ChunkStatus.FULL,
+ true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER,
+ (unused) -> {
+ completeSpawn(world, selected, toComplete);
+ }
+ );
+ return;
}
+ } while (!trySpawnOrSchedule(world, player, random, attemptCount, maxAttempts, toComplete));
+ }
+
+ // Folia end - region threading
+
+ public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.Completable<Location> toComplete) { // Folia - region threading
+ BlockPos blockposition = world.getSharedSpawnPos();
+
+ if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
+ // Folia start - region threading
+ selectSpawn(world, player, player.random, new int[1], 500, toComplete);
+ // Folia end - region threading
+ } else {
+ // Folia start - region threading + // Folia start - region threading
+ world.loadChunksForMoveAsync(player.getBoundingBoxAt(blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5), + world.loadChunksForMoveAsync(player.getBoundingBoxAt(blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5),
+ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER,
@ -14788,7 +14892,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
return horizontalSpawnArea <= 16 ? horizontalSpawnArea - 1 : 17; return horizontalSpawnArea <= 16 ? horizontalSpawnArea - 1 : 17;
} }
@@ -1161,6 +1200,345 @@ public class ServerPlayer extends Player { @@ -1161,6 +1258,345 @@ public class ServerPlayer extends Player {
} }
} }
@ -15134,7 +15238,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
@Nullable @Nullable
@Override @Override
public Entity changeDimension(ServerLevel destination) { public Entity changeDimension(ServerLevel destination) {
@@ -1170,6 +1548,11 @@ public class ServerPlayer extends Player { @@ -1170,6 +1606,11 @@ public class ServerPlayer extends Player {
@Nullable @Nullable
public Entity changeDimension(ServerLevel worldserver, PlayerTeleportEvent.TeleportCause cause) { public Entity changeDimension(ServerLevel worldserver, PlayerTeleportEvent.TeleportCause cause) {
@ -15146,7 +15250,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
// CraftBukkit end // CraftBukkit end
if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154 if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154
// this.isChangingDimension = true; // CraftBukkit - Moved down and into PlayerList#changeDimension // this.isChangingDimension = true; // CraftBukkit - Moved down and into PlayerList#changeDimension
@@ -2114,6 +2497,12 @@ public class ServerPlayer extends Player { @@ -2114,6 +2555,12 @@ public class ServerPlayer extends Player {
public void setCamera(@Nullable Entity entity) { public void setCamera(@Nullable Entity entity) {
Entity entity1 = this.getCamera(); Entity entity1 = this.getCamera();
@ -15159,7 +15263,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
this.camera = (Entity) (entity == null ? this : entity); this.camera = (Entity) (entity == null ? this : entity);
if (entity1 != this.camera) { if (entity1 != this.camera) {
// Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event
@@ -2307,7 +2696,7 @@ public class ServerPlayer extends Player { @@ -2307,7 +2754,7 @@ public class ServerPlayer extends Player {
} }
public void untrackChunk(ChunkPos chunkPos) { public void untrackChunk(ChunkPos chunkPos) {
@ -15168,7 +15272,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..aa42c1a05f12a614c0a7553d52efa113
this.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos.x, chunkPos.z)); this.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos.x, chunkPos.z));
// Paper start // Paper start
if(io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0){ if(io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0){
@@ -2626,7 +3015,7 @@ public class ServerPlayer extends Player { @@ -2626,7 +3073,7 @@ public class ServerPlayer extends Player {
this.experienceLevel = this.newLevel; this.experienceLevel = this.newLevel;
this.totalExperience = this.newTotalExp; this.totalExperience = this.newTotalExp;
this.experienceProgress = 0; this.experienceProgress = 0;

View File

@ -9,10 +9,10 @@ data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly. some accesses may throw and as such we need to fix this directly.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index aa42c1a05f12a614c0a7553d52efa1137b9363f9..817f79bfca1aec161cb4635b9c7a8e21b14db7eb 100644 index abbc8992523e55a665318df07dd732af8a9e8791..febd0ba72922462364eb65243640dcb693129e21 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -571,7 +571,7 @@ public class ServerPlayer extends Player { @@ -629,7 +629,7 @@ public class ServerPlayer extends Player {
this.getBukkitEntity().readExtraData(nbt); // CraftBukkit this.getBukkitEntity().readExtraData(nbt); // CraftBukkit
if (this.isSleeping()) { if (this.isSleeping()) {

View File

@ -139,10 +139,10 @@ index 916bfdfb13d8f8093e1908a7c35344b83d0ee0ac..25fe439c8d1e88a86e85ac9a4761425d
} }
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 f95f1d1bc08b3c8f331a4f760e3218238f74ff67..042ca6b3faae5249210567f2c26dff404974e1ff 100644 index bb07ad1bb895297356b88dfc4cd17e5e93795c38..60b409e873d8f5d7975cce6e86ee2ed5525d348c 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
@@ -2638,12 +2638,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -2663,12 +2663,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.entityLookup; // Paper - rewrite chunk system return this.entityLookup; // Paper - rewrite chunk system
} }