diff --git a/patches/server/0004-Threaded-Regions.patch b/patches/server/0004-Threaded-Regions.patch index 6d27f0f..9c6ce7a 100644 --- a/patches/server/0004-Threaded-Regions.patch +++ b/patches/server/0004-Threaded-Regions.patch @@ -2046,7 +2046,7 @@ index 4b002e8b75d117b726b0de274a76d3596fce015b..897cb94abf7b53da8ba7cda5135b6580 metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { Map> map = new HashMap<>(); diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -index 4f3670b2bdb8b1b252e9f074a6af56a018a8c465..bb3df6a4d8b87219c3c0406c56428c28d5f9ab4e 100644 +index 4f3670b2bdb8b1b252e9f074a6af56a018a8c465..5c1ea572a97b130c3ff77624189b4acf3e9e9ece 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -179,11 +179,7 @@ public final class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockCo @@ -2058,12 +2058,12 @@ index 4f3670b2bdb8b1b252e9f074a6af56a018a8c465..bb3df6a4d8b87219c3c0406c56428c28 - MinecraftServer.getServer().scheduleOnMain(() -> modifyBlocks(chunkPacket, chunkPacketInfo)); - return; - } -+ // Paper - region threading ++ // Folia - region threading LevelChunk chunk = chunkPacketInfo.getChunk(); int x = chunk.getPos().x; diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index 309fe1162db195c7c3c94d785d6aa2700e42b08a..70db79d37257dedada9f55b3cf1127451c151072 100644 +index 309fe1162db195c7c3c94d785d6aa2700e42b08a..27f8c9b1c56cbf9af400a9ae15c2076a2db8b284 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -97,7 +97,7 @@ public final class ChatProcessor { @@ -2071,7 +2071,7 @@ index 309fe1162db195c7c3c94d785d6aa2700e42b08a..70db79d37257dedada9f55b3cf112745 final AsyncPlayerChatEvent ae = new AsyncPlayerChatEvent(this.async, player, this.craftbukkit$originalMessage, new LazyPlayerSet(this.server)); this.post(ae); - if (listenersOnSyncEvent) { -+ if (false && listenersOnSyncEvent) { // Paper - region threading ++ if (false && listenersOnSyncEvent) { // Folia - region threading final PlayerChatEvent se = new PlayerChatEvent(player, ae.getMessage(), ae.getFormat(), ae.getRecipients()); se.setCancelled(ae.isCancelled()); // propagate cancelled state this.queueIfAsyncOrRunImmediately(new Waitable() { @@ -2080,21 +2080,21 @@ index 309fe1162db195c7c3c94d785d6aa2700e42b08a..70db79d37257dedada9f55b3cf112745 this.post(ae); final boolean listenersOnSyncEvent = canYouHearMe(ChatEvent.getHandlerList()); - if (listenersOnSyncEvent) { -+ if (false && listenersOnSyncEvent) { // Paper - region threading ++ if (false && listenersOnSyncEvent) { // Folia - region threading this.queueIfAsyncOrRunImmediately(new Waitable() { @Override protected Void evaluate() { diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -index 6df1948b1204a7288ecb7238b6fc2a733f7d25b3..7ac1ca0e358a38cf5d1e7f7cdc7383ca9c7df6f2 100644 +index 6df1948b1204a7288ecb7238b6fc2a733f7d25b3..6a413abc67aa4dcbab64231be3eb13446d5cc820 100644 --- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java @@ -91,6 +91,9 @@ public final class ChunkSystem { for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { chunkMap.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z); } -+ // Paper start - threaded regions ++ // Folia start - threaded regions + level.regioniser.addChunk(holder.pos.x, holder.pos.z); -+ // Paper end - threaded regions ++ // Folia end - threaded regions } public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { @@ -2102,9 +2102,9 @@ index 6df1948b1204a7288ecb7238b6fc2a733f7d25b3..7ac1ca0e358a38cf5d1e7f7cdc7383ca for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) { chunkMap.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z); } -+ // Paper start - threaded regions ++ // Folia start - threaded regions + level.regioniser.removeChunk(holder.pos.x, holder.pos.z); -+ // Paper end - threaded regions ++ // Folia end - threaded regions } public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { @@ -2113,27 +2113,27 @@ index 6df1948b1204a7288ecb7238b6fc2a733f7d25b3..7ac1ca0e358a38cf5d1e7f7cdc7383ca public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().tickingChunks.add(chunk); -+ // Paper - region threading ++ // Folia - region threading } public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().tickingChunks.remove(chunk); -+ // Paper - region threading ++ // Folia - region threading } public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().entityTickingChunks.add(chunk); -+ chunk.level.getCurrentWorldData().addEntityTickingChunks(chunk); // Paper - region threading ++ chunk.level.getCurrentWorldData().addEntityTickingChunks(chunk); // Folia - region threading } public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { - chunk.level.getChunkSource().entityTickingChunks.remove(chunk); -+ chunk.level.getCurrentWorldData().removeEntityTickingChunk(chunk); // Paper - region threading ++ chunk.level.getCurrentWorldData().removeEntityTickingChunk(chunk); // Folia - region threading } public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { diff --git a/src/main/java/io/papermc/paper/chunk/system/RegionisedPlayerChunkLoader.java b/src/main/java/io/papermc/paper/chunk/system/RegionisedPlayerChunkLoader.java -index a4d58352eebed11fafde8c381afe3572893b8f8f..b9b3ab0bcddbbe485bb138bfd4882a21067f8bde 100644 +index a4d58352eebed11fafde8c381afe3572893b8f8f..2d601807b0b2ddc332e45878d4350b3bd661f5e2 100644 --- a/src/main/java/io/papermc/paper/chunk/system/RegionisedPlayerChunkLoader.java +++ b/src/main/java/io/papermc/paper/chunk/system/RegionisedPlayerChunkLoader.java @@ -231,14 +231,14 @@ public class RegionisedPlayerChunkLoader { @@ -2141,7 +2141,7 @@ index a4d58352eebed11fafde8c381afe3572893b8f8f..b9b3ab0bcddbbe485bb138bfd4882a21 public void tick() { TickThread.ensureTickThread("Cannot tick player chunk loader async"); - for (final ServerPlayer player : this.world.players()) { -+ for (final ServerPlayer player : this.world.getLocalPlayers()) { // Paper - region threding ++ for (final ServerPlayer player : this.world.getLocalPlayers()) { // Folia - region threding player.chunkLoader.update(); } } @@ -2149,12 +2149,12 @@ index a4d58352eebed11fafde8c381afe3572893b8f8f..b9b3ab0bcddbbe485bb138bfd4882a21 public void tickMidTick() { final long time = System.nanoTime(); - for (final ServerPlayer player : this.world.players()) { -+ for (final ServerPlayer player : this.world.getLocalPlayers()) { // Paper - region threading ++ for (final ServerPlayer player : this.world.getLocalPlayers()) { // Folia - region threading player.chunkLoader.midTickUpdate(time); } } diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java -index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e31008458 100644 +index 61c170555c8854b102c640b0b6a615f9f732edbf..687fc3e7ada3da9c5b938b0ffb9e8bcf90c2d1c7 100644 --- a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java +++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java @@ -187,7 +187,12 @@ public final class EntityLookup implements LevelEntityGetter { @@ -2162,12 +2162,12 @@ index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e @Override public Iterable getAll() { - return new ArrayIterable<>(this.accessibleEntities.getRawData(), 0, this.accessibleEntities.size()); -+ // Paper start - region threading ++ // Folia start - region threading + synchronized (this.accessibleEntities) { + Entity[] iterate = java.util.Arrays.copyOf(this.accessibleEntities.getRawData(), this.accessibleEntities.size()); + return new ArrayIterable<>(iterate, 0, iterate.length); + } -+ // Paper end - region threading ++ // Folia end - region threading } @Override @@ -2175,9 +2175,9 @@ index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e if (newVisibility.ordinal() > oldVisibility.ordinal()) { // status upgrade if (!oldVisibility.isAccessible() && newVisibility.isAccessible()) { -+ synchronized (this.accessibleEntities) { // Paper - region threading ++ synchronized (this.accessibleEntities) { // Folia - region threading this.accessibleEntities.add(entity); -+ } // Paper - region threading ++ } // Folia - region threading EntityLookup.this.worldCallback.onTrackingStart(entity); } @@ -2185,9 +2185,9 @@ index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e } if (oldVisibility.isAccessible() && !newVisibility.isAccessible()) { -+ synchronized (this.accessibleEntities) { // Paper - region threading ++ synchronized (this.accessibleEntities) { // Folia - region threading this.accessibleEntities.remove(entity); -+ } // Paper - region threading ++ } // Folia - region threading EntityLookup.this.worldCallback.onTrackingEnd(entity); } } @@ -2195,7 +2195,7 @@ index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e entity.setLevelCallback(new EntityCallback(entity)); -+ this.world.getCurrentWorldData().addEntity(entity); // Paper - region threading ++ this.world.getCurrentWorldData().addEntity(entity); // Folia - region threading + this.entityStatusChange(entity, slices, Visibility.HIDDEN, getEntityStatus(entity), false, !fromDisk, false); @@ -2213,13 +2213,13 @@ index 61c170555c8854b102c640b0b6a615f9f732edbf..576e48f68861b817bcd94252e1fd587e this.entity.setLevelCallback(NoOpCallback.INSTANCE); + -+ // only AFTER full removal callbacks, so that thread checking will work. // Paper - region threading -+ EntityLookup.this.world.getCurrentWorldData().removeEntity(entity); // Paper - region threading ++ // only AFTER full removal callbacks, so that thread checking will work. // Folia - region threading ++ EntityLookup.this.world.getCurrentWorldData().removeEntity(entity); // Folia - region threading } } diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java -index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911bae0c30c 100644 +index c6d20bc2f0eab737338db6b88dacb63f0decb66c..309b45885edc1400ae5a97cac7e5e5a19d73be0c 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java @@ -3,7 +3,6 @@ package io.papermc.paper.chunk.system.scheduling; @@ -2256,12 +2256,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 import java.util.concurrent.locks.ReentrantLock; import java.util.function.Predicate; -+// Paper start - region threading ++// Folia start - region threading +import io.papermc.paper.threadedregions.RegionisedServer; +import io.papermc.paper.threadedregions.ThreadedRegioniser; +import io.papermc.paper.threadedregions.TickRegionScheduler; +import io.papermc.paper.threadedregions.TickRegions; -+// Paper end - region threading ++// Folia end - region threading + public final class ChunkHolderManager { @@ -2271,20 +2271,20 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 public static final int MAX_TICKET_LEVEL = ChunkMap.MAX_CHUNK_DISTANCE; // inclusive - private static final long NO_TIMEOUT_MARKER = -1L; -+ // Paper start - region threading ++ // Folia start - region threading + private static final long NO_TIMEOUT_MARKER = Long.MIN_VALUE; + private static final long PROBE_MARKER = Long.MIN_VALUE + 1; -+ // Paper end - region threading ++ // Folia end - region threading - final ReentrantLock ticketLock = new ReentrantLock(); -+ public final ReentrantLock ticketLock = new ReentrantLock(); // Paper - region threading ++ public final ReentrantLock ticketLock = new ReentrantLock(); // Folia - region threading private final SWMRLong2ObjectHashTable chunkHolders = new SWMRLong2ObjectHashTable<>(16384, 0.25f); - private final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap<>(8192, 0.25f); - // what a disaster of a name - // this is a map of removal tick to a map of chunks and the number of tickets a chunk has that are to expire that tick - private final Long2ObjectOpenHashMap removeTickToChunkExpireTicketCount = new Long2ObjectOpenHashMap<>(); -+ // Paper - region threading ++ // Folia - region threading private final ServerLevel world; private final ChunkTaskScheduler taskScheduler; - private long currentTick; @@ -2293,7 +2293,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 - private final ObjectRBTreeSet autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> { - if (c1 == c2) { - return 0; -+ // Paper start - region threading ++ // Folia start - region threading + public static final class HolderManagerRegionData { + private final ArrayDeque pendingFullLoadUpdate = new ArrayDeque<>(); + private final ObjectRBTreeSet autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> { @@ -2483,7 +2483,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + + return region.getData().getHolderManagerRegionData(); + } -+ // Paper end - region threading ++ // Folia end - region threading + public ChunkHolderManager(final ServerLevel world, final ChunkTaskScheduler taskScheduler) { @@ -2492,14 +2492,14 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } public void close(final boolean save, final boolean halt) { -+ // Paper start - region threading ++ // Folia start - region threading + this.close(save, halt, true, true, true); + } + public void close(final boolean save, final boolean halt, final boolean first, final boolean last, final boolean checkRegions) { -+ // Paper end - region threading ++ // Folia end - region threading TickThread.ensureTickThread("Closing world off-main"); - if (halt) { -+ if (first && halt) { // Paper - region threading ++ if (first && halt) { // Folia - region threading LOGGER.info("Waiting 60s for chunk system to halt for world '" + this.world.getWorld().getName() + "'"); if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { LOGGER.warn("Failed to halt world generation/loading tasks for world '" + this.world.getWorld().getName() + "'"); @@ -2508,10 +2508,10 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 if (save) { - this.saveAllChunks(true, true, true); -+ this.saveAllChunksRegionised(true, true, true, first, last, checkRegions); // Paper - region threading ++ this.saveAllChunksRegionised(true, true, true, first, last, checkRegions); // Folia - region threading } -+ if (last) { // Paper - region threading ++ if (last) { // Folia - region threading if (this.world.chunkDataControllerNew.hasTasks() || this.world.entityDataControllerNew.hasTasks() || this.world.poiDataControllerNew.hasTasks()) { RegionFileIOThread.flush(); } @@ -2519,18 +2519,18 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } catch (final IOException ex) { LOGGER.error("Failed to close poi regionfile cache for world '" + this.world.getWorld().getName() + "'", ex); } -+ } // Paper - region threading ++ } // Folia - region threading } void ensureInAutosave(final NewChunkHolder holder) { - if (!this.autoSaveQueue.contains(holder)) { - holder.lastAutoSave = MinecraftServer.currentTick; - this.autoSaveQueue.add(holder); -+ // Paper start - region threading ++ // Folia start - region threading + final HolderManagerRegionData regionData = this.getCurrentRegionData(); + if (!regionData.autoSaveQueue.contains(holder)) { + holder.lastAutoSave = RegionisedServer.getCurrentTick(); -+ // Paper end - region threading ++ // Folia end - region threading + regionData.autoSaveQueue.add(holder); } } @@ -2542,10 +2542,10 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 final long maxSaveTime = currentTick - this.world.paperConfig().chunks.autoSaveInterval.value(); - for (int autoSaved = 0; autoSaved < this.world.paperConfig().chunks.maxAutoSaveChunksPerTick && !this.autoSaveQueue.isEmpty();) { - final NewChunkHolder holder = this.autoSaveQueue.first(); -+ // Paper start - region threading ++ // Folia start - region threading + final HolderManagerRegionData regionData = this.getCurrentRegionData(); + for (int autoSaved = 0; autoSaved < this.world.paperConfig().chunks.maxAutoSaveChunksPerTick && !regionData.autoSaveQueue.isEmpty();) { -+ // Paper end - region threading ++ // Folia end - region threading + final NewChunkHolder holder = regionData.autoSaveQueue.first(); if (holder.lastAutoSave > maxSaveTime) { @@ -2568,15 +2568,15 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } public void saveAllChunks(final boolean flush, final boolean shutdown, final boolean logProgress) { -+ // Paper start - region threading ++ // Folia start - region threading + this.saveAllChunksRegionised(flush, shutdown, logProgress, true, true, true); + } + public void saveAllChunksRegionised(final boolean flush, final boolean shutdown, final boolean logProgress, final boolean first, final boolean last, final boolean checkRegion) { -+ // Paper end - region threading ++ // Folia end - region threading final List holders = this.getChunkHolders(); - if (logProgress) { -+ if (first && logProgress) { // Paper - region threading ++ if (first && logProgress) { // Folia - region threading LOGGER.info("Saving all chunkholders for world '" + this.world.getWorld().getName() + "'"); } @@ -2593,12 +2593,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 for (int i = 0, len = holders.size(); i < len; ++i) { final NewChunkHolder holder = holders.get(i); -+ // Paper start - region threading ++ // Folia start - region threading + if (!checkRegion && !TickThread.isTickThreadFor(this.world, holder.chunkX, holder.chunkZ)) { + // skip holders that would fail the thread check + continue; + } -+ // Paper end - region threading ++ // Folia end - region threading try { final NewChunkHolder.SaveStat saveStat = holder.save(shutdown, false); if (saveStat != null) { @@ -2607,7 +2607,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } } - if (flush) { -+ if (last && flush) { // Paper - region threading ++ if (last && flush) { // Folia - region threading RegionFileIOThread.flush(); } if (logProgress) { @@ -2621,17 +2621,17 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 - } finally { - this.ticketLock.unlock(); - } -+ return !this.getTicketsCopy().isEmpty(); // Paper - region threading ++ return !this.getTicketsCopy().isEmpty(); // Folia - region threading } public String getTicketDebugString(final long coordinate) { this.ticketLock.lock(); try { - final SortedArraySet> tickets = this.tickets.get(coordinate); -+ // Paper start - region threading ++ // Folia start - region threading + final ChunkHolderManager.HolderManagerRegionData holderManagerRegionData = this.getDataFor(coordinate); + final SortedArraySet> tickets = holderManagerRegionData == null ? null : holderManagerRegionData.tickets.get(coordinate); -+ // Paper end - region threading ++ // Folia end - region threading return tickets != null ? tickets.first().toString() : "no_ticket"; } finally { @@ -2640,7 +2640,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 this.ticketLock.lock(); try { - return this.tickets.clone(); -+ // Paper start - region threading ++ // Folia start - region threading + Long2ObjectOpenHashMap>> ret = new Long2ObjectOpenHashMap<>(); + this.world.regioniser.computeForAllRegions((region) -> { + for (final LongIterator iterator = region.getData().getHolderManagerRegionData().tickets.keySet().longIterator(); iterator.hasNext();) { @@ -2650,7 +2650,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + } + }); + return ret; -+ // Paper end - region threading ++ // Folia end - region threading } finally { this.ticketLock.unlock(); } @@ -2659,11 +2659,11 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 this.ticketLock.lock(); try { - SortedArraySet> tickets = this.tickets.get(ChunkPos.asLong(x, z)); -+ // Paper start - region threading ++ // Folia start - region threading + final long coordinate = CoordinateUtils.getChunkKey(x, z); + final ChunkHolderManager.HolderManagerRegionData holderManagerRegionData = this.getDataFor(coordinate); + final SortedArraySet> tickets = holderManagerRegionData == null ? null : holderManagerRegionData.tickets.get(coordinate); -+ // Paper end - region threading ++ // Folia end - region threading if (tickets == null) { return Collections.emptyList(); @@ -2672,7 +2672,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 this.ticketLock.lock(); try { - final long removeTick = removeDelay == 0 ? NO_TIMEOUT_MARKER : this.currentTick + removeDelay; -+ // Paper start - region threading ++ // Folia start - region threading + NewChunkHolder holder = this.chunkHolders.get(chunk); + final boolean addToSpecial = holder == null; + if (addToSpecial) { @@ -2688,12 +2688,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + // the unload chunks call will perform it + targetData.specialCaseUnload.add(holder); + } -+ // Paper end - region threading -+ final long removeTick = removeDelay == 0 ? NO_TIMEOUT_MARKER : targetData.currentTick + removeDelay; // Paper - region threading ++ // Folia end - region threading ++ final long removeTick = removeDelay == 0 ? NO_TIMEOUT_MARKER : targetData.currentTick + removeDelay; // Folia - region threading final Ticket ticket = new Ticket<>(type, level, identifier, removeTick); - final SortedArraySet> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (final long keyInMap) -> { -+ final SortedArraySet> ticketsAtChunk = targetData.tickets.computeIfAbsent(chunk, (final long keyInMap) -> { // Paper - region threading ++ final SortedArraySet> ticketsAtChunk = targetData.tickets.computeIfAbsent(chunk, (final long keyInMap) -> { // Folia - region threading return SortedArraySet.create(4); }); @@ -2702,20 +2702,20 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 if (removeTick != oldRemovalTick) { if (oldRemovalTick != NO_TIMEOUT_MARKER) { - final Long2IntOpenHashMap removeCounts = this.removeTickToChunkExpireTicketCount.get(oldRemovalTick); -+ final Long2IntOpenHashMap removeCounts = targetData.removeTickToChunkExpireTicketCount.get(oldRemovalTick); // Paper - region threading ++ final Long2IntOpenHashMap removeCounts = targetData.removeTickToChunkExpireTicketCount.get(oldRemovalTick); // Folia - region threading final int prevCount = removeCounts.addTo(chunk, -1); if (prevCount == 1) { removeCounts.remove(chunk); if (removeCounts.isEmpty()) { - this.removeTickToChunkExpireTicketCount.remove(oldRemovalTick); -+ targetData.removeTickToChunkExpireTicketCount.remove(oldRemovalTick); // Paper - region threading ++ targetData.removeTickToChunkExpireTicketCount.remove(oldRemovalTick); // Folia - region threading } } } if (removeTick != NO_TIMEOUT_MARKER) { - this.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { -+ targetData.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { // Paper - region threading ++ targetData.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { // Folia - region threading return new Long2IntOpenHashMap(); }).addTo(chunk, 1); } @@ -2723,7 +2723,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } else { if (removeTick != NO_TIMEOUT_MARKER) { - this.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { -+ targetData.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { // Paper - region threading ++ targetData.removeTickToChunkExpireTicketCount.computeIfAbsent(removeTick, (final long keyInMap) -> { // Folia - region threading return new Long2IntOpenHashMap(); }).addTo(chunk, 1); } @@ -2731,25 +2731,25 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 return false; } -+ final ChunkHolderManager.HolderManagerRegionData currRegionData = this.getCurrentRegionData(); // Paper - region threading ++ final ChunkHolderManager.HolderManagerRegionData currRegionData = this.getCurrentRegionData(); // Folia - region threading + this.ticketLock.lock(); try { - final SortedArraySet> ticketsAtChunk = this.tickets.get(chunk); -+ // Paper start - region threading ++ // Folia start - region threading + final ChunkHolderManager.HolderManagerRegionData targetData = this.getDataFor(chunk); + + final boolean sameRegion = currRegionData == targetData; + + final SortedArraySet> ticketsAtChunk = targetData == null ? null : targetData.tickets.get(chunk); -+ // Paper end - region threading ++ // Folia end - region threading if (ticketsAtChunk == null) { return false; } final int oldLevel = getTicketLevelAt(ticketsAtChunk); - final Ticket ticket = (Ticket)ticketsAtChunk.removeAndGet(new Ticket<>(type, level, identifier, -2L)); -+ final Ticket ticket = (Ticket)ticketsAtChunk.removeAndGet(new Ticket<>(type, level, identifier, PROBE_MARKER)); // Paper - region threading ++ final Ticket ticket = (Ticket)ticketsAtChunk.removeAndGet(new Ticket<>(type, level, identifier, PROBE_MARKER)); // Folia - region threading if (ticket == null) { return false; @@ -2757,7 +2757,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 if (ticketsAtChunk.isEmpty()) { - this.tickets.remove(chunk); -+ targetData.tickets.remove(chunk); // Paper - region threading ++ targetData.tickets.remove(chunk); // Folia - region threading } final int newLevel = getTicketLevelAt(ticketsAtChunk); @@ -2765,14 +2765,14 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 final long removeTick = ticket.removalTick; if (removeTick != NO_TIMEOUT_MARKER) { - final Long2IntOpenHashMap removeCounts = this.removeTickToChunkExpireTicketCount.get(removeTick); -+ final Long2IntOpenHashMap removeCounts = targetData.removeTickToChunkExpireTicketCount.get(removeTick); // Paper - region threading ++ final Long2IntOpenHashMap removeCounts = targetData.removeTickToChunkExpireTicketCount.get(removeTick); // Folia - region threading final int currCount = removeCounts.addTo(chunk, -1); if (currCount == 1) { removeCounts.remove(chunk); if (removeCounts.isEmpty()) { - this.removeTickToChunkExpireTicketCount.remove(removeTick); -+ targetData.removeTickToChunkExpireTicketCount.remove(removeTick); // Paper - region threading ++ targetData.removeTickToChunkExpireTicketCount.remove(removeTick); // Folia - region threading } } } @@ -2780,12 +2780,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 this.updateTicketLevel(chunk, newLevel); } -+ // Paper start - region threading ++ // Folia start - region threading + // if we're not the target region, we should not change the ticket levels while the target region may be ticking + if (!sameRegion && newLevel > level) { + this.addTicketAtLevel(TicketType.UNKNOWN, chunk, level, new ChunkPos(chunk)); + } -+ // Paper end - region threading ++ // Folia end - region threading + return true; } finally { @@ -2796,7 +2796,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 try { - for (final LongIterator iterator = new LongArrayList(this.tickets.keySet()).longIterator(); iterator.hasNext();) { - final long chunk = iterator.nextLong(); -+ // Paper start - region threading ++ // Folia start - region threading + this.world.regioniser.computeForAllRegions((region) -> { + for (final LongIterator iterator = new LongArrayList(region.getData().getHolderManagerRegionData().tickets.keySet()).longIterator(); iterator.hasNext();) { + final long chunk = iterator.nextLong(); @@ -2806,7 +2806,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + this.removeTicketAtLevel(ticketType, chunk, ticketLevel, ticketIdentifier); + } + }); -+ // Paper end - region threading ++ // Folia end - region threading } finally { this.ticketLock.unlock(); } @@ -2814,20 +2814,20 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 public void tick() { - TickThread.ensureTickThread("Cannot tick ticket manager off-main"); -+ // Paper start - region threading ++ // Folia start - region threading + final ChunkHolderManager.HolderManagerRegionData data = this.getCurrentRegionData(); + if (data == null) { + throw new IllegalStateException("Not running tick() while on a region"); + } -+ // Paper end - region threading ++ // Folia end - region threading this.ticketLock.lock(); try { - final long tick = ++this.currentTick; -+ final long tick = ++data.currentTick; // Paper - region threading ++ final long tick = ++data.currentTick; // Folia - region threading - final Long2IntOpenHashMap toRemove = this.removeTickToChunkExpireTicketCount.remove(tick); -+ final Long2IntOpenHashMap toRemove = data.removeTickToChunkExpireTicketCount.remove(tick); // Paper - region threading ++ final Long2IntOpenHashMap toRemove = data.removeTickToChunkExpireTicketCount.remove(tick); // Folia - region threading if (toRemove == null) { return; @@ -2836,11 +2836,11 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 final long chunk = iterator.nextLong(); - final SortedArraySet> tickets = this.tickets.get(chunk); -+ final SortedArraySet> tickets = data.tickets.get(chunk); // Paper - region threading ++ final SortedArraySet> tickets = data.tickets.get(chunk); // Folia - region threading tickets.removeIf(expireNow); if (tickets.isEmpty()) { - this.tickets.remove(chunk); -+ data.tickets.remove(chunk); // Paper - region threading ++ data.tickets.remove(chunk); // Folia - region threading this.ticketLevelPropagator.removeSource(chunk); } else { this.ticketLevelPropagator.setSource(chunk, convertBetweenTicketLevels(tickets.first().getTicketLevel())); @@ -2897,7 +2897,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + final int chunkZ = CoordinateUtils.getChunkZ(sectionKey) << regionShift; + + final List regionHolders = entry.getValue(); -+ this.taskScheduler.scheduleChunkTaskEventually(chunkX, chunkZ, () -> { // Paper - region threading ++ this.taskScheduler.scheduleChunkTaskEventually(chunkX, chunkZ, () -> { // Folia - region threading + ChunkHolderManager.this.getCurrentRegionData().pendingFullLoadUpdate.addAll(regionHolders); + ChunkHolderManager.this.processPendingFullUpdate(); + }, PrioritisedExecutor.Priority.HIGHEST); @@ -2914,9 +2914,9 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 holder.killed = true; holder.vanillaChunkHolder.onChunkRemove(); - this.autoSaveQueue.remove(holder); -+ // Paper - region threading ++ // Folia - region threading ChunkSystem.onChunkHolderDelete(this.world, holder.vanillaChunkHolder); -+ this.getCurrentRegionData().autoSaveQueue.remove(holder); // Paper - region threading ++ this.getCurrentRegionData().autoSaveQueue.remove(holder); // Folia - region threading this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ)); } @@ -2924,7 +2924,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 throw new IllegalStateException("Cannot hold scheduling lock while calling processUnloads"); } -+ final ChunkHolderManager.HolderManagerRegionData currentData = this.getCurrentRegionData(); // Paper - region threading ++ final ChunkHolderManager.HolderManagerRegionData currentData = this.getCurrentRegionData(); // Folia - region threading + final List unloadQueue; final List scheduleList = new ArrayList<>(); @@ -2932,12 +2932,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 try { this.taskScheduler.schedulingLock.lock(); try { -+ // Paper start - region threading ++ // Folia start - region threading + for (final NewChunkHolder special : currentData.specialCaseUnload) { + special.checkUnload(); + } + currentData.specialCaseUnload.clear(); -+ // Paper end - region threading ++ // Folia end - region threading if (this.unloadQueue.isEmpty()) { return; } @@ -2949,7 +2949,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 - final int unloadCount = Math.max(50, (int)(this.unloadQueue.size() * 0.05)); - for (int i = 0; i < unloadCount && !this.unloadQueue.isEmpty(); ++i) { - final NewChunkHolder chunkHolder = this.unloadQueue.removeFirst(); -+ // Paper start - region threading ++ // Folia start - region threading + final ArrayDeque toUnload = new ArrayDeque<>(); + // The unload queue is globally maintained, but we can only unload chunks in our region + for (final NewChunkHolder holder : this.unloadQueue) { @@ -2957,13 +2957,13 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 + toUnload.add(holder); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + -+ final int unloadCount = Math.max(50, (int)(toUnload.size() * 0.05)); // Paper - region threading -+ unloadQueue = new ArrayList<>(unloadCount + 1); // Paper - region threading -+ for (int i = 0; i < unloadCount && !toUnload.isEmpty(); ++i) { // Paper - region threading -+ final NewChunkHolder chunkHolder = toUnload.removeFirst(); // Paper - region threading -+ this.unloadQueue.remove(chunkHolder); // Paper - region threading ++ final int unloadCount = Math.max(50, (int)(toUnload.size() * 0.05)); // Folia - region threading ++ unloadQueue = new ArrayList<>(unloadCount + 1); // Folia - region threading ++ for (int i = 0; i < unloadCount && !toUnload.isEmpty(); ++i) { // Folia - region threading ++ final NewChunkHolder chunkHolder = toUnload.removeFirst(); // Folia - region threading ++ this.unloadQueue.remove(chunkHolder); // Folia - region threading if (chunkHolder.isSafeToUnload() != null) { LOGGER.error("Chunkholder " + chunkHolder + " is not safe to unload but is inside the unload queue?"); continue; @@ -2997,7 +2997,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 private JsonObject getDebugJsonNoLock() { final JsonObject ret = new JsonObject(); - ret.addProperty("current_tick", Long.valueOf(this.currentTick)); -+ // Paper - region threading - move down ++ // Folia - region threading - move down final JsonArray unloadQueue = new JsonArray(); ret.add("unload_queue", unloadQueue); @@ -3007,7 +3007,7 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 - final JsonArray removeTickToChunkExpireTicketCount = new JsonArray(); - ret.add("remove_tick_to_chunk_expire_ticket_count", removeTickToChunkExpireTicketCount); -+ // Paper start - region threading ++ // Folia start - region threading + final JsonArray regions = new JsonArray(); + ret.add("regions", regions); + this.world.regioniser.computeForAllRegionsUnsynchronised((region) -> { @@ -3109,12 +3109,12 @@ index c6d20bc2f0eab737338db6b88dacb63f0decb66c..8f44efc736055aaf85e4f9068618e911 } - } + }); -+ // Paper end - region threading ++ // Folia end - region threading return ret; } diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java -index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed928760a81 100644 +index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..93b666893a9755e426701f5c2849fc0fb2026bb7 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java @@ -113,7 +113,7 @@ public final class ChunkTaskScheduler { @@ -3122,7 +3122,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 public final PrioritisedThreadPool.PrioritisedPoolExecutor loadExecutor; - private final PrioritisedThreadedTaskQueue mainThreadExecutor = new PrioritisedThreadedTaskQueue(); -+ // Paper - regionised ticking ++ // Folia - regionised ticking final ReentrantLock schedulingLock = new ReentrantLock(); public final ChunkHolderManager chunkHolderManager; @@ -3131,7 +3131,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 // this may not be good enough, specifically thanks to stupid ass plugins swallowing exceptions - this.scheduleChunkTask(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); -+ this.scheduleChunkTaskEventually(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); // Paper - region threading ++ this.scheduleChunkTaskEventually(chunkX, chunkZ, crash, PrioritisedExecutor.Priority.BLOCKING); // Folia - region threading // so, make the main thread pick it up MinecraftServer.chunkSystemCrash = new RuntimeException("Chunk system crash propagated from unrecoverableChunkSystemFailure", reportedException); } @@ -3139,7 +3139,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 public boolean executeMainThreadTask() { - TickThread.ensureTickThread("Cannot execute main thread task off-main"); - return this.mainThreadExecutor.executeTask(); -+ throw new UnsupportedOperationException("Use regionised ticking hooks"); // Paper - regionised ticking ++ throw new UnsupportedOperationException("Use regionised ticking hooks"); // Folia - regionised ticking } public void raisePriority(final int x, final int z, final PrioritisedExecutor.Priority priority) { @@ -3156,7 +3156,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 }); } -+ // Paper start - region threading ++ // Folia start - region threading + // only appropriate to use with ServerLevel#syncLoadNonFull + public boolean beginChunkLoadForNonFullSync(final int chunkX, final int chunkZ, final ChunkStatus toStatus, + final PrioritisedExecutor.Priority priority) { @@ -3195,7 +3195,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 + + return true; + } -+ // Paper end - region threading ++ // Folia end - region threading + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { @@ -3238,7 +3238,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 @Deprecated public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run) { - return this.scheduleChunkTask(run, PrioritisedExecutor.Priority.NORMAL); -+ throw new UnsupportedOperationException(); // Paper - regionised ticking ++ throw new UnsupportedOperationException(); // Folia - regionised ticking } /** @@ -3247,7 +3247,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 @Deprecated public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final Runnable run, final PrioritisedExecutor.Priority priority) { - return this.mainThreadExecutor.queueRunnable(run, priority); -+ throw new UnsupportedOperationException(); // Paper - regionised ticking ++ throw new UnsupportedOperationException(); // Folia - regionised ticking } public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run) { @@ -3256,7 +3256,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 public PrioritisedExecutor.PrioritisedTask createChunkTask(final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { - return this.mainThreadExecutor.createTask(run, priority); -+ return MinecraftServer.getServer().regionisedServer.taskQueue.createChunkTask(this.world, chunkX, chunkZ, run, priority); // Paper - regionised ticking ++ return MinecraftServer.getServer().regionisedServer.taskQueue.createChunkTask(this.world, chunkX, chunkZ, run, priority); // Folia - regionised ticking } public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run) { @@ -3267,7 +3267,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 public PrioritisedExecutor.PrioritisedTask scheduleChunkTask(final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { - return this.mainThreadExecutor.queueRunnable(run, priority); -+ return MinecraftServer.getServer().regionisedServer.taskQueue.queueChunkTask(this.world, chunkX, chunkZ, run, priority); // Paper - regionised ticking ++ return MinecraftServer.getServer().regionisedServer.taskQueue.queueChunkTask(this.world, chunkX, chunkZ, run, priority); // Folia - regionised ticking } - public void executeTasksUntil(final BooleanSupplier exit) { @@ -3279,7 +3279,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 - counter = ConcurrentUtil.linearLongBackoff(counter, 100_000L, 5_000_000L); // 100us, 5ms - } - } -+ // Paper start - region threading ++ // Folia start - region threading + // this function is guaranteed to never touch the ticket lock or schedule lock + // yes, this IS a hack so that we can avoid deadlock due to region threading introducing the + // ticket lock in the schedule logic @@ -3291,9 +3291,9 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 + }); + return ret; } -+ // Paper end - region threading ++ // Folia end - region threading + -+ // Paper - regionised ticking ++ // Folia - regionised ticking public boolean halt(final boolean sync, final long maxWaitNS) { this.lightExecutor.halt(); @@ -3306,7 +3306,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..b3ae296cdf3f81550e2cc4d9516f4ed9 if ( !this.lightExecutor.isActive() && diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java -index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f067860ec0 100644 +index 8013dd333e27aa5fd0beb431fa32491eec9f5246..3b70ccd8e0b1ada943f57faf99c23b2935249cf6 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java +++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java @@ -708,7 +708,7 @@ public final class NewChunkHolder { @@ -3314,7 +3314,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f0 // must hold scheduling lock - private void checkUnload() { -+ void checkUnload() { // Paper - region threading ++ void checkUnload() { // Folia - region threading if (this.killed) { return; } @@ -3323,7 +3323,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f0 // must be scheduled to main, we do not trust the callback to not do anything stupid - this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { -+ this.scheduler.scheduleChunkTaskEventually(this.chunkX, this.chunkZ, () -> { // Paper - region threading ++ this.scheduler.scheduleChunkTaskEventually(this.chunkX, this.chunkZ, () -> { // Folia - region threading for (final Consumer consumer : consumers) { try { consumer.accept(chunk); @@ -3332,7 +3332,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f0 // must be scheduled to main, we do not trust the callback to not do anything stupid - this.scheduler.scheduleChunkTask(this.chunkX, this.chunkZ, () -> { -+ this.scheduler.scheduleChunkTaskEventually(this.chunkX, this.chunkZ, () -> { // Paper - region threading ++ this.scheduler.scheduleChunkTaskEventually(this.chunkX, this.chunkZ, () -> { // Folia - region threading for (final Consumer consumer : consumers) { try { consumer.accept(chunk); @@ -3341,7 +3341,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f0 } - public long lastAutoSave; -+ public long lastAutoSave; // Paper - region threaded - change to relative delay ++ public long lastAutoSave; // Folia - region threaded - change to relative delay public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} @@ -3373,7 +3373,7 @@ index 8013dd333e27aa5fd0beb431fa32491eec9f5246..63d2cec73e2bcf7031cdb5dfca8151f0 return true; diff --git a/src/main/java/io/papermc/paper/command/PaperCommands.java b/src/main/java/io/papermc/paper/command/PaperCommands.java -index d31b5ed47cffc61c90c926a0cd2005b72ebddfc5..e22632ba0d84c796a9bab3a1a9c43d5e5dcf73e8 100644 +index d31b5ed47cffc61c90c926a0cd2005b72ebddfc5..b07a41fe1a58c2af048d2341ea0db306bcbb8b52 100644 --- a/src/main/java/io/papermc/paper/command/PaperCommands.java +++ b/src/main/java/io/papermc/paper/command/PaperCommands.java @@ -17,7 +17,8 @@ public final class PaperCommands { @@ -3381,48 +3381,48 @@ index d31b5ed47cffc61c90c926a0cd2005b72ebddfc5..e22632ba0d84c796a9bab3a1a9c43d5e static { COMMANDS.put("paper", new PaperCommand("paper")); - COMMANDS.put("mspt", new MSPTCommand("mspt")); -+ COMMANDS.put("tpa", new io.papermc.paper.threadedregions.commands.CommandsTPA()); // Paper - region threading -+ COMMANDS.put("tps", new io.papermc.paper.threadedregions.commands.CommandServerHealth()); // Paper - region threading ++ COMMANDS.put("tpa", new io.papermc.paper.threadedregions.commands.CommandsTPA()); // Folia - region threading ++ COMMANDS.put("tps", new io.papermc.paper.threadedregions.commands.CommandServerHealth()); // Folia - region threading } public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/io/papermc/paper/command/subcommands/HeapDumpCommand.java b/src/main/java/io/papermc/paper/command/subcommands/HeapDumpCommand.java -index cd2e4d792e972b8bf1e07b8961594a670ae949cf..645fe0d8d6d301fcb7897f9162fac8971bc6abbe 100644 +index cd2e4d792e972b8bf1e07b8961594a670ae949cf..6c24e8567d303db35328fe4f0a7b05df16f3590a 100644 --- a/src/main/java/io/papermc/paper/command/subcommands/HeapDumpCommand.java +++ b/src/main/java/io/papermc/paper/command/subcommands/HeapDumpCommand.java @@ -18,7 +18,9 @@ import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; public final class HeapDumpCommand implements PaperSubcommand { @Override public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading this.dumpHeap(sender); -+ }); // Paper - region threading ++ }); // Folia - region threading return true; } diff --git a/src/main/java/io/papermc/paper/command/subcommands/ReloadCommand.java b/src/main/java/io/papermc/paper/command/subcommands/ReloadCommand.java -index bd68139ae635f2ad7ec8e7a21e0056a139c4c62e..872b59bccddf2adc7bce4bec5ecdcf5f0a0f0815 100644 +index bd68139ae635f2ad7ec8e7a21e0056a139c4c62e..0f641ac581243db55a667ad8bc5d1110206b389e 100644 --- a/src/main/java/io/papermc/paper/command/subcommands/ReloadCommand.java +++ b/src/main/java/io/papermc/paper/command/subcommands/ReloadCommand.java @@ -16,7 +16,9 @@ import static net.kyori.adventure.text.format.NamedTextColor.RED; public final class ReloadCommand implements PaperSubcommand { @Override public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading this.doReload(sender); -+ }); // Paper - region threading ++ }); // Folia - region threading return true; } diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 9f5f0d8ddc8f480b48079c70e38c9c08eff403f6..1d0e1311de8dafd42070edea40b1990c04eb7746 100644 +index 9f5f0d8ddc8f480b48079c70e38c9c08eff403f6..3b83f25a24d6f9cdbf131d5a4432fb4ad018be4e 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -288,6 +288,18 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean strictAdvancementDimensionCheck = false; } -+ // Paper start - threaded regions ++ // Folia start - threaded regions + public ThreadedRegions threadedRegions; + public class ThreadedRegions extends Post { + @@ -3433,7 +3433,7 @@ index 9f5f0d8ddc8f480b48079c70e38c9c08eff403f6..1d0e1311de8dafd42070edea40b1990c + io.papermc.paper.threadedregions.TickRegions.init(this); + } + } -+ // Paper end - threaded regions ++ // Folia end - threaded regions public ChunkLoadingBasic chunkLoadingBasic; public class ChunkLoadingBasic extends ConfigurationPart { @@ -8862,7 +8862,7 @@ index 0000000000000000000000000000000000000000..f220176831ff7030f00620b020fef9e0 + } +} diff --git a/src/main/java/io/papermc/paper/util/CachedLists.java b/src/main/java/io/papermc/paper/util/CachedLists.java -index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd4294b9bb274 100644 +index e08f4e39db4ee3fed62e37364d17dcc5c5683504..03d239460a2e856c1f59d6bcd95811c8e4e0cf6d 100644 --- a/src/main/java/io/papermc/paper/util/CachedLists.java +++ b/src/main/java/io/papermc/paper/util/CachedLists.java @@ -9,49 +9,57 @@ import java.util.List; @@ -8871,11 +8871,11 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 // Paper start - optimise collisions - static final UnsafeList TEMP_COLLISION_LIST = new UnsafeList<>(1024); - static boolean tempCollisionListInUse; -+ // Paper - region threading ++ // Folia - region threading public static UnsafeList getTempCollisionList() { - if (!Bukkit.isPrimaryThread() || tempCollisionListInUse) { -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); + if (worldData == null) { return new UnsafeList<>(16); @@ -8883,12 +8883,12 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 - tempCollisionListInUse = true; - return TEMP_COLLISION_LIST; + return worldData.tempCollisionList.get(); -+ // Paper end - region threading ++ // Folia end - region threading } public static void returnTempCollisionList(List list) { - if (list != TEMP_COLLISION_LIST) { -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); + if (worldData == null) { return; @@ -8896,16 +8896,16 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 - ((UnsafeList)list).setSize(0); - tempCollisionListInUse = false; + worldData.tempCollisionList.ret(list); -+ // Paper end - region threading ++ // Folia end - region threading } - static final UnsafeList TEMP_GET_ENTITIES_LIST = new UnsafeList<>(1024); - static boolean tempGetEntitiesListInUse; -+ // Paper - region threading ++ // Folia - region threading public static UnsafeList getTempGetEntitiesList() { - if (!Bukkit.isPrimaryThread() || tempGetEntitiesListInUse) { -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); + if (worldData == null) { return new UnsafeList<>(16); @@ -8913,12 +8913,12 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 - tempGetEntitiesListInUse = true; - return TEMP_GET_ENTITIES_LIST; + return worldData.tempEntitiesList.get(); -+ // Paper end - region threading ++ // Folia end - region threading } public static void returnTempGetEntitiesList(List list) { - if (list != TEMP_GET_ENTITIES_LIST) { -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); + if (worldData == null) { return; @@ -8926,7 +8926,7 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 - ((UnsafeList)list).setSize(0); - tempGetEntitiesListInUse = false; + worldData.tempEntitiesList.ret(list); -+ // Paper end - region threading ++ // Folia end - region threading } // Paper end - optimise collisions @@ -8935,12 +8935,12 @@ index e08f4e39db4ee3fed62e37364d17dcc5c5683504..d849ea4ad40b3bac3d1add263c1cd429 - TEMP_COLLISION_LIST.completeReset(); - TEMP_GET_ENTITIES_LIST.completeReset(); - // Paper end - optimise collisions -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); + if (worldData != null) { + worldData.resetCollisionLists(); + } -+ // Paper end - region threading ++ // Folia end - region threading } } diff --git a/src/main/java/io/papermc/paper/util/CoordinateUtils.java b/src/main/java/io/papermc/paper/util/CoordinateUtils.java @@ -8988,7 +8988,7 @@ index 413e4b6da027876dbbe8eb78f2568a440f431547..d29a4a3bab456df99fbccddc832a9ac2 throw new RuntimeException(); } diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index 6898c704e60d89d53c8ed114e5e12f73ed63605a..34f8a98f9e299a0c173f6b57bed54768251baaca 100644 +index 6898c704e60d89d53c8ed114e5e12f73ed63605a..594ada3cdec25784c7bd6abb9ad42d3f1e2bd733 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java @@ -28,6 +28,7 @@ import net.minecraft.world.level.ClipContext; @@ -9003,7 +9003,7 @@ index 6898c704e60d89d53c8ed114e5e12f73ed63605a..34f8a98f9e299a0c173f6b57bed54768 */ public static void ensureMain(String reason, Runnable run) { if (!isMainThread()) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading if (reason != null) { MinecraftServer.LOGGER.warn("Asynchronous " + reason + "!", new IllegalStateException()); } @@ -9011,7 +9011,7 @@ index 6898c704e60d89d53c8ed114e5e12f73ed63605a..34f8a98f9e299a0c173f6b57bed54768 return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); } -+ // Paper start - TODO MERGE INTO MCUTIL ++ // Folia start - TODO MERGE INTO MCUTIL + /** + * Converts a NMS World/Vector to Bukkit Location + * @param world @@ -9033,7 +9033,7 @@ index 6898c704e60d89d53c8ed114e5e12f73ed63605a..34f8a98f9e299a0c173f6b57bed54768 + public static Location toLocation(Level world, Vec3 pos, float yaw, float pitch) { + return new Location(world.getWorld(), pos.x(), pos.y(), pos.z(), yaw, pitch); + } -+ // Paper end - TODO MERGE INTO MCUTIL ++ // Folia end - TODO MERGE INTO MCUTIL + /** * Converts an NMS entity's current location to a Bukkit Location @@ -9441,7 +9441,7 @@ index 0000000000000000000000000000000000000000..cf9b66afc1762dbe2c625f09f9e804ca + } +} diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index ae5dd08de75a7ed231295f306fd0974da3988249..79aa36ec0e8b78787db2428f96913cb7f80c79d3 100644 +index ae5dd08de75a7ed231295f306fd0974da3988249..0674c69e7180c482bcace9797af877e09263e88b 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java @@ -66,7 +66,7 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy @@ -9449,12 +9449,12 @@ index ae5dd08de75a7ed231295f306fd0974da3988249..79aa36ec0e8b78787db2428f96913cb7 public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) { this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> { - }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(server)); -+ }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate((Runnable run) -> { io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(run);})); // Paper - region threading ++ }, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate((Runnable run) -> { io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(run);})); // Folia - region threading } protected CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity, boolean silent, @Nullable ResultConsumer consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext signedArguments, TaskChainer messageChainTaskQueue) { diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 330f6c79417378da855326b4da665f9d240e748d..47f3c31db4bb80cbecc3c26ec56caad91c41f3a6 100644 +index 330f6c79417378da855326b4da665f9d240e748d..22f06033a731c3ba1b815842be7a9d575fa820f2 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -139,12 +139,12 @@ public class Commands { @@ -9462,16 +9462,16 @@ index 330f6c79417378da855326b4da665f9d240e748d..47f3c31db4bb80cbecc3c26ec56caad9 AttributeCommand.register(this.dispatcher, commandRegistryAccess); ExecuteCommand.register(this.dispatcher, commandRegistryAccess); - BossBarCommands.register(this.dispatcher); -+ //BossBarCommands.register(this.dispatcher); // Paper - region threading - TODO ++ //BossBarCommands.register(this.dispatcher); // Folia - region threading - TODO ClearInventoryCommands.register(this.dispatcher, commandRegistryAccess); - CloneCommands.register(this.dispatcher, commandRegistryAccess); - DataCommands.register(this.dispatcher); - DataPackCommand.register(this.dispatcher); - DebugCommand.register(this.dispatcher); -+ //CloneCommands.register(this.dispatcher, commandRegistryAccess); // Paper - region threading - TODO -+ //DataCommands.register(this.dispatcher); // Paper - region threading - TODO -+ //DataPackCommand.register(this.dispatcher); // Paper - region threading - TODO -+ //DebugCommand.register(this.dispatcher); // Paper - region threading - TODO ++ //CloneCommands.register(this.dispatcher, commandRegistryAccess); // Folia - region threading - TODO ++ //DataCommands.register(this.dispatcher); // Folia - region threading - TODO ++ //DataPackCommand.register(this.dispatcher); // Folia - region threading - TODO ++ //DebugCommand.register(this.dispatcher); // Folia - region threading - TODO DefaultGameModeCommands.register(this.dispatcher); DifficultyCommand.register(this.dispatcher); EffectCommands.register(this.dispatcher, commandRegistryAccess); @@ -9480,56 +9480,56 @@ index 330f6c79417378da855326b4da665f9d240e748d..47f3c31db4bb80cbecc3c26ec56caad9 FillBiomeCommand.register(this.dispatcher, commandRegistryAccess); ForceLoadCommand.register(this.dispatcher); - FunctionCommand.register(this.dispatcher); -+ //FunctionCommand.register(this.dispatcher); // Paper - region threading - TODO ++ //FunctionCommand.register(this.dispatcher); // Folia - region threading - TODO GameModeCommand.register(this.dispatcher); GameRuleCommand.register(this.dispatcher); GiveCommand.register(this.dispatcher, commandRegistryAccess); HelpCommand.register(this.dispatcher); - ItemCommands.register(this.dispatcher, commandRegistryAccess); -+ //ItemCommands.register(this.dispatcher, commandRegistryAccess); // Paper - region threading - TODO later ++ //ItemCommands.register(this.dispatcher, commandRegistryAccess); // Folia - region threading - TODO later KickCommand.register(this.dispatcher); KillCommand.register(this.dispatcher); ListPlayersCommand.register(this.dispatcher); LocateCommand.register(this.dispatcher, commandRegistryAccess); - LootCommand.register(this.dispatcher, commandRegistryAccess); -+ //LootCommand.register(this.dispatcher, commandRegistryAccess); // Paper - region threading - TODO later ++ //LootCommand.register(this.dispatcher, commandRegistryAccess); // Folia - region threading - TODO later MsgCommand.register(this.dispatcher); ParticleCommand.register(this.dispatcher, commandRegistryAccess); PlaceCommand.register(this.dispatcher); PlaySoundCommand.register(this.dispatcher); - ReloadCommand.register(this.dispatcher); -+ //ReloadCommand.register(this.dispatcher); // Paper - region threading ++ //ReloadCommand.register(this.dispatcher); // Folia - region threading RecipeCommand.register(this.dispatcher); SayCommand.register(this.dispatcher); - ScheduleCommand.register(this.dispatcher); - ScoreboardCommand.register(this.dispatcher); -+ //ScheduleCommand.register(this.dispatcher); // Paper - region threading -+ //ScoreboardCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //ScheduleCommand.register(this.dispatcher); // Folia - region threading ++ //ScoreboardCommand.register(this.dispatcher); // Folia - region threading - TODO later SeedCommand.register(this.dispatcher, environment != Commands.CommandSelection.INTEGRATED); SetBlockCommand.register(this.dispatcher, commandRegistryAccess); SetSpawnCommand.register(this.dispatcher); SetWorldSpawnCommand.register(this.dispatcher); - SpectateCommand.register(this.dispatcher); - SpreadPlayersCommand.register(this.dispatcher); -+ //SpectateCommand.register(this.dispatcher); // Paper - region threading - TODO later -+ //SpreadPlayersCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //SpectateCommand.register(this.dispatcher); // Folia - region threading - TODO later ++ //SpreadPlayersCommand.register(this.dispatcher); // Folia - region threading - TODO later StopSoundCommand.register(this.dispatcher); SummonCommand.register(this.dispatcher, commandRegistryAccess); - TagCommand.register(this.dispatcher); - TeamCommand.register(this.dispatcher); - TeamMsgCommand.register(this.dispatcher); -+ //TagCommand.register(this.dispatcher); // Paper - region threading - TODO later -+ //TeamCommand.register(this.dispatcher); // Paper - region threading - TODO later -+ //TeamMsgCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //TagCommand.register(this.dispatcher); // Folia - region threading - TODO later ++ //TeamCommand.register(this.dispatcher); // Folia - region threading - TODO later ++ //TeamMsgCommand.register(this.dispatcher); // Folia - region threading - TODO later TeleportCommand.register(this.dispatcher); TellRawCommand.register(this.dispatcher); TimeCommand.register(this.dispatcher); TitleCommand.register(this.dispatcher); - TriggerCommand.register(this.dispatcher); -+ //TriggerCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later WeatherCommand.register(this.dispatcher); - WorldBorderCommand.register(this.dispatcher); -+ //WorldBorderCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //WorldBorderCommand.register(this.dispatcher); // Folia - region threading - TODO later if (JvmProfiler.INSTANCE.isAvailable()) { JfrCommand.register(this.dispatcher); } @@ -9539,8 +9539,8 @@ index 330f6c79417378da855326b4da665f9d240e748d..47f3c31db4bb80cbecc3c26ec56caad9 PardonIpCommand.register(this.dispatcher); - PerfCommand.register(this.dispatcher); - SaveAllCommand.register(this.dispatcher); -+ //PerfCommand.register(this.dispatcher); // Paper - region threading - TODO later -+ //SaveAllCommand.register(this.dispatcher); // Paper - region threading - TODO later ++ //PerfCommand.register(this.dispatcher); // Folia - region threading - TODO later ++ //SaveAllCommand.register(this.dispatcher); // Folia - region threading - TODO later SaveOffCommand.register(this.dispatcher); SaveOnCommand.register(this.dispatcher); SetPlayerIdleTimeoutCommand.register(this.dispatcher); @@ -9551,17 +9551,17 @@ index 330f6c79417378da855326b4da665f9d240e748d..47f3c31db4bb80cbecc3c26ec56caad9 - net.minecraft.server.MinecraftServer.getServer().execute(() -> { - runSync(player, bukkit, rootcommandnode); - }); -+ // Paper start - region threading ++ // Folia start - region threading + // ignore if retired + player.getBukkitEntity().taskScheduler.schedule((updatedPlayer) -> { + runSync((ServerPlayer)updatedPlayer, bukkit, rootcommandnode); + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading } private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { diff --git a/src/main/java/net/minecraft/core/dispenser/AbstractProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/AbstractProjectileDispenseBehavior.java -index 309ad5a1da6b3a297d5526cd9247359ac5f49406..6690e72c2f2ef39f1b127f5459b3991d16c69087 100644 +index 309ad5a1da6b3a297d5526cd9247359ac5f49406..5a85fcbcd2966af95683106d4f459653983a28e6 100644 --- a/src/main/java/net/minecraft/core/dispenser/AbstractProjectileDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/AbstractProjectileDispenseBehavior.java @@ -33,7 +33,7 @@ public abstract class AbstractProjectileDispenseBehavior extends DefaultDispense @@ -9569,12 +9569,12 @@ index 309ad5a1da6b3a297d5526cd9247359ac5f49406..6690e72c2f2ef39f1b127f5459b3991d BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) enumdirection.getStepX(), (double) ((float) enumdirection.getStepY() + 0.1F), (double) enumdirection.getStepZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -index 958134519befadc27a5b647caf64acf272ee2db4..81a4c04a512d152ba96b347bbc612af9924cb373 100644 +index 958134519befadc27a5b647caf64acf272ee2db4..a0712ad55c8e02a88ddf55bb0e70e05dc1ddbcdc 100644 --- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java @@ -58,7 +58,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { @@ -9582,12 +9582,12 @@ index 958134519befadc27a5b647caf64acf272ee2db4..81a4c04a512d152ba96b347bbc612af9 BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java -index 1e6ba6d9cceda1d4867b183c3dbc03d317ed287f..4d11d80dc3df7ff439d11155f8eb23feadea8b68 100644 +index 1e6ba6d9cceda1d4867b183c3dbc03d317ed287f..de8cf0f0d34708b960f1c81cb10d813a797df02b 100644 --- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java @@ -74,7 +74,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior { @@ -9595,12 +9595,12 @@ index 1e6ba6d9cceda1d4867b183c3dbc03d317ed287f..4d11d80dc3df7ff439d11155f8eb23fe BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), CraftVector.toBukkit(entityitem.getDeltaMovement())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading world.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc1493df54 100644 +index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..28a260dfe6ba9f7e9ff161562dcb87a6314af87c 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -221,7 +221,7 @@ public interface DispenseItemBehavior { @@ -9608,7 +9608,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9617,7 +9617,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9626,7 +9626,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) list.get(0).getBukkitEntity()); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading world.getCraftServer().getPluginManager().callEvent(event); } @@ -9635,7 +9635,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityhorseabstract.getBukkitEntity()); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading world.getCraftServer().getPluginManager().callEvent(event); } @@ -9644,7 +9644,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityhorsechestedabstract.getBukkitEntity()); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading world.getCraftServer().getPluginManager().callEvent(event); } @@ -9653,7 +9653,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(enumdirection.getStepX(), enumdirection.getStepY(), enumdirection.getStepZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9662,7 +9662,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9671,7 +9671,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9680,7 +9680,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9689,7 +9689,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9698,7 +9698,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9707,8 +9707,8 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc } - worldserver.captureTreeGeneration = true; -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = worldserver.getCurrentWorldData(); // Paper - region threading -+ worldData.captureTreeGeneration = true; // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = worldserver.getCurrentWorldData(); // Folia - region threading ++ worldData.captureTreeGeneration = true; // Folia - region threading // CraftBukkit end if (!BoneMealItem.growCrop(stack, worldserver, blockposition) && !BoneMealItem.growWaterPlant(stack, worldserver, blockposition, (Direction) null)) { @@ -9718,15 +9718,15 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc // CraftBukkit start - worldserver.captureTreeGeneration = false; - if (worldserver.capturedBlockStates.size() > 0) { -+ worldData.captureTreeGeneration = false; // Paper - region threading -+ if (worldData.capturedBlockStates.size() > 0) { // Paper - region threading ++ worldData.captureTreeGeneration = false; // Folia - region threading ++ if (worldData.capturedBlockStates.size() > 0) { // Folia - region threading TreeType treeType = SaplingBlock.treeType; SaplingBlock.treeType = null; Location location = new Location(worldserver.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); - List blocks = new java.util.ArrayList<>(worldserver.capturedBlockStates.values()); - worldserver.capturedBlockStates.clear(); -+ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading StructureGrowEvent structureEvent = null; if (treeType != null) { structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); @@ -9735,7 +9735,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9744,7 +9744,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9753,7 +9753,7 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } @@ -9762,12 +9762,12 @@ index 58fa7b99dc7a9745afe6faf31c1804e95ed27dbe..694cdd790fb128c1648797dba314debc BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index d1127d93a85a837933d0d73c24cacac4adc3a5b9..536e0b75f70ba93e73c9cad92252aa86e248be77 100644 +index d1127d93a85a837933d0d73c24cacac4adc3a5b9..ac9f4f2ac817e5fe9a15759c549a57ad8473b6ac 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -40,7 +40,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { @@ -9775,12 +9775,12 @@ index d1127d93a85a837933d0d73c24cacac4adc3a5b9..536e0b75f70ba93e73c9cad92252aa86 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java -index 0159ed9cbc644c39fa79e62327f13375193fdc98..ce86619e2d8a394df24d2ea7113b0f38e5859e62 100644 +index 0159ed9cbc644c39fa79e62327f13375193fdc98..a930c8eb64d6c7044646d6b0156e202ea334a1f9 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java @@ -37,7 +37,7 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { @@ -9788,12 +9788,12 @@ index 0159ed9cbc644c39fa79e62327f13375193fdc98..ce86619e2d8a394df24d2ea7113b0f38 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading pointer.getLevel().getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c44ec2e71 100644 +index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..5e74408bbdcc9b434447e3d9cf7523ef122ec03e 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -73,7 +73,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -9810,7 +9810,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c public boolean preparing = true; // Spigot End - private PacketListener packetListener; -+ private volatile PacketListener packetListener; // Paper - region threading ++ private volatile PacketListener packetListener; // Folia - region threading private Component disconnectedReason; private boolean encrypted; private boolean disconnectionHandled; @@ -9818,7 +9818,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c this.receiving = side; } -+ // Paper start - region threading ++ // Folia start - region threading + private volatile boolean becomeActive; + + public boolean becomeActive() { @@ -9842,7 +9842,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c + public final boolean isPlayerConnected() { + return this.packetListener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl; + } -+ // Paper end - region threading ++ // Folia end - region threading + public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { super.channelActive(channelhandlercontext); @@ -9851,7 +9851,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c Connection.LOGGER.error(LogUtils.FATAL_MARKER, "Failed to change protocol to handshake", throwable); } -+ this.becomeActive = true; // Paper - region threading ++ this.becomeActive = true; // Folia - region threading } public void setProtocol(ConnectionProtocol state) { @@ -9983,7 +9983,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c - if (Connection.currTick != net.minecraft.server.MinecraftServer.currentTick) { - Connection.currTick = net.minecraft.server.MinecraftServer.currentTick; - Connection.joinAttemptsThisTick = 0; -+ // Paper start - region threading ++ // Folia start - region threading + // handle disconnect requests, but only after flushQueue() + DisconnectReq disconnectReq; + while ((disconnectReq = this.disconnectReqs.poll()) != null) { @@ -10010,8 +10010,8 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c + this.handleDisconnection(); + return; + } -+ // Paper end - region threading -+ // Paper - this is broken ++ // Folia end - region threading ++ // Folia - this is broken PacketListener packetlistener = this.packetListener; if (packetlistener instanceof TickablePacketListener) { @@ -10021,7 +10021,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c - if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener) - || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT - || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) { -+ if (true) { // Paper - region threading ++ if (true) { // Folia - region threading // Paper start - detailed watchdog information net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener); try { // Paper end - detailed watchdog information @@ -10054,7 +10054,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c this.channel.close(); // We can't wait as this may be called from an event loop. this.disconnectedReason = disconnectReason; } -+ this.becomeActive = true; // Paper - region threading ++ this.becomeActive = true; // Folia - region threading } @@ -10063,12 +10063,12 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(playerConnection.player.getUUID(), playerConnection.player.getScoreboardName(), ((java.net.InetSocketAddress)address).getAddress(), false).callEvent(); + // Note: It can be in the connection set if it is in ready to accept if handleAcceptedLogin fails -+ // Paper start - region threading ++ // Folia start - region threading + net.minecraft.server.MinecraftServer.getServer().getPlayerList().removeConnection( + playerConnection.player.getScoreboardName(), + playerConnection.player.getUUID(), this + ); -+ // Paper end - region threading ++ // Folia end - region threading } else if (packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl) { /* Player is login stage */ final net.minecraft.server.network.ServerLoginPacketListenerImpl loginListener = (net.minecraft.server.network.ServerLoginPacketListenerImpl) packetListener; @@ -10076,7 +10076,7 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c - case READY_TO_ACCEPT: - case DELAY_ACCEPT: - case ACCEPTED: -+ // Paper start - region threading ++ // Folia start - region threading + if (loginListener.state.ordinal() >= net.minecraft.server.network.ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT.ordinal()) { + // Note: It can be in the connection set if it is in ready to accept if handleAcceptedLogin fails + net.minecraft.server.MinecraftServer.getServer().getPlayerList().removeConnection( @@ -10085,13 +10085,13 @@ index 38c09c65dfa4a7a0c80d36f726c1fd028cbe05f8..e522c13a733aaf6228e981a9baecca8c + this + ); + } -+ // Paper end - region threading -+ if (loginListener.state.ordinal() >= net.minecraft.server.network.ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT.ordinal()) { // Paper - region threading - rewrite login process ++ // Folia end - region threading ++ if (loginListener.state.ordinal() >= net.minecraft.server.network.ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT.ordinal()) { // Folia - region threading - rewrite login process final com.mojang.authlib.GameProfile profile = loginListener.gameProfile; /* Should be non-null at this stage */ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(), profile.getName(), ((java.net.InetSocketAddress)address).getAddress(), false).callEvent(); diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index 27d4aa45e585842c04491839826d405d6f447f0e..6cec00f409e8d9b90aa0b238620d2b7dca61f86c 100644 +index 27d4aa45e585842c04491839826d405d6f447f0e..e6ef0691588fbb33d47692db4269c56557814c9b 100644 --- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java @@ -2,6 +2,7 @@ package net.minecraft.network.protocol; @@ -10107,7 +10107,7 @@ index 27d4aa45e585842c04491839826d405d6f447f0e..6cec00f409e8d9b90aa0b238620d2b7d public static void ensureRunningOnSameThread(Packet packet, T listener, BlockableEventLoop engine) throws RunningOnDifferentThreadException { if (!engine.isSameThread()) { - engine.execute(() -> { // Paper - Fix preemptive player kick on a server shutdown. -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading packetProcessing.push(listener); // Paper - detailed watchdog information try { // Paper - detailed watchdog information if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 @@ -10116,7 +10116,7 @@ index 27d4aa45e585842c04491839826d405d6f447f0e..6cec00f409e8d9b90aa0b238620d2b7d // Paper end - detailed watchdog information - }); -+ }; // Paper start - region threading ++ }; // Folia start - region threading + ServerGamePacketListenerImpl actualListener = (ServerGamePacketListenerImpl)listener; + // ignore retired state, if removed then we don't want the packet to be handled + actualListener.player.getBukkitEntity().taskScheduler.schedule( @@ -10126,12 +10126,12 @@ index 27d4aa45e585842c04491839826d405d6f447f0e..6cec00f409e8d9b90aa0b238620d2b7d + null, + 1L + ); -+ // Paper end - region threading ++ // Folia end - region threading throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD; // CraftBukkit start - SPIGOT-5477, MC-142590 } else if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137f5fec6ff 100644 +index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..9577b633ecf5ebd1ff5bf79aa6ea61160f59e764 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -291,7 +291,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public Commands vanillaCommandDispatcher; @@ -10148,13 +10148,13 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // Spigot end public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; - public static long currentTickLong = 0L; // Paper -+ //public static long currentTickLong = 0L; // Paper // Paper - threaded regions ++ //public static long currentTickLong = 0L; // Paper // Folia - threaded regions public volatile Thread shutdownThread; // Paper public volatile boolean abnormalExit = false; // Paper public boolean isIteratingOverLevels = false; // Paper -+ // Paper start - regionised ticking ++ // Folia start - regionised ticking + public final io.papermc.paper.threadedregions.RegionisedServer regionisedServer = new io.papermc.paper.threadedregions.RegionisedServer(); + + @Override @@ -10180,7 +10180,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + } + super.tell(runnable); + } -+ // Paper end - regionised ticking ++ // Folia end - regionised ticking + public static S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); @@ -10190,7 +10190,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified()); this.addLevel(world); // Paper - move up - this.initWorld(world, worlddata, worldData, worldoptions); -+ // Paper start - region threading ++ // Folia start - region threading + // the spawn should be within ~32 blocks, so we force add ticket levels to ensure the first thread + // to init spawn will not run into any ownership issues + // move init to start of tickServer @@ -10204,7 +10204,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + ); + } + } -+ // Paper end - region threading ++ // Folia end - region threading // Paper - move up this.getPlayerList().addWorldborderListener(world); @@ -10212,7 +10212,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.forceDifficulty(); for (ServerLevel worldserver : this.getAllLevels()) { this.prepareLevels(worldserver.getChunkSource().chunkMap.progressListener, worldserver); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addWorld(worldserver); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addWorld(worldserver); // Folia - region threading //worldserver.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - rewrite chunk system, not required to "tick" anything this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld())); } @@ -10221,7 +10221,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 } else { ServerChunkCache chunkproviderserver = world.getChunkSource(); - ChunkPos chunkcoordintpair = new ChunkPos(chunkproviderserver.randomState().sampler().findSpawnPosition()); -+ ChunkPos chunkcoordintpair = world.randomSpawnSelection; // Paper - region threading ++ ChunkPos chunkcoordintpair = world.randomSpawnSelection; // Folia - region threading // CraftBukkit start if (world.generator != null) { Random rand = new Random(world.getSeed()); @@ -10229,7 +10229,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 if (i < world.getMinBuildHeight()) { BlockPos blockposition = chunkcoordintpair.getWorldPosition(); -+ world.getChunk(blockposition.offset(8, 0, 8)); // Paper - region threading - sync load first ++ world.getChunk(blockposition.offset(8, 0, 8)); // Folia - region threading - sync load first i = world.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition.getX() + 8, blockposition.getZ() + 8); } @@ -10238,7 +10238,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // this.nextTickTime = SystemUtils.getMillis() + 10L; - this.executeModerately(); -+ //this.executeModerately(); // Paper - region threading ++ //this.executeModerately(); // Folia - region threading // Iterator iterator = this.levels.values().iterator(); } @@ -10247,7 +10247,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // CraftBukkit start // this.nextTickTime = SystemUtils.getMillis() + 10L; - this.executeModerately(); -+ //this.executeModerately(); // Paper - region threading ++ //this.executeModerately(); // Folia - region threading // CraftBukkit end if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper chunkproviderserver.getLightEngine().setTaskPerBatch(worldserver.paperConfig().misc.lightQueueSize); // Paper - increase light queue size @@ -10255,7 +10255,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 } // CraftBukkit end -+ // Paper start - region threading ++ // Folia start - region threading + private final java.util.concurrent.atomic.AtomicBoolean hasStartedShutdownThread = new java.util.concurrent.atomic.AtomicBoolean(); + + private void haltServerRegionThreading() { @@ -10271,10 +10271,10 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + throw new IllegalStateException(); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + public void stopServer() { -+ // Paper start - region threading ++ // Folia start - region threading + // halt scheduler + // don't wait, we may be on a scheduler thread + io.papermc.paper.threadedregions.TickRegions.getScheduler().halt(false, 0L); @@ -10285,7 +10285,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + return; + } // else: fall through to regular stop logic + } -+ // Paper end - region threading ++ // Folia end - region threading // CraftBukkit start - prevent double stopping on multiple threads synchronized(this.stopLock) { if (this.hasStopped) return; @@ -10294,7 +10294,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 shutdownThread = Thread.currentThread(); org.spigotmc.WatchdogThread.doStop(); // Paper - if (!isSameThread()) { -+ if (false && !isSameThread()) { // Paper - region threading ++ if (false && !isSameThread()) { // Folia - region threading MinecraftServer.LOGGER.info("Stopping main thread (Ignore any thread death message you see! - DO NOT REPORT THREAD DEATH TO PAPER)"); while (this.getRunningThread().isAlive()) { this.getRunningThread().stop(); @@ -10302,12 +10302,12 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets } -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + // the rest till part 2 is handled by the region shutdown thread + return; + } -+ // Paper end - region threading ++ // Folia end - region threading + MinecraftServer.LOGGER.info("Saving worlds"); Iterator iterator = this.getAllLevels().iterator(); @@ -10316,11 +10316,11 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.saveAllChunks(false, true, false, true); // Paper - rewrite chunk system - move closing into here this.isSaving = false; -+ // Paper start - region threading ++ // Folia start - region threading + this.stopPart2(); + } + public void stopPart2() { -+ // Paper end - region threading ++ // Folia end - region threading this.resources.close(); try { @@ -10328,7 +10328,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper // Paper end this.running = false; -+ this.stopServer(); // Paper - region threading ++ this.stopServer(); // Folia - region threading if (waitForShutdown) { try { this.serverThread.join(); @@ -10336,9 +10336,9 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.status.setEnforcesSecureChat(this.enforceSecureProfile()); this.updateStatusIcon(this.status); -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().init(); // Paper - region threading - only after loading worlds ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().init(); // Folia - region threading - only after loading worlds + String doneTime = String.format(java.util.Locale.ROOT, "%.3fs", (double) (Util.getNanos() - serverStartTime) / 1.0E9D); + LOGGER.info("Done ({})! For help, type \"help\"", doneTime); + for (;;) { @@ -10347,7 +10347,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + } catch (final InterruptedException ex) {} + } + } -+ // Paper end - region threading ++ // Folia end - region threading + // Spigot start // Paper start - move done tracking @@ -10358,8 +10358,8 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 - ++MinecraftServer.currentTickLong; // Paper - if ( ++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0 ) -+ //++MinecraftServer.currentTickLong; // Paper // Paper - threaded regions -+ if ( false ) // Paper - region threading ++ //++MinecraftServer.currentTickLong; // Paper // Folia - threaded regions ++ if ( false ) // Folia - region threading { final long diff = curTime - tickSection; java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP); @@ -10368,7 +10368,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.startMetricsRecordingTick(); this.profiler.push("tick"); - this.tickServer(this::haveTime); -+ this.tickServer(curTime, this.nextTickTime, 0L, null); // Paper - region threading ++ this.tickServer(curTime, this.nextTickTime, 0L, null); // Folia - region threading this.profiler.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); @@ -10376,7 +10376,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 @Override public boolean pollTask() { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading boolean flag = this.pollTaskInternal(); this.mayHaveDelayedTasks = flag; @@ -10384,7 +10384,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 } private boolean pollTaskInternal() { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading if (super.pollTask()) { this.executeMidTickTasks(); // Paper - execute chunk tasks mid tick return true; @@ -10392,7 +10392,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 } public void doRunTask(TickTask ticktask) { // CraftBukkit - decompile error -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading this.getProfiler().incrementCounter("runTask"); super.doRunTask(ticktask); } @@ -10401,7 +10401,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 public void onServerExit() {} - public void tickServer(BooleanSupplier shouldKeepTicking) { -+ // Paper start - region threading ++ // Folia start - region threading + public void tickServer(long startTime, long scheduledEnd, long targetBuffer, + io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { + if (region != null) { @@ -10409,7 +10409,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + if (region.world.checkInitialised.get() != ServerLevel.WORLD_INIT_CHECKED) { + synchronized (region.world.checkInitialised) { + if (region.world.checkInitialised.compareAndSet(ServerLevel.WORLD_INIT_NOT_CHECKED, ServerLevel.WORLD_INIT_CHECKING)) { -+ this.initWorld(region.world, region.world.serverLevelData, worldData, region.world.serverLevelData.worldGenOptions()); // Paper - delayed until first tick of world ++ this.initWorld(region.world, region.world.serverLevelData, worldData, region.world.serverLevelData.worldGenOptions()); // Folia - delayed until first tick of world + region.world.checkInitialised.set(ServerLevel.WORLD_INIT_CHECKED); + } // else: must be checked + } @@ -10419,24 +10419,24 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + return scheduledEnd - System.nanoTime() > targetBuffer; + }; + new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper -+ // Paper end - region threading ++ // Folia end - region threading co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper - long i = Util.getNanos(); -+ long i = startTime; // Paper - region threading ++ long i = startTime; // Folia - region threading // Paper start - move oversleep into full server tick -+ if (region == null) { // Paper - region threading ++ if (region == null) { // Folia - region threading isOversleep = true;MinecraftTimings.serverOversleep.startTiming(); this.managedBlock(() -> { return !this.canOversleep(); }); isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); -+ } // Paper - region threading ++ } // Folia - region threading // Paper end - new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper -+ // Paper - region threading - move up ++ // Folia - region threading - move up + -+ // Paper start - region threading ++ // Folia start - region threading + if (region != null) { + region.getTaskQueueData().drainTasks(); + // now run all the entity schedulers @@ -10451,15 +10451,15 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + } + } + // now tick connections -+ region.world.getCurrentWorldData().tickConnections(); // Paper - region threading ++ region.world.getCurrentWorldData().tickConnections(); // Folia - region threading + } -+ // Paper end - region threading ++ // Folia end - region threading ++this.tickCount; - this.tickChildren(shouldKeepTicking); - if (i - this.lastServerStatus >= 5000000000L) { -+ this.tickChildren(shouldKeepTicking, region); // Paper - region threading -+ if (region == null && i - this.lastServerStatus >= 5000000000L) { // Paper - region threading - moved to global tick ++ this.tickChildren(shouldKeepTicking, region); // Folia - region threading ++ if (region == null && i - this.lastServerStatus >= 5000000000L) { // Folia - region threading - moved to global tick this.lastServerStatus = i; this.status.setPlayers(new ServerStatus.Players(this.getMaxPlayers(), this.getPlayerCount())); if (!this.hidesOnlinePlayers()) { @@ -10468,10 +10468,10 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.playerList.saveAll(playerSaveInterval); } - for (ServerLevel level : this.getAllLevels()) { -+ for (ServerLevel level : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Paper - region threading ++ for (ServerLevel level : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Folia - region threading if (level.paperConfig().chunks.autoSaveInterval.value() > 0) { - level.saveIncrementally(fullSave); -+ level.saveIncrementally(region == null && fullSave); // Paper - region threading - don't save level.dat ++ level.saveIncrementally(region == null && fullSave); // Folia - region threading - don't save level.dat } } } finally { @@ -10480,7 +10480,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 io.papermc.paper.util.CachedLists.reset(); // Paper // Paper start - move executeAll() into full server tick timing - try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { -+ if (region == null) try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { // Paper - region threading ++ if (region == null) try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { // Folia - region threading this.runAllTasks(); } // Paper end @@ -10488,11 +10488,11 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 long endTime = System.nanoTime(); - long remaining = (TICK_TIME - (endTime - lastTick)) - catchupTime; - new com.destroystokyo.paper.event.server.ServerTickEndEvent(this.tickCount, ((double)(endTime - lastTick) / 1000000D), remaining).callEvent(); -+ long remaining = scheduledEnd - endTime; // Paper - region ticking -+ new com.destroystokyo.paper.event.server.ServerTickEndEvent(this.tickCount, ((double)(endTime - startTime) / 1000000D), remaining).callEvent(); // Paper - region ticking ++ long remaining = scheduledEnd - endTime; // Folia - region ticking ++ new com.destroystokyo.paper.event.server.ServerTickEndEvent(this.tickCount, ((double)(endTime - startTime) / 1000000D), remaining).callEvent(); // Folia - region ticking // Paper end this.profiler.push("tallying"); -+ if (region == null) { // Paper - region threading ++ if (region == null) { // Folia - region threading long l = this.tickTimes[this.tickCount % 100] = Util.getNanos() - i; this.averageTickTime = this.averageTickTime * 0.8F + (float) l / 1000000.0F * 0.19999999F; @@ -10500,22 +10500,22 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // Paper end this.frameTimer.logFrameDuration(i1 - i); -+ } // Paper - region threading ++ } // Folia - region threading this.profiler.pop(); org.spigotmc.WatchdogThread.tick(); // Spigot co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper } - public void tickChildren(BooleanSupplier shouldKeepTicking) { -+ public void tickChildren(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Paper - region threading ++ public void tickChildren(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - region threading MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper - this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit -+ if (region == null) this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit // Paper - region threading - TODO REPLACE CRAFT SCHEDULER ++ if (region == null) this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit // Folia - region threading - TODO REPLACE CRAFT SCHEDULER MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper this.profiler.push("commandFunctions"); MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper - this.getFunctions().tick(); -+ if (region == null) this.getFunctions().tick(); // Paper - region threading - TODO Purge functions ++ if (region == null) this.getFunctions().tick(); // Folia - region threading - TODO Purge functions MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper this.profiler.popPush("levels"); //Iterator iterator = this.getAllLevels().iterator(); // Paper - moved down @@ -10524,7 +10524,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // Run tasks that are waiting on processing MinecraftTimings.processQueueTimer.startTiming(); // Spigot - while (!this.processQueue.isEmpty()) { -+ if (region == null) while (!this.processQueue.isEmpty()) { // Paper - region threading ++ if (region == null) while (!this.processQueue.isEmpty()) { // Folia - region threading this.processQueue.remove().run(); } MinecraftTimings.processQueueTimer.stopTiming(); // Spigot @@ -10533,15 +10533,15 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 // Send time updates to everyone, it will get the right time from the world the player is in. // Paper start - optimize time updates - for (final ServerLevel world : this.getAllLevels()) { -+ for (final ServerLevel world : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Paper - region threading ++ for (final ServerLevel world : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Folia - region threading final boolean doDaylight = world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT); final long dayTime = world.getDayTime(); long worldTime = world.getGameTime(); final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight); - for (Player entityhuman : world.players()) { - if (!(entityhuman instanceof ServerPlayer) || (tickCount + entityhuman.getId()) % 20 != 0) { -+ for (Player entityhuman : world.getLocalPlayers()) { // Paper - region threading -+ if (!(entityhuman instanceof ServerPlayer) || ((region == null ? tickCount : region.getCurrentTick()) + entityhuman.getId()) % 20 != 0) { // Paper - region threading ++ for (Player entityhuman : world.getLocalPlayers()) { // Folia - region threading ++ if (!(entityhuman instanceof ServerPlayer) || ((region == null ? tickCount : region.getCurrentTick()) + entityhuman.getId()) % 20 != 0) { // Folia - region threading continue; } ServerPlayer entityplayer = (ServerPlayer) entityhuman; @@ -10551,14 +10551,14 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 - this.isIteratingOverLevels = true; // Paper - Iterator iterator = this.getAllLevels().iterator(); // Paper - move down -+ if (region == null) this.isIteratingOverLevels = true; // Paper // Paper - region threading -+ Iterator iterator = region == null ? this.getAllLevels().iterator() : Arrays.asList(region.world).iterator(); // Paper - move down // Paper - region threading ++ if (region == null) this.isIteratingOverLevels = true; // Paper // Folia - region threading ++ Iterator iterator = region == null ? this.getAllLevels().iterator() : Arrays.asList(region.world).iterator(); // Paper - move down // Folia - region threading while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); - worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper -+ // Paper - region threading ++ // Folia - region threading this.profiler.push(() -> { return worldserver + " " + worldserver.dimension().location(); @@ -10567,7 +10567,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 try { worldserver.timings.doTick.startTiming(); // Spigot - worldserver.tick(shouldKeepTicking); -+ worldserver.tick(shouldKeepTicking, region); // Paper - region threading ++ worldserver.tick(shouldKeepTicking, region); // Folia - region threading // Paper start for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) { regionManager.recalculateRegions(); @@ -10576,20 +10576,20 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 this.profiler.pop(); this.profiler.pop(); - worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions -+ //worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions // Paper - region threading ++ //worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions // Folia - region threading } - this.isIteratingOverLevels = false; // Paper -+ if (region == null) this.isIteratingOverLevels = false; // Paper // Paper - region threading ++ if (region == null) this.isIteratingOverLevels = false; // Paper // Folia - region threading this.profiler.popPush("connection"); MinecraftTimings.connectionTimer.startTiming(); // Spigot - this.getConnection().tick(); -+ if (region == null) this.getConnection().tick(); // Paper - region threading - moved into post entity scheduler tick ++ if (region == null) this.getConnection().tick(); // Folia - region threading - moved into post entity scheduler tick MinecraftTimings.connectionTimer.stopTiming(); // Spigot this.profiler.popPush("players"); MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper - this.playerList.tick(); -+ if (false) this.playerList.tick(); // Paper - region threading ++ if (false) this.playerList.tick(); // Folia - region threading MinecraftTimings.playerListTimer.stopTiming(); // Spigot // Paper if (SharedConstants.IS_RUNNING_IN_IDE) { GameTestTicker.SINGLETON.tick(); @@ -10598,7 +10598,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 MinecraftTimings.tickablesTimer.startTiming(); // Spigot // Paper - for (int i = 0; i < this.tickables.size(); ++i) { -+ if (region == null) for (int i = 0; i < this.tickables.size(); ++i) { // Paper - region threading - TODO WTF is this? ++ if (region == null) for (int i = 0; i < this.tickables.size(); ++i) { // Folia - region threading - TODO WTF is this? ((Runnable) this.tickables.get(i)).run(); } MinecraftTimings.tickablesTimer.stopTiming(); // Spigot // Paper @@ -10606,7 +10606,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 } public void invalidateStatus() { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + // we don't need this to notify the global tick region + io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTaskWithoutNotify(() -> { @@ -10614,7 +10614,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 + }); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading this.lastServerStatus = 0L; } @@ -10622,7 +10622,7 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 @Override public void executeIfPossible(Runnable runnable) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading if (this.isStopped()) { throw new RejectedExecutionException("Server already shutting down"); } else { @@ -10649,20 +10649,20 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 - executed = true; - } - } -+ // Paper - region threading ++ // Folia - region threading - return executed; -+ private boolean tickMidTickTasks(io.papermc.paper.threadedregions.RegionisedWorldData worldData) { // Paper - region threading -+ // Paper - region threading - only execute for one world ++ private boolean tickMidTickTasks(io.papermc.paper.threadedregions.RegionisedWorldData worldData) { // Folia - region threading ++ // Folia - region threading - only execute for one world + return worldData.world.getChunkSource().pollTask(); } public final void executeMidTickTasks() { org.spigotmc.AsyncCatcher.catchOp("mid tick chunk task execution"); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData(); // Folia - region threading long startTime = System.nanoTime(); - if ((startTime - lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) { -+ if ((startTime - worldData.lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - worldData.lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) { // Paper - region threading ++ if ((startTime - worldData.lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - worldData.lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) { // Folia - region threading // it's shown to be bad to constantly hit the queue (chunk loads slow to a crawl), even if no tasks are executed. // so, backoff to prevent this return; @@ -10671,14 +10671,14 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 try { for (;;) { - boolean moreTasks = this.tickMidTickTasks(); -+ boolean moreTasks = this.tickMidTickTasks(worldData); // Paper - region threading ++ boolean moreTasks = this.tickMidTickTasks(worldData); // Folia - region threading long currTime = System.nanoTime(); long diff = currTime - startTime; if (!moreTasks || diff >= MAX_CHUNK_EXEC_TIME) { if (!moreTasks) { - lastMidTickExecuteFailure = currTime; -+ worldData.lastMidTickExecuteFailure = currTime; // Paper - region threading ++ worldData.lastMidTickExecuteFailure = currTime; // Folia - region threading } // note: negative values reduce the time @@ -10687,12 +10687,12 @@ index 2ee4e5e8d17a3a1e6a342c74b13135df030ffef6..33b1cdd7c8d655a61868dd464303d137 long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME); - lastMidTickExecute = currTime + extraSleep; -+ worldData.lastMidTickExecute = currTime + extraSleep; // Paper - region threading ++ worldData.lastMidTickExecute = currTime + extraSleep; // Folia - region threading return; } } diff --git a/src/main/java/net/minecraft/server/commands/AdvancementCommands.java b/src/main/java/net/minecraft/server/commands/AdvancementCommands.java -index 147c256e794f3e579e70927329fd1905ad1b33af..837d7c1228a415240081a8218468974a582209b7 100644 +index 147c256e794f3e579e70927329fd1905ad1b33af..10f3c46334c77241f3cb6bbd833b381d7e68d527 100644 --- a/src/main/java/net/minecraft/server/commands/AdvancementCommands.java +++ b/src/main/java/net/minecraft/server/commands/AdvancementCommands.java @@ -61,7 +61,11 @@ public class AdvancementCommands { @@ -10700,10 +10700,10 @@ index 147c256e794f3e579e70927329fd1905ad1b33af..837d7c1228a415240081a8218468974a for(ServerPlayer serverPlayer : targets) { - i += operation.perform(serverPlayer, selection); -+ i += 1; // Paper - region threading -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ i += 1; // Folia - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading + operation.perform(serverPlayer, selection); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading + } @@ -10712,40 +10712,40 @@ index 147c256e794f3e579e70927329fd1905ad1b33af..837d7c1228a415240081a8218468974a throw new CommandRuntimeException(Component.translatable("commands.advancement.criterionNotFound", advancement.getChatComponent(), criterion)); } else { for(ServerPlayer serverPlayer : targets) { -+ ++i; // Paper - region threading -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ ++i; // Folia - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading if (operation.performCriterion(serverPlayer, advancement, criterion)) { - ++i; -+ // Paper - region threading ++ // Folia - region threading } -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading + } if (i == 0) { diff --git a/src/main/java/net/minecraft/server/commands/AttributeCommand.java b/src/main/java/net/minecraft/server/commands/AttributeCommand.java -index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25ae0535c0 100644 +index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..b01aeb7bae3b6d3d291f76d19e8807980452646c 100644 --- a/src/main/java/net/minecraft/server/commands/AttributeCommand.java +++ b/src/main/java/net/minecraft/server/commands/AttributeCommand.java @@ -92,58 +92,113 @@ public class AttributeCommand { } } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int getAttributeValue(CommandSourceStack source, Entity target, Holder attribute, double multiplier) throws CommandSyntaxException { - LivingEntity livingEntity = getEntityWithAttribute(target, attribute); - double d = livingEntity.getAttributeValue(attribute); - source.sendSuccess(Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), target.getName(), d), false); - return (int)(d * multiplier); -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { -+ LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); // Paper - region threading ++ LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); // Folia - region threading + double d = livingEntity.getAttributeValue(attribute); + source.sendSuccess(Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), nmsEntity.getName(), d), false); + } catch (CommandSyntaxException ex) { @@ -10753,7 +10753,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + } + }, null, 1L); + return 0; -+ // Paper end - region threading ++ // Folia end - region threading } private static int getAttributeBase(CommandSourceStack source, Entity target, Holder attribute, double multiplier) throws CommandSyntaxException { @@ -10761,7 +10761,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 - double d = livingEntity.getAttributeBaseValue(attribute); - source.sendSuccess(Component.translatable("commands.attribute.base_value.get.success", getAttributeDescription(attribute), target.getName(), d), false); - return (int)(d * multiplier); -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); @@ -10772,7 +10772,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + } + }, null, 1L); + return 0; -+ // Paper end - region threading ++ // Folia end - region threading + } @@ -10786,7 +10786,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 - source.sendSuccess(Component.translatable("commands.attribute.modifier.value.get.success", uuid, getAttributeDescription(attribute), target.getName(), d), false); - return (int)(d * multiplier); - } -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + LivingEntity livingEntity = getEntityWithAttribute(nmsEntity, attribute); @@ -10802,13 +10802,13 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + } + }, null, 1L); + return 0; -+ // Paper end - region threading ++ // Folia end - region threading } private static int setAttributeBase(CommandSourceStack source, Entity target, Holder attribute, double value) throws CommandSyntaxException { - getAttributeInstance(target, attribute).setBaseValue(value); - source.sendSuccess(Component.translatable("commands.attribute.base_value.set.success", getAttributeDescription(attribute), target.getName(), value), false); -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + getAttributeInstance(nmsEntity, attribute).setBaseValue(value); @@ -10817,7 +10817,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + sendMessage(source, ex); + } + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading return 1; } @@ -10831,7 +10831,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 - source.sendSuccess(Component.translatable("commands.attribute.modifier.add.success", uuid, getAttributeDescription(attribute), target.getName()), false); - return 1; - } -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + AttributeInstance attributeInstance = getAttributeInstance(nmsEntity, attribute); @@ -10847,7 +10847,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + } + }, null, 1L); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } private static int removeModifier(CommandSourceStack source, Entity target, Holder attribute, UUID uuid) throws CommandSyntaxException { @@ -10858,7 +10858,7 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 - } else { - throw ERROR_NO_SUCH_MODIFIER.create(target.getName(), getAttributeDescription(attribute), uuid); - } -+ // Paper start - region threading ++ // Folia start - region threading + target.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + AttributeInstance attributeInstance = getAttributeInstance(nmsEntity, attribute); @@ -10872,12 +10872,12 @@ index e846bd5db018f79c083d29f8f7b305a3d7ab45f5..8adf0bdf19de696b110c59b898e7ba25 + } + }, null, 1L); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } private static Component getAttributeDescription(Holder attribute) { diff --git a/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java b/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java -index 74623df731de543d3ef5832e818b10adec7b0f01..f852441fbc4f04d619dad48a51a9438ae683358a 100644 +index 74623df731de543d3ef5832e818b10adec7b0f01..74a5e35c66e4d6aeae61733ad3ef1e51c0cfd593 100644 --- a/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java +++ b/src/main/java/net/minecraft/server/commands/ClearInventoryCommands.java @@ -46,9 +46,12 @@ public class ClearInventoryCommands { @@ -10886,35 +10886,35 @@ index 74623df731de543d3ef5832e818b10adec7b0f01..f852441fbc4f04d619dad48a51a9438a for(ServerPlayer serverPlayer : targets) { - i += serverPlayer.getInventory().clearOrCountMatchingItems(item, maxCount, serverPlayer.inventoryMenu.getCraftSlots()); + ++i; -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading + serverPlayer.getInventory().clearOrCountMatchingItems(item, maxCount, serverPlayer.inventoryMenu.getCraftSlots()); serverPlayer.containerMenu.broadcastChanges(); serverPlayer.inventoryMenu.slotsChanged(serverPlayer.getInventory()); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } if (i == 0) { diff --git a/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java b/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java -index 1bf4c5b36f53ef1e71d50d1a9af8e1410e5dff60..0f7c2baed057242b0107ec525ac034fe8388ba51 100644 +index 1bf4c5b36f53ef1e71d50d1a9af8e1410e5dff60..fd455c794fa52b565a5741b376bc394ac8dda07c 100644 --- a/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java +++ b/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java @@ -25,12 +25,14 @@ public class DefaultGameModeCommands { GameType gameType = minecraftServer.getForcedGameType(); if (gameType != null) { for(ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) { -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading // Paper start - extend PlayerGameModeChangeEvent org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, net.kyori.adventure.text.Component.empty()); if (event != null && event.isCancelled()) { source.sendSuccess(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), false); } // Paper end -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading ++i; } } diff --git a/src/main/java/net/minecraft/server/commands/EffectCommands.java b/src/main/java/net/minecraft/server/commands/EffectCommands.java -index bed3ffb18398f34077503ba2d7aa6ecc7c0537c2..672ab95a8c2afe4d074ebbcd68a247a827522f49 100644 +index bed3ffb18398f34077503ba2d7aa6ecc7c0537c2..8651d87632a4f5d0ccd69332a78f9a9969eb638f 100644 --- a/src/main/java/net/minecraft/server/commands/EffectCommands.java +++ b/src/main/java/net/minecraft/server/commands/EffectCommands.java @@ -76,7 +76,15 @@ public class EffectCommands { @@ -10922,15 +10922,15 @@ index bed3ffb18398f34077503ba2d7aa6ecc7c0537c2..672ab95a8c2afe4d074ebbcd68a247a8 MobEffectInstance mobeffect = new MobEffectInstance(mobeffectlist, k, amplifier, false, showParticles); - if (((LivingEntity) entity).addEffect(mobeffect, source.getEntity(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND)) { // CraftBukkit -+ // Paper start - region threading ++ // Folia start - region threading + entity.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { + if (!(nmsEntity instanceof LivingEntity)) { + return; + } + ((LivingEntity) nmsEntity).addEffect(mobeffect, null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND); + }, null, 1L); -+ // Paper end - region threading -+ if (true) { // CraftBukkit // Paper - region threading ++ // Folia end - region threading ++ if (true) { // CraftBukkit // Folia - region threading ++j; } } @@ -10939,16 +10939,16 @@ index bed3ffb18398f34077503ba2d7aa6ecc7c0537c2..672ab95a8c2afe4d074ebbcd68a247a8 Entity entity = (Entity) iterator.next(); - if (entity instanceof LivingEntity && ((LivingEntity) entity).removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND)) { // CraftBukkit -+ if (entity instanceof LivingEntity) { // CraftBukkit // Paper - region threading ++ if (entity instanceof LivingEntity) { // CraftBukkit // Folia - region threading ++i; -+ // Paper start - region threading ++ // Folia start - region threading + entity.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { + if (!(nmsEntity instanceof LivingEntity)) { + return; + } + ((LivingEntity) nmsEntity).removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND); + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading } } @@ -10957,32 +10957,32 @@ index bed3ffb18398f34077503ba2d7aa6ecc7c0537c2..672ab95a8c2afe4d074ebbcd68a247a8 Entity entity = (Entity) iterator.next(); - if (entity instanceof LivingEntity && ((LivingEntity) entity).removeEffect(mobeffectlist, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND)) { // CraftBukkit -+ if (entity instanceof LivingEntity) { // CraftBukkit // Paper - region threading ++ if (entity instanceof LivingEntity) { // CraftBukkit // Folia - region threading ++i; -+ // Paper start - region threading ++ // Folia start - region threading + entity.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { + if (!(nmsEntity instanceof LivingEntity)) { + return; + } + ((LivingEntity) nmsEntity).removeEffect(mobeffectlist, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.COMMAND); + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading } } diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java -index e639c0ec642910e66b1d68ae0b9208ef58d91fce..c17b8ed18952c1ab7e9f12ea7d39a4c94bcc3232 100644 +index e639c0ec642910e66b1d68ae0b9208ef58d91fce..9ad71bda2f7498ad6e0853a1070c5be2d8016548 100644 --- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java +++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java @@ -46,6 +46,12 @@ public class EnchantCommand { }))))); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int enchant(CommandSourceStack source, Collection targets, Holder enchantment, int level) throws CommandSyntaxException { Enchantment enchantment2 = enchantment.value(); @@ -10999,7 +10999,7 @@ index e639c0ec642910e66b1d68ae0b9208ef58d91fce..c17b8ed18952c1ab7e9f12ea7d39a4c9 - ++i; - } else if (targets.size() == 1) { - throw ERROR_INCOMPATIBLE.create(itemStack.getItem().getName(itemStack).getString()); -+ // Paper start - region threading ++ // Folia start - region threading + entity.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> { + try { + LivingEntity livingEntity = (LivingEntity)nmsEntity; @@ -11021,31 +11021,31 @@ index e639c0ec642910e66b1d68ae0b9208ef58d91fce..c17b8ed18952c1ab7e9f12ea7d39a4c9 - } + }, null, 1L); + ++i; -+ // Paper end - region threading ++ // Folia end - region threading } else if (targets.size() == 1) { throw ERROR_NOT_LIVING_ENTITY.create(entity.getName().getString()); } diff --git a/src/main/java/net/minecraft/server/commands/ExperienceCommand.java b/src/main/java/net/minecraft/server/commands/ExperienceCommand.java -index a628e3730b1c26c2e6a85c449440af0afe4c0d8d..1be09bf6356e02300dd7854695ec7a677b8ed5f4 100644 +index a628e3730b1c26c2e6a85c449440af0afe4c0d8d..6651376603c3fb2331ae0955343285ac7c37726f 100644 --- a/src/main/java/net/minecraft/server/commands/ExperienceCommand.java +++ b/src/main/java/net/minecraft/server/commands/ExperienceCommand.java @@ -46,14 +46,18 @@ public class ExperienceCommand { } private static int queryExperience(CommandSourceStack source, ServerPlayer player, ExperienceCommand.Type component) { -+ player.getBukkitEntity().taskScheduler.schedule((ServerPlayer p) -> { // Paper - region threading ++ player.getBukkitEntity().taskScheduler.schedule((ServerPlayer p) -> { // Folia - region threading int i = component.query.applyAsInt(player); source.sendSuccess(Component.translatable("commands.experience.query." + component.name, player.getDisplayName(), i), false); - return i; -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading + return 0; } private static int addExperience(CommandSourceStack source, Collection targets, int amount, ExperienceCommand.Type component) { for(ServerPlayer serverPlayer : targets) { -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading component.add.accept(serverPlayer, amount); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } if (targets.size() == 1) { @@ -11053,29 +11053,29 @@ index a628e3730b1c26c2e6a85c449440af0afe4c0d8d..1be09bf6356e02300dd7854695ec7a67 int i = 0; for(ServerPlayer serverPlayer : targets) { -+ ++i; // Paper - region threading -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ ++i; // Folia - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading if (component.set.test(serverPlayer, amount)) { - ++i; -+ // Paper - region threading ++ // Folia - region threading } -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } if (i == 0) { diff --git a/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java b/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java -index 6c29947dc9259f453782de3c973c1cabb87e3de5..aed35fdb60bd60a0afd25b41142b58ea1b0a17bb 100644 +index 6c29947dc9259f453782de3c973c1cabb87e3de5..c8e60578f15a358223ed056460d3ea2c57b0cd40 100644 --- a/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java +++ b/src/main/java/net/minecraft/server/commands/FillBiomeCommand.java @@ -69,6 +69,12 @@ public class FillBiomeCommand { }; } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int fill(CommandSourceStack source, BlockPos from, BlockPos to, Holder.Reference biome, Predicate> filter) throws CommandSyntaxException { BlockPos blockPos = quantize(from); @@ -11085,7 +11085,7 @@ index 6c29947dc9259f453782de3c973c1cabb87e3de5..aed35fdb60bd60a0afd25b41142b58ea } else { ServerLevel serverLevel = source.getLevel(); - List list = new ArrayList<>(); -+ // Paper start - region threading ++ // Folia start - region threading + int buffer = 0; + // no buffer, we do not touch neighbours + serverLevel.loadChunksAsync( @@ -11138,23 +11138,23 @@ index 6c29947dc9259f453782de3c973c1cabb87e3de5..aed35fdb60bd60a0afd25b41142b58ea + } + ); + return 0; -+ // Paper end - region threading ++ // Folia end - region threading } } } diff --git a/src/main/java/net/minecraft/server/commands/FillCommand.java b/src/main/java/net/minecraft/server/commands/FillCommand.java -index 99fbb24dabe867ed4956a2996543107f58a57193..c6b748060aa120bea3be9723a46b83ecea3f5b66 100644 +index 99fbb24dabe867ed4956a2996543107f58a57193..01360d24522a877bf7c3524f17ec65ef2b514b0c 100644 --- a/src/main/java/net/minecraft/server/commands/FillCommand.java +++ b/src/main/java/net/minecraft/server/commands/FillCommand.java @@ -57,6 +57,12 @@ public class FillCommand { })))))); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int fillBlocks(CommandSourceStack source, BoundingBox range, BlockInput block, FillCommand.Mode mode, @Nullable Predicate filter) throws CommandSyntaxException { int i = range.getXSpan() * range.getYSpan() * range.getZSpan(); @@ -11174,7 +11174,7 @@ index 99fbb24dabe867ed4956a2996543107f58a57193..c6b748060aa120bea3be9723a46b83ec - if (blockInput.place(serverLevel, blockPos, 2)) { - list.add(blockPos.immutable()); - ++j; -+ // Paper start - region threading ++ // Folia start - region threading + int buffer = 32; + // physics may spill into neighbour chunks, so use a buffer + serverLevel.loadChunksAsync( @@ -11213,10 +11213,10 @@ index 99fbb24dabe867ed4956a2996543107f58a57193..c6b748060aa120bea3be9723a46b83ec + } + + if (j == 0) { -+ sendMessage(source, ERROR_FAILED.create()); return; // Paper - region threading ++ sendMessage(source, ERROR_FAILED.create()); return; // Folia - region threading + } else { + source.sendSuccess(Component.translatable("commands.fill.success", j), true); -+ return; // Paper - region threading ++ return; // Folia - region threading + } + } + ); @@ -11228,23 +11228,23 @@ index 99fbb24dabe867ed4956a2996543107f58a57193..c6b748060aa120bea3be9723a46b83ec - return j; - } + return 0; -+ // Paper end - region threading ++ // Folia end - region threading } } diff --git a/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java b/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java -index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768cdaf330e 100644 +index de484336165891d16220fdc0363e5283ba92b75d..3f165dbca5ce094ad39e46ecc2fa2bb9e80968ce 100644 --- a/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java +++ b/src/main/java/net/minecraft/server/commands/ForceLoadCommand.java @@ -49,96 +49,126 @@ public class ForceLoadCommand { })))); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int queryForceLoad(CommandSourceStack source, ColumnPos pos) throws CommandSyntaxException { ChunkPos chunkPos = pos.toChunkPos(); @@ -11257,7 +11257,7 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 - } else { - throw ERROR_NOT_TICKING.create(chunkPos, resourceKey.location()); - } -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { + try { + boolean bl = serverLevel.getForcedChunks().contains(chunkPos.toLong()); @@ -11272,7 +11272,7 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 + } + }); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } private static int listForceLoad(CommandSourceStack source) { @@ -11284,7 +11284,7 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 - String string = Joiner.on(", ").join(longSet.stream().sorted().map(ChunkPos::new).map(ChunkPos::toString).iterator()); - if (i == 1) { - source.sendSuccess(Component.translatable("commands.forceload.list.single", resourceKey.location(), string), false); -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { + LongSet longSet = serverLevel.getForcedChunks(); + int i = longSet.size(); @@ -11306,19 +11306,19 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 - return i; + }); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } private static int removeAll(CommandSourceStack source) { ServerLevel serverLevel = source.getLevel(); ResourceKey resourceKey = serverLevel.dimension(); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading LongSet longSet = serverLevel.getForcedChunks(); longSet.forEach((chunkPos) -> { serverLevel.setChunkForced(ChunkPos.getX(chunkPos), ChunkPos.getZ(chunkPos), false); }); source.sendSuccess(Component.translatable("commands.forceload.removed.all", resourceKey.location()), true); -+ }); // Paper - region threading ++ }); // Folia - region threading return 0; } @@ -11340,7 +11340,7 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 - ResourceKey resourceKey = serverLevel.dimension(); - ChunkPos chunkPos = null; - int r = 0; -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { + try { + int i = Math.min(from.x(), to.x()); @@ -11418,42 +11418,42 @@ index de484336165891d16220fdc0363e5283ba92b75d..0ab53877345ec69a2babc199a1489768 - } + }); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } } diff --git a/src/main/java/net/minecraft/server/commands/GameModeCommand.java b/src/main/java/net/minecraft/server/commands/GameModeCommand.java -index 27c0aaf123c3e945eb24e8a3892bd8ac42115733..a8fa32601ccc07f67f3ac58867529a5cded088e8 100644 +index 27c0aaf123c3e945eb24e8a3892bd8ac42115733..2f9f73e75b6c730a9cf327767ba1c34e34c64ed8 100644 --- a/src/main/java/net/minecraft/server/commands/GameModeCommand.java +++ b/src/main/java/net/minecraft/server/commands/GameModeCommand.java @@ -44,15 +44,18 @@ public class GameModeCommand { int i = 0; for(ServerPlayer serverPlayer : targets) { -+ serverPlayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading ++ serverPlayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading // Paper start - extend PlayerGameModeChangeEvent org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty()); if (event != null && !event.isCancelled()) { logGamemodeChange(context.getSource(), serverPlayer, gameMode); - ++i; -+ // Paper - region threading ++ // Folia - region threading } else if (event != null && event.cancelMessage() != null) { context.getSource().sendSuccess(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true); // Paper end } -+ }, null, 1L); // Paper - region threading -+ ++i; // Paper - region threading ++ }, null, 1L); // Folia - region threading ++ ++i; // Folia - region threading } return i; diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java -index 06e3a868e922f1b7a586d0ca28f64a67ae463b68..49d6b02129fe4c8347bd12793608efab8d8101eb 100644 +index 06e3a868e922f1b7a586d0ca28f64a67ae463b68..8f4a7b6ed27e97c22153dadf837e521a75bb6940 100644 --- a/src/main/java/net/minecraft/server/commands/GiveCommand.java +++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java @@ -55,6 +55,7 @@ public class GiveCommand { l -= i1; ItemStack itemstack = item.createItemStack(i1, false); -+ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading ++ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading boolean flag = entityplayer.getInventory().add(itemstack); ItemEntity entityitem; @@ -11461,12 +11461,12 @@ index 06e3a868e922f1b7a586d0ca28f64a67ae463b68..49d6b02129fe4c8347bd12793608efab entityitem.setOwner(entityplayer.getUUID()); } } -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } } diff --git a/src/main/java/net/minecraft/server/commands/KillCommand.java b/src/main/java/net/minecraft/server/commands/KillCommand.java -index a6e4bd9243dab7feaed1bd968108a324d6c37ed7..793d2735a65d5f09ed081961265ab7fa3c067448 100644 +index a6e4bd9243dab7feaed1bd968108a324d6c37ed7..4637e60292128e8c4053fb3a5fed48e53ec6553f 100644 --- a/src/main/java/net/minecraft/server/commands/KillCommand.java +++ b/src/main/java/net/minecraft/server/commands/KillCommand.java @@ -22,7 +22,9 @@ public class KillCommand { @@ -11474,25 +11474,25 @@ index a6e4bd9243dab7feaed1bd968108a324d6c37ed7..793d2735a65d5f09ed081961265ab7fa private static int kill(CommandSourceStack source, Collection targets) { for(Entity entity : targets) { - entity.kill(); -+ entity.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading -+ nmsEntity.kill(); // Paper - region threading -+ }, null, 1L); // Paper - region threading ++ entity.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading ++ nmsEntity.kill(); // Folia - region threading ++ }, null, 1L); // Folia - region threading } if (targets.size() == 1) { diff --git a/src/main/java/net/minecraft/server/commands/PlaceCommand.java b/src/main/java/net/minecraft/server/commands/PlaceCommand.java -index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972ad0942ec 100644 +index 6835072c6b30ee0b79c43e05526fd6d605bf7139..0a6baec737ef847fc84723176c7f267d3999ad4c 100644 --- a/src/main/java/net/minecraft/server/commands/PlaceCommand.java +++ b/src/main/java/net/minecraft/server/commands/PlaceCommand.java @@ -83,82 +83,130 @@ public class PlaceCommand { }))))))))); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + public static int placeFeature(CommandSourceStack source, Holder.Reference> feature, BlockPos pos) throws CommandSyntaxException { ServerLevel serverLevel = source.getLevel(); @@ -11506,7 +11506,7 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 - source.sendSuccess(Component.translatable("commands.place.feature.success", string, pos.getX(), pos.getY(), pos.getZ()), true); - return 1; - } -+ // Paper start - region threading ++ // Folia start - region threading + serverLevel.loadChunksAsync( + pos, 16, net.minecraft.world.level.chunk.ChunkStatus.FULL, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, @@ -11524,7 +11524,7 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 + } + ); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } public static int placeJigsaw(CommandSourceStack source, Holder structurePool, ResourceLocation id, int maxDepth, BlockPos pos) throws CommandSyntaxException { @@ -11535,7 +11535,7 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 - source.sendSuccess(Component.translatable("commands.place.jigsaw.success", pos.getX(), pos.getY(), pos.getZ()), true); - return 1; - } -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + serverLevel, pos.getX() >> 4, pos.getZ() >> 4, () -> { + try { @@ -11550,7 +11550,7 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 + } + ); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } public static int placeStructure(CommandSourceStack source, Holder.Reference structure, BlockPos pos) throws CommandSyntaxException { @@ -11574,7 +11574,7 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 - source.sendSuccess(Component.translatable("commands.place.structure.success", string, pos.getX(), pos.getY(), pos.getZ()), true); - return 1; - } -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + serverLevel, pos.getX() >> 4, pos.getZ() >> 4, () -> { + try { @@ -11600,13 +11600,13 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 + } + ); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } public static int placeTemplate(CommandSourceStack source, ResourceLocation id, BlockPos pos, Rotation rotation, Mirror mirror, float integrity, int seed) throws CommandSyntaxException { ServerLevel serverLevel = source.getLevel(); - StructureTemplateManager structureTemplateManager = serverLevel.getStructureManager(); -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + serverLevel, pos.getX() >> 4, pos.getZ() >> 4, () -> { + try { @@ -11664,12 +11664,12 @@ index 6835072c6b30ee0b79c43e05526fd6d605bf7139..59b8f1796873a76b703f5e97ae5bf972 - } + ); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } private static void checkLoaded(ServerLevel world, ChunkPos pos1, ChunkPos pos2) throws CommandSyntaxException { diff --git a/src/main/java/net/minecraft/server/commands/RecipeCommand.java b/src/main/java/net/minecraft/server/commands/RecipeCommand.java -index 2a92e542e4b3e4dfb26adfc4b21490a629b79382..980bf5e6af4f8835f9841d2dc92a58ce236f205e 100644 +index 2a92e542e4b3e4dfb26adfc4b21490a629b79382..d3405192a705637daba66735c717d64708362bd1 100644 --- a/src/main/java/net/minecraft/server/commands/RecipeCommand.java +++ b/src/main/java/net/minecraft/server/commands/RecipeCommand.java @@ -36,7 +36,12 @@ public class RecipeCommand { @@ -11677,12 +11677,12 @@ index 2a92e542e4b3e4dfb26adfc4b21490a629b79382..980bf5e6af4f8835f9841d2dc92a58ce for(ServerPlayer serverPlayer : targets) { - i += serverPlayer.awardRecipes(recipes); -+ // Paper start - region threading ++ // Folia start - region threading + ++i; + serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { + serverPlayer.awardRecipes(recipes); + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading } if (i == 0) { @@ -11691,28 +11691,28 @@ index 2a92e542e4b3e4dfb26adfc4b21490a629b79382..980bf5e6af4f8835f9841d2dc92a58ce for(ServerPlayer serverPlayer : targets) { - i += serverPlayer.resetRecipes(recipes); -+ // Paper start - region threading ++ // Folia start - region threading + ++i; + serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { + serverPlayer.resetRecipes(recipes); + }, null, 1L); -+ // Paper end - region threading ++ // Folia end - region threading } if (i == 0) { diff --git a/src/main/java/net/minecraft/server/commands/SetBlockCommand.java b/src/main/java/net/minecraft/server/commands/SetBlockCommand.java -index ad435815e56ca5a8d5ea6046ee4a3ed4d3673a48..175296e956b118d8095792ed68b95739b64582a6 100644 +index ad435815e56ca5a8d5ea6046ee4a3ed4d3673a48..2e53969ae222c13a7ef034f96a7014f924960481 100644 --- a/src/main/java/net/minecraft/server/commands/SetBlockCommand.java +++ b/src/main/java/net/minecraft/server/commands/SetBlockCommand.java @@ -38,29 +38,45 @@ public class SetBlockCommand { }))))); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void sendMessage(CommandSourceStack src, CommandSyntaxException ex) { + src.sendFailure((Component)ex.getRawMessage()); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static int setBlock(CommandSourceStack source, BlockPos pos, BlockInput block, SetBlockCommand.Mode mode, @Nullable Predicate condition) throws CommandSyntaxException { ServerLevel serverLevel = source.getLevel(); @@ -11728,7 +11728,7 @@ index ad435815e56ca5a8d5ea6046ee4a3ed4d3673a48..175296e956b118d8095792ed68b95739 - Clearable.tryClear(blockEntity); - bl = true; - } -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + serverLevel, pos.getX() >> 4, pos.getZ() >> 4, () -> { + try { @@ -11765,12 +11765,12 @@ index ad435815e56ca5a8d5ea6046ee4a3ed4d3673a48..175296e956b118d8095792ed68b95739 - } + ); + return 1; -+ // Paper end - region threading ++ // Folia end - region threading } public interface Filter { diff --git a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java -index 1e41de9523c5fa3b9cfced798a5c35a24ec9d349..a4fbc369e20831642bc9c9141e6a8bd7a95c39cd 100644 +index 1e41de9523c5fa3b9cfced798a5c35a24ec9d349..aa2c3d3161d01c87cd88e3311907e6559e81aa4e 100644 --- a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java +++ b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java @@ -35,7 +35,12 @@ public class SetSpawnCommand { @@ -11778,17 +11778,17 @@ index 1e41de9523c5fa3b9cfced798a5c35a24ec9d349..a4fbc369e20831642bc9c9141e6a8bd7 for(ServerPlayer serverPlayer : targets) { // Paper start - PlayerSetSpawnEvent - if (serverPlayer.setRespawnPosition(resourceKey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) { -+ // Paper start - region threading ++ // Folia start - region threading + serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { + player.setRespawnPosition(resourceKey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND); + }, null, 1L); -+ // Paper end - region threading -+ if (true) { // Paper - region threading ++ // Folia end - region threading ++ if (true) { // Folia - region threading actualTargets.add(serverPlayer); } // Paper end diff --git a/src/main/java/net/minecraft/server/commands/SummonCommand.java b/src/main/java/net/minecraft/server/commands/SummonCommand.java -index ade2626bc63f986a53277378cdc19f5366f9372f..d0f181dadaf7a116c50e0278b8b8fc5c8433165d 100644 +index ade2626bc63f986a53277378cdc19f5366f9372f..b2081239f13d3a001bbfa467933518ec400baea7 100644 --- a/src/main/java/net/minecraft/server/commands/SummonCommand.java +++ b/src/main/java/net/minecraft/server/commands/SummonCommand.java @@ -63,11 +63,18 @@ public class SummonCommand { @@ -11798,7 +11798,7 @@ index ade2626bc63f986a53277378cdc19f5366f9372f..d0f181dadaf7a116c50e0278b8b8fc5c - if (initialize && entity instanceof Mob) { - ((Mob) entity).finalizeSpawn(source.getLevel(), source.getLevel().getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, (SpawnGroupData) null, (CompoundTag) null); - } -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + worldserver, entity.chunkPosition().x, entity.chunkPosition().z, () -> { + if (initialize && entity instanceof Mob) { @@ -11807,15 +11807,15 @@ index ade2626bc63f986a53277378cdc19f5366f9372f..d0f181dadaf7a116c50e0278b8b8fc5c + worldserver.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.COMMAND); + } + ); -+ // Paper end - region threading ++ // Folia end - region threading - if (!worldserver.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.COMMAND)) { // CraftBukkit - pass a spawn reason of "COMMAND" -+ if (false) { // CraftBukkit - pass a spawn reason of "COMMAND" // Paper - region threading ++ if (false) { // CraftBukkit - pass a spawn reason of "COMMAND" // Folia - region threading throw SummonCommand.ERROR_DUPLICATE_UUID.create(); } else { source.sendSuccess(Component.translatable("commands.summon.success", entity.getDisplayName()), true); diff --git a/src/main/java/net/minecraft/server/commands/TeleportCommand.java b/src/main/java/net/minecraft/server/commands/TeleportCommand.java -index 027ca5b67c544048815ddef4bb36d0a8fc3d038c..34e97bb14e5b215cff2632f6917798a87ff1d7c5 100644 +index 027ca5b67c544048815ddef4bb36d0a8fc3d038c..13961a2e282c46b6db4d9d30e0e8a5ffe130cc2f 100644 --- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java +++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java @@ -78,7 +78,7 @@ public class TeleportCommand { @@ -11823,7 +11823,7 @@ index 027ca5b67c544048815ddef4bb36d0a8fc3d038c..34e97bb14e5b215cff2632f6917798a8 Entity entity1 = (Entity) iterator.next(); - TeleportCommand.performTeleport(source, entity1, (ServerLevel) destination.level, destination.getX(), destination.getY(), destination.getZ(), EnumSet.noneOf(ClientboundPlayerPositionPacket.RelativeArgument.class), destination.getYRot(), destination.getXRot(), (TeleportCommand.LookAt) null); -+ io.papermc.paper.threadedregions.TeleportUtils.teleport(entity1, destination, Float.valueOf(destination.getYRot()), Float.valueOf(destination.getXRot()), Entity.TELEPORT_FLAG_LOAD_CHUNK, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.COMMAND, null); // Paper - region threading ++ io.papermc.paper.threadedregions.TeleportUtils.teleport(entity1, destination, Float.valueOf(destination.getYRot()), Float.valueOf(destination.getXRot()), Entity.TELEPORT_FLAG_LOAD_CHUNK, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.COMMAND, null); // Folia - region threading } if (targets.size() == 1) { @@ -11831,7 +11831,7 @@ index 027ca5b67c544048815ddef4bb36d0a8fc3d038c..34e97bb14e5b215cff2632f6917798a8 float f2 = Mth.wrapDegrees(yaw); float f3 = Mth.wrapDegrees(pitch); -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + ServerLevel worldFinal = world; + Vec3 posFinal = new Vec3(x, y, z); @@ -11848,19 +11848,19 @@ index 027ca5b67c544048815ddef4bb36d0a8fc3d038c..34e97bb14e5b215cff2632f6917798a8 + }, null, 1L); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading if (target instanceof ServerPlayer) { ChunkPos chunkcoordintpair = new ChunkPos(new BlockPos(x, y, z)); diff --git a/src/main/java/net/minecraft/server/commands/TimeCommand.java b/src/main/java/net/minecraft/server/commands/TimeCommand.java -index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..866c6c843ed06bc8c88fff0210f1e8d820d4c928 100644 +index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..00f63992885c16ea01384fc00e1325f389cc1a0f 100644 --- a/src/main/java/net/minecraft/server/commands/TimeCommand.java +++ b/src/main/java/net/minecraft/server/commands/TimeCommand.java @@ -56,6 +56,7 @@ public class TimeCommand { while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading // CraftBukkit start TimeSkipEvent event = new TimeSkipEvent(worldserver.getWorld(), TimeSkipEvent.SkipReason.COMMAND, time - worldserver.getDayTime()); Bukkit.getPluginManager().callEvent(event); @@ -11868,7 +11868,7 @@ index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..866c6c843ed06bc8c88fff0210f1e8d8 worldserver.setDayTime((long) worldserver.getDayTime() + event.getSkipAmount()); } // CraftBukkit end -+ }); // Paper - region threading ++ }); // Folia - region threading } source.sendSuccess(Component.translatable("commands.time.set", time), true); @@ -11876,7 +11876,7 @@ index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..866c6c843ed06bc8c88fff0210f1e8d8 while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading // CraftBukkit start TimeSkipEvent event = new TimeSkipEvent(worldserver.getWorld(), TimeSkipEvent.SkipReason.COMMAND, time); Bukkit.getPluginManager().callEvent(event); @@ -11884,51 +11884,51 @@ index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..866c6c843ed06bc8c88fff0210f1e8d8 worldserver.setDayTime(worldserver.getDayTime() + event.getSkipAmount()); } // CraftBukkit end -+ }); // Paper - region threading ++ }); // Folia - region threading } -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading int j = TimeCommand.getDayTime(source.getLevel()); source.sendSuccess(Component.translatable("commands.time.set", j), true); - return j; -+ }); // Paper - region threading -+ return 0; // Paper - region threading ++ }); // Folia - region threading ++ return 0; // Folia - region threading } } diff --git a/src/main/java/net/minecraft/server/commands/WeatherCommand.java b/src/main/java/net/minecraft/server/commands/WeatherCommand.java -index 71fd7887a4fa174d3f74c4bbe24497b156cbd3c8..e10b98e171ab83c82c09cc68f67afd57a6228c03 100644 +index 71fd7887a4fa174d3f74c4bbe24497b156cbd3c8..b8e1054cd5c906fd425fe5987c10db963cb32c62 100644 --- a/src/main/java/net/minecraft/server/commands/WeatherCommand.java +++ b/src/main/java/net/minecraft/server/commands/WeatherCommand.java @@ -28,20 +28,26 @@ public class WeatherCommand { } private static int setClear(CommandSourceStack source, int duration) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading source.getLevel().setWeatherParameters(duration, 0, false, false); source.sendSuccess(Component.translatable("commands.weather.set.clear"), true); -+ }); // Paper - region threading ++ }); // Folia - region threading return duration; } private static int setRain(CommandSourceStack source, int duration) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading source.getLevel().setWeatherParameters(0, duration, true, false); source.sendSuccess(Component.translatable("commands.weather.set.rain"), true); -+ }); // Paper - region threading ++ }); // Folia - region threading return duration; } private static int setThunder(CommandSourceStack source, int duration) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading source.getLevel().setWeatherParameters(0, duration, true, true); source.sendSuccess(Component.translatable("commands.weather.set.thunder"), true); -+ }); // Paper - region threading ++ }); // Folia - region threading return duration; } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 51b3db0b6c2cede95b584268e035c0fb36d38094..417cf9050091543f79cc463480e56735118790f7 100644 +index 51b3db0b6c2cede95b584268e035c0fb36d38094..48718c37e96821576f0d6bf0e510cd5806a23d4c 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -436,9 +436,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -11938,9 +11938,9 @@ index 51b3db0b6c2cede95b584268e035c0fb36d38094..417cf9050091543f79cc463480e56735 - public void tickChildren(BooleanSupplier shouldKeepTicking) { - super.tickChildren(shouldKeepTicking); - this.handleConsoleInputs(); -+ public void tickChildren(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Paper - region threading -+ super.tickChildren(shouldKeepTicking, region); // Paper - region threading -+ if (region == null) this.handleConsoleInputs(); // Paper - region threading ++ public void tickChildren(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - region threading ++ super.tickChildren(shouldKeepTicking, region); // Folia - region threading ++ if (region == null) this.handleConsoleInputs(); // Folia - region threading } @Override @@ -11948,17 +11948,17 @@ index 51b3db0b6c2cede95b584268e035c0fb36d38094..417cf9050091543f79cc463480e56735 @Override public String runCommand(String command) { -+ // Paper start - region threading ++ // Folia start - region threading + // RIP RCON + if (true) { + throw new UnsupportedOperationException(); + } -+ // Paper end - region threading ++ // Folia end - region threading Waitable[] waitableArray = new Waitable[1]; this.rconConsoleSource.prepareForCommand(); this.executeBlocking(() -> { diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 0b9cb85c063f913ad9245bafb8587d2f06c0ac6e..e7a93ebf2e91fe649c4a1704294a65cc04f8a315 100644 +index 0b9cb85c063f913ad9245bafb8587d2f06c0ac6e..179e142e7012eebbe636f65804f5ac6b8fb72abe 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java @@ -85,18 +85,18 @@ public class ChunkHolder { @@ -11967,20 +11967,20 @@ index 0b9cb85c063f913ad9245bafb8587d2f06c0ac6e..e7a93ebf2e91fe649c4a1704294a65cc long key = io.papermc.paper.util.MCUtil.getCoordinateKey(this.pos); - this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key); - this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); -+ this.playersInMobSpawnRange = null; // Paper - region threading -+ this.playersInChunkTickRange = null; // Paper - region threading ++ this.playersInMobSpawnRange = null; // Folia - region threading ++ this.playersInChunkTickRange = null; // Folia - region threading // Paper end - optimise anyPlayerCloseEnoughForSpawning // Paper start - optimise chunk tick iteration if (this.needsBroadcastChanges()) { - this.chunkMap.needsChangeBroadcasting.add(this); -+ this.chunkMap.level.getCurrentWorldData().addChunkHolderNeedsBroadcasting(this); // Paper - region threading ++ this.chunkMap.level.getCurrentWorldData().addChunkHolderNeedsBroadcasting(this); // Folia - region threading } // Paper end - optimise chunk tick iteration // Paper start - optimise checkDespawn LevelChunk chunk = this.getFullChunkNowUnchecked(); if (chunk != null) { - chunk.updateGeneralAreaCache(); -+ //chunk.updateGeneralAreaCache(); // Paper - region threading ++ //chunk.updateGeneralAreaCache(); // Folia - region threading } // Paper end - optimise checkDespawn } @@ -11989,14 +11989,14 @@ index 0b9cb85c063f913ad9245bafb8587d2f06c0ac6e..e7a93ebf2e91fe649c4a1704294a65cc // Paper start - optimise chunk tick iteration if (this.needsBroadcastChanges()) { - this.chunkMap.needsChangeBroadcasting.remove(this); -+ this.chunkMap.level.getCurrentWorldData().removeChunkHolderNeedsBroadcasting(this); // Paper - region threading ++ this.chunkMap.level.getCurrentWorldData().removeChunkHolderNeedsBroadcasting(this); // Folia - region threading } // Paper end - optimise chunk tick iteration // Paper start - optimise checkDespawn LevelChunk chunk = this.getFullChunkNowUnchecked(); if (chunk != null) { - chunk.removeGeneralAreaCache(); -+ //chunk.removeGeneralAreaCache(); // Paper - region threading ++ //chunk.removeGeneralAreaCache(); // Folia - region threading } // Paper end - optimise checkDespawn } @@ -12005,12 +12005,12 @@ index 0b9cb85c063f913ad9245bafb8587d2f06c0ac6e..e7a93ebf2e91fe649c4a1704294a65cc private void addToBroadcastMap() { org.spigotmc.AsyncCatcher.catchOp("ChunkHolder update"); - this.chunkMap.needsChangeBroadcasting.add(this); -+ this.chunkMap.level.getCurrentWorldData().addChunkHolderNeedsBroadcasting(this); // Paper - region threading ++ this.chunkMap.level.getCurrentWorldData().addChunkHolderNeedsBroadcasting(this); // Folia - region threading } // Paper end - optimise chunk tick iteration diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630defdffd1c65 100644 +index 870f4d6fae8c14502b4653f246a2df9e345ccca3..af9289ca259ebc665dea803972b362af2b06d679 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -146,21 +146,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -12019,16 +12019,16 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def private final String storageName; - private final PlayerMap playerMap; - public final Int2ObjectMap entityMap; -+ //private final PlayerMap playerMap; // Paper - region threading -+ //public final Int2ObjectMap entityMap; // Paper - region threading ++ //private final PlayerMap playerMap; // Folia - region threading ++ //public final Int2ObjectMap entityMap; // Folia - region threading private final Long2ByteMap chunkTypeCache; private final Long2LongMap chunkSaveCooldowns; private final Queue unloadQueue; int viewDistance; - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper - public final ReferenceOpenHashSet needsChangeBroadcasting = new ReferenceOpenHashSet<>(); -+ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper // Paper - region threading -+ //public final ReferenceOpenHashSet needsChangeBroadcasting = new ReferenceOpenHashSet<>(); // Paper - region threading ++ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper // Folia - region threading ++ //public final ReferenceOpenHashSet needsChangeBroadcasting = new ReferenceOpenHashSet<>(); // Folia - region threading // Paper - rewrite chunk system // Paper start - optimise checkDespawn @@ -12036,7 +12036,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def public static final double GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE = 16.0 * (GENERAL_AREA_MAP_SQUARE_RADIUS - 1); public static final double GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE_SQUARED = GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE * GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE; - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; -+ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; // Paper - region threading ++ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; // Folia - region threading // Paper end - optimise checkDespawn // Paper start - distance maps @@ -12046,8 +12046,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // these maps are named after spigot's uses - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; -+ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick // Paper - region threading -+ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; // Paper - region threading ++ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick // Folia - region threading ++ //public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; // Folia - region threading // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - use distance map to optimise tracker public static boolean isLegacyTrackingEntity(Entity entity) { @@ -12060,7 +12060,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - public final int getEntityTrackerRange(final int ordinal) { - return this.entityTrackerTrackRanges[ordinal]; - } -+ // Paper - region threading ++ // Folia - region threading private int convertSpigotRangeToVanilla(final int vanilla) { return MinecraftServer.getServer().getScaledTrackingDistance(vanilla); @@ -12069,12 +12069,12 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); // Note: players need to be explicitly added to distance maps before they can be updated - this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning -+ //this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper - region threading ++ //this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Folia - region threading // Paper start - per player mob spawning - if (this.playerMobDistanceMap != null) { - this.playerMobDistanceMap.add(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - per player mob spawning // Paper start - use distance map to optimise entity tracker - for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { @@ -12083,10 +12083,10 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - - trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - use distance map to optimise entity tracker - this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn -+ //this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn // Paper - region threading ++ //this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn // Folia - region threading } void removePlayerFromDistanceMaps(ServerPlayer player) { @@ -12095,22 +12095,22 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning - this.playerMobSpawnMap.remove(player); - this.playerChunkTickRangeMap.remove(player); -+ this.level.getCurrentWorldData().mobSpawnMap.remove(player); // Paper - region threading -+ //this.playerChunkTickRangeMap.remove(player); // Paper - region threading ++ this.level.getCurrentWorldData().mobSpawnMap.remove(player); // Folia - region threading ++ //this.playerChunkTickRangeMap.remove(player); // Folia - region threading // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning - this.playerGeneralAreaMap.remove(player); // Paper - optimise checkDespawns -+ //this.playerGeneralAreaMap.remove(player); // Paper - optimise checkDespawns // Paper - region threading ++ //this.playerGeneralAreaMap.remove(player); // Paper - optimise checkDespawns // Folia - region threading // Paper start - per player mob spawning - if (this.playerMobDistanceMap != null) { - this.playerMobDistanceMap.remove(player); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - per player mob spawning // Paper start - use distance map to optimise tracker - for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { - this.playerEntityTrackerTrackMaps[i].remove(player); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - use distance map to optimise tracker } @@ -12119,12 +12119,12 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // Note: players need to be explicitly added to distance maps before they can be updated this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader - this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning -+ //this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper - region threading ++ //this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Folia - region threading // Paper start - per player mob spawning - if (this.playerMobDistanceMap != null) { - this.playerMobDistanceMap.update(player, chunkX, chunkZ, io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(player)); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - per player mob spawning // Paper start - use distance map to optimise entity tracker - for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { @@ -12133,10 +12133,10 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - - trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player))); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - use distance map to optimise entity tracker - this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn -+ //this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn // Paper - region threading ++ //this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); // Paper - optimise checkDespawn // Folia - region threading } // Paper end // Paper start @@ -12146,8 +12146,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def this.tickingGenerated = new AtomicInteger(); - this.playerMap = new PlayerMap(); - this.entityMap = new Int2ObjectOpenHashMap(); -+ //this.playerMap = new PlayerMap(); // Paper - region threading -+ //this.entityMap = new Int2ObjectOpenHashMap(); // Paper - region threading ++ //this.playerMap = new PlayerMap(); // Folia - region threading ++ //this.entityMap = new Int2ObjectOpenHashMap(); // Folia - region threading this.chunkTypeCache = new Long2ByteOpenHashMap(); this.chunkSaveCooldowns = new Long2LongOpenHashMap(); this.unloadQueue = Queues.newConcurrentLinkedQueue(); @@ -12156,10 +12156,10 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // Paper start this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new); - this.regionManagers.add(this.dataRegionManager); -+ //this.regionManagers.add(this.dataRegionManager); // Paper - region threading ++ //this.regionManagers.add(this.dataRegionManager); // Folia - region threading // Paper end - this.playerMobDistanceMap = this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper -+ //this.playerMobDistanceMap = this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper // Paper - region threading ++ //this.playerMobDistanceMap = this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper // Folia - region threading // Paper start - use distance map to optimise entity tracker - this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length]; - this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length]; @@ -12198,7 +12198,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - - this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - use distance map to optimise entity tracker // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning - this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, @@ -12231,8 +12231,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - playerChunk.playersInMobSpawnRange = newState; - } - }); -+ // Paper - region threading -+ // Paper - region threading ++ // Folia - region threading ++ // Folia - region threading // Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning // Paper start - optimise checkDespawn - this.playerGeneralAreaMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, @@ -12250,7 +12250,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - chunk.updateGeneralAreaCache(newState); - } - }); -+ // Paper - region threading ++ // Folia - region threading // Paper end - optimise checkDespawn } @@ -12271,7 +12271,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - } - ++player.mobCounts[index]; - } -+ // Paper - region threading ++ // Folia - region threading } public int getMobCountNear(ServerPlayer entityPlayer, net.minecraft.world.entity.MobCategory mobCategory) { @@ -12279,12 +12279,12 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // Paper start // rets true if to prevent the entity from being added public static boolean checkDupeUUID(ServerLevel level, Entity entity) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + // TODO fix this shit later + return false; + } -+ // Paper end - region threading ++ // Folia end - region threading io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode mode = level.paperConfig().entities.spawning.duplicateUuid.mode; if (mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.WARN && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.DELETE @@ -12292,7 +12292,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def } final boolean anyPlayerCloseEnoughForSpawning(ChunkHolder playerchunk, ChunkPos chunkcoordintpair, boolean reducedRange) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + java.util.List players = this.level.getLocalPlayers(); + if (reducedRange) { @@ -12323,7 +12323,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def + // no players in range + return false; + } -+ // Paper end - region threading ++ // Folia end - region threading // this function is so hot that removing the map lookup call can have an order of magnitude impact on its performance // tested and confirmed via System.nanoTime() com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playersInRange = reducedRange ? playerchunk.playersInMobSpawnRange : playerchunk.playersInChunkTickRange; @@ -12332,7 +12332,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def } else { Builder builder = ImmutableList.builder(); - Iterator iterator = this.playerMap.getPlayers(i).iterator(); -+ Iterator iterator = this.level.getLocalPlayers().iterator(); // Paper - region threading ++ Iterator iterator = this.level.getLocalPlayers().iterator(); // Folia - region threading while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); @@ -12344,16 +12344,16 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - boolean flag2 = this.playerMap.ignoredOrUnknown(player); - int i = SectionPos.blockToSectionCoord(player.getBlockX()); - int j = SectionPos.blockToSectionCoord(player.getBlockZ()); -+ // Paper - region threading ++ // Folia - region threading if (added) { - this.playerMap.addPlayer(ChunkPos.asLong(i, j), player, flag1); -+ // Paper - region threading ++ // Folia - region threading this.updatePlayerPos(player); - if (!flag1) { - this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); - } -+ // Paper - region threading ++ // Folia - region threading this.addPlayerToDistanceMaps(player); // Paper - distance maps } else { SectionPos sectionposition = player.getLastSectionPos(); @@ -12362,8 +12362,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - if (!flag2) { - this.distanceManager.removePlayer(sectionposition, player); - } -+ // Paper - region threading -+ // Paper - region threading ++ // Folia - region threading ++ // Folia - region threading this.removePlayerFromDistanceMaps(player); // Paper - distance maps } @@ -12408,7 +12408,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - int j1 = sectionposition.z(); - int k1; - int l1; -+ // Paper - region threading - none of this logic is relevant anymore thanks to the player chunk loader ++ // Folia - region threading - none of this logic is relevant anymore thanks to the player chunk loader // Paper - replaced by PlayerChunkLoader @@ -12417,7 +12417,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot // Paper start - ignore and warn about illegal addEntity calls instead of crashing server - if (!entity.valid || entity.level != this.level || this.entityMap.containsKey(entity.getId())) { -+ if (!entity.valid || entity.level != this.level || entity.tracker != null) { // Paper - region threading ++ if (!entity.valid || entity.level != this.level || entity.tracker != null) { // Folia - region threading LOGGER.error("Illegal ChunkMap::addEntity for world " + this.level.getWorld().getName() - + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable()); + + ": " + entity + (entity.tracker != null ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable()); @@ -12429,7 +12429,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def int j = entitytypes.updateInterval(); - if (this.entityMap.containsKey(entity.getId())) { -+ if (entity.tracker != null) { // Paper - region threading ++ if (entity.tracker != null) { // Folia - region threading throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("Entity is already tracked!")); } else { ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas()); @@ -12437,8 +12437,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker - this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); - playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players -+ // Paper - region threading -+ playerchunkmap_entitytracker.updatePlayers(this.level.getLocalPlayers()); // Paper - don't search all players // Paper - region threading ++ // Folia - region threading ++ playerchunkmap_entitytracker.updatePlayers(this.level.getLocalPlayers()); // Paper - don't search all players // Folia - region threading if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; @@ -12450,13 +12450,13 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - - if (playerchunkmap_entitytracker1.entity != entityplayer) { - playerchunkmap_entitytracker1.updatePlayer(entityplayer); -+ // Paper start - region threading ++ // Folia start - region threading + for (Entity possible : this.level.getCurrentWorldData().getLocalEntities()) { + if (possible.tracker != null) { + possible.tracker.updatePlayer(entityplayer); } } -+ // Paper end - region threading ++ // Folia end - region threading } } @@ -12470,17 +12470,17 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next(); - - playerchunkmap_entitytracker.removePlayer(entityplayer); -+ // Paper start - region threading ++ // Folia start - region threading + for (Entity possible : this.level.getCurrentWorldData().getLocalEntities()) { + if (possible.tracker != null) { + possible.tracker.removePlayer(entityplayer); + } } -+ // Paper end - region threading ++ // Folia end - region threading } - ChunkMap.TrackedEntity playerchunkmap_entitytracker1 = (ChunkMap.TrackedEntity) this.entityMap.remove(entity.getId()); -+ ChunkMap.TrackedEntity playerchunkmap_entitytracker1 = entity.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity playerchunkmap_entitytracker1 = entity.tracker; // Folia - region threading if (playerchunkmap_entitytracker1 != null) { playerchunkmap_entitytracker1.broadcastRemoved(); @@ -12503,8 +12503,8 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - try { - for (TrackedEntity tracker : this.entityMap.values()) { - tracker.serverEntity.sendChanges(); -+ // Paper start - region threading -+ List players = this.level.getLocalPlayers(); // Paper - region threading ++ // Folia start - region threading ++ List players = this.level.getLocalPlayers(); // Folia - region threading + for (Entity entity : this.level.getCurrentWorldData().getLocalEntities()) { + TrackedEntity tracker = entity.tracker; + if (tracker == null) { @@ -12516,7 +12516,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def + tracker.removeNonTickThreadPlayers(); + tracker.serverEntity.sendChanges(); } -+ // Paper end - region threading ++ // Folia end - region threading } // Paper end - optimised tracker @@ -12564,13 +12564,13 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - } - level.timings.tracker2.stopTiming(); // Paper - } -+ // Paper - region threading ++ // Folia - region threading } public void broadcast(Entity entity, Packet packet) { - ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) this.entityMap.get(entity.getId()); -+ ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) entity.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) entity.tracker; // Folia - region threading if (playerchunkmap_entitytracker != null) { playerchunkmap_entitytracker.broadcast(packet); @@ -12579,7 +12579,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def protected void broadcastAndSend(Entity entity, Packet packet) { - ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) this.entityMap.get(entity.getId()); -+ ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) entity.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) entity.tracker; // Folia - region threading if (playerchunkmap_entitytracker != null) { playerchunkmap_entitytracker.broadcastAndSend(packet); @@ -12622,7 +12622,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def - } - } - // Paper end - use distance map to optimise tracker -+ // Paper - region threading ++ // Folia - region threading public boolean equals(Object object) { return object instanceof ChunkMap.TrackedEntity ? ((ChunkMap.TrackedEntity) object).entity.getId() == this.entity.getId() : false; @@ -12630,7 +12630,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def } } -+ // Paper start - region threading ++ // Folia start - region threading + public void removeNonTickThreadPlayers() { + boolean foundToRemove = false; + for (ServerPlayerConnection conn : this.seenBy) { @@ -12651,7 +12651,7 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def + } + } + } -+ // Paper end - region threading ++ // Folia end - region threading public void updatePlayer(ServerPlayer player) { org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot @@ -12660,20 +12660,20 @@ index 870f4d6fae8c14502b4653f246a2df9e345ccca3..3d6ea2ccf27afd1b57cac4776b630def // CraftBukkit start - respect vanish API - if (!player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - region threading ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(player) || !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Folia - region threading flag = false; } // CraftBukkit end -+ // Paper start - region threading ++ // Folia start - region threading + if ((this.entity instanceof ServerPlayer thisEntity) && thisEntity.broadcastedDeath) { + flag = false; + } -+ // Paper end - region threading ++ // Folia end - region threading if (flag) { if (this.seenBy.add(player.connection)) { this.serverEntity.addPairing(player); diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 88fca8b160df6804f30ed2cf8cf1f645085434e2..34f76afe573f312b855fc38e90d978b566acf8af 100644 +index 88fca8b160df6804f30ed2cf8cf1f645085434e2..341650384498eebe3f7a3315c398bec994a3195b 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java @@ -200,14 +200,14 @@ public abstract class DistanceManager { @@ -12681,7 +12681,7 @@ index 88fca8b160df6804f30ed2cf8cf1f645085434e2..34f76afe573f312b855fc38e90d978b5 // Paper start - use distance map to implement // note: this is the spawn chunk count - return this.chunkMap.playerChunkTickRangeMap.size(); -+ return this.chunkMap.level.getCurrentWorldData().mobSpawnMap.size(); // Paper - region threading ++ return this.chunkMap.level.getCurrentWorldData().mobSpawnMap.size(); // Folia - region threading // Paper end - use distance map to implement } @@ -12689,12 +12689,12 @@ index 88fca8b160df6804f30ed2cf8cf1f645085434e2..34f76afe573f312b855fc38e90d978b5 // Paper start - use distance map to implement // note: this is the is spawn chunk method - return this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(chunkPos) != null; -+ return this.chunkMap.level.getCurrentWorldData().mobSpawnMap.getObjectsInRange(chunkPos) != null; // Paper - region threading ++ return this.chunkMap.level.getCurrentWorldData().mobSpawnMap.getObjectsInRange(chunkPos) != null; // Folia - region threading // Paper end - use distance map to implement } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec4033f9f8 100644 +index 736f37979c882e41e7571202df38eb6a2923fcb0..d6cb55cb5970d0fdc23fcd01c1e62956048cba8d 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -61,7 +61,7 @@ public class ServerChunkCache extends ChunkSource { @@ -12702,7 +12702,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec public final ChunkMap chunkMap; private final DimensionDataStorage dataStorage; - private long lastInhabitedUpdate; -+ //private long lastInhabitedUpdate; // Paper - region threading ++ //private long lastInhabitedUpdate; // Folia - region threading public boolean spawnEnemies = true; public boolean spawnFriendlies = true; private static final int CACHE_SIZE = 4; @@ -12712,11 +12712,11 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec // Paper start - final com.destroystokyo.paper.util.concurrent.WeakSeqLock loadedChunkMapSeqLock = new com.destroystokyo.paper.util.concurrent.WeakSeqLock(); - final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f); -+ // Paper - region threading -+ final ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable loadedChunkMap = new ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable<>(8192, 0.5f); // Paper - region threading ++ // Folia - region threading ++ final ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable loadedChunkMap = new ca.spottedleaf.concurrentutil.map.SWMRLong2ObjectHashTable<>(8192, 0.5f); // Folia - region threading - private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; -+ // Paper - region threading ++ // Folia - region threading private static int getChunkCacheKey(int x, int z) { return x & 3 | ((z & 3) << 2); @@ -12725,7 +12725,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec public void addLoadedChunk(LevelChunk chunk) { - this.loadedChunkMapSeqLock.acquireWrite(); - try { -+ synchronized (this.loadedChunkMap) { // Paper - region threading ++ synchronized (this.loadedChunkMap) { // Folia - region threading this.loadedChunkMap.put(chunk.coordinateKey, chunk); - } finally { - this.loadedChunkMapSeqLock.releaseWrite(); @@ -12734,21 +12734,21 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - // rewrite cache if we have to - // we do this since we also cache null chunks - int cacheKey = getChunkCacheKey(chunk.locX, chunk.locZ); -+ } // Paper - region threading ++ } // Folia - region threading - this.lastLoadedChunks[cacheKey] = chunk; -+ // Paper - region threading ++ // Folia - region threading } public void removeLoadedChunk(LevelChunk chunk) { - this.loadedChunkMapSeqLock.acquireWrite(); - try { -+ synchronized (this.loadedChunkMap) { // Paper - region threading ++ synchronized (this.loadedChunkMap) { // Folia - region threading this.loadedChunkMap.remove(chunk.coordinateKey); - } finally { - this.loadedChunkMapSeqLock.releaseWrite(); - } -+ } // Paper - region threading ++ } // Folia - region threading - // rewrite cache if we have to - // we do this since we also cache null chunks @@ -12758,7 +12758,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - if (cachedChunk != null && cachedChunk.coordinateKey == chunk.coordinateKey) { - this.lastLoadedChunks[cacheKey] = null; - } -+ // Paper - region threading ++ // Folia - region threading } public final LevelChunk getChunkAtIfLoadedMainThread(int x, int z) { @@ -12775,7 +12775,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - // Skipping a null check to avoid extra instructions to improve inline capability - this.lastLoadedChunks[cacheKey] = cachedChunk; - return cachedChunk; -+ return this.loadedChunkMap.get(ChunkPos.asLong(x, z)); // Paper - region threading ++ return this.loadedChunkMap.get(ChunkPos.asLong(x, z)); // Folia - region threading } public final LevelChunk getChunkAtIfLoadedMainThreadNoCache(int x, int z) { @@ -12784,7 +12784,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec } - long chunkFutureAwaitCounter; // Paper - private -> package private -+ final java.util.concurrent.atomic.AtomicLong chunkFutureAwaitCounter = new java.util.concurrent.atomic.AtomicLong(); // Paper - private -> package private // Paper - region threading - TODO MERGE INTO CHUNK SYSTEM PATCH ++ final java.util.concurrent.atomic.AtomicLong chunkFutureAwaitCounter = new java.util.concurrent.atomic.AtomicLong(); // Paper - private -> package private // Folia - region threading - TODO MERGE INTO CHUNK SYSTEM PATCH public void getEntityTickingChunkAsync(int x, int z, java.util.function.Consumer onLoad) { io.papermc.paper.chunk.system.ChunkSystem.scheduleTickingState( @@ -12794,7 +12794,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet tickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true); - public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true); -+ // Paper - region threading ++ // Folia - region threading // Paper end public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { @@ -12822,7 +12822,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - } while (!this.loadedChunkMapSeqLock.tryReleaseRead(readlock)); - - return ret; -+ return this.loadedChunkMap.get(k); // Paper - region threading ++ return this.loadedChunkMap.get(k); // Folia - region threading } // Paper end // Paper start - async chunk io @@ -12830,7 +12830,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec } public CompletableFuture> getChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading boolean flag1 = io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system CompletableFuture completablefuture; @@ -12838,13 +12838,13 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec } private void tickChunks() { -+ io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.level.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.level.getCurrentWorldData(); // Folia - region threading long i = this.level.getGameTime(); - long j = i - this.lastInhabitedUpdate; -+ long j = 1; // Paper - region threading ++ long j = 1; // Folia - region threading - this.lastInhabitedUpdate = i; -+ //this.lastInhabitedUpdate = i; // Paper - region threading ++ //this.lastInhabitedUpdate = i; // Folia - region threading boolean flag = this.level.isDebug(); if (flag) { @@ -12853,12 +12853,12 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec // Paper start - optimize isOutisdeRange ChunkMap playerChunkMap = this.chunkMap; - for (ServerPlayer player : this.level.players) { -+ // Paper - region threading ++ // Folia - region threading + -+ for (ServerPlayer player : this.level.getLocalPlayers()) { // Paper - region threading ++ for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading if (!player.affectsSpawning || player.isSpectator()) { - playerChunkMap.playerMobSpawnMap.remove(player); -+ regionisedWorldData.mobSpawnMap.remove(player); // Paper - region threading ++ regionisedWorldData.mobSpawnMap.remove(player); // Folia - region threading continue; } @@ -12868,9 +12868,9 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec event.callEvent(); - if (event.isCancelled() || event.getSpawnRadius() < 0 || playerChunkMap.playerChunkTickRangeMap.getLastViewDistance(player) == -1) { - playerChunkMap.playerMobSpawnMap.remove(player); -+ if (event.isCancelled() || event.getSpawnRadius() < 0) { // Paper - region threading -+ player.lastEntitySpawnRadiusSquared = -1.0; player.playerNaturallySpawnedEvent = null; // Paper - region threading -+ regionisedWorldData.mobSpawnMap.remove(player); // Paper - region threading ++ if (event.isCancelled() || event.getSpawnRadius() < 0) { // Folia - region threading ++ player.lastEntitySpawnRadiusSquared = -1.0; player.playerNaturallySpawnedEvent = null; // Folia - region threading ++ regionisedWorldData.mobSpawnMap.remove(player); // Folia - region threading continue; } @@ -12879,7 +12879,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); - playerChunkMap.playerMobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); -+ regionisedWorldData.mobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); // Paper - region threading ++ regionisedWorldData.mobSpawnMap.addOrUpdate(player, chunkX, chunkZ, range); // Folia - region threading player.lastEntitySpawnRadiusSquared = (double)((range << 4) * (range << 4)); // used in anyPlayerCloseEnoughForSpawning player.playerNaturallySpawnedEvent = event; } @@ -12888,7 +12888,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec gameprofilerfiller.push("pollingChunks"); int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); - boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit -+ boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getRedstoneGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit // Paper - region threading ++ boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getRedstoneGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit // Folia - region threading gameprofilerfiller.push("naturalSpawnCount"); this.level.timings.countNaturalMobs.startTiming(); // Paper - timings @@ -12896,16 +12896,16 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec // Paper start - per player mob spawning NaturalSpawner.SpawnState spawnercreature_d; // moved down - if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't count mobs when animals and monsters are disabled -+ if ((this.spawnFriendlies || this.spawnEnemies)) { // don't count mobs when animals and monsters are disabled // Paper - region threading ++ if ((this.spawnFriendlies || this.spawnEnemies)) { // don't count mobs when animals and monsters are disabled // Folia - region threading // re-set mob counts for (ServerPlayer player : this.level.players) { Arrays.fill(player.mobCounts, 0); } - spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, null, true); -+ spawnercreature_d = NaturalSpawner.createState(l, regionisedWorldData.getLocalEntities(), this::getFullChunk, null, true); // Paper - region threading ++ spawnercreature_d = NaturalSpawner.createState(l, regionisedWorldData.getLocalEntities(), this::getFullChunk, null, true); // Folia - region threading } else { - spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, this.chunkMap.playerMobDistanceMap == null ? new LocalMobCapCalculator(this.chunkMap) : null, false); -+ spawnercreature_d = NaturalSpawner.createState(l, regionisedWorldData.getLocalEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap), false); // Paper - region threading ++ spawnercreature_d = NaturalSpawner.createState(l, regionisedWorldData.getLocalEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap), false); // Folia - region threading } // Paper end this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings @@ -12914,7 +12914,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec gameprofilerfiller.popPush("spawnAndTick"); - boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit -+ boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !regionisedWorldData.getLocalPlayers().isEmpty(); // CraftBukkit // Paper - region threading ++ boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !regionisedWorldData.getLocalPlayers().isEmpty(); // CraftBukkit // Folia - region threading // Paper - only shuffle if per-player mob spawning is disabled // Paper - moved natural spawn event up @@ -12922,12 +12922,12 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec Iterator iterator1; if (this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { - iterator1 = this.entityTickingChunks.iterator(); -+ iterator1 = regionisedWorldData.getEntityTickingChunks().iterator(); // Paper - region threading ++ iterator1 = regionisedWorldData.getEntityTickingChunks().iterator(); // Folia - region threading } else { - iterator1 = this.entityTickingChunks.unsafeIterator(); - List shuffled = Lists.newArrayListWithCapacity(this.entityTickingChunks.size()); -+ iterator1 = regionisedWorldData.getEntityTickingChunks().unsafeIterator(); // Paper - region threading -+ List shuffled = Lists.newArrayListWithCapacity(regionisedWorldData.getEntityTickingChunks().size()); // Paper - region threading ++ iterator1 = regionisedWorldData.getEntityTickingChunks().unsafeIterator(); // Folia - region threading ++ List shuffled = Lists.newArrayListWithCapacity(regionisedWorldData.getEntityTickingChunks().size()); // Folia - region threading while (iterator1.hasNext()) { shuffled.add(iterator1.next()); } @@ -12938,15 +12938,15 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec - if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) { - ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone(); - this.chunkMap.needsChangeBroadcasting.clear(); -+ if (!regionisedWorldData.getNeedsChangeBroadcasting().isEmpty()) { // Paper - region threading -+ ReferenceOpenHashSet copy = regionisedWorldData.getNeedsChangeBroadcasting().clone(); // Paper - region threading -+ regionisedWorldData.getNeedsChangeBroadcasting().clear(); // Paper - region threading ++ if (!regionisedWorldData.getNeedsChangeBroadcasting().isEmpty()) { // Folia - region threading ++ ReferenceOpenHashSet copy = regionisedWorldData.getNeedsChangeBroadcasting().clone(); // Folia - region threading ++ regionisedWorldData.getNeedsChangeBroadcasting().clear(); // Folia - region threading for (ChunkHolder holder : copy) { holder.broadcastChanges(holder.getFullChunkNowUnchecked()); // LevelChunks are NEVER unloaded if (holder.needsBroadcastChanges()) { // I DON'T want to KNOW what DUMB plugins might be doing. - this.chunkMap.needsChangeBroadcasting.add(holder); -+ regionisedWorldData.getNeedsChangeBroadcasting().add(holder); // Paper - region threading ++ regionisedWorldData.getNeedsChangeBroadcasting().add(holder); // Folia - region threading } } } @@ -12956,8 +12956,8 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec // Paper start - controlled flush for entity tracker packets - List disabledFlushes = new java.util.ArrayList<>(this.level.players.size()); - for (ServerPlayer player : this.level.players) { -+ List disabledFlushes = new java.util.ArrayList<>(regionisedWorldData.getLocalPlayers().size()); // Paper - region threading -+ for (ServerPlayer player : regionisedWorldData.getLocalPlayers()) { // Paper - region threading ++ List disabledFlushes = new java.util.ArrayList<>(regionisedWorldData.getLocalPlayers().size()); // Folia - region threading ++ for (ServerPlayer player : regionisedWorldData.getLocalPlayers()) { // Folia - region threading net.minecraft.server.network.ServerGamePacketListenerImpl connection = player.connection; if (connection != null) { connection.connection.disableAutomaticFlush(); @@ -12966,7 +12966,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec @Override public void onLightUpdate(LightLayer type, SectionPos pos) { - this.mainThreadProcessor.execute(() -> { -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.chunk().toLong()); if (playerchunk != null) { @@ -12974,12 +12974,12 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec } - }); -+ }; // Paper - region threading -+ // Paper start - region threading ++ }; // Folia - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask( + this.level, pos.getX(), pos.getZ(), run + ); -+ // Paper end - region threading ++ // Folia end - region threading } public void addRegionTicket(TicketType ticketType, ChunkPos pos, int radius, T argument) { @@ -12987,7 +12987,7 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec return ServerChunkCache.this.mainThread; } -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public void tell(Runnable runnable) { + if (true) { @@ -13019,11 +13019,11 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec + } + super.executeIfPossible(runnable); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override protected void doRunTask(Runnable task) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading ServerChunkCache.this.level.getProfiler().incrementCounter("runTask"); super.doRunTask(task); } @@ -13031,22 +13031,22 @@ index 736f37979c882e41e7571202df38eb6a2923fcb0..1cc6c4d0e9b3b3de2c07de11e8c0b9ec @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { -+ // Paper start - region threading ++ // Folia start - region threading + if (ServerChunkCache.this.level != io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionisedWorldData().world) { + throw new IllegalStateException("Polling tasks from non-owned region"); + } -+ // Paper end - region threading ++ // Folia end - region threading ServerChunkCache.this.chunkMap.level.playerChunkLoader.tickMidTick(); // Paper - replace player chunk loader if (ServerChunkCache.this.runDistanceManagerUpdates()) { return true; } - return super.pollTask() | ServerChunkCache.this.level.chunkTaskScheduler.executeMainThreadTask(); // Paper - rewrite chunk system -+ return io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion().getData().getTaskQueueData().executeChunkTask(); // Paper - rewrite chunk system // Paper - region threading ++ return io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion().getData().getTaskQueueData().executeChunkTask(); // Paper - rewrite chunk system // Folia - region threading } } diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924dd7657be 100644 +index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..53b21c1d78f6ab0816343f1a6264671ca828b519 100644 --- a/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 { @@ -13054,7 +13054,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 private final MinecraftServer server; public final PrimaryLevelData serverLevelData; // CraftBukkit - type - final EntityTickList entityTickList; -+ //final EntityTickList entityTickList; // Paper - region threading ++ //final EntityTickList entityTickList; // Folia - region threading //public final PersistentEntitySectionManager entityManager; // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; @@ -13063,17 +13063,17 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 private final PortalForcer portalForcer; - private final LevelTicks blockTicks; - private final LevelTicks fluidTicks; -+ //private final LevelTicks blockTicks; // Paper - region threading -+ //private final LevelTicks fluidTicks; // Paper - region threading ++ //private final LevelTicks blockTicks; // Folia - region threading ++ //private final LevelTicks fluidTicks; // Folia - region threading final Set navigatingMobs; volatile boolean isUpdatingNavigations; protected final Raids raids; - private final ObjectLinkedOpenHashSet blockEvents; - private final List blockEventsToReschedule; - private boolean handlingTick; -+ //private final ObjectLinkedOpenHashSet blockEvents; // Paper - region threading -+ //private final List blockEventsToReschedule; // Paper - region threading -+ //private boolean handlingTick; // Paper - region threading ++ //private final ObjectLinkedOpenHashSet blockEvents; // Folia - region threading ++ //private final List blockEventsToReschedule; // Folia - region threading ++ //private boolean handlingTick; // Folia - region threading private final List customSpawners; @Nullable private final EndDragonFight dragonFight; @@ -13082,15 +13082,15 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 private final StructureCheck structureCheck; - private final boolean tickTime; - public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick -+ public final boolean tickTime; // Paper - region threading -+ // Paper - region threading ++ public final boolean tickTime; // Folia - region threading ++ // Folia - region threading // CraftBukkit start public final LevelStorageSource.LevelStorageAccess convertable; public final UUID uuid; - public boolean hasPhysicsEvent = true; // Paper - public boolean hasEntityMoveEvent = false; // Paper -+ // Paper - region threading ++ // Folia - region threading private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) public static Throwable getAddToWorldStackTrace(Entity entity) { final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); @@ -13106,7 +13106,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - }); - return; - } -+ // Paper start - region threading - TODO rebase ++ // Folia start - region threading - TODO rebase + public final void loadChunksAsync(BlockPos pos, int radiusBlocks, + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, + java.util.function.Consumer> onLoad) { @@ -13196,11 +13196,11 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } } } -+ // Paper end - region threading - TODO rebase ++ // Folia end - region threading - TODO rebase + + public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority, + java.util.function.Consumer> onLoad) { -+ // Paper - region threading - TODO MERGE INTO CHUNK SYSTEM PATCH ++ // Folia - region threading - TODO MERGE INTO CHUNK SYSTEM PATCH + + int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; + int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; @@ -13214,7 +13214,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + int minChunkZ = minBlockZ >> 4; + int maxChunkZ = maxBlockZ >> 4; + -+ this.loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, priority, onLoad); // Paper - region threading - move into own function TODO rebase ++ this.loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, priority, onLoad); // Folia - region threading - move into own function TODO rebase + } // Paper start - rewrite chunk system @@ -13224,7 +13224,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 // Paper start - optimise checkDespawn - public final List playersAffectingSpawning = new java.util.ArrayList<>(); -+ // Paper - region threading ++ // Folia - region threading // Paper end - optimise checkDespawn // Paper start - optimise get nearest players for entity AI - @Override @@ -13236,7 +13236,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - if (nearby == null) { - return null; - } -+ // Paper - region threading ++ // Folia - region threading - Object[] backingSet = nearby.getBackingSet(); - @@ -13259,7 +13259,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - - return closest; - } -+ // Paper - region threading ++ // Folia - region threading - @Override - public Player getNearestPlayer(net.minecraft.world.entity.ai.targeting.TargetingConditions pathfindertargetcondition, LivingEntity entityliving) { @@ -13298,11 +13298,11 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - ret.add(player); - } - } -+ // Paper - region threading ++ // Folia - region threading - return ret; - } -+ // Paper - region threading ++ // Folia - region threading // 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); @@ -13310,7 +13310,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 }); } -+ // Paper start - regionised ticking ++ // Folia start - regionised ticking + public final io.papermc.paper.threadedregions.TickRegions tickRegions = new io.papermc.paper.threadedregions.TickRegions(); + public final io.papermc.paper.threadedregions.ThreadedRegioniser regioniser; + { @@ -13331,7 +13331,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + public final java.util.concurrent.atomic.AtomicInteger checkInitialised = new java.util.concurrent.atomic.AtomicInteger(WORLD_INIT_NOT_CHECKED); + public ChunkPos randomSpawnSelection; + -+ // Paper end - regionised ticking ++ // Folia end - regionised ticking + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { @@ -13344,15 +13344,15 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - this.entityTickList = new EntityTickList(); - this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); - this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); -+ this.players = new java.util.concurrent.CopyOnWriteArrayList<>(); // Paper - region threading -+ //this.entityTickList = new EntityTickList(); // Paper - region threading -+ //this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); // Paper - moved to RegioniedWorldData -+ //this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); // Paper - moved to RegioniedWorldData ++ this.players = new java.util.concurrent.CopyOnWriteArrayList<>(); // Folia - region threading ++ //this.entityTickList = new EntityTickList(); // Folia - region threading ++ //this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); // Folia - moved to RegioniedWorldData ++ //this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); // Folia - moved to RegioniedWorldData this.navigatingMobs = new ObjectOpenHashSet(); - this.blockEvents = new ObjectLinkedOpenHashSet(); - this.blockEventsToReschedule = new ArrayList(64); -+ //this.blockEvents = new ObjectLinkedOpenHashSet(); // Paper - moved to RegioniedWorldData -+ //this.blockEventsToReschedule = new ArrayList(64); // Paper - moved to RegioniedWorldData ++ //this.blockEvents = new ObjectLinkedOpenHashSet(); // Folia - moved to RegioniedWorldData ++ //this.blockEventsToReschedule = new ArrayList(64); // Folia - moved to RegioniedWorldData this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; @@ -13361,7 +13361,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 this.chunkSource.getGeneratorState().ensureStructuresGenerated(); this.portalForcer = new PortalForcer(this); - this.updateSkyBrightness(); -+ //this.updateSkyBrightness(); // Paper - region threading - delay until first tick ++ //this.updateSkyBrightness(); // Folia - region threading - delay until first tick this.prepareWeather(); this.getWorldBorder().setAbsoluteMaxSize(minecraftserver.getAbsoluteMaxWorldSize()); this.raids = (Raids) this.getDataStorage().computeIfAbsent((nbttagcompound) -> { @@ -13369,14 +13369,14 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 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.updateTickData(); // Paper - region threading - make sure it is initialised before ticked ++ this.updateTickData(); // Folia - region threading - make sure it is initialised before ticked } -+ // Paper start - region threading ++ // Folia start - region threading + public void updateTickData() { + this.tickData = new io.papermc.paper.threadedregions.RegionisedServer.WorldLevelData(this, this.serverLevelData.getGameTime(), this.serverLevelData.getDayTime()); + } -+ // Paper end - region threading ++ // Folia end - region threading + public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) { this.serverLevelData.setClearWeatherTime(clearDuration); @@ -13394,16 +13394,16 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - } - } - // Paper end - optimise checkDespawn -+ public void tick(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Paper - regionised ticking -+ final io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.getCurrentWorldData(); // Paper - regionised ticking -+ // Paper - region threading ++ public void tick(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking ++ final io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking ++ // Folia - region threading ProfilerFiller gameprofilerfiller = this.getProfiler(); - this.handlingTick = true; -+ regionisedWorldData.setHandlingTick(true); // Paper - regionised ticking ++ regionisedWorldData.setHandlingTick(true); // Folia - regionised ticking gameprofilerfiller.push("world border"); - this.getWorldBorder().tick(); -+ if (region == null) this.getWorldBorder().tick(); // Paper - regionised ticking - moved into global tick ++ if (region == null) this.getWorldBorder().tick(); // Folia - regionised ticking - moved into global tick gameprofilerfiller.popPush("weather"); - this.advanceWeatherCycle(); + if (region == null) this.advanceWeatherCycle(); @@ -13411,7 +13411,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 long j; - if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { -+ if (region != null && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { // Paper - region threading - TODO bring this back ++ if (region != null && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { // Folia - region threading - TODO bring this back // CraftBukkit start j = this.levelData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime()); @@ -13420,19 +13420,19 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - this.updateSkyBrightness(); -+ if (region == null) this.updateSkyBrightness(); // Paper - region threading ++ if (region == null) this.updateSkyBrightness(); // Folia - region threading this.tickTime(); gameprofilerfiller.popPush("tickPending"); timings.scheduledBlocks.startTiming(); // Paper if (!this.isDebug()) { - j = this.getGameTime(); -+ j = regionisedWorldData.getRedstoneGameTime(); // Paper - region threading ++ j = regionisedWorldData.getRedstoneGameTime(); // Folia - region threading gameprofilerfiller.push("blockTicks"); - this.blockTicks.tick(j, 65536, this::tickBlock); -+ regionisedWorldData.getBlockLevelTicks().tick(j, 65536, this::tickBlock); // Paper - region ticking ++ regionisedWorldData.getBlockLevelTicks().tick(j, 65536, this::tickBlock); // Folia - region ticking gameprofilerfiller.popPush("fluidTicks"); - this.fluidTicks.tick(j, 65536, this::tickFluid); -+ regionisedWorldData.getFluidLevelTicks().tick(j, 65536, this::tickFluid); // Paper - region ticking ++ regionisedWorldData.getFluidLevelTicks().tick(j, 65536, this::tickFluid); // Folia - region ticking gameprofilerfiller.pop(); } timings.scheduledBlocks.stopTiming(); // Paper @@ -13440,7 +13440,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 gameprofilerfiller.popPush("raid"); this.timings.raids.startTiming(); // Paper - timings - this.raids.tick(); -+ if (region == null) this.raids.tick(); // Paper - region threading - TODO fucking RAIDS ++ if (region == null) this.raids.tick(); // Folia - region threading - TODO fucking RAIDS this.timings.raids.stopTiming(); // Paper - timings gameprofilerfiller.popPush("chunkSource"); this.timings.chunkProviderTick.startTiming(); // Paper - timings @@ -13449,7 +13449,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 this.runBlockEvents(); timings.doSounds.stopTiming(); // Spigot - this.handlingTick = false; -+ regionisedWorldData.setHandlingTick(false); // Paper - regionised ticking ++ regionisedWorldData.setHandlingTick(false); // Folia - regionised ticking gameprofilerfiller.pop(); boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players @@ -13457,31 +13457,31 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 gameprofilerfiller.push("entities"); timings.tickEntities.startTiming(); // Spigot if (this.dragonFight != null) { -+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this, 0, 0)) { // Paper - region threading ++ if (io.papermc.paper.util.TickThread.isTickThreadFor(this, 0, 0)) { // Folia - region threading gameprofilerfiller.push("dragonFight"); this.dragonFight.tick(); gameprofilerfiller.pop(); -+ } else { // Paper start - region threading ++ } else { // Folia start - region threading + // try to load dragon fight + ChunkPos fightCenter = new ChunkPos(0, 0); + this.chunkSource.addTicketAtLevel( + TicketType.UNKNOWN, fightCenter, io.papermc.paper.chunk.system.scheduling.ChunkHolderManager.MAX_TICKET_LEVEL, + fightCenter + ); -+ } // Paper end - region threading ++ } // Folia end - region threading } org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot - this.entityTickList.forEach((entity) -> { -+ regionisedWorldData.forEachTickingEntity((entity) -> { // Paper - regionised ticking ++ regionisedWorldData.forEachTickingEntity((entity) -> { // Folia - regionised ticking if (!entity.isRemoved()) { if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); } else { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); -+ if (entity.isRemoved()) return; // Paper - region threading - if we despawned, DON'T TICK IT! ++ if (entity.isRemoved()) return; // Folia - region threading - if we despawned, DON'T TICK IT! gameprofilerfiller.pop(); if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list Entity entity1 = entity.getVehicle(); @@ -13490,15 +13490,15 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 protected void tickTime() { if (this.tickTime) { - long i = this.levelData.getGameTime() + 1L; -+ io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.getCurrentWorldData(); // Paper - region threading -+ long i = regionisedWorldData.getRedstoneGameTime() + 1L; // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = this.getCurrentWorldData(); // Folia - region threading ++ long i = regionisedWorldData.getRedstoneGameTime() + 1L; // Folia - region threading - this.serverLevelData.setGameTime(i); - this.serverLevelData.getScheduledEvents().tick(this.server, i); - if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { -+ regionisedWorldData.setRedstoneGameTime(i); // Paper - region threading -+ if (false) this.serverLevelData.getScheduledEvents().tick(this.server, i); // Paper - region threading - TODO any way to bring this in? -+ if (false && this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { // Paper - region threading ++ regionisedWorldData.setRedstoneGameTime(i); // Folia - region threading ++ if (false) this.serverLevelData.getScheduledEvents().tick(this.server, i); // Folia - region threading - TODO any way to bring this in? ++ if (false && this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { // Folia - region threading this.setDayTime(this.levelData.getDayTime() + 1L); } @@ -13508,12 +13508,12 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 // Paper start - optimise random block ticking - private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos(); - private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong()); -+ private final ThreadLocal chunkTickMutablePosition = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos()); // Paper - region threading -+ private final ThreadLocal randomTickRandom = ThreadLocal.withInitial(() -> new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong())); // Paper - region threading ++ private final ThreadLocal chunkTickMutablePosition = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos()); // Folia - region threading ++ private final ThreadLocal randomTickRandom = ThreadLocal.withInitial(() -> new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong())); // Folia - region threading // Paper end public void tickChunk(LevelChunk chunk, int randomTickSpeed) { -+ io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = this.randomTickRandom.get(); // Paper - region threading ++ io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = this.randomTickRandom.get(); // Folia - region threading ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); int j = chunkcoordintpair.getMinBlockX(); @@ -13522,7 +13522,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 gameprofilerfiller.push("thunder"); - final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change -+ final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition.get(); // Paper - use mutable to reduce allocation rate, final to force compile fail on change // Paper - region threading ++ final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition.get(); // Paper - use mutable to reduce allocation rate, final to force compile fail on change // Folia - region threading 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 @@ -13531,7 +13531,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 for (int a = 0; a < randomTickSpeed; ++a) { int tickingBlocks = section.tickingList.size(); - int index = this.randomTickRandom.nextInt(16 * 16 * 16); -+ int index = randomTickRandom.nextInt(16 * 16 * 16); // Paper - region threading ++ int index = randomTickRandom.nextInt(16 * 16 * 16); // Folia - region threading if (index >= tickingBlocks) { continue; } @@ -13540,7 +13540,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw); - iblockdata.randomTick(this, blockposition2, this.randomTickRandom); -+ iblockdata.randomTick(this, blockposition2, randomTickRandom); // Paper - region threading ++ iblockdata.randomTick(this, blockposition2, randomTickRandom); // Folia - region threading // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock). // TODO CHECK ON UPDATE (ping the Canadian) } @@ -13549,7 +13549,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public boolean isHandlingTick() { - return this.handlingTick; -+ return this.getCurrentWorldData().isHandlingTick(); // Paper - regionised ticking ++ return this.getCurrentWorldData().isHandlingTick(); // Folia - regionised ticking } public boolean canSleepThroughNights() { @@ -13557,7 +13557,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } public void updateSleepingPlayerList() { -+ if (true) return; // Paper - region threading - TODO figure this shit out ++ if (true) return; // Folia - region threading - TODO figure this shit out if (!this.players.isEmpty() && this.sleepStatus.update(this.players)) { this.announceSleepStatus(); } @@ -13566,7 +13566,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - private void advanceWeatherCycle() { -+ public void advanceWeatherCycle() { // Paper - region threading - public ++ public void advanceWeatherCycle() { // Folia - region threading - public boolean flag = this.isRaining(); if (this.dimensionType().hasSkyLight()) { @@ -13577,10 +13577,10 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - for (int idx = 0; idx < this.players.size(); ++idx) { - if (((ServerPlayer) this.players.get(idx)).level == this) { - ((ServerPlayer) this.players.get(idx)).tickWeather(); -+ ServerPlayer[] players = this.players.toArray(new ServerPlayer[0]); // Paper - region threading -+ for (ServerPlayer player : players) { // Paper - region threading -+ if (player.level == this) { // Paper - region threading -+ player.tickWeather(); // Paper - region threading ++ ServerPlayer[] players = this.players.toArray(new ServerPlayer[0]); // Folia - region threading ++ for (ServerPlayer player : players) { // Folia - region threading ++ if (player.level == this) { // Folia - region threading ++ player.tickWeather(); // Folia - region threading } } @@ -13589,18 +13589,18 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - for (int idx = 0; idx < this.players.size(); ++idx) { - if (((ServerPlayer) this.players.get(idx)).level == this) { - ((ServerPlayer) this.players.get(idx)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); -+ for (ServerPlayer player : players) { // Paper - region threading -+ if (player.level == this) { // Paper - region threading -+ player.setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); // Paper - region threading ++ for (ServerPlayer player : players) { // Folia - region threading ++ if (player.level == this) { // Folia - region threading ++ player.setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); // Folia - region threading } } } - for (int idx = 0; idx < this.players.size(); ++idx) { - if (((ServerPlayer) this.players.get(idx)).level == this) { - ((ServerPlayer) this.players.get(idx)).updateWeather(this.oRainLevel, this.rainLevel, this.oThunderLevel, this.thunderLevel); -+ for (ServerPlayer player : players) { // Paper - region threading -+ if (player.level == this) { // Paper - region threading -+ player.updateWeather(this.oRainLevel, this.rainLevel, this.oThunderLevel, this.thunderLevel); // Paper - region threading ++ for (ServerPlayer player : players) { // Folia - region threading ++ if (player.level == this) { // Folia - region threading ++ player.updateWeather(this.oRainLevel, this.rainLevel, this.oThunderLevel, this.thunderLevel); // Folia - region threading } } // CraftBukkit end @@ -13609,7 +13609,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public void tickNonPassenger(Entity entity) { // Paper start - log detailed entity tick information - io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); -+ io.papermc.paper.util.TickThread.ensureTickThread(entity, "Cannot tick an entity off-main"); // Paper - region threading ++ io.papermc.paper.util.TickThread.ensureTickThread(entity, "Cannot tick an entity off-main"); // Folia - region threading try { if (currentlyTickingEntity.get() == null) { currentlyTickingEntity.lazySet(entity); @@ -13618,7 +13618,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 TimingHistory.activatedEntityTicks++; entity.tick(); - entity.postTick(); // CraftBukkit -+ // Paper start - region threading ++ // Folia start - region threading + if (!io.papermc.paper.util.TickThread.isTickThreadFor(entity)) { + // removed from region while ticking + return; @@ -13627,7 +13627,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + // portalled + return; + } -+ // Paper end - region threading ++ // Folia end - region threading } else { entity.inactiveTick(); } // Paper - EAR 2 this.getProfiler().pop(); } finally { timer.stopTiming(); } // Paper - timings @@ -13636,7 +13636,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 private void tickPassenger(Entity vehicle, Entity passenger) { if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { - if (passenger instanceof Player || this.entityTickList.contains(passenger)) { -+ if (passenger instanceof Player || this.getCurrentWorldData().hasEntityTickingEntity(passenger)) { // Paper - region threading ++ if (passenger instanceof Player || this.getCurrentWorldData().hasEntityTickingEntity(passenger)) { // Folia - region threading // Paper - EAR 2 final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper @@ -13645,7 +13645,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 if (isActive) { passenger.rideTick(); - passenger.postTick(); // CraftBukkit -+ // Paper start - region threading ++ // Folia start - region threading + if (!io.papermc.paper.util.TickThread.isTickThreadFor(passenger)) { + // removed from region while ticking + return; @@ -13654,7 +13654,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + // portalled + return; + } -+ // Paper end - region threading ++ // Folia end - region threading } else { passenger.setDeltaMovement(Vec3.ZERO); passenger.inactiveTick(); @@ -13662,14 +13662,14 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 // Paper - rewrite chunk system - entity saving moved into ChunkHolder } else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system -+ // Paper - move into saveLevelData() ++ // Folia - move into saveLevelData() + } -+ public void saveLevelData() { // Paper - region threading ++ public void saveLevelData() { // Folia - region threading + if (this.dragonFight != null) { + this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit + } -+ // Paper start - region threading ++ // Folia start - region threading + // moved from save // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; @@ -13684,7 +13684,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - if (this.dragonFight != null) { - this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit - } -+ // Paper end - region threading ++ // Folia end - region threading this.getChunkSource().getDataStorage().save(); } @@ -13692,7 +13692,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 return list; } -+ // Paper start - region threading ++ // Folia start - region threading + @Nullable + public ServerPlayer getRandomLocalPlayer() { + List list = this.getLocalPlayers(); @@ -13703,7 +13703,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + + return list.isEmpty() ? null : (ServerPlayer) list.get(this.random.nextInt(list.size())); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable public ServerPlayer getRandomPlayer() { @@ -13714,8 +13714,8 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 // Paper start - capture all item additions to the world - if (captureDrops != null && entity instanceof net.minecraft.world.entity.item.ItemEntity) { - captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity); -+ if (this.getCurrentWorldData().captureDrops != null && entity instanceof net.minecraft.world.entity.item.ItemEntity) { // Paper - region threading -+ this.getCurrentWorldData().captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity); // Paper - region threading ++ if (this.getCurrentWorldData().captureDrops != null && entity instanceof net.minecraft.world.entity.item.ItemEntity) { // Folia - region threading ++ this.getCurrentWorldData().captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity); // Folia - region threading return true; } // Paper end @@ -13724,7 +13724,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 @Override public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { - if (this.isUpdatingNavigations) { -+ if (false && this.isUpdatingNavigations) { // Paper - region threading ++ if (false && this.isUpdatingNavigations) { // Folia - region threading String s = "recursive call to sendBlockUpdated"; Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated")); @@ -13733,7 +13733,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) { List list = new ObjectArrayList(); - Iterator iterator = this.navigatingMobs.iterator(); -+ Iterator iterator = this.getCurrentWorldData().getNavigatingMobs(); // Paper - region threading ++ Iterator iterator = this.getCurrentWorldData().getNavigatingMobs(); // Folia - region threading while (iterator.hasNext()) { // CraftBukkit start - fix SPIGOT-6362 @@ -13742,7 +13742,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 try { - this.isUpdatingNavigations = true; -+ //this.isUpdatingNavigations = true; // Paper - region threading ++ //this.isUpdatingNavigations = true; // Folia - region threading iterator = list.iterator(); while (iterator.hasNext()) { @@ -13751,7 +13751,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } } finally { - this.isUpdatingNavigations = false; -+ //this.isUpdatingNavigations = false; // Paper - region threading ++ //this.isUpdatingNavigations = false; // Folia - region threading } } @@ -13761,26 +13761,26 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { - if (captureBlockStates) { return; } // Paper - Cancel all physics during placement - this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null); -+ if (this.getCurrentWorldData().captureBlockStates) { return; } // Paper - Cancel all physics during placement // Paper - region threading -+ this.getCurrentWorldData().neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null); // Paper - region threading ++ if (this.getCurrentWorldData().captureBlockStates) { return; } // Paper - Cancel all physics during placement // Folia - region threading ++ this.getCurrentWorldData().neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null); // Folia - region threading } @Override public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block sourceBlock, Direction direction) { - this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction); -+ this.getCurrentWorldData().neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction); // Paper - region threading ++ this.getCurrentWorldData().neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction); // Folia - region threading } @Override public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos sourcePos) { - this.neighborUpdater.neighborChanged(pos, sourceBlock, sourcePos); -+ this.getCurrentWorldData().neighborUpdater.neighborChanged(pos, sourceBlock, sourcePos); // Paper - region threading ++ this.getCurrentWorldData().neighborUpdater.neighborChanged(pos, sourceBlock, sourcePos); // Folia - region threading } @Override public void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { - this.neighborUpdater.neighborChanged(state, pos, sourceBlock, sourcePos, notify); -+ this.getCurrentWorldData().neighborUpdater.neighborChanged(state, pos, sourceBlock, sourcePos, notify); // Paper - region threading ++ this.getCurrentWorldData().neighborUpdater.neighborChanged(state, pos, sourceBlock, sourcePos, notify); // Folia - region threading } @Override @@ -13789,7 +13789,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - Iterator iterator = this.players.iterator(); -+ Iterator iterator = this.getLocalPlayers().iterator(); // Paper - region thraeding ++ Iterator iterator = this.getLocalPlayers().iterator(); // Folia - region thraeding while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); @@ -13798,20 +13798,20 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 @Override public void blockEvent(BlockPos pos, Block block, int type, int data) { - this.blockEvents.add(new BlockEventData(pos, block, type, data)); -+ this.getCurrentWorldData().pushBlockEvent(new BlockEventData(pos, block, type, data)); // Paper - regionised ticking ++ this.getCurrentWorldData().pushBlockEvent(new BlockEventData(pos, block, type, data)); // Folia - regionised ticking } private void runBlockEvents() { - this.blockEventsToReschedule.clear(); -+ List blockEventsToReschedule = new ArrayList<>(64); // Paper - regionised ticking ++ List blockEventsToReschedule = new ArrayList<>(64); // Folia - regionised ticking - while (!this.blockEvents.isEmpty()) { - BlockEventData blockactiondata = (BlockEventData) this.blockEvents.removeFirst(); -+ // Paper start - regionised ticking ++ // Folia start - regionised ticking + io.papermc.paper.threadedregions.RegionisedWorldData worldRegionData = this.getCurrentWorldData(); + BlockEventData blockactiondata; + while ((blockactiondata = worldRegionData.removeFirstBlockEvent()) != null) { -+ // Paper end - regionised ticking ++ // Folia end - regionised ticking if (this.shouldTickBlocksAt(blockactiondata.pos())) { if (this.doBlockEvent(blockactiondata)) { @@ -13819,12 +13819,12 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } } else { - this.blockEventsToReschedule.add(blockactiondata); -+ blockEventsToReschedule.add(blockactiondata); // Paper - regionised ticking ++ blockEventsToReschedule.add(blockactiondata); // Folia - regionised ticking } } - this.blockEvents.addAll(this.blockEventsToReschedule); -+ worldRegionData.pushBlockEvents(blockEventsToReschedule); // Paper - regionised ticking ++ worldRegionData.pushBlockEvents(blockEventsToReschedule); // Folia - regionised ticking } private boolean doBlockEvent(BlockEventData event) { @@ -13833,13 +13833,13 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 @Override public LevelTicks getBlockTicks() { - return this.blockTicks; -+ return this.getCurrentWorldData().getBlockLevelTicks(); // Paper - region ticking ++ return this.getCurrentWorldData().getBlockLevelTicks(); // Folia - region ticking } @Override public LevelTicks getFluidTicks() { - return this.fluidTicks; -+ return this.getCurrentWorldData().getFluidLevelTicks(); // Paper - region ticking ++ return this.getCurrentWorldData().getFluidLevelTicks(); // Folia - region ticking } @Nonnull @@ -13848,7 +13848,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public 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 - return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force); -+ return sendParticles(this.getLocalPlayers(), sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force); // Paper - region threading ++ return sendParticles(this.getLocalPlayers(), sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force); // Folia - region threading } public int sendParticles(List 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 @@ -13857,14 +13857,14 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 Entity entity = (Entity) this.getEntities().get(id); - return entity != null ? entity : (Entity) this.dragonParts.get(id); -+ // Paper start - region threading ++ // Folia start - region threading + if (entity != null) { + return entity; + } + synchronized (this.dragonParts) { + return this.dragonParts.get(id); + } -+ // Paper end - region threading ++ // Folia end - region threading } @Nullable @@ -13872,7 +13872,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 return (Entity) this.getEntities().get(uuid); } -+ // Paper start - region threading ++ // Folia start - region threading + private final java.util.concurrent.atomic.AtomicLong nonFullSyncLoadIdGenerator = new java.util.concurrent.atomic.AtomicLong(); + + private ChunkAccess getIfAboveStatus(int chunkX, int chunkZ, net.minecraft.world.level.chunk.ChunkStatus status) { @@ -13925,7 +13925,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 + + return loaded; + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable public BlockPos findNearestMapStructure(TagKey structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) { @@ -13935,7 +13935,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 flag1 = forcedchunk.getChunks().add(k); if (flag1) { - this.getChunk(x, z); -+ //this.getChunk(x, z); // Paper - region threading - we must let the chunk load asynchronously ++ //this.getChunk(x, z); // Folia - region threading - we must let the chunk load asynchronously } } else { flag1 = forcedchunk.getChunks().remove(k); @@ -13944,20 +13944,20 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 optional.ifPresent((holder) -> { - this.getServer().execute(() -> { -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading this.getPoiManager().remove(blockposition1); DebugPackets.sendPoiRemovedPacket(this, blockposition1); - }); -+ }; // Paper - region threading -+ // Paper start - region threading ++ }; // Folia - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask( + this, blockposition1.getX() >> 4, blockposition1.getZ() >> 4, run + ); -+ // Paper end - region threading ++ // Folia end - region threading }); optional1.ifPresent((holder) -> { - this.getServer().execute(() -> { -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading // Paper start if (optional.isEmpty() && this.getPoiManager().exists(blockposition1, poiType -> true)) { this.getPoiManager().remove(blockposition1); @@ -13966,12 +13966,12 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 this.getPoiManager().add(blockposition1, holder); DebugPackets.sendPoiAddedPacket(this, blockposition1); - }); -+ }; // Paper - region threading -+ // Paper start - region threading ++ }; // Folia - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask( + this, blockposition1.getX() >> 4, blockposition1.getZ() >> 4, run + ); -+ // Paper end - region threading ++ // Folia end - region threading }); } } @@ -13980,7 +13980,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 try { - bufferedwriter.write(String.format(Locale.ROOT, "spawning_chunks: %d\n", playerchunkmap.getDistanceManager().getNaturalSpawnChunkCount())); -+ //bufferedwriter.write(String.format(Locale.ROOT, "spawning_chunks: %d\n", playerchunkmap.getDistanceManager().getNaturalSpawnChunkCount())); // Paper - region threading ++ //bufferedwriter.write(String.format(Locale.ROOT, "spawning_chunks: %d\n", playerchunkmap.getDistanceManager().getNaturalSpawnChunkCount())); // Folia - region threading NaturalSpawner.SpawnState spawnercreature_d = this.getChunkSource().getLastSpawnState(); if (spawnercreature_d != null) { @@ -13989,7 +13989,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityLookup.getDebugInfo())); // Paper - rewrite chunk system - bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); -+ //bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); // Paper - region threading ++ //bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); // Folia - region threading 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("distance_manager: " + playerchunkmap.getDistanceManager().getDebugStatus() + "\n"); @@ -13998,7 +13998,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 private void dumpBlockEntityTickers(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(writer); - Iterator iterator = this.blockEntityTickers.iterator(); -+ Iterator iterator = null; // Paper - region threading ++ Iterator iterator = null; // Folia - region threading while (iterator.hasNext()) { TickingBlockEntity tickingblockentity = (TickingBlockEntity) iterator.next(); @@ -14007,7 +14007,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 @VisibleForTesting public void clearBlockEvents(BoundingBox box) { - this.blockEvents.removeIf((blockactiondata) -> { -+ this.getCurrentWorldData().removeIfBlockEvents((blockactiondata) -> { // Paper - regionised ticking ++ this.getCurrentWorldData().removeIfBlockEvents((blockactiondata) -> { // Folia - regionised ticking return box.isInside(blockactiondata.pos()); }); } @@ -14016,7 +14016,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 if (!this.isDebug()) { // CraftBukkit start - if (populating) { -+ if (this.getCurrentWorldData().populating) { // Paper - region threading ++ if (this.getCurrentWorldData().populating) { // Folia - region threading return; } // CraftBukkit end @@ -14027,7 +14027,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - return String.format(Locale.ROOT, "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s", this.players.size(), this.entityLookup.getDebugInfo(), ServerLevel.getTypeCount(this.entityLookup.getAll(), (entity) -> { // Paper - rewrite chunk system - return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); - }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); -+ return "region threading"; // Paper - region threading ++ return "region threading"; // Folia - region threading } private static String getTypeCount(Iterable items, Function classifier) { @@ -14035,12 +14035,12 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public static void makeObsidianPlatform(ServerLevel worldserver, Entity entity) { // CraftBukkit end BlockPos blockposition = ServerLevel.END_SPAWN_POINT; -+ // Paper start - region threading ++ // Folia start - region threading + makeObsidianPlatform(worldserver, entity, blockposition); + } + + public static void makeObsidianPlatform(ServerLevel worldserver, Entity entity, BlockPos blockposition) { -+ // Paper end - region threading ++ // Folia end - region threading int i = blockposition.getX(); int j = blockposition.getY() - 2; int k = blockposition.getZ(); @@ -14053,7 +14053,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 - - worldserver.getCraftServer().getPluginManager().callEvent(portalEvent); - if (!portalEvent.isCancelled()) { -+ if (true) { // Paper - region threading ++ if (true) { // Folia - region threading blockList.updateList(); } // CraftBukkit end @@ -14062,20 +14062,20 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public void startTickingChunk(LevelChunk chunk) { - chunk.unpackTicks(this.getLevelData().getGameTime()); -+ chunk.unpackTicks(this.getRedstoneGameTime()); // Paper - region threading ++ chunk.unpackTicks(this.getRedstoneGameTime()); // Folia - region threading } public void onStructureStartsAvailable(ChunkAccess chunk) { - this.server.execute(() -> { - this.structureCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts()); - }); -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask( + this, chunk.getPos().x, chunk.getPos().z, () -> { + this.structureCheck.onStructureLoad(chunk.getPos(), chunk.getAllStarts()); + } + ); -+ // Paper end - region threading ++ // Folia end - region threading } @Override @@ -14084,7 +14084,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { -+ public boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { // Paper - region threaded - make public ++ public boolean isPositionTickingWithEntitiesLoaded(long chunkPos) { // Folia - region threaded - make public // Paper start - optimize is ticking ready type functions 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 @@ -14093,18 +14093,18 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 public void onDestroyed(Entity entity) { - ServerLevel.this.getScoreboard().entityRemoved(entity); -+ // ServerLevel.this.getScoreboard().entityRemoved(entity); // Paper - region threading ++ // ServerLevel.this.getScoreboard().entityRemoved(entity); // Folia - region threading } public void onTickingStart(Entity entity) { if (entity instanceof net.minecraft.world.entity.Marker) return; // Paper - Don't tick markers - ServerLevel.this.entityTickList.add(entity); -+ ServerLevel.this.getCurrentWorldData().addEntityTickingEntity(entity); // Paper - region threading ++ ServerLevel.this.getCurrentWorldData().addEntityTickingEntity(entity); // Folia - region threading } public void onTickingEnd(Entity entity) { - ServerLevel.this.entityTickList.remove(entity); -+ ServerLevel.this.getCurrentWorldData().removeEntityTickingEntity(entity); // Paper - region threading ++ ServerLevel.this.getCurrentWorldData().removeEntityTickingEntity(entity); // Folia - region threading // Paper start - Reset pearls when they stop being ticked if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { pearl.cachedOwner = null; @@ -14113,7 +14113,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - ServerLevel.this.navigatingMobs.add(entityinsentient); -+ ServerLevel.this.getCurrentWorldData().addNavigatingMob(entityinsentient); // Paper - region threading ++ ServerLevel.this.getCurrentWorldData().addNavigatingMob(entityinsentient); // Folia - region threading } if (entity instanceof EnderDragon) { @@ -14121,9 +14121,9 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 for (int j = 0; j < i; ++j) { EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; -+ synchronized (ServerLevel.this.dragonParts) { // Paper - region threading ++ synchronized (ServerLevel.this.dragonParts) { // Folia - region threading ServerLevel.this.dragonParts.put(entitycomplexpart.getId(), entitycomplexpart); -+ } // Paper - region threading ++ } // Folia - region threading } } @@ -14132,7 +14132,7 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 } - ServerLevel.this.navigatingMobs.remove(entityinsentient); -+ ServerLevel.this.getCurrentWorldData().removeNavigatingMob(entityinsentient); // Paper - region threading ++ ServerLevel.this.getCurrentWorldData().removeNavigatingMob(entityinsentient); // Folia - region threading } if (entity instanceof EnderDragon) { @@ -14140,21 +14140,21 @@ index 714637cdd9dcdbffa344b19e77944fb3c7541ff7..89752d05e3172a83869695e2c1537924 for (int j = 0; j < i; ++j) { EnderDragonPart entitycomplexpart = aentitycomplexpart[j]; -+ synchronized (ServerLevel.this.dragonParts) { // Paper - region threading ++ synchronized (ServerLevel.this.dragonParts) { // Folia - region threading ServerLevel.this.dragonParts.remove(entitycomplexpart.getId()); -+ } // Paper - region threading ++ } // Folia - region threading } } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove); // CraftBukkit start entity.valid = false; -+ // Paper - region threading - TODO THIS SHIT ++ // Folia - region threading - TODO THIS SHIT if (!(entity instanceof ServerPlayer)) { for (ServerPlayer player : ServerLevel.this.players) { 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 -index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb237c8de5 100644 +index 869daafbc236b3ff63f878e5fe28427fde75afe5..2bfbb9c02ebd45cf632d5bee5b88d47b3b7b7bfa 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -181,7 +181,7 @@ import org.bukkit.inventory.MainHand; @@ -14162,7 +14162,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb private static final Logger LOGGER = LogUtils.getLogger(); - public long lastSave = MinecraftServer.currentTick; // Paper -+ public long lastSave = Long.MIN_VALUE; // Paper // Paper - threaded regions ++ public long lastSave = Long.MIN_VALUE; // Paper // Folia - threaded regions private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; public ServerGamePacketListenerImpl connection; @@ -14170,8 +14170,8 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb }); } -+ // Paper start - region threading -+ // Paper end - region threading ++ // Folia start - region threading ++ // Folia end - region threading + public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); @@ -14182,12 +14182,12 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb - public void fudgeSpawnLocation(ServerLevel world) { - BlockPos blockposition = world.getSharedSpawnPos(); -+ public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.Completable toComplete) { // Paper - region threading -+ BlockPos blockposition = world.getSharedSpawnPos(); final BlockPos spawnPos = blockposition; // Paper - region threading ++ public static void fudgeSpawnLocation(ServerLevel world, ServerPlayer player, ca.spottedleaf.concurrentutil.completable.Completable toComplete) { // Folia - region threading ++ BlockPos blockposition = world.getSharedSpawnPos(); final BlockPos spawnPos = blockposition; // Folia - region threading if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit - int i = Math.max(0, this.server.getSpawnRadius(world)); -+ int i = Math.max(0, MinecraftServer.getServer().getSpawnRadius(world)); // Paper - region threading ++ 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())); if (j < i) { @@ -14196,7 +14196,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb long l = k * k; int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; - int j1 = this.getCoprime(i1); -+ int j1 = getCoprime(i1); // Paper - region threading ++ int j1 = getCoprime(i1); // Folia - region threading int k1 = RandomSource.create().nextInt(i1); - for (int l1 = 0; l1 < i1; ++l1) { @@ -14210,7 +14210,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb - if (world.noCollision(this, this.getBoundingBox(), true)) { // Paper - make sure this loads chunks, we default to NOT loading now - break; - } -+ // Paper start - region threading ++ // Folia start - region threading + int[] l1 = new int[1]; + final int finalI = i; + Runnable attempt = new Runnable() { @@ -14255,14 +14255,14 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb - } + }; + attempt.run(); -+ // Paper end - region threading ++ // Folia end - region threading } else { - this.moveTo(blockposition, 0.0F, 0.0F); - - 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()); - } -+ // Paper start - region threading ++ // Folia start - region threading + world.loadChunksForMoveAsync(player.getBoundingBoxAt(blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5), + ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER, + (c) -> { @@ -14273,13 +14273,13 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb + toComplete.complete(io.papermc.paper.util.MCUtil.toLocation(world, Vec3.atBottomCenterOf(ret), world.levelData.getSpawnAngle(), 0.0f)); + } + ); -+ // Paper end - region threading ++ // Folia end - region threading } } - private int getCoprime(int horizontalSpawnArea) { -+ private static int getCoprime(int horizontalSpawnArea) { // Paper - region threading - not static ++ private static int getCoprime(int horizontalSpawnArea) { // Folia - region threading - not static return horizontalSpawnArea <= 16 ? horizontalSpawnArea - 1 : 17; } @@ -14287,7 +14287,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb } } -+ // Paper start - region threading ++ // Folia start - region threading + /** + * Teleport flag indicating that the player is to be respawned, expected to only be used + * internally for {@link #respawn(java.util.function.Consumer)}. @@ -14302,7 +14302,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb + public static final long TELEPORT_FLAGS_AVOID_SUFFOCATION = Long.MIN_VALUE >>> 1; + + private void avoidSuffocation() { -+ while (!this.getLevel().noCollision(this, this.getBoundingBox(), true) && this.getY() < (double)this.getLevel().getMaxBuildHeight()) { // Paper - make sure this loads chunks, we default to NOT loading now ++ while (!this.getLevel().noCollision(this, this.getBoundingBox(), true) && this.getY() < (double)this.getLevel().getMaxBuildHeight()) { // Folia - make sure this loads chunks, we default to NOT loading now + this.setPos(this.getX(), this.getY() + 1.0D, this.getZ()); + } + } @@ -14617,7 +14617,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb + this.enteredNetherPosition = this.position(); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable @Override @@ -14626,11 +14626,11 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb if (entity1 == entity) return; // new spec target is the current spec target -+ // Paper start - region threading ++ // Folia start - region threading + if (!io.papermc.paper.util.TickThread.isTickThreadFor(entity)) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading + if (entity == this) { com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity()); @@ -14640,7 +14640,7 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb // Make sure we're tracking the entity before sending - ChunkMap.TrackedEntity tracker = ((ServerLevel)entity.level).getChunkSource().chunkMap.entityMap.get(entity.getId()); -+ ChunkMap.TrackedEntity tracker = entity.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity tracker = entity.tracker; // Folia - region threading if (tracker != null) { // dumb plugins... tracker.updatePlayer(this); } @@ -14649,12 +14649,12 @@ index 869daafbc236b3ff63f878e5fe28427fde75afe5..ef954194ec674c81b67227110e13cddb this.totalExperience = this.newTotalExp; this.experienceProgress = 0; - this.deathTime = 0; -+ this.deathTime = 0; this.broadcastedDeath = false; // Paper - region threading ++ this.deathTime = 0; this.broadcastedDeath = false; // Folia - region threading this.setArrowCount(0, true); // CraftBukkit - ArrowBodyCountChangeEvent this.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DEATH); this.effectsDirty = true; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 58b093bb1de78ee3b3b2ea364aa50474883f443a..dd0f309f725a6548057d5975602f914b47c96ed9 100644 +index 58b093bb1de78ee3b3b2ea364aa50474883f443a..147c9baaf73d0f8c315477ee32236bc163e1736c 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java @@ -123,7 +123,7 @@ public class ServerPlayerGameMode { @@ -14662,7 +14662,7 @@ index 58b093bb1de78ee3b3b2ea364aa50474883f443a..dd0f309f725a6548057d5975602f914b public void tick() { - this.gameTicks = MinecraftServer.currentTick; // CraftBukkit; -+ ++this.gameTicks; // CraftBukkit; // Paper - region threading ++ ++this.gameTicks; // CraftBukkit; // Folia - region threading BlockState iblockdata; if (this.hasDelayedDestroy) { @@ -14671,7 +14671,7 @@ index 58b093bb1de78ee3b3b2ea364aa50474883f443a..dd0f309f725a6548057d5975602f914b // CraftBukkit start org.bukkit.block.BlockState state = bblock.getState(); - level.captureDrops = new ArrayList<>(); -+ level.getCurrentWorldData().captureDrops = new ArrayList<>(); // Paper - region threading ++ level.getCurrentWorldData().captureDrops = new ArrayList<>(); // Folia - region threading // CraftBukkit end block.playerWillDestroy(this.level, pos, iblockdata, this.player); boolean flag = this.level.removeBlock(pos, false); @@ -14681,13 +14681,13 @@ index 58b093bb1de78ee3b3b2ea364aa50474883f443a..dd0f309f725a6548057d5975602f914b // CraftBukkit start - java.util.List itemsToDrop = level.captureDrops; // Paper - store current list - level.captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff -+ java.util.List itemsToDrop = level.getCurrentWorldData().captureDrops; // Paper - store current list // Paper - region threading -+ level.getCurrentWorldData().captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff // Paper - region threading ++ java.util.List itemsToDrop = level.getCurrentWorldData().captureDrops; // Paper - store current list // Folia - region threading ++ level.getCurrentWorldData().captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff // Folia - region threading if (event.isDropItems()) { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - use stored ref } diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1dc485a326 100644 +index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..eef501b0558680e5563b0a15a93bd3ab217b91d8 100644 --- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java +++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java @@ -98,10 +98,15 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @@ -14695,16 +14695,16 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d this.theLightEngine.relightChunks(chunks, (ChunkPos chunkPos) -> { chunkLightCallback.accept(chunkPos); - ((java.util.concurrent.Executor)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().mainThreadProcessor).execute(() -> { -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong()).broadcast(new net.minecraft.network.protocol.game.ClientboundLightUpdatePacket(chunkPos, ThreadedLevelLightEngine.this, null, null, true), false); ((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().removeTicketAtLevel(TicketType.CHUNK_RELIGHT, chunkPos, io.papermc.paper.util.MCUtil.getTicketLevelFor(ChunkStatus.LIGHT), ticketIds.get(chunkPos)); - }); -+ }; // Paper - region threading -+ // Paper start - region threading ++ }; // Folia - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask( + (ServerLevel)this.theLightEngine.getWorld(), chunkPos.x, chunkPos.z, run + ); -+ // Paper end - region threading ++ // Folia end - region threading }, onComplete); }); this.tryScheduleUpdate(); @@ -14713,7 +14713,7 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d } - private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); -+ //private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); // Paper - region threading ++ //private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); // Folia - region threading private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, final Supplier> runnable) { final ServerLevel world = (ServerLevel)this.theLightEngine.getWorld(); @@ -14722,18 +14722,18 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d } - if (!world.getChunkSource().chunkMap.mainThreadExecutor.isSameThread()) { -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(world, chunkX, chunkZ)) { // Paper - region threading ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(world, chunkX, chunkZ)) { // Folia - region threading // ticket logic is not safe to run off-main, re-schedule - world.getChunkSource().chunkMap.mainThreadExecutor.execute(() -> { -+ Runnable run = () -> { // Paper - region threading ++ Runnable run = () -> { // Folia - region threading this.queueTaskForSection(chunkX, chunkY, chunkZ, runnable); - }); -+ }; // Paper - region threading -+ // Paper start - region threading ++ }; // Folia - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + world, chunkX, chunkZ, run + ); -+ // Paper end - region threading ++ // Folia end - region threading return; } @@ -14742,7 +14742,7 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d } - final int references = this.chunksBeingWorkedOn.addTo(key, 1); -+ final int references = this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.addTo(key, 1); // Paper - region threading ++ final int references = this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.addTo(key, 1); // Folia - region threading if (references == 0) { final ChunkPos pos = new ChunkPos(chunkX, chunkZ); world.getChunkSource().addRegionTicket(ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); @@ -14758,7 +14758,7 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d - this.chunksBeingWorkedOn.put(key, newReferences - 1); - } - }, world.getChunkSource().chunkMap.mainThreadExecutor).whenComplete((final Void ignore, final Throwable thr) -> { -+ // Paper start - region threading ++ // Folia start - region threading + updateFuture.thenAccept((final Void ignore) -> { + io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( + this.chunkMap.level, chunkX, chunkZ, () -> { @@ -14773,47 +14773,47 @@ index 660693c6dc0ef86f4013df980b6d0c11c03e46cd..62ff993a69035c154c7b492f0e035c1d + } + ); + }).whenComplete((final Void ignore, final Throwable thr) -> { -+ // Paper end - region threading ++ // Folia end - region threading if (thr != null) { LOGGER.error("Failed to remove ticket level for post chunk task " + new ChunkPos(chunkX, chunkZ), thr); } diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index 97d1ff2af23bac14e67bca5896843325aaa5bfc1..f3d874af5e6196a8c29069220407fcb53d4317c2 100644 +index 97d1ff2af23bac14e67bca5896843325aaa5bfc1..cf38de369a57e30a29dfa13e116f950b0dbf5904 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -35,6 +35,12 @@ public class TicketType { public static final TicketType POI_LOAD = create("poi_load", Long::compareTo); public static final TicketType UNLOAD_COOLDOWN = create("unload_cooldown", (u1, u2) -> 0, 5 * 20); // Paper end - rewrite chunk system -+ // Paper start - region threading ++ // Folia start - region threading + public static final TicketType LOGIN = create("login", (u1, u2) -> 0, 20); + public static final TicketType DELAYED = create("delay", (u1, u2) -> 0, 5); + public static final TicketType END_GATEWAY_EXIT_SEARCH = create("end_gateway_exit_search", Long::compareTo); + public static final TicketType NON_FULL_SYNC_LOAD = create("non_full_sync_load", Long::compareTo); -+ // Paper end - region threading ++ // Folia end - region threading public static TicketType create(String name, Comparator argumentComparator) { return new TicketType<>(name, argumentComparator, 0L); diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java -index 877498729c66de9aa6a27c9148f7494d7895615c..28cb049980be93c0ae7d613b82ef5232b15f3759 100644 +index 877498729c66de9aa6a27c9148f7494d7895615c..d8af2d59fb1f112f2f1a9fdbb3517fc72a2e572d 100644 --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java @@ -84,6 +84,13 @@ public class WorldGenRegion implements WorldGenLevel { private final AtomicLong subTickCount = new AtomicLong(); private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random"); -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public StructureManager structureManager() { + return this.structureManager; + } -+ // Paper end - region threading ++ // Folia end - region threading + public WorldGenRegion(ServerLevel world, List chunks, ChunkStatus status, int placementRadius) { this.generatingStatus = status; this.writeRadiusCutoff = placementRadius; diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java -index abcc3266d18f34d160eac87fdea153dce24c60b8..1a2d38b16a74f7e2698c0426a8c4503e528c68b1 100644 +index abcc3266d18f34d160eac87fdea153dce24c60b8..7cf0619883577a0f21ed75ba70ece90d5c316c21 100644 --- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java +++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java @@ -155,10 +155,13 @@ public class ServerConnectionListener { @@ -14821,13 +14821,13 @@ index abcc3266d18f34d160eac87fdea153dce24c60b8..1a2d38b16a74f7e2698c0426a8c4503e // ServerConnectionListener.this.connections.add((Connection) object); // CraftBukkit - decompile error - pending.add((Connection) object); // Paper -+ // Paper - connection fixes - move down ++ // Folia - connection fixes - move down channel.pipeline().addLast("packet_handler", (ChannelHandler) object); ((Connection) object).setListener(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object)); io.papermc.paper.network.ChannelInitializeListenerHolder.callListeners(channel); // Paper -+ // Paper start - regionised threading ++ // Folia start - regionised threading + io.papermc.paper.threadedregions.RegionisedServer.getInstance().addConnection((Connection)object); -+ // Paper end - regionised threading ++ // Folia end - regionised threading } }).group((EventLoopGroup) lazyinitvar.get()).localAddress(address)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit // Paper } @@ -14836,12 +14836,12 @@ index abcc3266d18f34d160eac87fdea153dce24c60b8..1a2d38b16a74f7e2698c0426a8c4503e this.addPending(); // Paper // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order - if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 ) -+ if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && 0 % org.spigotmc.SpigotConfig.playerShuffle == 0 ) // Paper - region threading ++ if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && 0 % org.spigotmc.SpigotConfig.playerShuffle == 0 ) // Folia - region threading { Collections.shuffle( this.connections ); } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257cab45ad4 100644 +index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..e5310e236671b432af61fea1ec545aead59caa44 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -320,10 +320,10 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic @@ -14849,12 +14849,12 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 private final org.bukkit.craftbukkit.CraftServer cserver; public boolean processedDisconnect; - private int lastTick = MinecraftServer.currentTick; -+ private long lastTick = Util.getMillis() / 50L; // Paper - region threading ++ private long lastTick = Util.getMillis() / 50L; // Folia - region threading private int allowedPlayerTicks = 1; - private int lastDropTick = MinecraftServer.currentTick; - private int lastBookTick = MinecraftServer.currentTick; -+ private long lastDropTick = Util.getMillis() / 50L; // Paper - region threading -+ private long lastBookTick = Util.getMillis() / 50L; // Paper - region threading ++ private long lastDropTick = Util.getMillis() / 50L; // Folia - region threading ++ private long lastBookTick = Util.getMillis() / 50L; // Folia - region threading private int dropCount = 0; // Get position of last block hit for BlockDamageLevel.STOPPED @@ -14862,7 +14862,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 } // CraftBukkit end -+ // Paper start - region threading ++ // Folia start - region threading + public net.minecraft.world.level.ChunkPos disconnectPos; + private static final java.util.concurrent.atomic.AtomicLong DISCONNECT_TICKET_ID_GENERATOR = new java.util.concurrent.atomic.AtomicLong(); + public static final net.minecraft.server.level.TicketType DISCONNECT_TICKET = net.minecraft.server.level.TicketType.create("disconnect_ticket", Long::compareTo); @@ -14886,16 +14886,16 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 + } + } + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override public void tick() { -+ // Paper start - region threading ++ // Folia start - region threading + this.checkKeepAlive(); + if (this.player.wonGame) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading if (this.ackBlockChangesUpTo > -1) { this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); this.ackBlockChangesUpTo = -1; @@ -14919,7 +14919,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 - this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge)); - } - } -+ // Paper - region threading - move to own method above ++ // Folia - region threading - move to own method above // Paper end this.server.getProfiler().pop(); @@ -14945,8 +14945,8 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 - } catch (ExecutionException e) { - throw new RuntimeException(e); - } -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this.player)) { // Paper - region threading -+ this.connection.disconnectSafely(PaperAdventure.asVanilla(reason), cause); // Paper - region threading - it HAS to be delayed/async to avoid deadlock if we try to wait for another region ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this.player)) { // Folia - region threading ++ this.connection.disconnectSafely(PaperAdventure.asVanilla(reason), cause); // Folia - region threading - it HAS to be delayed/async to avoid deadlock if we try to wait for another region return; } @@ -14963,11 +14963,11 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 // CraftBukkit start - handle custom speeds and skipped ticks - this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; -+ int currTick = (int)(Util.getMillis() / 50); // Paper - region threading -+ this.allowedPlayerTicks += currTick - this.lastTick; // Paper - region threading ++ int currTick = (int)(Util.getMillis() / 50); // Folia - region threading ++ this.allowedPlayerTicks += currTick - this.lastTick; // Folia - region threading this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); - this.lastTick = (int) (System.currentTimeMillis() / 50); -+ this.lastTick = (int) currTick; // Paper - region threading ++ this.lastTick = (int) currTick; // Folia - region threading ++this.receivedMovePacketCount; int i = this.receivedMovePacketCount - this.knownMovePacketCount; @@ -14976,14 +14976,14 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 // CraftBukkit start if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable - server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - region threading ++ this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Folia - region threading return; } // Paper start String str = packet.getCommand(); int index = -1; if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) { - server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - region threading ++ this.disconnect(Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Folia - region threading return; } // Paper end @@ -14992,7 +14992,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (!event.isCancelled()) { - this.server.scheduleOnMain(() -> { // This needs to be on main -+ this.player.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ this.player.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { @@ -15001,7 +15001,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 // Paper end - Brigadier API }); - }); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } } else if (!completions.isEmpty()) { final com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(command, stringreader.getTotalLength()); @@ -15010,7 +15010,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (byteLength > 256 * 4) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!"); - server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause -+ this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - region threading ++ this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Folia - region threading return; } byteTotal += byteLength; @@ -15019,7 +15019,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size()); - server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause -+ this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - region threading ++ this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Folia - region threading return; } } @@ -15028,7 +15028,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 - if (this.lastBookTick + 20 > MinecraftServer.currentTick) { - server.scheduleOnMain(() -> this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause // Paper - Also ensure this is called on main + if (this.lastBookTick + 20 > this.lastTick) { -+ this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - Also ensure this is called on main // Paper - region threading ++ this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - Also ensure this is called on main // Folia - region threading return; } - this.lastBookTick = MinecraftServer.currentTick; @@ -15041,11 +15041,11 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 // CraftBukkit start - handle custom speeds and skipped ticks - this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; -+ int currTick = (int)(Util.getMillis() / 50); // Paper - region threading -+ this.allowedPlayerTicks += currTick - this.lastTick; // Paper - region threading ++ int currTick = (int)(Util.getMillis() / 50); // Folia - region threading ++ this.allowedPlayerTicks += currTick - this.lastTick; // Folia - region threading this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); - this.lastTick = (int) (System.currentTimeMillis() / 50); -+ this.lastTick = (int) currTick; // Paper - region threading ++ this.lastTick = (int) currTick; // Folia - region threading if (i > Math.max(this.allowedPlayerTicks, 5)) { ServerGamePacketListenerImpl.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), i); @@ -15066,7 +15066,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (entity != null) { - this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit -+ io.papermc.paper.threadedregions.TeleportUtils.teleport(this.player, entity, null, null, Entity.TELEPORT_FLAG_LOAD_CHUNK, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE, null); // Paper - region threading ++ io.papermc.paper.threadedregions.TeleportUtils.teleport(this.player, entity, null, null, Entity.TELEPORT_FLAG_LOAD_CHUNK, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE, null); // Folia - region threading return; } } @@ -15074,8 +15074,8 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 this.player.disconnect(); // Paper start - Adventure quitMessage = quitMessage == null ? this.server.getPlayerList().remove(this.player) : this.server.getPlayerList().remove(this.player, quitMessage); // Paper - pass in quitMessage to fix kick message not being used -+ this.disconnectPos = this.player.chunkPosition(); // Paper - region threading - note: only set after removing, since it can tick the player -+ this.player.getLevel().chunkSource.addTicketAtLevel(DISCONNECT_TICKET, this.disconnectPos, io.papermc.paper.chunk.system.scheduling.ChunkHolderManager.MAX_TICKET_LEVEL, this.disconnectTicketId); // Paper - region threading - force chunk to be loaded so that the region is not lost ++ this.disconnectPos = this.player.chunkPosition(); // Folia - region threading - note: only set after removing, since it can tick the player ++ this.player.getLevel().chunkSource.addTicketAtLevel(DISCONNECT_TICKET, this.disconnectPos, io.papermc.paper.chunk.system.scheduling.ChunkHolderManager.MAX_TICKET_LEVEL, this.disconnectTicketId); // Folia - region threading - force chunk to be loaded so that the region is not lost if ((quitMessage != null) && !quitMessage.equals(net.kyori.adventure.text.Component.empty())) { this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false); // Paper end @@ -15084,10 +15084,10 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 // CraftBukkit end if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.message())) { - this.server.scheduleOnMain(() -> { // Paper - push to main for event firing -+ // Paper - region threading ++ // Folia - region threading this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause - }); // Paper - push to main for event firing -+ // Paper - region threading ++ // Folia - region threading } else { Optional optional = this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages()); @@ -15096,20 +15096,20 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 public void handleChatCommand(ServerboundChatCommandPacket packet) { if (ServerGamePacketListenerImpl.isChatMessageIllegal(packet.command())) { - this.server.scheduleOnMain(() -> { // Paper - push to main for event firing -+ // Paper - region threading ++ // Folia - region threading this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - }); // Paper - push to main for event firing -+ // Paper - region threading ++ // Folia - region threading } else { Optional optional = this.tryHandleChat(packet.command(), packet.timeStamp(), packet.lastSeenMessages()); if (optional.isPresent()) { - this.server.submit(() -> { -+ this.player.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Paper - region threading ++ this.player.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading this.performChatCommand(packet, (LastSeenMessages) optional.get()); this.detectRateSpam("/" + packet.command()); // Spigot - }); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } } @@ -15118,10 +15118,10 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (!this.updateChatOrder(timestamp)) { ServerGamePacketListenerImpl.LOGGER.warn("{} sent out-of-order chat: '{}': {} > {}", this.player.getName().getString(), message, this.lastChatTimeStamp.get().getEpochSecond(), timestamp.getEpochSecond()); // Paper - this.server.scheduleOnMain(() -> { // Paper - push to main -+ // Paper - region threading ++ // Folia - region threading this.disconnect(Component.translatable("multiplayer.disconnect.out_of_order_chat"), org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event ca - }); // Paper - push to main -+ // Paper - region threading ++ // Folia - region threading return Optional.empty(); } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); @@ -15130,7 +15130,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 this.cserver.getPluginManager().callEvent(event); - if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { -+ if (false && PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { // Paper - region threading ++ if (false && PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { // Folia - region threading // Evil plugins still listening to deprecated event final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients()); queueEvent.setCancelled(event.isCancelled()); @@ -15138,7 +15138,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 public void handleCommand(String s) { // Paper - private -> public // Paper Start if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading LOGGER.error("Command Dispatched Async: " + s); LOGGER.error("Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); Waitable wait = new Waitable<>() { @@ -15146,7 +15146,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (s.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message"); } else if (this.getCraftPlayer().isConversing()) { -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading final String conversationInput = s; this.server.processQueue.add(new Runnable() { @Override @@ -15154,12 +15154,12 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 switch (packetplayinclientcommand_enumclientcommand) { case PERFORM_RESPAWN: if (this.player.wonGame) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + this.player.exitEndCredits(); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading this.player.wonGame = false; this.player = this.server.getPlayerList().respawn(this.player, this.server.getLevel(this.player.getRespawnDimension()), true, null, true, org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag.END_PORTAL); // Paper - add isEndCreditsRespawn argument CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD); @@ -15167,7 +15167,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 return; } -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + this.player.respawn((ServerPlayer player) -> { + if (ServerGamePacketListenerImpl.this.server.isHardcore()) { @@ -15177,7 +15177,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 + }); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading + this.player = this.server.getPlayerList().respawn(this.player, false); if (this.server.isHardcore()) { @@ -15187,7 +15187,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 if (!org.bukkit.Bukkit.isPrimaryThread()) { if (recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) { - server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause -+ this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - region threading ++ this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Folia - region threading return; } } @@ -15196,7 +15196,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 this.filterTextPacket(list).thenAcceptAsync((list1) -> { this.updateSignText(packet, list1); - }, this.server); -+ }, (Runnable run) -> { // Paper start - region threading ++ }, (Runnable run) -> { // Folia start - region threading + this.player.getBukkitEntity().taskScheduler.schedule( + (player) -> { + run.run(); @@ -15207,7 +15207,7 @@ index 3472f7f9b98d6d9c9f6465872803ef17fa67486d..56dc95a795e7742cb15ad23f0eb3a257 private void updateSignText(ServerboundSignUpdatePacket packet, List signText) { diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293577e8a81 100644 +index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..805557d4fedd234a593ccf2655399a2b87ee6b60 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -53,7 +53,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -15215,7 +15215,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 final MinecraftServer server; public final Connection connection; - public ServerLoginPacketListenerImpl.State state; -+ public volatile ServerLoginPacketListenerImpl.State state; // Paper - region threading ++ public volatile ServerLoginPacketListenerImpl.State state; // Folia - region threading private int tick; public @Nullable GameProfile gameProfile; @@ -15225,7 +15225,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 if (this.state == ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT) { - // Paper start - prevent logins to be processed even though disconnect was called - if (connection.isConnected()) { -+ // Paper start - region threading - rewrite login process ++ // Folia start - region threading - rewrite login process + String name = this.gameProfile.getName(); + UUID uniqueId = UUIDUtil.getOrCreatePlayerUUID(this.gameProfile); + if (this.server.getPlayerList().pushPendingJoin(name, uniqueId, this.connection)) { @@ -15241,8 +15241,8 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 - this.delayedAcceptPlayer = null; - } - } -+ // Paper end - region threading - rewrite login process -+ } // Paper - region threading - remove delayed accept ++ // Folia end - region threading - rewrite login process ++ } // Folia - region threading - remove delayed accept if (this.tick++ == 600) { this.disconnect(Component.translatable("multiplayer.disconnect.slow_login")); @@ -15251,7 +15251,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 // CraftBukkit end } else { - this.state = ServerLoginPacketListenerImpl.State.ACCEPTED; -+ this.state = ServerLoginPacketListenerImpl.State.HANDING_OFF; // Paper - region threading - rewrite login process ++ this.state = ServerLoginPacketListenerImpl.State.HANDING_OFF; // Folia - region threading - rewrite login process if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) { this.connection.send(new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()), PacketSendListener.thenRun(() -> { this.connection.setupCompression(this.server.getCompressionThreshold(), true); @@ -15260,7 +15260,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 this.connection.send(new ClientboundGameProfilePacket(this.gameProfile)); - ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); -+ // Paper - region threading - rewrite login process ++ // Folia - region threading - rewrite login process try { - ServerPlayer entityplayer1 = this.server.getPlayerList().getPlayerForLogin(this.gameProfile, s); // CraftBukkit - add player reference @@ -15271,7 +15271,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 - } else { - this.placeNewPlayer(entityplayer1); - } -+ // Paper start - region threading - rewrite login process ++ // Folia start - region threading - rewrite login process + org.apache.commons.lang3.mutable.MutableObject data = new org.apache.commons.lang3.mutable.MutableObject<>(); + org.apache.commons.lang3.mutable.MutableObject lastKnownName = new org.apache.commons.lang3.mutable.MutableObject<>(); + ca.spottedleaf.concurrentutil.completable.Completable toComplete = new ca.spottedleaf.concurrentutil.completable.Completable<>(); @@ -15316,7 +15316,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 + ); + }); + this.server.getPlayerList().loadSpawnForNewPlayer(this.connection, s, data, lastKnownName, toComplete); -+ // Paper end - region threading - rewrite login process ++ // Folia end - region threading - rewrite login process } catch (Exception exception) { ServerLoginPacketListenerImpl.LOGGER.error("Couldn't place player in world", exception); MutableComponent ichatmutablecomponent = Component.translatable("multiplayer.disconnect.invalid_player_data"); @@ -15327,7 +15327,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 - private void placeNewPlayer(ServerPlayer player) { - this.server.getPlayerList().placeNewPlayer(this.connection, player); - } -+ // Paper end - region threading - rewrite login process ++ // Folia end - region threading - rewrite login process @Override public void onDisconnect(Component reason) { @@ -15336,7 +15336,7 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 // Paper end - if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { -+ if (false && PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { // Paper - region threading ++ if (false && PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { // Folia - region threading final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { event.disallow(asyncEvent.getResult(), asyncEvent.kickMessage()); // Paper - Adventure @@ -15345,12 +15345,12 @@ index a25306fe8a35bb70a490e6a0c01d0340bbc0d781..9f06b025e09dfb5b148da536fec33293 public static enum State { - HELLO, KEY, AUTHENTICATING, NEGOTIATING, READY_TO_ACCEPT, DELAY_ACCEPT, ACCEPTED; -+ HELLO, KEY, AUTHENTICATING, NEGOTIATING, READY_TO_ACCEPT, DELAY_ACCEPT, HANDING_OFF, ACCEPTED; // Paper - region threading ++ HELLO, KEY, AUTHENTICATING, NEGOTIATING, READY_TO_ACCEPT, DELAY_ACCEPT, HANDING_OFF, ACCEPTED; // Folia - region threading private State() {} } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921be5f58e8c 100644 +index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..a0267f2e110bacd30f33978414fd2aff2dc84ab1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -138,7 +138,7 @@ public abstract class PlayerList { @@ -15358,7 +15358,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b private final MinecraftServer server; public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety - private final Map playersByUUID = Maps.newHashMap(); -+ private final Map playersByUUID = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - region threading - change to CHM - Note: we do NOT expect concurrency PER KEY! ++ private final Map playersByUUID = new java.util.concurrent.ConcurrentHashMap<>(); // Folia - region threading - change to CHM - Note: we do NOT expect concurrency PER KEY! private final UserBanList bans; private final IpBanList ipBans; private final ServerOpList ops; @@ -15367,10 +15367,10 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b // CraftBukkit start private CraftServer cserver; - private final Map playersByName = new java.util.HashMap<>(); -+ private final Map playersByName = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - region threading - change to CHM - Note: we do NOT expect concurrency PER KEY! ++ private final Map playersByName = new java.util.concurrent.ConcurrentHashMap<>(); // Folia - region threading - change to CHM - Note: we do NOT expect concurrency PER KEY! public @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule -+ // Paper start - region threading ++ // Folia start - region threading + private final Object stateLock = new Object(); + private final Map connectionByName = new java.util.HashMap<>(); + private final Map connectionById = new java.util.HashMap<>(); @@ -15415,7 +15415,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b + return this.connectionById.size(); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { this.cserver = server.server = new CraftServer((DedicatedServer) server, this); @@ -15435,8 +15435,8 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b - if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are.... - -+ // Paper start - region threading - rewrite login process -+ if (nbttagcompound == null) ServerPlayer.fudgeSpawnLocation(worldserver1, player, toComplete); // Paper - only move to spawn on first login, otherwise, stay where you are.... ++ // Folia start - region threading - rewrite login process ++ if (nbttagcompound == null) ServerPlayer.fudgeSpawnLocation(worldserver1, player, toComplete); // Folia - only move to spawn on first login, otherwise, stay where you are.... + if (nbttagcompound != null) { + worldserver1.loadChunksForMoveAsync( + player.getBoundingBox(), @@ -15456,7 +15456,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b + ServerLevel worldserver1 = ((CraftWorld)selectedSpawn.getWorld()).getHandle(); + player.setPosRaw(selectedSpawn.getX(), selectedSpawn.getY(), selectedSpawn.getZ()); + player.lastSave = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); -+ // Paper end - region threading - rewrite login process ++ // Folia end - region threading - rewrite login process player.setLevel(worldserver1); String s1 = "local"; @@ -15465,7 +15465,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b Player spawnPlayer = player.getBukkitEntity(); org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent(spawnPlayer, spawnPlayer.getLocation()); // Paper use our duplicate event - this.cserver.getPluginManager().callEvent(ev); -+ //this.cserver.getPluginManager().callEvent(ev); // Paper - region threading - TODO WTF TO DO WITH THIS EVENT? ++ //this.cserver.getPluginManager().callEvent(ev); // Folia - region threading - TODO WTF TO DO WITH THIS EVENT? Location loc = ev.getSpawnLocation(); worldserver1 = ((CraftWorld) loc.getWorld()).getHandle(); @@ -15473,7 +15473,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b player.loadGameTypes(nbttagcompound); ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player); -+ worldserver1.getCurrentWorldData().connections.add(connection); // Paper - region threading - only AFTER updating listener to game ++ worldserver1.getCurrentWorldData().connections.add(connection); // Folia - region threading - only AFTER updating listener to game GameRules gamerules = worldserver1.getGameRules(); boolean flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); @@ -15482,7 +15482,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b player.getStats().markAllDirty(); player.getRecipeBook().sendInitialRecipeBook(player); - this.updateEntireScoreboard(worldserver1.getScoreboard(), player); -+ if (false) this.updateEntireScoreboard(worldserver1.getScoreboard(), player); // Paper - region threading ++ if (false) this.updateEntireScoreboard(worldserver1.getScoreboard(), player); // Folia - region threading this.server.invalidateStatus(); MutableComponent ichatmutablecomponent; @@ -15492,7 +15492,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b final List onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - use single player info update packet - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); -+ for (ServerPlayer entityplayer1 : this.players) { // Paper - region threadingv ++ for (ServerPlayer entityplayer1 : this.players) { // Folia - region threadingv if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { entityplayer1.connection.send(packet); @@ -15501,7 +15501,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName); - if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { -+ if (false && this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { // Paper - region threading ++ if (false && this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { // Folia - region threading scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end @@ -15510,7 +15510,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b protected void save(ServerPlayer player) { if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit - player.lastSave = MinecraftServer.currentTick; // Paper -+ player.lastSave = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - region threading ++ player.lastSave = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - region threading this.playerIo.save(player); ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit @@ -15519,7 +15519,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b // Paper start - Remove from collideRule team if needed - if (this.collideRuleTeamName != null) { -+ if (false && this.collideRuleTeamName != null) { // Paper - region threading ++ if (false && this.collideRuleTeamName != null) { // Folia - region threading final Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam team = scoreBoard.getPlayersTeam(this.collideRuleTeamName); if (entityplayer.getTeam() == team && team != null) { @@ -15527,7 +15527,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b entityplayer.unRide(); worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER); -+ entityplayer.retireScheduler(); // Paper - region threading ++ entityplayer.retireScheduler(); // Folia - region threading entityplayer.getAdvancements().stopListening(); this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot @@ -15537,7 +15537,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(entityplayer.getUUID())); - for (int i = 0; i < this.players.size(); i++) { - ServerPlayer entityplayer2 = (ServerPlayer) this.players.get(i); -+ for (ServerPlayer entityplayer2 : this.players) { // Paper - region threading ++ for (ServerPlayer entityplayer2 : this.players) { // Folia - region threading if (entityplayer2.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { entityplayer2.connection.send(packet); @@ -15551,7 +15551,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b - list.add(entityplayer); - } - } -+ // Paper - region threading - rewrite login process - moved to pushPendingJoin ++ // Folia - region threading - rewrite login process - moved to pushPendingJoin Iterator iterator = list.iterator(); @@ -15559,7 +15559,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b entityplayer = (ServerPlayer) iterator.next(); - this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved - entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause -+ // Paper - moved to pushPendingJoin ++ // Folia - moved to pushPendingJoin } // Instead of kicking then returning, we need to store the kick reason @@ -15568,7 +15568,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; - if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { -+ if (this.getTotalConnections() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { // Paper - region threading - we control connection state here now async, not player list size ++ if (this.getTotalConnections() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { // Folia - region threading - we control connection state here now async, not player list size event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure } } @@ -15578,11 +15578,11 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b // CraftBukkit start - for (int i = 0; i < this.players.size(); ++i) { - final ServerPlayer target = (ServerPlayer) this.players.get(i); -+ ServerPlayer[] players = this.players.toArray(new ServerPlayer[0]); // Paper - region threading -+ for (final ServerPlayer target : players) { // Paper - region threading ++ ServerPlayer[] players = this.players.toArray(new ServerPlayer[0]); // Folia - region threading ++ for (final ServerPlayer target : players) { // Folia - region threading - target.connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY), this.players.stream().filter(new Predicate() { -+ target.connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY), java.util.Arrays.stream(players).filter(new Predicate() { // Paper - region threading ++ target.connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY), java.util.Arrays.stream(players).filter(new Predicate() { // Folia - region threading @Override public boolean test(ServerPlayer input) { return target.getBukkitEntity().canSee(input.getBukkitEntity()); @@ -15592,20 +15592,20 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer = this.players.get(i); -+ for (ServerPlayer entityplayer : this.players) { // Paper - region threading ++ for (ServerPlayer entityplayer : this.players) { // Folia - region threading if (entityhuman != null && !entityplayer.getBukkitEntity().canSee(entityhuman.getBukkitEntity())) { continue; } - ((ServerPlayer) this.players.get(i)).connection.send(packet); -+ entityplayer.connection.send(packet); // Paper - region threading ++ entityplayer.connection.send(packet); // Folia - region threading } } public void broadcastAll(Packet packet, Level world) { - for (int i = 0; i < world.players().size(); ++i) { - ((ServerPlayer) world.players().get(i)).connection.send(packet); -+ for (net.minecraft.world.entity.player.Player player : world.players()) { // Paper - region threading -+ ((ServerPlayer) player).connection.send(packet); // Paper - region threading ++ for (net.minecraft.world.entity.player.Player player : world.players()) { // Folia - region threading ++ ((ServerPlayer) player).connection.send(packet); // Folia - region threading } } @@ -15615,7 +15615,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b } else { - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer = (ServerPlayer) this.players.get(i); -+ for (ServerPlayer entityplayer : this.players) { // Paper - region threading ++ for (ServerPlayer entityplayer : this.players) { // Folia - region threading if (entityplayer.getTeam() != scoreboardteambase) { entityplayer.sendSystemMessage(message); @@ -15624,14 +15624,14 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b public String[] getPlayerNamesArray() { - String[] astring = new String[this.players.size()]; -+ List players = new java.util.ArrayList<>(this.players); // Paper start - region threading ++ List players = new java.util.ArrayList<>(this.players); // Folia start - region threading + String[] astring = new String[players.size()]; - for (int i = 0; i < this.players.size(); ++i) { - astring[i] = ((ServerPlayer) this.players.get(i)).getGameProfile().getName(); + for (int i = 0; i < players.size(); ++i) { + astring[i] = ((ServerPlayer) players.get(i)).getGameProfile().getName(); -+ // Paper end - region threading ++ // Folia end - region threading } return astring; @@ -15639,9 +15639,9 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { -+ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading ++ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading this.sendPlayerPermissionLevel(entityplayer); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading } } @@ -15649,9 +15649,9 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { -+ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Paper - region threading ++ entityplayer.getBukkitEntity().taskScheduler.schedule((nmsEntity) -> { // Folia - region threading this.sendPlayerPermissionLevel(entityplayer); -+ }, null, 1L); // Paper - region threading ++ }, null, 1L); // Folia - region threading + } @@ -15662,7 +15662,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey worldKey, Packet packet) { - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer = (ServerPlayer) this.players.get(i); -+ for (ServerPlayer entityplayer : this.players) { // Paper - region threading ++ for (ServerPlayer entityplayer : this.players) { // Folia - region threading // CraftBukkit start - Test if player receiving packet can see the source of the packet if (player != null && !entityplayer.getBukkitEntity().canSee(player.getBukkitEntity())) { @@ -15673,12 +15673,12 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b - long now = MinecraftServer.currentTick; - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer = this.players.get(i); -+ long now = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - region threading -+ for (ServerPlayer entityplayer : this.players) { // Paper start - region threading ++ long now = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - region threading ++ for (ServerPlayer entityplayer : this.players) { // Folia start - region threading + if (!io.papermc.paper.util.TickThread.isTickThreadFor(entityplayer)) { + continue; + } -+ // Paper end - region threading ++ // Folia end - region threading if (interval == -1 || now - entityplayer.lastSave >= interval) { this.save(entityplayer); if (interval != -1 && ++numSaved <= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) { break; } @@ -15686,7 +15686,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b } public void removeAll(boolean isRestarting) { -+ // Paper start - region threading ++ // Folia start - region threading + // just send disconnect packet, don't modify state + for (ServerPlayer player : this.players) { + final Component ichatbasecomponent = PaperAdventure.asVanilla(this.server.server.shutdownMessage()); // Paper - Adventure @@ -15699,7 +15699,7 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b + if (true) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading // Paper end // CraftBukkit start - disconnect safely for (ServerPlayer player : this.players) { @@ -15708,19 +15708,19 @@ index 3c9d08c37a44a60bc70387d8d0dbd0a39ea98a26..56603d8d817657ef5de23ccfd58a921b // Paper start - Remove collideRule team if it exists - if (this.collideRuleTeamName != null) { -+ if (false && this.collideRuleTeamName != null) { // Paper - region threading ++ if (false && this.collideRuleTeamName != null) { // Folia - region threading final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName); if (team != null) scoreboard.removePlayerTeam(team); diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..8b96df8a6a96b976c1bad4f899d3332b1a4ec7a9 100644 +index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..e07eddbfbe3fa5e5915580a0f4d753ce54b33248 100644 --- a/src/main/java/net/minecraft/server/players/StoredUserList.java +++ b/src/main/java/net/minecraft/server/players/StoredUserList.java @@ -148,6 +148,7 @@ public abstract class StoredUserList> { } public void save() throws IOException { -+ synchronized (this) { // Paper - region threading ++ synchronized (this) { // Folia - region threading this.removeExpired(); // Paper - remove expired values before saving JsonArray jsonarray = new JsonArray(); Stream stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error @@ -15728,12 +15728,12 @@ index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..8b96df8a6a96b976c1bad4f899d3332b if (bufferedwriter != null) { bufferedwriter.close(); } -+ } // Paper - region threading ++ } // Folia - region threading } public void load() throws IOException { -+ synchronized (this) { // Paper - region threading ++ synchronized (this) { // Folia - region threading if (this.file.exists()) { BufferedReader bufferedreader = Files.newReader(this.file, StandardCharsets.UTF_8); @@ -15741,11 +15741,11 @@ index 4fd709a550bf8da1e996894a1ca6b91206c31e9e..8b96df8a6a96b976c1bad4f899d3332b } } -+ } // Paper - region threading ++ } // Folia - region threading } } diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java -index 4f5f2c25e12ee6d977bc98d9118650cfe91e6c0e..4f32db746ffd4d4f8e2bdecc91a46824ca05aca0 100644 +index 4f5f2c25e12ee6d977bc98d9118650cfe91e6c0e..d227b91defc3992f1a003a19264bc3aa29718795 100644 --- a/src/main/java/net/minecraft/util/SortedArraySet.java +++ b/src/main/java/net/minecraft/util/SortedArraySet.java @@ -82,7 +82,7 @@ public class SortedArraySet extends AbstractSet { @@ -15753,7 +15753,7 @@ index 4f5f2c25e12ee6d977bc98d9118650cfe91e6c0e..4f32db746ffd4d4f8e2bdecc91a46824 } - private static int getInsertionPosition(int binarySearchResult) { -+ public static int getInsertionPosition(int binarySearchResult) { // Paper - region threading - public ++ public static int getInsertionPosition(int binarySearchResult) { // Folia - region threading - public return -binarySearchResult - 1; } @@ -15761,7 +15761,7 @@ index 4f5f2c25e12ee6d977bc98d9118650cfe91e6c0e..4f32db746ffd4d4f8e2bdecc91a46824 } } // Paper end - rewrite chunk system -+ // Paper start - region threading ++ // Folia start - region threading + public int binarySearch(final T search) { + return this.findIndex(search); + } @@ -15794,12 +15794,12 @@ index 4f5f2c25e12ee6d977bc98d9118650cfe91e6c0e..4f32db746ffd4d4f8e2bdecc91a46824 + + return ret; + } -+ // Paper end - region threading ++ // Folia end - region threading @Override public boolean remove(Object object) { diff --git a/src/main/java/net/minecraft/util/SpawnUtil.java b/src/main/java/net/minecraft/util/SpawnUtil.java -index 83ef8cb27db685cceb5c2b7c9674e17b93ba081c..720b7a43356becbdf82f700e17ca0de7c717fc8d 100644 +index 83ef8cb27db685cceb5c2b7c9674e17b93ba081c..2d87c16420a97b9142d4ea76ceb6013deed22a1f 100644 --- a/src/main/java/net/minecraft/util/SpawnUtil.java +++ b/src/main/java/net/minecraft/util/SpawnUtil.java @@ -59,7 +59,7 @@ public class SpawnUtil { @@ -15807,12 +15807,12 @@ index 83ef8cb27db685cceb5c2b7c9674e17b93ba081c..720b7a43356becbdf82f700e17ca0de7 } - t0.discard(); -+ //t0.discard(); // Paper - region threading ++ //t0.discard(); // Folia - region threading } } } diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed70b532d46 100644 +index 1eaab1f6923e6aa34b643293347348e5cc19af3c..61845598d8a0f3ada2691da6eed3f123498f05b2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -165,7 +165,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { @@ -15820,7 +15820,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 // Paper start public static RandomSource SHARED_RANDOM = new RandomRandomSource(); - private static final class RandomRandomSource extends java.util.Random implements net.minecraft.world.level.levelgen.BitRandomSource { -+ public static final class RandomRandomSource extends java.util.Random implements net.minecraft.world.level.levelgen.BitRandomSource { // Paper - region threading ++ public static final class RandomRandomSource extends java.util.Random implements net.minecraft.world.level.levelgen.BitRandomSource { // Folia - region threading private boolean locked = false; @Override @@ -15829,29 +15829,29 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper public boolean collisionLoadChunks = false; // Paper - private CraftEntity bukkitEntity; -+ private volatile CraftEntity bukkitEntity; // Paper - region threading ++ private volatile CraftEntity bukkitEntity; // Folia - region threading public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper public @Nullable Throwable addedToWorldStack; // Paper - entity debug public CraftEntity getBukkitEntity() { if (this.bukkitEntity == null) { - this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); -+ // Paper start - region threading ++ // Folia start - region threading + synchronized (this) { + if (this.bukkitEntity == null) { + return this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); + } + } -+ // Paper end - region threading ++ // Folia end - region threading } return this.bukkitEntity; } -+ // Paper start - region threading ++ // Folia start - region threading + public CraftEntity getBukkitEntityRaw() { + return this.bukkitEntity; + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override public CommandSender getBukkitSender(CommandSourceStack wrapper) { @@ -15882,7 +15882,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 - - return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this)); - } -+ // Paper - region threading ++ // Folia - region threading // Paper end - optimise entity tracking // Paper start - make end portalling safe public BlockPos portalBlock; @@ -15890,7 +15890,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 this.teleportTo(worldserver, null); } // Paper end - make end portalling safe -+ // Paper start ++ // Folia start + private static final java.util.concurrent.ConcurrentHashMap, Integer> CLASS_ID_MAP = new java.util.concurrent.ConcurrentHashMap<>(); + private static final AtomicInteger CLASS_ID_GENERATOR = new AtomicInteger(); + public final int classId = CLASS_ID_MAP.computeIfAbsent(this.getClass(), (Class c) -> { @@ -15898,8 +15898,8 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 + }); + private static final java.util.concurrent.atomic.AtomicLong REFERENCE_ID_GENERATOR = new java.util.concurrent.atomic.AtomicLong(); + public final long referenceId = REFERENCE_ID_GENERATOR.getAndIncrement(); -+ // Paper end -+ // Paper start - region ticking ++ // Folia end ++ // Folia start - region ticking + public void updateTicks(long fromTickOffset, long fromRedstoneTimeOffset) { + if (this.activatedTick != Integer.MIN_VALUE) { + this.activatedTick += fromTickOffset; @@ -15908,7 +15908,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 + this.activatedImmunityTick += fromTickOffset; + } + } -+ // Paper end - region ticking ++ // Folia end - region ticking public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); @@ -15916,11 +15916,11 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 } public final void discard() { -+ // Paper start - region threading ++ // Folia start - region threading + if (this.isRemoved()) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading this.remove(Entity.RemovalReason.DISCARDED); } @@ -15928,12 +15928,12 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 // CraftBukkit start public void postTick() { -+ // Paper start - region threading ++ // Folia start - region threading + // moved to doPortalLogic + if (true) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities this.handleNetherPortal(); @@ -15942,7 +15942,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 this.xRotO = this.getXRot(); this.yRotO = this.getYRot(); - if (this instanceof ServerPlayer) this.handleNetherPortal(); // CraftBukkit - // Moved up to postTick -+ //if (this instanceof ServerPlayer) this.handleNetherPortal(); // CraftBukkit - // Moved up to postTick // Paper - region threading - ONLY allow in postTick() ++ //if (this instanceof ServerPlayer) this.handleNetherPortal(); // CraftBukkit - // Moved up to postTick // Folia - region threading - ONLY allow in postTick() if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } @@ -15951,12 +15951,12 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 this.setSecondsOnFire(15, false); } - CraftEventFactory.blockDamage = (this.lastLavaContact) == null ? null : org.bukkit.craftbukkit.block.CraftBlock.at(level, lastLavaContact); -+ CraftEventFactory.blockDamageRT.set((this.lastLavaContact) == null ? null : org.bukkit.craftbukkit.block.CraftBlock.at(level, lastLavaContact)); // Paper - region threading ++ CraftEventFactory.blockDamageRT.set((this.lastLavaContact) == null ? null : org.bukkit.craftbukkit.block.CraftBlock.at(level, lastLavaContact)); // Folia - region threading if (this.hurt(DamageSource.LAVA, 4.0F)) { this.playSound(SoundEvents.GENERIC_BURN, 0.4F, 2.0F + this.random.nextFloat() * 0.4F); } - CraftEventFactory.blockDamage = null; -+ CraftEventFactory.blockDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // Folia - region threading // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls } @@ -15975,11 +15975,11 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 @Nullable public Team getTeam() { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + return null; + } -+ // Paper end - region threading ++ // Folia end - region threading if (!this.level.paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof Player)) { return null; } // Paper return this.level.getScoreboard().getPlayersTeam(this.getScoreboardName()); } @@ -15988,10 +15988,10 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 return; } - CraftEventFactory.entityDamage = lightning; -+ CraftEventFactory.entityDamageRT.set(lightning); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(lightning); // Folia - region threading if (!this.hurt(DamageSource.LIGHTNING_BOLT, 5.0F)) { - CraftEventFactory.entityDamage = null; -+ CraftEventFactory.entityDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading return; } // CraftBukkit end @@ -15999,7 +15999,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 this.portalEntrancePos = original.portalEntrancePos; } -+ // Paper start - region threading ++ // Folia start - region threading + public static class EntityTreeNode { + @Nullable + public EntityTreeNode parent; @@ -16619,7 +16619,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 + + return true; + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable public Entity changeDimension(ServerLevel destination) { @@ -16631,7 +16631,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 - if (io.papermc.paper.event.player.PlayerTrackEntityEvent.getHandlerList().getRegisteredListeners().length > 0) { - new io.papermc.paper.event.player.PlayerTrackEntityEvent(player.getBukkitEntity(), this.getBukkitEntity()).callEvent(); - } -+ // Paper - region threading - no ++ // Folia - region threading - no } // Paper end @@ -16640,7 +16640,7 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 - if(io.papermc.paper.event.player.PlayerUntrackEntityEvent.getHandlerList().getRegisteredListeners().length > 0) { - new io.papermc.paper.event.player.PlayerUntrackEntityEvent(player.getBukkitEntity(), this.getBukkitEntity()).callEvent(); - } -+ // Paper - region threading - no ++ // Folia - region threading - no } // Paper end @@ -16649,8 +16649,8 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 } // Paper end - fix MC-4 - if (this.position.x != x || this.position.y != y || this.position.z != z) { -+ boolean posChanged = this.position.x != x || this.position.y != y || this.position.z != z; // Paper - region threading -+ if (posChanged) { // Paper - region threading ++ boolean posChanged = this.position.x != x || this.position.y != y || this.position.z != z; // Folia - region threading ++ if (posChanged) { // Folia - region threading synchronized (this.posLock) { // Paper this.position = new Vec3(x, y, z); } // Paper @@ -16667,15 +16667,15 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 if (reason != RemovalReason.UNLOADED_TO_CHUNK) this.getPassengers().forEach(Entity::stopRiding); // Paper - chunk system - don't adjust passenger state when unloading, it's just not safe (and messes with our logic in entity chunk unload) this.levelCallback.onRemove(reason); -+ // Paper start - region threading ++ // Folia start - region threading + if (!(this instanceof ServerPlayer) && reason != RemovalReason.CHANGED_DIMENSION) { + // Players need to be special cased, because they are regularly removed from the world + this.retireScheduler(); + } -+ // Paper end - region threading ++ // Folia end - region threading + } + -+ // Paper start - region threading ++ // Folia start - region threading + /** + * Invoked only when the entity is truly removed from the server, never to be added to any world. + */ @@ -16683,12 +16683,12 @@ index 1eaab1f6923e6aa34b643293347348e5cc19af3c..53b6c6c850625176e2f4632d38e5fed7 + // we need to force create the bukkit entity so that the scheduler can be retired... + this.getBukkitEntity().taskScheduler.retire(); } -+ // Paper end - region threading ++ // Folia end - region threading public void unsetRemoved() { this.removalReason = null; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 42eb78830855d7282b7f3f1bdbe85e632d489784..3ca2b0c5f2d78d8cdfba76bf7f6020c808b6691b 100644 +index 42eb78830855d7282b7f3f1bdbe85e632d489784..e3f5f3692018426eafbee3d3bc63bf2755548117 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -469,7 +469,7 @@ public abstract class LivingEntity extends Entity { @@ -16696,7 +16696,7 @@ index 42eb78830855d7282b7f3f1bdbe85e632d489784..3ca2b0c5f2d78d8cdfba76bf7f6020c8 if (this.isDeadOrDying() && this.level.shouldTickDeath(this)) { this.tickDeath(); - } -+ } else { this.broadcastedDeath = false; } // Paper - region threading ++ } else { this.broadcastedDeath = false; } // Folia - region threading if (this.lastHurtByPlayerTime > 0) { --this.lastHurtByPlayerTime; @@ -16704,15 +16704,15 @@ index 42eb78830855d7282b7f3f1bdbe85e632d489784..3ca2b0c5f2d78d8cdfba76bf7f6020c8 return false; } -+ public boolean broadcastedDeath = false; // Paper - region threading ++ public boolean broadcastedDeath = false; // Folia - region threading protected void tickDeath() { ++this.deathTime; - if (this.deathTime >= 20 && !this.level.isClientSide() && !this.isRemoved()) { -+ if (this.deathTime >= 20 && !this.level.isClientSide() && !this.isRemoved() && !this.broadcastedDeath) { // Paper - region threading -+ this.broadcastedDeath = true; // Paper - region threading ++ if (this.deathTime >= 20 && !this.level.isClientSide() && !this.isRemoved() && !this.broadcastedDeath) { // Folia - region threading ++ this.broadcastedDeath = true; // Folia - region threading this.level.broadcastEntityEvent(this, (byte) 60); - this.remove(Entity.RemovalReason.KILLED); -+ if (!(this instanceof ServerPlayer)) this.remove(Entity.RemovalReason.KILLED); // Paper - region threading - don't remove, we want the tick scheduler to be running ++ if (!(this instanceof ServerPlayer)) this.remove(Entity.RemovalReason.KILLED); // Folia - region threading - don't remove, we want the tick scheduler to be running } } @@ -16721,10 +16721,10 @@ index 42eb78830855d7282b7f3f1bdbe85e632d489784..3ca2b0c5f2d78d8cdfba76bf7f6020c8 this.hurtTime = nbt.getShort("HurtTime"); - this.deathTime = nbt.getShort("DeathTime"); -+ this.deathTime = nbt.getShort("DeathTime"); this.broadcastedDeath = false; // Paper - region threading ++ this.deathTime = nbt.getShort("DeathTime"); this.broadcastedDeath = false; // Folia - region threading this.lastHurtByMobTimestamp = nbt.getInt("HurtByTimestamp"); - if (nbt.contains("Team", 8)) { -+ if (false && nbt.contains("Team", 8)) { // Paper start - region threading ++ if (false && nbt.contains("Team", 8)) { // Folia start - region threading String s = nbt.getString("Team"); PlayerTeam scoreboardteam = this.level.getScoreboard().getPlayerTeam(s); if (!level.paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { scoreboardteam = null; } // Paper @@ -16742,25 +16742,25 @@ index 42eb78830855d7282b7f3f1bdbe85e632d489784..3ca2b0c5f2d78d8cdfba76bf7f6020c8 Level world = this.level; - if (world.hasChunkAt(blockposition)) { -+ if (io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel)world, blockposition) && world.hasChunkAt(blockposition)) { // Paper - region threading ++ if (io.papermc.paper.util.TickThread.isTickThreadFor((ServerLevel)world, blockposition) && world.hasChunkAt(blockposition)) { // Folia - region threading boolean flag2 = false; while (!flag2 && blockposition.getY() > world.getMinBuildHeight()) { diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 49b983064ea810382b6112f5dc7f93ba4e5710bd..645de1d871d3ff9dc1bb42842a12b7ae1abbb8c7 100644 +index 49b983064ea810382b6112f5dc7f93ba4e5710bd..ee24904679e37007c38d3eb7095b406f345444f6 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -135,6 +135,14 @@ public abstract class Mob extends LivingEntity { public boolean aware = true; // CraftBukkit -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public void preChangeDimension() { + super.preChangeDimension(); + this.dropLeash(true, true); + } -+ // Paper end - region threading ++ // Folia end - region threading + protected Mob(EntityType type, Level world) { super(type, world); @@ -16775,12 +16775,12 @@ index 49b983064ea810382b6112f5dc7f93ba4e5710bd..645de1d871d3ff9dc1bb42842a12b7ae - entityhuman = ((ServerLevel)this.level).playersAffectingSpawning.isEmpty() ? null : ((ServerLevel)this.level).playersAffectingSpawning.get(0); - } - // Paper end - optimise checkDespawn -+ Player entityhuman = this.level.getNearestPlayer(this, -1.0D); // Paper - region threading ++ Player entityhuman = this.level.getNearestPlayer(this, -1.0D); // Folia - region threading if (entityhuman != null) { double d0 = entityhuman.distanceToSqr((Entity) this); diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java -index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca7db7b15f 100644 +index 11a101e8ff05fbda5e84018358be02014ca01854..8cfa70e9b07e0f993d172d3e4d3804490a4d9fd5 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/FollowOwnerGoal.java @@ -70,7 +70,7 @@ public class FollowOwnerGoal extends Goal { @@ -16788,7 +16788,7 @@ index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca @Override public boolean canContinueToUse() { - return this.navigation.isDone() ? false : (this.tamable.isOrderedToSit() ? false : this.tamable.distanceToSqr((Entity) this.owner) > (double) (this.stopDistance * this.stopDistance)); -+ return this.navigation.isDone() ? false : (this.tamable.isOrderedToSit() ? false : (this.owner.level == this.level && this.tamable.distanceToSqr((Entity) this.owner) > (double) (this.stopDistance * this.stopDistance))); // Paper - region threading - check level ++ return this.navigation.isDone() ? false : (this.tamable.isOrderedToSit() ? false : (this.owner.level == this.level && this.tamable.distanceToSqr((Entity) this.owner) > (double) (this.stopDistance * this.stopDistance))); // Folia - region threading - check level } @Override @@ -16797,7 +16797,7 @@ index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca this.timeToRecalcPath = this.adjustedTickDelay(10); if (!this.tamable.isLeashed() && !this.tamable.isPassenger()) { - if (this.tamable.distanceToSqr((Entity) this.owner) >= 144.0D) { -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this.owner) || this.tamable.distanceToSqr((Entity) this.owner) >= 144.0D) { // Paper - region threading - required in case the player suddenly moves into another dimension ++ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this.owner) || this.tamable.distanceToSqr((Entity) this.owner) >= 144.0D) { // Folia - region threading - required in case the player suddenly moves into another dimension this.teleportToOwner(); } else { this.navigation.moveTo((Entity) this.owner, this.speedModifier); @@ -16805,11 +16805,11 @@ index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca private void teleportToOwner() { BlockPos blockposition = this.owner.blockPosition(); -+ // Paper start - region threading ++ // Folia start - region threading + if (this.owner.isRemoved() || this.owner.level != level) { + return; + } -+ // Paper end - region threading ++ // Folia end - region threading for (int i = 0; i < 10; ++i) { int j = this.randomIntInclusive(-3, 3); @@ -16818,7 +16818,7 @@ index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca to = event.getTo(); - this.tamable.moveTo(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); -+ // Paper start - region threading - can't teleport here, we may be removed by teleport logic - delay until next tick ++ // Folia start - region threading - can't teleport here, we may be removed by teleport logic - delay until next tick + // also, use teleportAsync so that crossing region boundaries will not blow up + Location finalTo = to; + this.tamable.getBukkitEntity().taskScheduler.schedule((TamableAnimal nmsEntity) -> { @@ -16832,12 +16832,12 @@ index 11a101e8ff05fbda5e84018358be02014ca01854..38c93d299f612ac1cc75c7f1ad5c52ca + ); + } + }, null, 1L); -+ // Paper start - region threading - can't teleport here, we may be removed by teleport logic - delay until next tick ++ // Folia start - region threading - can't teleport here, we may be removed by teleport logic - delay until next tick // CraftBukkit end this.navigation.stop(); return true; diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 97257b450e848f53fdb9b5b7affa57b03ea5f459..9720bc8766cc1dac6892a8a1ef3bf8c238679a3a 100644 +index 97257b450e848f53fdb9b5b7affa57b03ea5f459..5485eba13ae544a3e5b7ff5e416c369db8f9c7bc 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -79,11 +79,11 @@ public abstract class PathNavigation { @@ -16845,12 +16845,12 @@ index 97257b450e848f53fdb9b5b7affa57b03ea5f459..9720bc8766cc1dac6892a8a1ef3bf8c2 public void recomputePath() { - if (this.level.getGameTime() - this.timeLastRecompute > 20L) { -+ if (this.tick - this.timeLastRecompute > 20L) { // Paper - region threading ++ if (this.tick - this.timeLastRecompute > 20L) { // Folia - region threading if (this.targetPos != null) { this.path = null; this.path = this.createPath(this.targetPos, this.reachRange); - this.timeLastRecompute = this.level.getGameTime(); -+ this.timeLastRecompute = this.tick; // Paper - region threading ++ this.timeLastRecompute = this.tick; // Folia - region threading this.hasDelayedRecomputation = false; } } else { @@ -16859,7 +16859,7 @@ index 97257b450e848f53fdb9b5b7affa57b03ea5f459..9720bc8766cc1dac6892a8a1ef3bf8c2 public boolean moveTo(Entity entity, double speed) { // Paper start - Pathfinding optimizations - if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) { -+ if (this.pathfindFailures > 10 && this.path == null && this.tick < this.lastFailure + 40) { // Paper - region threading ++ if (this.pathfindFailures > 10 && this.path == null && this.tick < this.lastFailure + 40) { // Folia - region threading return false; } // Paper end @@ -16868,12 +16868,12 @@ index 97257b450e848f53fdb9b5b7affa57b03ea5f459..9720bc8766cc1dac6892a8a1ef3bf8c2 } else { this.pathfindFailures++; - this.lastFailure = net.minecraft.server.MinecraftServer.currentTick; -+ this.lastFailure = this.tick; // Paper - region threading ++ this.lastFailure = this.tick; // Folia - region threading return false; } // Paper end diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/TemptingSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/TemptingSensor.java -index e3242cf9a6ad51a23c5781142198dec30c8f376d..2c14888d09168d906c6f4c9e173305c072c3c715 100644 +index e3242cf9a6ad51a23c5781142198dec30c8f376d..f32f5982ceb368b240062b9b8ac0141be59e2f1e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/TemptingSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/TemptingSensor.java @@ -37,7 +37,7 @@ public class TemptingSensor extends Sensor { @@ -16881,12 +16881,12 @@ index e3242cf9a6ad51a23c5781142198dec30c8f376d..2c14888d09168d906c6f4c9e173305c0 protected void doTick(ServerLevel world, PathfinderMob entity) { Brain behaviorcontroller = entity.getBrain(); - Stream stream = world.players().stream().filter(EntitySelector.NO_SPECTATORS).filter((entityplayer) -> { // CraftBukkit - decompile error -+ Stream stream = world.getLocalPlayers().stream().filter(EntitySelector.NO_SPECTATORS).filter((entityplayer) -> { // CraftBukkit - decompile error // Paper - region threading ++ Stream stream = world.getLocalPlayers().stream().filter(EntitySelector.NO_SPECTATORS).filter((entityplayer) -> { // CraftBukkit - decompile error // Folia - region threading return TemptingSensor.TEMPT_TARGETING.test(entity, entityplayer); }).filter((entityplayer) -> { return entity.closerThan(entityplayer, 10.0D); diff --git a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java -index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd79c32f873 100644 +index fed09b886f4fa0006d160e5f2abb00dfee45434d..394d73b10bc53310d936d1ad568a77bf852ef9d6 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java @@ -22,62 +22,66 @@ import org.slf4j.Logger; @@ -16900,62 +16900,62 @@ index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd7 - private int spawnX; - private int spawnY; - private int spawnZ; -+ // Paper - region threading ++ // Folia - region threading public VillageSiege() { - this.siegeState = VillageSiege.State.SIEGE_DONE; -+ // Paper - region threading ++ // Folia - region threading } @Override public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ // Paper start - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ // Folia start - region threading + // check if the spawn pos is no longer owned by this region + if (worldData.villageSiegeState.siegeState != State.SIEGE_DONE + && !io.papermc.paper.util.TickThread.isTickThreadFor(world, worldData.villageSiegeState.spawnX >> 4, worldData.villageSiegeState.spawnZ >> 4, 8)) { + // can't spawn here, just re-set + worldData.villageSiegeState = new io.papermc.paper.threadedregions.RegionisedWorldData.VillageSiegeState(); + } -+ // Paper end - region threading ++ // Folia end - region threading if (!world.isDay() && spawnMonsters) { float f = world.getTimeOfDay(0.0F); if ((double) f == 0.5D) { - this.siegeState = world.random.nextInt(10) == 0 ? VillageSiege.State.SIEGE_TONIGHT : VillageSiege.State.SIEGE_DONE; -+ worldData.villageSiegeState.siegeState = world.random.nextInt(10) == 0 ? VillageSiege.State.SIEGE_TONIGHT : VillageSiege.State.SIEGE_DONE; // Paper - region threading ++ worldData.villageSiegeState.siegeState = world.random.nextInt(10) == 0 ? VillageSiege.State.SIEGE_TONIGHT : VillageSiege.State.SIEGE_DONE; // Folia - region threading } - if (this.siegeState == VillageSiege.State.SIEGE_DONE) { -+ if (worldData.villageSiegeState.siegeState == VillageSiege.State.SIEGE_DONE) { // Paper - region threading ++ if (worldData.villageSiegeState.siegeState == VillageSiege.State.SIEGE_DONE) { // Folia - region threading return 0; } else { - if (!this.hasSetupSiege) { -+ if (!worldData.villageSiegeState.hasSetupSiege) { // Paper - region threading ++ if (!worldData.villageSiegeState.hasSetupSiege) { // Folia - region threading if (!this.tryToSetupSiege(world)) { return 0; } - this.hasSetupSiege = true; -+ worldData.villageSiegeState.hasSetupSiege = true; // Paper - region threading ++ worldData.villageSiegeState.hasSetupSiege = true; // Folia - region threading } - if (this.nextSpawnTime > 0) { - --this.nextSpawnTime; -+ if (worldData.villageSiegeState.nextSpawnTime > 0) { // Paper - region threading -+ --worldData.villageSiegeState.nextSpawnTime; // Paper - region threading ++ if (worldData.villageSiegeState.nextSpawnTime > 0) { // Folia - region threading ++ --worldData.villageSiegeState.nextSpawnTime; // Folia - region threading return 0; } else { - this.nextSpawnTime = 2; - if (this.zombiesToSpawn > 0) { -+ worldData.villageSiegeState.nextSpawnTime = 2; // Paper - region threading -+ if (worldData.villageSiegeState.zombiesToSpawn > 0) { // Paper - region threading ++ worldData.villageSiegeState.nextSpawnTime = 2; // Folia - region threading ++ if (worldData.villageSiegeState.zombiesToSpawn > 0) { // Folia - region threading this.trySpawn(world); - --this.zombiesToSpawn; -+ --worldData.villageSiegeState.zombiesToSpawn; // Paper - region threading ++ --worldData.villageSiegeState.zombiesToSpawn; // Folia - region threading } else { - this.siegeState = VillageSiege.State.SIEGE_DONE; -+ worldData.villageSiegeState.siegeState = VillageSiege.State.SIEGE_DONE; // Paper - region threading ++ worldData.villageSiegeState.siegeState = VillageSiege.State.SIEGE_DONE; // Folia - region threading } return 1; @@ -16964,16 +16964,16 @@ index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd7 } else { - this.siegeState = VillageSiege.State.SIEGE_DONE; - this.hasSetupSiege = false; -+ worldData.villageSiegeState.siegeState = VillageSiege.State.SIEGE_DONE; // Paper - region threading -+ worldData.villageSiegeState.hasSetupSiege = false; // Paper - region threading ++ worldData.villageSiegeState.siegeState = VillageSiege.State.SIEGE_DONE; // Folia - region threading ++ worldData.villageSiegeState.hasSetupSiege = false; // Folia - region threading return 0; } } private boolean tryToSetupSiege(ServerLevel world) { - Iterator iterator = world.players().iterator(); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ Iterator iterator = world.getLocalPlayers().iterator(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ Iterator iterator = world.getLocalPlayers().iterator(); // Folia - region threading while (iterator.hasNext()) { Player entityhuman = (Player) iterator.next(); @@ -16987,12 +16987,12 @@ index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd7 - if (this.findRandomSpawnPos(world, new BlockPos(this.spawnX, this.spawnY, this.spawnZ)) != null) { - this.nextSpawnTime = 0; - this.zombiesToSpawn = 20; -+ worldData.villageSiegeState.spawnX = blockposition.getX() + Mth.floor(Mth.cos(f) * 32.0F); // Paper - region threading -+ worldData.villageSiegeState.spawnY = blockposition.getY(); // Paper - region threading -+ worldData.villageSiegeState.spawnZ = blockposition.getZ() + Mth.floor(Mth.sin(f) * 32.0F); // Paper - region threading -+ if (this.findRandomSpawnPos(world, new BlockPos(worldData.villageSiegeState.spawnX, worldData.villageSiegeState.spawnY, worldData.villageSiegeState.spawnZ)) != null) { // Paper - region threading -+ worldData.villageSiegeState.nextSpawnTime = 0; // Paper - region threading -+ worldData.villageSiegeState.zombiesToSpawn = 20; // Paper - region threading ++ worldData.villageSiegeState.spawnX = blockposition.getX() + Mth.floor(Mth.cos(f) * 32.0F); // Folia - region threading ++ worldData.villageSiegeState.spawnY = blockposition.getY(); // Folia - region threading ++ worldData.villageSiegeState.spawnZ = blockposition.getZ() + Mth.floor(Mth.sin(f) * 32.0F); // Folia - region threading ++ if (this.findRandomSpawnPos(world, new BlockPos(worldData.villageSiegeState.spawnX, worldData.villageSiegeState.spawnY, worldData.villageSiegeState.spawnZ)) != null) { // Folia - region threading ++ worldData.villageSiegeState.nextSpawnTime = 0; // Folia - region threading ++ worldData.villageSiegeState.zombiesToSpawn = 20; // Folia - region threading break; } } @@ -17001,8 +17001,8 @@ index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd7 private void trySpawn(ServerLevel world) { - Vec3 vec3d = this.findRandomSpawnPos(world, new BlockPos(this.spawnX, this.spawnY, this.spawnZ)); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ Vec3 vec3d = this.findRandomSpawnPos(world, new BlockPos(worldData.villageSiegeState.spawnX, worldData.villageSiegeState.spawnY, worldData.villageSiegeState.spawnZ)); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ Vec3 vec3d = this.findRandomSpawnPos(world, new BlockPos(worldData.villageSiegeState.spawnX, worldData.villageSiegeState.spawnY, worldData.villageSiegeState.spawnZ)); // Folia - region threading if (vec3d != null) { Zombie entityzombie; @@ -17011,25 +17011,25 @@ index fed09b886f4fa0006d160e5f2abb00dfee45434d..df017df6ad9f09e7b4b9f908a7d76fd7 } - private static enum State { -+ public static enum State { // Paper - region threading ++ public static enum State { // Folia - region threading SIEGE_CAN_ACTIVATE, SIEGE_TONIGHT, SIEGE_DONE; diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 9be85eb0abec02bc0e0eded71c34ab1c565c63e7..1348a64e7530d449fb9177a4dfc74cdc275b5942 100644 +index 9be85eb0abec02bc0e0eded71c34ab1c565c63e7..9c56304476b4fc841b5d7694232617586ebd8e84 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java @@ -48,11 +48,13 @@ public class PoiManager extends SectionStorage { } protected void updateDistanceTracking(long section) { -+ synchronized (this.villageDistanceTracker) { // Paper - region threading ++ synchronized (this.villageDistanceTracker) { // Folia - region threading if (this.isVillageCenter(section)) { this.villageDistanceTracker.setSource(section, POI_DATA_SOURCE); } else { this.villageDistanceTracker.removeSource(section); } -+ } // Paper - region threading ++ } // Folia - region threading } // Paper end - rewrite chunk system @@ -17037,10 +17037,10 @@ index 9be85eb0abec02bc0e0eded71c34ab1c565c63e7..1348a64e7530d449fb9177a4dfc74cdc } public int sectionsToVillage(SectionPos pos) { -+ synchronized (this.villageDistanceTracker) { // Paper - region threading ++ synchronized (this.villageDistanceTracker) { // Folia - region threading this.villageDistanceTracker.propagateUpdates(); // Paper - replace distance tracking util return convertBetweenLevels(this.villageDistanceTracker.getLevel(io.papermc.paper.util.CoordinateUtils.getChunkSectionKey(pos))); // Paper - replace distance tracking util -+ } // Paper - region threading ++ } // Folia - region threading } boolean isVillageCenter(long pos) { @@ -17048,14 +17048,14 @@ index 9be85eb0abec02bc0e0eded71c34ab1c565c63e7..1348a64e7530d449fb9177a4dfc74cdc @Override public void tick(BooleanSupplier shouldKeepTicking) { -+ synchronized (this.villageDistanceTracker) { // Paper - region threading ++ synchronized (this.villageDistanceTracker) { // Folia - region threading this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system -+ } // Paper - region threading ++ } // Folia - region threading } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java -index 0114c1cf3b6b0500149a77ebc190cb7fa2832184..de7f839d6cf68080ca43f058a0635b624a927a15 100644 +index 0114c1cf3b6b0500149a77ebc190cb7fa2832184..1189465e79005c99204f873ca7768171218d6399 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java @@ -366,7 +366,7 @@ public class Cat extends TamableAnimal implements VariantHolder { @@ -17063,12 +17063,12 @@ index 0114c1cf3b6b0500149a77ebc190cb7fa2832184..de7f839d6cf68080ca43f058a0635b62 ServerLevel worldserver = world.getLevel(); - if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK, world).isValid()) { // Paper - fix deadlock -+ if (world.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) { // Paper - fix deadlock // Paper - region threading - properly fix this ++ if (world.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) { // Paper - fix deadlock // Folia - region threading - properly fix this this.setVariant((CatVariant) BuiltInRegistries.CAT_VARIANT.getOrThrow(CatVariant.ALL_BLACK)); this.setPersistenceRequired(); } diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 25503678e7d049a8b3172cfad8a5606958c32302..a2b11e8b87bdfcb6157b26a67ccec93293d0ff67 100644 +index 25503678e7d049a8b3172cfad8a5606958c32302..13d60258c6c491a7d0ba5cc93934f0c9b2abd35b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -336,9 +336,9 @@ public class Turtle extends Animal { @@ -17076,15 +17076,15 @@ index 25503678e7d049a8b3172cfad8a5606958c32302..a2b11e8b87bdfcb6157b26a67ccec932 @Override public void thunderHit(ServerLevel world, LightningBolt lightning) { - org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = lightning; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(lightning); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(lightning); // CraftBukkit // Folia - region threading this.hurt(DamageSource.LIGHTNING_BOLT, Float.MAX_VALUE); - org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Folia - region threading } private static class TurtleMoveControl extends MoveControl { diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index eacb8a407fe99af2c13f23c12b5544696bda8890..fb50ac26690182b1b173471ea2c66d7f32bcbdfd 100644 +index eacb8a407fe99af2c13f23c12b5544696bda8890..723d5f44c59a8073040669549d9cab88b45e9a3e 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -292,9 +292,9 @@ public class FallingBlockEntity extends Entity { @@ -17092,15 +17092,15 @@ index eacb8a407fe99af2c13f23c12b5544696bda8890..fb50ac26690182b1b173471ea2c66d7f this.level.getEntities((Entity) this, this.getBoundingBox(), predicate).forEach((entity) -> { - CraftEventFactory.entityDamage = this; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Folia - region threading entity.hurt(damagesource1, f2); - CraftEventFactory.entityDamage = null; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Folia - region threading }); boolean flag = this.blockState.is(BlockTags.ANVIL); diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c59994c812 100644 +index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..d07060fb35df66e77ebdd404444c58564fdb9402 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -50,7 +50,7 @@ public class ItemEntity extends Entity { @@ -17108,7 +17108,7 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 private UUID owner; public final float bobOffs; - private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit -+ //private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit // Paper - region threading ++ //private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit // Folia - region threading public boolean canMobPickup = true; // Paper private int despawnRate = -1; // Paper public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper @@ -17123,11 +17123,11 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 - if (this.age != -32768) this.age += elapsedTicks; - this.lastTick = MinecraftServer.currentTick; - // CraftBukkit end -+ // Paper start - region threading - restore original timers ++ // Folia start - region threading - restore original timers + if (this.pickupDelay > 0 && this.pickupDelay != 32767) { + --this.pickupDelay; + } -+ // Paper end - region threading - restore original timers ++ // Folia end - region threading - restore original timers this.xo = this.getX(); this.yo = this.getY(); @@ -17136,12 +17136,12 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 } - /* CraftBukkit start - moved up -+ // Paper - region threading - restore original timers ++ // Folia - region threading - restore original timers if (this.age != -32768) { ++this.age; } - // CraftBukkit end */ -+ // Paper - region threading - restore original timers ++ // Folia - region threading - restore original timers this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing(); if (!this.level.isClientSide) { @@ -17156,14 +17156,14 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 - if (this.age != -32768) this.age += elapsedTicks; - this.lastTick = MinecraftServer.currentTick; - // CraftBukkit end -+ // Paper start - region threading - restore original timers ++ // Folia start - region threading - restore original timers + if (this.pickupDelay > 0 && this.pickupDelay != 32767) { + --this.pickupDelay; + } + if (this.age != -32768) { + ++this.age; + } -+ // Paper end - region threading - restore original timers ++ // Folia end - region threading - restore original timers if (!this.level.isClientSide && this.age >= this.despawnRate) { // Spigot // Paper // CraftBukkit start - fire ItemDespawnEvent @@ -17171,13 +17171,13 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 return false; } -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public void postChangeDimension() { + super.postChangeDimension(); + this.mergeWithNeighbours(); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable @Override @@ -17187,12 +17187,12 @@ index f0ccdfbd7d7be8c6e302609accf8fe9cac8885c4..e93bc71c212dbf3a35c6ee7dff91e1c5 - if (!this.level.isClientSide && entity instanceof ItemEntity) { - ((ItemEntity) entity).mergeWithNeighbours(); - } -+ if (entity != null) entity.postChangeDimension(); // Paper - region threading - move to post change ++ if (entity != null) entity.postChangeDimension(); // Folia - region threading - move to post change return entity; } diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java -index bedee2c93bd0aff148f93dcf111e0fc3d9bce4a0..b58bf927e1527147ffbb23a14d906aff22870908 100644 +index bedee2c93bd0aff148f93dcf111e0fc3d9bce4a0..718701a39d0c5369600119330cec7f8015fd95b0 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -59,7 +59,7 @@ public class PrimedTnt extends Entity { @@ -17200,7 +17200,7 @@ index bedee2c93bd0aff148f93dcf111e0fc3d9bce4a0..b58bf927e1527147ffbb23a14d906aff @Override public void tick() { - if (level.spigotConfig.maxTntTicksPerTick > 0 && ++level.spigotConfig.currentPrimedTnt > level.spigotConfig.maxTntTicksPerTick) { return; } // Spigot -+ if (level.spigotConfig.maxTntTicksPerTick > 0 && ++level.getCurrentWorldData().currentPrimedTnt > level.spigotConfig.maxTntTicksPerTick) { return; } // Spigot // Paper - region threading ++ if (level.spigotConfig.maxTntTicksPerTick > 0 && ++level.getCurrentWorldData().currentPrimedTnt > level.spigotConfig.maxTntTicksPerTick) { return; } // Spigot // Folia - region threading if (!this.isNoGravity()) { this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.04D, 0.0D)); } @@ -17209,12 +17209,12 @@ index bedee2c93bd0aff148f93dcf111e0fc3d9bce4a0..b58bf927e1527147ffbb23a14d906aff // Send position and velocity updates to nearby players on every tick while the TNT is in water. // This does pretty well at keeping their clients in sync with the server. - net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel)this.level).getChunkSource().chunkMap.entityMap.get(this.getId()); -+ net.minecraft.server.level.ChunkMap.TrackedEntity ete = this.tracker; // Paper - region threading ++ net.minecraft.server.level.ChunkMap.TrackedEntity ete = this.tracker; // Folia - region threading if (ete != null) { net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this); net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = new net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java -index 9976205537cfe228735687f1e9c52c74ac025690..e1e93b48a7ea11f13a0f635eea4a1745af0890d5 100644 +index 9976205537cfe228735687f1e9c52c74ac025690..f286abfff186b657db99f28d3592465ccee4498a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -94,7 +94,7 @@ public class Zombie extends Monster { @@ -17222,7 +17222,7 @@ index 9976205537cfe228735687f1e9c52c74ac025690..e1e93b48a7ea11f13a0f635eea4a1745 private int inWaterTime; public int conversionTime; - private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field -+ // private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Paper - region threading - restore original timers ++ // private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Folia - region threading - restore original timers private boolean shouldBurnInDay = true; // Paper public Zombie(EntityType type, Level world) { @@ -17234,7 +17234,7 @@ index 9976205537cfe228735687f1e9c52c74ac025690..e1e93b48a7ea11f13a0f635eea4a1745 - int elapsedTicks = MinecraftServer.currentTick - this.lastTick; - this.conversionTime -= elapsedTicks; - // CraftBukkit end -+ --this.conversionTime; // Paper - region threading - restore original timers ++ --this.conversionTime; // Folia - region threading - restore original timers if (this.conversionTime < 0) { this.doUnderWaterConversion(); } @@ -17243,7 +17243,7 @@ index 9976205537cfe228735687f1e9c52c74ac025690..e1e93b48a7ea11f13a0f635eea4a1745 super.tick(); - this.lastTick = MinecraftServer.currentTick; // CraftBukkit -+ //this.lastTick = MinecraftServer.currentTick; // CraftBukkit // Paper - region threading - restore original timers ++ //this.lastTick = MinecraftServer.currentTick; // CraftBukkit // Folia - region threading - restore original timers } @Override @@ -17252,12 +17252,12 @@ index 9976205537cfe228735687f1e9c52c74ac025690..e1e93b48a7ea11f13a0f635eea4a1745 // Paper end public void startUnderWaterConversion(int ticksUntilWaterConversion) { - this.lastTick = MinecraftServer.currentTick; // CraftBukkit -+ // Paper - region threading - restore original timers ++ // Folia - region threading - restore original timers this.conversionTime = ticksUntilWaterConversion; this.getEntityData().set(Zombie.DATA_DROWNED_CONVERSION_ID, true); } diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java -index 71a36cf9b976443cca9ab63cd0eb23253f638562..b6d9cf729c732f3954aacdced6e8b7661c65f606 100644 +index 71a36cf9b976443cca9ab63cd0eb23253f638562..c7a03304d8fb33e2e5c90547cba46665b51eec79 100644 --- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java @@ -70,7 +70,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { @@ -17265,7 +17265,7 @@ index 71a36cf9b976443cca9ab63cd0eb23253f638562..b6d9cf729c732f3954aacdced6e8b766 private CompoundTag tradeOffers; private int villagerXp; - private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field -+ // private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Paper - region threading - restore original timers ++ // private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Folia - region threading - restore original timers public ZombieVillager(EntityType type, Level world) { super(type, world); @@ -17277,7 +17277,7 @@ index 71a36cf9b976443cca9ab63cd0eb23253f638562..b6d9cf729c732f3954aacdced6e8b766 - int elapsedTicks = MinecraftServer.currentTick - this.lastTick; - i *= elapsedTicks; - // CraftBukkit end -+ // Paper - region threading - restore original timers ++ // Folia - region threading - restore original timers this.villagerConversionTime -= i; if (this.villagerConversionTime <= 0) { @@ -17286,36 +17286,36 @@ index 71a36cf9b976443cca9ab63cd0eb23253f638562..b6d9cf729c732f3954aacdced6e8b766 super.tick(); - this.lastTick = MinecraftServer.currentTick; // CraftBukkit -+ // Paper - region threading - restore original timers ++ // Folia - region threading - restore original timers } @Override diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index ca96b893e22de3ae7c11d5cded51edf70bdcb6f2..2122761e70931bf80d859f8c13fc6757acbeca6b 100644 +index ca96b893e22de3ae7c11d5cded51edf70bdcb6f2..6000e891620850aac303630bf6676085d41f65b5 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -213,10 +213,18 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa this.readInventoryFromTag(nbt); } -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public void preChangeDimension() { + super.preChangeDimension(); + this.stopTrading(); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable @Override public Entity changeDimension(ServerLevel destination) { - this.stopTrading(); -+ this.preChangeDimension(); // Paper - region threading - move into preChangeDimension ++ this.preChangeDimension(); // Folia - region threading - move into preChangeDimension return super.changeDimension(destination); } diff --git a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java -index 5f407535298a31a34cfe114dd863fd6a9b977707..a7937515a94bcaf981dfd7d525eed4cac9b85639 100644 +index 5f407535298a31a34cfe114dd863fd6a9b977707..1f1e3d6e5e94b985a5c929ab266a996471432923 100644 --- a/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/CatSpawner.java @@ -21,17 +21,18 @@ import net.minecraft.world.phys.AABB; @@ -17323,35 +17323,35 @@ index 5f407535298a31a34cfe114dd863fd6a9b977707..a7937515a94bcaf981dfd7d525eed4ca public class CatSpawner implements CustomSpawner { private static final int TICK_DELAY = 1200; - private int nextTick; -+ //private int nextTick; // Paper - region threading ++ //private int nextTick; // Folia - region threading @Override public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) { if (spawnAnimals && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { - --this.nextTick; - if (this.nextTick > 0) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ --worldData.catSpawnerNextTick; // Paper - region threading -+ if (worldData.catSpawnerNextTick > 0) { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ --worldData.catSpawnerNextTick; // Folia - region threading ++ if (worldData.catSpawnerNextTick > 0) { // Folia - region threading return 0; } else { - this.nextTick = 1200; - Player player = world.getRandomPlayer(); -+ worldData.catSpawnerNextTick = 1200; // Paper - region threading -+ Player player = world.getRandomLocalPlayer(); // Paper - region threading ++ worldData.catSpawnerNextTick = 1200; // Folia - region threading ++ Player player = world.getRandomLocalPlayer(); // Folia - region threading if (player == null) { return 0; } else { diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index 18eac340386a396c9850f53f30d20a41c1437788..bbae576e1b360809ee5b8d0ba2da7456d042b622 100644 +index 18eac340386a396c9850f53f30d20a41c1437788..81efaadf67f7bcc6097c19c05ba2fdb6b34d8218 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -710,6 +710,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler ServerLevel worldserver = minecraftserver.getLevel(globalpos.dimension()); if (worldserver != null) { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( // Paper - region threading -+ worldserver, globalpos.pos().getX() >> 4, globalpos.pos().getZ() >> 4, () -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue( // Folia - region threading ++ worldserver, globalpos.pos().getX() >> 4, globalpos.pos().getZ() >> 4, () -> { // Folia - region threading PoiManager villageplace = worldserver.getPoiManager(); Optional> optional = villageplace.getType(globalpos.pos()); BiPredicate> bipredicate = (BiPredicate) Villager.POI_MEMORIES.get(pos); @@ -17359,12 +17359,12 @@ index 18eac340386a396c9850f53f30d20a41c1437788..bbae576e1b360809ee5b8d0ba2da7456 villageplace.release(globalpos.pos()); DebugPackets.sendPoiTicketCountPacket(worldserver, globalpos.pos()); } -+ }); // Paper - region threading ++ }); // Folia - region threading } }); diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..818cea3b1d00879fea4346d8e1c761a28cb9e206 100644 +index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..d9d832b7978d03417912408564f6e21bb5e52dc3 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -32,16 +32,14 @@ public class WanderingTraderSpawner implements CustomSpawner { @@ -17372,18 +17372,18 @@ index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..818cea3b1d00879fea4346d8e1c761a2 private static final int SPAWN_ONE_IN_X_CHANCE = 10; private static final int NUMBER_OF_SPAWN_ATTEMPTS = 10; - private final RandomSource random = RandomSource.create(); -+ private final RandomSource random = new net.minecraft.world.entity.Entity.RandomRandomSource(); // Paper - region threading ++ private final RandomSource random = new net.minecraft.world.entity.Entity.RandomRandomSource(); // Folia - region threading private final ServerLevelData serverLevelData; - private int tickDelay; - private int spawnDelay; - private int spawnChance; -+ // Paper - region threading ++ // Folia - region threading public WanderingTraderSpawner(ServerLevelData properties) { this.serverLevelData = properties; // Paper start - this.tickDelay = Integer.MIN_VALUE; -+ //this.tickDelay = Integer.MIN_VALUE; // Paper - region threading - moved to regionisedworlddata ++ //this.tickDelay = Integer.MIN_VALUE; // Folia - region threading - moved to regionisedworlddata //this.spawnDelay = properties.getWanderingTraderSpawnDelay(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value //this.spawnChance = properties.getWanderingTraderSpawnChance(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value //if (this.spawnDelay == 0 && this.spawnChance == 0) { @@ -17391,50 +17391,50 @@ index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..818cea3b1d00879fea4346d8e1c761a2 @Override public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading // Paper start - if (this.tickDelay == Integer.MIN_VALUE) { - this.tickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; - this.spawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; - this.spawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; -+ if (worldData.wanderingTraderTickDelay == Integer.MIN_VALUE) { // Paper - region threading -+ worldData.wanderingTraderTickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Paper - region threading -+ worldData.wanderingTraderSpawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Paper - region threading -+ worldData.wanderingTraderSpawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Paper - region threading ++ if (worldData.wanderingTraderTickDelay == Integer.MIN_VALUE) { // Folia - region threading ++ worldData.wanderingTraderTickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading ++ worldData.wanderingTraderSpawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Folia - region threading ++ worldData.wanderingTraderSpawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Folia - region threading } if (!world.getGameRules().getBoolean(GameRules.RULE_DO_TRADER_SPAWNING)) { return 0; - } else if (this.tickDelay - 1 > 0) { - this.tickDelay = this.tickDelay - 1; -+ } else if (worldData.wanderingTraderTickDelay - 1 > 0) { // Paper - region threading -+ worldData.wanderingTraderTickDelay = worldData.wanderingTraderTickDelay - 1; // Paper - region threading ++ } else if (worldData.wanderingTraderTickDelay - 1 > 0) { // Folia - region threading ++ worldData.wanderingTraderTickDelay = worldData.wanderingTraderTickDelay - 1; // Folia - region threading return 0; } else { - this.tickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; - this.spawnDelay = this.spawnDelay - world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; -+ worldData.wanderingTraderTickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Paper - region threading -+ worldData.wanderingTraderSpawnDelay = worldData.wanderingTraderSpawnDelay - world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Paper - region threading ++ worldData.wanderingTraderTickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading ++ worldData.wanderingTraderSpawnDelay = worldData.wanderingTraderSpawnDelay - world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading //this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways - if (this.spawnDelay > 0) { -+ if (worldData.wanderingTraderSpawnDelay > 0) { // Paper - region threading ++ if (worldData.wanderingTraderSpawnDelay > 0) { // Folia - region threading return 0; } else { - this.spawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; -+ worldData.wanderingTraderSpawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Paper - region threading ++ worldData.wanderingTraderSpawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Folia - region threading if (!world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { return 0; } else { - int i = this.spawnChance; -+ int i = worldData.wanderingTraderSpawnChance; // Paper - region threading ++ int i = worldData.wanderingTraderSpawnChance; // Folia - region threading - this.spawnChance = Mth.clamp(i + world.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax); -+ worldData.wanderingTraderSpawnChance = Mth.clamp(i + world.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax); // Paper - region threading ++ worldData.wanderingTraderSpawnChance = Mth.clamp(i + world.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax); // Folia - region threading //this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways if (this.random.nextInt(100) > i) { return 0; } else if (this.spawn(world)) { - this.spawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; -+ worldData.wanderingTraderSpawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Paper - region threading ++ worldData.wanderingTraderSpawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Folia - region threading // Paper end return 1; } else { @@ -17443,7 +17443,7 @@ index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..818cea3b1d00879fea4346d8e1c761a2 private boolean spawn(ServerLevel world) { - ServerPlayer entityplayer = world.getRandomPlayer(); -+ ServerPlayer entityplayer = world.getRandomLocalPlayer(); // Paper - region threading ++ ServerPlayer entityplayer = world.getRandomLocalPlayer(); // Folia - region threading if (entityplayer == null) { return true; @@ -17452,12 +17452,12 @@ index 0ae8e9134a3671cdf2a480cd4dd6598653e261ab..818cea3b1d00879fea4346d8e1c761a2 } - this.serverLevelData.setWanderingTraderId(entityvillagertrader.getUUID()); -+ //this.serverLevelData.setWanderingTraderId(entityvillagertrader.getUUID()); // Paper - region threading - doesn't appear to be used anywhere, so avoid the race condition here... ++ //this.serverLevelData.setWanderingTraderId(entityvillagertrader.getUUID()); // Folia - region threading - doesn't appear to be used anywhere, so avoid the race condition here... // entityvillagertrader.setDespawnDelay(48000); // CraftBukkit - moved to EntityVillagerTrader constructor. This lets the value be modified by plugins on CreatureSpawnEvent entityvillagertrader.setWanderTarget(blockposition1); entityvillagertrader.restrictTo(blockposition1, 16); 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..793ce02233202542ca7f421e0ba8e7e5a3dc3763 100644 +index c7265a650a5d6bdc42d41c5c90cad401d7f1c99d..c95d80ee142dc056874af6baf2d058cc932985e9 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java +++ b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java @@ -128,9 +128,9 @@ public class EvokerFangs extends Entity { @@ -17465,25 +17465,25 @@ index c7265a650a5d6bdc42d41c5c90cad401d7f1c99d..793ce02233202542ca7f421e0ba8e7e5 if (target.isAlive() && !target.isInvulnerable() && target != entityliving1) { if (entityliving1 == null) { - org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = this; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Folia - region threading target.hurt(DamageSource.MAGIC, 6.0F); - org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Folia - region threading } else { if (entityliving1.isAlliedTo((Entity) target)) { return; diff --git a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -index 5406925cd66f46ab8744123c670d72cea7bfc3a1..39ba77db0767a09798fe17156b2dffeca11af1c3 100644 +index 5406925cd66f46ab8744123c670d72cea7bfc3a1..d0fa197283a3bf14ead356e832500430ecae3f86 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java @@ -130,6 +130,10 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { }); } -+ if (this.attachedToEntity != null && !io.papermc.paper.util.TickThread.isTickThreadFor(this.attachedToEntity)) { // Paper start - region threading ++ if (this.attachedToEntity != null && !io.papermc.paper.util.TickThread.isTickThreadFor(this.attachedToEntity)) { // Folia start - region threading + this.attachedToEntity = null; + } -+ // Paper end - region threading ++ // Folia end - region threading if (this.attachedToEntity != null) { if (this.attachedToEntity.isFallFlying()) { @@ -17492,10 +17492,10 @@ index 5406925cd66f46ab8744123c670d72cea7bfc3a1..39ba77db0767a09798fe17156b2dffec if (f > 0.0F) { if (this.attachedToEntity != null) { - CraftEventFactory.entityDamage = this; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Folia - region threading this.attachedToEntity.hurt(DamageSource.fireworks(this, this.getOwner()), 5.0F + (float) (nbttaglist.size() * 2)); - CraftEventFactory.entityDamage = null; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Folia - region threading } double d0 = 5.0D; @@ -17504,22 +17504,22 @@ index 5406925cd66f46ab8744123c670d72cea7bfc3a1..39ba77db0767a09798fe17156b2dffec float f1 = f * (float) Math.sqrt((5.0D - (double) this.distanceTo(entityliving)) / 5.0D); - CraftEventFactory.entityDamage = this; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(this); // CraftBukkit // Folia - region threading entityliving.hurt(DamageSource.fireworks(this, this.getOwner()), f1); - CraftEventFactory.entityDamage = null; // CraftBukkit -+ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // CraftBukkit // Folia - region threading } } } 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..e67ebc2284dc18b74e098694549f8c9850112bcf 100644 +index 66476b33cede1e44db5ec166a0cea81f82ffe47a..26a17e3098317f6f623cdcab59dceb9d213c7f63 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -52,8 +52,19 @@ public abstract class Projectile extends Entity { } -+ // Paper start - region threading ++ // Folia start - region threading + // In general, this is an entire mess. At the time of writing, there are fifty usages of getOwner. + // Usage of this function is to avoid concurrency issues, even if it sacrifices behavior. @Nullable @@ -17527,11 +17527,11 @@ index 66476b33cede1e44db5ec166a0cea81f82ffe47a..e67ebc2284dc18b74e098694549f8c98 + Entity ret = this.getOwnerRaw(); + return io.papermc.paper.util.TickThread.isTickThreadFor(ret) ? ret : null; + } -+ // Paper end - region threading ++ // Folia end - region threading + + @Nullable -+ public Entity getOwnerRaw() { // Paper - region threading -+ io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot update owner state asynchronously"); // Paper - region threading ++ public Entity getOwnerRaw() { // Folia - region threading ++ io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot update owner state asynchronously"); // Folia - region threading if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) { return this.cachedOwner; } else if (this.ownerUUID != null && this.level instanceof ServerLevel) { @@ -17540,11 +17540,11 @@ index 66476b33cede1e44db5ec166a0cea81f82ffe47a..e67ebc2284dc18b74e098694549f8c98 Entity entity = this.getOwner(); - return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ return entity instanceof Player && io.papermc.paper.util.TickThread.isTickThreadFor(entity) ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Paper - region threading ++ return entity instanceof Player && io.papermc.paper.util.TickThread.isTickThreadFor(entity) ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Folia - region threading } } diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java -index 00ac1cdc4734cc57f15433c5c6e7a3a545739d33..3f26008055462987bd4c0e38303e0dcab0315fa2 100644 +index 00ac1cdc4734cc57f15433c5c6e7a3a545739d33..39b0034b7c612759fed87b6a5fff1819583f3f85 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java @@ -23,7 +23,7 @@ public class SmallFireball extends Fireball { @@ -17552,19 +17552,19 @@ index 00ac1cdc4734cc57f15433c5c6e7a3a545739d33..3f26008055462987bd4c0e38303e0dca super(EntityType.SMALL_FIREBALL, owner, velocityX, velocityY, velocityZ, world); // CraftBukkit start - if (this.getOwner() != null && this.getOwner() instanceof Mob) { -+ if (owner != null && owner instanceof Mob) { // Paper - region threading ++ if (owner != null && owner instanceof Mob) { // Folia - region threading isIncendiary = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); } // CraftBukkit end 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..05c4cad5c3cec3a1316337fcd89eedd875deb0bc 100644 +index f224ebbc0efefddede43d87f0300c014077b9931..2627610b77e779722bb33eeb1096d862aa9639d2 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java @@ -44,6 +44,62 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityHitResult.getEntity().hurt(DamageSource.thrown(this, this.getOwner()), 0.0F); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void attemptTeleport(Entity source, ServerLevel checkWorld, net.minecraft.world.phys.Vec3 to) { + // ignore retired callback, in those cases we do not want to teleport + source.getBukkitEntity().taskScheduler.schedule( @@ -17618,7 +17618,7 @@ index f224ebbc0efefddede43d87f0300c014077b9931..05c4cad5c3cec3a1316337fcd89eedd8 + 1L + ); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override protected void onHit(HitResult hitResult) { @@ -17627,7 +17627,7 @@ index f224ebbc0efefddede43d87f0300c014077b9931..05c4cad5c3cec3a1316337fcd89eedd8 } if (!this.level.isClientSide && !this.isRemoved()) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + // we can't fire events, because we do not actually know where the other entity is located + if (!io.papermc.paper.util.TickThread.isTickThreadFor(this)) { @@ -17640,7 +17640,7 @@ index f224ebbc0efefddede43d87f0300c014077b9931..05c4cad5c3cec3a1316337fcd89eedd8 + this.discard(); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading Entity entity = this.getOwner(); if (entity instanceof ServerPlayer) { @@ -17649,10 +17649,10 @@ index f224ebbc0efefddede43d87f0300c014077b9931..05c4cad5c3cec3a1316337fcd89eedd8 entityplayer.connection.teleport(teleEvent.getTo()); entity.resetFallDistance(); - CraftEventFactory.entityDamage = this; -+ CraftEventFactory.entityDamageRT.set(this); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(this); // Folia - region threading entity.hurt(DamageSource.FALL, 5.0F); - CraftEventFactory.entityDamage = null; -+ CraftEventFactory.entityDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading } // CraftBukkit end } @@ -17660,19 +17660,19 @@ index f224ebbc0efefddede43d87f0300c014077b9931..05c4cad5c3cec3a1316337fcd89eedd8 } -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public void preChangeDimension() { + super.preChangeDimension(); + // Don't change the owner here, since the tick logic will consider it anyways. + } -+ // Paper end - region threading ++ // Folia end - region threading + @Nullable @Override public Entity changeDimension(ServerLevel destination) { diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java -index 08b18428e867baf14f551beb72e3875b0c420639..25a281c2944d79d7b91d8bdfa535b3cccf565668 100644 +index 08b18428e867baf14f551beb72e3875b0c420639..7ee273a8a7fa72fcdea925be5fa0dd626dc54b71 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raid.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java @@ -527,7 +527,7 @@ public class Raid { @@ -17680,12 +17680,12 @@ index 08b18428e867baf14f551beb72e3875b0c420639..25a281c2944d79d7b91d8bdfa535b3cc Collection collection = this.raidEvent.getPlayers(); long i = this.random.nextLong(); - Iterator iterator = this.level.players().iterator(); -+ Iterator iterator = this.level.getLocalPlayers().iterator(); // Paper - region threading ++ Iterator iterator = this.level.getLocalPlayers().iterator(); // Folia - region threading while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java -index e5ccbaf72f29731f1d1aa939b9297b644a408cd4..27318f3a879f6798af4b4ae96d597958266cd7da 100644 +index e5ccbaf72f29731f1d1aa939b9297b644a408cd4..1792655d2f0357b388b3c83886cac4bc109e1aa9 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java @@ -91,7 +91,7 @@ public abstract class Raider extends PatrollingMonster { @@ -17693,7 +17693,7 @@ index e5ccbaf72f29731f1d1aa939b9297b644a408cd4..27318f3a879f6798af4b4ae96d597958 if (this.canJoinRaid()) { if (raid == null) { - if (this.level.getGameTime() % 20L == 0L) { -+ if (this.level.getRedstoneGameTime() % 20L == 0L) { // Paper - region threading ++ if (this.level.getRedstoneGameTime() % 20L == 0L) { // Folia - region threading Raid raid1 = ((ServerLevel) this.level).getRaidAt(this.blockPosition()); if (raid1 != null && Raids.canJoinRaid(this, raid1)) { @@ -17711,7 +17711,7 @@ index 70f1916185b79bbb9f033f4ef8119d7b17a13ef8..54d55e8827f4ab286fca722f199aac42 // Paper end diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java -index 9c8604376228c02f8bbd9a15673fbdf5097e7cb2..ed784d9b434a17e9806ec413359c0f8047f5cc7a 100644 +index 9c8604376228c02f8bbd9a15673fbdf5097e7cb2..40410ce889ef18344291f04d29938b4d1d3c9766 100644 --- a/src/main/java/net/minecraft/world/item/ArmorItem.java +++ b/src/main/java/net/minecraft/world/item/ArmorItem.java @@ -63,7 +63,7 @@ public class ArmorItem extends Item implements Wearable { @@ -17719,12 +17719,12 @@ index 9c8604376228c02f8bbd9a15673fbdf5097e7cb2..ed784d9b434a17e9806ec413359c0f80 BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityliving.getBukkitEntity()); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading world.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935dc02d43bf 100644 +index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..00cc67322d7de29c30b54aa7da62cc44d6469a1d 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java @@ -333,6 +333,7 @@ public final class ItemStack { @@ -17739,15 +17739,15 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d CompoundTag oldData = this.getTagClone(); int oldCount = this.getCount(); ServerLevel world = (ServerLevel) itemactioncontext.getLevel(); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading if (!(this.getItem() instanceof BucketItem/* || this.getItem() instanceof SolidBucketItem*/)) { // if not bucket // Paper - capture block states for snow buckets - world.captureBlockStates = true; -+ worldData.captureBlockStates = true; // Paper - region threading ++ worldData.captureBlockStates = true; // Folia - region threading // special case bonemeal if (this.getItem() == Items.BONE_MEAL) { - world.captureTreeGeneration = true; -+ worldData.captureTreeGeneration = true; // Paper - region threading ++ worldData.captureTreeGeneration = true; // Folia - region threading } } Item item = this.getItem(); @@ -17758,16 +17758,16 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d - world.captureBlockStates = false; - if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { - world.captureTreeGeneration = false; -+ worldData.captureBlockStates = false; // Paper - region threading -+ if (enuminteractionresult.consumesAction() && worldData.captureTreeGeneration && worldData.capturedBlockStates.size() > 0) { // Paper - region threading -+ world.getCurrentWorldData().captureTreeGeneration = false; // Paper - region threading ++ worldData.captureBlockStates = false; // Folia - region threading ++ if (enuminteractionresult.consumesAction() && worldData.captureTreeGeneration && worldData.capturedBlockStates.size() > 0) { // Folia - region threading ++ world.getCurrentWorldData().captureTreeGeneration = false; // Folia - region threading Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); TreeType treeType = SaplingBlock.treeType; SaplingBlock.treeType = null; - List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); - world.capturedBlockStates.clear(); -+ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading StructureGrowEvent structureEvent = null; if (treeType != null) { boolean isBonemeal = this.getItem() == Items.BONE_MEAL; @@ -17776,14 +17776,14 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d return enuminteractionresult; } - world.captureTreeGeneration = false; -+ worldData.captureTreeGeneration = false; // Paper - region threading ++ worldData.captureTreeGeneration = false; // Folia - region threading if (entityhuman != null && enuminteractionresult.shouldAwardStats()) { org.bukkit.event.block.BlockPlaceEvent placeEvent = null; - List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); - world.capturedBlockStates.clear(); -+ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading if (blocks.size() > 1) { placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - don't call event twice for snow buckets @@ -17792,15 +17792,15 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d // PAIL: Remove this when MC-99075 fixed placeEvent.getPlayer().updateInventory(); - world.capturedTileEntities.clear(); // Paper - clear out tile entities as chests and such will pop loot -+ worldData.capturedTileEntities.clear(); // Paper - clear out tile entities as chests and such will pop loot // Paper - region threading ++ worldData.capturedTileEntities.clear(); // Paper - clear out tile entities as chests and such will pop loot // Folia - region threading // revert back all captured blocks - world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 -+ worldData.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 // Paper - region threading ++ worldData.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 // Folia - region threading for (BlockState blockstate : blocks) { blockstate.update(true, false); } - world.preventPoiUpdated = false; -+ worldData.preventPoiUpdated = false; // Paper - region threading ++ worldData.preventPoiUpdated = false; // Folia - region threading // Brute force all possible updates BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); @@ -17809,7 +17809,7 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d } - for (Map.Entry e : world.capturedTileEntities.entrySet()) { -+ for (Map.Entry e : worldData.capturedTileEntities.entrySet()) { // Paper - region threading ++ for (Map.Entry e : worldData.capturedTileEntities.entrySet()) { // Folia - region threading world.setBlockEntity(e.getValue()); } @@ -17819,13 +17819,13 @@ index 6860096cb8c0deecc9c1d87543d1128fb95fd2d4..0cf04eaaaa28da545038c181cf1d935d } - world.capturedTileEntities.clear(); - world.capturedBlockStates.clear(); -+ worldData.capturedTileEntities.clear(); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ worldData.capturedTileEntities.clear(); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading // CraftBukkit end return enuminteractionresult; diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index c6d2f764efa9b8bec730bbe757d480e365b25ccc..6349e2b658936d96e7e61cc075c9e622efe9f2c4 100644 +index c6d2f764efa9b8bec730bbe757d480e365b25ccc..af9313a3b3aaa0af4f2a2f4fb2424dc3e9140d9c 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java @@ -67,7 +67,7 @@ public class MinecartItem extends Item { @@ -17833,35 +17833,35 @@ index c6d2f764efa9b8bec730bbe757d480e365b25ccc..6349e2b658936d96e7e61cc075c9e622 BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); - if (!DispenserBlock.eventFired) { -+ if (!DispenserBlock.eventFired.get()) { // Paper - region threading ++ if (!DispenserBlock.eventFired.get()) { // Folia - region threading worldserver.getCraftServer().getPluginManager().callEvent(event); } diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java -index 888936385196a178ab8b730fd5e4fff4a5466428..4ed13a0d861be38b90e3876400b62437758c9e71 100644 +index 888936385196a178ab8b730fd5e4fff4a5466428..df4632a6ddef8744df160163c99bdcdd6225dd97 100644 --- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java +++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java @@ -111,6 +111,7 @@ public abstract class BaseCommandBlock implements CommandSource { } public boolean performCommand(Level world) { -+ if (true) return false; // Paper - region threading ++ if (true) return false; // Folia - region threading if (!world.isClientSide && world.getGameTime() != this.lastExecution) { if ("Searge".equalsIgnoreCase(this.command)) { this.lastOutput = Component.literal("#itzlipofutzli"); diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a935802537784 100644 +index 3b959f42d958bf0f426853aee56753d6c455fcdb..b1a6a66ed02706c1adc36dcedfa415f5a24a25a0 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java @@ -38,6 +38,12 @@ public interface EntityGetter { return this.getEntities(EntityTypeTest.forClass(entityClass), box, predicate); } -+ // Paper start - region threading ++ // Folia start - region threading + default List getLocalPlayers() { + return java.util.Collections.emptyList(); + } -+ // Paper end - region threading ++ // Folia end - region threading + List players(); @@ -17871,7 +17871,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 Player player = null; - for(Player player2 : this.players()) { -+ for(Player player2 : this.getLocalPlayers()) { // Paper - region threading ++ for(Player player2 : this.getLocalPlayers()) { // Folia - region threading if (targetPredicate == null || targetPredicate.test(player2)) { double e = player2.distanceToSqr(x, y, z); if ((maxDistance < 0.0D || e < maxDistance * maxDistance) && (d == -1.0D || e < d)) { @@ -17880,7 +17880,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 com.google.common.collect.ImmutableList.Builder builder = com.google.common.collect.ImmutableList.builder(); - for (Player human : this.players()) { -+ for (Player human : this.getLocalPlayers()) { // Paper - region threading ++ for (Player human : this.getLocalPlayers()) { // Folia - region threading if (predicate == null || predicate.test(human)) { double distanceSquared = human.distanceToSqr(x, y, z); @@ -17889,7 +17889,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 // Paper start default boolean hasNearbyAlivePlayerThatAffectsSpawning(double x, double y, double z, double range) { - for (Player player : this.players()) { -+ for (Player player : this.getLocalPlayers()) { // Paper - region threading ++ for (Player player : this.getLocalPlayers()) { // Folia - region threading if (EntitySelector.PLAYER_AFFECTS_SPAWNING.test(player)) { // combines NO_SPECTATORS and LIVING_ENTITY_STILL_ALIVE with an "affects spawning" check double distanceSqr = player.distanceToSqr(x, y, z); if (range < 0.0D || distanceSqr < range * range) { @@ -17898,7 +17898,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) { - for(Player player : this.players()) { -+ for(Player player : this.getLocalPlayers()) { // Paper - region threading ++ for(Player player : this.getLocalPlayers()) { // Folia - region threading if (EntitySelector.NO_SPECTATORS.test(player) && EntitySelector.LIVING_ENTITY_STILL_ALIVE.test(player)) { double d = player.distanceToSqr(x, y, z); if (range < 0.0D || d < range * range) { @@ -17907,19 +17907,19 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 @Nullable default Player getNearestPlayer(TargetingConditions targetPredicate, LivingEntity entity) { - return this.getNearestEntity(this.players(), targetPredicate, entity, entity.getX(), entity.getY(), entity.getZ()); -+ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, entity, entity.getX(), entity.getY(), entity.getZ()); // Paper - region threading ++ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, entity, entity.getX(), entity.getY(), entity.getZ()); // Folia - region threading } @Nullable default Player getNearestPlayer(TargetingConditions targetPredicate, LivingEntity entity, double x, double y, double z) { - return this.getNearestEntity(this.players(), targetPredicate, entity, x, y, z); -+ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, entity, x, y, z); // Paper - region threading ++ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, entity, x, y, z); // Folia - region threading } @Nullable default Player getNearestPlayer(TargetingConditions targetPredicate, double x, double y, double z) { - return this.getNearestEntity(this.players(), targetPredicate, (LivingEntity)null, x, y, z); -+ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, (LivingEntity)null, x, y, z); // Paper - region threading ++ return this.getNearestEntity(this.getLocalPlayers(), targetPredicate, (LivingEntity)null, x, y, z); // Folia - region threading } @Nullable @@ -17928,7 +17928,7 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 List list = Lists.newArrayList(); - for(Player player : this.players()) { -+ for(Player player : this.getLocalPlayers()) { // Paper - region threading ++ for(Player player : this.getLocalPlayers()) { // Folia - region threading if (box.contains(player.getX(), player.getY(), player.getZ()) && targetPredicate.test(entity, player)) { list.add(player); } @@ -17938,12 +17938,12 @@ index 3b959f42d958bf0f426853aee56753d6c455fcdb..4b7c27db1eef71fef6bdea797b6a9358 default Player getPlayerByUUID(UUID uuid) { - for(int i = 0; i < this.players().size(); ++i) { - Player player = this.players().get(i); -+ for(Player player : this.getLocalPlayers()) { // Paper - region threading ++ for(Player player : this.getLocalPlayers()) { // Folia - region threading if (uuid.equals(player.getUUID())) { return player; } diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index a213f4098859858a73ddd601bbe8c7511972e0d5..aeadc22e0df2d759252f5c73f9a79b7557991b10 100644 +index a213f4098859858a73ddd601bbe8c7511972e0d5..07aa859ccfd3283097c172672c5d80130187cd4c 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -246,7 +246,7 @@ public class Explosion { @@ -17951,7 +17951,7 @@ index a213f4098859858a73ddd601bbe8c7511972e0d5..aeadc22e0df2d759252f5c73f9a79b75 } - CraftEventFactory.entityDamage = this.source; -+ CraftEventFactory.entityDamageRT.set(this.source); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(this.source); // Folia - region threading entity.lastDamageCancelled = false; if (entity instanceof EnderDragon) { @@ -17960,7 +17960,7 @@ index a213f4098859858a73ddd601bbe8c7511972e0d5..aeadc22e0df2d759252f5c73f9a79b75 } - CraftEventFactory.entityDamage = null; -+ CraftEventFactory.entityDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled continue; } @@ -17969,7 +17969,7 @@ index a213f4098859858a73ddd601bbe8c7511972e0d5..aeadc22e0df2d759252f5c73f9a79b75 // Paper start - Optimize explosions private float getBlockDensity(Vec3 vec3d, Entity entity) { - if (!this.level.paperConfig().environment.optimizeExplosions) { -+ if (true || !this.level.paperConfig().environment.optimizeExplosions) { // Paper - region threading ++ if (true || !this.level.paperConfig().environment.optimizeExplosions) { // Folia - region threading return getSeenPercent(vec3d, entity); } - CacheKey key = new CacheKey(this, entity.getBoundingBox()); @@ -17980,12 +17980,12 @@ index a213f4098859858a73ddd601bbe8c7511972e0d5..aeadc22e0df2d759252f5c73f9a79b75 - } - - return blockDensity; -+ return 0.0f; // Paper - region threading ++ return 0.0f; // Folia - region threading } static class CacheKey { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14d7f2bcd8 100644 +index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..54f50326beaef3985277ff941e40415a671f31fb 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -116,10 +116,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -17996,10 +17996,10 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - protected final NeighborUpdater neighborUpdater; - private final List pendingBlockEntityTickers = Lists.newArrayList(); - private boolean tickingBlockEntities; -+ //protected final List blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper // Paper - region threading ++ //protected final List blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper // Folia - region threading + public final int neighbourUpdateMax; //protected final NeighborUpdater neighborUpdater; -+ //private final List pendingBlockEntityTickers = Lists.newArrayList(); // Paper - region threading -+ //private boolean tickingBlockEntities; // Paper - region threading ++ //private final List pendingBlockEntityTickers = Lists.newArrayList(); // Folia - region threading ++ //private boolean tickingBlockEntities; // Folia - region threading public final Thread thread; private final boolean isDebug; private int skyDarken; @@ -18008,7 +18008,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 protected float oThunderLevel; public float thunderLevel; - public final RandomSource random = RandomSource.create(); -+ public final RandomSource random = new Entity.RandomRandomSource(); // Paper - region threading ++ public final RandomSource random = new Entity.RandomRandomSource(); // Folia - region threading /** @deprecated */ @Deprecated private final RandomSource threadSafeRandom = RandomSource.createThreadSafe(); @@ -18017,7 +18017,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 private final BiomeManager biomeManager; private final ResourceKey dimension; - private long subTickCount; -+ private final java.util.concurrent.atomic.AtomicLong subTickCount = new java.util.concurrent.atomic.AtomicLong(); //private long subTickCount; // Paper - region threading ++ private final java.util.concurrent.atomic.AtomicLong subTickCount = new java.util.concurrent.atomic.AtomicLong(); //private long subTickCount; // Folia - region threading // CraftBukkit start Added the following private final CraftWorld world; @@ -18031,7 +18031,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - public Map capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper - public Map capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - public List captureDrops; -+ // Paper - region threading - moved to regionised data ++ // Folia - region threading - moved to regionised data public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>(); - // Paper start - public int wakeupInactiveRemainingAnimals; @@ -18040,8 +18040,8 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - public int wakeupInactiveRemainingVillagers; - // Paper end - public boolean populating; -+ // Paper - region threading - moved to regionised data -+ // Paper - region threading ++ // Folia - region threading - moved to regionised data ++ // Folia - region threading public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot // Paper start private final io.papermc.paper.configuration.WorldConfiguration paperConfig; @@ -18052,9 +18052,9 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - private int tileTickPosition; - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions - public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here -+ //private int tileTickPosition; // Paper - region threading -+ //public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions // Paper - region threading -+ //public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here // Paper - region threading ++ //private int tileTickPosition; // Folia - region threading ++ //public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions // Folia - region threading ++ //public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here // Folia - region threading // Paper start - fix and optimise world upgrading // copied from below @@ -18063,7 +18063,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 double maxRangeSquared = maxRange * maxRange; - for (net.minecraft.server.level.ServerPlayer player : (List)this.players()) { -+ for (net.minecraft.server.level.ServerPlayer player : (List)this.getLocalPlayers()) { // Paper - region threading ++ for (net.minecraft.server.level.ServerPlayer player : (List)this.getLocalPlayers()) { // Folia - region threading if ((maxRange < 0.0 || player.distanceToSqr(sourceX, sourceY, sourceZ) < maxRangeSquared)) { if (predicate == null || predicate.test(player)) { ret.add(player); @@ -18072,7 +18072,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 double closestRangeSquared = maxRange < 0.0 ? Double.MAX_VALUE : maxRange * maxRange; - for (net.minecraft.server.level.ServerPlayer player : (List)this.players()) { -+ for (net.minecraft.server.level.ServerPlayer player : (List)this.getLocalPlayers()) { // Paper - region threading ++ for (net.minecraft.server.level.ServerPlayer player : (List)this.getLocalPlayers()) { // Folia - region threading double distanceSquared = player.distanceToSqr(sourceX, sourceY, sourceZ); if (distanceSquared < closestRangeSquared && (predicate == null || predicate.test(player))) { closest = player; @@ -18080,7 +18080,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 public abstract ResourceKey getTypeKey(); -+ // Paper start - region ticking ++ // Folia start - region ticking + public final io.papermc.paper.threadedregions.RegionisedData worldRegionData + = new io.papermc.paper.threadedregions.RegionisedData<>( + (ServerLevel)this, () -> new io.papermc.paper.threadedregions.RegionisedWorldData((ServerLevel)Level.this), @@ -18096,7 +18096,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 + public List getLocalPlayers() { + return this.getCurrentWorldData().getLocalPlayers(); + } -+ // Paper end - region ticking ++ // Folia end - region ticking + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot @@ -18106,7 +18106,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 this.biomeManager = new BiomeManager(this, i); this.isDebug = flag1; - this.neighborUpdater = new CollectingNeighborUpdater(this, j); -+ this.neighbourUpdateMax = j; // Paper - region threading ++ this.neighbourUpdateMax = j; // Folia - region threading // CraftBukkit start this.getWorldBorder().world = (ServerLevel) this; // From PlayerList.setPlayerFileData @@ -18116,8 +18116,8 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - tree generation - if (captureTreeGeneration) { - CraftBlockState previous = capturedBlockStates.get(blockposition); -+ if (this.getCurrentWorldData().captureTreeGeneration) { // Paper - region threading -+ CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(blockposition); // Paper - region threading ++ if (this.getCurrentWorldData().captureTreeGeneration) { // Folia - region threading ++ CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(blockposition); // Folia - region threading if (previous != null) { return previous.getHandle(); } @@ -18125,20 +18125,20 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = this.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = this.getCurrentWorldData(); // Folia - region threading // CraftBukkit start - tree generation - if (this.captureTreeGeneration) { -+ if (worldData.captureTreeGeneration) { // Paper - region threading ++ if (worldData.captureTreeGeneration) { // Folia - region threading // Paper start BlockState type = getBlockState(pos); if (!type.isDestroyable()) return false; // Paper end - CraftBlockState blockstate = this.capturedBlockStates.get(pos); -+ CraftBlockState blockstate = worldData.capturedBlockStates.get(pos); // Paper - region threading ++ CraftBlockState blockstate = worldData.capturedBlockStates.get(pos); // Folia - region threading if (blockstate == null) { blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags); - this.capturedBlockStates.put(pos.immutable(), blockstate); -+ worldData.capturedBlockStates.put(pos.immutable(), blockstate); // Paper - region threading ++ worldData.capturedBlockStates.put(pos.immutable(), blockstate); // Folia - region threading } blockstate.setData(state); return true; @@ -18147,11 +18147,11 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - capture blockstates boolean captured = false; - if (this.captureBlockStates && !this.capturedBlockStates.containsKey(pos)) { -+ if (worldData.captureBlockStates && !worldData.capturedBlockStates.containsKey(pos)) { // Paper - region threading ++ if (worldData.captureBlockStates && !worldData.capturedBlockStates.containsKey(pos)) { // Folia - region threading CraftBlockState blockstate = (CraftBlockState) world.getBlockAt(pos.getX(), pos.getY(), pos.getZ()).getState(); // Paper - use CB getState to get a suitable snapshot blockstate.setFlag(flags); // Paper - set flag - this.capturedBlockStates.put(pos.immutable(), blockstate); -+ worldData.capturedBlockStates.put(pos.immutable(), blockstate); // Paper - region threading ++ worldData.capturedBlockStates.put(pos.immutable(), blockstate); // Folia - region threading captured = true; } // CraftBukkit end @@ -18161,8 +18161,8 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - remove blockstate if failed (or the same) - if (this.captureBlockStates && captured) { - this.capturedBlockStates.remove(pos); -+ if (worldData.captureBlockStates && captured) { // Paper - region threading -+ worldData.capturedBlockStates.remove(pos); // Paper - region threading ++ if (worldData.captureBlockStates && captured) { // Folia - region threading ++ worldData.capturedBlockStates.remove(pos); // Folia - region threading } // CraftBukkit end return false; @@ -18171,7 +18171,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - if (!this.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates -+ if (!worldData.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates // Paper - region threading ++ if (!worldData.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates // Folia - region threading // Modularize client and physic updates // Spigot start try { @@ -18180,7 +18180,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam CraftWorld world = ((ServerLevel) this).getWorld(); - if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper -+ if (world != null && ((ServerLevel)this).getCurrentWorldData().hasPhysicsEvent) { // Paper // Paper - region threading ++ if (world != null && ((ServerLevel)this).getCurrentWorldData().hasPhysicsEvent) { // Paper // Folia - region threading BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); this.getCraftServer().getPluginManager().callEvent(event); @@ -18189,7 +18189,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - SPIGOT-5710 - if (!this.preventPoiUpdated) { -+ if (!this.getCurrentWorldData().preventPoiUpdated) { // Paper - region threading ++ if (!this.getCurrentWorldData().preventPoiUpdated) { // Folia - region threading this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); } // CraftBukkit end @@ -18198,7 +18198,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 @Override public void neighborShapeChanged(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) { - this.neighborUpdater.shapeUpdate(direction, neighborState, pos, neighborPos, flags, maxUpdateDepth); -+ this.getCurrentWorldData().neighborUpdater.shapeUpdate(direction, neighborState, pos, neighborPos, flags, maxUpdateDepth); // Paper - region threading ++ this.getCurrentWorldData().neighborUpdater.shapeUpdate(direction, neighborState, pos, neighborPos, flags, maxUpdateDepth); // Folia - region threading } @Override @@ -18206,7 +18206,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 return this.getChunkSource().getLightEngine(); } -+ // Paper start - region threading ++ // Folia start - region threading + @Nullable + public BlockState getBlockStateFromEmptyChunk(BlockPos pos) { + net.minecraft.server.level.ServerChunkCache chunkProvider = (net.minecraft.server.level.ServerChunkCache)this.getChunkSource(); @@ -18217,15 +18217,15 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 + chunk = chunkProvider.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.EMPTY, true); + return chunk.getBlockState(pos); + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override public BlockState getBlockState(BlockPos pos) { // CraftBukkit start - tree generation - if (this.captureTreeGeneration) { - CraftBlockState previous = this.capturedBlockStates.get(pos); // Paper -+ if (this.getCurrentWorldData().captureTreeGeneration) { // Paper - region threading -+ CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(pos); // Paper // Paper - region threading ++ if (this.getCurrentWorldData().captureTreeGeneration) { // Folia - region threading ++ CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(pos); // Paper // Folia - region threading if (previous != null) { return previous.getHandle(); } @@ -18234,7 +18234,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 public void addBlockEntityTicker(TickingBlockEntity ticker) { - (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(ticker); -+ ((ServerLevel)this).getCurrentWorldData().addBlockEntityTicker(ticker); // Paper - regionised ticking ++ ((ServerLevel)this).getCurrentWorldData().addBlockEntityTicker(ticker); // Folia - regionised ticking } protected void tickBlockEntities() { @@ -18247,10 +18247,10 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); - this.pendingBlockEntityTickers.clear(); - } -+ final io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = ((ServerLevel)this).getCurrentWorldData(); // Paper - regionised ticking -+ regionisedWorldData.seTtickingBlockEntities(true); // Paper - regionised ticking -+ regionisedWorldData.pushPendingTickingBlockEntities(); // Paper - regionised ticking -+ List blockEntityTickers = regionisedWorldData.getBlockEntityTickers(); // Paper - regionised ticking ++ final io.papermc.paper.threadedregions.RegionisedWorldData regionisedWorldData = ((ServerLevel)this).getCurrentWorldData(); // Folia - regionised ticking ++ regionisedWorldData.seTtickingBlockEntities(true); // Folia - regionised ticking ++ regionisedWorldData.pushPendingTickingBlockEntities(); // Folia - regionised ticking ++ List blockEntityTickers = regionisedWorldData.getBlockEntityTickers(); // Folia - regionised ticking timings.tileEntityPending.stopTiming(); // Spigot timings.tileEntityTick.startTiming(); // Spigot @@ -18261,8 +18261,8 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 - for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters - this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0; - TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(tileTickPosition); -+ for (int i = 0; i < blockEntityTickers.size(); i++) { // Paper - Disable tick limiters // Paper - regionised ticking -+ TickingBlockEntity tickingblockentity = (TickingBlockEntity) blockEntityTickers.get(i); // Paper - regionised ticking ++ for (int i = 0; i < blockEntityTickers.size(); i++) { // Paper - Disable tick limiters // Folia - regionised ticking ++ TickingBlockEntity tickingblockentity = (TickingBlockEntity) blockEntityTickers.get(i); // Folia - regionised ticking // Spigot start if (tickingblockentity == null) { this.getCraftServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); @@ -18271,23 +18271,23 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 tickingblockentity.tick(); // Paper start - execute chunk tasks during tick - if ((this.tileTickPosition & 7) == 0) { -+ if ((i & 7) == 0) { // Paper - regionised ticking ++ if ((i & 7) == 0) { // Folia - regionised ticking MinecraftServer.getServer().executeMidTickTasks(); } // Paper end - execute chunk tasks during tick } } - this.blockEntityTickers.removeAll(toRemove); -+ blockEntityTickers.removeAll(toRemove); // Paper - regionised ticking ++ blockEntityTickers.removeAll(toRemove); // Folia - regionised ticking timings.tileEntityTick.stopTiming(); // Spigot - this.tickingBlockEntities = false; - co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper -+ regionisedWorldData.seTtickingBlockEntities(false); // Paper - regionised ticking -+ //co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper // Paper - region threading ++ regionisedWorldData.seTtickingBlockEntities(false); // Folia - regionised ticking ++ //co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper // Folia - region threading gameprofilerfiller.pop(); - spigotConfig.currentPrimedTnt = 0; // Spigot -+ regionisedWorldData.currentPrimedTnt = 0; // Spigot // Paper - region threading ++ regionisedWorldData.currentPrimedTnt = 0; // Spigot // Folia - region threading } public void guardEntityTick(Consumer tickConsumer, T entity) { @@ -18296,7 +18296,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // Paper start - Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; - if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(blockposition)) != null) { -+ if (!this.getCurrentWorldData().capturedTileEntities.isEmpty() && (blockEntity = this.getCurrentWorldData().capturedTileEntities.get(blockposition)) != null) { // Paper - region threading ++ if (!this.getCurrentWorldData().capturedTileEntities.isEmpty() && (blockEntity = this.getCurrentWorldData().capturedTileEntities.get(blockposition)) != null) { // Folia - region threading return blockEntity; } // Paper end @@ -18306,8 +18306,8 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // CraftBukkit start - if (this.captureBlockStates) { - this.capturedTileEntities.put(blockposition.immutable(), blockEntity); -+ if (this.getCurrentWorldData().captureBlockStates) { // Paper - region threading -+ this.getCurrentWorldData().capturedTileEntities.put(blockposition.immutable(), blockEntity); // Paper - region threading ++ if (this.getCurrentWorldData().captureBlockStates) { // Folia - region threading ++ this.getCurrentWorldData().capturedTileEntities.put(blockposition.immutable(), blockEntity); // Folia - region threading return; } // CraftBukkit end @@ -18315,7 +18315,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 public void disconnect() {} -+ @Override // Paper - region threading ++ @Override // Folia - region threading public long getGameTime() { - return this.levelData.getGameTime(); + // Dumb world gen thread calls this for some reason. So, check for null. @@ -18330,7 +18330,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 + return worldData == null ? this.getLevelData().getDayTime() : worldData.getTickData().dayTime(); + } + -+ // Paper start - region threading ++ // Folia start - region threading + @Override + public long dayTime() { + return this.getDayTime(); @@ -18340,7 +18340,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 + public long getRedstoneGameTime() { + return this.getCurrentWorldData().getRedstoneGameTime(); } -+ // Paper end - region threading ++ // Folia end - region threading public boolean mayInteract(Player player, BlockPos pos) { return true; @@ -18350,7 +18350,7 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 // Paper end - this.randValue = this.randValue * 3 + 1013904223; - int i1 = this.randValue >> 2; -+ int i1 = this.random.nextInt() >> 2; // Paper - region threading ++ int i1 = this.random.nextInt() >> 2; // Folia - region threading out.set(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15)); // Paper - change to setValues call return out; // Paper @@ -18359,19 +18359,19 @@ index 60003ff929f7ac6b34f9230c53ccbd54dc9e176b..47871e3aaa54fad6f01ea31137a1fc14 @Override public long nextSubTickCount() { - return (long) (this.subTickCount++); -+ return this.subTickCount.getAndIncrement(); // Paper - region threading ++ return this.subTickCount.getAndIncrement(); // Folia - region threading } public static enum ExplosionInteraction { diff --git a/src/main/java/net/minecraft/world/level/LevelAccessor.java b/src/main/java/net/minecraft/world/level/LevelAccessor.java -index 73d1adc5ddf0363966eac0c77c8dfbbb20a2b6a3..0e2c93b55cf0c14b5f439d722c98fe9665da591f 100644 +index 73d1adc5ddf0363966eac0c77c8dfbbb20a2b6a3..375a2b57bcb29458443c1a4e2be3c0e5f4e6019c 100644 --- a/src/main/java/net/minecraft/world/level/LevelAccessor.java +++ b/src/main/java/net/minecraft/world/level/LevelAccessor.java @@ -35,12 +35,22 @@ public interface LevelAccessor extends CommonLevelAccessor, LevelTimeAccess { LevelTickAccess getBlockTicks(); -+ // Paper start - region threading ++ // Folia start - region threading + default long getGameTime() { + return this.getLevelData().getGameTime(); + } @@ -18379,35 +18379,35 @@ index 73d1adc5ddf0363966eac0c77c8dfbbb20a2b6a3..0e2c93b55cf0c14b5f439d722c98fe96 + default long getRedstoneGameTime() { + return this.getLevelData().getGameTime(); + } -+ // Paper end - region threading ++ // Folia end - region threading + default ScheduledTick createTick(BlockPos pos, T type, int delay, TickPriority priority) { // CraftBukkit - decompile error - return new ScheduledTick<>(type, pos, this.getLevelData().getGameTime() + (long) delay, priority, this.nextSubTickCount()); -+ return new ScheduledTick<>(type, pos, this.getRedstoneGameTime() + (long) delay, priority, this.nextSubTickCount()); // Paper - region threading ++ return new ScheduledTick<>(type, pos, this.getRedstoneGameTime() + (long) delay, priority, this.nextSubTickCount()); // Folia - region threading } default ScheduledTick createTick(BlockPos pos, T type, int delay) { // CraftBukkit - decompile error - return new ScheduledTick<>(type, pos, this.getLevelData().getGameTime() + (long) delay, this.nextSubTickCount()); -+ return new ScheduledTick<>(type, pos, this.getRedstoneGameTime() + (long) delay, this.nextSubTickCount()); // Paper - region threading ++ return new ScheduledTick<>(type, pos, this.getRedstoneGameTime() + (long) delay, this.nextSubTickCount()); // Folia - region threading } default void scheduleTick(BlockPos pos, Block block, int delay, TickPriority priority) { diff --git a/src/main/java/net/minecraft/world/level/LevelReader.java b/src/main/java/net/minecraft/world/level/LevelReader.java -index 7fe1b8856bf916796fa6d2a984f0a07a2331e23b..5bedb130094c4e510f2467fbdb5c393c0972043a 100644 +index 7fe1b8856bf916796fa6d2a984f0a07a2331e23b..07802d0a25e49519c3c9b33c217e05002cf05e31 100644 --- a/src/main/java/net/minecraft/world/level/LevelReader.java +++ b/src/main/java/net/minecraft/world/level/LevelReader.java @@ -135,6 +135,15 @@ public interface LevelReader extends BlockAndTintGetter, CollisionGetter, BiomeM return this.getChunk(chunkX, chunkZ, ChunkStatus.FULL, true); } -+ // Paper start - region threaeding ++ // Folia start - region threaeding + default ChunkAccess syncLoadNonFull(int chunkX, int chunkZ, ChunkStatus status) { + if (status == null || status.isOrAfter(ChunkStatus.FULL)) { + throw new IllegalArgumentException("Status: " + status.getName()); + } + return this.getChunk(chunkX, chunkZ, status, true); + } -+ // Paper end - region threaeding ++ // Folia end - region threaeding + default ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus status) { return this.getChunk(chunkX, chunkZ, status, true); @@ -18416,7 +18416,7 @@ index 7fe1b8856bf916796fa6d2a984f0a07a2331e23b..5bedb130094c4e510f2467fbdb5c393c return maxY >= this.getMinBuildHeight() && minY < this.getMaxBuildHeight() ? this.hasChunksAt(minX, minZ, maxX, maxZ) : false; } -+ // Paper start - region threading ++ // Folia start - region threading + default boolean hasAndOwnsChunksAt(int minX, int minZ, int maxX, int maxZ) { + int i = SectionPos.blockToSectionCoord(minX); + int j = SectionPos.blockToSectionCoord(maxX); @@ -18433,13 +18433,13 @@ index 7fe1b8856bf916796fa6d2a984f0a07a2331e23b..5bedb130094c4e510f2467fbdb5c393c + + return true; + } -+ // Paper end - region threading ++ // Folia end - region threading + /** @deprecated */ @Deprecated default boolean hasChunksAt(int minX, int minZ, int maxX, int maxZ) { diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 01b21f520ef1c834b9bafc3de85c1fa4fcf539d6..593a7a4a852a4f667d6847c1120c09d1fe0f926d 100644 +index 01b21f520ef1c834b9bafc3de85c1fa4fcf539d6..d4f220124ff812bd5e37a4c5acdc572538c609a0 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -146,7 +146,7 @@ public final class NaturalSpawner { @@ -18447,7 +18447,7 @@ index 01b21f520ef1c834b9bafc3de85c1fa4fcf539d6..593a7a4a852a4f667d6847c1120c09d1 SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumcreaturetype); if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { - spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % world.ticksPerSpawnCategory.getLong(spawnCategory) == 0; -+ spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && world.getRedstoneGameTime() % world.ticksPerSpawnCategory.getLong(spawnCategory) == 0; // Paper - region threading ++ spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && world.getRedstoneGameTime() % world.ticksPerSpawnCategory.getLong(spawnCategory) == 0; // Folia - region threading limit = world.getWorld().getSpawnLimit(spawnCategory); } @@ -18469,7 +18469,7 @@ index 01b21f520ef1c834b9bafc3de85c1fa4fcf539d6..593a7a4a852a4f667d6847c1120c09d1 - } - difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; - } -+ // Paper - region threading ++ // Folia - region threading if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && difference > 0) { // Paper end // CraftBukkit end @@ -18478,29 +18478,29 @@ index 01b21f520ef1c834b9bafc3de85c1fa4fcf539d6..593a7a4a852a4f667d6847c1120c09d1 // Paper start int spawnCount = NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn, - difference, world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); -+ difference, false && world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); // Paper - region threading ++ difference, false && world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); // Folia - region threading info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum); // Paper end } diff --git a/src/main/java/net/minecraft/world/level/ServerLevelAccessor.java b/src/main/java/net/minecraft/world/level/ServerLevelAccessor.java -index 3d377b9e461040405e0a7dcbd72d1506b48eb44e..ec0e143ace34c2b5990bb31ccf21dd494bdbd33d 100644 +index 3d377b9e461040405e0a7dcbd72d1506b48eb44e..782890e227ff9dab44dd92327979c201985f116e 100644 --- a/src/main/java/net/minecraft/world/level/ServerLevelAccessor.java +++ b/src/main/java/net/minecraft/world/level/ServerLevelAccessor.java @@ -7,6 +7,12 @@ public interface ServerLevelAccessor extends LevelAccessor { ServerLevel getLevel(); -+ // Paper start - region threading ++ // Folia start - region threading + default public StructureManager structureManager() { + throw new UnsupportedOperationException(); + } -+ // Paper end - region threading ++ // Folia end - region threading + default void addFreshEntityWithPassengers(Entity entity) { // CraftBukkit start this.addFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); diff --git a/src/main/java/net/minecraft/world/level/StructureManager.java b/src/main/java/net/minecraft/world/level/StructureManager.java -index bad7031426ae6c750ae4376beb238186e7d65270..bb2d87b19838e25d9f8b5120c4ec8b9ee0f96db1 100644 +index bad7031426ae6c750ae4376beb238186e7d65270..82c2389cfd42365632c6b05bbff2f2c7e4cb806b 100644 --- a/src/main/java/net/minecraft/world/level/StructureManager.java +++ b/src/main/java/net/minecraft/world/level/StructureManager.java @@ -44,11 +44,8 @@ public class StructureManager { @@ -18512,7 +18512,7 @@ index bad7031426ae6c750ae4376beb238186e7d65270..bb2d87b19838e25d9f8b5120c4ec8b9e - } - public List startsForStructure(ChunkPos pos, Predicate predicate, @Nullable ServerLevelAccessor levelAccessor) { - Map map = (levelAccessor == null ? this.level : levelAccessor).getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); -+ // Paper - region threading ++ // Folia - region threading + Map map = this.level.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Paper end ImmutableList.Builder builder = ImmutableList.builder(); @@ -18526,7 +18526,7 @@ index bad7031426ae6c750ae4376beb238186e7d65270..bb2d87b19838e25d9f8b5120c4ec8b9e - } - public StructureStart getStructureWithPieceAt(BlockPos pos, TagKey structureTag, @Nullable ServerLevelAccessor levelAccessor) { - // Paper end -+ // Paper - region threading ++ // Folia - region threading Registry registry = this.registryAccess().registryOrThrow(Registries.STRUCTURE); for(StructureStart structureStart : this.startsForStructure(new ChunkPos(pos), (structure) -> { @@ -18534,12 +18534,12 @@ index bad7031426ae6c750ae4376beb238186e7d65270..bb2d87b19838e25d9f8b5120c4ec8b9e return reference.is(structureTag); }).orElse(false); - }, levelAccessor)) { // Paper -+ })) { // Paper // Paper - region threading ++ })) { // Paper // Folia - region threading if (this.structureHasPieceAt(pos, structureStart)) { return structureStart; } diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java -index 7b71073027f4cf79736546500ededdfbb83d968e..49721b17af6c5f4fbdd9a2cdd1aab71ec8ced15b 100644 +index 7b71073027f4cf79736546500ededdfbb83d968e..6c6b7b94e875dce36619461e3994b148148e7f8a 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java @@ -398,8 +398,8 @@ public class Block extends BlockBehaviour implements ItemLike { @@ -18548,13 +18548,13 @@ index 7b71073027f4cf79736546500ededdfbb83d968e..49721b17af6c5f4fbdd9a2cdd1aab71e // CraftBukkit start - if (world.captureDrops != null) { - world.captureDrops.add(entityitem); -+ if (world.getCurrentWorldData().captureDrops != null) { // Paper - region threading -+ world.getCurrentWorldData().captureDrops.add(entityitem); // Paper - region threading ++ if (world.getCurrentWorldData().captureDrops != null) { // Folia - region threading ++ world.getCurrentWorldData().captureDrops.add(entityitem); // Folia - region threading } else { world.addFreshEntity(entityitem); } diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java -index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..d43e111d63ac3432e51a5f31ae3eb66246893156 100644 +index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..d2e3e1d20d60f5edd0d93709b808f812c31e7491 100644 --- a/src/main/java/net/minecraft/world/level/block/BushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java @@ -24,7 +24,7 @@ public class BushBlock extends Block { @@ -18562,12 +18562,12 @@ index 03fde6e47c4a347c62fe9b4a3351769aedf874f6..d43e111d63ac3432e51a5f31ae3eb662 // CraftBukkit start if (!state.canSurvive(world, pos)) { - if (!(world instanceof net.minecraft.server.level.ServerLevel && ((net.minecraft.server.level.ServerLevel) world).hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper -+ if (!(world instanceof net.minecraft.server.level.ServerLevel && ((net.minecraft.server.level.ServerLevel) world).getCurrentWorldData().hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Paper - region threading ++ if (!(world instanceof net.minecraft.server.level.ServerLevel && ((net.minecraft.server.level.ServerLevel) world).getCurrentWorldData().hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Folia - region threading return Blocks.AIR.defaultBlockState(); } } diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index 1ec242205b82a5a1f10deb2312795cc5dc157a76..e1d17e63c5ba43a69d48748a66275de3498a18a3 100644 +index 1ec242205b82a5a1f10deb2312795cc5dc157a76..ae08011006851493ad315f2490a4374877b2a02d 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java @@ -118,9 +118,9 @@ public class CactusBlock extends Block { @@ -18575,15 +18575,15 @@ index 1ec242205b82a5a1f10deb2312795cc5dc157a76..e1d17e63c5ba43a69d48748a66275de3 public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - CraftEventFactory.blockDamage = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); // CraftBukkit // Folia - region threading entity.hurt(DamageSource.CACTUS, 1.0F); - CraftEventFactory.blockDamage = null; // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Folia - region threading } @Override diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index a4c44cb59dee29cf227dbb51bfc1576d89dfb2e3..8683451bcd1ef207663c187a02304e6b0e97f274 100644 +index a4c44cb59dee29cf227dbb51bfc1576d89dfb2e3..3d3f85e10c56dc95a0b6e576bd4b8d33a9daa8a3 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java @@ -95,9 +95,9 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB @@ -18591,15 +18591,15 @@ index a4c44cb59dee29cf227dbb51bfc1576d89dfb2e3..8683451bcd1ef207663c187a02304e6b if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper if ((Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { - org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = CraftBlock.at(world, pos); // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Folia - region threading entity.hurt(DamageSource.IN_FIRE, (float) this.fireDamage); - org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Folia - region threading } super.entityInside(state, world, pos, entity); diff --git a/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java b/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java -index 16504b8be08064e61b013fa943f692816612cbd0..23f340c8b8f1d00b183bdacabf0bde3124886fda 100644 +index 16504b8be08064e61b013fa943f692816612cbd0..076c6209725bac9268c19c7bfec7b5a94f2ea9a1 100644 --- a/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DaylightDetectorBlock.java @@ -113,7 +113,7 @@ public class DaylightDetectorBlock extends BaseEntityBlock { @@ -18607,12 +18607,12 @@ index 16504b8be08064e61b013fa943f692816612cbd0..23f340c8b8f1d00b183bdacabf0bde31 private static void tickEntity(Level world, BlockPos pos, BlockState state, DaylightDetectorBlockEntity blockEntity) { - if (world.getGameTime() % 20L == 0L) { -+ if (world.getRedstoneGameTime() % 20L == 0L) { // Paper - region threading ++ if (world.getRedstoneGameTime() % 20L == 0L) { // Folia - region threading DaylightDetectorBlock.updateSignalStrength(state, world, pos); } diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -index 8f55d0753fa26924235c943595f0d1a06a933a6f..970ec44a19163bf2c22567c29dc4a7e456d8a202 100644 +index 8f55d0753fa26924235c943595f0d1a06a933a6f..a195d37847e3278d7721641b5db858913c0afe46 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java @@ -47,7 +47,7 @@ public class DispenserBlock extends BaseEntityBlock { @@ -18620,7 +18620,7 @@ index 8f55d0753fa26924235c943595f0d1a06a933a6f..970ec44a19163bf2c22567c29dc4a7e4 }); private static final int TRIGGER_DURATION = 4; - public static boolean eventFired = false; // CraftBukkit -+ public static ThreadLocal eventFired = ThreadLocal.withInitial(() -> Boolean.FALSE); // CraftBukkit // Paper - region threading ++ public static ThreadLocal eventFired = ThreadLocal.withInitial(() -> Boolean.FALSE); // CraftBukkit // Folia - region threading public static void registerBehavior(ItemLike provider, DispenseItemBehavior behavior) { DispenserBlock.DISPENSER_REGISTRY.put(provider.asItem(), behavior); @@ -18629,12 +18629,12 @@ index 8f55d0753fa26924235c943595f0d1a06a933a6f..970ec44a19163bf2c22567c29dc4a7e4 if (idispensebehavior != DispenseItemBehavior.NOOP) { if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(world, pos, itemstack, i)) return; // Paper - BlockPreDispenseEvent is called here - DispenserBlock.eventFired = false; // CraftBukkit - reset event status -+ DispenserBlock.eventFired.set(false); // CraftBukkit - reset event status // Paper - region threading ++ DispenserBlock.eventFired.set(false); // CraftBukkit - reset event status // Folia - region threading tileentitydispenser.setItem(i, idispensebehavior.dispense(sourceblock, itemstack)); } diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index e234ae13fe9793db237adb6f6216fa32638cfc4f..6d0ed8e7003c402c246ca6834721ac7e4623a3ae 100644 +index e234ae13fe9793db237adb6f6216fa32638cfc4f..9447bc16dcd7ecfa941081197d5e4c34f78c79d4 100644 --- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java @@ -95,7 +95,7 @@ public class DoublePlantBlock extends BushBlock { @@ -18642,12 +18642,12 @@ index e234ae13fe9793db237adb6f6216fa32638cfc4f..6d0ed8e7003c402c246ca6834721ac7e protected static void preventCreativeDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { // CraftBukkit start - if (((net.minecraft.server.level.ServerLevel)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper -+ if (((net.minecraft.server.level.ServerLevel)world).getCurrentWorldData().hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Paper - region threading ++ if (((net.minecraft.server.level.ServerLevel)world).getCurrentWorldData().hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Folia - region threading return; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java -index 683f24251baf8ef3bef8f32ba83dc7f0e8ed7d70..f138f30c3e6588708811cd0d511fc66c9a334ed9 100644 +index 683f24251baf8ef3bef8f32ba83dc7f0e8ed7d70..b0352a9f05ad1ec49314d505dc99ed7b29ed09c3 100644 --- a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java +++ b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java @@ -81,7 +81,7 @@ public class HoneyBlock extends HalfTransparentBlock { @@ -18655,12 +18655,12 @@ index 683f24251baf8ef3bef8f32ba83dc7f0e8ed7d70..f138f30c3e6588708811cd0d511fc66c private void maybeDoSlideAchievement(Entity entity, BlockPos pos) { - if (entity instanceof ServerPlayer && entity.level.getGameTime() % 20L == 0L) { -+ if (entity instanceof ServerPlayer && entity.level.getRedstoneGameTime() % 20L == 0L) { // Paper - region threading ++ if (entity instanceof ServerPlayer && entity.level.getRedstoneGameTime() % 20L == 0L) { // Folia - region threading CriteriaTriggers.HONEY_BLOCK_SLIDE.trigger((ServerPlayer)entity, entity.level.getBlockState(pos)); } diff --git a/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java b/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java -index da3b301a42a93c891d083a6e02d1be8ed35adf1d..4bd815ba372809fb2a4b70bf04ac836750f25609 100644 +index da3b301a42a93c891d083a6e02d1be8ed35adf1d..f354981843868bf938be0b5ac1ef2ce39fb067ef 100644 --- a/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LightningRodBlock.java @@ -112,7 +112,7 @@ public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBloc @@ -18668,12 +18668,12 @@ index da3b301a42a93c891d083a6e02d1be8ed35adf1d..4bd815ba372809fb2a4b70bf04ac8367 @Override public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { - if (world.isThundering() && (long) world.random.nextInt(200) <= world.getGameTime() % 200L && pos.getY() == world.getHeight(Heightmap.Types.WORLD_SURFACE, pos.getX(), pos.getZ()) - 1) { -+ if (world.isThundering() && (long) world.random.nextInt(200) <= world.getRedstoneGameTime() % 200L && pos.getY() == world.getHeight(Heightmap.Types.WORLD_SURFACE, pos.getX(), pos.getZ()) - 1) { // Paper - region threading ++ if (world.isThundering() && (long) world.random.nextInt(200) <= world.getRedstoneGameTime() % 200L && pos.getY() == world.getHeight(Heightmap.Types.WORLD_SURFACE, pos.getX(), pos.getZ()) - 1) { // Folia - region threading ParticleUtils.spawnParticlesAlongAxis(((Direction) state.getValue(LightningRodBlock.FACING)).getAxis(), world, pos, 0.125D, ParticleTypes.ELECTRIC_SPARK, UniformInt.of(1, 2)); } } diff --git a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -index d3540a4daaa8021ae009bfd4d9ef4f1172ab4c56..70d046e0fe0de64691195bd5fde36b3eb1f5e968 100644 +index d3540a4daaa8021ae009bfd4d9ef4f1172ab4c56..336a4797d114ccfad319086c68e3546bdf3f6fe1 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java @@ -29,9 +29,9 @@ public class MagmaBlock extends Block { @@ -18681,15 +18681,15 @@ index d3540a4daaa8021ae009bfd4d9ef4f1172ab4c56..70d046e0fe0de64691195bd5fde36b3e public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { if (!entity.isSteppingCarefully() && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { - org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); // CraftBukkit // Folia - region threading entity.hurt(DamageSource.HOT_FLOOR, 1.0F); - org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Folia - region threading } super.stepOn(world, pos, state, entity); diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index e78fdd317d59cfca6a28deb6e0bd02aabe91e930..9c61ef8643ddfef3aeae0df597e309b94daff4b9 100644 +index e78fdd317d59cfca6a28deb6e0bd02aabe91e930..c2cb07426d22ff0c14dfa24cc2ead785eaaf1903 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java @@ -143,9 +143,9 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @@ -18697,15 +18697,15 @@ index e78fdd317d59cfca6a28deb6e0bd02aabe91e930..9c61ef8643ddfef3aeae0df597e309b9 public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { if (state.getValue(PointedDripstoneBlock.TIP_DIRECTION) == Direction.UP && state.getValue(PointedDripstoneBlock.THICKNESS) == DripstoneThickness.TIP) { - CraftEventFactory.blockDamage = CraftBlock.at(world, pos); // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Folia - region threading entity.causeFallDamage(fallDistance + 2.0F, 2.0F, DamageSource.STALAGMITE); - CraftEventFactory.blockDamage = null; // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Folia - region threading } else { super.fallOn(world, state, pos, entity, fallDistance); } diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a08b9b86c 100644 +index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..1c23d52b77fea5f9817b482e2904083237ee58c4 100644 --- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java @@ -262,7 +262,7 @@ public class RedStoneWireBlock extends Block { @@ -18713,7 +18713,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a */ private void updateSurroundingRedstone(Level worldIn, BlockPos pos, BlockState state, BlockPos source) { - if (worldIn.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.EIGENCRAFT) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.EIGENCRAFT) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.EIGENCRAFT) { // Folia - region threading turbo.updateSurroundingRedstone(worldIn, pos, state, source); return; } @@ -18722,7 +18722,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a this.shouldSignal = true; - if (worldIn.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { // Folia - region threading // This code is totally redundant to if statements just below the loop. if (k > 0 && k > j - 1) { j = k; @@ -18731,7 +18731,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a // following loop can affect the power level of the wire. Therefore, the loop is // skipped if k is already 15. - if (worldIn.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA || k < 15) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA || k < 15) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA || k < 15) { // Folia - region threading for (Direction enumfacing : Direction.Plane.HORIZONTAL) { BlockPos blockpos = pos1.relative(enumfacing); boolean flag = blockpos.getX() != pos2.getX() || blockpos.getZ() != pos2.getZ(); @@ -18740,7 +18740,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a } - if (worldIn.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA) { // Folia - region threading // The old code would decrement the wire value only by 1 at a time. if (l > j) { j = l - 1; @@ -18749,7 +18749,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a if (!oldState.is(state.getBlock()) && !world.isClientSide) { // Paper start - optimize redstone - replace call to updatePowerStrength - if (world.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Folia - region threading world.getWireHandler().onWireAdded(pos); // Alternate Current } else { this.updateSurroundingRedstone(world, pos, state, null); // vanilla/Eigencraft @@ -18758,7 +18758,7 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a // Paper start - optimize redstone - replace call to updatePowerStrength - if (world.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Folia - region threading world.getWireHandler().onWireRemoved(pos, state); // Alternate Current } else { this.updateSurroundingRedstone(world, pos, state, null); // vanilla/Eigencraft @@ -18767,12 +18767,12 @@ index 5ea09cc455bd86beb450f0e0275d7c6c8da98084..551666836298d98b062a46afee24755a // Paper start - optimize redstone (Alternate Current) // Alternate Current handles breaking of redstone wires in the WireHandler. - if (world.paperConfig().misc.redstoneImplementation == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { -+ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Paper - region threading ++ if (io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.VANILLA == io.papermc.paper.configuration.WorldConfiguration.Misc.RedstoneImplementation.ALTERNATE_CURRENT) { // Folia - region threading world.getWireHandler().onWireUpdated(pos); } else // Paper end diff --git a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -index da07fce0cf7c9fbdb57d2c59e431b59bf583bf50..d31ab3f657369688ddd593ad04ed9cb705319b0e 100644 +index da07fce0cf7c9fbdb57d2c59e431b59bf583bf50..16e46bb6205c3f7444e864c553e8072f0519746d 100644 --- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java +++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java @@ -73,10 +73,10 @@ public class RedstoneTorchBlock extends TorchBlock { @@ -18780,11 +18780,11 @@ index da07fce0cf7c9fbdb57d2c59e431b59bf583bf50..d31ab3f657369688ddd593ad04ed9cb7 boolean flag = this.hasNeighborSignal(world, pos, state); // Paper start - java.util.ArrayDeque redstoneUpdateInfos = world.redstoneUpdateInfos; -+ java.util.ArrayDeque redstoneUpdateInfos = world.getCurrentWorldData().redstoneUpdateInfos; // Paper - region threading ++ java.util.ArrayDeque redstoneUpdateInfos = world.getCurrentWorldData().redstoneUpdateInfos; // Folia - region threading if (redstoneUpdateInfos != null) { RedstoneTorchBlock.Toggle curr; - while ((curr = redstoneUpdateInfos.peek()) != null && world.getGameTime() - curr.when > 60L) { -+ while ((curr = redstoneUpdateInfos.peek()) != null && world.getRedstoneGameTime() - curr.when > 60L) { // Paper - region threading ++ while ((curr = redstoneUpdateInfos.peek()) != null && world.getRedstoneGameTime() - curr.when > 60L) { // Folia - region threading redstoneUpdateInfos.poll(); } } @@ -18793,16 +18793,16 @@ index da07fce0cf7c9fbdb57d2c59e431b59bf583bf50..d31ab3f657369688ddd593ad04ed9cb7 private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) { // Paper start - java.util.ArrayDeque list = world.redstoneUpdateInfos; -+ java.util.ArrayDeque list = world.getCurrentWorldData().redstoneUpdateInfos; // Paper - region threading ++ java.util.ArrayDeque list = world.getCurrentWorldData().redstoneUpdateInfos; // Folia - region threading if (list == null) { - list = world.redstoneUpdateInfos = new java.util.ArrayDeque<>(); -+ list = world.getCurrentWorldData().redstoneUpdateInfos = new java.util.ArrayDeque<>(); // Paper - region threading ++ list = world.getCurrentWorldData().redstoneUpdateInfos = new java.util.ArrayDeque<>(); // Folia - region threading } if (addNew) { - list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), world.getGameTime())); -+ list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), world.getRedstoneGameTime())); // Paper - region threading ++ list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), world.getRedstoneGameTime())); // Folia - region threading } int i = 0; @@ -18812,23 +18812,23 @@ index da07fce0cf7c9fbdb57d2c59e431b59bf583bf50..d31ab3f657369688ddd593ad04ed9cb7 - final BlockPos pos; - final long when; -+ public final BlockPos pos; // Paper - region threading -+ long when; // Paper - region ticking ++ public final BlockPos pos; // Folia - region threading ++ long when; // Folia - region ticking public Toggle(BlockPos pos, long time) { this.pos = pos; this.when = time; } + -+ // Paper start - region ticking ++ // Folia start - region ticking + public void offsetTime(long offset) { + this.when += offset; + } -+ // Paper end - region ticking ++ // Folia end - region ticking } } diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java -index 901978a338f0f1b6f20ffb65aac59704bfa6f36a..63b09042a603abb9c8adf651061ebf972725c6dd 100644 +index 901978a338f0f1b6f20ffb65aac59704bfa6f36a..01d8895fc04830d6f691852aaadf21d3ede75808 100644 --- a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java @@ -52,18 +52,19 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { @@ -18836,29 +18836,29 @@ index 901978a338f0f1b6f20ffb65aac59704bfa6f36a..63b09042a603abb9c8adf651061ebf97 } else { // CraftBukkit start - if (world.captureTreeGeneration) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ if (worldData.captureTreeGeneration) { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ if (worldData.captureTreeGeneration) { // Folia - region threading this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); } else { - world.captureTreeGeneration = true; -+ worldData.captureTreeGeneration = true; // Paper - region threading ++ worldData.captureTreeGeneration = true; // Folia - region threading this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); - world.captureTreeGeneration = false; - if (world.capturedBlockStates.size() > 0) { -+ worldData.captureTreeGeneration = false; // Paper - region threading -+ if (worldData.capturedBlockStates.size() > 0) { // Paper - region threading ++ worldData.captureTreeGeneration = false; // Folia - region threading ++ if (worldData.capturedBlockStates.size() > 0) { // Folia - region threading TreeType treeType = SaplingBlock.treeType; SaplingBlock.treeType = null; Location location = new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); - java.util.List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); - world.capturedBlockStates.clear(); -+ java.util.List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ java.util.List blocks = new java.util.ArrayList<>(worldData.capturedBlockStates.values()); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading StructureGrowEvent event = null; if (treeType != null) { event = new StructureGrowEvent(location, treeType, false, null, blocks); diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -index af46c05a34292d271fd4a809398e6b299e10b12b..420a4cef902edf25cf4722b195be43d29c5a6d92 100644 +index af46c05a34292d271fd4a809398e6b299e10b12b..49a8d37b9c77dbc869c03e9f495efeeef606fa4a 100644 --- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java @@ -51,7 +51,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock { @@ -18866,12 +18866,12 @@ index af46c05a34292d271fd4a809398e6b299e10b12b..420a4cef902edf25cf4722b195be43d2 @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper -+ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper // Paper - regionised ticking ++ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper // Folia - regionised ticking // Paper start net.minecraft.world.level.chunk.ChunkAccess cachedBlockChunk = world.getChunkIfLoaded(pos); if (cachedBlockChunk == null) { // Is this needed? diff --git a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -index c926cd3ebb916115a608e86b389ffe7e15d48cd7..9985714f2ee95e57256eeef7d7fb6a54aa331c98 100644 +index c926cd3ebb916115a608e86b389ffe7e15d48cd7..5375f79c6d5e05f4202a6363eaf50e6e6548a789 100644 --- a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java @@ -86,9 +86,9 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock @@ -18879,15 +18879,15 @@ index c926cd3ebb916115a608e86b389ffe7e15d48cd7..9985714f2ee95e57256eeef7d7fb6a54 if (d0 >= 0.003000000026077032D || d1 >= 0.003000000026077032D) { - CraftEventFactory.blockDamage = CraftBlock.at(world, pos); // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // CraftBukkit // Folia - region threading entity.hurt(DamageSource.SWEET_BERRY_BUSH, 1.0F); - CraftEventFactory.blockDamage = null; // CraftBukkit -+ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // CraftBukkit // Folia - region threading } } diff --git a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java -index b91effe91dad2e1aeea0ea31140f7432833b343f..e41ad437d61e04bfe6430911a0d85afca4375bc5 100644 +index b91effe91dad2e1aeea0ea31140f7432833b343f..46979b4ee8c24b499577aa64167c759664148240 100644 --- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java +++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java @@ -53,7 +53,7 @@ public class WitherSkullBlock extends SkullBlock { @@ -18895,12 +18895,12 @@ index b91effe91dad2e1aeea0ea31140f7432833b343f..e41ad437d61e04bfe6430911a0d85afc public static void checkSpawn(Level world, BlockPos pos, SkullBlockEntity blockEntity) { - if (world.captureBlockStates) return; // CraftBukkit -+ if (world.getCurrentWorldData().captureBlockStates) return; // CraftBukkit // Paper - region threading ++ if (world.getCurrentWorldData().captureBlockStates) return; // CraftBukkit // Folia - region threading if (!world.isClientSide) { BlockState iblockdata = blockEntity.getBlockState(); boolean flag = iblockdata.is(Blocks.WITHER_SKELETON_SKULL) || iblockdata.is(Blocks.WITHER_SKELETON_WALL_SKULL); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index 928625b5ab054ffa412be8a438f58291cc7a3cc0..5560e0a83662872627fdad78d96a9c7a2b51de75 100644 +index 928625b5ab054ffa412be8a438f58291cc7a3cc0..bbc051be1c3a2697e33cc316e328760b838af243 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -202,7 +202,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name @@ -18908,19 +18908,19 @@ index 928625b5ab054ffa412be8a438f58291cc7a3cc0..5560e0a83662872627fdad78d96a9c7a i1 = blockEntity.levels; - if (world.getGameTime() % 80L == 0L) { -+ if (world.getRedstoneGameTime() % 80L == 0L) { // Paper - region threading ++ if (world.getRedstoneGameTime() % 80L == 0L) { // Folia - region threading if (!blockEntity.beamSections.isEmpty()) { blockEntity.levels = BeaconBlockEntity.updateBase(world, i, j, k); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java -index 648d8f3e72e30aacf68eb073a1ac30f8ec29503c..b15ba5dd5e27c53652f965893344d48df395ddb8 100644 +index 648d8f3e72e30aacf68eb073a1ac30f8ec29503c..9f20efa5c89d1ab6741c9f349b868126d8df8a21 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java @@ -36,6 +36,18 @@ public class BellBlockEntity extends BlockEntity { private boolean resonating; private int resonationTicks; -+ // Paper start - region ticking ++ // Folia start - region ticking + + @Override + public void updateTicks(long fromTickOffset, long fromGameTimeOffset) { @@ -18930,30 +18930,30 @@ index 648d8f3e72e30aacf68eb073a1ac30f8ec29503c..b15ba5dd5e27c53652f965893344d48d + } + } + -+ // Paper end - region ticking ++ // Folia end - region ticking + public BellBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.BELL, pos, state); } diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 58986bc0677c5ea1ad54d7d6d4efa5c2ea233aea..49f83e421642a00ed5025c851ac73261cfd971f4 100644 +index 58986bc0677c5ea1ad54d7d6d4efa5c2ea233aea..db3c174afe8f9ddce6f410e5c692d7de2289d4ea 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java @@ -42,6 +42,12 @@ public abstract class BlockEntity { protected boolean remove; private BlockState blockState; -+ // Paper start - region ticking ++ // Folia start - region ticking + public void updateTicks(final long fromTickOffset, final long fromGameTimeOffset) { + + } -+ // Paper end - region ticking ++ // Folia end - region ticking + public BlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { this.type = type; this.worldPosition = pos.immutable(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index 55006724ccec9f3de828ec18693728e9741ff65f..751b1d8f67821dc07be8228cdd65f065769eed01 100644 +index 55006724ccec9f3de828ec18693728e9741ff65f..9e806ba83240916d422c4a736a9cfd61e73108e4 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java @@ -54,7 +54,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements @@ -18961,7 +18961,7 @@ index 55006724ccec9f3de828ec18693728e9741ff65f..751b1d8f67821dc07be8228cdd65f065 protected final ContainerData dataAccess; // CraftBukkit start - add fields and methods - private int lastTick = MinecraftServer.currentTick; -+ //private int lastTick = MinecraftServer.currentTick; // Paper - region ticking - restore original timers ++ //private int lastTick = MinecraftServer.currentTick; // Folia - region ticking - restore original timers public List transaction = new java.util.ArrayList(); private int maxStack = 64; @@ -18971,23 +18971,23 @@ index 55006724ccec9f3de828ec18693728e9741ff65f..751b1d8f67821dc07be8228cdd65f065 // CraftBukkit start - Use wall time instead of ticks for brewing - int elapsedTicks = MinecraftServer.currentTick - blockEntity.lastTick; - blockEntity.lastTick = MinecraftServer.currentTick; -+ // Paper - region ticking - restore original timers ++ // Folia - region ticking - restore original timers if (flag1) { - blockEntity.brewTime -= elapsedTicks; -+ --blockEntity.brewTime; // Paper - region ticking - restore original timers ++ --blockEntity.brewTime; // Folia - region ticking - restore original timers boolean flag2 = blockEntity.brewTime <= 0; // == -> <= // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..97f20df314d4f8e956a53c767c52ae6abd41e645 100644 +index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..79e586c4d7a7392721f440e57f86c11de7369151 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java @@ -52,6 +52,16 @@ public class ConduitBlockEntity extends BlockEntity { private UUID destroyTargetUUID; private long nextAmbientSoundActivation; -+ // Paper start - region ticking ++ // Folia start - region ticking + @Override + public void updateTicks(long fromTickOffset, long fromGameTimeOffset) { + super.updateTicks(fromTickOffset, fromGameTimeOffset); @@ -18995,7 +18995,7 @@ index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..97f20df314d4f8e956a53c767c52ae6a + this.nextAmbientSoundActivation += fromGameTimeOffset; + } + } -+ // Paper end - region ticking ++ // Folia end - region ticking + public ConduitBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.CONDUIT, pos, state); @@ -19005,7 +19005,7 @@ index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..97f20df314d4f8e956a53c767c52ae6a public static void clientTick(Level world, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity) { ++blockEntity.tickCount; - long i = world.getGameTime(); -+ long i = world.getRedstoneGameTime(); // Paper - region threading ++ long i = world.getRedstoneGameTime(); // Folia - region threading List list = blockEntity.effectBlocks; if (i % 40L == 0L) { @@ -19014,7 +19014,7 @@ index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..97f20df314d4f8e956a53c767c52ae6a public static void serverTick(Level world, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity) { ++blockEntity.tickCount; - long i = world.getGameTime(); -+ long i = world.getRedstoneGameTime(); // Paper - region threading ++ long i = world.getRedstoneGameTime(); // Folia - region threading List list = blockEntity.effectBlocks; if (i % 40L == 0L) { @@ -19023,24 +19023,24 @@ index 05eab04e4aec4151018f25b59f92ddbbb4c09f87..97f20df314d4f8e956a53c767c52ae6a if (blockEntity.destroyTarget != null) { // CraftBukkit start - CraftEventFactory.blockDamage = CraftBlock.at(world, pos); -+ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(CraftBlock.at(world, pos)); // Folia - region threading if (blockEntity.destroyTarget.hurt(DamageSource.MAGIC, 4.0F)) { world.playSound((Player) null, blockEntity.destroyTarget.getX(), blockEntity.destroyTarget.getY(), blockEntity.destroyTarget.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F); } - CraftEventFactory.blockDamage = null; -+ CraftEventFactory.blockDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // Folia - region threading // CraftBukkit end } diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index ccad692aba2ed77259f6814d88f01b91ed9d229b..1e2b1658d2eee5a44bdde736a3449567daf53171 100644 +index ccad692aba2ed77259f6814d88f01b91ed9d229b..e687aa729619c8639bc30a6bdf0a5a1513a7ee04 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -77,6 +77,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } // CraftBukkit end -+ // Paper start - region ticking ++ // Folia start - region ticking + @Override + public void updateTicks(long fromTickOffset, long fromGameTimeOffset) { + super.updateTicks(fromTickOffset, fromGameTimeOffset); @@ -19048,13 +19048,13 @@ index ccad692aba2ed77259f6814d88f01b91ed9d229b..1e2b1658d2eee5a44bdde736a3449567 + this.tickedGameTime += fromGameTimeOffset; + } + } -+ // Paper end - region ticking ++ // Folia end - region ticking + public HopperBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.HOPPER, pos, state); this.items = NonNullList.withSize(5, ItemStack.EMPTY); diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -index 163e63e3c538c7c1c75ed634896db9d8c00416f3..766034bf1f5c10106ed728fc3b8164e3ea2f38b7 100644 +index 163e63e3c538c7c1c75ed634896db9d8c00416f3..740cb2858a3f78298895a463fb0fac9e88a9a4a0 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java @@ -86,9 +86,9 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi @@ -19062,15 +19062,15 @@ index 163e63e3c538c7c1c75ed634896db9d8c00416f3..766034bf1f5c10106ed728fc3b8164e3 public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) { - org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. -+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(blockEntity.getBlockPos()); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(blockEntity.getBlockPos()); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. // Folia - region threading blockEntity.sculkSpreader.updateCursors(world, pos, world.getRandom(), true); - org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = null; // CraftBukkit -+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(null); // CraftBukkit // Paper - region threading ++ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverrideRT.set(null); // CraftBukkit // Folia - region threading } @Override diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae722d6039 100644 +index f80545f80948db27d1fbde77d0505c916eb504ed..3b656e7d5e8b75f8f415d5f43ed5c91da963731b 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -51,9 +51,12 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -19078,11 +19078,11 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae private int teleportCooldown; @Nullable - public BlockPos exitPortal; -+ public volatile BlockPos exitPortal; // Paper - region threading - volatile ++ public volatile BlockPos exitPortal; // Folia - region threading - volatile public boolean exactTeleport; -+ private static final java.util.concurrent.atomic.AtomicLong SEARCHING_FOR_EXIT_ID_GENERATOR = new java.util.concurrent.atomic.AtomicLong(); // Paper - region threading -+ private Long searchingForExitId; // Paper - region threading ++ private static final java.util.concurrent.atomic.AtomicLong SEARCHING_FOR_EXIT_ID_GENERATOR = new java.util.concurrent.atomic.AtomicLong(); // Folia - region threading ++ private Long searchingForExitId; // Folia - region threading + public TheEndGatewayBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.END_GATEWAY, pos, state); @@ -19092,7 +19092,7 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae public static boolean canEntityTeleport(Entity entity) { - return EntitySelector.NO_SPECTATORS.test(entity) && !entity.getRootVehicle().isOnPortalCooldown(); -+ return EntitySelector.NO_SPECTATORS.test(entity) && !entity.getRootVehicle().isOnPortalCooldown() && entity.canPortalAsync(true); // Paper - region threading - correct portal check ++ return EntitySelector.NO_SPECTATORS.test(entity) && !entity.getRootVehicle().isOnPortalCooldown() && entity.canPortalAsync(true); // Folia - region threading - correct portal check } public boolean isSpawning() { @@ -19100,7 +19100,7 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae } } -+ // Paper start - region threading ++ // Folia start - region threading + private void trySearchForExit(ServerLevel world, BlockPos fromPos) { + if (this.searchingForExitId != null) { + return; @@ -19196,16 +19196,16 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae + ); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + public static void teleportEntity(Level world, BlockPos pos, BlockState state, Entity entity, TheEndGatewayBlockEntity blockEntity) { if (world instanceof ServerLevel && !blockEntity.isCoolingDown()) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + teleportRegionThreading(world, pos, state, entity.getRootVehicle(), blockEntity); + return; + } -+ // Paper end - region threading ++ // Folia end - region threading ServerLevel worldserver = (ServerLevel) world; blockEntity.teleportCooldown = 100; @@ -19213,7 +19213,7 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae return TheEndGatewayBlockEntity.findTallestBlock(world, blockposition1, 16, true); } -+ // Paper start - region threading ++ // Folia start - region threading + private static void findOrCreateValidTeleportPosRegionThreading(ServerLevel world, BlockPos pos, + ca.spottedleaf.concurrentutil.completable.Completable complete) { + ca.spottedleaf.concurrentutil.completable.Completable tentativeSelection = new ca.spottedleaf.concurrentutil.completable.Completable<>(); @@ -19330,20 +19330,20 @@ index f80545f80948db27d1fbde77d0505c916eb504ed..3ed3a9c1c441e1ae400ca4d852f36bae + } + ); + } -+ // Paper end - region threading ++ // Folia end - region threading + private static Vec3 findExitPortalXZPosTentative(ServerLevel world, BlockPos pos) { Vec3 vec3d = (new Vec3((double) pos.getX(), 0.0D, (double) pos.getZ())).normalize(); boolean flag = true; diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 221c5d080d55326e458c1182823d6b49224ef498..de2f6d0271bb55f2fe0a5627e6cdc5879584456d 100644 +index 221c5d080d55326e458c1182823d6b49224ef498..2d020e5fc26871528b90ddc80dc1d5f49d4b1940 100644 --- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java @@ -44,6 +44,16 @@ public class PistonMovingBlockEntity extends BlockEntity { private long lastTicked; private int deathTicks; -+ // Paper start - region ticking ++ // Folia start - region ticking + @Override + public void updateTicks(long fromTickOffset, long fromGameTimeOffset) { + super.updateTicks(fromTickOffset, fromGameTimeOffset); @@ -19351,7 +19351,7 @@ index 221c5d080d55326e458c1182823d6b49224ef498..de2f6d0271bb55f2fe0a5627e6cdc587 + this.lastTicked += fromGameTimeOffset; + } + } -+ // Paper end - region ticking ++ // Folia end - region ticking + public PistonMovingBlockEntity(BlockPos pos, BlockState state) { super(BlockEntityType.PISTON, pos, state); @@ -19362,20 +19362,20 @@ index 221c5d080d55326e458c1182823d6b49224ef498..de2f6d0271bb55f2fe0a5627e6cdc587 // Paper - EAR items stuck in in slime pushed by a piston - entity.activatedTick = Math.max(entity.activatedTick, net.minecraft.server.MinecraftServer.currentTick + 10); - entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, net.minecraft.server.MinecraftServer.currentTick + 10); -+ entity.activatedTick = Math.max(entity.activatedTick, io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + 10); // Paper - region threading -+ entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + 10); // Paper - region threading ++ entity.activatedTick = Math.max(entity.activatedTick, io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + 10); // Folia - region threading ++ entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + 10); // Folia - region threading // Paper end break; } diff --git a/src/main/java/net/minecraft/world/level/border/WorldBorder.java b/src/main/java/net/minecraft/world/level/border/WorldBorder.java -index 7a12a4da4864306ec6589ca81368e84718825047..75fef911238058a5616a2504502de5b911563f06 100644 +index 7a12a4da4864306ec6589ca81368e84718825047..e3ef5ccad7f8a8138b1372f419680409ddeab291 100644 --- a/src/main/java/net/minecraft/world/level/border/WorldBorder.java +++ b/src/main/java/net/minecraft/world/level/border/WorldBorder.java @@ -33,19 +33,19 @@ public class WorldBorder { public WorldBorder() {} -+ // Paper - region threading - TODO make this shit thread-safe ++ // Folia - region threading - TODO make this shit thread-safe + public boolean isWithinBounds(BlockPos pos) { return (double) (pos.getX() + 1) > this.getMinX() && (double) pos.getX() < this.getMaxX() && (double) (pos.getZ() + 1) > this.getMinZ() && (double) pos.getZ() < this.getMaxZ(); @@ -19383,21 +19383,21 @@ index 7a12a4da4864306ec6589ca81368e84718825047..75fef911238058a5616a2504502de5b9 // Paper start - private final BlockPos.MutableBlockPos mutPos = new BlockPos.MutableBlockPos(); -+ private static final ThreadLocal mutPos = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos()); // Paper - region threading ++ private static final ThreadLocal mutPos = ThreadLocal.withInitial(() -> new BlockPos.MutableBlockPos()); // Folia - region threading public boolean isBlockInBounds(int chunkX, int chunkZ) { - this.mutPos.set(chunkX, 64, chunkZ); - return this.isWithinBounds(this.mutPos); -+ return this.isWithinBounds(mutPos.get().set(chunkX, 64, chunkZ)); // Paper - region threading ++ return this.isWithinBounds(mutPos.get().set(chunkX, 64, chunkZ)); // Folia - region threading } public boolean isChunkInBounds(int chunkX, int chunkZ) { - this.mutPos.set(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15); - return this.isWithinBounds(this.mutPos); -+ return this.isWithinBounds(mutPos.get().set(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15)); // Paper - region threading ++ return this.isWithinBounds(mutPos.get().set(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15)); // Folia - region threading } // Paper end diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index 7e9c388179c75a233d9b179ea1e00428ac65ee99..90c91179c189f9ed9bd90587978f02fc1853866e 100644 +index 7e9c388179c75a233d9b179ea1e00428ac65ee99..e5eb4ca68aafed44ab8cb1fb409f304c4776460a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -308,7 +308,7 @@ public abstract class ChunkGenerator { @@ -19405,12 +19405,12 @@ index 7e9c388179c75a233d9b179ea1e00428ac65ee99..90c91179c189f9ed9bd90587978f02fc } - ChunkAccess ichunkaccess = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); -+ ChunkAccess ichunkaccess = world.syncLoadNonFull(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); // Paper - region threading ++ ChunkAccess ichunkaccess = world.syncLoadNonFull(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); // Folia - region threading structurestart = structureAccessor.getStartForStructure(SectionPos.bottomOf(ichunkaccess), (Structure) holder.value(), ichunkaccess); } while (structurestart == null); diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653ce214e221 100644 +index e776eb8afef978938da084f9ae29d611181b43fe..cf43b204f0611af18b1e41bd9c7e803b474bb0b6 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -233,51 +233,15 @@ public class LevelChunk extends ChunkAccess { @@ -19441,7 +19441,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c - this.playerGeneralAreaCache = value; - } - -+ // Paper - region threading ++ // Folia - region threading public net.minecraft.server.level.ServerPlayer findNearestPlayer(double sourceX, double sourceY, double sourceZ, double maxRange, java.util.function.Predicate predicate) { - if (!this.playerGeneralAreaCacheSet) { @@ -19455,7 +19455,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c - } - - Object[] backingSet = nearby.getBackingSet(); -+ // Paper start - region threading ++ // Folia start - region threading double closestDistance = maxRange < 0.0 ? Double.MAX_VALUE : maxRange * maxRange; net.minecraft.server.level.ServerPlayer closest = null; - for (int i = 0, len = backingSet.length; i < len; ++i) { @@ -19476,7 +19476,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c } - return closest; -+ // Paper end - region threading ++ // Folia end - region threading } public void getNearestPlayers(double sourceX, double sourceY, double sourceZ, java.util.function.Predicate predicate, @@ -19491,7 +19491,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c - return; - } - -+ // Paper start - region threading ++ // Folia start - region threading double rangeSquared = range * range; - - Object[] backingSet = nearby.getBackingSet(); @@ -19511,7 +19511,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c ret.add(player); } } -+ // Paper end - region threading ++ // Folia end - region threading } // Paper end - optimise checkDespawn @@ -19520,7 +19520,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c } else { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. - if (!this.level.isClientSide && doPlace && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { -+ if (!this.level.isClientSide && doPlace && (!this.level.getCurrentWorldData().captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Paper - region threading ++ if (!this.level.isClientSide && doPlace && (!this.level.getCurrentWorldData().captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Folia - region threading iblockdata.onPlace(this.level, blockposition, iblockdata1, flag); } @@ -19529,7 +19529,7 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) { // CraftBukkit start - BlockEntity tileentity = level.capturedTileEntities.get(pos); -+ BlockEntity tileentity = level.getCurrentWorldData().capturedTileEntities.get(pos); // Paper - region threading ++ BlockEntity tileentity = level.getCurrentWorldData().capturedTileEntities.get(pos); // Folia - region threading if (tileentity == null) { tileentity = (BlockEntity) this.blockEntities.get(pos); } @@ -19538,14 +19538,14 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c org.bukkit.World world = this.level.getWorld(); if (world != null) { - this.level.populating = true; -+ this.level.getCurrentWorldData().populating = true; // Paper - region threading ++ this.level.getCurrentWorldData().populating = true; // Folia - region threading try { for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { populator.populate(world, random, bukkitChunk); } } finally { - this.level.populating = false; -+ this.level.getCurrentWorldData().populating = false; // Paper - region threading ++ this.level.getCurrentWorldData().populating = false; // Folia - region threading } } server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(this.bukkitChunk)); @@ -19554,12 +19554,12 @@ index e776eb8afef978938da084f9ae29d611181b43fe..928351ab809c0be2366ebaab1d1b653c public boolean isUnsaved() { // Paper start - add dirty system to tick lists - long gameTime = this.level.getLevelData().getGameTime(); -+ long gameTime = this.level.getRedstoneGameTime(); // Paper - region threading ++ long gameTime = this.level.getRedstoneGameTime(); // Folia - region threading if (this.blockTicks.isDirty(gameTime) || this.fluidTicks.isDirty(gameTime)) { return true; } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 256642f2e2aa66f7e8c00cae91a75060a8817c9c..4737011de22b17ad8c291a8cb04d71ee2f8943db 100644 +index 256642f2e2aa66f7e8c00cae91a75060a8817c9c..9fb91e3648db3ad79bb6d1fe79894a13ddc07cbb 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -687,7 +687,7 @@ public class ChunkSerializer { @@ -19567,19 +19567,19 @@ index 256642f2e2aa66f7e8c00cae91a75060a8817c9c..4737011de22b17ad8c291a8cb04d71ee private static void saveTicks(ServerLevel world, CompoundTag nbt, ChunkAccess.TicksToSave tickSchedulers) { - long i = world.getLevelData().getGameTime(); -+ long i = world.getRedstoneGameTime(); // Paper - region threading ++ long i = world.getRedstoneGameTime(); // Folia - region threading nbt.put("block_ticks", tickSchedulers.blocks().save(i, (block) -> { return BuiltInRegistries.BLOCK.getKey(block).toString(); diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java -index e9eb32469a5c03f7a3677ef50fd4541c1ed662ad..f09c5d7b3230d6553e825101fba164a98fa6b43b 100644 +index e9eb32469a5c03f7a3677ef50fd4541c1ed662ad..3ff5e74a2aae72eebe6730a4df15b17c1c8ff43a 100644 --- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java +++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java @@ -168,6 +168,7 @@ public class EndDragonFight { if (!this.dragonEvent.getPlayers().isEmpty()) { this.level.getChunkSource().addRegionTicket(TicketType.DRAGON, new ChunkPos(0, 0), 9, Unit.INSTANCE); boolean bl = this.isArenaLoaded(); -+ if (!bl) { return; }// Paper - region threading - don't tick if we don't own the entire region ++ if (!bl) { return; }// Folia - region threading - don't tick if we don't own the entire region if (this.needsStateScanning && bl) { this.scanState(); this.needsStateScanning = false; @@ -19587,12 +19587,12 @@ index e9eb32469a5c03f7a3677ef50fd4541c1ed662ad..f09c5d7b3230d6553e825101fba164a9 } List list = this.level.getDragons(); -+ // Paper start - region threading ++ // Folia start - region threading + // we do not want to deal with any dragons NOT nearby + list.removeIf((dragon) -> { + return !io.papermc.paper.util.TickThread.isTickThreadFor(dragon); + }); -+ // Paper end - region threading ++ // Folia end - region threading if (list.isEmpty()) { this.dragonKilled = true; } else { @@ -19602,13 +19602,13 @@ index e9eb32469a5c03f7a3677ef50fd4541c1ed662ad..f09c5d7b3230d6553e825101fba164a9 for(int j = 8; j <= 8; ++j) { - ChunkAccess chunkAccess = this.level.getChunk(i, j, ChunkStatus.FULL, false); - if (!(chunkAccess instanceof LevelChunk)) { -+ ChunkAccess chunkAccess = this.level.getChunkIfLoaded(i, j); // Paper - region threading -+ if (!(chunkAccess instanceof LevelChunk) || !io.papermc.paper.util.TickThread.isTickThreadFor(this.level, i, j, this.level.regioniser.regionSectionChunkSize)) { // Paper - region threading ++ ChunkAccess chunkAccess = this.level.getChunkIfLoaded(i, j); // Folia - region threading ++ if (!(chunkAccess instanceof LevelChunk) || !io.papermc.paper.util.TickThread.isTickThreadFor(this.level, i, j, this.level.regioniser.regionSectionChunkSize)) { // Folia - region threading return false; } diff --git a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java -index a908652f1ebb426d265ef614746f70cd1e538268..08e35b6aea5f6bdfb3e5a6ef602aaeb4a97a57be 100644 +index a908652f1ebb426d265ef614746f70cd1e538268..b2a9cd719c4968a1cde8f0b30f46f01d5872fbc9 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java @@ -19,7 +19,7 @@ import net.minecraft.world.level.block.state.BlockState; @@ -19616,7 +19616,7 @@ index a908652f1ebb426d265ef614746f70cd1e538268..08e35b6aea5f6bdfb3e5a6ef602aaeb4 public class PatrolSpawner implements CustomSpawner { - private int nextTick; -+ //private int nextTick; // Paper - region threading ++ //private int nextTick; // Folia - region threading public PatrolSpawner() {} @@ -19624,18 +19624,18 @@ index a908652f1ebb426d265ef614746f70cd1e538268..08e35b6aea5f6bdfb3e5a6ef602aaeb4 return 0; } else { RandomSource randomsource = world.random; -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading // Paper start - Patrol settings // Random player selection moved up for per player spawning and configuration - int j = world.players().size(); -+ int j = world.getLocalPlayers().size(); // Paper - region threading ++ int j = world.getLocalPlayers().size(); // Folia - region threading if (j < 1) { return 0; } - net.minecraft.server.level.ServerPlayer entityhuman = world.players().get(randomsource.nextInt(j)); -+ net.minecraft.server.level.ServerPlayer entityhuman = world.getLocalPlayers().get(randomsource.nextInt(j)); // Paper - region threading ++ net.minecraft.server.level.ServerPlayer entityhuman = world.getLocalPlayers().get(randomsource.nextInt(j)); // Folia - region threading if (entityhuman.isSpectator()) { return 0; } @@ -19645,8 +19645,8 @@ index a908652f1ebb426d265ef614746f70cd1e538268..08e35b6aea5f6bdfb3e5a6ef602aaeb4 } else { - this.nextTick--; - patrolSpawnDelay = this.nextTick; -+ worldData.patrolSpawnerNextTick--; // Paper - region threading -+ patrolSpawnDelay = worldData.patrolSpawnerNextTick; // Paper - region threading ++ worldData.patrolSpawnerNextTick--; // Folia - region threading ++ patrolSpawnDelay = worldData.patrolSpawnerNextTick; // Folia - region threading } if (patrolSpawnDelay > 0) { @@ -19655,12 +19655,12 @@ index a908652f1ebb426d265ef614746f70cd1e538268..08e35b6aea5f6bdfb3e5a6ef602aaeb4 entityhuman.patrolSpawnDelay += world.paperConfig().entities.behavior.pillagerPatrols.spawnDelay.ticks + randomsource.nextInt(1200); } else { - this.nextTick += world.paperConfig().entities.behavior.pillagerPatrols.spawnDelay.ticks + randomsource.nextInt(1200); -+ worldData.patrolSpawnerNextTick += world.paperConfig().entities.behavior.pillagerPatrols.spawnDelay.ticks + randomsource.nextInt(1200); // Paper - region threading ++ worldData.patrolSpawnerNextTick += world.paperConfig().entities.behavior.pillagerPatrols.spawnDelay.ticks + randomsource.nextInt(1200); // Folia - region threading } if (days >= world.paperConfig().entities.behavior.pillagerPatrols.start.day && world.isDay()) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java -index 1c3718d9244513d9fc795dceb564a81375734557..d20c539d0d4f9e7fee42333ffe45cc01e05e9a43 100644 +index 1c3718d9244513d9fc795dceb564a81375734557..f445e1db1538fb9eda4b2f81f62748dc57fda24a 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -24,7 +24,7 @@ import net.minecraft.world.level.material.FluidState; @@ -19668,7 +19668,7 @@ index 1c3718d9244513d9fc795dceb564a81375734557..d20c539d0d4f9e7fee42333ffe45cc01 public class PhantomSpawner implements CustomSpawner { - private int nextTick; -+ //private int nextTick; // Paper - region threading ++ //private int nextTick; // Folia - region threading public PhantomSpawner() {} @@ -19678,36 +19678,36 @@ index 1c3718d9244513d9fc795dceb564a81375734557..d20c539d0d4f9e7fee42333ffe45cc01 - --this.nextTick; - if (this.nextTick > 0) { -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading + -+ --worldData.phantomSpawnerNextTick; // Paper - region threading -+ if (worldData.phantomSpawnerNextTick > 0) { // Paper - region threading ++ --worldData.phantomSpawnerNextTick; // Folia - region threading ++ if (worldData.phantomSpawnerNextTick > 0) { // Folia - region threading return 0; } else { // Paper start int spawnAttemptMinSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMinSeconds; int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds; - this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; -+ worldData.phantomSpawnerNextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; // Paper - region threading ++ worldData.phantomSpawnerNextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20; // Folia - region threading // Paper end if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) { return 0; } else { int i = 0; - Iterator iterator = world.players().iterator(); -+ Iterator iterator = world.getLocalPlayers().iterator(); // Paper - region threading ++ Iterator iterator = world.getLocalPlayers().iterator(); // Folia - region threading while (iterator.hasNext()) { Player entityhuman = (Player) iterator.next(); diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..a2a0926f2712bfb8e92b646a2105cd490ac8ded2 100644 +index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..7fb7083a2a437b1c14bf1e6e66cd09f2769dc433 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/src/main/java/net/minecraft/world/level/levelgen/structure/StructureCheck.java @@ -70,6 +70,7 @@ public class StructureCheck { } public StructureCheckResult checkStart(ChunkPos pos, Structure type, boolean skipReferencedStructures) { -+ if (true) return StructureCheckResult.CHUNK_LOAD_NEEDED; // Paper - region threading ++ if (true) return StructureCheckResult.CHUNK_LOAD_NEEDED; // Folia - region threading long l = pos.toLong(); Object2IntMap object2IntMap = this.loadedChunks.get(l); if (object2IntMap != null) { @@ -19715,7 +19715,7 @@ index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..a2a0926f2712bfb8e92b646a2105cd49 @Nullable private StructureCheckResult tryLoadFromStorage(ChunkPos pos, Structure structure, boolean skipReferencedStructures, long posLong) { -+ if (true) return StructureCheckResult.CHUNK_LOAD_NEEDED; // Paper - region threading ++ if (true) return StructureCheckResult.CHUNK_LOAD_NEEDED; // Folia - region threading CollectFields collectFields = new CollectFields(new FieldSelector(IntTag.TYPE, "DataVersion"), new FieldSelector("Level", "Structures", CompoundTag.TYPE, "Starts"), new FieldSelector("structures", CompoundTag.TYPE, "starts")); try { @@ -19723,7 +19723,7 @@ index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..a2a0926f2712bfb8e92b646a2105cd49 } public void onStructureLoad(ChunkPos pos, Map structureStarts) { -+ if (true) return; // Paper - region threading ++ if (true) return; // Folia - region threading long l = pos.toLong(); Object2IntMap object2IntMap = new Object2IntOpenHashMap<>(); structureStarts.forEach((start, structureStart) -> { @@ -19731,7 +19731,7 @@ index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..a2a0926f2712bfb8e92b646a2105cd49 } private void storeFullResults(long pos, Object2IntMap referencesByStructure) { -+ if (true) return; // Paper - region threading ++ if (true) return; // Folia - region threading this.loadedChunks.put(pos, deduplicateEmptyMap(referencesByStructure)); this.featureChecks.values().forEach((generationPossibilityByChunkPos) -> { generationPossibilityByChunkPos.remove(pos); @@ -19739,12 +19739,12 @@ index 4761aa772bc34dd66547dd4dd561c2e04c3229ad..a2a0926f2712bfb8e92b646a2105cd49 } public void incrementReference(ChunkPos pos, Structure structure) { -+ if (true) return; // Paper - region threading ++ if (true) return; // Folia - region threading this.loadedChunks.compute(pos.toLong(), (posx, referencesByStructure) -> { if (referencesByStructure == null || referencesByStructure.isEmpty()) { referencesByStructure = new Object2IntOpenHashMap<>(); diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index 92d13c9f1ec1e5ff72c1d68f924a8d1c86c91565..8c4fb6c24437edc1daf81f2e20d22e34ef683bf1 100644 +index 92d13c9f1ec1e5ff72c1d68f924a8d1c86c91565..3f224315f1e0a8f69e9d84d27fd7dbe45ea75667 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -89,10 +89,10 @@ public class PortalForcer { @@ -19752,28 +19752,28 @@ index 92d13c9f1ec1e5ff72c1d68f924a8d1c86c91565..8c4fb6c24437edc1daf81f2e20d22e34 this.level.getChunkSource().addRegionTicket(TicketType.PORTAL, new ChunkPos(blockposition1), 3, blockposition1); - BlockState iblockdata = this.level.getBlockState(blockposition1); -+ BlockState iblockdata = this.level.getBlockStateFromEmptyChunk(blockposition1); // Paper - region threading ++ BlockState iblockdata = this.level.getBlockStateFromEmptyChunk(blockposition1); // Folia - region threading return BlockUtil.getLargestRectangleAround(blockposition1, (Direction.Axis) iblockdata.getValue(BlockStateProperties.HORIZONTAL_AXIS), 21, Direction.Axis.Y, 21, (blockposition2) -> { - return this.level.getBlockState(blockposition2) == iblockdata; -+ return this.level.getBlockStateFromEmptyChunk(blockposition2) == iblockdata; // Paper - region threading ++ return this.level.getBlockStateFromEmptyChunk(blockposition2) == iblockdata; // Folia - region threading }); }); } diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java -index b1c594dc6a6b8a6c737b99272acab9e7dbd0ed63..a1923908277d096d5cb1f5a585490ee7e885d0fd 100644 +index b1c594dc6a6b8a6c737b99272acab9e7dbd0ed63..7c1768452fa0f7278ccc84470ef0965a3f96b0df 100644 --- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java +++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java @@ -46,6 +46,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater { } private void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates entry) { -+ io.papermc.paper.util.TickThread.ensureTickThread((net.minecraft.server.level.ServerLevel)this.level, pos, "Adding block without owning region"); // Paper - region threading ++ io.papermc.paper.util.TickThread.ensureTickThread((net.minecraft.server.level.ServerLevel)this.level, pos, "Adding block without owning region"); // Folia - region threading boolean bl = this.count > 0; boolean bl2 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates; ++this.count; diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java -index b2845ed8d28627178589da3d2224cd9edd29c31e..5c10849906fcec82a3e92646daab065ac86be58f 100644 +index b2845ed8d28627178589da3d2224cd9edd29c31e..9df7c7e44e9a75187bd1e3e8f7e6bc5d385b0733 100644 --- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java @@ -368,7 +368,7 @@ public class MapItemSavedData extends SavedData { @@ -19781,19 +19781,19 @@ index b2845ed8d28627178589da3d2224cd9edd29c31e..5c10849906fcec82a3e92646daab065a b2 = (byte) ((int) (rotation * 16.0D / 360.0D)); if (this.dimension == Level.NETHER && world != null) { - int j = (int) (world.getLevelData().getDayTime() / 10L); -+ int j = (int) (world.getLevelData().getDayTime() / 10L); // Paper - region threading - TODO ++ int j = (int) (world.getLevelData().getDayTime() / 10L); // Folia - region threading - TODO b2 = (byte) (j * j * 34187121 + j * 121 >> 15 & 15); } diff --git a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java -index ac807277a6b26d140ea9873d17c7aa4fb5fe37b2..e5305a2773302dab02d8ec7741406b6ace85bc48 100644 +index ac807277a6b26d140ea9873d17c7aa4fb5fe37b2..e13d8700593f1f486cfc5c96ac25894202c07b71 100644 --- a/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java +++ b/src/main/java/net/minecraft/world/ticks/LevelChunkTicks.java @@ -37,6 +37,21 @@ public class LevelChunkTicks implements SerializableTickContainer, TickCon this.dirty = false; } // Paper end - add dirty flag -+ // Paper start - region threading ++ // Folia start - region threading + public void offsetTicks(final long offset) { + if (offset == 0 || this.tickQueue.isEmpty()) { + return; @@ -19807,12 +19807,12 @@ index ac807277a6b26d140ea9873d17c7aa4fb5fe37b2..e5305a2773302dab02d8ec7741406b6a + this.tickQueue.add(newEntry); + } + } -+ // Paper end - region threading ++ // Folia end - region threading public LevelChunkTicks() { } diff --git a/src/main/java/net/minecraft/world/ticks/LevelTicks.java b/src/main/java/net/minecraft/world/ticks/LevelTicks.java -index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c325627c583 100644 +index 7f1ac2cb29eb84833c0895442d611dfa0504527e..c79cfebc65fd04994735dabcf5bb6e6cc714aca8 100644 --- a/src/main/java/net/minecraft/world/ticks/LevelTicks.java +++ b/src/main/java/net/minecraft/world/ticks/LevelTicks.java @@ -42,13 +42,70 @@ public class LevelTicks implements LevelTickAccess { @@ -19821,14 +19821,14 @@ index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c32 private final BiConsumer, ScheduledTick> chunkScheduleUpdater = (chunkTickScheduler, tick) -> { - if (tick.equals(chunkTickScheduler.peek())) { - this.updateContainerScheduling(tick); -+ if (tick.equals(chunkTickScheduler.peek())) { // Paper - diff on change -+ this.updateContainerScheduling(tick); // Paper - diff on change ++ if (tick.equals(chunkTickScheduler.peek())) { // Folia - diff on change ++ this.updateContainerScheduling(tick); // Folia - diff on change } }; - public LevelTicks(LongPredicate tickingFutureReadyPredicate, Supplier profilerGetter) { -+ // Paper start - region threading ++ // Folia start - region threading + public final net.minecraft.server.level.ServerLevel world; + public final boolean isBlock; + @@ -19883,9 +19883,9 @@ index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c32 + regionToData.get(regionSectionKey).nextTickForContainer.put(chunkKey, entry.getLongValue()); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + -+ public LevelTicks(LongPredicate tickingFutureReadyPredicate, Supplier profilerGetter, net.minecraft.server.level.ServerLevel world, boolean isBlock) { this.world = world; this.isBlock = isBlock; // Paper - add world and isBlock ++ public LevelTicks(LongPredicate tickingFutureReadyPredicate, Supplier profilerGetter, net.minecraft.server.level.ServerLevel world, boolean isBlock) { this.world = world; this.isBlock = isBlock; // Folia - add world and isBlock this.tickCheck = tickingFutureReadyPredicate; this.profiler = profilerGetter; } @@ -19894,7 +19894,7 @@ index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c32 } - scheduler.setOnTickAdded(this.chunkScheduleUpdater); -+ // Paper start - region threading ++ // Folia start - region threading + final boolean isBlock = this.isBlock; + final net.minecraft.server.level.ServerLevel world = this.world; + // make sure the lambda contains no reference to this LevelTicks @@ -19904,7 +19904,7 @@ index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c32 + (isBlock ? worldData.getBlockLevelTicks() : worldData.getFluidLevelTicks()).updateContainerScheduling((ScheduledTick)tick); + } + }); -+ // Paper end - region threading ++ // Folia end - region threading } public void removeContainer(ChunkPos pos) { @@ -19912,21 +19912,21 @@ index 7f1ac2cb29eb84833c0895442d611dfa0504527e..2784ad4f943aeb5b1640e28a40ce2c32 @Override public void schedule(ScheduledTick orderedTick) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, orderedTick.pos(), "Cannot schedule tick for another region!"); // Paper - region threading ++ io.papermc.paper.util.TickThread.ensureTickThread(this.world, orderedTick.pos(), "Cannot schedule tick for another region!"); // Folia - region threading long l = ChunkPos.asLong(orderedTick.pos()); LevelChunkTicks levelChunkTicks = this.allContainers.get(l); if (levelChunkTicks == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb2f0af249 100644 +index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4c2a393ee2d5fbcdbf3abb4a49f1bfae2d2c618 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -879,6 +879,9 @@ public final class CraftServer implements Server { // NOTE: Should only be called from DedicatedServer.ah() public boolean dispatchServerCommand(CommandSender sender, ConsoleInput serverCommand) { -+ // Paper start - region threading ++ // Folia start - region threading + io.papermc.paper.threadedregions.RegionisedServer.ensureGlobalTickThread("May not dispatch server commands async"); -+ // Paper end - region threading ++ // Folia end - region threading if (sender instanceof Conversable) { Conversable conversable = (Conversable) sender; @@ -19934,7 +19934,7 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb } } -+ // Paper start - region threading ++ // Folia start - region threading + public void dispatchCmdAsync(CommandSender sender, String commandLine) { + if ((sender instanceof Entity entity)) { + ((org.bukkit.craftbukkit.entity.CraftEntity)entity).taskScheduler.schedule( @@ -19953,7 +19953,7 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb + throw new UnsupportedOperationException("Dispatching command for " + sender); + } + } -+ // Paper end - region threading ++ // Folia end - region threading + @Override public boolean dispatchCommand(CommandSender sender, String commandLine) { @@ -19961,7 +19961,7 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb Validate.notNull(commandLine, "CommandLine cannot be null"); org.spigotmc.AsyncCatcher.catchOp("command dispatch"); // Spigot -+ // Paper start - region threading ++ // Folia start - region threading + if ((sender instanceof Entity entity)) { + io.papermc.paper.util.TickThread.ensureTickThread(((org.bukkit.craftbukkit.entity.CraftEntity)entity).getHandle(), "Dispatching command async"); + } else if (sender instanceof ConsoleCommandSender console) { @@ -19970,7 +19970,7 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb + // huh? + throw new UnsupportedOperationException("Dispatching command for " + sender); + } -+ // Paper end - region threading ++ // Folia end - region threading + // Paper Start if (!org.spigotmc.AsyncCatcher.shuttingDown && !Bukkit.isPrimaryThread()) { @@ -19980,12 +19980,12 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..c4ce387a09b97b289e5d67919359bfdb @Override public int getCurrentTick() { - return net.minecraft.server.MinecraftServer.currentTick; -+ return (int)io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - region threading ++ return (int)io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - region threading } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb794ba503 100644 +index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08af148fff 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -180,7 +180,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -19993,7 +19993,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb @Override public int getTickableTileEntityCount() { - return world.getTotalTileEntityTickers(); -+ throw new UnsupportedOperationException(); // Paper - region threading - TODO fix this? ++ throw new UnsupportedOperationException(); // Folia - region threading - TODO fix this? } @Override @@ -20003,17 +20003,17 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { - world.captureTreeGeneration = true; - world.captureBlockStates = true; -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading -+ worldData.captureTreeGeneration = true; // Paper - region threading -+ worldData.captureBlockStates = true; // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading ++ worldData.captureTreeGeneration = true; // Folia - region threading ++ worldData.captureBlockStates = true; // Folia - region threading boolean grownTree = this.generateTree(loc, type); - world.captureBlockStates = false; - world.captureTreeGeneration = false; -+ worldData.captureBlockStates = false; // Paper - region threading -+ worldData.captureTreeGeneration = false; // Paper - region threading ++ worldData.captureBlockStates = false; // Folia - region threading ++ worldData.captureTreeGeneration = false; // Folia - region threading if (grownTree) { // Copy block data to delegate - for (BlockState blockstate : world.capturedBlockStates.values()) { -+ for (BlockState blockstate : worldData.capturedBlockStates.values()) { // Paper - region threading ++ for (BlockState blockstate : worldData.capturedBlockStates.values()) { // Folia - region threading BlockPos position = ((CraftBlockState) blockstate).getPosition(); net.minecraft.world.level.block.state.BlockState oldBlock = this.world.getBlockState(position); int flag = ((CraftBlockState) blockstate).getFlag(); @@ -20022,11 +20022,11 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb this.world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, newBlock, flag, 512); } - world.capturedBlockStates.clear(); -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading return true; } else { - world.capturedBlockStates.clear(); -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading return false; } } @@ -20035,7 +20035,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb @Override public long getGameTime() { - return world.levelData.getGameTime(); -+ return this.getHandle().getGameTime(); // Paper - region threading ++ return this.getHandle().getGameTime(); // Folia - region threading } @Override @@ -20044,7 +20044,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect(sound)), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, this.getHandle().getRandom().nextLong()); - ChunkMap.TrackedEntity entityTracker = this.getHandle().getChunkSource().chunkMap.entityMap.get(entity.getEntityId()); -+ ChunkMap.TrackedEntity entityTracker = ((CraftEntity) entity).getHandle().tracker; // Paper - region threading ++ ChunkMap.TrackedEntity entityTracker = ((CraftEntity) entity).getHandle().tracker; // Folia - region threading if (entityTracker != null) { entityTracker.broadcastAndSend(packet); } @@ -20053,39 +20053,39 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..8eb33972ccd3cb7a860c2497dee752cb io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { - net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue(this.getHandle(), x, z, () -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueTickTaskQueue(this.getHandle(), x, z, () -> { // Folia - region threading net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; if (chunk != null) addTicket(x, z); // Paper ret.complete(chunk == null ? null : chunk.getBukkitChunk()); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 350cbf64c17938021002d5fd67176c44b398231e..173f180272de79afe853848f04c8f39e24c807dc 100644 +index 350cbf64c17938021002d5fd67176c44b398231e..e54713a530e18344a7c7d1c400147fc33d64967f 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -568,16 +568,17 @@ public class CraftBlock implements Block { ServerLevel world = this.getCraftWorld().getHandle(); UseOnContext context = new UseOnContext(world, null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false)); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading // SPIGOT-6895: Call StructureGrowEvent and BlockFertilizeEvent - world.captureTreeGeneration = true; -+ worldData.captureTreeGeneration = true; // Paper - region threading ++ worldData.captureTreeGeneration = true; // Folia - region threading InteractionResult result = BoneMealItem.applyBonemeal(context); - world.captureTreeGeneration = false; -+ worldData.captureTreeGeneration = false; // Paper - region threading ++ worldData.captureTreeGeneration = false; // Folia - region threading - if (world.capturedBlockStates.size() > 0) { -+ if (worldData.capturedBlockStates.size() > 0) { // Paper - region threading ++ if (worldData.capturedBlockStates.size() > 0) { // Folia - region threading TreeType treeType = SaplingBlock.treeType; SaplingBlock.treeType = null; - List blocks = new ArrayList<>(world.capturedBlockStates.values()); - world.capturedBlockStates.clear(); -+ List blocks = new ArrayList<>(worldData.capturedBlockStates.values()); // Paper - region threading -+ worldData.capturedBlockStates.clear(); // Paper - region threading ++ List blocks = new ArrayList<>(worldData.capturedBlockStates.values()); // Folia - region threading ++ worldData.capturedBlockStates.clear(); // Folia - region threading StructureGrowEvent structureEvent = null; if (treeType != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java -index cd4ad8261e56365850068db1d83d6a8454026737..2daae3c5a237ac8e8d74d26e715131a26e870a6c 100644 +index cd4ad8261e56365850068db1d83d6a8454026737..c098ae9f057a3dcc77c61555feb870452e947ae7 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java @@ -50,7 +50,7 @@ public class ConsoleCommandCompleter implements Completer { @@ -20093,7 +20093,7 @@ index cd4ad8261e56365850068db1d83d6a8454026737..2daae3c5a237ac8e8d74d26e715131a2 } }; - server.getServer().processQueue.add(syncCompletions); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(syncCompletions); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(syncCompletions); // Folia - region threading try { final List legacyCompletions = syncCompletions.get(); completions.removeIf(it -> !legacyCompletions.contains(it.suggestion())); // remove any suggestions that were removed @@ -20102,19 +20102,19 @@ index cd4ad8261e56365850068db1d83d6a8454026737..2daae3c5a237ac8e8d74d26e715131a2 } }; - server.getServer().processQueue.add(waitable); // Paper - Remove "this." -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(waitable); // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(waitable); // Folia - region threading try { List offers = waitable.get(); if (offers == null) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 78f53ee557276de85f0431ebcb146445b1f4fb92..1723dc6b981a267018e90ecf6f21a74f38367379 100644 +index 78f53ee557276de85f0431ebcb146445b1f4fb92..ab6db7c5193a7c4b3f9433c6997dd24c76a84904 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -200,6 +200,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { private EntityDamageEvent lastDamageEvent; private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY); protected net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers -+ public final io.papermc.paper.threadedregions.EntityScheduler taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this); // Paper - region threading ++ public final io.papermc.paper.threadedregions.EntityScheduler taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this); // Folia - region threading public CraftEntity(final CraftServer server, final Entity entity) { this.server = server; @@ -20122,11 +20122,11 @@ index 78f53ee557276de85f0431ebcb146445b1f4fb92..1723dc6b981a267018e90ecf6f21a74f @Override public boolean teleport(Location location, TeleportCause cause, boolean ignorePassengers, boolean dismount) { -+ // Paper start - region threading ++ // Folia start - region threading + if (true) { + throw new UnsupportedOperationException("Must use teleportAsync while in region threading"); + } -+ // Paper end - region threading ++ // Folia end - region threading // Paper end Preconditions.checkArgument(location != null, "location cannot be null"); location.checkFinite(); @@ -20135,7 +20135,7 @@ index 78f53ee557276de85f0431ebcb146445b1f4fb92..1723dc6b981a267018e90ecf6f21a74f ServerLevel world = ((CraftWorld) this.getWorld()).getHandle(); - ChunkMap.TrackedEntity entityTracker = world.getChunkSource().chunkMap.entityMap.get(this.getEntityId()); -+ ChunkMap.TrackedEntity entityTracker = this.getHandle().tracker; // Paper - region threading ++ ChunkMap.TrackedEntity entityTracker = this.getHandle().tracker; // Folia - region threading if (entityTracker == null) { return; @@ -20145,7 +20145,7 @@ index 78f53ee557276de85f0431ebcb146445b1f4fb92..1723dc6b981a267018e90ecf6f21a74f Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call. - - net.minecraft.server.level.ServerLevel world = ((CraftWorld)locationClone.getWorld()).getHandle(); -+ // Paper start - region threading ++ // Folia start - region threading java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); - - world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()), @@ -20193,12 +20193,12 @@ index 78f53ee557276de85f0431ebcb146445b1f4fb92..1723dc6b981a267018e90ecf6f21a74f + } return ret; -+ // Paper end - region threading ++ // Folia end - region threading } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 0351eb67bac6ce257f820af60aa3bba9f45da687..2530d925b969c27358edda71a62d2611260fd5f5 100644 +index 0351eb67bac6ce257f820af60aa3bba9f45da687..88006751825515966dcea1f779ac5452c8ddd964 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1702,7 +1702,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -20206,7 +20206,7 @@ index 0351eb67bac6ce257f820af60aa3bba9f45da687..2530d925b969c27358edda71a62d2611 // Paper end ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; - ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); -+ ChunkMap.TrackedEntity entry = other.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity entry = other.tracker; // Folia - region threading if (entry != null) { entry.removePlayer(this.getHandle()); } @@ -20215,12 +20215,12 @@ index 0351eb67bac6ce257f820af60aa3bba9f45da687..2530d925b969c27358edda71a62d2611 } - ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); -+ ChunkMap.TrackedEntity entry = other.tracker; // Paper - region threading ++ ChunkMap.TrackedEntity entry = other.tracker; // Folia - region threading if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) { entry.updatePlayer(this.getHandle()); } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262ea31ee9aa 100644 +index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..2a6fe4a3fdba9d0027a2e445b694afc80a18053c 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -228,8 +228,8 @@ import org.bukkit.event.entity.SpawnerSpawnEvent; // Spigot @@ -20239,7 +20239,7 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e } - public static BlockPos sourceBlockOverride = null; // SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. -+ public static ThreadLocal sourceBlockOverrideRT = new ThreadLocal<>(); // SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. // Paper - region threading ++ public static ThreadLocal sourceBlockOverrideRT = new ThreadLocal<>(); // SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep. // Folia - region threading public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) { // Suppress during worldgen if (!(world instanceof Level)) { @@ -20248,7 +20248,7 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e state.setData(block); - BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverride != null ? CraftEventFactory.sourceBlockOverride : source), state); -+ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverrideRT.get() != null ? CraftEventFactory.sourceBlockOverrideRT.get() : source), state); // Paper - region threading ++ BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, CraftEventFactory.sourceBlockOverrideRT.get() != null ? CraftEventFactory.sourceBlockOverrideRT.get() : source), state); // Folia - region threading Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { @@ -20258,8 +20258,8 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e DamageCause damageCause; - Entity damager = CraftEventFactory.entityDamage; - CraftEventFactory.entityDamage = null; -+ Entity damager = CraftEventFactory.entityDamageRT.get(); // Paper - region threading -+ CraftEventFactory.entityDamageRT.set(null); // Paper - region threading ++ Entity damager = CraftEventFactory.entityDamageRT.get(); // Folia - region threading ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading EntityDamageEvent event; if (damager == null) { event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions); @@ -20268,16 +20268,16 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e return event; } else if (source == DamageSource.LAVA) { - EntityDamageEvent event = (new EntityDamageByBlockEvent(CraftEventFactory.blockDamage, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); -+ EntityDamageEvent event = (new EntityDamageByBlockEvent(CraftEventFactory.blockDamageRT.get(), entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); // Paper - region threading ++ EntityDamageEvent event = (new EntityDamageByBlockEvent(CraftEventFactory.blockDamageRT.get(), entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); // Folia - region threading event.setCancelled(cancelled); - Block damager = CraftEventFactory.blockDamage; - CraftEventFactory.blockDamage = null; // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call + Block damager = CraftEventFactory.blockDamageRT.get(); -+ CraftEventFactory.blockDamageRT.set(null); // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call // Folia - region threading CraftEventFactory.callEvent(event); - CraftEventFactory.blockDamage = damager; // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause -+ CraftEventFactory.blockDamageRT.set(damager); // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(damager); // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause // Folia - region threading if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); @@ -20286,10 +20286,10 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e } return event; - } else if (CraftEventFactory.blockDamage != null) { -+ } else if (CraftEventFactory.blockDamageRT.get() != null) { // Paper - region threading ++ } else if (CraftEventFactory.blockDamageRT.get() != null) { // Folia - region threading DamageCause cause = null; - Block damager = CraftEventFactory.blockDamage; -+ Block damager = CraftEventFactory.blockDamageRT.get(); // Paper - region threading ++ Block damager = CraftEventFactory.blockDamageRT.get(); // Folia - region threading if (source == DamageSource.CACTUS || source == DamageSource.SWEET_BERRY_BUSH || source == DamageSource.STALAGMITE || "fallingStalactite".equals(source.msgId) || "anvil".equals(source.msgId)) { cause = DamageCause.CONTACT; } else if (source == DamageSource.HOT_FLOOR) { @@ -20298,10 +20298,10 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e event.setCancelled(cancelled); - CraftEventFactory.blockDamage = null; // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call -+ CraftEventFactory.blockDamageRT.set(null); // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(null); // SPIGOT-6639: Clear blockDamage to allow other entity damage during event call // Folia - region threading CraftEventFactory.callEvent(event); - CraftEventFactory.blockDamage = damager; // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause -+ CraftEventFactory.blockDamageRT.set(damager); // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause // Paper - region threading ++ CraftEventFactory.blockDamageRT.set(damager); // SPIGOT-6639: Re-set blockDamage so that other entities which are also getting damaged have the right cause // Folia - region threading if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); @@ -20310,65 +20310,65 @@ index 6a52ae70b5f7fd9953b6b2605cae722f606e7fec..8ee60d2b04ce9d93e086a9cce8a7262e } return event; - } else if (CraftEventFactory.entityDamage != null) { -+ } else if (CraftEventFactory.entityDamageRT.get() != null) { // Paper - region threading ++ } else if (CraftEventFactory.entityDamageRT.get() != null) { // Folia - region threading DamageCause cause = null; - CraftEntity damager = CraftEventFactory.entityDamage.getBukkitEntity(); - CraftEventFactory.entityDamage = null; + CraftEntity damager = CraftEventFactory.entityDamageRT.get().getBukkitEntity(); -+ CraftEventFactory.entityDamageRT.set(null); // Paper - region threading ++ CraftEventFactory.entityDamageRT.set(null); // Folia - region threading if ("fallingStalactite".equals(source.msgId) || "fallingBlock".equals(source.msgId) || "anvil".equals(source.msgId)) { cause = DamageCause.FALLING_BLOCK; } else if (damager instanceof LightningStrike) { diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index cdefb2025eedea7e204d70d568adaf1c1ec4c03c..7ae3f2da090e6596b9f52762cd7bcc13bf7d0a99 100644 +index cdefb2025eedea7e204d70d568adaf1c1ec4c03c..9136fb30db749737e9f189d0901024fcad02e402 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -533,6 +533,7 @@ public class CraftScheduler implements BukkitScheduler { } protected CraftTask handle(final CraftTask task, final long delay) { // Paper -+ if (true) throw new UnsupportedOperationException(); // Paper - region threading ++ if (true) throw new UnsupportedOperationException(); // Folia - region threading // Paper start if (!this.isAsyncScheduler && !task.isSync()) { this.asyncScheduler.handle(task, delay); diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7d5c84eb2 100644 +index e881584d38dc354204479863f004e974a0ac6c07..7d99ba41a3178f5321403eb7749f0a4b898ad0a9 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -65,26 +65,27 @@ public class ActivationRange private static int checkInactiveWakeup(Entity entity) { Level world = entity.level; -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - threaded regions ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - threaded regions SpigotWorldConfig config = world.spigotConfig; - long inactiveFor = MinecraftServer.currentTick - entity.activatedTick; -+ long inactiveFor = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick; // Paper - threaded regions ++ long inactiveFor = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick; // Folia - threaded regions if (entity.activationType == ActivationType.VILLAGER) { - if (inactiveFor > config.wakeUpInactiveVillagersEvery && world.wakeupInactiveRemainingVillagers > 0) { - world.wakeupInactiveRemainingVillagers--; -+ if (inactiveFor > config.wakeUpInactiveVillagersEvery && worldData.wakeupInactiveRemainingVillagers > 0) { // Paper - threaded regions -+ worldData.wakeupInactiveRemainingVillagers--; // Paper - threaded regions ++ if (inactiveFor > config.wakeUpInactiveVillagersEvery && worldData.wakeupInactiveRemainingVillagers > 0) { // Folia - threaded regions ++ worldData.wakeupInactiveRemainingVillagers--; // Folia - threaded regions return config.wakeUpInactiveVillagersFor; } } else if (entity.activationType == ActivationType.ANIMAL) { - if (inactiveFor > config.wakeUpInactiveAnimalsEvery && world.wakeupInactiveRemainingAnimals > 0) { - world.wakeupInactiveRemainingAnimals--; -+ if (inactiveFor > config.wakeUpInactiveAnimalsEvery && worldData.wakeupInactiveRemainingAnimals > 0) { // Paper - threaded regions -+ worldData.wakeupInactiveRemainingAnimals--; // Paper - threaded regions ++ if (inactiveFor > config.wakeUpInactiveAnimalsEvery && worldData.wakeupInactiveRemainingAnimals > 0) { // Folia - threaded regions ++ worldData.wakeupInactiveRemainingAnimals--; // Folia - threaded regions return config.wakeUpInactiveAnimalsFor; } } else if (entity.activationType == ActivationType.FLYING_MONSTER) { - if (inactiveFor > config.wakeUpInactiveFlyingEvery && world.wakeupInactiveRemainingFlying > 0) { - world.wakeupInactiveRemainingFlying--; -+ if (inactiveFor > config.wakeUpInactiveFlyingEvery && worldData.wakeupInactiveRemainingFlying > 0) { // Paper - threaded regions -+ worldData.wakeupInactiveRemainingFlying--; // Paper - threaded regions ++ if (inactiveFor > config.wakeUpInactiveFlyingEvery && worldData.wakeupInactiveRemainingFlying > 0) { // Folia - threaded regions ++ worldData.wakeupInactiveRemainingFlying--; // Folia - threaded regions return config.wakeUpInactiveFlyingFor; } } else if (entity.activationType == ActivationType.MONSTER || entity.activationType == ActivationType.RAIDER) { - if (inactiveFor > config.wakeUpInactiveMonstersEvery && world.wakeupInactiveRemainingMonsters > 0) { - world.wakeupInactiveRemainingMonsters--; -+ if (inactiveFor > config.wakeUpInactiveMonstersEvery && worldData.wakeupInactiveRemainingMonsters > 0) { // Paper - threaded regions -+ worldData.wakeupInactiveRemainingMonsters--; // Paper - threaded regions ++ if (inactiveFor > config.wakeUpInactiveMonstersEvery && worldData.wakeupInactiveRemainingMonsters > 0) { // Folia - threaded regions ++ worldData.wakeupInactiveRemainingMonsters--; // Folia - threaded regions return config.wakeUpInactiveMonstersFor; } } @@ -20380,11 +20380,11 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 - world.wakeupInactiveRemainingVillagers = Math.min(world.wakeupInactiveRemainingVillagers + 1, world.spigotConfig.wakeUpInactiveVillagers); - world.wakeupInactiveRemainingMonsters = Math.min(world.wakeupInactiveRemainingMonsters + 1, world.spigotConfig.wakeUpInactiveMonsters); - world.wakeupInactiveRemainingFlying = Math.min(world.wakeupInactiveRemainingFlying + 1, world.spigotConfig.wakeUpInactiveFlying); -+ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Paper - threaded regions -+ worldData.wakeupInactiveRemainingAnimals = Math.min(worldData.wakeupInactiveRemainingAnimals + 1, world.spigotConfig.wakeUpInactiveAnimals); // Paper - threaded regions -+ worldData.wakeupInactiveRemainingVillagers = Math.min(worldData.wakeupInactiveRemainingVillagers + 1, world.spigotConfig.wakeUpInactiveVillagers); // Paper - threaded regions -+ worldData.wakeupInactiveRemainingMonsters = Math.min(worldData.wakeupInactiveRemainingMonsters + 1, world.spigotConfig.wakeUpInactiveMonsters); // Paper - threaded regions -+ worldData.wakeupInactiveRemainingFlying = Math.min(worldData.wakeupInactiveRemainingFlying + 1, world.spigotConfig.wakeUpInactiveFlying); // Paper - threaded regions ++ io.papermc.paper.threadedregions.RegionisedWorldData worldData = world.getCurrentWorldData(); // Folia - threaded regions ++ worldData.wakeupInactiveRemainingAnimals = Math.min(worldData.wakeupInactiveRemainingAnimals + 1, world.spigotConfig.wakeUpInactiveAnimals); // Folia - threaded regions ++ worldData.wakeupInactiveRemainingVillagers = Math.min(worldData.wakeupInactiveRemainingVillagers + 1, world.spigotConfig.wakeUpInactiveVillagers); // Folia - threaded regions ++ worldData.wakeupInactiveRemainingMonsters = Math.min(worldData.wakeupInactiveRemainingMonsters + 1, world.spigotConfig.wakeUpInactiveMonsters); // Folia - threaded regions ++ worldData.wakeupInactiveRemainingFlying = Math.min(worldData.wakeupInactiveRemainingFlying + 1, world.spigotConfig.wakeUpInactiveFlying); // Folia - threaded regions final ServerChunkCache chunkProvider = (ServerChunkCache) world.getChunkSource(); // Paper end @@ -20393,10 +20393,10 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 maxRange = Math.min( ( world.spigotConfig.simulationDistance << 4 ) - 8, maxRange ); - for ( Player player : world.players() ) -+ for ( Player player : world.getLocalPlayers() ) // Paper - region threading ++ for ( Player player : world.getLocalPlayers() ) // Folia - region threading { - player.activatedTick = MinecraftServer.currentTick; -+ player.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - region threading ++ player.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - region threading if ( world.spigotConfig.ignoreSpectatorActivation && player.isSpectator() ) { continue; @@ -20405,7 +20405,7 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 for (int i = 0; i < entities.size(); i++) { Entity entity = entities.get(i); - ActivationRange.activateEntity(entity); -+ if (io.papermc.paper.util.TickThread.isTickThreadFor(entity)) ActivationRange.activateEntity(entity); // Paper - region ticking ++ if (io.papermc.paper.util.TickThread.isTickThreadFor(entity)) ActivationRange.activateEntity(entity); // Folia - region ticking } // Paper end } @@ -20414,18 +20414,18 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 private static void activateEntity(Entity entity) { - if ( MinecraftServer.currentTick > entity.activatedTick ) -+ if ( io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() > entity.activatedTick ) // Paper - threaded regions ++ if ( io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() > entity.activatedTick ) // Folia - threaded regions { if ( entity.defaultActivationState ) { - entity.activatedTick = MinecraftServer.currentTick; -+ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - threaded regions ++ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - threaded regions return; } if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) { - entity.activatedTick = MinecraftServer.currentTick; -+ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - threaded regions ++ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - threaded regions } } } @@ -20434,11 +20434,11 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 return 2; } - if (entity.activatedImmunityTick >= MinecraftServer.currentTick) { -+ if (entity.activatedImmunityTick >= io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick()) { // Paper - threaded regions ++ if (entity.activatedImmunityTick >= io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick()) { // Folia - threaded regions return 1; } - long inactiveFor = MinecraftServer.currentTick - entity.activatedTick; -+ long inactiveFor = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick; // Paper - threaded regions ++ long inactiveFor = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick; // Folia - threaded regions // Paper end // quick checks. if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByFluid()) ) // Paper @@ -20447,33 +20447,33 @@ index e881584d38dc354204479863f004e974a0ac6c07..589b4093a0243b3fab2febcafc36b3d7 // Paper end - boolean isActive = entity.activatedTick >= MinecraftServer.currentTick; -+ boolean isActive = entity.activatedTick >= io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Paper - threaded regions ++ boolean isActive = entity.activatedTick >= io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick(); // Folia - threaded regions entity.isTemporarilyActive = false; // Paper // Should this entity tick? if ( !isActive ) { - if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 ) -+ if ( ( io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick - 1 ) % 20 == 0 ) // Paper - threaded regions ++ if ( ( io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() - entity.activatedTick - 1 ) % 20 == 0 ) // Folia - threaded regions { // Check immunities every 20 ticks. // Paper start int immunity = checkEntityImmunities(entity); if (immunity >= 0) { - entity.activatedTick = MinecraftServer.currentTick + immunity; -+ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + immunity; // Paper - threaded regions ++ entity.activatedTick = io.papermc.paper.threadedregions.RegionisedServer.getCurrentTick() + immunity; // Folia - threaded regions } else { entity.isTemporarilyActive = true; } diff --git a/src/main/java/org/spigotmc/SpigotCommand.java b/src/main/java/org/spigotmc/SpigotCommand.java -index 3112a8695639c402e9d18710acbc11cff5611e9c..e113e9a5f7acf6e7310d367e32edb35a7c272d06 100644 +index 3112a8695639c402e9d18710acbc11cff5611e9c..72976bdb3db5d0066599272fab1055b2e20c5b26 100644 --- a/src/main/java/org/spigotmc/SpigotCommand.java +++ b/src/main/java/org/spigotmc/SpigotCommand.java @@ -29,6 +29,7 @@ public class SpigotCommand extends Command { Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues."); Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); -+ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Paper - region threading ++ io.papermc.paper.threadedregions.RegionisedServer.getInstance().addTask(() -> { // Folia - region threading MinecraftServer console = MinecraftServer.getServer(); org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); for (ServerLevel world : console.getAllLevels()) { @@ -20481,12 +20481,12 @@ index 3112a8695639c402e9d18710acbc11cff5611e9c..e113e9a5f7acf6e7310d367e32edb35a console.server.reloadCount++; Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); -+ }); // Paper - region threading ++ }); // Folia - region threading } return true; diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java -index 612c3169c3463d702b85975e1db79ae6e47d60d0..65441b5226255f85b9f790b9e7b22d209fba74b5 100644 +index 612c3169c3463d702b85975e1db79ae6e47d60d0..6f77134ba451e7bd6bcba1000134ce8a2c762979 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -228,7 +228,7 @@ public class SpigotConfig @@ -20494,7 +20494,7 @@ index 612c3169c3463d702b85975e1db79ae6e47d60d0..65441b5226255f85b9f790b9e7b22d20 SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript ); SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) ); - SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) ); -+ //SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) ); // Paper - region threading ++ //SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) ); // Folia - region threading // WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to after paper config initialization } @@ -20503,12 +20503,12 @@ index 612c3169c3463d702b85975e1db79ae6e47d60d0..65441b5226255f85b9f790b9e7b22d20 private static void tpsCommand() { - SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); -+ //SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); // Paper - region threading ++ //SpigotConfig.commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); // Folia - region threading } public static int playerSample; diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index 5503ad6a93d331771a0e92c0da6adedf2ac81aff..9be6a8acf4924cc9480c57f1eea418536404c8fd 100644 +index 5503ad6a93d331771a0e92c0da6adedf2ac81aff..a06408a10cb24c203cfc25f25ccd37ac1a587a1a 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -425,7 +425,7 @@ public class SpigotWorldConfig @@ -20516,7 +20516,7 @@ index 5503ad6a93d331771a0e92c0da6adedf2ac81aff..9be6a8acf4924cc9480c57f1eea41853 } - public int currentPrimedTnt = 0; -+ //public int currentPrimedTnt = 0; // Paper - region threading - moved to regionised world data ++ //public int currentPrimedTnt = 0; // Folia - region threading - moved to regionised world data public int maxTntTicksPerTick; private void maxTntPerTick() { if ( SpigotConfig.version < 7 )