From bea112c6913b98dce83610ddac1e61abace64a1b Mon Sep 17 00:00:00 2001 From: MrHua269 Date: Sun, 31 Mar 2024 00:53:03 +0000 Subject: [PATCH] Rework WorldData patches --- patches/server/0003-Basement-patches.patch | 858 ------------------ ...eck-if-the-polling-thread-is-global.patch} | 4 +- .../server/0005-Rewrite-world-data-pool.patch | 263 ------ ...6-Portal-events-and-teleport-events.patch} | 0 .../0007-Rework-WorldData-patches.patch | 202 +++++ ...-chunk-pos-shifting-in-WorldDataPool.patch | 19 - .../server/0009-Fix-incorrect-shifting.patch | 41 - 7 files changed, 204 insertions(+), 1183 deletions(-) rename patches/server/{0006-Disable-thread-check-if-the-polling-thread-is-global.patch => 0005-Disable-thread-check-if-the-polling-thread-is-global.patch} (89%) delete mode 100644 patches/server/0005-Rewrite-world-data-pool.patch rename patches/server/{0007-Portal-events-and-teleport-events.patch => 0006-Portal-events-and-teleport-events.patch} (100%) create mode 100644 patches/server/0007-Rework-WorldData-patches.patch delete mode 100644 patches/server/0008-Fix-incorrect-chunk-pos-shifting-in-WorldDataPool.patch delete mode 100644 patches/server/0009-Fix-incorrect-shifting.patch diff --git a/patches/server/0003-Basement-patches.patch b/patches/server/0003-Basement-patches.patch index 8e4ff15..0842f9b 100644 --- a/patches/server/0003-Basement-patches.patch +++ b/patches/server/0003-Basement-patches.patch @@ -147,46 +147,6 @@ index 190c5f0b02a3d99054704ae1afbffb3498ddffe1..8106114c49e4589a70bf00430a83a132 final E lastRet = this.lastRet; if (lastRet == null) { -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 5bef4f50082e56b89239cfd62dd7429926b71c09..2d70632ccbc55f58c4a3ad8d39eeaa07707878de 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 -@@ -18,6 +18,7 @@ import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.entity.EntityInLevelCallback; - import net.minecraft.world.level.entity.EntityTypeTest; - import net.minecraft.world.level.entity.LevelCallback; -@@ -443,7 +444,7 @@ public final class EntityLookup implements LevelEntityGetter { - - entity.setLevelCallback(new EntityCallback(entity)); - -- this.world.getCurrentWorldData().addEntity(entity); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(entity).addEntity(entity); - - this.entityStatusChange(entity, slices, Visibility.HIDDEN, getEntityStatus(entity), false, !fromDisk, false); - -@@ -888,7 +889,7 @@ public final class EntityLookup implements LevelEntityGetter { - @Override - public void onMove() { - final Entity entity = this.entity; -- final io.papermc.paper.threadedregions.RegionizedWorldData regionData = entity.level().getCurrentWorldData(); // Folia - region threading -+ final io.papermc.paper.threadedregions.RegionizedWorldData regionData = Level.WORLD_DATA_POOL.getDataAnyThread(entity); // Folia - region threading - final Visibility oldVisibility = getEntityStatus(entity); - final ChunkEntitySlices newSlices = EntityLookup.this.moveEntity(this.entity); - if (newSlices == null) { -@@ -918,7 +919,8 @@ public final class EntityLookup implements LevelEntityGetter { - this.entity.setLevelCallback(NoOpCallback.INSTANCE); - - // only AFTER full removal callbacks, so that thread checking will work. // Folia - region threading -- EntityLookup.this.world.getCurrentWorldData().removeEntity(entity); // Folia - region threading -+ //EntityLookup.this.world.getCurrentWorldData().removeEntity(entity); // Folia - region threading //Molia -+ Level.WORLD_DATA_POOL.getDataAnyThread(entity).removeEntity(entity); - } - } - 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 0d8b2a4127e8c8e4970d220b8a2240490da6e7df..5eeda811ca67731b802f8d5b52cb76930a7802a1 100644 --- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java @@ -642,132 +602,6 @@ index ab5f832aafc479eca1c5da012e180d6374e32325..f44277006412ce5db83d6d2f7bf871b6 } /** -diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -index 78c50292fb25e8703e9c91db892f05456f07d72f..68c790d69c336fcaec01dc990ff61f17330098da 100644 ---- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -@@ -8,17 +8,28 @@ import io.papermc.paper.configuration.GlobalConfiguration; - import it.unimi.dsi.fastutil.longs.Long2ReferenceMap; - import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; -+import it.unimi.dsi.fastutil.objects.Reference2ReferenceMaps; - import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; - import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import net.minecraft.core.BlockPos; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.chunk.LevelChunk; -+import org.bukkit.Bukkit; -+import org.bukkit.World; - import org.slf4j.Logger; - import java.util.Iterator; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicInteger; - import java.util.concurrent.atomic.AtomicLong; -+import java.util.concurrent.locks.ReadWriteLock; -+import java.util.concurrent.locks.ReentrantReadWriteLock; - import java.util.function.BooleanSupplier; - -+import static org.bukkit.craftbukkit.scheduler.CraftScheduler.MINECRAFT; -+ - public final class TickRegions implements ThreadedRegionizer.RegionCallbacks { - - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -156,6 +167,32 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks> 4,pos.getY() >> 4).getData().getRegionStats().updateFrom(Level.WORLD_DATA_POOL.getDataAnyThread(level,pos)); -+ } -+ -+ static void updateCurrentRegion(LevelChunk chunk) { -+ final ThreadedRegionizer.ThreadedRegion got = ((ServerLevel) chunk.level).regioniser.getRegionAtUnsynchronised(chunk.getPos().getMiddleBlockX(),chunk.getPos().getMiddleBlockZ()); -+ if (got != null) { -+ got.getData().getRegionStats().updateFrom(Level.WORLD_DATA_POOL.getDataAnyThread(chunk.getPos().x,chunk.getPos().z,chunk.level)); -+ }else{ -+ Bukkit.getRegionScheduler().execute(MINECRAFT,chunk.level.getWorld(),chunk.getPos().x,chunk.getPos().z,()->{ -+ TickRegionScheduler.getCurrentRegion().getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); -+ }); -+ } -+ } -+ -+ static void updateCurrentRegion(Entity entity) { -+ final ThreadedRegionizer.ThreadedRegion got = ((ServerLevel) entity.level()).regioniser.getRegionAtUnsynchronised(entity.sectionX,entity.sectionZ); -+ if (got != null) { -+ got.getData().getRegionStats().updateFrom(Level.WORLD_DATA_POOL.getDataAnyThread(entity)); -+ }else{ -+ Bukkit.getRegionScheduler().execute(MINECRAFT,entity.getBukkitEntity().getLocation(),()->{ -+ TickRegionScheduler.getCurrentRegion().getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); -+ }); -+ } -+ } - } - - public static final class TickRegionData implements ThreadedRegionizer.ThreadedRegionData { -@@ -168,7 +205,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks, Object> regionizedData = new Reference2ReferenceOpenHashMap<>(); -+ private final Reference2ReferenceMap, Object> regionizedData = Reference2ReferenceMaps.synchronize(new Reference2ReferenceOpenHashMap<>()); - - // tick data - private ConcreteRegionTickHandle tickHandle = new ConcreteRegionTickHandle(this, SchedulerThreadPool.DEADLINE_NOT_SET); -@@ -213,12 +250,12 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks T getRegionizedData(final RegionizedData regionizedData) { -+ public T getRegionizedData(final RegionizedData regionizedData) { - return (T)this.regionizedData.get(regionizedData); - } - - T getOrCreateRegionizedData(final RegionizedData regionizedData) { -- T ret = (T)this.regionizedData.get(regionizedData); -+ T ret = (T) this.regionizedData.get(regionizedData); - - if (ret != null) { - return ret; -@@ -245,7 +282,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks, Object>> dataIterator = this.regionizedData.reference2ReferenceEntrySet().fastIterator(); -+ for (final Iterator, Object>> dataIterator = this.regionizedData.reference2ReferenceEntrySet().iterator(); - dataIterator.hasNext();) { - final Reference2ReferenceMap.Entry, Object> regionDataEntry = dataIterator.next(); - final RegionizedData data = regionDataEntry.getKey(); -@@ -312,8 +349,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks, Object>> iterator = this.regionizedData.reference2ReferenceEntrySet().fastIterator(); -- iterator.hasNext();) { -+ for (final Iterator, Object>> iterator = this.regionizedData.reference2ReferenceEntrySet().iterator(); iterator.hasNext();) { - final Reference2ReferenceMap.Entry, Object> entry = iterator.next(); - final RegionizedData regionizedData = entry.getKey(); - final Object from = entry.getValue(); -@@ -321,7 +357,6 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks)regionizedData).getCallback().merge(from, to, fromTickOffset); - } -- - // chunk holder manager data - this.holderManagerRegionData.merge(into.getData().holderManagerRegionData, fromTickOffset); - -@@ -375,7 +410,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks list = new ObjectArrayList(); -- Iterator iterator = this.getCurrentWorldData().getNavigatingMobs(); // Folia - region threading -+ final IteratorSafeOrderedReferenceSet navigationMobs = Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).getNavigatingMobs(); - -- while (iterator.hasNext()) { -- // CraftBukkit start - fix SPIGOT-6362 -- Mob entityinsentient; -- try { -- entityinsentient = (Mob) iterator.next(); -- } catch (java.util.ConcurrentModificationException ex) { -- // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register -- // In this case we just run the update again across all the iterators as the chunk will then be loaded -- // As this is a relative edge case it is much faster than copying navigators (on either read or write) -- this.sendBlockUpdated(pos, oldState, newState, flags); -- return; -- } -- // CraftBukkit end -- PathNavigation navigationabstract = entityinsentient.getNavigation(); -+ Iterator iterator; -+ synchronized (navigationMobs){ -+ iterator = navigationMobs.iterator(); // Folia - region threading - -- if (navigationabstract.shouldRecomputePath(pos)) { -- list.add(navigationabstract); -+ while (iterator.hasNext()) { -+ // CraftBukkit start - fix SPIGOT-6362 -+ Mob entityinsentient; -+ try { -+ entityinsentient = (Mob) iterator.next(); -+ } catch (java.util.ConcurrentModificationException ex) { -+ // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register -+ // In this case we just run the update again across all the iterators as the chunk will then be loaded -+ // As this is a relative edge case it is much faster than copying navigators (on either read or write) -+ this.sendBlockUpdated(pos, oldState, newState, flags); -+ return; -+ } -+ // CraftBukkit end -+ PathNavigation navigationabstract = entityinsentient.getNavigation(); -+ -+ if (navigationabstract.shouldRecomputePath(pos)) { -+ list.add(navigationabstract); -+ } - } - } - -@@ -2076,23 +2083,24 @@ public class ServerLevel extends Level implements WorldGenLevel { - - @Override - public void updateNeighborsAt(BlockPos pos, Block sourceBlock) { -- 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 -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,pos); -+ if (data.captureBlockStates) { return; } // Paper - Cancel all physics during placement // Folia - region threading -+ data.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null); // Folia - region threading - } - - @Override - public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block sourceBlock, Direction direction) { -- this.getCurrentWorldData().neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, direction); // Folia - region threading - } - - @Override - public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos sourcePos) { -- this.getCurrentWorldData().neighborUpdater.neighborChanged(pos, sourceBlock, sourcePos); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).neighborUpdater.neighborChanged(pos, sourceBlock, sourcePos); // Folia - region threading - } - - @Override - public void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { -- this.getCurrentWorldData().neighborUpdater.neighborChanged(state, pos, sourceBlock, sourcePos, notify); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).neighborUpdater.neighborChanged(state, pos, sourceBlock, sourcePos, notify); // Folia - region threading - } - - @Override -@@ -2138,7 +2146,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - - @Override - public void blockEvent(BlockPos pos, Block block, int type, int data) { -- this.getCurrentWorldData().pushBlockEvent(new BlockEventData(pos, block, type, data)); // Folia - regionised ticking -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).pushBlockEvent(new BlockEventData(pos, block, type, data)); // Folia - regionised ticking - } - - private void runBlockEvents() { -@@ -2727,7 +2735,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - public void blockUpdated(BlockPos pos, Block block) { - if (!this.isDebug()) { - // CraftBukkit start -- if (this.getCurrentWorldData().populating) { // Folia - region threading -+ if (Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).populating) { // Folia - region threading - return; - } - // CraftBukkit end -@@ -2942,11 +2950,11 @@ public class ServerLevel extends Level implements WorldGenLevel { - - public void onTickingStart(Entity entity) { - if (entity instanceof net.minecraft.world.entity.Marker && !paperConfig().entities.markers.tick) return; // Paper - Configurable marker ticking -- ServerLevel.this.getCurrentWorldData().addEntityTickingEntity(entity); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(entity).addEntityTickingEntity(entity); // Folia - region threading - } - - public void onTickingEnd(Entity entity) { -- ServerLevel.this.getCurrentWorldData().removeEntityTickingEntity(entity); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(entity).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; -@@ -2957,7 +2965,8 @@ public class ServerLevel extends Level implements WorldGenLevel { - - public void onTrackingStart(Entity entity) { - org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot -- ServerLevel.this.getCurrentWorldData().addLoadedEntity(entity); // Folia - region threading -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(entity); -+ data.addLoadedEntity(entity); // Folia - region threading - // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true - if (entity instanceof ServerPlayer) { - ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -2975,7 +2984,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); - } - -- ServerLevel.this.getCurrentWorldData().addNavigatingMob(entityinsentient); // Folia - region threading -+ data.addNavigatingMob(entityinsentient); // Folia - region threading - } - - if (entity instanceof EnderDragon) { -@@ -3010,7 +3019,8 @@ public class ServerLevel extends Level implements WorldGenLevel { - - public void onTrackingEnd(Entity entity) { - org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot -- ServerLevel.this.getCurrentWorldData().removeLoadedEntity(entity); -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(entity); -+ data.removeLoadedEntity(entity); - // Spigot start - if ( entity instanceof Player ) - { -@@ -3072,7 +3082,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - Util.logAndPauseIfInIde("onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")); - } - -- ServerLevel.this.getCurrentWorldData().removeNavigatingMob(entityinsentient); // Folia - region threading -+ data.removeNavigatingMob(entityinsentient); // Folia - region threading - } - - if (entity instanceof EnderDragon) { -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f2068e7608ed765e35759eb981db6c95b07a06d8..22fbafe6f4f59492f12555d20beced43ffb7df0d 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1348,7 +1348,7 @@ public class ServerPlayer extends Player { - ServerPlayer.this.reset(); - } - // must be manually removed from connections, delay until after reset() so that we do not trip any thread checks -- this.serverLevel().getCurrentWorldData().connections.remove(this.connection.connection); -+ Level.WORLD_DATA_POOL.getDataAnyThread(this).connections.remove(this.connection.connection); - - BlockPos respawnPos = this.getRespawnPosition(); - float respawnAngle = this.getRespawnAngle(); -diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 100293099156978ff701bc6c9d8df94ba8282021..92d61b242128cde0989a720adfb28ebd738a6c1f 100644 ---- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -+++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -1,7 +1,9 @@ - package net.minecraft.server.level; - -+import ca.spottedleaf.starlight.common.light.StarLightInterface; - import com.mojang.datafixers.util.Pair; - import com.mojang.logging.LogUtils; -+import io.papermc.paper.threadedregions.RegionizedServer; - import it.unimi.dsi.fastutil.objects.ObjectArrayList; - import it.unimi.dsi.fastutil.objects.ObjectList; - import it.unimi.dsi.fastutil.objects.ObjectListIterator; -@@ -15,6 +17,7 @@ import net.minecraft.core.SectionPos; - import net.minecraft.util.thread.ProcessorHandle; - import net.minecraft.util.thread.ProcessorMailbox; - import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.LightLayer; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.DataLayer; -@@ -161,7 +164,7 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - } - updateFuture.isTicketAdded = true; - -- final int references = this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.addTo(key, 1); // Folia - region threading -+ final int references = Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ,this.chunkMap.level).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); -@@ -169,15 +172,15 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - - // Folia start - region threading - updateFuture.onComplete.thenAccept((final Void ignore) -> { -- io.papermc.paper.threadedregions.RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( -+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( - this.chunkMap.level, chunkX, chunkZ, () -> { -- final int newReferences = this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.get(key); -+ final int newReferences = Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ,this.chunkMap.level).chunksBeingWorkedOn.get(key); - if (newReferences == 1) { -- this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.remove(key); -+ Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ, this.chunkMap.level).chunksBeingWorkedOn.remove(key); - final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -- world.getChunkSource().removeRegionTicket(ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); -+ world.getChunkSource().removeRegionTicket(StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); - } else { -- this.chunkMap.level.getCurrentWorldData().chunksBeingWorkedOn.put(key, newReferences - 1); -+ Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ, this.chunkMap.level).chunksBeingWorkedOn.put(key, newReferences - 1); - } - } - ); diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java index 83701fbfaa56a232593ee8f11a3afb8941238bfa..5815afa3a85e23b25aa04acb5ac61bc39892b658 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java @@ -1661,359 +1174,6 @@ index 8f40db062159dea7761a5663edef997a113e828b..4138f9c8cde185b8db7c07bdaf43103a // restore passenger tree passengerTree.restore(); passengerTree.adjustRiders(true); -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 84b47e6cea7ed9730f9c450ba8ba3167d71b2cc9..fe1c93b546873a75f354575bcf1751c6812eb5d8 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3569,7 +3569,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.pushEntities(); - this.level().getProfiler().pop(); - // Paper start - Add EntityMoveEvent -- if (((ServerLevel) this.level()).getCurrentWorldData().hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { // Folia - region threading -+ if (Level.WORLD_DATA_POOL.getDataAnyThread(this).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { // Folia - region threading - if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { - Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO); - Location to = new Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -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 c366da764e2e11018460430595c14b17480c6da7..c79d86e590ef90be025ce9b78f1e8f48d787b5b5 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -5,6 +5,7 @@ import java.util.Iterator; - import java.util.UUID; - import javax.annotation.Nullable; - -+import io.papermc.paper.threadedregions.RegionizedServer; - import io.papermc.paper.threadedregions.TickRegionScheduler; - import net.minecraft.core.BlockPos; - import net.minecraft.nbt.CompoundTag; -@@ -54,7 +55,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { - private int loadedLifetime = 0; - @Override - public void setPos(double x, double y, double z) { -- long currentTick = TickRegionScheduler.getCurrentRegion().getData().getCurrentTick(); -+ long currentTick = RegionizedServer.isGlobalTickThread() ? RegionizedServer.getGlobalTickData().getCurrentTick() : TickRegionScheduler.getCurrentRegion().getData().getCurrentTick(); - if (loadedTick != currentTick) { - loadedTick = currentTick; - loadedThisTick = 0; -diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index b937437d4446fbf80376399067fd04dc7f95e64a..dd0118fed3a3ccdd5d7ca292f3213618499c8d6f 100644 ---- a/src/main/java/net/minecraft/world/level/Explosion.java -+++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -870,7 +870,7 @@ public class Explosion { - if (!this.level.paperConfig().environment.optimizeExplosions) { - return this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise explosions - } -- io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.level.getCurrentWorldData(); // Folia - region threading -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = Level.WORLD_DATA_POOL.getDataAnyThread(entity); - CacheKey key = new CacheKey(this, entity.getBoundingBox()); - Float blockDensity = worldData.explosionDensityCache.get(key); // Folia - region threading - if (blockDensity == null) { -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index a9921af214c596ef2601ccdbf37b4234bcf4ea1d..3deeea9365601e1ce120d03f807bbffeb06b7c1a 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -10,6 +10,8 @@ import java.util.function.Consumer; - import java.util.function.Predicate; - import java.util.function.Supplier; - import javax.annotation.Nullable; -+ -+import me.earthme.lightingluminol.pool.WorldDataPool; - import net.minecraft.CrashReport; - import net.minecraft.CrashReportCategory; - import net.minecraft.ReportedException; -@@ -104,6 +106,7 @@ import org.bukkit.event.world.GenericGameEvent; - - public abstract class Level implements LevelAccessor, AutoCloseable { - -+ public static final WorldDataPool WORLD_DATA_POOL = new WorldDataPool(); //DirtyMolia - public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); - public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, new ResourceLocation("overworld")); - public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, new ResourceLocation("the_nether")); -@@ -227,6 +230,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return ret; - } - -+ public io.papermc.paper.threadedregions.RegionizedWorldData getCurrentWorldDataUnsafe() { -+ final io.papermc.paper.threadedregions.RegionizedWorldData ret = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionizedWorldData(); -+ if (ret == null) { -+ return ret; -+ } -+ Level world = ret.world; -+ if (world != this) { -+ return null; -+ } -+ return ret; -+ } -+ - @Override - public List getLocalPlayers() { - return this.getCurrentWorldData().getLocalPlayers(); -@@ -871,8 +886,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - @Nullable - public final BlockState getBlockStateIfLoaded(BlockPos pos) { - // CraftBukkit start - tree generation -- if (this.getCurrentWorldData().captureTreeGeneration) { // Folia - region threading -- CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(pos); // Folia - region threading -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,pos); -+ if (data.captureTreeGeneration) { // Folia - region threading -+ CraftBlockState previous = data.capturedBlockStates.get(pos); // Folia - region threading - if (previous != null) { - return previous.getHandle(); - } -@@ -935,7 +951,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - @Override - public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { - io.papermc.paper.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // Folia - region threading -- io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.getCurrentWorldData(); // Folia - region threading -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = Level.WORLD_DATA_POOL.getDataAnyThread(this,pos); // Folia - region threading - // CraftBukkit start - tree generation - if (worldData.captureTreeGeneration) { // Folia - region threading - // Paper start - Protect Bedrock and End Portal/Frames from being destroyed -@@ -1056,6 +1072,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - } - -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,blockposition); - if ((i & 16) == 0 && j > 0) { - int k = i & -34; - -@@ -1063,7 +1080,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - 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(); - boolean cancelledUpdates = false; // Paper - Fix block place logic -- if (world != null && ((ServerLevel)this).getCurrentWorldData().hasPhysicsEvent) { // Paper - BlockPhysicsEvent // Folia - region threading -+ if (world != null && data.hasPhysicsEvent) { // Paper - BlockPhysicsEvent // Folia - region threading - BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); - this.getCraftServer().getPluginManager().callEvent(event); - -@@ -1077,7 +1094,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - - // CraftBukkit start - SPIGOT-5710 -- if (!this.getCurrentWorldData().preventPoiUpdated) { // Folia - region threading -+ if (!data.preventPoiUpdated) { // Folia - region threading - this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); - } - // CraftBukkit end -@@ -1161,7 +1178,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - @Override - public void neighborShapeChanged(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) { -- this.getCurrentWorldData().neighborUpdater.shapeUpdate(direction, neighborState, pos, neighborPos, flags, maxUpdateDepth); // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,pos).neighborUpdater.shapeUpdate(direction, neighborState, pos, neighborPos, flags, maxUpdateDepth); // Folia - region threading - } - - @Override -@@ -1212,8 +1229,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - @Override - public BlockState getBlockState(BlockPos pos) { - // CraftBukkit start - tree generation -- if (this.getCurrentWorldData().captureTreeGeneration) { // Folia - region threading -- CraftBlockState previous = this.getCurrentWorldData().capturedBlockStates.get(pos); // Paper // Folia - region threading -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,pos); -+ if (data.captureTreeGeneration) { // Folia - region threading -+ CraftBlockState previous = data.capturedBlockStates.get(pos); // Paper // Folia - region threading - if (previous != null) { - return previous.getHandle(); - } -@@ -1310,7 +1328,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - } - - public void addBlockEntityTicker(TickingBlockEntity ticker) { -- ((ServerLevel)this).getCurrentWorldData().addBlockEntityTicker(ticker); // Folia - regionised ticking -+ Level.WORLD_DATA_POOL.getDataAnyThread(this,ticker.getPos()).addBlockEntityTicker(ticker); // Folia - regionised ticking - } - - protected void tickBlockEntities() { -@@ -1336,22 +1354,24 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - int tilesThisCycle = 0; - var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll - toRemove.add(null); // Paper - Fix MC-117075 -- 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 end -- -- if (tickingblockentity.isRemoved()) { -- // Spigot start -- tilesThisCycle--; -- toRemove.add(tickingblockentity); // Paper - Fix MC-117075; use removeAll -+ synchronized(blockEntityTickers) { -+ 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 end -- } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { -- tickingblockentity.tick(); -- // Paper start - execute chunk tasks during tick -- if ((i & 7) == 0) { // Folia - regionised ticking -- MinecraftServer.getServer().executeMidTickTasks(); -+ -+ if (tickingblockentity.isRemoved()) { -+ // Spigot start -+ tilesThisCycle--; -+ toRemove.add(tickingblockentity); // Paper - Fix MC-117075; use removeAll -+ // Spigot end -+ } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { -+ tickingblockentity.tick(); -+ // Paper start - execute chunk tasks during tick -+ if ((i & 7) == 0) { // Folia - regionised ticking -+ MinecraftServer.getServer().executeMidTickTasks(); -+ } -+ // Paper end - execute chunk tasks during tick - } -- // Paper end - execute chunk tasks during tick - } - } - blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 // Folia - regionised ticking -@@ -1482,7 +1502,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - // Folia end - region threading - // Paper start - Perf: Optimize capturedTileEntities lookup - net.minecraft.world.level.block.entity.BlockEntity blockEntity; -- if (!this.getCurrentWorldData().capturedTileEntities.isEmpty() && (blockEntity = this.getCurrentWorldData().capturedTileEntities.get(blockposition)) != null) { // Folia - region threading -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,blockposition); -+ if (!data.capturedTileEntities.isEmpty() && (blockEntity = data.capturedTileEntities.get(blockposition)) != null) { // Folia - region threading - return blockEntity; - } - // Paper end - Perf: Optimize capturedTileEntities lookup -@@ -1495,8 +1516,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - if (!this.isOutsideBuildHeight(blockposition)) { - // CraftBukkit start -- if (this.getCurrentWorldData().captureBlockStates) { // Folia - region threading -- this.getCurrentWorldData().capturedTileEntities.put(blockposition.immutable(), blockEntity); // Folia - region threading -+ var data = Level.WORLD_DATA_POOL.getDataAnyThread(this,blockposition); -+ if (data.captureBlockStates) { // Folia - region threading -+ data.capturedTileEntities.put(blockposition.immutable(), blockEntity); // Folia - region threading - return; - } - // CraftBukkit end -@@ -1637,13 +1659,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - @Override // Folia - region threading - public long getGameTime() { - // Dumb world gen thread calls this for some reason. So, check for null. -- io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.getCurrentWorldData(); -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.getCurrentWorldDataUnsafe(); - return worldData == null ? this.getLevelData().getGameTime() : worldData.getTickData().nonRedstoneGameTime(); - } - - public long getDayTime() { - // Dumb world gen thread calls this for some reason. So, check for null. -- io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.getCurrentWorldData(); -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.getCurrentWorldDataUnsafe(); - return worldData == null ? this.getLevelData().getDayTime() : worldData.getTickData().dayTime(); - } - -diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java -index 11ba667fd0fe79513d505b34eb0cf1ec66fc2842..258d661e29c33e77fdab8f0cdddc866c7b3d95a0 100644 ---- a/src/main/java/net/minecraft/world/level/block/BedBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java -@@ -367,7 +367,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock - - world.setBlock(blockposition1, (BlockState) state.setValue(BedBlock.PART, BedPart.HEAD), 3); - // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states -- if (world.getCurrentWorldData().captureBlockStates) { // Folia - region threading -+ if (Level.WORLD_DATA_POOL.getDataAnyThread(world,pos).captureBlockStates) { // Folia - region threading - return; - } - // CraftBukkit end -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 6df3913145aaf37f9a1b7dc77fed12f6952d77e6..c6764e08dcb29a4835b5782408e96c5df3a45d33 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 { - - entityitem.setDefaultPickUpDelay(); - // CraftBukkit start -- if (world.getCurrentWorldData().captureDrops != null) { // Folia - region threading -- world.getCurrentWorldData().captureDrops.add(entityitem); // Folia - region threading -+ if (Level.WORLD_DATA_POOL.getDataAnyThread(entityitem).captureDrops != null) { // Folia - region threading -+ Level.WORLD_DATA_POOL.getDataAnyThread(entityitem).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 46c81d73813c6607d95062358e6e3cd05ffe3192..31639efa8c386cd115386fd929c7949b235325d2 100644 ---- a/src/main/java/net/minecraft/world/level/block/BushBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java -@@ -3,8 +3,10 @@ package net.minecraft.world.level.block; - import com.mojang.serialization.MapCodec; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.tags.BlockTags; - import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelAccessor; - import net.minecraft.world.level.LevelReader; - import net.minecraft.world.level.block.state.BlockBehaviour; -@@ -28,7 +30,7 @@ public abstract class BushBlock extends Block { - public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - // CraftBukkit start - if (!state.canSurvive(world, pos)) { -- 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 -+ if (!(world instanceof net.minecraft.server.level.ServerLevel && Level.WORLD_DATA_POOL.getDataAnyThread(((Level) world),pos).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/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index 4fb595a8300ce2b163540603c7a2b002869a84c1..4e4125fc8373ac9cd5ac01b6804fc2a4619d14ad 100644 ---- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -102,7 +102,7 @@ public class DoublePlantBlock extends BushBlock { - - protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { - // CraftBukkit start -- if (((net.minecraft.server.level.ServerLevel)world).getCurrentWorldData().hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper // Folia - region threading -+ if (Level.WORLD_DATA_POOL.getDataAnyThread(world,pos).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/RedstoneTorchBlock.java b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -index 332f606d9a41ab19707f2f11bd43d2880b410180..b1fbd41e183998148ec06556b7851047a1da97a6 100644 ---- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java -@@ -81,7 +81,7 @@ public class RedstoneTorchBlock extends BaseTorchBlock { - public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - boolean flag = this.hasNeighborSignal(world, pos, state); - // Paper start - Faster redstone torch rapid clock removal -- java.util.ArrayDeque redstoneUpdateInfos = world.getCurrentWorldData().redstoneUpdateInfos; // Folia - region threading -+ java.util.ArrayDeque redstoneUpdateInfos = Level.WORLD_DATA_POOL.getDataAnyThread(world,pos).redstoneUpdateInfos; // Folia - region threading - if (redstoneUpdateInfos != null) { - RedstoneTorchBlock.Toggle curr; - while ((curr = redstoneUpdateInfos.peek()) != null && world.getRedstoneGameTime() - curr.when > 60L) { // Folia - region threading -@@ -165,9 +165,9 @@ public class RedstoneTorchBlock extends BaseTorchBlock { - - private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) { - // Paper start - Faster redstone torch rapid clock removal -- java.util.ArrayDeque list = world.getCurrentWorldData().redstoneUpdateInfos; // Folia - region threading -+ java.util.ArrayDeque list = Level.WORLD_DATA_POOL.getDataAnyThread(world,pos).redstoneUpdateInfos; // Folia - region threading - if (list == null) { -- list = world.getCurrentWorldData().redstoneUpdateInfos = new java.util.ArrayDeque<>(); // Folia - region threading -+ list = Level.WORLD_DATA_POOL.getDataAnyThread(world,pos).redstoneUpdateInfos = new java.util.ArrayDeque<>(); // Folia - region threading - } - // Paper end - Faster redstone torch rapid clock removal - -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 4847f7caa9147a63f85a86c1c45500f45ff48fbb..4af607a435888c0e9d45e8ccafef01766a89a3e6 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -470,7 +470,7 @@ public class LevelChunk extends ChunkAccess { - return null; - } 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.getCurrentWorldData().captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Folia - region threading -+ if (!this.level.isClientSide && doPlace && (!Level.WORLD_DATA_POOL.getDataAnyThread(level,blockposition).captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Folia - region threading - iblockdata.onPlace(this.level, blockposition, iblockdata1, flag); - } - -@@ -516,7 +516,7 @@ public class LevelChunk extends ChunkAccess { - @Nullable - public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) { - // CraftBukkit start -- BlockEntity tileentity = this.level.getCurrentWorldData().capturedTileEntities.get(pos); // Folia - region threading -+ BlockEntity tileentity = Level.WORLD_DATA_POOL.getDataAnyThread(level,pos).capturedTileEntities.get(pos); // Folia - region threading - if (tileentity == null) { - tileentity = (BlockEntity) this.blockEntities.get(pos); - } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index ead0e0d84d47b227a79c18ea5e0538705b4ff0f3..6899d579da676b63812d717c6a21c9621bd60619 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2173,15 +1333,6 @@ index e268ef6a373fa0e144104eb7fcfaf7bc9005c987..cd4e721b581300f44ae00516c25c4d87 if (chunkStatus == ChunkStatus.NOISE) { future.join().left().ifPresent(chunk -> net.minecraft.world.level.levelgen.Heightmap.primeHeightmaps(chunk, ChunkStatus.POST_FEATURES)); } -@@ -816,7 +821,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - @Override - public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { - io.papermc.paper.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // Folia - region threading -- io.papermc.paper.threadedregions.RegionizedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = Level.WORLD_DATA_POOL.getDataAnyThread(loc); // Folia - region threading - worldData.captureTreeGeneration = true; // Folia - region threading - worldData.captureBlockStates = true; // Folia - region threading - boolean grownTree = this.generateTree(loc, type); @@ -868,7 +873,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override @@ -2447,15 +1598,6 @@ index b451b9df3233355fb16092edc3a4dd63d7d2ff14..c8544663e8f60bf8e4ecec53ddaa85ec import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Blocks; -@@ -592,7 +593,7 @@ 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.RegionizedWorldData worldData = world.getCurrentWorldData(); // Folia - region threading -+ io.papermc.paper.threadedregions.RegionizedWorldData worldData = Level.WORLD_DATA_POOL.getDataAnyThread(world,position); // Folia - region threading - // SPIGOT-6895: Call StructureGrowEvent and BlockFertilizeEvent - worldData.captureTreeGeneration = true; // Folia - region threading - InteractionResult result = BoneMealItem.applyBonemeal(context); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index aedf5ec139613a4ddf6cdb87cc52ae29eda323b2..8c439cf8b94478dba707570f1abeba4a6e41f8a8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/patches/server/0006-Disable-thread-check-if-the-polling-thread-is-global.patch b/patches/server/0005-Disable-thread-check-if-the-polling-thread-is-global.patch similarity index 89% rename from patches/server/0006-Disable-thread-check-if-the-polling-thread-is-global.patch rename to patches/server/0005-Disable-thread-check-if-the-polling-thread-is-global.patch index 17587f1..c35b04b 100644 --- a/patches/server/0006-Disable-thread-check-if-the-polling-thread-is-global.patch +++ b/patches/server/0005-Disable-thread-check-if-the-polling-thread-is-global.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable thread check if the polling thread is global region diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 313db44c6045cd9710f965010234849c69dcf6e8..5c78254fcd983c9979890f0f22290e2bdf415e2c 100644 +index e3fecedf153e21a7842faf037393974b5ff545ac..ea830d500a3b26ef4c87f9d4b7e9136e1223c922 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -885,8 +885,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -884,8 +884,10 @@ public class ServerChunkCache extends ChunkSource { // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { // Folia start - region threading diff --git a/patches/server/0005-Rewrite-world-data-pool.patch b/patches/server/0005-Rewrite-world-data-pool.patch deleted file mode 100644 index a721ebd..0000000 --- a/patches/server/0005-Rewrite-world-data-pool.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrHua269 -Date: Sat, 2 Mar 2024 11:27:49 +0000 -Subject: [PATCH] Rewrite world data pool - - -diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -index c24a0b1c1d038e723dc85f32b7e13642fca033e8..77b1a7cb90d60b4e702ecd7e139e8d2cabcde63e 100644 ---- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java -@@ -188,9 +188,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks{ -+ entity.getBukkitEntity().taskScheduler.schedule(t -> { - TickRegionScheduler.getCurrentRegion().getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); -- }); -+ },null,1); - } - } - } -@@ -207,6 +207,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks, Object> regionizedData = Reference2ReferenceMaps.synchronize(new Reference2ReferenceOpenHashMap<>()); - -+ //locks for dirty fork use -+ private final ReadWriteLock regionizedDataAccessLock = new ReentrantReadWriteLock(); -+ - // tick data - private ConcreteRegionTickHandle tickHandle = new ConcreteRegionTickHandle(this, SchedulerThreadPool.DEADLINE_NOT_SET); - -@@ -251,20 +254,30 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks T getRegionizedData(final RegionizedData regionizedData) { -- return (T)this.regionizedData.get(regionizedData); -+ this.regionizedDataAccessLock.readLock().lock(); -+ try { -+ return (T)this.regionizedData.get(regionizedData); -+ }finally { -+ this.regionizedDataAccessLock.readLock().unlock(); -+ } - } - - T getOrCreateRegionizedData(final RegionizedData regionizedData) { -- T ret = (T) this.regionizedData.get(regionizedData); -+ this.regionizedDataAccessLock.writeLock().lock(); -+ try { -+ T ret = (T) this.regionizedData.get(regionizedData); - -- if (ret != null) { -- return ret; -- } -+ if (ret != null) { -+ return ret; -+ } - -- ret = regionizedData.createNewValue(); -- this.regionizedData.put(regionizedData, ret); -+ ret = regionizedData.createNewValue(); -+ this.regionizedData.put(regionizedData, ret); - -- return ret; -+ return ret; -+ }finally { -+ this.regionizedDataAccessLock.writeLock().unlock(); -+ } - } - - @Override -@@ -282,30 +295,35 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks, Object>> dataIterator = this.regionizedData.reference2ReferenceEntrySet().iterator(); -- dataIterator.hasNext();) { -- final Reference2ReferenceMap.Entry, Object> regionDataEntry = dataIterator.next(); -- final RegionizedData data = regionDataEntry.getKey(); -- final Object from = regionDataEntry.getValue(); -+ this.regionizedDataAccessLock.writeLock().lock(); -+ try { -+ for (final Iterator, Object>> dataIterator = this.regionizedData.reference2ReferenceEntrySet().iterator(); -+ dataIterator.hasNext();) { -+ final Reference2ReferenceMap.Entry, Object> regionDataEntry = dataIterator.next(); -+ final RegionizedData data = regionDataEntry.getKey(); -+ final Object from = regionDataEntry.getValue(); - -- final ReferenceOpenHashSet dataSet = new ReferenceOpenHashSet<>(regions.size(), 0.75f); -+ final ReferenceOpenHashSet dataSet = new ReferenceOpenHashSet<>(regions.size(), 0.75f); - -- for (final ThreadedRegionizer.ThreadedRegion region : regions) { -- dataSet.add(region.getData().getOrCreateRegionizedData(data)); -- } -+ for (final ThreadedRegionizer.ThreadedRegion region : regions) { -+ dataSet.add(region.getData().getOrCreateRegionizedData(data)); -+ } - -- final Long2ReferenceOpenHashMap regionToData = new Long2ReferenceOpenHashMap<>(into.size(), 0.75f); -+ final Long2ReferenceOpenHashMap regionToData = new Long2ReferenceOpenHashMap<>(into.size(), 0.75f); - -- for (final Iterator>> regionIterator = into.long2ReferenceEntrySet().fastIterator(); -- regionIterator.hasNext();) { -- final Long2ReferenceMap.Entry> entry = regionIterator.next(); -- final ThreadedRegionizer.ThreadedRegion region = entry.getValue(); -- final Object to = region.getData().getOrCreateRegionizedData(data); -+ for (final Iterator>> regionIterator = into.long2ReferenceEntrySet().fastIterator(); -+ regionIterator.hasNext();) { -+ final Long2ReferenceMap.Entry> entry = regionIterator.next(); -+ final ThreadedRegionizer.ThreadedRegion region = entry.getValue(); -+ final Object to = region.getData().getOrCreateRegionizedData(data); - -- regionToData.put(entry.getLongKey(), to); -- } -+ regionToData.put(entry.getLongKey(), to); -+ } - -- ((RegionizedData)data).getCallback().split(from, shift, regionToData, dataSet); -+ ((RegionizedData)data).getCallback().split(from, shift, regionToData, dataSet); -+ } -+ }finally { -+ this.regionizedDataAccessLock.writeLock().unlock(); - } - - // chunk holder manager data -diff --git a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -index 3e7f358a1a8623be58ef4f842f37b09beeb926e1..cebd86d0523f815a6b076dbfa5b6dd229c35005c 100644 ---- a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -+++ b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -@@ -2,58 +2,87 @@ package me.earthme.lightingluminol.pool; - - import io.papermc.paper.threadedregions.RegionizedWorldData; - import io.papermc.paper.threadedregions.ThreadedRegionizer; -+import io.papermc.paper.threadedregions.TickRegionScheduler; - import io.papermc.paper.threadedregions.TickRegions; -+import io.papermc.paper.util.TickThread; - import net.minecraft.core.BlockPos; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.level.Level; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; - import org.bukkit.Location; - import org.bukkit.craftbukkit.CraftWorld; - import org.jetbrains.annotations.NotNull; - import org.jetbrains.annotations.Nullable; - - public class WorldDataPool { -+ private static final boolean enableThreadChecks = Boolean.parseBoolean(System.getProperty("enable_thread_check_crossing_regions","true")); -+ private static final Logger logger = LogManager.getLogger(); -+ -+ static{ -+ if (!enableThreadChecks){ -+ logger.warn("Thread checks for world data pool are disabled!This would cause some bugs!"); -+ } -+ } - - @Nullable - public RegionizedWorldData getDataAnyThread(@NotNull Entity ent){ -- final RegionizedWorldData got = ent.level().getCurrentWorldDataUnsafe(); -- return got == null ? getDataOffTickThread((int)ent.position.x >> 4,(int)ent.position.z >> 4, (ServerLevel) ent.level()) : got; //Skip it if we got the current world data -+ return this.getDataAnyThreadUnsafe(((ServerLevel) ent.level()), (int) ent.position.x, (int) ent.position.z); - } - - @Nullable -- public RegionizedWorldData getDataAnyThread(@NotNull Level level, BlockPos pos){ -- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); -- return got == null ? getDataOffTickThread(pos.getX() >> 4,pos.getZ() >> 4, ((ServerLevel) level)) : got; //Skip it if we got the current world data -+ public RegionizedWorldData getDataAnyThread(@NotNull Level level, @NotNull BlockPos pos){ -+ return this.getDataAnyThreadUnsafe(((ServerLevel) level),pos.getX(),pos.getZ()); - } - - @Nullable - public RegionizedWorldData getDataAnyThread(@NotNull Level level, int x,int z){ -- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); -- return got == null ? getDataOffTickThread(x >> 4,z >> 4, ((ServerLevel) level)) : got; //Skip it if we got the current world data -+ return this.getDataAnyThreadUnsafe(((ServerLevel) level),x,z); - } - - @Nullable - public RegionizedWorldData getDataAnyThread(int chunkX,int chunkZ,Level level){ -- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); -- return got == null ? getDataOffTickThread(chunkX,chunkZ, ((ServerLevel) level)) : got; //Skip it if we got the current world data -+ return this.getDataAnyThreadUnsafe(((ServerLevel) level),4 << chunkX,4 << chunkZ); - } - - - @Nullable - public RegionizedWorldData getDataAnyThread(@NotNull Location loc){ -- final RegionizedWorldData got = ((CraftWorld) loc.getWorld()).getHandle().getCurrentWorldDataUnsafe(); -- return got == null ? getDataOffTickThread(loc.blockX() >> 4,loc.blockZ() >> 4, ((CraftWorld) loc.getWorld()).getHandle()) : got; //Skip it if we got the current world data -+ return this.getDataAnyThreadUnsafe(((CraftWorld) loc.getWorld()).getHandle(),loc.blockX(),loc.blockZ()); - } - - @Nullable -- public RegionizedWorldData getDataOffTickThread(int chunkX,int chunkZ,@NotNull ServerLevel level){ -- ThreadedRegionizer.ThreadedRegion target = level.regioniser.getRegionAtUnsynchronised(chunkX,chunkZ); -- RegionizedWorldData ret; -+ public RegionizedWorldData getDataAnyThreadUnsafe(@NotNull ServerLevel level, int posX, int posZ){ -+ final ThreadedRegionizer.ThreadedRegion currrent = TickRegionScheduler.getCurrentRegion(); -+ final ThreadedRegionizer.ThreadedRegion target = level.regioniser.getRegionAtUnsynchronised(posX >> 4, posZ >> 4); -+ -+ if (target == null){ -+ /*if (!level.chunkSource.isChunkLoaded(posX >> 4,posZ >> 4)){ -+ return enableThreadChecks ? this.onDataMissing(level,posX,posZ) : level.getCurrentWorldDataUnsafe(); -+ }*/ -+ -+ return level.getCurrentWorldDataUnsafe(); -+ } - -- if ((target != null) && target.getData() != null && (ret = target.getData().getRegionizedData(target.regioniser.world.worldRegionData)) != null){ -- return ret; -+ final RegionizedWorldData targetWorldData = target.getData() == null ? null : target.getData().getRegionizedData(level.worldRegionData); -+ -+ if (currrent == null){ -+ return targetWorldData != null ? targetWorldData : this.onDataMissing(level,posX,posZ); -+ } -+ -+ if (currrent != target && enableThreadChecks){ -+ return targetWorldData != null ? targetWorldData : this.onDataMissing(level,posX,posZ); - } - -- return null; //TODO Fast-fail? -+ return level.getCurrentWorldDataUnsafe(); -+ } -+ -+ //TODO Fast fail -+ @Nullable -+ public RegionizedWorldData onDataMissing(@NotNull ServerLevel targetLevel,int targetX,int targetZ){ -+ logger.error("The thread {} has required a missing region for nms use!X:{},Z:{},World:{}",Thread.currentThread().getName(),targetX,targetZ,targetLevel.dimension().registry()); -+ new Throwable().printStackTrace(); -+ return null; - } - } -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index e3fecedf153e21a7842faf037393974b5ff545ac..313db44c6045cd9710f965010234849c69dcf6e8 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -204,6 +204,11 @@ public class ServerChunkCache extends ChunkSource { - public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { - final int x1 = x; final int z1 = z; // Paper - conflict on variable change - if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system -+ LevelChunk ifLoaded = this.getChunkAtIfLoadedMainThread(x, z); -+ if (ifLoaded != null) { -+ return ifLoaded; -+ } -+ - return CompletableFuture.supplyAsync(() -> { - return this.getChunk(x, z, leastStatus, create); - }, SchedulerUtil.regionSchedulerAsExecutor(this.level.getWorld(),x,z)).join(); -@@ -232,11 +237,7 @@ public class ServerChunkCache extends ChunkSource { - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, x1, z1); // Paper - rewrite chunk system - com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads - this.level.timings.syncChunkLoad.startTiming(); // Paper -- if (!RegionizedServer.isGlobalTickThread() || !TickThread.isTickThreadFor(this.level,x,z)){ -- chunkproviderserver_b.managedBlock(completablefuture::isDone); -- }else{ -- completablefuture.join(); -- } -+ chunkproviderserver_b.managedBlock(completablefuture::isDone); - io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - rewrite chunk system - this.level.timings.syncChunkLoad.stopTiming(); // Paper - } // Paper diff --git a/patches/server/0007-Portal-events-and-teleport-events.patch b/patches/server/0006-Portal-events-and-teleport-events.patch similarity index 100% rename from patches/server/0007-Portal-events-and-teleport-events.patch rename to patches/server/0006-Portal-events-and-teleport-events.patch diff --git a/patches/server/0007-Rework-WorldData-patches.patch b/patches/server/0007-Rework-WorldData-patches.patch new file mode 100644 index 0000000..1189a3b --- /dev/null +++ b/patches/server/0007-Rework-WorldData-patches.patch @@ -0,0 +1,202 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 31 Mar 2024 00:53:02 +0000 +Subject: [PATCH] Rework WorldData patches + + +diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java +index 78c50292fb25e8703e9c91db892f05456f07d72f..efdfd5b514e6f0368275f0c9d63c38a6a1c30faf 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java ++++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java +@@ -12,6 +12,8 @@ import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; + import net.minecraft.server.MinecraftServer; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.chunk.LevelChunk; + import org.slf4j.Logger; + import java.util.Iterator; + import java.util.concurrent.TimeUnit; +@@ -153,6 +155,28 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks region = ++ TickRegionScheduler.getCurrentRegion(); ++ ++ if (region == null){ ++ region = ((ServerLevel) entity.level()).regioniser.getRegionAtUnsynchronised(entity.getBlockX() >> 4,entity.getBlockZ() >> 4); ++ } ++ ++ region.getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); ++ } ++ ++ static void updateCurrentRegion(LevelChunk chunk) { ++ ThreadedRegionizer.ThreadedRegion region = ++ TickRegionScheduler.getCurrentRegion(); ++ ++ if (region == null){ ++ region = chunk.level.regioniser.getRegionAtUnsynchronised(chunk.locX,chunk.locZ); ++ } ++ ++ region.getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); ++ } ++ + static void updateCurrentRegion() { + TickRegionScheduler.getCurrentRegion().getData().getRegionStats().updateFrom(TickRegionScheduler.getCurrentRegionizedWorldData()); + } +@@ -227,6 +251,10 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks> 4,(int)ent.position.z >> 4, (ServerLevel) ent.level()) : got; //Skip it if we got the current world data +- } +- +- @Nullable +- public RegionizedWorldData getDataAnyThread(@NotNull Level level, BlockPos pos){ +- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); +- return got == null ? getDataOffTickThread(pos.getX() >> 4,pos.getZ() >> 4, ((ServerLevel) level)) : got; //Skip it if we got the current world data +- } +- +- @Nullable +- public RegionizedWorldData getDataAnyThread(@NotNull Level level, int x,int z){ +- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); +- return got == null ? getDataOffTickThread(x >> 4,z >> 4, ((ServerLevel) level)) : got; //Skip it if we got the current world data +- } +- +- @Nullable +- public RegionizedWorldData getDataAnyThread(int chunkX,int chunkZ,Level level){ +- final RegionizedWorldData got = level.getCurrentWorldDataUnsafe(); +- return got == null ? getDataOffTickThread(chunkX,chunkZ, ((ServerLevel) level)) : got; //Skip it if we got the current world data +- } +- +- +- @Nullable +- public RegionizedWorldData getDataAnyThread(@NotNull Location loc){ +- final RegionizedWorldData got = ((CraftWorld) loc.getWorld()).getHandle().getCurrentWorldDataUnsafe(); +- return got == null ? getDataOffTickThread(loc.blockX() >> 4,loc.blockZ() >> 4, ((CraftWorld) loc.getWorld()).getHandle()) : got; //Skip it if we got the current world data +- } +- +- @Nullable +- public RegionizedWorldData getDataOffTickThread(int chunkX,int chunkZ,@NotNull ServerLevel level){ +- ThreadedRegionizer.ThreadedRegion target = level.regioniser.getRegionAtUnsynchronised(chunkX,chunkZ); +- RegionizedWorldData ret; +- +- if ((target != null) && target.getData() != null && (ret = target.getData().getRegionizedData(target.regioniser.world.worldRegionData)) != null){ +- return ret; +- } +- +- return null; //TODO Fast-fail? +- } +-} +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 25a2f23618cd02366f71e704638adfbaed9fa8c5..62fe8ca9e71d5ad6ca42b2a2b23e99168eef4449 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -6,6 +6,7 @@ import com.google.common.collect.Lists; + import com.mojang.datafixers.DataFixer; + import com.mojang.datafixers.util.Pair; + import com.mojang.logging.LogUtils; ++import io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; + import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + import it.unimi.dsi.fastutil.longs.LongSet; +@@ -2035,7 +2036,7 @@ public class ServerLevel extends Level implements WorldGenLevel { + + if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) { + List list = new ObjectArrayList(); +- Iterator iterator = this.getCurrentWorldData().getNavigatingMobs(); // Folia - region threading ++ Iterator iterator = this.getCurrentWorldData().getNavigatingMobs().iterator(); // Folia - region threading + + while (iterator.hasNext()) { + // CraftBukkit start - fix SPIGOT-6362 +diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java +index a9921af214c596ef2601ccdbf37b4234bcf4ea1d..9f9655f4ffd4bdc4abc793fe694df3935ecd30f6 100644 +--- a/src/main/java/net/minecraft/world/level/Level.java ++++ b/src/main/java/net/minecraft/world/level/Level.java +@@ -10,6 +10,9 @@ import java.util.function.Consumer; + import java.util.function.Predicate; + import java.util.function.Supplier; + import javax.annotation.Nullable; ++ ++import io.papermc.paper.threadedregions.RegionizedWorldData; ++import me.earthme.lightingluminol.RegonizedWorldDataSwitcher; + import net.minecraft.CrashReport; + import net.minecraft.CrashReportCategory; + import net.minecraft.ReportedException; +@@ -214,16 +217,19 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + ); + public volatile io.papermc.paper.threadedregions.RegionizedServer.WorldLevelData tickData; + public final java.util.concurrent.ConcurrentHashMap.KeySetView needsChangeBroadcasting = java.util.concurrent.ConcurrentHashMap.newKeySet(); ++ public final RegonizedWorldDataSwitcher dataSwitcher = new RegonizedWorldDataSwitcher(); + + public io.papermc.paper.threadedregions.RegionizedWorldData getCurrentWorldData() { + final io.papermc.paper.threadedregions.RegionizedWorldData ret = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionizedWorldData(); + if (ret == null) { +- return ret; ++ return this.dataSwitcher.getLastMatch(); + } + Level world = ret.world; + if (world != this) { +- throw new IllegalStateException("World mismatch: expected " + this.getWorld().getName() + " but got " + world.getWorld().getName()); ++ //throw new IllegalStateException("World mismatch: expected " + this.getWorld().getName() + " but got " + world.getWorld().getName()); ++ return this.dataSwitcher.getLastMatch(); + } ++ this.dataSwitcher.updateCurrent(ret); + return ret; + } + diff --git a/patches/server/0008-Fix-incorrect-chunk-pos-shifting-in-WorldDataPool.patch b/patches/server/0008-Fix-incorrect-chunk-pos-shifting-in-WorldDataPool.patch deleted file mode 100644 index 5e2002e..0000000 --- a/patches/server/0008-Fix-incorrect-chunk-pos-shifting-in-WorldDataPool.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrHua269 -Date: Sun, 3 Mar 2024 09:51:12 +0000 -Subject: [PATCH] Fix incorrect chunk pos shifting in WorldDataPool - - -diff --git a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -index cebd86d0523f815a6b076dbfa5b6dd229c35005c..87955f4453ab2200312f5cb84e8e435b32b01ef1 100644 ---- a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -+++ b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -@@ -43,7 +43,7 @@ public class WorldDataPool { - - @Nullable - public RegionizedWorldData getDataAnyThread(int chunkX,int chunkZ,Level level){ -- return this.getDataAnyThreadUnsafe(((ServerLevel) level),4 << chunkX,4 << chunkZ); -+ return this.getDataAnyThreadUnsafe(((ServerLevel) level),chunkX >> 4, chunkZ >> 4); - } - - diff --git a/patches/server/0009-Fix-incorrect-shifting.patch b/patches/server/0009-Fix-incorrect-shifting.patch deleted file mode 100644 index 3bad3ab..0000000 --- a/patches/server/0009-Fix-incorrect-shifting.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrHua269 -Date: Sat, 16 Mar 2024 12:30:01 +0000 -Subject: [PATCH] Fix incorrect shifting - - -diff --git a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -index 87955f4453ab2200312f5cb84e8e435b32b01ef1..f79c5096844d526a352468ffb01e0afca5fff519 100644 ---- a/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -+++ b/src/main/java/me/earthme/lightingluminol/pool/WorldDataPool.java -@@ -43,7 +43,7 @@ public class WorldDataPool { - - @Nullable - public RegionizedWorldData getDataAnyThread(int chunkX,int chunkZ,Level level){ -- return this.getDataAnyThreadUnsafe(((ServerLevel) level),chunkX >> 4, chunkZ >> 4); -+ return this.getDataAnyThreadUnsafe(((ServerLevel) level),chunkX << 4, chunkZ << 4); - } - - -diff --git a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -index 92d61b242128cde0989a720adfb28ebd738a6c1f..3390fb56d3ab917181b9bdd65a08a2e7518214e4 100644 ---- a/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -+++ b/src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java -@@ -174,13 +174,14 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl - updateFuture.onComplete.thenAccept((final Void ignore) -> { - RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( - this.chunkMap.level, chunkX, chunkZ, () -> { -- final int newReferences = Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ,this.chunkMap.level).chunksBeingWorkedOn.get(key); -+ var got = Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ,this.chunkMap.level); -+ final int newReferences = got.chunksBeingWorkedOn.get(key); - if (newReferences == 1) { -- Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ, this.chunkMap.level).chunksBeingWorkedOn.remove(key); -+ got.chunksBeingWorkedOn.remove(key); - final ChunkPos pos = new ChunkPos(chunkX, chunkZ); - world.getChunkSource().removeRegionTicket(StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); - } else { -- Level.WORLD_DATA_POOL.getDataAnyThread(chunkX,chunkZ, this.chunkMap.level).chunksBeingWorkedOn.put(key, newReferences - 1); -+ got.chunksBeingWorkedOn.put(key, newReferences - 1); - } - } - );