aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSpottedleaf <[email protected]>2024-12-20 09:19:19 -0800
committerSpottedleaf <[email protected]>2024-12-20 09:22:42 -0800
commit45c905b928fca277a4fba763b47427b3e08e9eef (patch)
treef257b5559f556cf39648a62cbf04f94fe68852fc
parent6186079231d3c0cc03c484c7932b6eb9ed3015b1 (diff)
downloadPaper-45c905b928fca277a4fba763b47427b3e08e9eef.tar.gz
Paper-45c905b928fca277a4fba763b47427b3e08e9eef.zip
Apply Moonrise patch minus CB diff
-rw-r--r--paper-server/patches/features/0018-Moonrise-optimisation-patches.patch (renamed from feature-patches/0018-Moonrise-optimisation-patches.patch)6316
1 files changed, 2744 insertions, 3572 deletions
diff --git a/feature-patches/0018-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0018-Moonrise-optimisation-patches.patch
index b20c8eacca..16ce461d49 100644
--- a/feature-patches/0018-Moonrise-optimisation-patches.patch
+++ b/paper-server/patches/features/0018-Moonrise-optimisation-patches.patch
@@ -17,35 +17,6 @@ Currently includes:
See https://github.com/Tuinity/Moonrise
-diff --git a/ca/spottedleaf/moonrise/common/PlatformHooks.java b/ca/spottedleaf/moonrise/common/PlatformHooks.java
-index 6c98d420ea84c10ef4f15d4deb3f04e610ed8548..9b879cbc037a17ffeb9a963111fd3f303a935eef 100644
---- a/ca/spottedleaf/moonrise/common/PlatformHooks.java
-+++ b/ca/spottedleaf/moonrise/common/PlatformHooks.java
-@@ -1,5 +1,6 @@
- package ca.spottedleaf.moonrise.common;
-
-+import ca.spottedleaf.moonrise.common.util.ChunkSystemHooks;
- import com.mojang.datafixers.DSL;
- import com.mojang.datafixers.DataFixer;
- import net.minecraft.core.BlockPos;
-@@ -23,7 +24,7 @@ import java.util.List;
- import java.util.ServiceLoader;
- import java.util.function.Predicate;
-
--public interface PlatformHooks {
-+public interface PlatformHooks extends ChunkSystemHooks {
- public static PlatformHooks get() {
- return Holder.INSTANCE;
- }
-@@ -63,8 +64,6 @@ public interface PlatformHooks {
-
- public void entityMove(final Entity entity, final long oldSection, final long newSection);
-
-- public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event);
--
- public boolean configFixMC224294();
-
- public boolean configAutoConfigSendDistance();
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b8193587814225c2ef2c5d9e667436eb50ff6c5
@@ -325,257 +296,65 @@ index 0000000000000000000000000000000000000000..1b8193587814225c2ef2c5d9e667436e
+ }
+ }
+}
-diff --git a/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..89406dbda09eea03579ed724fda0df2d42e2e504
---- /dev/null
-+++ b/ca/spottedleaf/moonrise/common/util/BaseChunkSystemHooks.java
-@@ -0,0 +1,190 @@
-+package ca.spottedleaf.moonrise.common.util;
-+
-+import ca.spottedleaf.concurrentutil.util.Priority;
-+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
-+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk;
-+import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader;
-+import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache;
-+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
-+import net.minecraft.server.level.ChunkHolder;
-+import net.minecraft.server.level.FullChunkStatus;
-+import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
-+import net.minecraft.server.level.progress.ChunkProgressListener;
-+import net.minecraft.world.level.chunk.ChunkAccess;
-+import net.minecraft.world.level.chunk.LevelChunk;
-+import net.minecraft.world.level.chunk.status.ChunkStatus;
-+import java.util.List;
-+import java.util.function.Consumer;
-+
-+public abstract class BaseChunkSystemHooks implements ChunkSystemHooks {
-+
-+ @Override
-+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
-+ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
-+ }
-+
-+ @Override
-+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
-+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority);
-+ }
-+
-+ @Override
-+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
-+ final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
-+ final Consumer<ChunkAccess> onComplete) {
-+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete);
-+ }
-+
-+ @Override
-+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
-+ final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
-+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
-+ }
-+
-+ @Override
-+ public void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
-+ final FullChunkStatus toStatus, final boolean addTicket,
-+ final Priority priority, final Consumer<LevelChunk> onComplete) {
-+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
-+ }
-+
-+ @Override
-+ public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
-+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
-+ }
-+
-+ @Override
-+ public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
-+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
-+ }
-+
-+ @Override
-+ public int getVisibleChunkHolderCount(final ServerLevel level) {
-+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
-+ }
-+
-+ @Override
-+ public int getUpdatingChunkHolderCount(final ServerLevel level) {
-+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
-+ }
-+
-+ @Override
-+ public boolean hasAnyChunkHolders(final ServerLevel level) {
-+ return getUpdatingChunkHolderCount(level) != 0;
-+ }
-+
-+ @Override
-+ public void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
-+
-+ }
-+
-+ @Override
-+ public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
-+ // Update progress listener for LevelLoadingScreen
-+ final ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener;
-+ if (progressListener != null) {
-+ this.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> {
-+ progressListener.onStatusChange(holder.getPos(), null);
-+ });
-+ }
-+ }
-+
-+ @Override
-+ public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
-+ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk);
-+ }
-+
-+ @Override
-+ public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ chunk.loadCallback();
-+ }
-+
-+ @Override
-+ public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().remove(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ chunk.unloadCallback();
-+ }
-+
-+ @Override
-+ public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
-+ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null);
-+ }
-+
-+ @Override
-+ public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().add(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) {
-+ chunk.postProcessGeneration((ServerLevel)chunk.getLevel());
-+ }
-+ ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk);
-+ ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet();
-+ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
-+ }
-+
-+ @Override
-+ public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ ((ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
-+ }
-+
-+ @Override
-+ public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().add(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ }
-+
-+ @Override
-+ public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
-+ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().remove(
-+ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
-+ );
-+ }
-+
-+ @Override
-+ public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
-+ return null;
-+ }
-+
-+ @Override
-+ public int getSendViewDistance(final ServerPlayer player) {
-+ return RegionizedPlayerChunkLoader.getAPISendViewDistance(player);
-+ }
-+
-+ @Override
-+ public int getViewDistance(final ServerPlayer player) {
-+ return RegionizedPlayerChunkLoader.getAPIViewDistance(player);
-+ }
-+
-+ @Override
-+ public int getTickViewDistance(final ServerPlayer player) {
-+ return RegionizedPlayerChunkLoader.getAPITickViewDistance(player);
-+ }
-+
-+ @Override
-+ public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) {
-+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player);
-+ }
-+
-+ @Override
-+ public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) {
-+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player);
-+ }
-+
-+ @Override
-+ public void updateMaps(final ServerLevel world, final ServerPlayer player) {
-+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player);
-+ }
-+}
-diff --git a/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
-deleted file mode 100644
-index 58a99bc38e137431f10af36fa9e2d04fe61694aa..0000000000000000000000000000000000000000
---- a/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
-+++ /dev/null
-@@ -1,288 +0,0 @@
--package ca.spottedleaf.moonrise.common.util;
--
--import ca.spottedleaf.concurrentutil.util.Priority;
--import ca.spottedleaf.moonrise.common.PlatformHooks;
--import com.mojang.logging.LogUtils;
--import net.minecraft.server.level.ChunkHolder;
--import net.minecraft.server.level.FullChunkStatus;
--import net.minecraft.server.level.ServerLevel;
--import net.minecraft.server.level.ServerPlayer;
--import net.minecraft.world.entity.Entity;
--import net.minecraft.world.level.chunk.ChunkAccess;
--import net.minecraft.world.level.chunk.LevelChunk;
--import net.minecraft.world.level.chunk.status.ChunkStatus;
--import org.slf4j.Logger;
--import java.util.List;
--import java.util.function.Consumer;
--
--public final class ChunkSystem {
--
+diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
+index c2dfbce23af5741b7f78ddd6df9bcbce69915ae9..5955a56a63e91edafbac07ac1f0c640a4f7cbb26 100644
+--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
++++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
+@@ -268,7 +268,7 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo
+
+ @Override
+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
+- net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities(), chunk.getPos()); // Paper - rewrite chunk system - add ChunkPos param
+ }
+
+ @Override
+diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
+index 34b45bc11124efb22f0f3ae5b2ad8f445c719476..62a9e62711a46283931d22b0e72b2b1903d973a1 100644
+--- a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
++++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
+@@ -23,218 +23,59 @@ import java.util.function.Consumer;
+
+ public abstract class BaseChunkSystemHooks implements ca.spottedleaf.moonrise.common.util.ChunkSystemHooks {
+
- private static final Logger LOGGER = LogUtils.getLogger();
-- private static final net.minecraft.world.level.chunk.status.ChunkStep FULL_CHUNK_STEP = net.minecraft.world.level.chunk.status.ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL);
+- private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL);
+- private static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo);
+-
+- private long chunkLoadCounter = 0L;
-
- private static int getDistance(final ChunkStatus status) {
- return FULL_CHUNK_STEP.getAccumulatedRadiusOf(status);
- }
-
-- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
-- scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
-- }
--
-- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
+ @Override
+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
+- this.scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
++ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
+ }
+
+ @Override
+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
- level.chunkSource.mainThreadProcessor.execute(run);
-- }
--
-- public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
-- final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
-- final Consumer<ChunkAccess> onComplete) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority);
+ }
+
+ @Override
+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
+ final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
+ final Consumer<ChunkAccess> onComplete) {
- if (gen) {
-- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
+- this.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- return;
- }
-- scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> {
+- this.scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> {
- if (chunk == null) {
- if (onComplete != null) {
- onComplete.accept(null);
- }
- } else {
- if (chunk.getPersistedStatus().isOrAfter(toStatus)) {
-- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
+- BaseChunkSystemHooks.this.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- } else {
- if (onComplete != null) {
- onComplete.accept(null);
@@ -583,23 +362,22 @@ index 58a99bc38e137431f10af36fa9e2d04fe61694aa..00000000000000000000000000000000
- }
- }
- });
-- }
--
-- static final net.minecraft.server.level.TicketType<Long> CHUNK_LOAD = net.minecraft.server.level.TicketType.create("chunk_load", Long::compareTo);
--
-- private static long chunkLoadCounter = 0L;
-- public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
-- final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
-- if (!org.bukkit.Bukkit.isOwnedByCurrentRegion(level.getWorld(), chunkX, chunkZ)) {
-- scheduleChunkTask(level, chunkX, chunkZ, () -> {
-- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete);
+ }
+
+ @Override
+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
+ final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
+- if (!Bukkit.isOwnedByCurrentRegion(level.getWorld(), chunkX, chunkZ)) {
+- this.scheduleChunkTask(level, chunkX, chunkZ, () -> {
+- BaseChunkSystemHooks.this.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- }, priority);
- return;
- }
-
- final int minLevel = 33 + getDistance(toStatus);
-- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
-- final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ);
+- final Long chunkReference = addTicket ? Long.valueOf(++this.chunkLoadCounter) : null;
+- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
-
- if (addTicket) {
- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
@@ -622,50 +400,52 @@ index 58a99bc38e137431f10af36fa9e2d04fe61694aa..00000000000000000000000000000000
- }
- };
-
-- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
-
- if (holder == null || holder.getTicketLevel() > minLevel) {
- loadCallback.accept(null);
- return;
- }
-
-- final java.util.concurrent.CompletableFuture<net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.ChunkAccess>> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap);
+- final CompletableFuture<ChunkResult<ChunkAccess>> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap);
-
- if (loadFuture.isDone()) {
- loadCallback.accept(loadFuture.join().orElse(null));
- return;
- }
-
-- loadFuture.whenCompleteAsync((final net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.ChunkAccess> result, final Throwable thr) -> {
+- loadFuture.whenCompleteAsync((final ChunkResult<ChunkAccess> result, final Throwable thr) -> {
- if (thr != null) {
- loadCallback.accept(null);
- return;
- }
- loadCallback.accept(result.orElse(null));
- }, (final Runnable r) -> {
-- scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
+- BaseChunkSystemHooks.this.scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
- });
-- }
--
-- public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
-- final FullChunkStatus toStatus, final boolean addTicket,
-- final Priority priority, final Consumer<LevelChunk> onComplete) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
+ }
+
+ @Override
+ public void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
+ final FullChunkStatus toStatus, final boolean addTicket,
+ final Priority priority, final Consumer<LevelChunk> onComplete) {
- // This method goes unused until the chunk system rewrite
- if (toStatus == FullChunkStatus.INACCESSIBLE) {
- throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status");
- }
-
-- if (!org.bukkit.Bukkit.isOwnedByCurrentRegion(level.getWorld(), chunkX, chunkZ)) {
-- scheduleChunkTask(level, chunkX, chunkZ, () -> {
-- scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
+- if (!Bukkit.isOwnedByCurrentRegion(level.getWorld(), chunkX, chunkZ)) {
+- this.scheduleChunkTask(level, chunkX, chunkZ, () -> {
+- BaseChunkSystemHooks.this.scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- }, priority);
- return;
- }
-
- final int minLevel = 33 - (toStatus.ordinal() - 1);
- final int radius = toStatus.ordinal() - 1;
-- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
-- final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ);
+- final Long chunkReference = addTicket ? Long.valueOf(++this.chunkLoadCounter) : null;
+- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
-
- if (addTicket) {
- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
@@ -682,20 +462,20 @@ index 58a99bc38e137431f10af36fa9e2d04fe61694aa..00000000000000000000000000000000
- com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
- } finally {
- if (addTicket) {
-- level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
+- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
- }
- }
- };
-
-- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
-
- if (holder == null || holder.getTicketLevel() > minLevel) {
- loadCallback.accept(null);
- return;
- }
-
-- final java.util.concurrent.CompletableFuture<net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.LevelChunk>> tickingState;
+- final CompletableFuture<ChunkResult<LevelChunk>> tickingState;
- switch (toStatus) {
- case FULL: {
- tickingState = holder.getFullChunkFuture();
@@ -719,220 +499,184 @@ index 58a99bc38e137431f10af36fa9e2d04fe61694aa..00000000000000000000000000000000
- return;
- }
-
-- tickingState.whenCompleteAsync((final net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.LevelChunk> result, final Throwable thr) -> {
+- tickingState.whenCompleteAsync((final ChunkResult<LevelChunk> result, final Throwable thr) -> {
- if (thr != null) {
- loadCallback.accept(null);
- return;
- }
- loadCallback.accept(result.orElse(null));
- }, (final Runnable r) -> {
-- scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
+- BaseChunkSystemHooks.this.scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
- });
-- }
--
-- public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
-- return new java.util.ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
-- }
--
-- public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
-- return new java.util.ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
-- }
--
-- public static int getVisibleChunkHolderCount(final ServerLevel level) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
+ }
+
+ @Override
+ public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
+- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
+ }
+
+ @Override
+ public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
+- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders();
+ }
+
+ @Override
+ public int getVisibleChunkHolderCount(final ServerLevel level) {
- return level.chunkSource.chunkMap.visibleChunkMap.size();
-- }
--
-- public static int getUpdatingChunkHolderCount(final ServerLevel level) {
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
+ }
+
+ @Override
+ public int getUpdatingChunkHolderCount(final ServerLevel level) {
- return level.chunkSource.chunkMap.updatingChunkMap.size();
-- }
--
-- public static boolean hasAnyChunkHolders(final ServerLevel level) {
-- return getUpdatingChunkHolderCount(level) != 0;
-- }
--
-- public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) {
-- if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) {
-- return false;
-- }
-- return true;
-- }
--
-- public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
--
-- }
--
-- public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
--
-- }
--
-- public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
--
-- }
--
-- public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
--
-- }
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size();
+ }
+
+ @Override
+ public boolean hasAnyChunkHolders(final ServerLevel level) {
+- return this.getUpdatingChunkHolderCount(level) != 0;
++ return getUpdatingChunkHolderCount(level) != 0;
+ }
+
+ @Override
+@@ -244,89 +85,110 @@ public abstract class BaseChunkSystemHooks implements ca.spottedleaf.moonrise.co
+
+ @Override
+ public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
-
-- public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
++ // Update progress listener for LevelLoadingScreen
++ final net.minecraft.server.level.progress.ChunkProgressListener progressListener = level.getChunkSource().chunkMap.progressListener;
++ if (progressListener != null) {
++ this.scheduleChunkTask(level, holder.getPos().x, holder.getPos().z, () -> {
++ progressListener.onStatusChange(holder.getPos(), null);
++ });
++ }
+ }
+
+ @Override
+ public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) {
-
-- }
++ ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
++ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk);
+ }
+
+ @Override
+ public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
-
-- public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
++ chunk.loadCallback();
+ }
+
+ @Override
+ public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
-
-- }
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().remove(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
++ chunk.unloadCallback();
+ }
+
+ @Override
+ public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
-
-- public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource())
++ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null);
+ }
+
+ @Override
+ public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
-
-- }
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().add(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
++ if (!((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) {
++ chunk.postProcessGeneration((ServerLevel)chunk.getLevel());
++ }
++ ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk);
++ ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet();
++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$markChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
+ }
+
+ @Override
+ public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
-
-- public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)(ServerLevel)chunk.getLevel()).moonrise$removeChunkForPlayerTicking(chunk); // Moonrise - chunk tick iteration
+ }
+
+ @Override
+ public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
-
-- }
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().add(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
+ }
+
+ @Override
+ public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
-
-- public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().remove(
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder()
++ );
+ }
+
+ @Override
+ public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
- return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ);
-- }
--
-- public static int getSendViewDistance(final ServerPlayer player) {
-- return getViewDistance(player);
-- }
--
-- public static int getViewDistance(final ServerPlayer player) {
++ return null;
+ }
+
+ @Override
+ public int getSendViewDistance(final ServerPlayer player) {
+- return this.getViewDistance(player);
++ return ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.getAPISendViewDistance(player);
+ }
+
+ @Override
+ public int getViewDistance(final ServerPlayer player) {
- final ServerLevel level = player.serverLevel();
- if (level == null) {
-- return org.bukkit.Bukkit.getViewDistance();
+- return Bukkit.getViewDistance();
- }
- return level.chunkSource.chunkMap.serverViewDistance;
-- }
--
-- public static int getTickViewDistance(final ServerPlayer player) {
++ return ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.getAPIViewDistance(player);
+ }
+
+ @Override
+ public int getTickViewDistance(final ServerPlayer player) {
- final ServerLevel level = player.serverLevel();
- if (level == null) {
-- return org.bukkit.Bukkit.getSimulationDistance();
+- return Bukkit.getSimulationDistance();
- }
- return level.chunkSource.chunkMap.distanceManager.simulationDistance;
-- }
--
-- private ChunkSystem() {}
--}
-diff --git a/ca/spottedleaf/moonrise/common/util/ChunkSystemHooks.java b/ca/spottedleaf/moonrise/common/util/ChunkSystemHooks.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..427079ae47b6e0e1aa42013a8760fbefa76941f2
---- /dev/null
-+++ b/ca/spottedleaf/moonrise/common/util/ChunkSystemHooks.java
-@@ -0,0 +1,77 @@
-+package ca.spottedleaf.moonrise.common.util;
-+
-+import ca.spottedleaf.concurrentutil.util.Priority;
-+import net.minecraft.server.level.ChunkHolder;
-+import net.minecraft.server.level.FullChunkStatus;
-+import net.minecraft.server.level.ServerLevel;
-+import net.minecraft.server.level.ServerPlayer;
-+import net.minecraft.world.entity.Entity;
-+import net.minecraft.world.level.chunk.ChunkAccess;
-+import net.minecraft.world.level.chunk.LevelChunk;
-+import net.minecraft.world.level.chunk.status.ChunkStatus;
-+import java.util.List;
-+import java.util.function.Consumer;
-+
-+public interface ChunkSystemHooks {
-+
-+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run);
-+
-+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority);
-+
-+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
-+ final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
-+ final Consumer<ChunkAccess> onComplete);
-+
-+ public void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
-+ final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete);
-+
-+ public void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
-+ final FullChunkStatus toStatus, final boolean addTicket,
-+ final Priority priority, final Consumer<LevelChunk> onComplete);
-+
-+ public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level);
-+
-+ public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level);
-+
-+ public int getVisibleChunkHolderCount(final ServerLevel level);
-+
-+ public int getUpdatingChunkHolderCount(final ServerLevel level);
-+
-+ public boolean hasAnyChunkHolders(final ServerLevel level);
-+
-+ public boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event);
-+
-+ public void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder);
-+
-+ public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder);
-+
-+ public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder);
-+
-+ public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ);
-+
-+ public int getSendViewDistance(final ServerPlayer player);
-+
-+ public int getViewDistance(final ServerPlayer player);
-+
-+ public int getTickViewDistance(final ServerPlayer player);
-+
-+ public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player);
-+
-+ public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player);
-+
-+ public void updateMaps(final ServerLevel world, final ServerPlayer player);
-+}
-diff --git a/ca/spottedleaf/moonrise/common/util/ThreadUnsafeRandom.java b/ca/spottedleaf/moonrise/common/util/ThreadUnsafeRandom.java
-index 12eb3add0931a4d77acdf6e875c42dda9c313dc3..5239993a681d6113eec99fa627b85508656ed7ac 100644
---- a/ca/spottedleaf/moonrise/common/util/ThreadUnsafeRandom.java
-+++ b/ca/spottedleaf/moonrise/common/util/ThreadUnsafeRandom.java
-@@ -9,7 +9,7 @@ import net.minecraft.world.level.levelgen.PositionalRandomFactory;
- /**
- * Avoid costly CAS of superclass
- */
--public final class ThreadUnsafeRandom implements BitRandomSource {
-+public class ThreadUnsafeRandom implements BitRandomSource { // Paper - replace random
-
- private static final long MULTIPLIER = 25214903917L;
- private static final long ADDEND = 11L;
-diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
-index 11cfe9cc29666ce3a6a40281069fb9eb4fa0ded2..8c197c59eb35e02f163ec98b8aa0888e4ff40b1a 100644
---- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
-+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
-@@ -27,7 +27,7 @@ import net.minecraft.world.phys.AABB;
- import java.util.List;
- import java.util.function.Predicate;
-
--public final class PaperHooks implements PlatformHooks {
-+public final class PaperHooks extends ca.spottedleaf.moonrise.common.util.BaseChunkSystemHooks implements PlatformHooks { // Paper - rewrite chunk system
++ return ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.getAPITickViewDistance(player);
+ }
@Override
- public String getBrand() {
-@@ -267,7 +267,7 @@ public final class PaperHooks implements PlatformHooks {
+ public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) {
+-
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player);
+ }
@Override
- public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
-- net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
-+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities(), chunk.getPos()); // Paper - rewrite chunk system - add ChunkPos param
+ public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) {
+-
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player);
}
@Override
+ public void updateMaps(final ServerLevel world, final ServerPlayer player) {
+-
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player);
+ }
+ }
diff --git a/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..93bc56daec4526f373c84763b8c7ccb4a30e800b
@@ -23024,7 +22768,7 @@ index 0000000000000000000000000000000000000000..689ce367164e79e0426eeecb81dbbc52
+ private SaveUtil() {}
+}
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
-index a6779295bff446ee79e7c9d41e405447becc2966..efc7f4071655201c59c912e9c84e35a8da66e34c 100644
+index 764daee7cd619c56314bcea9a4c35702afcb262d..e54355728183c594643f2e28ba2e92b1502882ac 100644
--- a/io/papermc/paper/FeatureHooks.java
+++ b/io/papermc/paper/FeatureHooks.java
@@ -1,6 +1,8 @@
@@ -23036,7 +22780,7 @@ index a6779295bff446ee79e7c9d41e405447becc2966..efc7f4071655201c59c912e9c84e35a8
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.longs.LongSets;
-@@ -29,9 +31,12 @@ import org.bukkit.World;
+@@ -30,9 +32,12 @@ import org.bukkit.World;
public final class FeatureHooks {
public static void initChunkTaskScheduler(final boolean useParallelGen) {
@@ -23471,7 +23215,7 @@ index 0000000000000000000000000000000000000000..8424cf9d4617b4732d44cc460d25b044
+
+}
diff --git a/net/minecraft/core/Direction.java b/net/minecraft/core/Direction.java
-index 690e1d2394e68356c56a39ac083cc53ee0388d71..928f38fd6beb00753c92ae9f4678f7507519a39b 100644
+index 3d3eec1db91cb47395f40c4f47aa77164ad42175..216f97207dac88cc1dc3df59c6ee8a62c7614b4a 100644
--- a/net/minecraft/core/Direction.java
+++ b/net/minecraft/core/Direction.java
@@ -28,7 +28,7 @@ import org.joml.Quaternionf;
@@ -23529,7 +23273,7 @@ index 690e1d2394e68356c56a39ac083cc53ee0388d71..928f38fd6beb00753c92ae9f4678f750
+ // Paper end - optimise collisions
private Direction(
- final int id,
+ final int data3d,
@@ -147,14 +187,13 @@ public enum Direction implements StringRepresentable {
}
@@ -23580,7 +23324,7 @@ index 690e1d2394e68356c56a39ac083cc53ee0388d71..928f38fd6beb00753c92ae9f4678f750
+ // Paper end - optimise collisions
}
diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java
-index 063630c1ffcce099139c59d598fc5a210e21f640..a61153c5d99bdc26f37a10f33baf839e943e17e1 100644
+index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff642b19ed 100644
--- a/net/minecraft/core/MappedRegistry.java
+++ b/net/minecraft/core/MappedRegistry.java
@@ -50,6 +50,19 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
@@ -23600,53 +23344,44 @@ index 063630c1ffcce099139c59d598fc5a210e21f640..a61153c5d99bdc26f37a10f33baf839e
+ }
+ // Paper end - fluid method optimisations
+
- public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
- this(key, lifecycle, false);
+ public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle registryLifecycle) {
+ this(key, registryLifecycle, false);
}
@@ -114,6 +127,7 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
- this.toId.put(value, i);
- this.registrationInfos.put(key, info);
- this.registryLifecycle = this.registryLifecycle.add(info.lifecycle());
+ this.toId.put(value, size);
+ this.registrationInfos.put(key, registrationInfo);
+ this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
+ this.injectFluidRegister(key, value); // Paper - fluid method optimisations
return reference;
}
}
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
-index 731bdabd53fd4a3d17494f26781223097a5d6e16..42d46c7a7437bea5335a23cbee5708ac57131474 100644
+index 4437283a5d157eede121b98be0112c1067eded5e..e627618f2368258d7cb9cd35908d0f42a9c504f5 100644
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
-@@ -322,6 +322,7 @@ public class Main {
-
- convertable_conversionsession.saveDataTag(iregistrycustom_dimension, savedata);
+@@ -320,6 +320,7 @@ public class Main {
+ WorldData worldData = worldStem.worldData();
+ levelStorageAccess.saveDataTag(frozen, worldData);
*/
+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName()); // Paper - load this sync so it won't fail later async
- final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
- DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius);
-
+ final DedicatedServer dedicatedServer = MinecraftServer.spin(
+ thread1 -> {
+ DedicatedServer dedicatedServer1 = new DedicatedServer(
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 807d05097f7313361eadb600187421d25e294413..5e7ba47247fc9b6bc8da86d8f67c6cd923cd0b1e 100644
+index 646c2f2b617ed706021c83c9fc4492860dfdd4e9..b4dcb4178b49af49cf6e654788efda3dd10c767e 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
-@@ -204,7 +204,7 @@ import org.bukkit.event.server.ServerLoadEvent;
- // CraftBukkit end
-
+@@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2;
+ import net.minecraft.world.phys.Vec3;
+ import org.slf4j.Logger;
-public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource {
+public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements ServerInfo, ChunkIOErrorReporter, CommandSource, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system
-
private static MinecraftServer SERVER; // Paper
public static final Logger LOGGER = LogUtils.getLogger();
-@@ -333,7 +333,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
- ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
- AtomicReference<S> atomicreference = new AtomicReference();
-- Thread thread = new Thread(() -> {
-+ Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system
- ((MinecraftServer) atomicreference.get()).runServer();
- }, "Server thread");
-
-@@ -352,6 +352,77 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- return s0;
+ public static final net.kyori.adventure.text.logger.slf4j.ComponentLogger COMPONENT_LOGGER = net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(LOGGER.getName()); // Paper
+@@ -316,6 +316,77 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ return minecraftServer;
}
+ // Paper start - rewrite chunk system
@@ -23720,73 +23455,71 @@ index 807d05097f7313361eadb600187421d25e294413..5e7ba47247fc9b6bc8da86d8f67c6cd9
+ }
+ // Paper end - rewrite chunk system
+
- public MinecraftServer(OptionSet options, WorldLoader.DataLoadContext worldLoader, Thread thread, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PackRepository resourcepackrepository, WorldStem worldstem, Proxy proxy, DataFixer datafixer, Services services, ChunkProgressListenerFactory worldloadlistenerfactory) {
- super("Server");
- SERVER = this; // Paper - better singleton
-@@ -672,7 +743,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ public MinecraftServer(
+ // CraftBukkit start
+ joptsimple.OptionSet options,
+@@ -626,7 +697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.forceDifficulty();
- for (ServerLevel worldserver : this.getAllLevels()) {
- this.prepareLevels(worldserver.getChunkSource().chunkMap.progressListener, worldserver);
-- worldserver.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
+ for (ServerLevel serverLevel : this.getAllLevels()) {
+ this.prepareLevels(serverLevel.getChunkSource().chunkMap.progressListener, serverLevel);
+- serverLevel.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
+ // Paper - rewrite chunk system
- this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld()));
+ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(serverLevel.getWorld()));
}
-@@ -888,6 +959,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -825,6 +896,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public abstract boolean shouldRconBroadcast();
- public boolean saveAllChunks(boolean suppressLogs, boolean flush, boolean force) {
+ public boolean saveAllChunks(boolean suppressLog, boolean flush, boolean forced) {
+ // Paper start - add close param
-+ return this.saveAllChunks(suppressLogs, flush, force, false);
++ return this.saveAllChunks(suppressLog, flush, forced, false);
+ }
-+ public boolean saveAllChunks(boolean suppressLogs, boolean flush, boolean force, boolean close) {
++ public boolean saveAllChunks(boolean suppressLog, boolean flush, boolean forced, boolean close) {
+ // Paper end - add close param
- boolean flag3 = false;
+ boolean flag = false;
- for (Iterator iterator = this.getAllLevels().iterator(); iterator.hasNext(); flag3 = true) {
-@@ -897,7 +973,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- MinecraftServer.LOGGER.info("Saving chunks for level '{}'/{}", worldserver, worldserver.dimension().location());
+ for (ServerLevel serverLevel : this.getAllLevels()) {
+@@ -832,7 +908,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ LOGGER.info("Saving chunks for level '{}'/{}", serverLevel, serverLevel.dimension().location());
}
-- worldserver.save((ProgressListener) null, flush, worldserver.noSave && !force);
-+ worldserver.save((ProgressListener) null, flush, worldserver.noSave && !force, close); // Paper - add close param
+- serverLevel.save(null, flush, serverLevel.noSave && !forced);
++ serverLevel.save(null, flush, serverLevel.noSave && !forced, close); // Paper - add close param
+ flag = true;
}
- // CraftBukkit start - moved to WorldServer.save
-@@ -998,7 +1074,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -923,7 +999,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
-- while (this.levels.values().stream().anyMatch((worldserver1) -> {
-+ while (false && this.levels.values().stream().anyMatch((worldserver1) -> { // Paper - rewrite chunk system
- return worldserver1.getChunkSource().chunkMap.hasWork();
- })) {
+- while (this.levels.values().stream().anyMatch(level -> level.getChunkSource().chunkMap.hasWork())) {
++ while (false && this.levels.values().stream().anyMatch(level -> level.getChunkSource().chunkMap.hasWork())) { // Paper - rewrite chunk system
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
-@@ -1015,19 +1091,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+
+ for (ServerLevel serverLevelx : this.getAllLevels()) {
+@@ -934,17 +1010,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.waitUntilNextTick();
}
- this.saveAllChunks(false, true, false);
-- iterator = this.getAllLevels().iterator();
-
-- while (iterator.hasNext()) {
-- worldserver = (ServerLevel) iterator.next();
-- if (worldserver != null) {
+- for (ServerLevel serverLevelx : this.getAllLevels()) {
+- if (serverLevelx != null) {
- try {
-- worldserver.close();
-- } catch (IOException ioexception) {
-- MinecraftServer.LOGGER.error("Exception closing the level", ioexception);
+- serverLevelx.close();
+- } catch (IOException var5) {
+- LOGGER.error("Exception closing the level", (Throwable)var5);
- }
- }
- }
-+ this.saveAllChunks(false, true, true, true); // Paper - rewrite chunk system
++ this.saveAllChunks(false, true, false, true); // Paper - rewrite chunk system
this.isSaving = false;
this.resources.close();
-@@ -1047,6 +1111,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -963,6 +1029,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving
}
// Spigot end
-
+ // Paper start - rewrite chunk system
+ LOGGER.info("Waiting for I/O tasks to complete...");
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.flush((MinecraftServer)(Object)this);
@@ -23798,21 +23531,21 @@ index 807d05097f7313361eadb600187421d25e294413..5e7ba47247fc9b6bc8da86d8f67c6cd9
}
public String getLocalIp() {
-@@ -1228,6 +1300,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- this.tickServer(flag ? () -> {
- return false;
- } : this::haveTime);
-+ // Paper start - rewrite chunk system
-+ final Throwable crash = this.chunkSystemCrash;
-+ if (crash != null) {
-+ this.chunkSystemCrash = null;
-+ throw new RuntimeException("Chunk system crash propagated to tick()", crash);
-+ }
-+ // Paper end - rewrite chunk system
- this.tickFrame.end();
- gameprofilerfiller.popPush("nextTickWait");
- this.mayHaveDelayedTasks = true;
-@@ -1432,6 +1511,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1133,6 +1207,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ profilerFiller.push("tick");
+ this.tickFrame.start();
+ this.tickServer(flag ? () -> false : this::haveTime);
++ // Paper start - rewrite chunk system
++ final Throwable crash = this.chunkSystemCrash;
++ if (crash != null) {
++ this.chunkSystemCrash = null;
++ throw new RuntimeException("Chunk system crash propagated to tick()", crash);
++ }
++ // Paper end - rewrite chunk system
+ this.tickFrame.end();
+ profilerFiller.popPush("nextTickWait");
+ this.mayHaveDelayedTasks = true;
+@@ -1305,6 +1386,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private boolean pollTaskInternal() {
if (super.pollTask()) {
@@ -23820,8 +23553,8 @@ index 807d05097f7313361eadb600187421d25e294413..5e7ba47247fc9b6bc8da86d8f67c6cd9
return true;
} else {
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
-@@ -2713,6 +2793,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
-
+@@ -2425,6 +2507,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ }
}
+ // Paper start - rewrite chunk system
@@ -23830,23 +23563,22 @@ index 807d05097f7313361eadb600187421d25e294413..5e7ba47247fc9b6bc8da86d8f67c6cd9
+ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThread();
+ }
+ // Paper end - rewrite chunk system
-+
+
// CraftBukkit start
public boolean isDebugging() {
- return false;
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
-index 2f47d95943c00020a24ea3ff1a49e64e114de675..0dd9ed7465d222505d5368781654ec4954f6e5c3 100644
+index 1ad96b964cdcf10b9f81d32d07e03c1a0ab6fe0a..ab356d1afb352f1f134d25dfa17ce5476a2039cd 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -458,7 +458,33 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
- return world.dimension() == net.minecraft.world.level.Level.NETHER ? this.getProperties().allowNether : true;
+@@ -432,7 +432,33 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+ return level.dimension() != Level.NETHER || this.getProperties().allowNether;
}
+ private static final java.util.concurrent.atomic.AtomicInteger ASYNC_DEBUG_CHUNKS_COUNT = new java.util.concurrent.atomic.AtomicInteger(); // Paper - rewrite chunk system
+
- public void handleConsoleInput(String command, CommandSourceStack commandSource) {
+ public void handleConsoleInput(String msg, CommandSourceStack source) {
+ // Paper start - rewrite chunk system
-+ if (command.equalsIgnoreCase("paper debug chunks --async")) {
++ if (msg.equalsIgnoreCase("paper debug chunks --async")) {
+ LOGGER.info("Scheduling async debug chunks");
+ Runnable run = () -> {
+ LOGGER.info("Async debug chunks executing");
@@ -23869,42 +23601,41 @@ index 2f47d95943c00020a24ea3ff1a49e64e114de675..0dd9ed7465d222505d5368781654ec49
+ return;
+ }
+ // Paper end - rewrite chunk system
- this.serverCommandQueue.add(new ConsoleInput(command, commandSource)); // Paper - Perf: use proper queue
+ this.serverCommandQueue.add(new ConsoleInput(msg, source)); // Paper - Perf: use proper queue
}
diff --git a/net/minecraft/server/level/ChunkHolder.java b/net/minecraft/server/level/ChunkHolder.java
-index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f977e09e7e0 100644
+index cc63e49b7d1b4ba6e8df87aff4cf71036d3de5c5..a37cc96ec26c92a60b0f0ca43d48705cd2bb072e 100644
--- a/net/minecraft/server/level/ChunkHolder.java
+++ b/net/minecraft/server/level/ChunkHolder.java
-@@ -32,46 +32,125 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
- import net.minecraft.server.MinecraftServer;
- // CraftBukkit end
+@@ -29,27 +29,112 @@ import net.minecraft.world.level.chunk.LevelChunkSection;
+ import net.minecraft.world.level.chunk.status.ChunkStatus;
+ import net.minecraft.world.level.lighting.LevelLightEngine;
-public class ChunkHolder extends GenerationChunkHolder {
+public class ChunkHolder extends GenerationChunkHolder implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder { // Paper - rewrite chunk system
-
public static final ChunkResult<LevelChunk> UNLOADED_LEVEL_CHUNK = ChunkResult.error("Unloaded level chunk");
- private static final CompletableFuture<ChunkResult<LevelChunk>> UNLOADED_LEVEL_CHUNK_FUTURE = CompletableFuture.completedFuture(ChunkHolder.UNLOADED_LEVEL_CHUNK);
+ private static final CompletableFuture<ChunkResult<LevelChunk>> UNLOADED_LEVEL_CHUNK_FUTURE = CompletableFuture.completedFuture(UNLOADED_LEVEL_CHUNK);
private final LevelHeightAccessor levelHeightAccessor;
-- private volatile CompletableFuture<ChunkResult<LevelChunk>> fullChunkFuture; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage
-- private volatile CompletableFuture<ChunkResult<LevelChunk>> tickingChunkFuture; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage
-- private volatile CompletableFuture<ChunkResult<LevelChunk>> entityTickingChunkFuture; private volatile boolean isEntityTickingReady; // Paper - cache chunk ticking stage
+- private volatile CompletableFuture<ChunkResult<LevelChunk>> fullChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE; private int fullChunkCreateCount; private volatile boolean isFullChunkReady; // Paper - cache chunk ticking stage
+- private volatile CompletableFuture<ChunkResult<LevelChunk>> tickingChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE; private volatile boolean isTickingReady; // Paper - cache chunk ticking stage
+- private volatile CompletableFuture<ChunkResult<LevelChunk>> entityTickingChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE; private volatile boolean isEntityTickingReady; // Paper - cache chunk ticking stage
- public int oldTicketLevel;
- private int ticketLevel;
- private int queueLevel;
+ // Paper - rewrite chunk system
private boolean hasChangedSections;
private final ShortSet[] changedBlocksPerSection;
- private final BitSet blockChangedLightSectionFilter;
- private final BitSet skyChangedLightSectionFilter;
+ private final BitSet blockChangedLightSectionFilter = new BitSet();
+ private final BitSet skyChangedLightSectionFilter = new BitSet();
private final LevelLightEngine lightEngine;
- private final ChunkHolder.LevelChangeListener onLevelChange;
+ // Paper - rewrite chunk system
public final ChunkHolder.PlayerProvider playerProvider;
- private boolean wasAccessibleSinceLastSave;
-- private CompletableFuture<?> pendingFullStateConfirmation;
-- private CompletableFuture<?> sendSync;
-- private CompletableFuture<?> saveSync;
+- private CompletableFuture<?> pendingFullStateConfirmation = CompletableFuture.completedFuture(null);
+- private CompletableFuture<?> sendSync = CompletableFuture.completedFuture(null);
+- private CompletableFuture<?> saveSync = CompletableFuture.completedFuture(null);
+ // Paper - rewrite chunk system
+
+ // Paper start - rewrite chunk system
@@ -24000,31 +23731,23 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
+ }
+ // Paper end - rewrite chunk system
- public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
+ public ChunkHolder(
+ ChunkPos pos,
+@@ -62,11 +147,9 @@ public class ChunkHolder extends GenerationChunkHolder {
super(pos);
-- this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-- this.tickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-- this.entityTickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
+ this.levelHeightAccessor = levelHeightAccessor;
+ this.lightEngine = lightEngine;
+- this.onLevelChange = onLevelChange;
+ // Paper - rewrite chunk system
- this.blockChangedLightSectionFilter = new BitSet();
- this.skyChangedLightSectionFilter = new BitSet();
-- this.pendingFullStateConfirmation = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
-- this.sendSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
-- this.saveSync = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
-+ // Paper - rewrite chunk system
- this.levelHeightAccessor = world;
- this.lightEngine = lightingProvider;
-- this.onLevelChange = levelUpdateListener;
-+ // Paper - rewrite chunk system
- this.playerProvider = playersWatchingChunkProvider;
+ this.playerProvider = playerProvider;
- this.oldTicketLevel = ChunkLevel.MAX_LEVEL + 1;
- this.ticketLevel = this.oldTicketLevel;
- this.queueLevel = this.oldTicketLevel;
+ // Paper - rewrite chunk system
- this.setTicketLevel(level);
- this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()];
+ this.setTicketLevel(ticketLevel);
+ this.changedBlocksPerSection = new ShortSet[levelHeightAccessor.getSectionsCount()];
}
-@@ -79,7 +158,7 @@ public class ChunkHolder extends GenerationChunkHolder {
+@@ -74,7 +157,7 @@ public class ChunkHolder extends GenerationChunkHolder {
// CraftBukkit start
public LevelChunk getFullChunkNow() {
// Note: We use the oldTicketLevel for isLoaded checks.
@@ -24033,7 +23756,7 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
return this.getFullChunkNowUnchecked();
}
-@@ -89,64 +168,65 @@ public class ChunkHolder extends GenerationChunkHolder {
+@@ -84,58 +167,63 @@ public class ChunkHolder extends GenerationChunkHolder {
// CraftBukkit end
public CompletableFuture<ChunkResult<LevelChunk>> getTickingChunkFuture() {
@@ -24052,8 +23775,8 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
}
@Nullable
- public final LevelChunk getTickingChunk() { // Paper - final for inline
-- return (LevelChunk) ((ChunkResult) this.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).orElse(null); // CraftBukkit - decompile error
+ public LevelChunk getTickingChunk() {
+- return this.getTickingChunkFuture().getNow(UNLOADED_LEVEL_CHUNK).orElse(null);
+ // Paper start - rewrite chunk system
+ if (this.newChunkHolder.isTickingReady()) {
+ if (this.newChunkHolder.getCurrentChunk() instanceof LevelChunk levelChunk) {
@@ -24081,16 +23804,13 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- public void addSendDependency(CompletableFuture<?> postProcessingFuture) {
+ public void addSendDependency(CompletableFuture<?> dependency) {
- if (this.sendSync.isDone()) {
-- this.sendSync = postProcessingFuture;
+- this.sendSync = dependency;
- } else {
-- this.sendSync = this.sendSync.thenCombine(postProcessingFuture, (object, object1) -> {
-- return null;
-- });
+- this.sendSync = this.sendSync.thenCombine((CompletionStage<? extends Object>)dependency, (object, object1) -> null);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
-
}
public CompletableFuture<?> getSaveSyncFuture() {
@@ -24104,52 +23824,49 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
}
@Override
- protected void addSaveDependency(CompletableFuture<?> savingFuture) {
+ protected void addSaveDependency(CompletableFuture<?> dependency) {
- if (this.saveSync.isDone()) {
-- this.saveSync = savingFuture;
+- this.saveSync = dependency;
- } else {
-- this.saveSync = this.saveSync.thenCombine(savingFuture, (object, object1) -> {
-- return null;
-- });
+- this.saveSync = this.saveSync.thenCombine((CompletionStage<? extends Object>)dependency, (object, object1) -> null);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
-
}
public boolean blockChanged(BlockPos pos) {
-- LevelChunk chunk = this.getTickingChunk();
-+ LevelChunk chunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system
-
- if (chunk == null) {
+- LevelChunk tickingChunk = this.getTickingChunk();
++ LevelChunk tickingChunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system
+ if (tickingChunk == null) {
return false;
-@@ -172,7 +252,7 @@ public class ChunkHolder extends GenerationChunkHolder {
+ } else {
+@@ -158,7 +246,7 @@ public class ChunkHolder extends GenerationChunkHolder {
return false;
} else {
- ichunkaccess.markUnsaved();
-- LevelChunk chunk = this.getTickingChunk();
-+ LevelChunk chunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system
-
- if (chunk == null) {
+ chunkIfPresent.markUnsaved();
+- LevelChunk tickingChunk = this.getTickingChunk();
++ LevelChunk tickingChunk = this.playersSentChunkTo.size() == 0 ? null : this.getChunkToSend(); // Paper - rewrite chunk system
+ if (tickingChunk == null) {
return false;
-@@ -207,7 +287,7 @@ public class ChunkHolder extends GenerationChunkHolder {
- List list;
-
+ } else {
+@@ -188,7 +276,7 @@ public class ChunkHolder extends GenerationChunkHolder {
+ if (this.hasChangesToBroadcast()) {
+ Level level = chunk.getLevel();
if (!this.skyChangedLightSectionFilter.isEmpty() || !this.blockChangedLightSectionFilter.isEmpty()) {
-- list = this.playerProvider.getPlayers(this.pos, true);
-+ list = this.moonrise$getPlayers(true); // Paper - rewrite chunk system
- if (!list.isEmpty()) {
- ClientboundLightUpdatePacket packetplayoutlightupdate = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, this.skyChangedLightSectionFilter, this.blockChangedLightSectionFilter);
-
-@@ -219,7 +299,7 @@ public class ChunkHolder extends GenerationChunkHolder {
+- List<ServerPlayer> players = this.playerProvider.getPlayers(this.pos, true);
++ List<ServerPlayer> players = this.moonrise$getPlayers(true); // Paper - rewrite chunk system
+ if (!players.isEmpty()) {
+ ClientboundLightUpdatePacket clientboundLightUpdatePacket = new ClientboundLightUpdatePacket(
+ chunk.getPos(), this.lightEngine, this.skyChangedLightSectionFilter, this.blockChangedLightSectionFilter
+@@ -201,7 +289,7 @@ public class ChunkHolder extends GenerationChunkHolder {
}
if (this.hasChangedSections) {
-- list = this.playerProvider.getPlayers(this.pos, false);
-+ list = this.moonrise$getPlayers(false); // Paper - rewrite chunk system
+- List<ServerPlayer> players = this.playerProvider.getPlayers(this.pos, false);
++ List<ServerPlayer> players = this.moonrise$getPlayers(false); // Paper - rewrite chunk system
- for (int i = 0; i < this.changedBlocksPerSection.length; ++i) {
- ShortSet shortset = this.changedBlocksPerSection[i];
-@@ -285,201 +365,48 @@ public class ChunkHolder extends GenerationChunkHolder {
+ for (int i = 0; i < this.changedBlocksPerSection.length; i++) {
+ ShortSet set = this.changedBlocksPerSection[i];
+@@ -256,193 +344,50 @@ public class ChunkHolder extends GenerationChunkHolder {
@Override
public int getTicketLevel() {
@@ -24163,8 +23880,8 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void setQueueLevel(int level) {
-- this.queueLevel = level;
+ private void setQueueLevel(int queueLevel) {
+- this.queueLevel = queueLevel;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -24173,41 +23890,36 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
+ // Paper - rewrite chunk system
}
- private void scheduleFullChunkPromotion(ChunkMap chunkLoadingManager, CompletableFuture<ChunkResult<LevelChunk>> chunkFuture, Executor executor, FullChunkStatus target) {
+ private void scheduleFullChunkPromotion(
+ ChunkMap chunkMap, CompletableFuture<ChunkResult<LevelChunk>> future, Executor executor, FullChunkStatus fullChunkStatus
+ ) {
- this.pendingFullStateConfirmation.cancel(false);
-- CompletableFuture<Void> completablefuture1 = new CompletableFuture();
--
-- completablefuture1.thenRunAsync(() -> {
-- chunkLoadingManager.onFullChunkStatusChange(this.pos, target);
-- }, executor);
-- this.pendingFullStateConfirmation = completablefuture1;
-- chunkFuture.thenAccept((chunkresult) -> {
-- chunkresult.ifSuccess((chunk) -> {
-- completablefuture1.complete(null); // CraftBukkit - decompile error
-- });
-- });
+- CompletableFuture<Void> completableFuture = new CompletableFuture<>();
+- completableFuture.thenRunAsync(() -> chunkMap.onFullChunkStatusChange(this.pos, fullChunkStatus), executor);
+- this.pendingFullStateConfirmation = completableFuture;
+- future.thenAccept(chunkResult -> chunkResult.ifSuccess(levelChunk -> completableFuture.complete(null)));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void demoteFullChunk(ChunkMap chunkLoadingManager, FullChunkStatus target) {
+ private void demoteFullChunk(ChunkMap chunkMap, FullChunkStatus fullChunkStatus) {
- this.pendingFullStateConfirmation.cancel(false);
-- chunkLoadingManager.onFullChunkStatusChange(this.pos, target);
+- chunkMap.onFullChunkStatusChange(this.pos, fullChunkStatus);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
// CraftBukkit start
// ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
// SPIGOT-7780: Moved out of updateFutures to call all chunk unload events before calling updateHighestAllowedStatus for all chunks
- protected void callEventIfUnloading(ChunkMap playerchunkmap) {
+ protected void callEventIfUnloading(ChunkMap chunkMap) {
- FullChunkStatus oldFullChunkStatus = ChunkLevel.fullStatus(this.oldTicketLevel);
- FullChunkStatus newFullChunkStatus = ChunkLevel.fullStatus(this.ticketLevel);
- boolean oldIsFull = oldFullChunkStatus.isOrAfter(FullChunkStatus.FULL);
- boolean newIsFull = newFullChunkStatus.isOrAfter(FullChunkStatus.FULL);
- if (oldIsFull && !newIsFull) {
- this.getFullChunkFuture().thenAccept((either) -> {
-- LevelChunk chunk = (LevelChunk) either.orElse(null);
+- LevelChunk chunk = either.orElse(null);
- if (chunk != null) {
-- playerchunkmap.callbackExecutor.execute(() -> {
+- chunkMap.callbackExecutor.execute(() -> {
- // Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick
- // lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag.
- // These actions may however happen deferred, so we manually set the needsSaving flag already here.
@@ -24217,34 +23929,33 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
- }
- }).exceptionally((throwable) -> {
- // ensure exceptions are printed, by default this is not the case
-- MinecraftServer.LOGGER.error("Failed to schedule unload callback for chunk " + ChunkHolder.this.pos, throwable);
+- net.minecraft.server.MinecraftServer.LOGGER.error("Failed to schedule unload callback for chunk " + ChunkHolder.this.pos, throwable);
- return null;
- });
-
- // Run callback right away if the future was already done
-- playerchunkmap.callbackExecutor.run();
+- chunkMap.callbackExecutor.run();
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
// CraftBukkit end
- protected void updateFutures(ChunkMap chunkLoadingManager, Executor executor) {
-- FullChunkStatus fullchunkstatus = ChunkLevel.fullStatus(this.oldTicketLevel);
-- FullChunkStatus fullchunkstatus1 = ChunkLevel.fullStatus(this.ticketLevel);
-- boolean flag = fullchunkstatus.isOrAfter(FullChunkStatus.FULL);
-- boolean flag1 = fullchunkstatus1.isOrAfter(FullChunkStatus.FULL);
--
-- this.wasAccessibleSinceLastSave |= flag1;
-- if (!flag && flag1) {
+ protected void updateFutures(ChunkMap chunkMap, Executor executor) {
+- FullChunkStatus fullChunkStatus = ChunkLevel.fullStatus(this.oldTicketLevel);
+- FullChunkStatus fullChunkStatus1 = ChunkLevel.fullStatus(this.ticketLevel);
+- boolean isOrAfter = fullChunkStatus.isOrAfter(FullChunkStatus.FULL);
+- boolean isOrAfter1 = fullChunkStatus1.isOrAfter(FullChunkStatus.FULL);
+- this.wasAccessibleSinceLastSave |= isOrAfter1;
+- if (!isOrAfter && isOrAfter1) {
- int expectCreateCount = ++this.fullChunkCreateCount; // Paper
-- this.fullChunkFuture = chunkLoadingManager.prepareAccessibleChunk(this);
-- this.scheduleFullChunkPromotion(chunkLoadingManager, this.fullChunkFuture, executor, FullChunkStatus.FULL);
+- this.fullChunkFuture = chunkMap.prepareAccessibleChunk(this);
+- this.scheduleFullChunkPromotion(chunkMap, this.fullChunkFuture, executor, FullChunkStatus.FULL);
- // Paper start - cache ticking ready status
- this.fullChunkFuture.thenAccept(chunkResult -> {
- chunkResult.ifSuccess(chunk -> {
- if (ChunkHolder.this.fullChunkCreateCount == expectCreateCount) {
- ChunkHolder.this.isFullChunkReady = true;
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkBorder(chunk, this);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkBorder(chunk, this);
- }
- });
- });
@@ -24252,99 +23963,97 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
- this.addSaveDependency(this.fullChunkFuture);
- }
-
-- if (flag && !flag1) {
+- if (isOrAfter && !isOrAfter1) {
- // Paper start
- if (this.isFullChunkReady) {
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper
- }
- // Paper end
-- this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK);
-- this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
+- this.fullChunkFuture.complete(UNLOADED_LEVEL_CHUNK);
+- this.fullChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE;
- }
-
-- boolean flag2 = fullchunkstatus.isOrAfter(FullChunkStatus.BLOCK_TICKING);
-- boolean flag3 = fullchunkstatus1.isOrAfter(FullChunkStatus.BLOCK_TICKING);
--
-- if (!flag2 && flag3) {
-- this.tickingChunkFuture = chunkLoadingManager.prepareTickingChunk(this);
-- this.scheduleFullChunkPromotion(chunkLoadingManager, this.tickingChunkFuture, executor, FullChunkStatus.BLOCK_TICKING);
+- boolean isOrAfter2 = fullChunkStatus.isOrAfter(FullChunkStatus.BLOCK_TICKING);
+- boolean isOrAfter3 = fullChunkStatus1.isOrAfter(FullChunkStatus.BLOCK_TICKING);
+- if (!isOrAfter2 && isOrAfter3) {
+- this.tickingChunkFuture = chunkMap.prepareTickingChunk(this);
+- this.scheduleFullChunkPromotion(chunkMap, this.tickingChunkFuture, executor, FullChunkStatus.BLOCK_TICKING);
- // Paper start - cache ticking ready status
- this.tickingChunkFuture.thenAccept(chunkResult -> {
- chunkResult.ifSuccess(chunk -> {
- // note: Here is a very good place to add callbacks to logic waiting on this.
- ChunkHolder.this.isTickingReady = true;
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkTicking(chunk, this);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkTicking(chunk, this);
- });
- });
- // Paper end
- this.addSaveDependency(this.tickingChunkFuture);
- }
-
-- if (flag2 && !flag3) {
+- if (isOrAfter2 && !isOrAfter3) {
- // Paper start
- if (this.isTickingReady) {
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper
- }
- // Paper end
- this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage
-- this.tickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
+- this.tickingChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE;
- }
-
-- boolean flag4 = fullchunkstatus.isOrAfter(FullChunkStatus.ENTITY_TICKING);
-- boolean flag5 = fullchunkstatus1.isOrAfter(FullChunkStatus.ENTITY_TICKING);
--
-- if (!flag4 && flag5) {
-- if (this.entityTickingChunkFuture != ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE) {
-- throw (IllegalStateException) Util.pauseInIde(new IllegalStateException());
+- boolean isOrAfter4 = fullChunkStatus.isOrAfter(FullChunkStatus.ENTITY_TICKING);
+- boolean isOrAfter5 = fullChunkStatus1.isOrAfter(FullChunkStatus.ENTITY_TICKING);
+- if (!isOrAfter4 && isOrAfter5) {
+- if (this.entityTickingChunkFuture != UNLOADED_LEVEL_CHUNK_FUTURE) {
+- throw (IllegalStateException)Util.pauseInIde(new IllegalStateException());
- }
-
-- this.entityTickingChunkFuture = chunkLoadingManager.prepareEntityTickingChunk(this);
-- this.scheduleFullChunkPromotion(chunkLoadingManager, this.entityTickingChunkFuture, executor, FullChunkStatus.ENTITY_TICKING);
+- this.entityTickingChunkFuture = chunkMap.prepareEntityTickingChunk(this);
+- this.scheduleFullChunkPromotion(chunkMap, this.entityTickingChunkFuture, executor, FullChunkStatus.ENTITY_TICKING);
- // Paper start - cache ticking ready status
- this.entityTickingChunkFuture.thenAccept(chunkResult -> {
- chunkResult.ifSuccess(chunk -> {
- ChunkHolder.this.isEntityTickingReady = true;
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkEntityTicking(chunk, this);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkEntityTicking(chunk, this);
- });
- });
- // Paper end
- this.addSaveDependency(this.entityTickingChunkFuture);
- }
-
-- if (flag4 && !flag5) {
+- if (isOrAfter4 && !isOrAfter5) {
- // Paper start
- if (this.isEntityTickingReady) {
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this);
- }
- // Paper end
- this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
-- this.entityTickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
+- this.entityTickingChunkFuture = UNLOADED_LEVEL_CHUNK_FUTURE;
- }
-
-- if (!fullchunkstatus1.isOrAfter(fullchunkstatus)) {
-- this.demoteFullChunk(chunkLoadingManager, fullchunkstatus1);
+- if (!fullChunkStatus1.isOrAfter(fullChunkStatus)) {
+- this.demoteFullChunk(chunkMap, fullChunkStatus1);
- }
-
- this.onLevelChange.onLevelChange(this.pos, this::getQueueLevel, this.ticketLevel, this::setQueueLevel);
- this.oldTicketLevel = this.ticketLevel;
- // CraftBukkit start
- // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins.
-- if (!fullchunkstatus.isOrAfter(FullChunkStatus.FULL) && fullchunkstatus1.isOrAfter(FullChunkStatus.FULL)) {
+- if (!fullChunkStatus.isOrAfter(FullChunkStatus.FULL) && fullChunkStatus1.isOrAfter(FullChunkStatus.FULL)) {
- this.getFullChunkFuture().thenAccept((either) -> {
- LevelChunk chunk = (LevelChunk) either.orElse(null);
- if (chunk != null) {
-- chunkLoadingManager.callbackExecutor.execute(() -> {
+- chunkMap.callbackExecutor.execute(() -> {
- chunk.loadCallback();
- });
- }
- }).exceptionally((throwable) -> {
- // ensure exceptions are printed, by default this is not the case
-- MinecraftServer.LOGGER.error("Failed to schedule load callback for chunk " + ChunkHolder.this.pos, throwable);
+- net.minecraft.server.MinecraftServer.LOGGER.error("Failed to schedule load callback for chunk " + ChunkHolder.this.pos, throwable);
- return null;
- });
-
- // Run callback right away if the future was already done
-- chunkLoadingManager.callbackExecutor.run();
+- chunkMap.callbackExecutor.run();
- }
- // CraftBukkit end
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
@@ -24362,7 +24071,7 @@ index b9ab241b930edc63a39dbbcf14cd0b5edacb9ea9..8dd9375f2ad2c65a773a3195aeff1f97
@FunctionalInterface
diff --git a/net/minecraft/server/level/ChunkLevel.java b/net/minecraft/server/level/ChunkLevel.java
-index 11b30b6daa1d049634350e34502c701e9800add4..fae17a075d7efaf24d916877dd5968eb9652bb66 100644
+index e823b8aac00158892538083bc877ccf99895909a..7d871318065f19540748363809de82652613e733 100644
--- a/net/minecraft/server/level/ChunkLevel.java
+++ b/net/minecraft/server/level/ChunkLevel.java
@@ -7,8 +7,8 @@ import net.minecraft.world.level.chunk.status.ChunkStep;
@@ -24377,50 +24086,50 @@ index 11b30b6daa1d049634350e34502c701e9800add4..fae17a075d7efaf24d916877dd5968eb
private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL);
public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius();
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
-index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e11526dfd7c2f 100644
+index 8c1eea5339b650bd1527b5b3aa010c12d70a6de1..86aaf32de5d80ee222cbe7eff0f6c119a032e04f 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
-@@ -108,7 +108,7 @@ import org.slf4j.Logger;
- import org.bukkit.craftbukkit.generator.CustomChunkGenerator;
- // CraftBukkit end
+@@ -96,7 +96,7 @@ import net.minecraft.world.level.storage.LevelStorageSource;
+ import org.apache.commons.lang3.mutable.MutableBoolean;
+ import org.slf4j.Logger;
-public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider, GeneratingChunkMap {
+public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider, GeneratingChunkMap, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemChunkMap { // Paper - rewrite chunk system
-
private static final ChunkResult<List<ChunkAccess>> UNLOADED_CHUNK_LIST_RESULT = ChunkResult.error("Unloaded chunks found in range");
- private static final CompletableFuture<ChunkResult<List<ChunkAccess>>> UNLOADED_CHUNK_LIST_FUTURE = CompletableFuture.completedFuture(ChunkMap.UNLOADED_CHUNK_LIST_RESULT);
-@@ -123,10 +123,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private static final CompletableFuture<ChunkResult<List<ChunkAccess>>> UNLOADED_CHUNK_LIST_FUTURE = CompletableFuture.completedFuture(
+ UNLOADED_CHUNK_LIST_RESULT
+@@ -112,10 +112,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public static final int MIN_VIEW_DISTANCE = 2;
public static final int MAX_VIEW_DISTANCE = 32;
public static final int FORCED_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING);
-- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
-- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
-- private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
-- private final List<ChunkGenerationTask> pendingGenerationTasks;
+- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap<>();
+- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap = this.updatingChunkMap.clone();
+- private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads = new Long2ObjectLinkedOpenHashMap<>();
+- private final List<ChunkGenerationTask> pendingGenerationTasks = new ArrayList<>();
+ // Paper - rewrite chunk system
public final ServerLevel level;
private final ThreadedLevelLightEngine lightEngine;
private final BlockableEventLoop<Runnable> mainThreadExecutor;
-@@ -136,22 +133,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -125,22 +122,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final PoiManager poiManager;
- public final LongSet toDrop;
+ public final LongSet toDrop = new LongOpenHashSet();
private boolean modified;
- private final ChunkTaskDispatcher worldgenTaskDispatcher;
- private final ChunkTaskDispatcher lightTaskDispatcher;
+ // Paper - rewrite chunk system
public final ChunkProgressListener progressListener;
private final ChunkStatusUpdateListener chunkStatusListener;
- public final ChunkMap.ChunkDistanceManager distanceManager;
-- private final AtomicInteger tickingGenerated;
-+ public final AtomicInteger tickingGenerated; // Paper - public
+ public final ChunkMap.DistanceManager distanceManager;
+- private final AtomicInteger tickingGenerated = new AtomicInteger();
++ public final AtomicInteger tickingGenerated = new AtomicInteger(); // Paper - public
private final String storageName;
- private final PlayerMap playerMap;
- public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap;
- private final Long2ByteMap chunkTypeCache;
-- private final Long2LongMap nextChunkSaveTime;
-- private final LongSet chunksToEagerlySave;
-- private final Queue<Runnable> unloadQueue;
-- private final AtomicInteger activeChunkWrites;
+ private final PlayerMap playerMap = new PlayerMap();
+ public final Int2ObjectMap<ChunkMap.TrackedEntity> entityMap = new Int2ObjectOpenHashMap<>();
+ private final Long2ByteMap chunkTypeCache = new Long2ByteOpenHashMap();
+- private final Long2LongMap nextChunkSaveTime = new Long2LongOpenHashMap();
+- private final LongSet chunksToEagerlySave = new LongLinkedOpenHashSet();
+- private final Queue<Runnable> unloadQueue = Queues.newConcurrentLinkedQueue();
+- private final AtomicInteger activeChunkWrites = new AtomicInteger();
+ // Paper - rewrite chunk system
public int serverViewDistance;
- private final WorldGenContext worldGenContext;
@@ -24428,7 +24137,7 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
-@@ -176,24 +169,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -165,9 +158,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start
public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) {
@@ -24444,62 +24153,50 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ }
+ // Paper end - rewrite chunk system
- public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
- super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
-- this.visibleChunkMap = this.updatingChunkMap.clone();
-- this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
-- this.pendingGenerationTasks = new ArrayList();
-+ // Paper - rewrite chunk system
- this.toDrop = new LongOpenHashSet();
- this.tickingGenerated = new AtomicInteger();
- this.playerMap = new PlayerMap();
- this.entityMap = new Int2ObjectOpenHashMap();
- this.chunkTypeCache = new Long2ByteOpenHashMap();
-- this.nextChunkSaveTime = new Long2LongOpenHashMap();
-- this.chunksToEagerlySave = new LongLinkedOpenHashSet();
-- this.unloadQueue = Queues.newConcurrentLinkedQueue();
-- this.activeChunkWrites = new AtomicInteger();
+ public ChunkMap(
+ ServerLevel level,
+@@ -213,10 +213,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ this.progressListener = progressListener;
+ this.chunkStatusListener = chunkStatusListener;
+ ConsecutiveExecutor consecutiveExecutor1 = new ConsecutiveExecutor(dispatcher, "light");
+- this.worldgenTaskDispatcher = new ChunkTaskDispatcher(consecutiveExecutor, dispatcher);
+- this.lightTaskDispatcher = new ChunkTaskDispatcher(consecutiveExecutor1, dispatcher);
+ // Paper - rewrite chunk system
- Path path = session.getDimensionPath(world.dimension());
-
- this.storageName = path.getFileName().toString();
-@@ -221,18 +216,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- this.chunkStatusListener = chunkStatusChangeListener;
- ConsecutiveExecutor consecutiveexecutor1 = new ConsecutiveExecutor(executor, "light");
-
-- this.worldgenTaskDispatcher = new ChunkTaskDispatcher(consecutiveexecutor, executor);
-- this.lightTaskDispatcher = new ChunkTaskDispatcher(consecutiveexecutor1, executor);
-- this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), consecutiveexecutor1, this.lightTaskDispatcher);
-+ this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), consecutiveexecutor1, null); // Paper - rewrite chunk system
- this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor);
- this.overworldDataStorage = persistentStateManagerFactory;
- this.poiManager = new PoiManager(new RegionStorageInfo(session.getLevelId(), world.dimension(), "poi"), path.resolve("poi"), dataFixer, dsync, iregistrycustom, world.getServer(), world);
+ this.lightEngine = new ThreadedLevelLightEngine(
+- lightChunk, this, this.level.dimensionType().hasSkyLight(), consecutiveExecutor1, this.lightTaskDispatcher
++ lightChunk, this, this.level.dimensionType().hasSkyLight(), consecutiveExecutor1, null // Paper - rewrite chunk system
+ );
+ this.distanceManager = new ChunkMap.DistanceManager(dispatcher, mainThreadExecutor);
+ this.overworldDataStorage = overworldDataStorage;
+@@ -230,11 +229,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ level
+ );
this.setServerViewDistance(viewDistance);
-- this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, mainThreadExecutor, this::setChunkUnsaved);
-+ this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, null, this::setChunkUnsaved); // Paper - rewrite chunk system
+- this.worldGenContext = new WorldGenContext(level, generator, structureManager, this.lightEngine, mainThreadExecutor, this::setChunkUnsaved);
++ this.worldGenContext = new WorldGenContext(level, generator, structureManager, this.lightEngine, null, this::setChunkUnsaved); // Paper - rewrite chunk system
}
- private void setChunkUnsaved(ChunkPos pos) {
-- this.chunksToEagerlySave.add(pos.toLong());
+ private void setChunkUnsaved(ChunkPos chunkPos) {
+- this.chunksToEagerlySave.add(chunkPos.toLong());
+ // Paper - rewrite chunk system
}
// Paper start
-@@ -263,23 +256,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -264,23 +263,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) {
-- return player.getChunkTrackingView().contains(chunkX, chunkZ) && !player.connection.chunkSender.isPending(ChunkPos.asLong(chunkX, chunkZ));
-+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().isChunkSent(player, chunkX, chunkZ); // Paper - rewrite chunk system
+ boolean isChunkTracked(ServerPlayer player, int x, int z) {
+- return player.getChunkTrackingView().contains(x, z) && !player.connection.chunkSender.isPending(ChunkPos.asLong(x, z));
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().isChunkSent(player, x, z); // Paper - rewrite chunk system
}
- private boolean isChunkOnTrackedBorder(ServerPlayer player, int chunkX, int chunkZ) {
-- if (!this.isChunkTracked(player, chunkX, chunkZ)) {
+ private boolean isChunkOnTrackedBorder(ServerPlayer player, int x, int z) {
+- if (!this.isChunkTracked(player, x, z)) {
- return false;
- } else {
-- for (int k = -1; k <= 1; ++k) {
-- for (int l = -1; l <= 1; ++l) {
-- if ((k != 0 || l != 0) && !this.isChunkTracked(player, chunkX + k, chunkZ + l)) {
+- for (int i = -1; i <= 1; i++) {
+- for (int i1 = -1; i1 <= 1; i1++) {
+- if ((i != 0 || i1 != 0) && !this.isChunkTracked(player, x + i, z + i1)) {
- return true;
- }
- }
@@ -24507,15 +24204,15 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
-
- return false;
- }
-+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().isChunkSent(player, chunkX, chunkZ, true); // Paper - rewrite chunk system
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().isChunkSent(player, x, z, true); // Paper - rewrite chunk system
}
protected ThreadedLevelLightEngine getLightEngine() {
-@@ -288,20 +269,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -289,21 +276,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@Nullable
- protected ChunkHolder getUpdatingChunkIfPresent(long pos) {
-- return (ChunkHolder) this.updatingChunkMap.get(pos);
+ protected ChunkHolder getUpdatingChunkIfPresent(long chunkPos) {
+- return this.updatingChunkMap.get(chunkPos);
+ // Paper start - rewrite chunk system
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(pos);
+ return holder == null ? null : holder.vanillaChunkHolder;
@@ -24523,73 +24220,65 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
}
@Nullable
- public ChunkHolder getVisibleChunkIfPresent(long pos) {
-- return (ChunkHolder) this.visibleChunkMap.get(pos);
+ public ChunkHolder getVisibleChunkIfPresent(long chunkPos) {
+- return this.visibleChunkMap.get(chunkPos);
+ // Paper start - rewrite chunk system
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(pos);
+ return holder == null ? null : holder.vanillaChunkHolder;
+ // Paper end - rewrite chunk system
}
- protected IntSupplier getChunkQueueLevel(long pos) {
+ protected IntSupplier getChunkQueueLevel(long chunkPos) {
- return () -> {
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
--
-- return playerchunk == null ? ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1 : Math.min(playerchunk.getQueueLevel(), ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1);
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(chunkPos);
+- return visibleChunkIfPresent == null
+- ? ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1
+- : Math.min(visibleChunkIfPresent.getQueueLevel(), ChunkTaskPriorityQueue.PRIORITY_LEVEL_COUNT - 1);
- };
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- public String getChunkDebugData(ChunkPos chunkPos) {
-@@ -330,56 +313,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ public String getChunkDebugData(ChunkPos pos) {
+@@ -329,47 +317,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- private CompletableFuture<ChunkResult<List<ChunkAccess>>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction<ChunkStatus> distanceToStatus) {
-- if (margin == 0) {
-- ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(0);
--
-- return centerChunk.scheduleChunkGenerationTask(chunkstatus, this).thenApply((chunkresult) -> {
-- return chunkresult.map(List::of);
-- });
+ private CompletableFuture<ChunkResult<List<ChunkAccess>>> getChunkRangeFuture(ChunkHolder chunkHolder, int range, IntFunction<ChunkStatus> statusGetter) {
+- if (range == 0) {
+- ChunkStatus chunkStatus = statusGetter.apply(0);
+- return chunkHolder.scheduleChunkGenerationTask(chunkStatus, this).thenApply(chunkResult -> chunkResult.map(List::of));
- } else {
-- int j = Mth.square(margin * 2 + 1);
-- List<CompletableFuture<ChunkResult<ChunkAccess>>> list = new ArrayList(j);
-- ChunkPos chunkcoordintpair = centerChunk.getPos();
--
-- for (int k = -margin; k <= margin; ++k) {
-- for (int l = -margin; l <= margin; ++l) {
-- int i1 = Math.max(Math.abs(l), Math.abs(k));
-- long j1 = ChunkPos.asLong(chunkcoordintpair.x + l, chunkcoordintpair.z + k);
-- ChunkHolder playerchunk1 = this.getUpdatingChunkIfPresent(j1);
--
-- if (playerchunk1 == null) {
-- return ChunkMap.UNLOADED_CHUNK_LIST_FUTURE;
+- int squared = Mth.square(range * 2 + 1);
+- List<CompletableFuture<ChunkResult<ChunkAccess>>> list = new ArrayList<>(squared);
+- ChunkPos pos = chunkHolder.getPos();
+-
+- for (int i = -range; i <= range; i++) {
+- for (int i1 = -range; i1 <= range; i1++) {
+- int max = Math.max(Math.abs(i1), Math.abs(i));
+- long packedChunkPos = ChunkPos.asLong(pos.x + i1, pos.z + i);
+- ChunkHolder updatingChunkIfPresent = this.getUpdatingChunkIfPresent(packedChunkPos);
+- if (updatingChunkIfPresent == null) {
+- return UNLOADED_CHUNK_LIST_FUTURE;
- }
-
-- ChunkStatus chunkstatus1 = (ChunkStatus) distanceToStatus.apply(i1);
--
-- list.add(playerchunk1.scheduleChunkGenerationTask(chunkstatus1, this));
+- ChunkStatus chunkStatus1 = statusGetter.apply(max);
+- list.add(updatingChunkIfPresent.scheduleChunkGenerationTask(chunkStatus1, this));
- }
- }
-
-- return Util.sequence(list).thenApply((list1) -> {
-- List<ChunkAccess> list2 = new ArrayList(list1.size());
-- Iterator iterator = list1.iterator();
--
-- while (iterator.hasNext()) {
-- ChunkResult<ChunkAccess> chunkresult = (ChunkResult) iterator.next();
+- return Util.sequence(list).thenApply(list1 -> {
+- List<ChunkAccess> list2 = new ArrayList<>(list1.size());
-
-- if (chunkresult == null) {
+- for (ChunkResult<ChunkAccess> chunkResult : list1) {
+- if (chunkResult == null) {
- throw this.debugFuturesAndCreateReportedException(new IllegalStateException("At least one of the chunk futures were null"), "n/a");
- }
-
-- ChunkAccess ichunkaccess = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error
--
-- if (ichunkaccess == null) {
-- return ChunkMap.UNLOADED_CHUNK_LIST_RESULT;
+- ChunkAccess chunkAccess = chunkResult.orElse(null);
+- if (chunkAccess == null) {
+- return UNLOADED_CHUNK_LIST_RESULT;
- }
-
-- list2.add(ichunkaccess);
+- list2.add(chunkAccess);
- }
-
- return ChunkResult.of(list2);
@@ -24599,49 +24288,44 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
}
public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) {
-@@ -409,104 +343,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -401,95 +349,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- public CompletableFuture<ChunkResult<LevelChunk>> prepareEntityTickingChunk(ChunkHolder holder) {
-- return this.getChunkRangeFuture(holder, 2, (i) -> {
-- return ChunkStatus.FULL;
-- }).thenApply((chunkresult) -> {
-- return chunkresult.map((list) -> {
-- return (LevelChunk) list.get(list.size() / 2);
-- });
-- });
+ public CompletableFuture<ChunkResult<LevelChunk>> prepareEntityTickingChunk(ChunkHolder chunk) {
+- return this.getChunkRangeFuture(chunk, 2, i -> ChunkStatus.FULL)
+- .thenApply(chunkResult -> chunkResult.map(list -> (LevelChunk)list.get(list.size() / 2)));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Nullable
- ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k) {
-- if (!ChunkLevel.isLoaded(k) && !ChunkLevel.isLoaded(level)) {
+ ChunkHolder updateChunkScheduling(long chunkPos, int newLevel, @Nullable ChunkHolder holder, int oldLevel) {
+- if (!ChunkLevel.isLoaded(oldLevel) && !ChunkLevel.isLoaded(newLevel)) {
- return holder;
- } else {
- if (holder != null) {
-- holder.setTicketLevel(level);
+- holder.setTicketLevel(newLevel);
- }
-
- if (holder != null) {
-- if (!ChunkLevel.isLoaded(level)) {
-- this.toDrop.add(pos);
+- if (!ChunkLevel.isLoaded(newLevel)) {
+- this.toDrop.add(chunkPos);
- } else {
-- this.toDrop.remove(pos);
+- this.toDrop.remove(chunkPos);
- }
- }
-
-- if (ChunkLevel.isLoaded(level) && holder == null) {
-- holder = (ChunkHolder) this.pendingUnloads.remove(pos);
+- if (ChunkLevel.isLoaded(newLevel) && holder == null) {
+- holder = this.pendingUnloads.remove(chunkPos);
- if (holder != null) {
-- holder.setTicketLevel(level);
+- holder.setTicketLevel(newLevel);
- } else {
-- holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this::onLevelChange, this);
+- holder = new ChunkHolder(new ChunkPos(chunkPos), newLevel, this.level, this.lightEngine, this::onLevelChange, this);
- // Paper start
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderCreate(this.level, holder);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderCreate(this.level, holder);
- // Paper end
- }
-
-- this.updatingChunkMap.put(pos, holder);
+- this.updatingChunkMap.put(chunkPos, holder);
- this.modified = true;
- }
-
@@ -24650,9 +24334,9 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void onLevelChange(ChunkPos pos, IntSupplier levelGetter, int targetLevel, IntConsumer levelSetter) {
-- this.worldgenTaskDispatcher.onLevelChange(pos, levelGetter, targetLevel, levelSetter);
-- this.lightTaskDispatcher.onLevelChange(pos, levelGetter, targetLevel, levelSetter);
+ private void onLevelChange(ChunkPos chunkPos, IntSupplier queueLevelGetter, int ticketLevel, IntConsumer queueLevelSetter) {
+- this.worldgenTaskDispatcher.onLevelChange(chunkPos, queueLevelGetter, ticketLevel, queueLevelSetter);
+- this.lightTaskDispatcher.onLevelChange(chunkPos, queueLevelGetter, ticketLevel, queueLevelSetter);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -24666,43 +24350,39 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
- super.close();
- }
+ throw new UnsupportedOperationException("Use ServerChunkCache#close"); // Paper - rewrite chunk system
-
}
protected void saveAllChunks(boolean flush) {
- if (flush) {
-- List<ChunkHolder> list = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper
-- MutableBoolean mutableboolean = new MutableBoolean();
+- List<ChunkHolder> list = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level) // Paper - moonrise
+- //.values() // Paper - moonrise
+- .stream()
+- .filter(ChunkHolder::wasAccessibleSinceLastSave)
+- .peek(ChunkHolder::refreshAccessibility)
+- .toList();
+- MutableBoolean mutableBoolean = new MutableBoolean();
-
- do {
-- mutableboolean.setFalse();
-- list.stream().map((playerchunk) -> {
-- BlockableEventLoop iasynctaskhandler = this.mainThreadExecutor;
--
-- Objects.requireNonNull(playerchunk);
-- iasynctaskhandler.managedBlock(playerchunk::isReadyForSaving);
-- return playerchunk.getLatestChunk();
-- }).filter((ichunkaccess) -> {
-- return ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk;
-- }).filter(this::save).forEach((ichunkaccess) -> {
-- mutableboolean.setTrue();
-- });
-- } while (mutableboolean.isTrue());
+- mutableBoolean.setFalse();
+- list.stream()
+- .map(chunk -> {
+- this.mainThreadExecutor.managedBlock(chunk::isReadyForSaving);
+- return chunk.getLatestChunk();
+- })
+- .filter(chunk -> chunk instanceof ImposterProtoChunk || chunk instanceof LevelChunk)
+- .filter(this::save)
+- .forEach(chunk -> mutableBoolean.setTrue());
+- } while (mutableBoolean.isTrue());
-
- this.poiManager.flushAll();
-- this.processUnloads(() -> {
-- return true;
-- });
+- this.processUnloads(() -> true);
- this.flushWorker();
- } else {
- this.nextChunkSaveTime.clear();
-- long i = Util.getMillis();
-- Iterator<ChunkHolder> objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper
--
-- while (objectiterator.hasNext()) {
-- ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
+- long millis = Util.getMillis();
-
-- this.saveChunkIfNeeded(playerchunk, i);
+- for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper
+- this.saveChunkIfNeeded(chunkHolder, millis);
- }
- }
+ // Paper start - rewrite chunk system
@@ -24710,112 +24390,104 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ flush, false, false
+ );
+ // Paper end - rewrite chunk system
-
}
-@@ -524,143 +384,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ protected void tick(BooleanSupplier hasMoreTime) {
+@@ -505,130 +387,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public boolean hasWork() {
-- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.worldgenTaskDispatcher.hasWork() || this.lightTaskDispatcher.hasWork() || this.distanceManager.hasTickets();
+- return this.lightEngine.hasLightWork()
+- || !this.pendingUnloads.isEmpty()
+- || ca.spottedleaf.moonrise.common.PlatformHooks.get().hasAnyChunkHolders(this.level) // Paper - moonrise
+- || !this.updatingChunkMap.isEmpty()
+- || this.poiManager.hasWork()
+- || !this.toDrop.isEmpty()
+- || !this.unloadQueue.isEmpty()
+- || this.worldgenTaskDispatcher.hasWork()
+- || this.lightTaskDispatcher.hasWork()
+- || this.distanceManager.hasTickets();
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void processUnloads(BooleanSupplier shouldKeepTicking) {
-- for (LongIterator longiterator = this.toDrop.iterator(); longiterator.hasNext(); longiterator.remove()) {
-- long i = longiterator.nextLong();
-- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.get(i);
--
-- if (playerchunk != null) {
-- this.updatingChunkMap.remove(i);
-- this.pendingUnloads.put(i, playerchunk);
+ private void processUnloads(BooleanSupplier hasMoreTime) {
+- for (LongIterator longIterator = this.toDrop.iterator(); longIterator.hasNext(); longIterator.remove()) {
+- long l = longIterator.nextLong();
+- ChunkHolder chunkHolder = this.updatingChunkMap.get(l);
+- if (chunkHolder != null) {
+- this.updatingChunkMap.remove(l);
+- this.pendingUnloads.put(l, chunkHolder);
- this.modified = true;
-- this.scheduleUnload(i, playerchunk);
+- this.scheduleUnload(l, chunkHolder);
- }
- }
-
-- int j = Math.max(0, this.unloadQueue.size() - 2000);
+- int max = Math.max(0, this.unloadQueue.size() - 2000);
-
- Runnable runnable;
--
-- while ((j > 0 || shouldKeepTicking.getAsBoolean()) && (runnable = (Runnable) this.unloadQueue.poll()) != null) {
-- --j;
+- while ((max > 0 || hasMoreTime.getAsBoolean()) && (runnable = this.unloadQueue.poll()) != null) {
+- max--;
- runnable.run();
- }
-
-- this.saveChunksEagerly(shouldKeepTicking);
+- this.saveChunksEagerly(hasMoreTime);
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.processUnloads(); // Paper - rewrite chunk system
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.autoSave(); // Paper - rewrite chunk system
}
- private void saveChunksEagerly(BooleanSupplier shouldKeepTicking) {
-- long i = Util.getMillis();
-- int j = 0;
-- LongIterator longiterator = this.chunksToEagerlySave.iterator();
--
-- while (j < 20 && this.activeChunkWrites.get() < 128 && shouldKeepTicking.getAsBoolean() && longiterator.hasNext()) {
-- long k = longiterator.nextLong();
-- ChunkHolder playerchunk = (ChunkHolder) this.visibleChunkMap.get(k);
-- ChunkAccess ichunkaccess = playerchunk != null ? playerchunk.getLatestChunk() : null;
--
-- if (ichunkaccess != null && ichunkaccess.isUnsaved()) {
-- if (this.saveChunkIfNeeded(playerchunk, i)) {
-- ++j;
-- longiterator.remove();
-- }
-- } else {
-- longiterator.remove();
+ private void saveChunksEagerly(BooleanSupplier hasMoreTime) {
+- long millis = Util.getMillis();
+- int i = 0;
+- LongIterator longIterator = this.chunksToEagerlySave.iterator();
+-
+- while (i < 20 && this.activeChunkWrites.get() < 128 && hasMoreTime.getAsBoolean() && longIterator.hasNext()) {
+- long l = longIterator.nextLong();
+- ChunkHolder chunkHolder = this.visibleChunkMap.get(l);
+- ChunkAccess chunkAccess = chunkHolder != null ? chunkHolder.getLatestChunk() : null;
+- if (chunkAccess == null || !chunkAccess.isUnsaved()) {
+- longIterator.remove();
+- } else if (this.saveChunkIfNeeded(chunkHolder, millis)) {
+- i++;
+- longIterator.remove();
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
-
}
- private void scheduleUnload(long pos, ChunkHolder chunk) {
-- CompletableFuture<?> completablefuture = chunk.getSaveSyncFuture();
-- Runnable runnable = () -> {
-- CompletableFuture<?> completablefuture1 = chunk.getSaveSyncFuture();
--
-- if (completablefuture1 != completablefuture) {
-- this.scheduleUnload(pos, chunk);
+ private void scheduleUnload(long chunkPos, ChunkHolder chunkHolder) {
+- CompletableFuture<?> saveSyncFuture = chunkHolder.getSaveSyncFuture();
+- saveSyncFuture.thenRunAsync(() -> {
+- CompletableFuture<?> saveSyncFuture1 = chunkHolder.getSaveSyncFuture();
+- if (saveSyncFuture1 != saveSyncFuture) {
+- this.scheduleUnload(chunkPos, chunkHolder);
- } else {
-- ChunkAccess ichunkaccess = chunk.getLatestChunk();
+- ChunkAccess latestChunk = chunkHolder.getLatestChunk();
- // Paper start
- boolean removed;
-- if ((removed = this.pendingUnloads.remove(pos, chunk)) && ichunkaccess != null) {
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk);
+- if ((removed = this.pendingUnloads.remove(chunkPos, chunkHolder)) && latestChunk != null) {
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
- // Paper end
-- LevelChunk chunk1;
--
-- if (ichunkaccess instanceof LevelChunk) {
-- chunk1 = (LevelChunk) ichunkaccess;
-- chunk1.setLoaded(false);
+- if (latestChunk instanceof LevelChunk levelChunk) {
+- levelChunk.setLoaded(false);
- }
-
-- this.save(ichunkaccess);
-- if (ichunkaccess instanceof LevelChunk) {
-- chunk1 = (LevelChunk) ichunkaccess;
-- this.level.unload(chunk1);
+- this.save(latestChunk);
+- if (latestChunk instanceof LevelChunk levelChunk) {
+- this.level.unload(levelChunk);
- }
-
-- this.lightEngine.updateChunkStatus(ichunkaccess.getPos());
+- this.lightEngine.updateChunkStatus(latestChunk.getPos());
- this.lightEngine.tryScheduleUpdate();
-- this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null);
-- this.nextChunkSaveTime.remove(ichunkaccess.getPos().toLong());
+- this.progressListener.onStatusChange(latestChunk.getPos(), null);
+- this.nextChunkSaveTime.remove(latestChunk.getPos().toLong());
- } else if (removed) { // Paper start
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunk);
+- ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
- } // Paper end
--
- }
-- };
-- Queue queue = this.unloadQueue;
--
-- Objects.requireNonNull(this.unloadQueue);
-- completablefuture.thenRunAsync(runnable, queue::add).whenComplete((ovoid, throwable) -> {
-- if (throwable != null) {
-- ChunkMap.LOGGER.error("Failed to save chunk {}", chunk.getPos(), throwable);
+- }, this.unloadQueue::add).whenComplete((_void, error) -> {
+- if (error != null) {
+- LOGGER.error("Failed to save chunk {}", chunkHolder.getPos(), error);
- }
--
- });
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -24831,120 +24503,99 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private CompletableFuture<ChunkAccess> scheduleChunkLoad(ChunkPos pos) {
-- CompletableFuture<Optional<SerializableChunkData>> completablefuture = this.readChunk(pos).thenApplyAsync((optional) -> {
-- return optional.map((nbttagcompound) -> {
-- SerializableChunkData serializablechunkdata = SerializableChunkData.parse(this.level, this.level.registryAccess(), nbttagcompound);
+ private CompletableFuture<ChunkAccess> scheduleChunkLoad(ChunkPos chunkPos) {
+- CompletableFuture<Optional<SerializableChunkData>> completableFuture = this.readChunk(chunkPos).thenApplyAsync(optional -> optional.map(tag -> {
+- SerializableChunkData serializableChunkData = SerializableChunkData.parse(this.level, this.level.registryAccess(), tag);
+- if (serializableChunkData == null) {
+- LOGGER.error("Chunk file at {} is missing level data, skipping", chunkPos);
+- }
-
-- if (serializablechunkdata == null) {
-- ChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", pos);
+- return serializableChunkData;
+- }), Util.backgroundExecutor().forName("parseChunk"));
+- CompletableFuture<?> completableFuture1 = this.poiManager.prefetch(chunkPos);
+- return completableFuture.<Object, Optional<SerializableChunkData>>thenCombine(
+- (CompletionStage<? extends Object>)completableFuture1, (optional, object) -> optional
+- )
+- .thenApplyAsync(optional -> {
+- Profiler.get().incrementCounter("chunkLoad");
+- if (optional.isPresent()) {
+- ChunkAccess chunkAccess = optional.get().read(this.level, this.poiManager, this.storageInfo(), chunkPos);
+- this.markPosition(chunkPos, chunkAccess.getPersistedStatus().getChunkType());
+- return chunkAccess;
+- } else {
+- return this.createEmptyChunk(chunkPos);
- }
--
-- return serializablechunkdata;
-- });
-- }, Util.backgroundExecutor().forName("parseChunk"));
-- CompletableFuture<?> completablefuture1 = this.poiManager.prefetch(pos);
--
-- return completablefuture.thenCombine(completablefuture1, (optional, object) -> {
-- return optional;
-- }).thenApplyAsync((optional) -> {
-- Profiler.get().incrementCounter("chunkLoad");
-- if (optional.isPresent()) {
-- ProtoChunk protochunk = ((SerializableChunkData) optional.get()).read(this.level, this.poiManager, this.storageInfo(), pos);
--
-- this.markPosition(pos, protochunk.getPersistedStatus().getChunkType());
-- return protochunk;
-- } else {
-- return this.createEmptyChunk(pos);
-- }
-- }, this.mainThreadExecutor).exceptionallyAsync((throwable) -> {
-- return this.handleChunkLoadFailure(throwable, pos);
-- }, this.mainThreadExecutor);
+- }, this.mainThreadExecutor)
+- .exceptionallyAsync(throwable -> this.handleChunkLoadFailure(throwable, chunkPos), this.mainThreadExecutor);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private ChunkAccess handleChunkLoadFailure(Throwable throwable, ChunkPos chunkPos) {
-@@ -716,139 +462,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private ChunkAccess handleChunkLoadFailure(Throwable exception, ChunkPos chunkPos) {
+@@ -666,108 +446,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@Override
- public GenerationChunkHolder acquireGeneration(long pos) {
-- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.get(pos);
--
-- playerchunk.increaseGenerationRefCount();
-- return playerchunk;
+ public GenerationChunkHolder acquireGeneration(long chunkPos) {
+- ChunkHolder chunkHolder = this.updatingChunkMap.get(chunkPos);
+- chunkHolder.increaseGenerationRefCount();
+- return chunkHolder;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Override
- public void releaseGeneration(GenerationChunkHolder chunkHolder) {
-- chunkHolder.decreaseGenerationRefCount();
+ public void releaseGeneration(GenerationChunkHolder chunk) {
+- chunk.decreaseGenerationRefCount();
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Override
- public CompletableFuture<ChunkAccess> applyStep(GenerationChunkHolder chunkHolder, ChunkStep step, StaticCache2D<GenerationChunkHolder> chunks) {
-- ChunkPos chunkcoordintpair = chunkHolder.getPos();
--
+ public CompletableFuture<ChunkAccess> applyStep(GenerationChunkHolder chunk, ChunkStep step, StaticCache2D<GenerationChunkHolder> cache) {
+- ChunkPos pos = chunk.getPos();
- if (step.targetStatus() == ChunkStatus.EMPTY) {
-- return this.scheduleChunkLoad(chunkcoordintpair);
+- return this.scheduleChunkLoad(pos);
- } else {
- try {
-- GenerationChunkHolder generationchunkholder1 = (GenerationChunkHolder) chunks.get(chunkcoordintpair.x, chunkcoordintpair.z);
-- ChunkAccess ichunkaccess = generationchunkholder1.getChunkIfPresentUnchecked(step.targetStatus().getParent());
--
-- if (ichunkaccess == null) {
+- GenerationChunkHolder generationChunkHolder = cache.get(pos.x, pos.z);
+- ChunkAccess chunkIfPresentUnchecked = generationChunkHolder.getChunkIfPresentUnchecked(step.targetStatus().getParent());
+- if (chunkIfPresentUnchecked == null) {
- throw new IllegalStateException("Parent chunk missing");
- } else {
-- CompletableFuture<ChunkAccess> completablefuture = step.apply(this.worldGenContext, chunks, ichunkaccess);
--
-- this.progressListener.onStatusChange(chunkcoordintpair, step.targetStatus());
-- return completablefuture;
+- CompletableFuture<ChunkAccess> completableFuture = step.apply(this.worldGenContext, cache, chunkIfPresentUnchecked);
+- this.progressListener.onStatusChange(pos, step.targetStatus());
+- return completableFuture;
- }
-- } catch (Exception exception) {
-- exception.getStackTrace();
-- CrashReport crashreport = CrashReport.forThrowable(exception, "Exception generating new chunk");
-- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk to be generated");
--
-- crashreportsystemdetails.setDetail("Status being generated", () -> {
-- return step.targetStatus().getName();
-- });
-- crashreportsystemdetails.setDetail("Location", (Object) String.format(Locale.ROOT, "%d,%d", chunkcoordintpair.x, chunkcoordintpair.z));
-- crashreportsystemdetails.setDetail("Position hash", (Object) ChunkPos.asLong(chunkcoordintpair.x, chunkcoordintpair.z));
-- crashreportsystemdetails.setDetail("Generator", (Object) this.generator());
+- } catch (Exception var8) {
+- var8.getStackTrace();
+- CrashReport crashReport = CrashReport.forThrowable(var8, "Exception generating new chunk");
+- CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk to be generated");
+- crashReportCategory.setDetail("Status being generated", () -> step.targetStatus().getName());
+- crashReportCategory.setDetail("Location", String.format(Locale.ROOT, "%d,%d", pos.x, pos.z));
+- crashReportCategory.setDetail("Position hash", ChunkPos.asLong(pos.x, pos.z));
+- crashReportCategory.setDetail("Generator", this.generator());
- this.mainThreadExecutor.execute(() -> {
-- throw new ReportedException(crashreport);
+- throw new ReportedException(crashReport);
- });
-- throw new ReportedException(crashreport);
+- throw new ReportedException(crashReport);
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Override
- public ChunkGenerationTask scheduleGenerationTask(ChunkStatus requestedStatus, ChunkPos pos) {
-- ChunkGenerationTask chunkgenerationtask = ChunkGenerationTask.create(this, requestedStatus, pos);
--
-- this.pendingGenerationTasks.add(chunkgenerationtask);
-- return chunkgenerationtask;
+ public ChunkGenerationTask scheduleGenerationTask(ChunkStatus targetStatus, ChunkPos pos) {
+- ChunkGenerationTask chunkGenerationTask = ChunkGenerationTask.create(this, targetStatus, pos);
+- this.pendingGenerationTasks.add(chunkGenerationTask);
+- return chunkGenerationTask;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void runGenerationTask(ChunkGenerationTask loader) {
-- GenerationChunkHolder generationchunkholder = loader.getCenter();
-- ChunkTaskDispatcher chunktaskdispatcher = this.worldgenTaskDispatcher;
-- Runnable runnable = () -> {
-- CompletableFuture<?> completablefuture = loader.runUntilWait();
--
-- if (completablefuture != null) {
-- completablefuture.thenRun(() -> {
-- this.runGenerationTask(loader);
-- });
+ private void runGenerationTask(ChunkGenerationTask task) {
+- GenerationChunkHolder center = task.getCenter();
+- this.worldgenTaskDispatcher.submit(() -> {
+- CompletableFuture<?> completableFuture = task.runUntilWait();
+- if (completableFuture != null) {
+- completableFuture.thenRun(() -> this.runGenerationTask(task));
- }
-- };
-- long i = generationchunkholder.getPos().toLong();
--
-- Objects.requireNonNull(generationchunkholder);
-- chunktaskdispatcher.submit(runnable, i, generationchunkholder::getQueueLevel);
+- }, center.getPos().toLong(), center::getQueueLevel);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -24956,46 +24607,34 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
}
public CompletableFuture<ChunkResult<LevelChunk>> prepareTickingChunk(ChunkHolder holder) {
-- CompletableFuture<ChunkResult<List<ChunkAccess>>> completablefuture = this.getChunkRangeFuture(holder, 1, (i) -> {
-- return ChunkStatus.FULL;
-- });
-- CompletableFuture<ChunkResult<LevelChunk>> completablefuture1 = completablefuture.thenApplyAsync((chunkresult) -> {
-- return chunkresult.map((list) -> {
-- LevelChunk chunk = (LevelChunk) list.get(list.size() / 2);
--
-- chunk.postProcessGeneration(this.level);
-- this.level.startTickingChunk(chunk);
-- CompletableFuture<?> completablefuture2 = holder.getSendSyncFuture();
--
-- if (completablefuture2.isDone()) {
-- this.onChunkReadyToSend(holder, chunk);
-- } else {
-- completablefuture2.thenAcceptAsync((object) -> {
-- this.onChunkReadyToSend(holder, chunk);
-- }, this.mainThreadExecutor);
-- }
--
-- return chunk;
-- });
-- }, this.mainThreadExecutor);
+- CompletableFuture<ChunkResult<List<ChunkAccess>>> chunkRangeFuture = this.getChunkRangeFuture(holder, 1, i -> ChunkStatus.FULL);
+- CompletableFuture<ChunkResult<LevelChunk>> completableFuture = chunkRangeFuture.thenApplyAsync(chunk -> chunk.map(list -> {
+- LevelChunk levelChunk = (LevelChunk)list.get(list.size() / 2);
+- levelChunk.postProcessGeneration(this.level);
+- this.level.startTickingChunk(levelChunk);
+- CompletableFuture<?> sendSyncFuture = holder.getSendSyncFuture();
+- if (sendSyncFuture.isDone()) {
+- this.onChunkReadyToSend(holder, levelChunk);
+- } else {
+- sendSyncFuture.thenAcceptAsync(object -> this.onChunkReadyToSend(holder, levelChunk), this.mainThreadExecutor);
+- }
-
-- completablefuture1.handle((chunkresult, throwable) -> {
+- return levelChunk;
+- }), this.mainThreadExecutor);
+- completableFuture.handle((chunk, exception) -> {
- this.tickingGenerated.getAndIncrement();
- return null;
- });
-- return completablefuture1;
+- return completableFuture;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
private void onChunkReadyToSend(ChunkHolder chunkHolder, LevelChunk chunk) {
-- ChunkPos chunkcoordintpair = chunk.getPos();
-- Iterator iterator = this.playerMap.getAllPlayers().iterator();
--
-- while (iterator.hasNext()) {
-- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+- ChunkPos pos = chunk.getPos();
-
-- if (entityplayer.getChunkTrackingView().contains(chunkcoordintpair)) {
-- ChunkMap.markChunkPendingToSend(entityplayer, chunk);
+- for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
+- if (serverPlayer.getChunkTrackingView().contains(pos)) {
+- markChunkPendingToSend(serverPlayer, chunk);
- }
- }
-
@@ -25003,39 +24642,33 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- public CompletableFuture<ChunkResult<LevelChunk>> prepareAccessibleChunk(ChunkHolder holder) {
-- return this.getChunkRangeFuture(holder, 1, ChunkLevel::getStatusAroundFullChunk).thenApply((chunkresult) -> {
-- return chunkresult.map((list) -> {
-- return (LevelChunk) list.get(list.size() / 2);
-- });
-- });
+ public CompletableFuture<ChunkResult<LevelChunk>> prepareAccessibleChunk(ChunkHolder chunk) {
+- return this.getChunkRangeFuture(chunk, 1, ChunkLevel::getStatusAroundFullChunk)
+- .thenApply(chunkResult -> chunkResult.map(list -> (LevelChunk)list.get(list.size() / 2)));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
public int getTickingGenerated() {
-@@ -856,144 +506,80 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -775,125 +490,78 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- private boolean saveChunkIfNeeded(ChunkHolder chunkHolder, long currentTime) {
-- if (chunkHolder.wasAccessibleSinceLastSave() && chunkHolder.isReadyForSaving()) {
-- ChunkAccess ichunkaccess = chunkHolder.getLatestChunk();
--
-- if (!(ichunkaccess instanceof ImposterProtoChunk) && !(ichunkaccess instanceof LevelChunk)) {
+ private boolean saveChunkIfNeeded(ChunkHolder chunk, long gametime) {
+- if (chunk.wasAccessibleSinceLastSave() && chunk.isReadyForSaving()) {
+- ChunkAccess latestChunk = chunk.getLatestChunk();
+- if (!(latestChunk instanceof ImposterProtoChunk) && !(latestChunk instanceof LevelChunk)) {
- return false;
-- } else if (!ichunkaccess.isUnsaved()) {
+- } else if (!latestChunk.isUnsaved()) {
- return false;
- } else {
-- long j = ichunkaccess.getPos().toLong();
-- long k = this.nextChunkSaveTime.getOrDefault(j, -1L);
--
-- if (currentTime < k) {
+- long packedChunkPos = latestChunk.getPos().toLong();
+- long orDefault = this.nextChunkSaveTime.getOrDefault(packedChunkPos, -1L);
+- if (gametime < orDefault) {
- return false;
- } else {
-- boolean flag = this.save(ichunkaccess);
--
-- chunkHolder.refreshAccessibility();
+- boolean flag = this.save(latestChunk);
+- chunk.refreshAccessibility();
- if (flag) {
-- this.nextChunkSaveTime.put(j, currentTime + 10000L);
+- this.nextChunkSaveTime.put(packedChunkPos, gametime + 10000L);
- }
-
- return flag;
@@ -25052,111 +24685,97 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
- if (!chunk.tryMarkSaved()) {
- return false;
- } else {
-- ChunkPos chunkcoordintpair = chunk.getPos();
+- ChunkPos pos = chunk.getPos();
-
- try {
-- ChunkStatus chunkstatus = chunk.getPersistedStatus();
--
-- if (chunkstatus.getChunkType() != ChunkType.LEVELCHUNK) {
-- if (this.isExistingChunkFull(chunkcoordintpair)) {
+- ChunkStatus persistedStatus = chunk.getPersistedStatus();
+- if (persistedStatus.getChunkType() != ChunkType.LEVELCHUNK) {
+- if (this.isExistingChunkFull(pos)) {
- return false;
- }
-
-- if (chunkstatus == ChunkStatus.EMPTY && chunk.getAllStarts().values().stream().noneMatch(StructureStart::isValid)) {
+- if (persistedStatus == ChunkStatus.EMPTY && chunk.getAllStarts().values().stream().noneMatch(StructureStart::isValid)) {
- return false;
- }
- }
-
- Profiler.get().incrementCounter("chunkSave");
- this.activeChunkWrites.incrementAndGet();
-- SerializableChunkData serializablechunkdata = SerializableChunkData.copyOf(this.level, chunk);
--
-- Objects.requireNonNull(serializablechunkdata);
-- CompletableFuture<CompoundTag> completablefuture = CompletableFuture.supplyAsync(serializablechunkdata::write, Util.backgroundExecutor());
--
-- Objects.requireNonNull(completablefuture);
-- this.write(chunkcoordintpair, completablefuture::join).handle((ovoid, throwable) -> {
-- if (throwable != null) {
-- this.level.getServer().reportChunkSaveFailure(throwable, this.storageInfo(), chunkcoordintpair);
+- SerializableChunkData serializableChunkData = SerializableChunkData.copyOf(this.level, chunk);
+- CompletableFuture<CompoundTag> completableFuture = CompletableFuture.supplyAsync(serializableChunkData::write, Util.backgroundExecutor());
+- this.write(pos, completableFuture::join).handle((_void, exception1) -> {
+- if (exception1 != null) {
+- this.level.getServer().reportChunkSaveFailure(exception1, this.storageInfo(), pos);
- }
-
- this.activeChunkWrites.decrementAndGet();
- return null;
- });
-- this.markPosition(chunkcoordintpair, chunkstatus.getChunkType());
+- this.markPosition(pos, persistedStatus.getChunkType());
- return true;
-- } catch (Exception exception) {
-- this.level.getServer().reportChunkSaveFailure(exception, this.storageInfo(), chunkcoordintpair);
+- } catch (Exception var6) {
+- this.level.getServer().reportChunkSaveFailure(var6, this.storageInfo(), pos);
- return false;
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private boolean isExistingChunkFull(ChunkPos pos) {
-- byte b0 = this.chunkTypeCache.get(pos.toLong());
--
-- if (b0 != 0) {
-- return b0 == 1;
+ private boolean isExistingChunkFull(ChunkPos chunkPos) {
+- byte b = this.chunkTypeCache.get(chunkPos.toLong());
+- if (b != 0) {
+- return b == 1;
- } else {
-- CompoundTag nbttagcompound;
--
+- CompoundTag compoundTag;
- try {
-- nbttagcompound = (CompoundTag) ((Optional) this.readChunk(pos).join()).orElse((Object) null);
-- if (nbttagcompound == null) {
-- this.markPositionReplaceable(pos);
+- compoundTag = this.readChunk(chunkPos).join().orElse(null);
+- if (compoundTag == null) {
+- this.markPositionReplaceable(chunkPos);
- return false;
- }
-- } catch (Exception exception) {
-- ChunkMap.LOGGER.error("Failed to read chunk {}", pos, exception);
-- this.markPositionReplaceable(pos);
+- } catch (Exception var5) {
+- LOGGER.error("Failed to read chunk {}", chunkPos, var5);
+- this.markPositionReplaceable(chunkPos);
- return false;
- }
-
-- ChunkType chunktype = SerializableChunkData.getChunkTypeFromTag(nbttagcompound);
--
-- return this.markPosition(pos, chunktype) == 1;
+- ChunkType chunkTypeFromTag = SerializableChunkData.getChunkTypeFromTag(compoundTag);
+- return this.markPosition(chunkPos, chunkTypeFromTag) == 1;
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- public void setServerViewDistance(int watchDistance) { // Paper - public
-- int j = Mth.clamp(watchDistance, 2, 32);
--
-- if (j != this.serverViewDistance) {
-- this.serverViewDistance = j;
+ public void setServerViewDistance(int viewDistance) { // Paper - publi
+- int i = Mth.clamp(viewDistance, 2, 32);
+- if (i != this.serverViewDistance) {
+- this.serverViewDistance = i;
- this.distanceManager.updatePlayerTickets(this.serverViewDistance);
-- Iterator iterator = this.playerMap.getAllPlayers().iterator();
--
-- while (iterator.hasNext()) {
-- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
-
-- this.updateChunkTracking(entityplayer);
+- for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
+- this.updateChunkTracking(serverPlayer);
- }
+ // Paper start - rewrite chunk system
-+ final int clamped = Mth.clamp(watchDistance, 2, ca.spottedleaf.moonrise.common.util.MoonriseConstants.MAX_VIEW_DISTANCE);
++ final int clamped = Mth.clamp(viewDistance, 2, ca.spottedleaf.moonrise.common.util.MoonriseConstants.MAX_VIEW_DISTANCE);
+ if (clamped == this.serverViewDistance) {
+ return;
}
-
++
+ this.serverViewDistance = clamped;
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().setLoadDistance(this.serverViewDistance + 1);
+ // Paper end - rewrite chunk system
}
- public int getPlayerViewDistance(ServerPlayer player) { // Paper - public
+ int getPlayerViewDistance(ServerPlayer player) {
- return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance);
+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getSendViewDistance(player); // Paper - rewrite chunk system
}
- private void markChunkPendingToSend(ServerPlayer player, ChunkPos pos) {
-- LevelChunk chunk = this.getChunkToSend(pos.toLong());
--
-- if (chunk != null) {
-- ChunkMap.markChunkPendingToSend(player, chunk);
+ private void markChunkPendingToSend(ServerPlayer player, ChunkPos chunkPos) {
+- LevelChunk chunkToSend = this.getChunkToSend(chunkPos.toLong());
+- if (chunkToSend != null) {
+- markChunkPendingToSend(player, chunkToSend);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
-
}
private static void markChunkPendingToSend(ServerPlayer player, LevelChunk chunk) {
@@ -25164,8 +24783,8 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private static void dropChunk(ServerPlayer player, ChunkPos pos) {
-- player.connection.chunkSender.dropChunk(player, pos);
+ private static void dropChunk(ServerPlayer player, ChunkPos chunkPos) {
+- player.connection.chunkSender.dropChunk(player, chunkPos);
+ // Paper - rewrite chunk system
+ }
+
@@ -25195,116 +24814,98 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionFileType.CHUNK_DATA
+ );
+ return null;
- }
-
++ }
++
+ @Override
+ public void flushWorker() {
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.flush(this.level);
-+ }
+ }
+ // Paper end - rewrite chunk system
-+
+
@Nullable
- public LevelChunk getChunkToSend(long pos) {
- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
-@@ -1059,7 +645,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ public LevelChunk getChunkToSend(long chunkPos) {
+@@ -981,7 +649,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
// CraftBukkit start
-- private CompoundTag upgradeChunkTag(CompoundTag nbttagcompound, ChunkPos chunkcoordintpair) {
-+ public CompoundTag upgradeChunkTag(CompoundTag nbttagcompound, ChunkPos chunkcoordintpair) { // Paper - public
- return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level);
- // CraftBukkit end
+- private CompoundTag upgradeChunkTag(CompoundTag tag, ChunkPos pos) {
++ public CompoundTag upgradeChunkTag(CompoundTag tag, ChunkPos pos) { // Paper - public
+ return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, tag, this.generator().getTypeNameForDataFixer(), pos, this.level);
+ // CraftBukkit end
}
-@@ -1069,7 +655,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- while (longiterator.hasNext()) {
- long i = longiterator.nextLong();
-- ChunkHolder playerchunk = (ChunkHolder) this.visibleChunkMap.get(i);
-+ ChunkHolder playerchunk = (ChunkHolder) this.getVisibleChunkIfPresent(i); // Paper - rewrite chunk system
+@@ -991,7 +659,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- if (playerchunk != null && this.anyPlayerCloseEnoughForSpawningInternal(playerchunk.getPos())) {
- callback.accept(playerchunk);
-@@ -1084,7 +670,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ while (spawnCandidateChunks.hasNext()) {
+ long l = spawnCandidateChunks.nextLong();
+- ChunkHolder chunkHolder = this.visibleChunkMap.get(l);
++ ChunkHolder chunkHolder = this.getVisibleChunkIfPresent(l); // Paper - rewrite chunk system
+ if (chunkHolder != null && this.anyPlayerCloseEnoughForSpawningInternal(chunkHolder.getPos())) {
+ action.accept(chunkHolder);
+ }
+@@ -1004,7 +672,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkcoordintpair, boolean reducedRange) {
-- return !this.distanceManager.hasPlayersNearby(chunkcoordintpair.toLong()) ? false : this.anyPlayerCloseEnoughForSpawningInternal(chunkcoordintpair, reducedRange);
-+ return this.anyPlayerCloseEnoughForSpawningInternal(chunkcoordintpair, reducedRange); // Paper - chunk tick iteration optimisation
+ boolean anyPlayerCloseEnoughForSpawning(ChunkPos chunkPos, boolean reducedRange) {
+- return this.distanceManager.hasPlayersNearby(chunkPos.toLong()) && this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, reducedRange);
++ return this.anyPlayerCloseEnoughForSpawningInternal(chunkPos, reducedRange); // Paper - chunk tick iteration optimisation
// Spigot end
}
-@@ -1096,16 +682,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkcoordintpair, boolean reducedRange) {
+@@ -1016,7 +684,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private boolean anyPlayerCloseEnoughForSpawningInternal(ChunkPos chunkPos, boolean reducedRange) {
double blockRange; // Paper - use from event
// Spigot end
-- Iterator iterator = this.playerMap.getAllPlayers().iterator();
--
-- ServerPlayer entityplayer;
+- for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
+ // Paper start - chunk tick iteration optimisation
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers().getPlayers(
-+ chunkcoordintpair, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE
++ chunkPos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE
+ );
+ if (players == null) {
+ return false;
+ }
-
-- do {
-- if (!iterator.hasNext()) {
-- return false;
-- }
++
+ final ServerPlayer[] raw = players.getRawDataUnchecked();
+ final int len = players.size();
-
-- entityplayer = (ServerPlayer) iterator.next();
++
+ Objects.checkFromIndexSize(0, len, raw.length);
+ for (int i = 0; i < len; ++i) {
-+ final ServerPlayer entityplayer = raw[i];
++ final ServerPlayer serverPlayer = raw[i];
// Paper start - PlayerNaturallySpawnCreaturesEvent
com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
blockRange = 16384.0D;
-@@ -1115,33 +705,47 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
- }
- // Paper end - PlayerNaturallySpawnCreaturesEvent
-- } while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot
-+ if (this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)) {
-+ return true;
-+ }
-+ }
+@@ -1032,26 +713,41 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
-- return true;
-+ return false;
+ return false;
+ // Paper end - chunk tick iteration optimisation
}
- public List<ServerPlayer> getPlayersCloseForSpawning(ChunkPos pos) {
-- long i = pos.toLong();
+ public List<ServerPlayer> getPlayersCloseForSpawning(ChunkPos chunkPos) {
+- long packedChunkPos = chunkPos.toLong();
+- if (!this.distanceManager.hasPlayersNearby(packedChunkPos)) {
+- return List.of();
+- } else {
+- Builder<ServerPlayer> builder = ImmutableList.builder();
+ // Paper start - chunk tick iteration optimisation
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getNearbyPlayers().getPlayers(
-+ pos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE
++ chunkPos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE
+ );
+ if (players == null) {
+ return new ArrayList<>();
+ }
-
-- if (!this.distanceManager.hasPlayersNearby(i)) {
-- return List.of();
-- } else {
-- Builder<ServerPlayer> builder = ImmutableList.builder();
-- Iterator iterator = this.playerMap.getAllPlayers().iterator();
++
+ List<ServerPlayer> ret = null;
-
-- while (iterator.hasNext()) {
-- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
++
+ final ServerPlayer[] raw = players.getRawDataUnchecked();
+ final int len = players.size();
-- if (this.playerIsCloseEnoughForSpawning(entityplayer, pos, 16384.0D)) { // Spigot
-- builder.add(entityplayer);
+- for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
+- if (this.playerIsCloseEnoughForSpawning(serverPlayer, chunkPos, 16384.0D)) { // Spigot
+- builder.add(serverPlayer);
+ Objects.checkFromIndexSize(0, len, raw.length);
+ for (int i = 0; i < len; ++i) {
+ final ServerPlayer player = raw[i];
-+ if (this.playerIsCloseEnoughForSpawning(player, pos, 16384.0D)) { // Spigot
++ if (this.playerIsCloseEnoughForSpawning(player, chunkPos, 16384.0D)) { // Spigot
+ if (ret == null) {
+ ret = new ArrayList<>(len - i);
+ ret.add(player);
@@ -25320,15 +24921,15 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ // Paper end - chunk tick iteration optimisation
}
-- private boolean playerIsCloseEnoughForSpawning(ServerPlayer entityplayer, ChunkPos chunkcoordintpair, double range) { // Spigot
-+ public boolean playerIsCloseEnoughForSpawning(ServerPlayer entityplayer, ChunkPos chunkcoordintpair, double range) { // Spigot // Paper - chunk tick iteration optimisation - public
- if (entityplayer.isSpectator()) {
+- private boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos, double range) { // Spigot
++ public boolean playerIsCloseEnoughForSpawning(ServerPlayer player, ChunkPos chunkPos, double range) { // Spigot // Paper - chunk tick iteration optimisation - public
+ if (player.isSpectator()) {
return false;
} else {
-@@ -1164,19 +768,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1072,18 +768,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.updatePlayerPos(player);
- if (!flag1) {
- this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player);
+ if (!flag) {
+ this.distanceManager.addPlayer(SectionPos.of(player), player);
+ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$addPlayer(player, SectionPos.of(player)); // Paper - chunk tick iteration optimisation
}
@@ -25336,121 +24937,95 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
- this.updateChunkTracking(player);
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().addPlayerToDistanceMaps(this.level, player); // Paper - rewrite chunk system
} else {
- SectionPos sectionposition = player.getLastSectionPos();
-
+ SectionPos lastSectionPos = player.getLastSectionPos();
this.playerMap.removePlayer(player);
- if (!flag2) {
- this.distanceManager.removePlayer(sectionposition, player);
+ if (!flag1) {
+ this.distanceManager.removePlayer(lastSectionPos, player);
+ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$removePlayer(player, SectionPos.of(player)); // Paper - chunk tick iteration optimisation
}
- this.applyChunkTrackingView(player, ChunkTrackingView.EMPTY);
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().removePlayerFromDistanceMaps(this.level, player); // Paper - rewrite chunk system
}
-
}
-@@ -1188,17 +794,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+@@ -1093,13 +791,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void move(ServerPlayer player) {
-- ObjectIterator objectiterator = this.entityMap.values().iterator();
--
-- while (objectiterator.hasNext()) {
-- ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next();
--
-- if (playerchunkmap_entitytracker.entity == player) {
-- playerchunkmap_entitytracker.updatePlayers(this.level.players());
+- for (ChunkMap.TrackedEntity trackedEntity : this.entityMap.values()) {
+- if (trackedEntity.entity == player) {
+- trackedEntity.updatePlayers(this.level.players());
- } else {
-- playerchunkmap_entitytracker.updatePlayer(player);
+- trackedEntity.updatePlayer(player);
- }
- }
+ // Paper - optimise entity tracker
- SectionPos sectionposition = player.getLastSectionPos();
- SectionPos sectionposition1 = SectionPos.of((EntityAccess) player);
-@@ -1208,6 +804,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
+ SectionPos lastSectionPos = player.getLastSectionPos();
+ SectionPos sectionPos = SectionPos.of(player);
+@@ -1108,6 +800,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ boolean flag2 = lastSectionPos.asLong() != sectionPos.asLong();
if (flag2 || flag != flag1) {
this.updatePlayerPos(player);
+ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$updatePlayer(player, sectionposition, sectionposition1, flag, flag1); // Paper - chunk tick iteration optimisation
if (!flag) {
- this.distanceManager.removePlayer(sectionposition, player);
+ this.distanceManager.removePlayer(lastSectionPos, player);
}
-@@ -1224,70 +821,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1124,49 +817,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.playerMap.unIgnorePlayer(player);
}
- this.updateChunkTracking(player);
+ // Paper - rewrite chunk system
}
-
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().updateMaps(this.level, player); // Paper - rewrite chunk system
}
private void updateChunkTracking(ServerPlayer player) {
-- ChunkPos chunkcoordintpair = player.chunkPosition();
-- int i = this.getPlayerViewDistance(player);
-- ChunkTrackingView chunktrackingview = player.getChunkTrackingView();
--
-- if (chunktrackingview instanceof ChunkTrackingView.Positioned chunktrackingview_a) {
-- if (chunktrackingview_a.center().equals(chunkcoordintpair) && chunktrackingview_a.viewDistance() == i) {
-- return;
-- }
+- ChunkPos chunkPos = player.chunkPosition();
+- int playerViewDistance = this.getPlayerViewDistance(player);
+- if (!(
+- player.getChunkTrackingView() instanceof ChunkTrackingView.Positioned positioned
+- && positioned.center().equals(chunkPos)
+- && positioned.viewDistance() == playerViewDistance
+- )) {
+- this.applyChunkTrackingView(player, ChunkTrackingView.of(chunkPos, playerViewDistance));
- }
--
-- this.applyChunkTrackingView(player, ChunkTrackingView.of(chunkcoordintpair, i));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void applyChunkTrackingView(ServerPlayer player, ChunkTrackingView chunkFilter) {
+ private void applyChunkTrackingView(ServerPlayer player, ChunkTrackingView chunkTrackingView) {
- if (player.level() == this.level) {
-- ChunkTrackingView chunktrackingview1 = player.getChunkTrackingView();
--
-- if (chunkFilter instanceof ChunkTrackingView.Positioned) {
-- label15:
-- {
-- ChunkTrackingView.Positioned chunktrackingview_a = (ChunkTrackingView.Positioned) chunkFilter;
--
-- if (chunktrackingview1 instanceof ChunkTrackingView.Positioned) {
-- ChunkTrackingView.Positioned chunktrackingview_a1 = (ChunkTrackingView.Positioned) chunktrackingview1;
--
-- if (chunktrackingview_a1.center().equals(chunktrackingview_a.center())) {
-- break label15;
-- }
-- }
--
-- player.connection.send(new ClientboundSetChunkCacheCenterPacket(chunktrackingview_a.center().x, chunktrackingview_a.center().z));
-- }
+- ChunkTrackingView chunkTrackingView1 = player.getChunkTrackingView();
+- if (chunkTrackingView instanceof ChunkTrackingView.Positioned positioned
+- && !(chunkTrackingView1 instanceof ChunkTrackingView.Positioned positioned1 && positioned1.center().equals(positioned.center()))) {
+- player.connection.send(new ClientboundSetChunkCacheCenterPacket(positioned.center().x, positioned.center().z));
- }
-
-- ChunkTrackingView.difference(chunktrackingview1, chunkFilter, (chunkcoordintpair) -> {
-- this.markChunkPendingToSend(player, chunkcoordintpair);
-- }, (chunkcoordintpair) -> {
-- ChunkMap.dropChunk(player, chunkcoordintpair);
-- });
-- player.setChunkTrackingView(chunkFilter);
+- ChunkTrackingView.difference(
+- chunkTrackingView1, chunkTrackingView, chunkPos -> this.markChunkPendingToSend(player, chunkPos), chunkPos -> dropChunk(player, chunkPos)
+- );
+- player.setChunkTrackingView(chunkTrackingView);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Override
- public List<ServerPlayer> getPlayers(ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge) {
-- Set<ServerPlayer> set = this.playerMap.getAllPlayers();
+ public List<ServerPlayer> getPlayers(ChunkPos pos, boolean boundaryOnly) {
+- Set<ServerPlayer> allPlayers = this.playerMap.getAllPlayers();
- Builder<ServerPlayer> builder = ImmutableList.builder();
-- Iterator iterator = set.iterator();
-
-- while (iterator.hasNext()) {
-- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
--
-- if (onlyOnWatchDistanceEdge && this.isChunkOnTrackedBorder(entityplayer, chunkPos.x, chunkPos.z) || !onlyOnWatchDistanceEdge && this.isChunkTracked(entityplayer, chunkPos.x, chunkPos.z)) {
-- builder.add(entityplayer);
+- for (ServerPlayer serverPlayer : allPlayers) {
+- if (boundaryOnly && this.isChunkOnTrackedBorder(serverPlayer, pos.x, pos.z) || !boundaryOnly && this.isChunkTracked(serverPlayer, pos.x, pos.z)) {
+- builder.add(serverPlayer);
- }
+ // Paper start - rewrite chunk system
-+ final ChunkHolder holder = this.getVisibleChunkIfPresent(chunkPos.toLong());
++ final ChunkHolder holder = this.getVisibleChunkIfPresent(pos.toLong());
+ if (holder == null) {
+ return new ArrayList<>();
+ } else {
-+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)holder).moonrise$getPlayers(onlyOnWatchDistanceEdge);
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)holder).moonrise$getPlayers(boundaryOnly);
}
-
- return builder.build();
@@ -25458,34 +25033,30 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
}
public void addEntity(Entity entity) {
-@@ -1314,6 +871,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
-
- this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
+@@ -1190,6 +863,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ } else {
+ ChunkMap.TrackedEntity trackedEntity = new ChunkMap.TrackedEntity(entity, i, updateInterval, type.trackDeltas());
+ this.entityMap.put(entity.getId(), trackedEntity);
+ // Paper start - optimise entity tracker
+ if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity() != null) {
+ throw new IllegalStateException("Entity is already tracked");
+ }
+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(playerchunkmap_entitytracker);
+ // Paper end - optimise entity tracker
- playerchunkmap_entitytracker.updatePlayers(this.level.players());
- if (entity instanceof ServerPlayer) {
- ServerPlayer entityplayer = (ServerPlayer) entity;
-@@ -1354,16 +917,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- playerchunkmap_entitytracker1.broadcastRemoved();
+ trackedEntity.updatePlayers(this.level.players());
+ if (entity instanceof ServerPlayer serverPlayer) {
+ this.updatePlayerStatus(serverPlayer, true);
+@@ -1219,12 +898,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ if (trackedEntity1 != null) {
+ trackedEntity1.broadcastRemoved();
}
-
+ ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(null); // Paper - optimise entity tracker
}
-- protected void tick() {
-- Iterator iterator = this.playerMap.getAllPlayers().iterator();
+ // Paper start - optimise entity tracker
+ private void newTrackerTick() {
+ final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();;
-
-- while (iterator.hasNext()) {
-- ServerPlayer entityplayer = (ServerPlayer) iterator.next();
++
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.entity.Entity> trackerEntities = entityLookup.trackerEntities;
+ final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked();
+ for (int i = 0, len = trackerEntities.size(); i < len; ++i) {
@@ -25502,9 +25073,10 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ }
+ }
+ // Paper end - optimise entity tracker
-
-- this.updateChunkTracking(entityplayer);
-+ protected void tick() {
++
+ protected void tick() {
+- for (ServerPlayer serverPlayer : this.playerMap.getAllPlayers()) {
+- this.updateChunkTracking(serverPlayer);
+ // Paper start - optimise entity tracker
+ if (true) {
+ this.newTrackerTick();
@@ -25515,28 +25087,24 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players();
-@@ -1466,27 +1051,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1302,23 +1007,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
- public void waitForLightBeforeSending(ChunkPos centerPos, int radius) {
-- int j = radius + 1;
--
-- ChunkPos.rangeClosed(centerPos, j).forEach((chunkcoordintpair1) -> {
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(chunkcoordintpair1.toLong());
--
-- if (playerchunk != null) {
-- playerchunk.addSendDependency(this.lightEngine.waitForPendingTasks(chunkcoordintpair1.x, chunkcoordintpair1.z));
+ public void waitForLightBeforeSending(ChunkPos chunkPos, int range) {
+- int i = range + 1;
+- ChunkPos.rangeClosed(chunkPos, i).forEach(pos -> {
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(pos.toLong());
+- if (visibleChunkIfPresent != null) {
+- visibleChunkIfPresent.addSendDependency(this.lightEngine.waitForPendingTasks(pos.x, pos.z));
- }
--
- });
+ // Paper - rewrite chunk system
}
-- public class ChunkDistanceManager extends DistanceManager { // Paper - public
-+ public class ChunkDistanceManager extends DistanceManager implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager { // Paper - public // Paper - rewrite chunk system
-
- protected ChunkDistanceManager(final Executor workerExecutor, final Executor mainThreadExecutor) {
- super(workerExecutor, mainThreadExecutor);
+- public class DistanceManager extends net.minecraft.server.level.DistanceManager { // Paper - public
++ public class DistanceManager extends net.minecraft.server.level.DistanceManager implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager { // Paper - public // Paper - rewrite chunk system
+ protected DistanceManager(final Executor dispatcher, final Executor mainThreadExecutor) {
+ super(dispatcher, mainThreadExecutor);
}
+ // Paper start - rewrite chunk system
@@ -25547,22 +25115,21 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ // Paper end - rewrite chunk system
+
@Override
- protected boolean isChunkToRemove(long pos) {
-- return ChunkMap.this.toDrop.contains(pos);
+ protected boolean isChunkToRemove(long chunkPos) {
+- return ChunkMap.this.toDrop.contains(chunkPos);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Nullable
-@@ -1502,7 +1085,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1334,13 +1040,96 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
- public class TrackedEntity {
+ public class TrackedEntity implements ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity { // Paper - optimise entity tracker
-
public final ServerEntity serverEntity;
final Entity entity;
-@@ -1510,6 +1093,89 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private final int range;
SectionPos lastSectionPos;
public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
@@ -25649,30 +25216,28 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ }
+ // Paper end - optimise entity tracker
+
- public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) {
- this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
+ public TrackedEntity(final Entity entity, final int range, final int updateInterval, final boolean trackDelta) {
+ this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, updateInterval, trackDelta, this::broadcast, this.seenBy); // CraftBukkit
this.entity = entity;
-@@ -1612,20 +1278,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1431,17 +1220,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
private int getEffectiveRange() {
- int i = this.range;
-- Iterator iterator = this.entity.getIndirectPassengers().iterator();
+ // Paper start - optimise entity tracker
+ final Entity entity = this.entity;
+ int range = this.range;
-- while (iterator.hasNext()) {
-- Entity entity = (Entity) iterator.next();
-- int j = entity.getType().clientTrackingRange() * 16;
-- j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper
+- for (Entity entity : this.entity.getIndirectPassengers()) {
+- int i1 = entity.getType().clientTrackingRange() * 16;
+- i1 = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i1); // Paper
+- if (i1 > i) {
+- i = i1;
+- }
+ if (entity.getPassengers() == ImmutableList.<Entity>of()) {
+ return this.scaledRange(range);
+ }
-
-- if (j > i) {
-- i = j;
-- }
++
+ // note: we change to List
+ final List<Entity> passengers = (List<Entity>)entity.getIndirectPassengers();
+ for (int i = 0, len = passengers.size(); i < len; ++i) {
@@ -25686,28 +25251,27 @@ index e9b585387f6cbc454e7b16feb36a256e733c5488..204965b3dfa2ac9f6709e61b847e1152
+ // Paper end - optimise entity tracker
}
- public void updatePlayers(List<ServerPlayer> players) {
+ public void updatePlayers(List<ServerPlayer> playersList) {
diff --git a/net/minecraft/server/level/DistanceManager.java b/net/minecraft/server/level/DistanceManager.java
-index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57fbca45b2 100644
+index e50e96861c0aefdb0a79674b7790798f2571010e..73599e8adbee0957c1318ee6688e49b9873d2411 100644
--- a/net/minecraft/server/level/DistanceManager.java
+++ b/net/minecraft/server/level/DistanceManager.java
-@@ -34,58 +34,57 @@ import net.minecraft.world.level.ChunkPos;
+@@ -34,56 +34,56 @@ import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.LevelChunk;
import org.slf4j.Logger;
-public abstract class DistanceManager {
+public abstract class DistanceManager implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager, ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager { // Paper - rewrite chunk system // Paper - chunk tick iteration optimisation
-
static final Logger LOGGER = LogUtils.getLogger();
static final int PLAYER_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING);
private static final int INITIAL_TICKET_LIST_CAPACITY = 4;
- final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk = new Long2ObjectOpenHashMap();
-- public final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets = new Long2ObjectOpenHashMap();
+ final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk = new Long2ObjectOpenHashMap<>();
+- public final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets = new Long2ObjectOpenHashMap<>();
- private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker();
- private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8);
- private final TickingTracker tickingTicketsTracker = new TickingTracker();
- private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(32);
-- final Set<ChunkHolder> chunksToUpdateFutures = new ReferenceOpenHashSet();
+- final Set<ChunkHolder> chunksToUpdateFutures = new ReferenceOpenHashSet<>();
- final ThrottlingChunkTaskDispatcher ticketDispatcher;
- final LongSet ticketsToRelease = new LongOpenHashSet();
- final Executor mainThreadExecutor;
@@ -25718,25 +25282,30 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
- public int simulationDistance = 10;
+ // Paper - rewrite chunk system
- protected DistanceManager(Executor workerExecutor, Executor mainThreadExecutor) {
- TaskScheduler<Runnable> taskscheduler = TaskScheduler.wrapExecutor("player ticket throttler", mainThreadExecutor);
-
-- this.ticketDispatcher = new ThrottlingChunkTaskDispatcher(taskscheduler, workerExecutor, 4);
+ protected DistanceManager(Executor dispatcher, Executor mainThreadExecutor) {
+ TaskScheduler<Runnable> taskScheduler = TaskScheduler.wrapExecutor("player ticket throttler", mainThreadExecutor);
+- this.ticketDispatcher = new ThrottlingChunkTaskDispatcher(taskScheduler, dispatcher, 4);
- this.mainThreadExecutor = mainThreadExecutor;
+ // Paper - rewrite chunk system
}
- protected void purgeStaleTickets() {
-- ++this.ticketTickCounter;
-- ObjectIterator<Entry<SortedArraySet<Ticket<?>>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator();
+- this.ticketTickCounter++;
+- ObjectIterator<Entry<SortedArraySet<Ticket<?>>>> objectIterator = this.tickets.long2ObjectEntrySet().fastIterator();
-
-- while (objectiterator.hasNext()) {
-- Entry<SortedArraySet<Ticket<?>>> entry = (Entry) objectiterator.next();
-- Iterator<Ticket<?>> iterator = ((SortedArraySet) entry.getValue()).iterator();
+- while (objectIterator.hasNext()) {
+- Entry<SortedArraySet<Ticket<?>>> entry = objectIterator.next();
+- Iterator<Ticket<?>> iterator = entry.getValue().iterator();
- boolean flag = false;
-
- while (iterator.hasNext()) {
-- Ticket<?> ticket = (Ticket) iterator.next();
+- Ticket<?> ticket = iterator.next();
+- if (ticket.timedOut(this.ticketTickCounter)) {
+- iterator.remove();
+- flag = true;
+- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket);
+- }
+- }
+ // Paper start - rewrite chunk system
+ @Override
+ public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager moonrise$getChunkHolderManager() {
@@ -25746,28 +25315,22 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ // Paper start - chunk tick iteration optimisation
+ private final ca.spottedleaf.moonrise.common.misc.PositionCountingAreaMap<ServerPlayer> spawnChunkTracker = new ca.spottedleaf.moonrise.common.misc.PositionCountingAreaMap<>();
-- if (ticket.timedOut(this.ticketTickCounter)) {
-- iterator.remove();
-- flag = true;
-- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket);
-- }
+- if (flag) {
+- this.ticketTracker.update(entry.getLongKey(), getTicketLevelAt(entry.getValue()), false);
- }
+ @Override
+ public final void moonrise$addPlayer(final ServerPlayer player, final SectionPos pos) {
+ this.spawnChunkTracker.add(player, pos.x(), pos.z(), ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE);
+ }
-- if (flag) {
-- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false);
+- if (entry.getValue().isEmpty()) {
+- objectIterator.remove();
- }
+ @Override
+ public final void moonrise$removePlayer(final ServerPlayer player, final SectionPos pos) {
+ this.spawnChunkTracker.remove(player);
+ }
-
-- if (((SortedArraySet) entry.getValue()).isEmpty()) {
-- objectiterator.remove();
-- }
++
+ @Override
+ public final void moonrise$updatePlayer(final ServerPlayer player,
+ final SectionPos oldPos, final SectionPos newPos,
@@ -25777,80 +25340,60 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ } else {
+ this.spawnChunkTracker.addOrUpdate(player, newPos.x(), newPos.z(), ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE);
}
-+ }
+ }
+ // Paper end - chunk tick iteration optimisation
+
+ protected void purgeStaleTickets() {
+ this.moonrise$getChunkHolderManager().tick(); // Paper - rewrite chunk system
++ }
- }
-
-@@ -102,105 +101,15 @@ public abstract class DistanceManager {
- protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k);
+ private static int getTicketLevelAt(SortedArraySet<Ticket<?>> tickets) {
+ return !tickets.isEmpty() ? tickets.first().getTicketLevel() : ChunkLevel.MAX_LEVEL + 1;
+@@ -98,81 +98,15 @@ public abstract class DistanceManager {
+ protected abstract ChunkHolder updateChunkScheduling(long chunkPos, int i, @Nullable ChunkHolder newLevel, int holder);
- public boolean runAllUpdates(ChunkMap chunkLoadingManager) {
+ public boolean runAllUpdates(ChunkMap chunkMap) {
- this.naturalSpawnChunkCounter.runAllUpdates();
- this.tickingTicketsTracker.runAllUpdates();
- this.playerTicketManager.runAllUpdates();
- int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE);
- boolean flag = i != 0;
--
- if (flag) {
-- ;
- }
-
- if (!this.chunksToUpdateFutures.isEmpty()) {
-- Iterator iterator = this.chunksToUpdateFutures.iterator();
--
-- ChunkHolder playerchunk;
--
- // CraftBukkit start - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
-- while (iterator.hasNext()) {
-- playerchunk = (ChunkHolder) iterator.next();
-- playerchunk.callEventIfUnloading(chunkLoadingManager);
+- for (final ChunkHolder chunkHolder : this.chunksToUpdateFutures) {
+- chunkHolder.callEventIfUnloading(chunkMap);
- }
+- // CraftBukkit end - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
-
-- iterator = this.chunksToUpdateFutures.iterator();
-- // CraftBukkit end
--
-- while (iterator.hasNext()) {
-- playerchunk = (ChunkHolder) iterator.next();
-- playerchunk.updateHighestAllowedStatus(chunkLoadingManager);
+- for (ChunkHolder chunkHolder : this.chunksToUpdateFutures) {
+- chunkHolder.updateHighestAllowedStatus(chunkMap);
- }
-
-- iterator = this.chunksToUpdateFutures.iterator();
--
-- while (iterator.hasNext()) {
-- playerchunk = (ChunkHolder) iterator.next();
-- playerchunk.updateFutures(chunkLoadingManager, this.mainThreadExecutor);
+- for (ChunkHolder chunkHolder : this.chunksToUpdateFutures) {
+- chunkHolder.updateFutures(chunkMap, this.mainThreadExecutor);
- }
-
- this.chunksToUpdateFutures.clear();
- return true;
- } else {
- if (!this.ticketsToRelease.isEmpty()) {
-- LongIterator longiterator = this.ticketsToRelease.iterator();
--
-- while (longiterator.hasNext()) {
-- long j = longiterator.nextLong();
+- LongIterator longIterator = this.ticketsToRelease.iterator();
-
-- if (this.getTickets(j).stream().anyMatch((ticket) -> {
-- return ticket.getType() == TicketType.PLAYER;
-- })) {
-- ChunkHolder playerchunk1 = chunkLoadingManager.getUpdatingChunkIfPresent(j);
--
-- if (playerchunk1 == null) {
+- while (longIterator.hasNext()) {
+- long l = longIterator.nextLong();
+- if (this.getTickets(l).stream().anyMatch(ticket -> ticket.getType() == TicketType.PLAYER)) {
+- ChunkHolder updatingChunkIfPresent = chunkMap.getUpdatingChunkIfPresent(l);
+- if (updatingChunkIfPresent == null) {
- throw new IllegalStateException();
- }
-
-- CompletableFuture<ChunkResult<LevelChunk>> completablefuture = playerchunk1.getEntityTickingChunkFuture();
--
-- completablefuture.thenAccept((chunkresult) -> {
-- this.mainThreadExecutor.execute(() -> {
-- this.ticketDispatcher.release(j, () -> {
-- }, false);
-- });
-- });
+- CompletableFuture<ChunkResult<LevelChunk>> entityTickingChunkFuture = updatingChunkIfPresent.getEntityTickingChunkFuture();
+- entityTickingChunkFuture.thenAccept(
+- chunkResult -> this.mainThreadExecutor.execute(() -> this.ticketDispatcher.release(l, () -> {}, false))
+- );
- }
- }
-
@@ -25862,115 +25405,105 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ return this.moonrise$getChunkHolderManager().processTicketUpdates(); // Paper - rewrite chunk system
}
- boolean addTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
-- SortedArraySet<Ticket<?>> arraysetsorted = this.getTickets(i);
-- int j = DistanceManager.getTicketLevelAt(arraysetsorted);
-- Ticket<?> ticket1 = (Ticket) arraysetsorted.addOrGet(ticket);
--
+ boolean addTicket(long chunkPos, Ticket<?> ticket) { // CraftBukkit - void -> boolean
+- SortedArraySet<Ticket<?>> tickets = this.getTickets(chunkPos);
+- int ticketLevelAt = getTicketLevelAt(tickets);
+- Ticket<?> ticket1 = tickets.addOrGet(ticket);
- ticket1.setCreatedTick(this.ticketTickCounter);
-- if (ticket.getTicketLevel() < j) {
-- this.ticketTracker.update(i, ticket.getTicketLevel(), true);
+- if (ticket.getTicketLevel() < ticketLevelAt) {
+- this.ticketTracker.update(chunkPos, ticket.getTicketLevel(), true);
- }
--
- return ticket == ticket1; // CraftBukkit
-+ return this.moonrise$getChunkHolderManager().addTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system
++ return this.moonrise$getChunkHolderManager().addTicketAtLevel((TicketType)ticket.getType(), chunkPos, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system
}
- boolean removeTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
-- SortedArraySet<Ticket<?>> arraysetsorted = this.getTickets(i);
--
+ boolean removeTicket(long chunkPos, Ticket<?> ticket) { // CraftBukkit - void -> boolean
+- SortedArraySet<Ticket<?>> tickets = this.getTickets(chunkPos);
- boolean removed = false; // CraftBukkit
-- if (arraysetsorted.remove(ticket)) {
+- if (tickets.remove(ticket)) {
- removed = true; // CraftBukkit
- }
-
-- if (arraysetsorted.isEmpty()) {
-- this.tickets.remove(i);
+- if (tickets.isEmpty()) {
+- this.tickets.remove(chunkPos);
- }
-
-- this.ticketTracker.update(i, DistanceManager.getTicketLevelAt(arraysetsorted), false);
+- this.ticketTracker.update(chunkPos, getTicketLevelAt(tickets), false);
- return removed; // CraftBukkit
-+ return this.moonrise$getChunkHolderManager().removeTicketAtLevel((TicketType)ticket.getType(), i, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system
++ return this.moonrise$getChunkHolderManager().removeTicketAtLevel((TicketType)ticket.getType(), chunkPos, ticket.getTicketLevel(), ticket.key); // Paper - rewrite chunk system
}
- public <T> void addTicket(TicketType<T> type, ChunkPos pos, int level, T argument) {
-@@ -219,13 +128,7 @@ public abstract class DistanceManager {
+ public <T> void addTicket(TicketType<T> type, ChunkPos pos, int level, T value) {
+@@ -189,12 +123,7 @@ public abstract class DistanceManager {
+ this.addRegionTicketAtDistance(type, pos, distance, value);
}
-
- public <T> boolean addRegionTicketAtDistance(TicketType<T> tickettype, ChunkPos chunkcoordintpair, int i, T t0) {
+ public <T> boolean addRegionTicketAtDistance(TicketType<T> type, ChunkPos pos, int distance, T value) {
- // CraftBukkit end
-- Ticket<T> ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0);
-- long j = chunkcoordintpair.toLong();
--
-- boolean added = this.addTicket(j, ticket); // CraftBukkit
-- this.tickingTicketsTracker.addTicket(j, ticket);
-- return added; // CraftBukkit
-+ return this.moonrise$getChunkHolderManager().addTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system
+- Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value);
+- long packedChunkPos = pos.toLong();
+- final boolean addded = this.addTicket(packedChunkPos, ticket); // CraftBukkit
+- this.tickingTicketsTracker.addTicket(packedChunkPos, ticket);
+- return addded; // CraftBukkit
++ return this.moonrise$getChunkHolderManager().addTicketAtLevel(type, pos, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value); // Paper - rewrite chunk system
}
- public <T> void removeRegionTicket(TicketType<T> type, ChunkPos pos, int radius, T argument) {
-@@ -234,32 +137,21 @@ public abstract class DistanceManager {
+ public <T> void removeRegionTicket(TicketType<T> type, ChunkPos pos, int distance, T value) {
+@@ -202,37 +131,29 @@ public abstract class DistanceManager {
+ removeRegionTicketAtDistance(type, pos, distance, value);
}
-
- public <T> boolean removeRegionTicketAtDistance(TicketType<T> tickettype, ChunkPos chunkcoordintpair, int i, T t0) {
+ public <T> boolean removeRegionTicketAtDistance(TicketType<T> type, ChunkPos pos, int distance, T value) {
- // CraftBukkit end
-- Ticket<T> ticket = new Ticket<>(tickettype, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0);
-- long j = chunkcoordintpair.toLong();
--
-- boolean removed = this.removeTicket(j, ticket); // CraftBukkit
-- this.tickingTicketsTracker.removeTicket(j, ticket);
+- Ticket<T> ticket = new Ticket<>(type, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value);
+- long packedChunkPos = pos.toLong();
+- final boolean removed = this.removeTicket(packedChunkPos, ticket); // CraftBukkit
+- this.tickingTicketsTracker.removeTicket(packedChunkPos, ticket);
- return removed; // CraftBukkit
-+ return this.moonrise$getChunkHolderManager().removeTicketAtLevel(tickettype, chunkcoordintpair, ChunkLevel.byStatus(FullChunkStatus.FULL) - i, t0); // Paper - rewrite chunk system
++ return this.moonrise$getChunkHolderManager().removeTicketAtLevel(type, pos, ChunkLevel.byStatus(FullChunkStatus.FULL) - distance, value); // Paper - rewrite chunk system
}
- private SortedArraySet<Ticket<?>> getTickets(long position) {
-- return (SortedArraySet) this.tickets.computeIfAbsent(position, (j) -> {
-- return SortedArraySet.create(4);
-- });
+ private SortedArraySet<Ticket<?>> getTickets(long chunkPos) {
+- return this.tickets.computeIfAbsent(chunkPos, l -> SortedArraySet.create(4));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- protected void updateChunkForced(ChunkPos pos, boolean forced) {
+ protected void updateChunkForced(ChunkPos pos, boolean add) {
- Ticket<ChunkPos> ticket = new Ticket<>(TicketType.FORCED, ChunkMap.FORCED_TICKET_LEVEL, pos);
-- long i = pos.toLong();
--
+- long packedChunkPos = pos.toLong();
+ // Paper start - rewrite chunk system
- if (forced) {
-- this.addTicket(i, ticket);
-- this.tickingTicketsTracker.addTicket(i, ticket);
+ if (add) {
+- this.addTicket(packedChunkPos, ticket);
+- this.tickingTicketsTracker.addTicket(packedChunkPos, ticket);
+ this.moonrise$getChunkHolderManager().addTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos);
} else {
-- this.removeTicket(i, ticket);
-- this.tickingTicketsTracker.removeTicket(i, ticket);
+- this.removeTicket(packedChunkPos, ticket);
+- this.tickingTicketsTracker.removeTicket(packedChunkPos, ticket);
+ this.moonrise$getChunkHolderManager().removeTicketAtLevel(TicketType.FORCED, pos, ChunkMap.FORCED_TICKET_LEVEL, pos);
}
+ // Paper end - rewrite chunk system
-
}
-@@ -270,9 +162,8 @@ public abstract class DistanceManager {
- ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> {
- return new ObjectOpenHashSet();
- })).add(player);
-- this.naturalSpawnChunkCounter.update(i, 0, true);
-- this.playerTicketManager.update(i, 0, true);
-- this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
+ public void addPlayer(SectionPos sectionPos, ServerPlayer player) {
+ ChunkPos chunkPos = sectionPos.chunk();
+ long packedChunkPos = chunkPos.toLong();
+ this.playersPerChunk.computeIfAbsent(packedChunkPos, l -> new ObjectOpenHashSet<>()).add(player);
+- this.naturalSpawnChunkCounter.update(packedChunkPos, 0, true);
+- this.playerTicketManager.update(packedChunkPos, 0, true);
+- this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkPos, this.getPlayerTicketLevel(), chunkPos);
+ // Paper - chunk tick iteration optimisation
+ // Paper - rewrite chunk system
}
- public void removePlayer(SectionPos pos, ServerPlayer player) {
-@@ -284,160 +175,93 @@ public abstract class DistanceManager {
- if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully
- if (objectset == null || objectset.isEmpty()) { // Paper
- this.playersPerChunk.remove(i);
-- this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false);
-- this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
-- this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
+ public void removePlayer(SectionPos sectionPos, ServerPlayer player) {
+@@ -246,136 +167,90 @@ public abstract class DistanceManager {
+ if (set == null || set.isEmpty()) {
+ // Paper end - some state corruption happens here, don't crash, clean up gracefully
+ this.playersPerChunk.remove(packedChunkPos);
+- this.naturalSpawnChunkCounter.update(packedChunkPos, Integer.MAX_VALUE, false);
+- this.playerTicketManager.update(packedChunkPos, Integer.MAX_VALUE, false);
+- this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkPos, this.getPlayerTicketLevel(), chunkPos);
+ // Paper - chunk tick iteration optimisation
+ // Paper - rewrite chunk system
}
-
}
private int getPlayerTicketLevel() {
@@ -25994,11 +25527,10 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ // Paper end - rewrite chunk system
}
- protected String getTicketDebugString(long pos) {
-- SortedArraySet<Ticket<?>> arraysetsorted = (SortedArraySet) this.tickets.get(pos);
--
-- return arraysetsorted != null && !arraysetsorted.isEmpty() ? ((Ticket) arraysetsorted.first()).toString() : "no_ticket";
-+ return this.moonrise$getChunkHolderManager().getTicketDebugString(pos); // Paper - rewrite chunk system
+ protected String getTicketDebugString(long chunkPos) {
+- SortedArraySet<Ticket<?>> set = this.tickets.get(chunkPos);
+- return set != null && !set.isEmpty() ? set.first().toString() : "no_ticket";
++ return this.moonrise$getChunkHolderManager().getTicketDebugString(chunkPos); // Paper - rewrite chunk system
}
protected void updatePlayerTickets(int viewDistance) {
@@ -26014,7 +25546,7 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ // Paper start - rewrite chunk system
+ // note: vanilla does not clamp to 0, but we do simply because we need a min of 0
+ final int clamped = net.minecraft.util.Mth.clamp(simulationDistance, 0, ca.spottedleaf.moonrise.common.util.MoonriseConstants.MAX_VIEW_DISTANCE);
-
++
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.moonrise$getChunkMap().level).moonrise$getPlayerChunkLoader().setTickDistance(clamped);
+ // Paper end - rewrite chunk system
}
@@ -26042,40 +25574,21 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
+ return "No DistanceManager stats available"; // Paper - rewrite chunk system
}
- private void dumpTickets(String path) {
-- try {
-- FileOutputStream fileoutputstream = new FileOutputStream(new File(path));
--
-- try {
-- ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().iterator();
--
-- while (objectiterator.hasNext()) {
-- Entry<SortedArraySet<Ticket<?>>> entry = (Entry) objectiterator.next();
-- ChunkPos chunkcoordintpair = new ChunkPos(entry.getLongKey());
-- Iterator iterator = ((SortedArraySet) entry.getValue()).iterator();
--
-- while (iterator.hasNext()) {
-- Ticket<?> ticket = (Ticket) iterator.next();
+ private void dumpTickets(String filename) {
+- try (FileOutputStream fileOutputStream = new FileOutputStream(new File(filename))) {
+- for (Entry<SortedArraySet<Ticket<?>>> entry : this.tickets.long2ObjectEntrySet()) {
+- ChunkPos chunkPos = new ChunkPos(entry.getLongKey());
-
-- fileoutputstream.write((chunkcoordintpair.x + "\t" + chunkcoordintpair.z + "\t" + String.valueOf(ticket.getType()) + "\t" + ticket.getTicketLevel() + "\t\n").getBytes(StandardCharsets.UTF_8));
-- }
-- }
-- } catch (Throwable throwable) {
-- try {
-- fileoutputstream.close();
-- } catch (Throwable throwable1) {
-- throwable.addSuppressed(throwable1);
+- for (Ticket<?> ticket : entry.getValue()) {
+- fileOutputStream.write(
+- (chunkPos.x + "\t" + chunkPos.z + "\t" + ticket.getType() + "\t" + ticket.getTicketLevel() + "\t\n").getBytes(StandardCharsets.UTF_8)
+- );
- }
--
-- throw throwable;
- }
--
-- fileoutputstream.close();
-- } catch (IOException ioexception) {
-- DistanceManager.LOGGER.error("Failed to dump tickets to {}", path, ioexception);
+- } catch (IOException var10) {
+- LOGGER.error("Failed to dump tickets to {}", filename, var10);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
-
}
@VisibleForTesting
@@ -26090,18 +25603,17 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
}
public void removeTicketsOnClosing() {
-- ImmutableSet<TicketType<?>> immutableset = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.FUTURE_AWAIT); // Paper - add additional tickets to preserve
-- ObjectIterator<Entry<SortedArraySet<Ticket<?>>>> objectiterator = this.tickets.long2ObjectEntrySet().fastIterator();
+- ImmutableSet<TicketType<?>> set = ImmutableSet.of(TicketType.UNKNOWN, TicketType.POST_TELEPORT, TicketType.FUTURE_AWAIT); // Paper - add additional tickets to preserve
+- ObjectIterator<Entry<SortedArraySet<Ticket<?>>>> objectIterator = this.tickets.long2ObjectEntrySet().fastIterator();
-
-- while (objectiterator.hasNext()) {
-- Entry<SortedArraySet<Ticket<?>>> entry = (Entry) objectiterator.next();
-- Iterator<Ticket<?>> iterator = ((SortedArraySet) entry.getValue()).iterator();
+- while (objectIterator.hasNext()) {
+- Entry<SortedArraySet<Ticket<?>>> entry = objectIterator.next();
+- Iterator<Ticket<?>> iterator = entry.getValue().iterator();
- boolean flag = false;
-
- while (iterator.hasNext()) {
-- Ticket<?> ticket = (Ticket) iterator.next();
--
-- if (!immutableset.contains(ticket.getType())) {
+- Ticket<?> ticket = iterator.next();
+- if (!set.contains(ticket.getType())) {
- iterator.remove();
- flag = true;
- this.tickingTicketsTracker.removeTicket(entry.getLongKey(), ticket);
@@ -26109,15 +25621,14 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
- }
-
- if (flag) {
-- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false);
+- this.ticketTracker.update(entry.getLongKey(), getTicketLevelAt(entry.getValue()), false);
- }
-
-- if (((SortedArraySet) entry.getValue()).isEmpty()) {
-- objectiterator.remove();
+- if (entry.getValue().isEmpty()) {
+- objectIterator.remove();
- }
- }
+ // Paper - rewrite chunk system
-
}
public boolean hasTickets() {
@@ -26146,36 +25657,36 @@ index f7c2c03749d6be25bf33afd61e1da120770b3432..746f61661e22d22f2acbbe54a5933e57
}
// CraftBukkit end
-+ /* // Paper - rewrite chunk system
- private class ChunkTicketTracker extends ChunkTracker {
-
++/* // Paper - rewrite chunk system
+ class ChunkTicketTracker extends ChunkTracker {
private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1;
-@@ -483,7 +307,7 @@ public abstract class DistanceManager {
- public int runDistanceUpdates(int distance) {
- return this.runUpdates(distance);
+
+@@ -420,7 +295,7 @@ public abstract class DistanceManager {
+ public int runDistanceUpdates(int toUpdateCount) {
+ return this.runUpdates(toUpdateCount);
}
- }
+ }*/ // Paper - rewrite chunk system
- private class FixedPlayerDistanceChunkTracker extends ChunkTracker {
-
-@@ -563,6 +387,7 @@ public abstract class DistanceManager {
+ class FixedPlayerDistanceChunkTracker extends ChunkTracker {
+ protected final Long2ByteMap chunks = new Long2ByteOpenHashMap();
+@@ -479,6 +354,7 @@ public abstract class DistanceManager {
}
}
-+ /* // Paper - rewrite chunk system
- private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker {
-
- private int viewDistance = 0;
-@@ -657,5 +482,5 @@ public abstract class DistanceManager {
- private boolean haveTicketFor(int distance) {
- return distance <= this.viewDistance;
++/* // Paper - rewrite chunk system
+ class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker {
+ private int viewDistance;
+ private final Long2IntMap queueLevels = Long2IntMaps.synchronize(new Long2IntOpenHashMap());
+@@ -555,5 +431,5 @@ public abstract class DistanceManager {
+ private boolean haveTicketFor(int level) {
+ return level <= this.viewDistance;
}
- }
+ }*/ // Paper - rewrite chunk system
}
diff --git a/net/minecraft/server/level/GenerationChunkHolder.java b/net/minecraft/server/level/GenerationChunkHolder.java
-index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a5fd7489a 100644
+index cb66209c64b855dedf2e4e114a7716da13bc4587..da1366fdc4889d6a3befd43d81a19a816ed4cbe9 100644
--- a/net/minecraft/server/level/GenerationChunkHolder.java
+++ b/net/minecraft/server/level/GenerationChunkHolder.java
@@ -27,13 +27,7 @@ public abstract class GenerationChunkHolder {
@@ -26196,52 +25707,52 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
@@ -43,243 +37,96 @@ public abstract class GenerationChunkHolder {
}
- public CompletableFuture<ChunkResult<ChunkAccess>> scheduleChunkGenerationTask(ChunkStatus requestedStatus, ChunkMap chunkLoadingManager) {
-- if (this.isStatusDisallowed(requestedStatus)) {
+ public CompletableFuture<ChunkResult<ChunkAccess>> scheduleChunkGenerationTask(ChunkStatus targetStatus, ChunkMap chunkMap) {
+- if (this.isStatusDisallowed(targetStatus)) {
- return UNLOADED_CHUNK_FUTURE;
- } else {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.getOrCreateFuture(requestedStatus);
-- if (completableFuture.isDone()) {
-- return completableFuture;
+- CompletableFuture<ChunkResult<ChunkAccess>> future = this.getOrCreateFuture(targetStatus);
+- if (future.isDone()) {
+- return future;
- } else {
- ChunkGenerationTask chunkGenerationTask = this.task.get();
-- if (chunkGenerationTask == null || requestedStatus.isAfter(chunkGenerationTask.targetStatus)) {
-- this.rescheduleChunkTask(chunkLoadingManager, requestedStatus);
+- if (chunkGenerationTask == null || targetStatus.isAfter(chunkGenerationTask.targetStatus)) {
+- this.rescheduleChunkTask(chunkMap, targetStatus);
- }
-
-- return completableFuture;
+- return future;
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- CompletableFuture<ChunkResult<ChunkAccess>> applyStep(ChunkStep step, GeneratingChunkMap chunkLoadingManager, StaticCache2D<GenerationChunkHolder> chunks) {
+ CompletableFuture<ChunkResult<ChunkAccess>> applyStep(ChunkStep step, GeneratingChunkMap chunkMap, StaticCache2D<GenerationChunkHolder> cache) {
- if (this.isStatusDisallowed(step.targetStatus())) {
- return UNLOADED_CHUNK_FUTURE;
- } else {
-- return this.acquireStatusBump(step.targetStatus()) ? chunkLoadingManager.applyStep(this, step, chunks).handle((chunk, throwable) -> {
+- return this.acquireStatusBump(step.targetStatus()) ? chunkMap.applyStep(this, step, cache).handle((chunkAccess, throwable) -> {
- if (throwable != null) {
- CrashReport crashReport = CrashReport.forThrowable(throwable, "Exception chunk generation/loading");
- MinecraftServer.setFatalException(new ReportedException(crashReport));
- } else {
-- this.completeFuture(step.targetStatus(), chunk);
+- this.completeFuture(step.targetStatus(), chunkAccess);
- }
-
-- return ChunkResult.of(chunk);
+- return ChunkResult.of(chunkAccess);
- }) : this.getOrCreateFuture(step.targetStatus());
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- protected void updateHighestAllowedStatus(ChunkMap chunkLoadingManager) {
+ protected void updateHighestAllowedStatus(ChunkMap chunkMap) {
- ChunkStatus chunkStatus = this.highestAllowedStatus;
-- ChunkStatus chunkStatus2 = ChunkLevel.generationStatus(this.getTicketLevel());
-- this.highestAllowedStatus = chunkStatus2;
-- boolean bl = chunkStatus != null && (chunkStatus2 == null || chunkStatus2.isBefore(chunkStatus));
-- if (bl) {
-- this.failAndClearPendingFuturesBetween(chunkStatus2, chunkStatus);
+- ChunkStatus chunkStatus1 = ChunkLevel.generationStatus(this.getTicketLevel());
+- this.highestAllowedStatus = chunkStatus1;
+- boolean flag = chunkStatus != null && (chunkStatus1 == null || chunkStatus1.isBefore(chunkStatus));
+- if (flag) {
+- this.failAndClearPendingFuturesBetween(chunkStatus1, chunkStatus);
- if (this.task.get() != null) {
-- this.rescheduleChunkTask(chunkLoadingManager, this.findHighestStatusWithPendingFuture(chunkStatus2));
+- this.rescheduleChunkTask(chunkMap, this.findHighestStatusWithPendingFuture(chunkStatus1));
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
@@ -26251,57 +25762,57 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = CompletableFuture.completedFuture(ChunkResult.of(chunk));
-
- for (int i = 0; i < this.futures.length() - 1; i++) {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture2 = this.futures.get(i);
-- Objects.requireNonNull(completableFuture2);
-- ChunkAccess chunkAccess = completableFuture2.getNow(NOT_DONE_YET).orElse(null);
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture1 = this.futures.get(i);
+- Objects.requireNonNull(completableFuture1);
+- ChunkAccess chunkAccess = completableFuture1.getNow(NOT_DONE_YET).orElse(null);
- if (!(chunkAccess instanceof ProtoChunk)) {
- throw new IllegalStateException("Trying to replace a ProtoChunk, but found " + chunkAccess);
- }
-
-- if (!this.futures.compareAndSet(i, completableFuture2, completableFuture)) {
+- if (!this.futures.compareAndSet(i, completableFuture1, completableFuture)) {
- throw new IllegalStateException("Future changed by other thread while trying to replace it");
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- void removeTask(ChunkGenerationTask loader) {
-- this.task.compareAndSet(loader, null);
+ void removeTask(ChunkGenerationTask task) {
+- this.task.compareAndSet(task, null);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void rescheduleChunkTask(ChunkMap chunkLoadingManager, @Nullable ChunkStatus requestedStatus) {
+ private void rescheduleChunkTask(ChunkMap chunkMap, @Nullable ChunkStatus targetStatus) {
- ChunkGenerationTask chunkGenerationTask;
-- if (requestedStatus != null) {
-- chunkGenerationTask = chunkLoadingManager.scheduleGenerationTask(requestedStatus, this.getPos());
+- if (targetStatus != null) {
+- chunkGenerationTask = chunkMap.scheduleGenerationTask(targetStatus, this.getPos());
- } else {
- chunkGenerationTask = null;
- }
-
-- ChunkGenerationTask chunkGenerationTask3 = this.task.getAndSet(chunkGenerationTask);
-- if (chunkGenerationTask3 != null) {
-- chunkGenerationTask3.markForCancellation();
+- ChunkGenerationTask chunkGenerationTask1 = this.task.getAndSet(chunkGenerationTask);
+- if (chunkGenerationTask1 != null) {
+- chunkGenerationTask1.markForCancellation();
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private CompletableFuture<ChunkResult<ChunkAccess>> getOrCreateFuture(ChunkStatus status) {
-- if (this.isStatusDisallowed(status)) {
+ private CompletableFuture<ChunkResult<ChunkAccess>> getOrCreateFuture(ChunkStatus targetStatus) {
+- if (this.isStatusDisallowed(targetStatus)) {
- return UNLOADED_CHUNK_FUTURE;
- } else {
-- int i = status.getIndex();
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(i);
+- int index = targetStatus.getIndex();
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(index);
-
- while (completableFuture == null) {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture2 = new CompletableFuture<>();
-- completableFuture = this.futures.compareAndExchange(i, null, completableFuture2);
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture1 = new CompletableFuture<>();
+- completableFuture = this.futures.compareAndExchange(index, null, completableFuture1);
- if (completableFuture == null) {
-- if (this.isStatusDisallowed(status)) {
-- this.failAndClearPendingFuture(i, completableFuture2);
+- if (this.isStatusDisallowed(targetStatus)) {
+- this.failAndClearPendingFuture(index, completableFuture1);
- return UNLOADED_CHUNK_FUTURE;
- }
-
-- return completableFuture2;
+- return completableFuture1;
- }
- }
-
@@ -26310,34 +25821,34 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void failAndClearPendingFuturesBetween(@Nullable ChunkStatus from, ChunkStatus to) {
-- int i = from == null ? 0 : from.getIndex() + 1;
-- int j = to.getIndex();
+ private void failAndClearPendingFuturesBetween(@Nullable ChunkStatus highestAllowableStatus, ChunkStatus currentStatus) {
+- int i = highestAllowableStatus == null ? 0 : highestAllowableStatus.getIndex() + 1;
+- int index = currentStatus.getIndex();
-
-- for (int k = i; k <= j; k++) {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(k);
+- for (int i1 = i; i1 <= index; i1++) {
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(i1);
- if (completableFuture != null) {
-- this.failAndClearPendingFuture(k, completableFuture);
+- this.failAndClearPendingFuture(i1, completableFuture);
- }
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void failAndClearPendingFuture(int statusIndex, CompletableFuture<ChunkResult<ChunkAccess>> previousFuture) {
-- if (previousFuture.complete(UNLOADED_CHUNK) && !this.futures.compareAndSet(statusIndex, previousFuture, null)) {
+ private void failAndClearPendingFuture(int status, CompletableFuture<ChunkResult<ChunkAccess>> future) {
+- if (future.complete(UNLOADED_CHUNK) && !this.futures.compareAndSet(status, future, null)) {
- throw new IllegalStateException("Nothing else should replace the future here");
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void completeFuture(ChunkStatus status, ChunkAccess chunk) {
-- ChunkResult<ChunkAccess> chunkResult = ChunkResult.of(chunk);
-- int i = status.getIndex();
+ private void completeFuture(ChunkStatus targetStatus, ChunkAccess chunkAccess) {
+- ChunkResult<ChunkAccess> chunkResult = ChunkResult.of(chunkAccess);
+- int index = targetStatus.getIndex();
-
- while (true) {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(i);
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(index);
- if (completableFuture == null) {
-- if (this.futures.compareAndSet(i, null, CompletableFuture.completedFuture(chunkResult))) {
+- if (this.futures.compareAndSet(index, null, CompletableFuture.completedFuture(chunkResult))) {
- return;
- }
- } else {
@@ -26356,14 +25867,14 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
}
@Nullable
- private ChunkStatus findHighestStatusWithPendingFuture(@Nullable ChunkStatus checkUpperBound) {
-- if (checkUpperBound == null) {
+ private ChunkStatus findHighestStatusWithPendingFuture(@Nullable ChunkStatus generationStatus) {
+- if (generationStatus == null) {
- return null;
- } else {
-- ChunkStatus chunkStatus = checkUpperBound;
+- ChunkStatus chunkStatus = generationStatus;
-
-- for (ChunkStatus chunkStatus2 = this.startedWork.get();
-- chunkStatus2 == null || chunkStatus.isAfter(chunkStatus2);
+- for (ChunkStatus chunkStatus1 = this.startedWork.get();
+- chunkStatus1 == null || chunkStatus.isAfter(chunkStatus1);
- chunkStatus = chunkStatus.getParent()
- ) {
- if (this.futures.get(chunkStatus.getIndex()) != null) {
@@ -26380,15 +25891,15 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private boolean acquireStatusBump(ChunkStatus nextStatus) {
-- ChunkStatus chunkStatus = nextStatus == ChunkStatus.EMPTY ? null : nextStatus.getParent();
-- ChunkStatus chunkStatus2 = this.startedWork.compareAndExchange(chunkStatus, nextStatus);
-- if (chunkStatus2 == chunkStatus) {
+ private boolean acquireStatusBump(ChunkStatus status) {
+- ChunkStatus chunkStatus = status == ChunkStatus.EMPTY ? null : status.getParent();
+- ChunkStatus chunkStatus1 = this.startedWork.compareAndExchange(chunkStatus, status);
+- if (chunkStatus1 == chunkStatus) {
- return true;
-- } else if (chunkStatus2 != null && !nextStatus.isAfter(chunkStatus2)) {
+- } else if (chunkStatus1 != null && !status.isAfter(chunkStatus1)) {
- return false;
- } else {
-- throw new IllegalStateException("Unexpected last startedWork status: " + chunkStatus2 + " while trying to start: " + nextStatus);
+- throw new IllegalStateException("Unexpected last startedWork status: " + chunkStatus1 + " while trying to start: " + status);
- }
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -26399,7 +25910,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- protected abstract void addSaveDependency(CompletableFuture<?> savingFuture);
+ protected abstract void addSaveDependency(CompletableFuture<?> saveDependency);
public void increaseGenerationRefCount() {
- if (this.generationRefCount.getAndIncrement() == 0) {
@@ -26423,19 +25934,19 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
}
@Nullable
- public ChunkAccess getChunkIfPresentUnchecked(ChunkStatus requestedStatus) {
-- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(requestedStatus.getIndex());
+ public ChunkAccess getChunkIfPresentUnchecked(ChunkStatus status) {
+- CompletableFuture<ChunkResult<ChunkAccess>> completableFuture = this.futures.get(status.getIndex());
- return completableFuture == null ? null : completableFuture.getNow(NOT_DONE_YET).orElse(null);
+ // Paper start - rewrite chunk system
-+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)(Object)this).moonrise$getRealChunkHolder().getChunkIfPresentUnchecked(requestedStatus);
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)(Object)this).moonrise$getRealChunkHolder().getChunkIfPresentUnchecked(status);
+ // Paper end - rewrite chunk system
}
@Nullable
- public ChunkAccess getChunkIfPresent(ChunkStatus requestedStatus) {
-- return this.isStatusDisallowed(requestedStatus) ? null : this.getChunkIfPresentUnchecked(requestedStatus);
+ public ChunkAccess getChunkIfPresent(ChunkStatus status) {
+- return this.isStatusDisallowed(status) ? null : this.getChunkIfPresentUnchecked(status);
+ // Paper start - rewrite chunk system
-+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)(Object)this).moonrise$getRealChunkHolder().getChunkIfPresent(requestedStatus);
++ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)(Object)this).moonrise$getRealChunkHolder().getChunkIfPresent(status);
+ // Paper end - rewrite chunk system
}
@@ -26445,8 +25956,8 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
- if (chunkStatus == null) {
- return null;
- } else {
-- ChunkAccess chunkAccess = this.getChunkIfPresentUnchecked(chunkStatus);
-- return chunkAccess != null ? chunkAccess : this.getChunkIfPresentUnchecked(chunkStatus.getParent());
+- ChunkAccess chunkIfPresentUnchecked = this.getChunkIfPresentUnchecked(chunkStatus);
+- return chunkIfPresentUnchecked != null ? chunkIfPresentUnchecked : this.getChunkIfPresentUnchecked(chunkStatus.getParent());
- }
+ // Paper start - rewrite chunk system
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder.ChunkCompletion lastCompletion = ((ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder)(Object)this).moonrise$getRealChunkHolder().getLastChunkCompletion();
@@ -26494,8 +26005,8 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
public ChunkStatus getLatestStatus() {
- for (int i = CHUNK_STATUSES.size() - 1; i >= 0; i--) {
- ChunkStatus chunkStatus = CHUNK_STATUSES.get(i);
-- ChunkAccess chunkAccess = this.getChunkIfPresentUnchecked(chunkStatus);
-- if (chunkAccess != null) {
+- ChunkAccess chunkIfPresentUnchecked = this.getChunkIfPresentUnchecked(chunkStatus);
+- if (chunkIfPresentUnchecked != null) {
- return chunkStatus;
- }
- }
@@ -26508,7 +26019,7 @@ index 65206fdfa5b94eaca139e433b4865c16b16641f3..bf4463bcb5dc439ac5a3fa08dd60845a
}
}
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
-index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa7130c20f 100644
+index 796b5f8541b0cf84482ab2b5a60adde544d43593..7ce641cc34ef95e248e62ebf0b7fdfb8b2924256 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -52,7 +52,7 @@ import net.minecraft.world.level.storage.DimensionDataStorage;
@@ -26517,10 +26028,10 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
-public class ServerChunkCache extends ChunkSource {
+public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache { // Paper - rewrite chunk system
-
private static final Logger LOGGER = LogUtils.getLogger();
private final DistanceManager distanceManager;
-@@ -81,6 +81,107 @@ public class ServerChunkCache extends ChunkSource {
+ private final ServerLevel level;
+@@ -80,6 +80,107 @@ public class ServerChunkCache extends ChunkSource {
}
long chunkFutureAwaitCounter;
// Paper end
@@ -26626,9 +26137,9 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
+ // Paper end - chunk tick iteration optimisations
+
- 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<DimensionDataStorage> persistentStateManagerFactory) {
- this.level = world;
-@@ -112,13 +213,7 @@ public class ServerChunkCache extends ChunkSource {
+ public ServerChunkCache(
+ ServerLevel level,
+@@ -138,13 +239,7 @@ public class ServerChunkCache extends ChunkSource {
}
// CraftBukkit end
// Paper start
@@ -26643,61 +26154,54 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
@Nullable
public ChunkAccess getChunkAtImmediately(int x, int z) {
-@@ -189,59 +284,42 @@ public class ServerChunkCache extends ChunkSource {
+@@ -215,51 +310,42 @@ public class ServerChunkCache extends ChunkSource {
@Nullable
@Override
- public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) {
+ public ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk) {
- if (Thread.currentThread() != this.mainThread) {
-- return (ChunkAccess) CompletableFuture.supplyAsync(() -> {
-- return this.getChunk(x, z, leastStatus, create);
-- }, this.mainThreadProcessor).join();
+- return CompletableFuture.<ChunkAccess>supplyAsync(() -> this.getChunk(x, z, chunkStatus, requireChunk), this.mainThreadProcessor).join();
- } else {
- // Paper start - Perf: Optimise getChunkAt calls for loaded chunks
-- LevelChunk ifLoaded = this.getChunkAtIfLoadedMainThread(x, z);
+- LevelChunk ifLoaded = this.getChunkAtIfCachedImmediately(x, z);
- if (ifLoaded != null) {
- return ifLoaded;
- }
- // Paper end - Perf: Optimise getChunkAt calls for loaded chunks
-- ProfilerFiller gameprofilerfiller = Profiler.get();
+- ProfilerFiller profilerFiller = Profiler.get();
+- profilerFiller.incrementCounter("getChunk");
+- long packedChunkPos = ChunkPos.asLong(x, z);
+-
+- for (int i = 0; i < 4; i++) {
+- if (packedChunkPos == this.lastChunkPos[i] && chunkStatus == this.lastChunkStatus[i]) {
+- ChunkAccess chunkAccess = this.lastChunk[i];
+- if (chunkAccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime
+- return chunkAccess;
+- }
+- }
+- }
+ // Paper start - rewrite chunk system
-+ if (leastStatus == ChunkStatus.FULL) {
++ if (chunkStatus == ChunkStatus.FULL) {
+ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(x, z));
-- gameprofilerfiller.incrementCounter("getChunk");
-- long k = ChunkPos.asLong(x, z);
--
-- for (int l = 0; l < 4; ++l) {
-- if (k == this.lastChunkPos[l] && leastStatus == this.lastChunkStatus[l]) {
-- ChunkAccess ichunkaccess = this.lastChunk[l];
--
-- if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime
-- return ichunkaccess;
-- }
-- }
+- profilerFiller.incrementCounter("getChunkCacheMiss");
+- CompletableFuture<ChunkResult<ChunkAccess>> chunkFutureMainThread = this.getChunkFutureMainThread(x, z, chunkStatus, requireChunk);
+- this.mainThreadProcessor.managedBlock(chunkFutureMainThread::isDone);
+- // com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads
+- ChunkResult<ChunkAccess> chunkResult = chunkFutureMainThread.join();
+- ChunkAccess chunkAccess1 = chunkResult.orElse(null);
+- if (chunkAccess1 == null && requireChunk) {
+- throw (IllegalStateException)Util.pauseInIde(new IllegalStateException("Chunk not there when requested: " + chunkResult.getError()));
+- } else {
+- this.storeInCache(packedChunkPos, chunkAccess1, chunkStatus);
+- return chunkAccess1;
+ if (ret != null) {
+ return ret;
}
-
-- gameprofilerfiller.incrementCounter("getChunkCacheMiss");
-- CompletableFuture<ChunkResult<ChunkAccess>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create);
-- ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor;
--
-- Objects.requireNonNull(completablefuture);
-- chunkproviderserver_b.managedBlock(completablefuture::isDone);
-- // com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x, z); // Paper - Add debug for sync chunk loads
-- ChunkResult<ChunkAccess> chunkresult = (ChunkResult) completablefuture.join();
-- ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error
--
-- if (ichunkaccess1 == null && create) {
-- throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("Chunk not there when requested: " + chunkresult.getError()));
-- } else {
-- this.storeInCache(k, ichunkaccess1, leastStatus);
-- return ichunkaccess1;
-- }
-+ return create ? this.getChunkFallback(x, z, leastStatus, create) : null;
++
++ return requireChunk ? this.getChunkFallback(x, z, chunkStatus, requireChunk) : null;
}
+
-+ return this.getChunkFallback(x, z, leastStatus, create);
++ return this.getChunkFallback(x, z, chunkStatus, requireChunk);
+ // Paper end - rewrite chunk system
}
@@ -26707,7 +26211,7 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
- if (Thread.currentThread() != this.mainThread) {
- return null;
- } else {
-- return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
+- return this.getChunkAtIfCachedImmediately(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
+ // Paper start - rewrite chunk system
+ final LevelChunk ret = this.fullChunks.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ if (!ca.spottedleaf.moonrise.common.PlatformHooks.get().hasCurrentlyLoadingChunk()) {
@@ -26716,64 +26220,64 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
+
+ if (ret != null || !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) {
+ return ret;
-+ }
+ }
+
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler()
+ .chunkHolderManager.getChunkHolder(chunkX, chunkZ);
+ if (holder == null) {
+ return ret;
- }
++ }
+
+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getCurrentlyLoadingChunk(holder.vanillaChunkHolder);
+ // Paper end - rewrite chunk system
}
private void clearCache() {
-@@ -272,56 +350,59 @@ public class ServerChunkCache extends ChunkSource {
+@@ -285,54 +371,59 @@ public class ServerChunkCache extends ChunkSource {
}
- private CompletableFuture<ChunkResult<ChunkAccess>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
-- ChunkPos chunkcoordintpair = new ChunkPos(chunkX, chunkZ);
-- long k = chunkcoordintpair.toLong();
-- int l = ChunkLevel.byStatus(leastStatus);
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(k);
--
+ private CompletableFuture<ChunkResult<ChunkAccess>> getChunkFutureMainThread(int x, int z, ChunkStatus chunkStatus, boolean requireChunk) {
+- ChunkPos chunkPos = new ChunkPos(x, z);
+- long packedChunkPos = chunkPos.toLong();
+- int i = ChunkLevel.byStatus(chunkStatus);
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(packedChunkPos);
- // CraftBukkit start - don't add new ticket for currently unloading chunk
- boolean currentlyUnloading = false;
-- if (playerchunk != null) {
-- FullChunkStatus oldChunkState = ChunkLevel.fullStatus(playerchunk.oldTicketLevel);
-- FullChunkStatus currentChunkState = ChunkLevel.fullStatus(playerchunk.getTicketLevel());
+- if (visibleChunkIfPresent != null) {
+- FullChunkStatus oldChunkState = ChunkLevel.fullStatus(visibleChunkIfPresent.oldTicketLevel);
+- FullChunkStatus currentChunkState = ChunkLevel.fullStatus(visibleChunkIfPresent.getTicketLevel());
- currentlyUnloading = (oldChunkState.isOrAfter(FullChunkStatus.FULL) && !currentChunkState.isOrAfter(FullChunkStatus.FULL));
- }
-- if (create && !currentlyUnloading) {
-- // CraftBukkit end
-- this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
-- if (this.chunkAbsent(playerchunk, l)) {
-- ProfilerFiller gameprofilerfiller = Profiler.get();
--
-- gameprofilerfiller.push("chunkLoad");
+- if (requireChunk && !currentlyUnloading) {
+- // CraftBukkit end
+- this.distanceManager.addTicket(TicketType.UNKNOWN, chunkPos, i, chunkPos);
+- if (this.chunkAbsent(visibleChunkIfPresent, i)) {
+- ProfilerFiller profilerFiller = Profiler.get();
+- profilerFiller.push("chunkLoad");
- this.runDistanceManagerUpdates();
-- playerchunk = this.getVisibleChunkIfPresent(k);
-- gameprofilerfiller.pop();
-- if (this.chunkAbsent(playerchunk, l)) {
-- throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added"));
+- visibleChunkIfPresent = this.getVisibleChunkIfPresent(packedChunkPos);
+- profilerFiller.pop();
+- if (this.chunkAbsent(visibleChunkIfPresent, i)) {
+- throw (IllegalStateException)Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added"));
- }
- }
+ // Paper start - rewrite chunk system
-+ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, x, z, "Scheduling chunk load off-main");
+
-+ final int minLevel = ChunkLevel.byStatus(leastStatus);
-+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ);
++ final int minLevel = ChunkLevel.byStatus(chunkStatus);
++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(x, z);
+
-+ final boolean needsFullScheduling = leastStatus == ChunkStatus.FULL && (chunkHolder == null || !chunkHolder.getChunkStatus().isOrAfter(FullChunkStatus.FULL));
++ final boolean needsFullScheduling = chunkStatus == ChunkStatus.FULL && (chunkHolder == null || !chunkHolder.getChunkStatus().isOrAfter(FullChunkStatus.FULL));
+
-+ if ((chunkHolder == null || chunkHolder.getTicketLevel() > minLevel || needsFullScheduling) && !create) {
++ if ((chunkHolder == null || chunkHolder.getTicketLevel() > minLevel || needsFullScheduling) && !requireChunk) {
+ return ChunkHolder.UNLOADED_CHUNK_FUTURE;
}
-- return this.chunkAbsent(playerchunk, l) ? GenerationChunkHolder.UNLOADED_CHUNK_FUTURE : playerchunk.scheduleChunkGenerationTask(leastStatus, this.chunkMap);
+- return this.chunkAbsent(visibleChunkIfPresent, i)
+- ? GenerationChunkHolder.UNLOADED_CHUNK_FUTURE
+- : visibleChunkIfPresent.scheduleChunkGenerationTask(chunkStatus, this.chunkMap);
- }
-+ final ChunkAccess ifPresent = chunkHolder == null ? null : chunkHolder.getChunkIfPresent(leastStatus);
++ final ChunkAccess ifPresent = chunkHolder == null ? null : chunkHolder.getChunkIfPresent(chunkStatus);
+ if (needsFullScheduling || ifPresent == null) {
+ // schedule
+ final CompletableFuture<ChunkResult<ChunkAccess>> ret = new CompletableFuture<>();
@@ -26785,10 +26289,10 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
+ }
+ };
-- private boolean chunkAbsent(@Nullable ChunkHolder holder, int maxLevel) {
-- return holder == null || holder.oldTicketLevel > maxLevel; // CraftBukkit using oldTicketLevel for isLoaded checks
+- private boolean chunkAbsent(@Nullable ChunkHolder chunkHolder, int status) {
+- return chunkHolder == null || chunkHolder.oldTicketLevel > status; // CraftBukkit using oldTicketLevel for isLoaded checks
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(
-+ chunkX, chunkZ, leastStatus, true,
++ x, z, chunkStatus, true,
+ ca.spottedleaf.concurrentutil.util.Priority.HIGHER,
+ complete
+ );
@@ -26803,20 +26307,18 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
@Override
public boolean hasChunk(int x, int z) {
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent((new ChunkPos(x, z)).toLong());
-- int k = ChunkLevel.byStatus(ChunkStatus.FULL);
--
-- return !this.chunkAbsent(playerchunk, k);
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(new ChunkPos(x, z).toLong());
+- int i = ChunkLevel.byStatus(ChunkStatus.FULL);
+- return !this.chunkAbsent(visibleChunkIfPresent, i);
+ return this.getChunkNow(x, z) != null; // Paper - rewrite chunk system
}
@Nullable
@Override
public LightChunk getChunkForLighting(int chunkX, int chunkZ) {
-- long k = ChunkPos.asLong(chunkX, chunkZ);
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(k);
--
-- return playerchunk == null ? null : playerchunk.getChunkIfPresentUnchecked(ChunkStatus.INITIALIZE_LIGHT.getParent());
+- long packedChunkPos = ChunkPos.asLong(chunkX, chunkZ);
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(packedChunkPos);
+- return visibleChunkIfPresent == null ? null : visibleChunkIfPresent.getChunkIfPresentUnchecked(ChunkStatus.INITIALIZE_LIGHT.getParent());
+ // Paper start - rewrite chunk system
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ);
+ if (newChunkHolder == null) {
@@ -26827,13 +26329,12 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
}
@Override
-@@ -334,30 +415,18 @@ public class ServerChunkCache extends ChunkSource {
+@@ -345,28 +436,18 @@ public class ServerChunkCache extends ChunkSource {
}
public boolean runDistanceManagerUpdates() { // Paper - public
- boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
- boolean flag1 = this.chunkMap.promoteChunkMap();
--
- this.chunkMap.runGenerationTasks();
- if (!flag && !flag1) {
- return false;
@@ -26844,16 +26345,15 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.processTicketUpdates(); // Paper - rewrite chunk system
}
- public boolean isPositionTicking(long pos) {
-- if (!this.level.shouldTickBlocksAt(pos)) {
+ public boolean isPositionTicking(long chunkPos) {
+- if (!this.level.shouldTickBlocksAt(chunkPos)) {
- return false;
- } else {
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
--
-- return playerchunk == null ? false : ((ChunkResult) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).isSuccess();
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(chunkPos);
+- return visibleChunkIfPresent != null && visibleChunkIfPresent.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).isSuccess();
- }
+ // Paper start - rewrite chunk system
-+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(pos);
++ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
+ return newChunkHolder != null && newChunkHolder.isTickingReady();
+ // Paper end - rewrite chunk system
}
@@ -26864,7 +26364,7 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
this.chunkMap.saveAllChunks(flush);
}
-@@ -368,17 +437,15 @@ public class ServerChunkCache extends ChunkSource {
+@@ -377,17 +458,15 @@ public class ServerChunkCache extends ChunkSource {
}
public void close(boolean save) throws IOException {
@@ -26885,50 +26385,50 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
ProfilerFiller gameprofilerfiller = Profiler.get();
gameprofilerfiller.push("purge");
-@@ -403,6 +470,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -411,6 +490,7 @@ public class ServerChunkCache extends ChunkSource {
this.runDistanceManagerUpdates();
- gameprofilerfiller.popPush("chunks");
+ profilerFiller.popPush("chunks");
if (tickChunks) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system
this.tickChunks();
this.chunkMap.tick();
}
-@@ -429,7 +497,10 @@ public class ServerChunkCache extends ChunkSource {
- gameprofilerfiller.push("filteringTickingChunks");
+@@ -435,7 +515,10 @@ public class ServerChunkCache extends ChunkSource {
+ profilerFiller.push("filteringTickingChunks");
this.collectTickingChunks(list);
- gameprofilerfiller.popPush("shuffleChunks");
+ profilerFiller.popPush("shuffleChunks");
- Util.shuffle(list, this.level.random);
+ // Paper start - chunk tick iteration optimisation
+ this.shuffleRandom.setSeed(this.level.random.nextLong());
+ Util.shuffle(list, this.shuffleRandom);
+ // Paper end - chunk tick iteration optimisation
- this.tickChunks(gameprofilerfiller, j, list);
- gameprofilerfiller.pop();
+ this.tickChunks(profilerFiller, l, list);
+ profilerFiller.pop();
} finally {
-@@ -448,7 +519,7 @@ public class ServerChunkCache extends ChunkSource {
-
- while (iterator.hasNext()) {
- ChunkHolder playerchunk = (ChunkHolder) iterator.next();
-- LevelChunk chunk = playerchunk.getTickingChunk();
-+ LevelChunk chunk = playerchunk.getChunkToSend(); // Paper - rewrite chunk system
-
- if (chunk != null) {
- playerchunk.broadcastChanges(chunk);
-@@ -460,14 +531,26 @@ public class ServerChunkCache extends ChunkSource {
+@@ -452,7 +535,7 @@ public class ServerChunkCache extends ChunkSource {
+ profiler.push("broadcast");
+
+ for (ChunkHolder chunkHolder : this.chunkHoldersToBroadcast) {
+- LevelChunk tickingChunk = chunkHolder.getTickingChunk();
++ LevelChunk tickingChunk = chunkHolder.getChunkToSend(); // Paper - rewrite chunk system
+ if (tickingChunk != null) {
+ chunkHolder.broadcastChanges(tickingChunk);
+ }
+@@ -463,12 +546,26 @@ public class ServerChunkCache extends ChunkSource {
}
- private void collectTickingChunks(List<LevelChunk> chunks) {
-- this.chunkMap.forEachSpawnCandidateChunk((playerchunk) -> {
-- LevelChunk chunk = playerchunk.getTickingChunk();
+ private void collectTickingChunks(List<LevelChunk> output) {
+- this.chunkMap.forEachSpawnCandidateChunk(chunk -> {
+- LevelChunk tickingChunk = chunk.getTickingChunk();
+- if (tickingChunk != null && this.level.isNaturalSpawningAllowed(chunk.getPos())) {
+- output.add(tickingChunk);
+ // Paper start - chunk tick iteration optimisation
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerChunkCache.ChunkAndHolder> tickingChunks =
+ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel)this.level).moonrise$getPlayerTickingChunks();
+
+ final ServerChunkCache.ChunkAndHolder[] raw = tickingChunks.getRawDataUnchecked();
+ final int size = tickingChunks.size();
-
-- if (chunk != null && this.level.isNaturalSpawningAllowed(playerchunk.getPos())) {
-- chunks.add(chunk);
++
+ final ChunkMap chunkMap = this.chunkMap;
+
+ for (int i = 0; i < size; ++i) {
@@ -26938,43 +26438,42 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
+ if (!this.isChunkNearPlayer(chunkMap, levelChunk.getPos(), levelChunk)) {
+ continue;
}
-
- });
-+ chunks.add(levelChunk);
++
++ output.add(levelChunk);
+ }
+ // Paper end - chunk tick iteration optimisation
}
- private void tickChunks(ProfilerFiller profiler, long timeDelta, List<LevelChunk> chunks) {
-@@ -508,7 +591,7 @@ public class ServerChunkCache extends ChunkSource {
- NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, list1);
+ private void tickChunks(ProfilerFiller profiler, long timeInhabited, List<LevelChunk> chunks) {
+@@ -504,7 +601,7 @@ public class ServerChunkCache extends ChunkSource {
+ NaturalSpawner.spawnForChunk(this.level, levelChunk, spawnState, filteredSpawningCategories);
}
-- if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) {
+- if (this.level.shouldTickBlocksAt(pos.toLong())) {
+ if (true) { // Paper - rewrite chunk system
- this.level.tickChunk(chunk, k);
+ this.level.tickChunk(levelChunk, _int);
}
}
-@@ -521,11 +604,13 @@ public class ServerChunkCache extends ChunkSource {
+@@ -516,10 +613,13 @@ public class ServerChunkCache extends ChunkSource {
}
- private void getFullChunk(long pos, Consumer<LevelChunk> chunkConsumer) {
-- ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
--
-- if (playerchunk != null) {
-- ((ChunkResult) playerchunk.getFullChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).ifSuccess(chunkConsumer);
+ private void getFullChunk(long chunkPos, Consumer<LevelChunk> fullChunkGetter) {
+- ChunkHolder visibleChunkIfPresent = this.getVisibleChunkIfPresent(chunkPos);
+- if (visibleChunkIfPresent != null) {
+- visibleChunkIfPresent.getFullChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).ifSuccess(fullChunkGetter);
+ // Paper start - rewrite chunk system
+ // note: bypass currentlyLoaded from getChunkNow
-+ final LevelChunk fullChunk = this.fullChunks.get(pos);
++ final LevelChunk fullChunk = this.fullChunks.get(chunkPos);
+ if (fullChunk != null) {
-+ chunkConsumer.accept(fullChunk);
++ fullChunkGetter.accept(fullChunk);
}
+ // Paper end - rewrite chunk system
-
}
-@@ -619,6 +704,12 @@ public class ServerChunkCache extends ChunkSource {
- this.chunkMap.setServerViewDistance(watchDistance);
+ @Override
+@@ -607,6 +707,12 @@ public class ServerChunkCache extends ChunkSource {
+ this.chunkMap.setServerViewDistance(viewDistance);
}
+ // Paper start - rewrite chunk system
@@ -26986,11 +26485,20 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
public void setSimulationDistance(int simulationDistance) {
this.distanceManager.updateSimulationDistance(simulationDistance);
}
-@@ -710,21 +801,19 @@ public class ServerChunkCache extends ChunkSource {
+@@ -654,7 +760,7 @@ public class ServerChunkCache extends ChunkSource {
+ }
+ }
+
+- record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) {
++ public record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) { // Paper - public
+ }
+
+ public final class MainThreadExecutor extends BlockableEventLoop<Runnable> {
+@@ -695,18 +801,14 @@ public class ServerChunkCache extends ChunkSource {
+
@Override
- // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
public boolean pollTask() {
-- try {
+- try { // CraftBukkit - process pending Chunk loadCallback() and unloadCallback() after each run task
- if (ServerChunkCache.this.runDistanceManagerUpdates()) {
+ // Paper start - rewrite chunk system
+ final ServerChunkCache serverChunkCache = ServerChunkCache.this;
@@ -26999,26 +26507,22 @@ index 6a2af3cd3aebe525a5ff41a801929547d59b8fec..d7382fc1498a33db909c343d8d07c5aa
} else {
- ServerChunkCache.this.lightEngine.tryScheduleUpdate();
- return super.pollTask();
+- }
+- // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
+- } finally {
+- ServerChunkCache.this.chunkMap.callbackExecutor.run();
+ return super.pollTask() | ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)serverChunkCache.level).moonrise$getChunkTaskScheduler().executeMainThreadTask();
}
-- } finally {
-- ServerChunkCache.this.chunkMap.callbackExecutor.run();
-- }
+- // CraftBukkit end - process pending Chunk loadCallback() and unloadCallback() after each run task
+ // Paper end - rewrite chunk system
- // CraftBukkit end
}
}
-
-- private static record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) {
-+ public static record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) { // Paper - rewrite chunk system - public
-
- }
}
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
-index d5bc702f2676b1b7a32c8f3a4a349fc2710ee825..301e8d6599d200cb0f1328f0e386af2f9a619939 100644
+index 4c891706c2a3efc8e8c44fc1c031e8a1d21efb60..d38ddfd7afba189a489701e62b5fa6db8df87a9d 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
-@@ -101,6 +101,11 @@ public class ServerEntity {
+@@ -91,6 +91,11 @@ public class ServerEntity {
}
public void sendChanges() {
@@ -27027,24 +26531,24 @@ index d5bc702f2676b1b7a32c8f3a4a349fc2710ee825..301e8d6599d200cb0f1328f0e386af2f
+ this.teleportDelay = 9999;
+ }
+ // Paper end - optimise collisions
- List<Entity> list = this.entity.getPassengers();
-
- if (!list.equals(this.lastPassengers)) {
+ List<Entity> passengers = this.entity.getPassengers();
+ if (!passengers.equals(this.lastPassengers)) {
+ this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
-index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905d8325618 100644
+index 08ee3583a07b6e4e877e530d422e386597bce6de..3927f5603d18f1c42eb29d916f287b6ef3f39612 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
-@@ -186,7 +186,7 @@ import org.bukkit.event.weather.LightningStrikeEvent;
- import org.bukkit.event.world.TimeSkipEvent;
- // CraftBukkit end
+@@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
+ import net.minecraft.world.ticks.LevelTicks;
+ import org.slf4j.Logger;
-public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel {
-+public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader, ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel { // Paper - rewrite chunk system // Paper - chunk tick iteration
-
++public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader, ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel { // Paper - rewrite chunk system // Paper - chunk tick iteration
public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0);
public static final IntProvider RAIN_DELAY = UniformInt.of(12000, 180000);
-@@ -202,7 +202,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- public final PrimaryLevelData serverLevelData; // CraftBukkit - type
+ public static final IntProvider RAIN_DURATION = UniformInt.of(12000, 24000);
+@@ -185,7 +185,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
private int lastSpawnChunkRadius;
final EntityTickList entityTickList = new EntityTickList();
- public final PersistentEntitySectionManager<Entity> entityManager;
@@ -27052,7 +26556,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
private final GameEventDispatcher gameEventDispatcher;
public boolean noSave;
private final SleepStatus sleepStatus;
-@@ -273,12 +273,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -256,12 +256,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority,
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
@@ -27066,7 +26570,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3;
int minBlockZ = Mth.floor(axisalignedbb.minZ - 1.0E-7D) - 3;
-@@ -297,32 +292,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -280,32 +275,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public final void loadChunks(int minChunkX, int minChunkZ, int maxChunkX, int maxChunkZ,
ca.spottedleaf.concurrentutil.util.Priority priority,
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
@@ -27114,9 +26618,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder.ChunkCompletion lastCompletion = newChunkHolder.getLastChunkCompletion();
+ return lastCompletion == null ? null : lastCompletion.chunk();
+ }
-
-- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1);
-- int[] loadedChunks = new int[1];
++
+ @Override
+ public final ChunkAccess moonrise$getSpecificChunkIfLoaded(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus leastStatus) {
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ);
@@ -27135,14 +26637,12 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ public final ChunkAccess moonrise$syncLoadNonFull(final int chunkX, final int chunkZ, final net.minecraft.world.level.chunk.status.ChunkStatus status) {
+ return this.moonrise$getChunkTaskScheduler().syncLoadNonFull(chunkX, chunkZ, status);
+ }
-
-- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++);
++
+ @Override
+ public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler moonrise$getChunkTaskScheduler() {
+ return this.chunkTaskScheduler;
+ }
-
-- java.util.function.Consumer<net.minecraft.world.level.chunk.ChunkAccess> consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> {
++
+ @Override
+ public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController moonrise$getChunkDataController() {
+ return this.chunkDataController;
@@ -27207,14 +26707,18 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ final java.util.function.Consumer<java.util.List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler chunkTaskScheduler = this.moonrise$getChunkTaskScheduler();
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager chunkHolderManager = chunkTaskScheduler.chunkHolderManager;
-+
+
+- int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1);
+- int[] loadedChunks = new int[1];
+ final int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1);
+ final java.util.concurrent.atomic.AtomicInteger loadedChunks = new java.util.concurrent.atomic.AtomicInteger();
+ final Long holderIdentifier = ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.getNextChunkLoadId();
+ final int ticketLevel = ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.getTicketLevel(chunkStatus);
-+
+
+- Long holderIdentifier = Long.valueOf(chunkProvider.chunkFutureAwaitCounter++);
+ final List<ChunkAccess> ret = new ArrayList<>(requiredChunks);
-+
+
+- java.util.function.Consumer<net.minecraft.world.level.chunk.ChunkAccess> consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> {
+ final java.util.function.Consumer<net.minecraft.world.level.chunk.ChunkAccess> consumer = (final ChunkAccess chunk) -> {
if (chunk != null) {
- int ticketLevel = Math.max(33, chunkProvider.chunkMap.getUpdatingChunkIfPresent(chunk.getPos().toLong()).getTicketLevel());
@@ -27242,14 +26746,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
}
}
-@@ -330,22 +452,137 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
-
- for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
- for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
-- ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(
-- this, cx, cz, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true, priority, consumer
-- );
-+ chunkTaskScheduler.scheduleChunkLoad(cx, cz, chunkStatus, true, priority, consumer);
+@@ -319,16 +441,133 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
}
}
@@ -27263,8 +26760,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
- return player != null && player.level() == this ? player : null;
+ public final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder moonrise$getViewDistanceHolder() {
+ return this.viewDistanceHolder;
- }
-- // Paper end - optimise getPlayerByUUID
++ }
+
+ @Override
+ public final long moonrise$getLastMidTickFailure() {
@@ -27279,7 +26775,8 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ @Override
+ public final ca.spottedleaf.moonrise.common.misc.NearbyPlayers moonrise$getNearbyPlayers() {
+ return this.nearbyPlayers;
-+ }
+ }
+- // Paper end - optimise getPlayerByUUID
+
+ @Override
+ public final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerChunkCache.ChunkAndHolder> moonrise$getLoadedChunks() {
@@ -27388,38 +26885,49 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ }
+ // Paper end - chunk tick iteration
- // Add env and gen to constructor, IWorldDataServer -> WorldDataServer
- public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
-@@ -379,14 +616,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- DataFixer datafixer = minecraftserver.getFixerUpper();
- EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver);
-
-- this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage);
-+ // Paper - rewrite chunk system
- StructureTemplateManager structuretemplatemanager = minecraftserver.getStructureManager();
- int j = this.spigotConfig.viewDistance; // Spigot
- int k = this.spigotConfig.simulationDistance; // Spigot
-- PersistentEntitySectionManager persistententitysectionmanager = this.entityManager;
+ public ServerLevel(
+ MinecraftServer server,
+@@ -376,18 +615,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ // CraftBukkit end
+ boolean flag = server.forceSynchronousWrites();
+ DataFixer fixerUpper = server.getFixerUpper();
+- EntityPersistentStorage<Entity> entityPersistentStorage = new EntityStorage(
+- new SimpleRegionStorage(
+- new RegionStorageInfo(levelStorageAccess.getLevelId(), dimension, "entities"),
+- levelStorageAccess.getDimensionPath(dimension).resolve("entities"),
+- fixerUpper,
+- flag,
+- DataFixTypes.ENTITY_CHUNK
+- ),
+- this,
+- server
+- );
+- this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entityPersistentStorage);
+ // Paper - rewrite chunk system
-
-- Objects.requireNonNull(this.entityManager);
-- this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, persistententitysectionmanager::updateChunkStatus, () -> {
-+ this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system
- return minecraftserver.overworld().getDataStorage();
- });
+ this.chunkSource = new ServerChunkCache(
+ this,
+ levelStorageAccess,
+@@ -399,7 +627,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ this.spigotConfig.simulationDistance, // Spigot
+ flag,
+ progressListener,
+- this.entityManager::updateChunkStatus,
++ null, // Paper - rewrite chunk system
+ () -> server.overworld().getDataStorage()
+ );
this.chunkSource.getGeneratorState().ensureStructuresGenerated();
-@@ -414,6 +650,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> {
- return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences");
- });
+@@ -437,6 +665,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ this.randomSequences = Objects.requireNonNullElseGet(
+ randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.factory(seed), "random_sequences")
+ );
+ // Paper start - rewrite chunk system
+ this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks()));
+ this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this);
+ this.entityDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController(
+ new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController.EntityRegionFileStorage(
-+ new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"),
-+ convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"),
-+ minecraftserver.forceSynchronousWrites()
++ new RegionStorageInfo(levelStorageAccess.getLevelId(), dimension, "entities"),
++ levelStorageAccess.getDimensionPath(dimension).resolve("entities"),
++ server.forceSynchronousWrites()
+ ),
+ this.chunkTaskScheduler
+ );
@@ -27429,22 +26937,23 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
}
-@@ -536,7 +786,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- gameprofilerfiller.push("checkDespawn");
- entity.checkDespawn();
- gameprofilerfiller.pop();
-- if (entity instanceof ServerPlayer || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) {
-+ if (true) { // Paper - rewrite chunk system
- Entity entity1 = entity.getVehicle();
-
- if (entity1 != null) {
-@@ -559,13 +809,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -560,8 +802,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ profilerFiller.push("checkDespawn");
+ entity.checkDespawn();
+ profilerFiller.pop();
+- if (entity instanceof ServerPlayer
+- || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) {
++ if (true) { // Paper - rewrite chunk system
+ Entity vehicle = entity.getVehicle();
+ if (vehicle != null) {
+ if (!vehicle.isRemoved() && vehicle.hasPassenger(entity)) {
+@@ -584,13 +825,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
- gameprofilerfiller.push("entityManagement");
+ profilerFiller.push("entityManagement");
- this.entityManager.tick();
+ // Paper - rewrite chunk system
- gameprofilerfiller.pop();
+ profilerFiller.pop();
}
@Override
@@ -27457,8 +26966,8 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
protected void tickTime() {
-@@ -605,7 +858,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- });
+@@ -621,14 +865,67 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList()).forEach(player -> player.stopSleepInBed(false, false));
}
+ // Paper start - optimise random ticking
@@ -27515,128 +27024,125 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
+ final ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom simpleRandom = this.simpleRandom; // Paper - optimise random ticking
- ChunkPos chunkcoordintpair = chunk.getPos();
- boolean flag = this.isRaining();
- int j = chunkcoordintpair.getMinBlockX();
-@@ -613,7 +919,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- ProfilerFiller gameprofilerfiller = Profiler.get();
-
- gameprofilerfiller.push("thunder");
-- if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder
-+ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && simpleRandom.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder // Paper - optimise random ticking
- BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
-
- if (this.isRainingAt(blockposition)) {
-@@ -645,7 +951,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ ChunkPos pos = chunk.getPos();
+ boolean isRaining = this.isRaining();
+ int minBlockX = pos.getMinBlockX();
+ int minBlockZ = pos.getMinBlockZ();
+ ProfilerFiller profilerFiller = Profiler.get();
+ profilerFiller.push("thunder");
+- if (!this.paperConfig().environment.disableThunder && isRaining && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder
++ if (!this.paperConfig().environment.disableThunder && isRaining && this.isThundering() && this.spigotConfig.thunderChance > 0 && simpleRandom.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - Option to disable thunder // Paper - optimise random ticking
+ BlockPos blockPos = this.findLightningTargetAround(this.getBlockRandomPos(minBlockX, 0, minBlockZ, 15));
+ if (this.isRainingAt(blockPos)) {
+ DifficultyInstance currentDifficultyAt = this.getCurrentDifficultyAt(blockPos);
+@@ -658,7 +955,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow
- for (int l = 0; l < randomTickSpeed; ++l) {
+ for (int i = 0; i < randomTickSpeed; i++) {
- if (this.random.nextInt(48) == 0) {
-+ if (simpleRandom.nextInt(48) == 0) { // Paper - optimise random ticking
- this.tickPrecipitation(this.getBlockRandomPos(j, 0, k, 15));
++ if (simpleRandom.nextInt(48) == 0) { // Paper - optimise random ticking
+ this.tickPrecipitation(this.getBlockRandomPos(minBlockX, 0, minBlockZ, 15));
}
}
-@@ -653,35 +959,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -666,33 +963,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- gameprofilerfiller.popPush("tickBlocks");
+ profilerFiller.popPush("tickBlocks");
if (randomTickSpeed > 0) {
-- LevelChunkSection[] achunksection = chunk.getSections();
--
-- for (int i1 = 0; i1 < achunksection.length; ++i1) {
-- LevelChunkSection chunksection = achunksection[i1];
--
-- if (chunksection.isRandomlyTicking()) {
-- int j1 = chunk.getSectionYFromSectionIndex(i1);
-- int k1 = SectionPos.sectionToBlockCoord(j1);
--
-- for (int l1 = 0; l1 < randomTickSpeed; ++l1) {
-- BlockPos blockposition1 = this.getBlockRandomPos(j, k1, k, 15);
--
-- gameprofilerfiller.push("randomTick");
-- BlockState iblockdata = chunksection.getBlockState(blockposition1.getX() - j, blockposition1.getY() - k1, blockposition1.getZ() - k);
--
-- if (iblockdata.isRandomlyTicking()) {
-- iblockdata.randomTick(this, blockposition1, this.random);
+- LevelChunkSection[] sections = chunk.getSections();
+-
+- for (int i1 = 0; i1 < sections.length; i1++) {
+- LevelChunkSection levelChunkSection = sections[i1];
+- if (levelChunkSection.isRandomlyTicking()) {
+- int sectionYFromSectionIndex = chunk.getSectionYFromSectionIndex(i1);
+- int blockPosCoord = SectionPos.sectionToBlockCoord(sectionYFromSectionIndex);
+-
+- for (int i2 = 0; i2 < randomTickSpeed; i2++) {
+- BlockPos blockRandomPos = this.getBlockRandomPos(minBlockX, blockPosCoord, minBlockZ, 15);
+- profilerFiller.push("randomTick");
+- BlockState blockState = levelChunkSection.getBlockState(
+- blockRandomPos.getX() - minBlockX, blockRandomPos.getY() - blockPosCoord, blockRandomPos.getZ() - minBlockZ
+- );
+- if (blockState.isRandomlyTicking()) {
+- blockState.randomTick(this, blockRandomPos, this.random);
- }
-
-- FluidState fluid = iblockdata.getFluidState();
--
-- if (fluid.isRandomlyTicking()) {
-- fluid.randomTick(this, blockposition1, this.random);
+- FluidState fluidState = blockState.getFluidState();
+- if (fluidState.isRandomlyTicking()) {
+- fluidState.randomTick(this, blockRandomPos, this.random);
- }
-
-- gameprofilerfiller.pop();
+- profilerFiller.pop();
- }
- }
- }
+ this.optimiseRandomTick(chunk, randomTickSpeed); // Paper - optimise random ticking
}
- gameprofilerfiller.pop();
-@@ -954,6 +1232,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- if (fluid1.is(fluid)) {
- fluid1.tick(this, pos, iblockdata);
+ profilerFiller.pop();
+@@ -946,6 +1217,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ if (fluidState.is(fluid)) {
+ fluidState.tick(this, pos, blockState);
}
+ // Paper start - rewrite chunk system
+ if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
+ }
+ // Paper end - rewrite chunk system
-
++
}
-@@ -963,6 +1246,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- if (iblockdata.is(block)) {
- iblockdata.tick(this, pos, this.random);
+ private void tickBlock(BlockPos pos, Block block) {
+@@ -953,6 +1230,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ if (blockState.is(block)) {
+ blockState.tick(this, pos, this.random);
}
+ // Paper start - rewrite chunk system
+ if ((++this.tickedBlocksOrFluids & 7L) != 0L) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer)this.server).moonrise$executeMidTickTasks();
+ }
+ // Paper end - rewrite chunk system
-
++
}
-@@ -1041,6 +1329,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ public void tickNonPassenger(Entity entity) {
+@@ -1007,6 +1290,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
- public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) {
+ public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
+ // Paper start - add close param
-+ this.save(progressListener, flush, savingDisabled, false);
++ this.save(progress, flush, skipSave, false);
+ }
-+ public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled, boolean close) {
++ public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave, boolean close) {
+ // Paper end - add close param
- ServerChunkCache chunkproviderserver = this.getChunkSource();
-
- if (!savingDisabled) {
-@@ -1054,14 +1347,19 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- progressListener.progressStage(Component.translatable("menu.savingChunks"));
+ ServerChunkCache chunkSource = this.getChunkSource();
+ if (!skipSave) {
+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit
+@@ -1019,13 +1307,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ progress.progressStage(Component.translatable("menu.savingChunks"));
}
-- chunkproviderserver.save(flush);
+- chunkSource.save(flush);
- if (flush) {
- this.entityManager.saveAll();
- } else {
- this.entityManager.autoSave();
-- }
-+ if (!close) { chunkproviderserver.save(flush); } // Paper - add close param
++ if (!close) { chunkSource.save(flush); } // Paper - add close param
+ // Paper - rewrite chunk system
-
- }
++ }
+ // Paper start - add close param
+ if (close) {
+ try {
-+ chunkproviderserver.close(!savingDisabled);
++ chunkSource.close(!skipSave);
+ } catch (IOException never) {
+ throw new RuntimeException(never);
-+ }
-+ }
+ }
+ }
+ // Paper end - add close param
// CraftBukkit start - moved from MinecraftServer.saveChunks
ServerLevel worldserver1 = this;
-@@ -1201,7 +1499,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED);
+@@ -1156,7 +1449,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ this.removePlayerImmediately((ServerPlayer)entity, Entity.RemovalReason.DISCARDED);
}
- this.entityManager.addNewEntity(player);
@@ -27644,7 +27150,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
// CraftBukkit start
-@@ -1232,7 +1530,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -1187,7 +1480,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
// CraftBukkit end
@@ -27653,56 +27159,52 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
}
-@@ -1243,11 +1541,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -1198,7 +1491,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
// CraftBukkit end
-- Stream<UUID> stream = entity.getSelfAndPassengers().map(Entity::getUUID); // CraftBukkit - decompile error
-- PersistentEntitySectionManager persistententitysectionmanager = this.entityManager;
--
-- Objects.requireNonNull(this.entityManager);
-- if (stream.anyMatch(persistententitysectionmanager::isLoaded)) {
+- if (entity.getSelfAndPassengers().map(Entity::getUUID).anyMatch(this.entityManager::isLoaded)) {
+ if (entity.getSelfAndPassengers().map(Entity::getUUID).anyMatch(this.moonrise$getEntityLookup()::hasEntity)) { // Paper - rewrite chunk system
return false;
} else {
this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit
-@@ -1924,7 +2218,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -1933,7 +2226,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
}
-- bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityManager.gatherStats()));
-+ bufferedwriter.write(String.format(Locale.ROOT, "entities: %s\n", this.moonrise$getEntityLookup().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_ticks: %d\n", this.getBlockTicks().count()));
- bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count()));
-@@ -1973,7 +2267,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1);
-
- try {
-- playerchunkmap.dumpChunks(bufferedwriter2);
-+ //playerchunkmap.dumpChunks(bufferedwriter2); // Paper - rewrite chunk system
- } catch (Throwable throwable4) {
- if (bufferedwriter2 != null) {
- try {
-@@ -1994,7 +2288,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2);
-
- try {
-- this.entityManager.dumpSections(bufferedwriter3);
-+ //this.entityManager.dumpSections(bufferedwriter3); // Paper - rewrite chunk system
- } catch (Throwable throwable6) {
- if (bufferedwriter3 != null) {
- try {
-@@ -2136,7 +2430,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+- bufferedWriter.write(String.format(Locale.ROOT, "entities: %s\n", this.entityManager.gatherStats()));
++ bufferedWriter.write(String.format(Locale.ROOT, "entities: %s\n", this.moonrise$getEntityLookup().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_ticks: %d\n", this.getBlockTicks().count()));
+ bufferedWriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count()));
+@@ -1951,13 +2244,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ Path path1 = path.resolve("chunks.csv");
+
+ try (Writer bufferedWriter2 = Files.newBufferedWriter(path1)) {
+- chunkMap.dumpChunks(bufferedWriter2);
++ //chunkMap.dumpChunks(bufferedWriter2); // Paper - rewrite chunk system
+ }
- @VisibleForTesting
- public String getWatchdogStats() {
-- 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.entityManager.gatherStats(), ServerLevel.getTypeCount(this.entityManager.getEntityGetter().getAll(), (entity) -> {
-+ 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.moonrise$getEntityLookup().getDebugInfo(), ServerLevel.getTypeCount(this.moonrise$getEntityLookup().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());
- }
-@@ -2166,15 +2460,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ Path path2 = path.resolve("entity_chunks.csv");
+
+ try (Writer bufferedWriter3 = Files.newBufferedWriter(path2)) {
+- this.entityManager.dumpSections(bufferedWriter3);
++ //this.entityManager.dumpSections(bufferedWriter3); // Paper - rewrite chunk system
+ }
+
+ Path path3 = path.resolve("entities.csv");
+@@ -2066,8 +2359,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ Locale.ROOT,
+ "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s",
+ this.players.size(),
+- this.entityManager.gatherStats(),
+- getTypeCount(this.entityManager.getEntityGetter().getAll(), entity -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()),
++ this.moonrise$getEntityLookup().getDebugInfo(), // Paper - rewrite chunk system
++ getTypeCount(this.moonrise$getEntityLookup().getAll(), entity -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()), // Paper - rewrite chunk system
+ this.blockEntityTickers.size(),
+ getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType),
+ this.getBlockTicks().count(),
+@@ -2099,15 +2392,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Override
public LevelEntityGetter<Entity> getEntities() {
org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
@@ -27731,7 +27233,7 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
public void startTickingChunk(LevelChunk chunk) {
-@@ -2194,34 +2498,47 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+@@ -2125,32 +2428,45 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Override
public void close() throws IOException {
super.close();
@@ -27741,10 +27243,8 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
@Override
public String gatherChunkSourceStats() {
- String s = this.chunkSource.gatherStats();
-
-- return "Chunks[S] W: " + s + " E: " + this.entityManager.gatherStats();
-+ return "Chunks[S] W: " + s + " E: " + this.moonrise$getEntityLookup().getDebugInfo(); // Paper - rewrite chunk system
+- return "Chunks[S] W: " + this.chunkSource.gatherStats() + " E: " + this.entityManager.gatherStats();
++ return "Chunks[S] W: " + this.chunkSource.gatherStats() + " E: " + this.moonrise$getEntityLookup().getDebugInfo(); // Paper - rewrite chunk system
}
public boolean areEntitiesLoaded(long chunkPos) {
@@ -27777,8 +27277,8 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
+ // Paper end - rewrite chunk system
}
- public boolean isNaturalSpawningAllowed(ChunkPos pos) {
-- return this.entityManager.canPositionTick(pos);
+ public boolean isNaturalSpawningAllowed(ChunkPos chunkPos) {
+- return this.entityManager.canPositionTick(chunkPos);
+ // Paper start - rewrite chunk system
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos));
+ return chunkHolder != null && chunkHolder.isEntityTickingReady();
@@ -27786,29 +27286,29 @@ index 6c71ef3c7430623900a7021f853d2bb514273e4d..cf692267c6376ed8484478dc90f4f905
}
@Override
-@@ -2277,7 +2594,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
- CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report);
-
- crashreportsystemdetails.setDetail("Loaded entity count", () -> {
-- return String.valueOf(this.entityManager.count());
-+ return String.valueOf(this.moonrise$getEntityLookup().getEntityCount()); // Paper - rewrite chunk system
- });
- return crashreportsystemdetails;
+@@ -2204,7 +2520,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ @Override
+ public CrashReportCategory fillReportDetails(CrashReport report) {
+ CrashReportCategory crashReportCategory = super.fillReportDetails(report);
+- crashReportCategory.setDetail("Loaded entity count", () -> String.valueOf(this.entityManager.count()));
++ crashReportCategory.setDetail("Loaded entity count", () -> String.valueOf(this.moonrise$getEntityLookup().getEntityCount())); // Paper - rewrite chunk system
+ return crashReportCategory;
}
+
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
-index f6e3073e1f1ff99f6917d84974a18e3e756fa9ea..ba873bcc183f9b3f64ba39be08cb88a95ff52b0e 100644
+index 940509d1f31aedf20b8f5b9192c34ad004875728..b455e0e0fea949bee1953324ae530c19405c5d3b 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
-@@ -217,7 +217,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
- import org.bukkit.inventory.MainHand;
- // CraftBukkit end
-
--public class ServerPlayer extends net.minecraft.world.entity.player.Player {
-+public class ServerPlayer extends net.minecraft.world.entity.player.Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
+@@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team;
+ import net.minecraft.world.scores.criteria.ObjectiveCriteria;
+ import org.slf4j.Logger;
+-public class ServerPlayer extends Player {
++public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
private static final Logger LOGGER = LogUtils.getLogger();
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
-@@ -322,6 +322,36 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
+ private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
+@@ -387,6 +387,36 @@ public class ServerPlayer extends Player {
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
@@ -27842,11 +27342,11 @@ index f6e3073e1f1ff99f6917d84974a18e3e756fa9ea..ba873bcc183f9b3f64ba39be08cb88a9
+ }
+ // Paper end - rewrite chunk system
+
- public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
- super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
- this.chatVisibility = ChatVisiblity.FULL;
+ public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) {
+ super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile);
+ this.textFilter = server.createTextFilterForPlayer(this);
diff --git a/net/minecraft/server/level/ThreadedLevelLightEngine.java b/net/minecraft/server/level/ThreadedLevelLightEngine.java
-index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157bddf99a7 100644
+index 11a264ef2f43c2b00741397c9c9ea5393afad6ab..5c9ac44a3b4bc8e047feaf61a94eb163761498a2 100644
--- a/net/minecraft/server/level/ThreadedLevelLightEngine.java
+++ b/net/minecraft/server/level/ThreadedLevelLightEngine.java
@@ -22,23 +22,134 @@ import net.minecraft.world.level.chunk.LightChunkGetter;
@@ -27981,17 +27481,17 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157
+ // Paper end - rewrite chunk system
public ThreadedLevelLightEngine(
- LightChunkGetter chunkProvider, ChunkMap chunkLoadingManager, boolean hasBlockLight, ConsecutiveExecutor processor, ChunkTaskDispatcher executor
+ LightChunkGetter lightChunkGetter, ChunkMap chunkMap, boolean skyLight, ConsecutiveExecutor consecutiveExecutor, ChunkTaskDispatcher taskDispatcher
) {
- super(chunkProvider, true, hasBlockLight);
- this.chunkMap = chunkLoadingManager;
-- this.taskDispatcher = executor;
-- this.consecutiveExecutor = processor;
-+ // Paper - rewrite chunk sytem
+ super(lightChunkGetter, true, skyLight);
+ this.chunkMap = chunkMap;
+- this.taskDispatcher = taskDispatcher;
+- this.consecutiveExecutor = consecutiveExecutor;
++ // Paper - rewrite chunk system
}
@Override
-@@ -52,164 +163,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl
+@@ -52,163 +163,73 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl
@Override
public void checkBlock(BlockPos pos) {
@@ -28010,35 +27510,35 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157
+ // Paper end - rewrite chunk system
}
- protected void updateChunkStatus(ChunkPos pos) {
-- this.addTask(pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
-- super.retainData(pos, false);
-- super.setLightEnabled(pos, false);
+ protected void updateChunkStatus(ChunkPos chunkPos) {
+- this.addTask(chunkPos.x, chunkPos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
+- super.retainData(chunkPos, false);
+- super.setLightEnabled(chunkPos, false);
-
-- for (int i = this.getMinLightSection(); i < this.getMaxLightSection(); i++) {
-- super.queueSectionData(LightLayer.BLOCK, SectionPos.of(pos, i), null);
-- super.queueSectionData(LightLayer.SKY, SectionPos.of(pos, i), null);
+- for (int lightSection = this.getMinLightSection(); lightSection < this.getMaxLightSection(); lightSection++) {
+- super.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, lightSection), null);
+- super.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, lightSection), null);
- }
-
-- for (int j = this.levelHeightAccessor.getMinSectionY(); j <= this.levelHeightAccessor.getMaxSectionY(); j++) {
-- super.updateSectionStatus(SectionPos.of(pos, j), true);
+- for (int lightSection = this.levelHeightAccessor.getMinSectionY(); lightSection <= this.levelHeightAccessor.getMaxSectionY(); lightSection++) {
+- super.updateSectionStatus(SectionPos.of(chunkPos, lightSection), true);
- }
-- }, () -> "updateChunkStatus " + pos + " true"));
+- }, () -> "updateChunkStatus " + chunkPos + " true"));
+ // Paper - rewrite chunk system
}
@Override
- public void updateSectionStatus(SectionPos pos, boolean notReady) {
+ public void updateSectionStatus(SectionPos pos, boolean isEmpty) {
- this.addTask(
- pos.x(),
- pos.z(),
- () -> 0,
- ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
-- Util.name(() -> super.updateSectionStatus(pos, notReady), () -> "updateSectionStatus " + pos + " " + notReady)
+- Util.name(() -> super.updateSectionStatus(pos, isEmpty), () -> "updateSectionStatus " + pos + " " + isEmpty)
- );
+ // Paper start - rewrite chunk system
+ this.queueTaskForSection(pos.getX(), pos.getY(), pos.getZ(), () -> {
-+ return ThreadedLevelLightEngine.this.starlight$getLightEngine().sectionChange(pos, notReady);
++ return ThreadedLevelLightEngine.this.starlight$getLightEngine().sectionChange(pos, isEmpty);
+ });
+ // Paper end - rewrite chunk system
}
@@ -28055,84 +27555,84 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157
}
@Override
- public void setLightEnabled(ChunkPos pos, boolean retainData) {
+ public void setLightEnabled(ChunkPos chunkPos, boolean lightEnabled) {
- this.addTask(
-- pos.x,
-- pos.z,
+- chunkPos.x,
+- chunkPos.z,
- ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
-- Util.name(() -> super.setLightEnabled(pos, retainData), () -> "enableLight " + pos + " " + retainData)
+- Util.name(() -> super.setLightEnabled(chunkPos, lightEnabled), () -> "enableLight " + chunkPos + " " + lightEnabled)
- );
+ // Paper start - rewrite chunk system
}
@Override
- public void queueSectionData(LightLayer lightType, SectionPos pos, @Nullable DataLayer nibbles) {
+ public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer) {
- this.addTask(
-- pos.x(),
-- pos.z(),
+- sectionPos.x(),
+- sectionPos.z(),
- () -> 0,
- ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
-- Util.name(() -> super.queueSectionData(lightType, pos, nibbles), () -> "queueData " + pos)
+- Util.name(() -> super.queueSectionData(lightLayer, sectionPos, dataLayer), () -> "queueData " + sectionPos)
- );
+ // Paper start - rewrite chunk system
}
- private void addTask(int x, int z, ThreadedLevelLightEngine.TaskType stage, Runnable task) {
-- this.addTask(x, z, this.chunkMap.getChunkQueueLevel(ChunkPos.asLong(x, z)), stage, task);
+ private void addTask(int chunkX, int chunkZ, ThreadedLevelLightEngine.TaskType type, Runnable task) {
+- this.addTask(chunkX, chunkZ, this.chunkMap.getChunkQueueLevel(ChunkPos.asLong(chunkX, chunkZ)), type, task);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- private void addTask(int x, int z, IntSupplier completedLevelSupplier, ThreadedLevelLightEngine.TaskType stage, Runnable task) {
+ private void addTask(int chunkX, int chunkZ, IntSupplier queueLevelSupplier, ThreadedLevelLightEngine.TaskType type, Runnable task) {
- this.taskDispatcher.submit(() -> {
-- this.lightTasks.add(Pair.of(stage, task));
+- this.lightTasks.add(Pair.of(type, task));
- if (this.lightTasks.size() >= 1000) {
- this.runUpdate();
- }
-- }, ChunkPos.asLong(x, z), completedLevelSupplier);
+- }, ChunkPos.asLong(chunkX, chunkZ), queueLevelSupplier);
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@Override
- public void retainData(ChunkPos pos, boolean retainData) {
+ public void retainData(ChunkPos pos, boolean retain) {
- this.addTask(
-- pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.retainData(pos, retainData), () -> "retainData " + pos)
+- pos.x, pos.z, () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.retainData(pos, retain), () -> "retainData " + pos)
- );
+ // Paper start - rewrite chunk system
}
- public CompletableFuture<ChunkAccess> initializeLight(ChunkAccess chunk, boolean bl) {
-- ChunkPos chunkPos = chunk.getPos();
-- this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
-- LevelChunkSection[] levelChunkSections = chunk.getSections();
+ public CompletableFuture<ChunkAccess> initializeLight(ChunkAccess chunk, boolean lightEnabled) {
+- ChunkPos pos = chunk.getPos();
+- this.addTask(pos.x, pos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
+- LevelChunkSection[] sections = chunk.getSections();
-
- for (int i = 0; i < chunk.getSectionsCount(); i++) {
-- LevelChunkSection levelChunkSection = levelChunkSections[i];
+- LevelChunkSection levelChunkSection = sections[i];
- if (!levelChunkSection.hasOnlyAir()) {
-- int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
-- super.updateSectionStatus(SectionPos.of(chunkPos, j), false);
+- int sectionYFromSectionIndex = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
+- super.updateSectionStatus(SectionPos.of(pos, sectionYFromSectionIndex), false);
- }
- }
-- }, () -> "initializeLight: " + chunkPos));
+- }, () -> "initializeLight: " + pos));
- return CompletableFuture.supplyAsync(() -> {
-- super.setLightEnabled(chunkPos, bl);
-- super.retainData(chunkPos, false);
+- super.setLightEnabled(pos, lightEnabled);
+- super.retainData(pos, false);
- return chunk;
-- }, task -> this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task));
+- }, task -> this.addTask(pos.x, pos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task));
+ return CompletableFuture.completedFuture(chunk); // Paper start - rewrite chunk system
}
- public CompletableFuture<ChunkAccess> lightChunk(ChunkAccess chunk, boolean excludeBlocks) {
-- ChunkPos chunkPos = chunk.getPos();
+ public CompletableFuture<ChunkAccess> lightChunk(ChunkAccess chunk, boolean isLighted) {
+- ChunkPos pos = chunk.getPos();
- chunk.setLightCorrect(false);
-- this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
-- if (!excludeBlocks) {
-- super.propagateLightSources(chunkPos);
+- this.addTask(pos.x, pos.z, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
+- if (!isLighted) {
+- super.propagateLightSources(pos);
- }
-- }, () -> "lightChunk " + chunkPos + " " + excludeBlocks));
+- }, () -> "lightChunk " + pos + " " + isLighted));
- return CompletableFuture.supplyAsync(() -> {
- chunk.setLightCorrect(true);
- return chunk;
-- }, task -> this.addTask(chunkPos.x, chunkPos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task));
+- }, task -> this.addTask(pos.x, pos.z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
@@ -28147,24 +27647,24 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157
}
private void runUpdate() {
-- int i = Math.min(this.lightTasks.size(), 1000);
+- int min = Math.min(this.lightTasks.size(), 1000);
- ObjectListIterator<Pair<ThreadedLevelLightEngine.TaskType, Runnable>> objectListIterator = this.lightTasks.iterator();
-
-- int j;
-- for (j = 0; objectListIterator.hasNext() && j < i; j++) {
+- int i;
+- for (i = 0; objectListIterator.hasNext() && i < min; i++) {
- Pair<ThreadedLevelLightEngine.TaskType, Runnable> pair = objectListIterator.next();
- if (pair.getFirst() == ThreadedLevelLightEngine.TaskType.PRE_UPDATE) {
- pair.getSecond().run();
- }
- }
-
-- objectListIterator.back(j);
+- objectListIterator.back(i);
- super.runLightUpdates();
-
-- for (int var5 = 0; objectListIterator.hasNext() && var5 < i; var5++) {
-- Pair<ThreadedLevelLightEngine.TaskType, Runnable> pair2 = objectListIterator.next();
-- if (pair2.getFirst() == ThreadedLevelLightEngine.TaskType.POST_UPDATE) {
-- pair2.getSecond().run();
+- for (int var5 = 0; objectListIterator.hasNext() && var5 < min; var5++) {
+- Pair<ThreadedLevelLightEngine.TaskType, Runnable> pair = objectListIterator.next();
+- if (pair.getFirst() == ThreadedLevelLightEngine.TaskType.POST_UPDATE) {
+- pair.getSecond().run();
- }
-
- objectListIterator.remove();
@@ -28173,14 +27673,13 @@ index 39d34f3728ae8d845d1bffc09f3ab8b64eb4d48b..3e82adf061bd0ec0100ca4d16ec9b157
}
public CompletableFuture<?> waitForPendingTasks(int x, int z) {
-- return CompletableFuture.runAsync(() -> {
-- }, callback -> this.addTask(x, z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, callback));
+- return CompletableFuture.runAsync(() -> {}, task -> this.addTask(x, z, ThreadedLevelLightEngine.TaskType.POST_UPDATE, task));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
static enum TaskType {
diff --git a/net/minecraft/server/level/Ticket.java b/net/minecraft/server/level/Ticket.java
-index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466f5512bcd 100644
+index e574f217386d677400b4c093d50261045df06d5c..ed8a3d5bd25909ee4648b1ec2ee66878198a1d8a 100644
--- a/net/minecraft/server/level/Ticket.java
+++ b/net/minecraft/server/level/Ticket.java
@@ -2,13 +2,25 @@ package net.minecraft.server.level;
@@ -28196,7 +27695,7 @@ index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466
+ // Paper start - rewrite chunk system
+ private long removeDelay;
-- protected Ticket(TicketType<T> type, int level, T argument) {
+- protected Ticket(TicketType<T> type, int ticketLevel, T key) {
+ @Override
+ public final long moonrise$getRemoveDelay() {
+ return this.removeDelay;
@@ -28206,12 +27705,12 @@ index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466
+ public final void moonrise$setRemoveDelay(final long removeDelay) {
+ this.removeDelay = removeDelay;
+ }
-+ // Paper end - rewerite chunk system
++ // Paper end - rewrite chunk system
+
-+ public Ticket(TicketType<T> type, int level, T argument) { // Paper - public
++ public Ticket(TicketType<T> type, int ticketLevel, T key) { // Paper - public
this.type = type;
- this.ticketLevel = level;
- this.key = argument;
+ this.ticketLevel = ticketLevel;
+ this.key = key;
@@ -41,7 +53,7 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
@Override
@@ -28224,22 +27723,22 @@ index eba83b085435150e5954fd5d41dda9ce1d0601ad..daf543b51d8875b374688957ae4bc466
@@ -53,11 +65,10 @@ public final class Ticket<T> implements Comparable<Ticket<?>> {
}
- protected void setCreatedTick(long tickCreated) {
-- this.createdTick = tickCreated;
+ protected void setCreatedTick(long timestamp) {
+- this.createdTick = timestamp;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- protected boolean timedOut(long currentTick) {
-- long l = this.type.timeout();
-- return l != 0L && currentTick - this.createdTick > l;
+ protected boolean timedOut(long currentTime) {
+- long timeout = this.type.timeout();
+- return timeout != 0L && currentTime - this.createdTick > timeout;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
}
diff --git a/net/minecraft/server/level/WorldGenRegion.java b/net/minecraft/server/level/WorldGenRegion.java
-index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8103b2ea6 100644
+index 4eb040006f5d41b47e5ac9df5d9f19c4315d6343..7fa41dea184b01891f45d8e404bc1cba19cf1bcf 100644
--- a/net/minecraft/server/level/WorldGenRegion.java
+++ b/net/minecraft/server/level/WorldGenRegion.java
-@@ -85,6 +85,36 @@ public class WorldGenRegion implements WorldGenLevel {
+@@ -78,6 +78,36 @@ public class WorldGenRegion implements WorldGenLevel {
private final AtomicLong subTickCount = new AtomicLong();
private static final ResourceLocation WORLDGEN_REGION_RANDOM = ResourceLocation.withDefaultNamespace("worldgen_region_random");
@@ -28273,33 +27772,33 @@ index b7d29389a357f142237cecd75f8ca91cf1eb6b5b..e4b0dc3121101d54394a0c3a413dabf8
+ }
+ // Paper end - rewrite chunk system
+
- public WorldGenRegion(ServerLevel world, StaticCache2D<GenerationChunkHolder> chunks, ChunkStep generationStep, ChunkAccess centerPos) {
- this.generatingStep = generationStep;
- this.cache = chunks;
+ public WorldGenRegion(ServerLevel level, StaticCache2D<GenerationChunkHolder> cache, ChunkStep generatingStep, ChunkAccess center) {
+ this.generatingStep = generatingStep;
+ this.cache = cache;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
-index c68040a59fa8aa9b8b9f1e0b4fdded565ea592d9..7913c41aac1f9dd53a2b49da2a17fd894bcb6b3a 100644
+index d227714de0fe13544779fae6cf0e9ff6af5469c7..4722230e74e0778ebdb2cfd383764b34004e9568 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
-@@ -1426,7 +1426,7 @@ public abstract class PlayerList {
+@@ -1318,7 +1318,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance;
- this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance));
+ //this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(viewDistance)); // Paper - rewrite chunk system
- Iterator iterator = this.server.getAllLevels().iterator();
- while (iterator.hasNext()) {
-@@ -1441,7 +1441,7 @@ public abstract class PlayerList {
+ for (ServerLevel serverLevel : this.server.getAllLevels()) {
+ if (serverLevel != null) {
+@@ -1329,7 +1329,7 @@ public abstract class PlayerList {
public void setSimulationDistance(int simulationDistance) {
this.simulationDistance = simulationDistance;
- this.broadcastAll(new ClientboundSetSimulationDistancePacket(simulationDistance));
-+ //this.broadcastAll(new ClientboundSetSimulationDistancePacket(simulationDistance)); // Paper - rewrite chunk system
- Iterator iterator = this.server.getAllLevels().iterator();
++ //this.broadcastAll(new ClientboundSetSimulationDistancePacket(simulationDistance)); // Paper - rewrite chunk system
- while (iterator.hasNext()) {
+ for (ServerLevel serverLevel : this.server.getAllLevels()) {
+ if (serverLevel != null) {
diff --git a/net/minecraft/util/BitStorage.java b/net/minecraft/util/BitStorage.java
-index 68648c5a5e3ff079f832092af0f2f801c42d1ede..e4e153cb8899e70273aa150b8ea26907cf68b15c 100644
+index 32fe9b22e1d3a422dd80c64d61156dbc7241ba20..02502d50f0255f5bbcc0ecb965abb48cc1a112da 100644
--- a/net/minecraft/util/BitStorage.java
+++ b/net/minecraft/util/BitStorage.java
@@ -2,7 +2,7 @@ package net.minecraft.util;
@@ -28312,7 +27811,7 @@ index 68648c5a5e3ff079f832092af0f2f801c42d1ede..e4e153cb8899e70273aa150b8ea26907
void set(int index, int value);
@@ -20,4 +20,22 @@ public interface BitStorage {
- void unpack(int[] out);
+ void unpack(int[] array);
BitStorage copy();
+
@@ -28335,7 +27834,7 @@ index 68648c5a5e3ff079f832092af0f2f801c42d1ede..e4e153cb8899e70273aa150b8ea26907
+ // Paper end - block counting
}
diff --git a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
-index 61dee55417bc802e25b9ba2f271d32d8c12844a9..a8a260a3caaa8e5004069b833ecc8b17b2fc8db5 100644
+index 4a7c83c56dfbff59af71c3cd2fa4205c9a22bdc7..f28fbf81a417a678726d3f77b3999054676d522e 100644
--- a/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
+++ b/net/minecraft/util/CrudeIncrementalIntIdentityHashBiMap.java
@@ -7,7 +7,7 @@ import java.util.Iterator;
@@ -28376,9 +27875,9 @@ index 61dee55417bc802e25b9ba2f271d32d8c12844a9..a8a260a3caaa8e5004069b833ecc8b17
+ // Paper end - optimise palette reads
}
- public void addMapping(K value, int id) {
+ public void addMapping(K object, int intKey) {
diff --git a/net/minecraft/util/SimpleBitStorage.java b/net/minecraft/util/SimpleBitStorage.java
-index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a6428b20c38 100644
+index 6fb3a3f167d8cbaa78135af0c180b592661e2c1d..e6306a68c8652d4c5d22d5ecb1416f5f931f76ee 100644
--- a/net/minecraft/util/SimpleBitStorage.java
+++ b/net/minecraft/util/SimpleBitStorage.java
@@ -208,6 +208,20 @@ public class SimpleBitStorage implements BitStorage {
@@ -28399,12 +27898,12 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
+ private final int mulBits;
+ // Paper end - optimise bitstorage read/write operations
+
- public SimpleBitStorage(int elementBits, int size, int[] data) {
- this(elementBits, size);
+ public SimpleBitStorage(int bits, int size, int[] data) {
+ this(bits, size);
int i = 0;
@@ -261,6 +275,13 @@ public class SimpleBitStorage implements BitStorage {
} else {
- this.data = new long[j];
+ this.data = new long[i1];
}
+ // Paper start - optimise bitstorage read/write operations
+ this.magic = BETTER_MAGIC[this.bits];
@@ -28416,16 +27915,16 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
}
private int cellIndex(int index) {
-@@ -273,31 +294,54 @@ public class SimpleBitStorage implements BitStorage {
+@@ -269,28 +290,51 @@ public class SimpleBitStorage implements BitStorage {
+
+ @Override
public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
-- int j = (index - i * this.valuesPerLong) * this.bits;
-- int k = (int)(l >> j & this.mask);
-- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j;
-- return k;
+- int i1 = (index - i * this.valuesPerLong) * this.bits;
+- int i2 = (int)(l >> i1 & this.mask);
+- this.data[i] = l & ~(this.mask << i1) | (value & this.mask) << i1;
+- return i2;
+ // Paper start - optimise bitstorage read/write operations
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
@@ -28446,12 +27945,10 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
@Override
public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
-- int j = (index - i * this.valuesPerLong) * this.bits;
-- this.data[i] = l & ~(this.mask << j) | ((long)value & this.mask) << j;
+- int i1 = (index - i * this.valuesPerLong) * this.bits;
+- this.data[i] = l & ~(this.mask << i1) | (value & this.mask) << i1;
+ // Paper start - optimise bitstorage read/write operations
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
@@ -28470,11 +27967,10 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
@Override
public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage
- //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage
- int i = this.cellIndex(index);
- long l = this.data[i];
-- int j = (index - i * this.valuesPerLong) * this.bits;
-- return (int)(l >> j & this.mask);
+- int i1 = (index - i * this.valuesPerLong) * this.bits;
+- return (int)(l >> i1 & this.mask);
+ // Paper start - optimise bitstorage read/write operations
+ final int full = this.magic * index; // 20 bits of magic + 12 bits of index = barely int
+ final int divQ = full >>> 20;
@@ -28485,7 +27981,7 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
}
@Override
-@@ -362,6 +406,67 @@ public class SimpleBitStorage implements BitStorage {
+@@ -355,6 +399,67 @@ public class SimpleBitStorage implements BitStorage {
return new SimpleBitStorage(this.bits, this.size, (long[])this.data.clone());
}
@@ -28554,7 +28050,7 @@ index 9f438d9c6eb05e43d24e4af68188a3d4c46a938c..d99ec470b4653beab630999a5b2c1a64
InitializationException(String message) {
super(message);
diff --git a/net/minecraft/util/SortedArraySet.java b/net/minecraft/util/SortedArraySet.java
-index ea72dcb064a35bc6245bc5c94d592efedd8faf41..87ee8e51dfa7657ed7d83fcbceef48bf857043e1 100644
+index 2c6b35b86eed9002016b8228c3195f8033d219ca..339b19e88567be382e550ed54477fabd58d51faa 100644
--- a/net/minecraft/util/SortedArraySet.java
+++ b/net/minecraft/util/SortedArraySet.java
@@ -8,12 +8,89 @@ import java.util.Iterator;
@@ -28649,7 +28145,7 @@ index ea72dcb064a35bc6245bc5c94d592efedd8faf41..87ee8e51dfa7657ed7d83fcbceef48bf
this.comparator = comparator;
if (initialCapacity < 0) {
diff --git a/net/minecraft/util/ZeroBitStorage.java b/net/minecraft/util/ZeroBitStorage.java
-index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7eb80334e 100644
+index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b89651948ed8 100644
--- a/net/minecraft/util/ZeroBitStorage.java
+++ b/net/minecraft/util/ZeroBitStorage.java
@@ -62,4 +62,22 @@ public class ZeroBitStorage implements BitStorage {
@@ -28676,19 +28172,19 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..1f9c436a632e4f110be61cf76fcfc3b7
+ // Paper end - block counting
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
-index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3b5d9b6ce 100644
+index 5a67aa9f1fe103e5622ed6fa93bc4bc25ddbb688..77d2c86c8bb20e96e0eed32c430ef0c1d122428b 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
-@@ -176,7 +176,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
- import org.bukkit.plugin.PluginManager;
- // CraftBukkit end
+@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
+ import net.minecraft.world.scores.Team;
+ import org.slf4j.Logger;
-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder {
+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
-@@ -187,7 +187,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -146,7 +146,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper start - Share random for entities to make them more random
public static RandomSource SHARED_RANDOM = new RandomRandomSource();
@@ -28707,7 +28203,7 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
private boolean locked = false;
@Override
-@@ -200,61 +210,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -159,61 +169,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
}
@@ -28770,7 +28266,7 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
}
// Paper end - Share random for entities to make them more random
public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
-@@ -462,6 +418,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -425,6 +381,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.dimensions.makeBoundingBox(x, y, z);
}
// Paper end
@@ -28925,26 +28421,24 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ }
+ // Paper end - optimise entity tracker
- public Entity(EntityType<?> type, Level world) {
- this.id = Entity.ENTITY_COUNTER.incrementAndGet();
-@@ -1387,41 +1493,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ public Entity(EntityType<?> entityType, Level level) {
+ this.type = entityType;
+@@ -1286,34 +1392,76 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
- private Vec3 collide(Vec3 movement) {
-- AABB axisalignedbb = this.getBoundingBox();
-- List<VoxelShape> list = this.level().getEntityCollisions(this, axisalignedbb.expandTowards(movement));
-- Vec3 vec3d1 = movement.lengthSqr() == 0.0D ? movement : Entity.collideBoundingBox(this, movement, axisalignedbb, this.level(), list);
-- boolean flag = movement.x != vec3d1.x;
-- boolean flag1 = movement.y != vec3d1.y;
-- boolean flag2 = movement.z != vec3d1.z;
-- boolean flag3 = flag1 && movement.y < 0.0D;
--
+ private Vec3 collide(Vec3 vec) {
+- AABB boundingBox = this.getBoundingBox();
+- List<VoxelShape> entityCollisions = this.level().getEntityCollisions(this, boundingBox.expandTowards(vec));
+- Vec3 vec3 = vec.lengthSqr() == 0.0 ? vec : collideBoundingBox(this, vec, boundingBox, this.level(), entityCollisions);
+- boolean flag = vec.x != vec3.x;
+- boolean flag1 = vec.y != vec3.y;
+- boolean flag2 = vec.z != vec3.z;
+- boolean flag3 = flag1 && vec.y < 0.0;
- if (this.maxUpStep() > 0.0F && (flag3 || this.onGround()) && (flag || flag2)) {
-- AABB axisalignedbb1 = flag3 ? axisalignedbb.move(0.0D, vec3d1.y, 0.0D) : axisalignedbb;
-- AABB axisalignedbb2 = axisalignedbb1.expandTowards(movement.x, (double) this.maxUpStep(), movement.z);
--
+- AABB aabb = flag3 ? boundingBox.move(0.0, vec3.y, 0.0) : boundingBox;
+- AABB aabb1 = aabb.expandTowards(vec.x, this.maxUpStep(), vec.z);
- if (!flag3) {
-- axisalignedbb2 = axisalignedbb2.expandTowards(0.0D, -9.999999747378752E-6D, 0.0D);
+- aabb1 = aabb1.expandTowards(0.0, -1.0E-5F, 0.0);
- }
+ // Paper start - optimise collisions
+ final boolean xZero = movement.x == 0.0;
@@ -28953,17 +28447,21 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ if (xZero & yZero & zZero) {
+ return movement;
+ }
-+
+
+- List<VoxelShape> list = collectColliders(this, this.level, entityCollisions, aabb1);
+- float f = (float)vec3.y;
+- float[] floats = collectCandidateStepUpHeights(aabb, list, this.maxUpStep(), f);
+ final AABB currentBox = this.getBoundingBox();
-+
+
+- for (float f1 : floats) {
+- Vec3 vec31 = collideWithShapes(new Vec3(vec.x, f1, vec.z), aabb, list);
+- if (vec31.horizontalDistanceSqr() > vec3.horizontalDistanceSqr()) {
+- double d = boundingBox.minY - aabb.minY;
+- return vec31.add(0.0, -d, 0.0);
+- }
+ final List<VoxelShape> potentialCollisionsVoxel = new ArrayList<>();
+ final List<AABB> potentialCollisionsBB = new ArrayList<>();
-
-- List<VoxelShape> list1 = Entity.collectColliders(this, this.level, list, axisalignedbb2);
-- float f = (float) vec3d1.y;
-- float[] afloat = Entity.collectCandidateStepUpHeights(axisalignedbb1, list1, this.maxUpStep(), f);
-- float[] afloat1 = afloat;
-- int i = afloat.length;
++
+ final AABB initialCollisionBox;
+ if (xZero & zZero) {
+ // note: xZero & zZero -> collision on x/z == 0 -> no step height calculation
@@ -28973,26 +28471,19 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ } else {
+ initialCollisionBox = currentBox.expandTowards(movement);
+ }
-
-- for (int j = 0; j < i; ++j) {
-- float f1 = afloat1[j];
-- Vec3 vec3d2 = Entity.collideWithShapes(new Vec3(movement.x, (double) f1, movement.z), axisalignedbb1, list1);
++
+ final List<AABB> entityAABBs = new ArrayList<>();
+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions(
+ this.level, (Entity)(Object)this, initialCollisionBox, entityAABBs, 0, null
+ );
-
-- if (vec3d2.horizontalDistanceSqr() > vec3d1.horizontalDistanceSqr()) {
-- double d0 = axisalignedbb.minY - axisalignedbb1.minY;
++
+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder(
+ this.level, (Entity)(Object)this, initialCollisionBox, potentialCollisionsVoxel, potentialCollisionsBB,
+ ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER, null
+ );
+ potentialCollisionsBB.addAll(entityAABBs);
+ final Vec3 collided = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currentBox, potentialCollisionsVoxel, potentialCollisionsBB);
-
-- return vec3d2.add(0.0D, -d0, 0.0D);
-- }
++
+ final boolean collidedX = collided.x != movement.x;
+ final boolean collidedY = collided.y != movement.y;
+ final boolean collidedZ = collided.z != movement.z;
@@ -29026,13 +28517,13 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
}
}
-- return vec3d1;
+- return vec3;
+ return collided;
+ // Paper end - optimise collisions
}
- private static float[] collectCandidateStepUpHeights(AABB collisionBox, List<VoxelShape> collisions, float f, float stepHeight) {
-@@ -2821,18 +2962,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
+@@ -2622,23 +2770,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public boolean isInWall() {
@@ -29041,20 +28532,25 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
return false;
- } else {
- float f = this.dimensions.width() * 0.8F;
-- AABB axisalignedbb = AABB.ofSize(this.getEyePosition(), (double) f, 1.0E-6D, (double) f);
+- AABB aabb = AABB.ofSize(this.getEyePosition(), f, 1.0E-6, f);
+- return BlockPos.betweenClosedStream(aabb)
+- .anyMatch(
+- pos -> {
+- BlockState blockState = this.level().getBlockState(pos);
+- return !blockState.isAir()
+- && blockState.isSuffocating(this.level(), pos)
+- && Shapes.joinIsNotEmpty(
+- blockState.getCollisionShape(this.level(), pos).move(pos.getX(), pos.getY(), pos.getZ()), Shapes.create(aabb), BooleanOp.AND
+- );
+ }
-
-- return BlockPos.betweenClosedStream(axisalignedbb).anyMatch((blockposition) -> {
-- BlockState iblockdata = this.level().getBlockState(blockposition);
++
+ final double reducedWith = (double)(this.dimensions.width() * 0.8F);
+ final AABB boundingBox = AABB.ofSize(this.getEyePosition(), reducedWith, 1.0E-6D, reducedWith);
+ final Level world = this.level;
-
-- return !iblockdata.isAir() && iblockdata.isSuffocating(this.level(), blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level(), blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND);
-- });
++
+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) {
+ return false;
- }
++ }
+
+ final int minBlockX = Mth.floor(boundingBox.minX);
+ final int minBlockY = Mth.floor(boundingBox.minY);
@@ -29084,7 +28580,8 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ final int sectionIdx = currChunkY - minSection;
+ if (sectionIdx < 0 || sectionIdx >= sections.length) {
+ continue;
-+ }
+ }
+- );
+ final net.minecraft.world.level.chunk.LevelChunkSection section = sections[sectionIdx];
+ if (section.hasOnlyAir()) {
+ // empty
@@ -29143,14 +28640,14 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ }
+ }
+ }
-+ }
+ }
+
+ return false;
+ // Paper end - optimise collisions
}
public InteractionResult interact(Player player, InteractionHand hand) {
-@@ -4310,14 +4543,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -4063,15 +4298,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public Iterable<Entity> getIndirectPassengers() {
@@ -29167,55 +28664,53 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ return ret;
}
- return indirectPassengers.build();
+- // Paper end - Optimize indirect passenger iteration
+
+ collectIndirectPassengers(ret, this.passengers);
+
+ return ret;
+ // Paper end - optimise entity tracker
}
- private Iterable<Entity> getIndirectPassengers_old() {
- // Paper end - Optimize indirect passenger iteration
-@@ -4475,82 +4711,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- return Mth.lerp(delta, this.yRotO, this.yRot);
+
+ public int countPlayerPassengers() {
+@@ -4209,77 +4446,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ return Mth.lerp(partialTick, this.yRotO, this.yRot);
}
-- public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tag, double speed) {
+- public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> fluidTag, double motionScale) {
+ // Paper start - optimise collisions
+ public boolean updateFluidHeightAndDoFluidPushing(final TagKey<Fluid> fluid, final double flowScale) {
if (this.touchingUnloadedChunk()) {
return false;
- } else {
-- AABB axisalignedbb = this.getBoundingBox().deflate(0.001D);
-- int i = Mth.floor(axisalignedbb.minX);
-- int j = Mth.ceil(axisalignedbb.maxX);
-- int k = Mth.floor(axisalignedbb.minY);
-- int l = Mth.ceil(axisalignedbb.maxY);
-- int i1 = Mth.floor(axisalignedbb.minZ);
-- int j1 = Mth.ceil(axisalignedbb.maxZ);
-- double d1 = 0.0D;
-- boolean flag = this.isPushedByFluid();
-- boolean flag1 = false;
-- Vec3 vec3d = Vec3.ZERO;
-- int k1 = 0;
-- BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
--
-- for (int l1 = i; l1 < j; ++l1) {
-- for (int i2 = k; i2 < l; ++i2) {
-- for (int j2 = i1; j2 < j1; ++j2) {
-- blockposition_mutableblockposition.set(l1, i2, j2);
-- FluidState fluid = this.level().getFluidState(blockposition_mutableblockposition);
--
-- if (fluid.is(tag)) {
-- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition));
--
-- if (d2 >= axisalignedbb.minY) {
-- flag1 = true;
-- d1 = Math.max(d2 - axisalignedbb.minY, d1);
-- if (flag) {
-- Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition);
--
-- if (d1 < 0.4D) {
-- vec3d1 = vec3d1.scale(d1);
+- AABB aabb = this.getBoundingBox().deflate(0.001);
+- int floor = Mth.floor(aabb.minX);
+- int ceil = Mth.ceil(aabb.maxX);
+- int floor1 = Mth.floor(aabb.minY);
+- int ceil1 = Mth.ceil(aabb.maxY);
+- int floor2 = Mth.floor(aabb.minZ);
+- int ceil2 = Mth.ceil(aabb.maxZ);
+- double d = 0.0;
+- boolean isPushedByFluid = this.isPushedByFluid();
+- boolean flag = false;
+- Vec3 vec3 = Vec3.ZERO;
+- int i = 0;
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
+-
+- for (int i1 = floor; i1 < ceil; i1++) {
+- for (int i2 = floor1; i2 < ceil1; i2++) {
+- for (int i3 = floor2; i3 < ceil2; i3++) {
+- mutableBlockPos.set(i1, i2, i3);
+- FluidState fluidState = this.level().getFluidState(mutableBlockPos);
+- if (fluidState.is(fluidTag)) {
+- double d1 = i2 + fluidState.getHeight(this.level(), mutableBlockPos);
+- if (d1 >= aabb.minY) {
+- flag = true;
+- d = Math.max(d1 - aabb.minY, d);
+- if (isPushedByFluid) {
+- Vec3 flow = fluidState.getFlow(this.level(), mutableBlockPos);
+- if (d < 0.4) {
+- flow = flow.scale(d);
- }
+ }
+
@@ -29277,8 +28772,8 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ final int minYIterate = currChunkY == minChunkY ? (minBlockY & 15) : 0;
+ final int maxYIterate = currChunkY == maxChunkY ? (maxBlockY & 15) : 15;
-- vec3d = vec3d.add(vec3d1);
-- ++k1;
+- vec3 = vec3.add(flow);
+- i++;
+ for (int currY = minYIterate; currY <= maxYIterate; ++currY) {
+ for (int currZ = minZIterate; currZ <= maxZIterate; ++currZ) {
+ for (int currX = minXIterate; currX <= maxXIterate; ++currX) {
@@ -29288,8 +28783,8 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
+ continue;
}
- // CraftBukkit start - store last lava contact location
-- if (tag == FluidTags.LAVA) {
-- this.lastLavaContact = blockposition_mutableblockposition.immutable();
+- if (fluidTag == FluidTags.LAVA) {
+- this.lastLavaContact = mutableBlockPos.immutable();
+
+ mutablePos.set(currX | (currChunkX << 4), currY | (currChunkY << 4), currZ | (currChunkZ << 4));
+
@@ -29324,53 +28819,52 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
}
+ }
-- if (vec3d.length() > 0.0D) {
-- if (k1 > 0) {
-- vec3d = vec3d.scale(1.0D / (double) k1);
+- if (vec3.length() > 0.0) {
+- if (i > 0) {
+- vec3 = vec3.scale(1.0 / i);
- }
+ this.fluidHeight.put(fluid, maxHeightDiff);
- if (!(this instanceof Player)) {
-- vec3d = vec3d.normalize();
+- vec3 = vec3.normalize();
- }
+ if (pushVector.lengthSqr() == 0.0) {
+ return inFluid;
+ }
-- Vec3 vec3d2 = this.getDeltaMovement();
+- Vec3 deltaMovement = this.getDeltaMovement();
+- vec3 = vec3.scale(motionScale);
+- double d2 = 0.003;
+- if (Math.abs(deltaMovement.x) < 0.003 && Math.abs(deltaMovement.z) < 0.003 && vec3.length() < 0.0045000000000000005) {
+- vec3 = vec3.normalize().scale(0.0045000000000000005);
+- }
+ // note: totalPushes != 0 as pushVector != 0
+ pushVector = pushVector.scale(1.0 / totalPushes);
+ final Vec3 currMovement = this.getDeltaMovement();
-- vec3d = vec3d.scale(speed);
-- double d3 = 0.003D;
+- this.setDeltaMovement(this.getDeltaMovement().add(vec3));
+- }
+ if (!((Entity)(Object)this instanceof Player)) {
+ pushVector = pushVector.normalize();
+ }
-- if (Math.abs(vec3d2.x) < 0.003D && Math.abs(vec3d2.z) < 0.003D && vec3d.length() < 0.0045000000000000005D) {
-- vec3d = vec3d.normalize().scale(0.0045000000000000005D);
-- }
+- this.fluidHeight.put(fluidTag, d);
+- return flag;
+ pushVector = pushVector.scale(flowScale);
+ if (Math.abs(currMovement.x) < 0.003 && Math.abs(currMovement.z) < 0.003 && pushVector.length() < 0.0045000000000000005) {
+ pushVector = pushVector.normalize().scale(0.0045000000000000005);
-+ }
-
-- this.setDeltaMovement(this.getDeltaMovement().add(vec3d));
-- }
+ }
++
+ this.setDeltaMovement(currMovement.add(pushVector));
-
-- this.fluidHeight.put(tag, d1);
-- return flag1;
-- }
++
+ // note: inFluid = true here as pushVector != 0
+ return true;
}
+ // Paper end - optimise collisions
public boolean touchingUnloadedChunk() {
- AABB axisalignedbb = this.getBoundingBox().inflate(1.0D);
-@@ -4702,6 +4992,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ AABB aabb = this.getBoundingBox().inflate(1.0);
+@@ -4430,6 +4726,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.setPosRaw(x, y, z, false);
}
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
@@ -29386,39 +28880,39 @@ index 766031d1482b0f49b196326b820d5ce9ae1c7c06..1f54752a4ea0788e73279cd99c7c35e3
if (!checkPosition(this, x, y, z)) {
return;
}
-@@ -4831,6 +5130,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -4558,6 +4863,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@Override
- public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) {
+ public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
+ // Paper start - rewrite chunk system
+ if (!((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this.level).moonrise$getEntityLookup().canRemoveEntity((Entity)(Object)this)) {
+ LOGGER.warn("Entity " + this + " is currently prevented from being removed from the world since it is processing section status updates", new Throwable());
+ return;
+ }
+ // Paper end - rewrite chunk system
- CraftEventFactory.callEntityRemoveEvent(this, cause);
+ org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause);
// CraftBukkit end
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
-@@ -4842,7 +5147,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -4569,7 +4880,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.stopRiding();
}
- this.getPassengers().forEach(Entity::stopRiding);
+ if (this.removalReason != Entity.RemovalReason.UNLOADED_TO_CHUNK) { this.getPassengers().forEach(Entity::stopRiding); } // Paper - rewrite chunk system
- this.levelCallback.onRemove(entity_removalreason);
- this.onRemoval(entity_removalreason);
+ this.levelCallback.onRemove(removalReason);
+ this.onRemoval(removalReason);
// Paper start - Folia schedulers
-@@ -4874,7 +5179,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
-
- @Override
+@@ -4603,7 +4914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public boolean shouldBeSaved() {
-- return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasExactlyOnePlayerPassenger());
-+ return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this).moonrise$hasAnyPlayerPassengers()); // Paper - rewrite chunk system
+ return (this.removalReason == null || this.removalReason.shouldSave())
+ && !this.isPassenger()
+- && (!this.isVehicle() || !this.hasExactlyOnePlayerPassenger());
++ && (!this.isVehicle() || !((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this).moonrise$hasAnyPlayerPassengers()); // Paper - rewrite chunk system
}
@Override
diff --git a/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/net/minecraft/world/entity/ai/village/poi/PoiManager.java
-index 96bc0ba60195e5e666d47b3a0b943b733986d96a..5930a430983061afddf20e3208ff2462ca1b78cd 100644
+index 7d590dd06cc69c0925d22708425520c38e3cda25..c8590e0175dacd6d7efdb1830bd60c92325083f9 100644
--- a/net/minecraft/world/entity/ai/village/poi/PoiManager.java
+++ b/net/minecraft/world/entity/ai/village/poi/PoiManager.java
@@ -38,12 +38,137 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
@@ -29558,10 +29052,10 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..5930a430983061afddf20e3208ff2462
+ // Paper end - rewrite chunk system
+
public PoiManager(
- RegionStorageInfo storageKey,
- Path directory,
+ RegionStorageInfo info,
+ Path folder,
@@ -64,6 +189,7 @@ public class PoiManager extends SectionStorage<PoiSection, PoiSection.Packed> {
- world
+ levelHeightAccessor
);
this.distanceTracker = new PoiManager.DistanceTracker();
+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper - rewrite chunk system
@@ -29571,30 +29065,29 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..5930a430983061afddf20e3208ff2462
@@ -197,8 +323,10 @@ public class PoiManager extends SectionStorage<PoiSection, PoiSection.Packed> {
}
- public int sectionsToVillage(SectionPos pos) {
+ public int sectionsToVillage(SectionPos sectionPos) {
- this.distanceTracker.runAllUpdates();
-- return this.distanceTracker.getLevel(pos.asLong());
+- return this.distanceTracker.getLevel(sectionPos.asLong());
+ // Paper start - rewrite chunk system
+ this.villageDistanceTracker.propagateUpdates();
-+ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(pos)));
++ return convertBetweenLevels(this.villageDistanceTracker.getLevel(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionKey(sectionPos)));
+ // Paper end - rewrite chunk system
}
- boolean isVillageCenter(long pos) {
+ boolean isVillageCenter(long chunkPos) {
@@ -212,19 +340,26 @@ public class PoiManager extends SectionStorage<PoiSection, PoiSection.Packed> {
@Override
- public void tick(BooleanSupplier shouldKeepTicking) {
-- super.tick(shouldKeepTicking);
+ public void tick(BooleanSupplier aheadOfTime) {
+- super.tick(aheadOfTime);
- this.distanceTracker.runAllUpdates();
+ this.villageDistanceTracker.propagateUpdates(); // Paper - rewrite chunk system
}
@Override
-- protected void setDirty(long pos) {
-- super.setDirty(pos);
-- this.distanceTracker.update(pos, this.distanceTracker.getLevelFromSource(pos), false);
-+ public void setDirty(long pos) { // Paper - public
+ protected void setDirty(long sectionPos) {
+- super.setDirty(sectionPos);
+- this.distanceTracker.update(sectionPos, this.distanceTracker.getLevelFromSource(sectionPos), false);
+ // Paper start - rewrite chunk system
+ final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionX(pos);
+ final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionZ(pos);
@@ -29608,23 +29101,23 @@ index 96bc0ba60195e5e666d47b3a0b943b733986d96a..5930a430983061afddf20e3208ff2462
}
@Override
- protected void onSectionLoad(long pos) {
-- this.distanceTracker.update(pos, this.distanceTracker.getLevelFromSource(pos), false);
-+ this.updateDistanceTracking(pos); // Paper - rewrite chunk system
+ protected void onSectionLoad(long sectionKey) {
+- this.distanceTracker.update(sectionKey, this.distanceTracker.getLevelFromSource(sectionKey), false);
++ this.updateDistanceTracking(sectionKey); // Paper - rewrite chunk system
}
- public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection chunkSection) {
+ public void checkConsistencyWithBlocks(SectionPos sectionPos, LevelChunkSection levelChunkSection) {
@@ -263,7 +398,7 @@ public class PoiManager extends SectionStorage<PoiSection, PoiSection.Packed> {
.map(sectionPos -> Pair.of(sectionPos, this.getOrLoad(sectionPos.asLong())))
.filter(pair -> !pair.getSecond().map(PoiSection::isValid).orElse(false))
.map(pair -> pair.getFirst().chunk())
- .filter(chunkPos -> this.loadedChunks.add(chunkPos.toLong()))
+ // Paper - rewrite chunk system
- .forEach(chunkPos -> world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.EMPTY));
+ .forEach(chunkPos -> levelReader.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.EMPTY));
}
diff --git a/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/net/minecraft/world/entity/ai/village/poi/PoiSection.java
-index b9e0bc8f1e948614d986335de1f3d2df199eea81..712cbfc100e8aaf612d1d651dae64f57f892a768 100644
+index 324cc0686f0f5b1371b2bbea5b8c8fdb1f363006..39cd1e3d8192d7077d6b7864d33933097cc6b986 100644
--- a/net/minecraft/world/entity/ai/village/poi/PoiSection.java
+++ b/net/minecraft/world/entity/ai/village/poi/PoiSection.java
@@ -23,13 +23,27 @@ import net.minecraft.core.SectionPos;
@@ -29653,27 +29146,27 @@ index b9e0bc8f1e948614d986335de1f3d2df199eea81..712cbfc100e8aaf612d1d651dae64f57
+ }
+ // Paper end - rewrite chunk system
+
- public PoiSection(Runnable updateListener) {
- this(updateListener, true, ImmutableList.of());
+ public PoiSection(Runnable setDirty) {
+ this(setDirty, true, ImmutableList.of());
}
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
-index 63f02cdc67d9e88cc6998d0ae9d139c83e85b447..70b8023c3badc745f342d5b0ab54699e3923826a 100644
+index 613675c86787dd1147e140f1ef4d17b09ab9a74b..5cc19a67c7a29f1bda8cdd6921201f47fe6bf91f 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
-@@ -364,7 +364,7 @@ public class ArmorStand extends LivingEntity {
+@@ -316,7 +316,7 @@ public class ArmorStand extends LivingEntity {
@Override
protected void pushEntities() {
if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper - Option to prevent armor stands from doing entity lookups
-- List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
-+ List<AbstractMinecart> list = this.level().getEntitiesOfClass(AbstractMinecart.class, this.getBoundingBox(), RIDABLE_MINECARTS); // Paper - optimise collisions
- Iterator iterator = list.iterator();
-
- while (iterator.hasNext()) {
+- for (Entity entity : this.level().getEntities(this, this.getBoundingBox(), RIDABLE_MINECARTS)) {
++ for (Entity entity : this.level().getEntitiesOfClass(AbstractMinecart.class, this.getBoundingBox(), RIDABLE_MINECARTS)) { // Paper - optimise collisions
+ if (this.distanceToSqr(entity) <= 0.2) {
+ entity.push(this);
+ }
diff --git a/net/minecraft/world/level/ClipContext.java b/net/minecraft/world/level/ClipContext.java
-index 3fa2964b979053ecbefc946c7fe76828de86d8f1..28bf0518f7d17099d7e4990defbeda6757b4477c 100644
+index 9f34fc4278860dd7bcfa1fd79b15e588b0cc3973..a7ebd624652cb6f0edc735bf6b9760e7b443594f 100644
--- a/net/minecraft/world/level/ClipContext.java
+++ b/net/minecraft/world/level/ClipContext.java
-@@ -18,7 +18,7 @@ public class ClipContext {
+@@ -17,7 +17,7 @@ public class ClipContext {
private final Vec3 from;
private final Vec3 to;
private final ClipContext.Block block;
@@ -29681,9 +29174,9 @@ index 3fa2964b979053ecbefc946c7fe76828de86d8f1..28bf0518f7d17099d7e4990defbeda67
+ public final ClipContext.Fluid fluid; // Paper - optimise collisions - public
private final CollisionContext collisionContext;
- public ClipContext(Vec3 start, Vec3 end, ClipContext.Block shapeType, ClipContext.Fluid fluidHandling, Entity entity) {
+ public ClipContext(Vec3 from, Vec3 to, ClipContext.Block block, ClipContext.Fluid fluid, Entity entity) {
diff --git a/net/minecraft/world/level/EntityGetter.java b/net/minecraft/world/level/EntityGetter.java
-index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b150013e940ee6 100644
+index 300f3ed58109219d97846082941b860585f66fed..e81195df621159da67136f020fa7a6d39d1ee5ed 100644
--- a/net/minecraft/world/level/EntityGetter.java
+++ b/net/minecraft/world/level/EntityGetter.java
@@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.BooleanOp;
@@ -29692,22 +29185,22 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001
-public interface EntityGetter {
+public interface EntityGetter extends ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter { // Paper - rewrite chunk system
- List<Entity> getEntities(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate);
+ List<Entity> getEntities(@Nullable Entity entity, AABB area, Predicate<? super Entity> predicate);
- <T extends Entity> List<T> getEntities(EntityTypeTest<Entity, T> filter, AABB box, Predicate<? super T> predicate);
+ <T extends Entity> List<T> getEntities(EntityTypeTest<Entity, T> entityTypeTest, AABB bounds, Predicate<? super T> predicate);
@@ -30,21 +30,44 @@ public interface EntityGetter {
- return this.getEntities(except, box, EntitySelector.NO_SPECTATORS);
+ return this.getEntities(entity, area, EntitySelector.NO_SPECTATORS);
}
-- default boolean isUnobstructed(@Nullable Entity except, VoxelShape shape) {
+- default boolean isUnobstructed(@Nullable Entity entity, VoxelShape shape) {
- if (shape.isEmpty()) {
- return true;
- } else {
-- for (Entity entity : this.getEntities(except, shape.bounds())) {
-- if (!entity.isRemoved()
-- && entity.blocksBuilding
-- && (except == null || !entity.isPassengerOfSameVehicle(except))
-- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
+- for (Entity entity1 : this.getEntities(entity, shape.bounds())) {
+- if (!entity1.isRemoved()
+- && entity1.blocksBuilding
+- && (entity == null || !entity1.isPassengerOfSameVehicle(entity))
+- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity1.getBoundingBox()), BooleanOp.AND)) {
- return false;
+ // Paper start - rewrite chunk system
+ @Override
@@ -29750,16 +29243,16 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001
+ // Paper end - optimise collisions
}
- default <T extends Entity> List<T> getEntitiesOfClass(Class<T> entityClass, AABB box) {
+ default <T extends Entity> List<T> getEntitiesOfClass(Class<T> entityClass, AABB area) {
@@ -52,23 +75,41 @@ public interface EntityGetter {
}
- default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AABB box) {
-- if (box.getSize() < 1.0E-7) {
+ default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AABB collisionBox) {
+- if (collisionBox.getSize() < 1.0E-7) {
- return List.of();
+ // Paper start - optimise collisions
+ // first behavior change is to correctly check for empty AABB
-+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(box)) {
++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(collisionBox)) {
+ // reduce indirection by always returning type with same class
+ return new java.util.ArrayList<>();
+ }
@@ -29767,23 +29260,23 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001
+ // to comply with vanilla intersection rules, expand by -epsilon so that we only get stuff we definitely collide with.
+ // Vanilla for hard collisions has this backwards, and they expand by +epsilon but this causes terrible problems
+ // specifically with boat collisions.
-+ box = box.inflate(-ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON, -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON, -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON);
++ collisionBox = collisionBox.inflate(-ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON, -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON, -ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON);
+
+ final List<Entity> entities;
-+ if (entity != null && ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)entity).moonrise$isHardColliding()) {
-+ entities = this.getEntities(entity, box, null);
++ if (entity != null && ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$isHardColliding()) {
++ entities = this.getEntities(entity, collisionBox, null);
} else {
- Predicate<Entity> predicate = entity == null ? EntitySelector.CAN_BE_COLLIDED_WITH : EntitySelector.NO_SPECTATORS.and(entity::canCollideWith);
-- List<Entity> list = this.getEntities(entity, box.inflate(1.0E-7), predicate);
-- if (list.isEmpty()) {
+- List<Entity> entities = this.getEntities(entity, collisionBox.inflate(1.0E-7), predicate);
+- if (entities.isEmpty()) {
- return List.of();
- } else {
-- Builder<VoxelShape> builder = ImmutableList.builderWithExpectedSize(list.size());
+- Builder<VoxelShape> builder = ImmutableList.builderWithExpectedSize(entities.size());
-
-- for (Entity entity2 : list) {
-- builder.add(Shapes.create(entity2.getBoundingBox()));
+- for (Entity entity1 : entities) {
+- builder.add(Shapes.create(entity1.getBoundingBox()));
- }
-+ entities = ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter)this).moonrise$getHardCollidingEntities(entity, box, null);
++ entities = ((ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter) this).moonrise$getHardCollidingEntities(entity, collisionBox, null);
+ }
- return builder.build();
@@ -29807,10 +29300,10 @@ index e185a33b5b1f8e8e0a0e666b24ba3e9186a8a7ff..5d7a6e4b73f032db356e7ec369b15001
// Paper start - Affects Spawning API
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
-index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b827401434bcfff1 100644
+index 872c3b8826f436b15f6ab0a3619692c5202eadc3..b5efce6faf35dbfee9aa6c17f2e7e9befe6a2040 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
-@@ -84,6 +84,7 @@ import net.minecraft.world.level.storage.LevelData;
+@@ -79,6 +79,7 @@ import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.storage.WritableLevelData;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
@@ -29818,25 +29311,25 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
import net.minecraft.world.scores.Scoreboard;
// CraftBukkit start
-@@ -105,7 +106,7 @@ import org.bukkit.entity.SpawnCategory;
+@@ -102,7 +103,7 @@ import org.bukkit.entity.SpawnCategory;
import org.bukkit.event.block.BlockPhysicsEvent;
// CraftBukkit end
-public abstract class Level implements LevelAccessor, AutoCloseable {
+public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel, ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemEntityGetter { // Paper - rewrite chunk system // Paper - optimise collisions
-
public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION);
public static final ResourceKey<Level> OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld"));
-@@ -131,7 +132,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ public static final ResourceKey<Level> NETHER = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_nether"));
+@@ -127,7 +128,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public float rainLevel;
protected float oThunderLevel;
public float thunderLevel;
- public final RandomSource random = RandomSource.create();
+ public final RandomSource random = new ca.spottedleaf.moonrise.common.util.ThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // Paper - replace random
- /** @deprecated */
@Deprecated
private final RandomSource threadSafeRandom = RandomSource.createThreadSafe();
-@@ -207,7 +208,639 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ private final Holder<DimensionType> dimensionTypeRegistration;
+@@ -202,6 +203,629 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public abstract ResourceKey<LevelStem> getTypeKey();
@@ -30463,9 +29956,15 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
+ }
+ // Paper end - optimise random ticking
+
- protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, 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<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray
+ protected Level(
+ WritableLevelData levelData,
+ ResourceKey<Level> dimension,
+@@ -218,6 +842,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, // Paper - create paper world config
+ java.util.concurrent.Executor executor // Paper - Anti-Xray
+ ) {
+ // Paper start - getblock optimisations - cache world height/sections
-+ final DimensionType dimType = holder.value();
++ final DimensionType dimType = dimensionTypeRegistration.value();
+ this.minY = dimType.minY();
+ this.height = dimType.height();
+ this.maxY = this.minY + this.height - 1;
@@ -30473,18 +29972,18 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
+ this.maxSectionY = this.maxY >> 4;
+ this.sectionsCount = this.maxSectionY - this.minSectionY + 1;
+ // Paper end - getblock optimisations - cache world height/sections
- this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
this.generator = gen;
-@@ -288,6 +921,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -298,6 +931,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime);
this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime);
- this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
+ this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new io.papermc.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : io.papermc.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
+ this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system
}
// Paper start - Cancel hit for vanished players
-@@ -557,7 +1191,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -567,7 +1201,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
this.setBlocksDirty(blockposition, iblockdata1, iblockdata2);
}
@@ -30493,19 +29992,19 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
this.sendBlockUpdated(blockposition, iblockdata1, iblockdata, i);
}
-@@ -820,6 +1454,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -836,6 +1470,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Iterator<TickingBlockEntity> iterator = this.blockEntityTickers.iterator();
- boolean flag = this.tickRateManager().runsNormally();
+ boolean runsNormally = this.tickRateManager().runsNormally();
+ int tickedEntities = 0; // Paper - rewrite chunk system
+
int tilesThisCycle = 0;
var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<TickingBlockEntity>(); // Paper - Fix MC-117075; use removeAll
toRemove.add(null); // Paper - Fix MC-117075
-@@ -835,6 +1471,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -850,6 +1486,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Spigot end
- } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
- tickingblockentity.tick();
+ } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) {
+ tickingBlockEntity.tick();
+ // Paper start - rewrite chunk system
+ if ((++tickedEntities & 7) == 0) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
@@ -30514,16 +30013,18 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
}
}
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
-@@ -855,12 +1496,20 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -870,6 +1511,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
// Paper end - Prevent block entity and entity crashes
}
+ this.moonrise$midTickTasks(); // Paper - rewrite chunk system
}
+
// Paper start - Option to prevent armor stands from doing entity lookups
- @Override
+@@ -877,7 +1519,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public boolean noCollision(@Nullable Entity entity, AABB box) {
- if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups)
+ return false;
- return LevelAccessor.super.noCollision(entity, box);
+ // Paper start - optimise collisions
+ final int flags = entity == null ? (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER | ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY) : ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_ONLY;
@@ -30536,59 +30037,62 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
}
// Paper end - Option to prevent armor stands from doing entity lookups
-@@ -912,7 +1561,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1015,7 +1664,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ if (this.isOutsideBuildHeight(pos)) {
+ return null;
+ } else {
+- return !this.isClientSide && Thread.currentThread() != this.thread
++ return !this.isClientSide && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread() // Paper - rewrite chunk system
+ ? null
+ : this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE);
}
- // Paper end - Perf: Optimize capturedTileEntities lookup
- // CraftBukkit end
-- return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE));
-+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system
- }
-
- public void setBlockEntity(BlockEntity blockEntity) {
-@@ -1004,23 +1653,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1108,22 +1757,16 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ public List<Entity> getEntities(@Nullable Entity entity, AABB boundingBox, Predicate<? super Entity> predicate) {
Profiler.get().incrementCounter("getEntities");
List<Entity> list = Lists.newArrayList();
-
-- this.getEntities().get(box, (entity1) -> {
-- if (entity1 != except && predicate.test(entity1)) {
+- this.getEntities().get(boundingBox, entity1 -> {
+- if (entity1 != entity && predicate.test(entity1)) {
- list.add(entity1);
- }
--
- });
-- Iterator iterator = this.dragonParts().iterator();
-+ // Paper start - rewrite chunk system
-+ final List<Entity> ret = new java.util.ArrayList<>();
-- while (iterator.hasNext()) {
-- EnderDragonPart entitycomplexpart = (EnderDragonPart) iterator.next();
-+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(except, box, ret, predicate);
-
-- if (entitycomplexpart != except && entitycomplexpart.parentMob != except && predicate.test(entitycomplexpart) && box.intersects(entitycomplexpart.getBoundingBox())) {
-- list.add(entitycomplexpart);
+- for (EnderDragonPart enderDragonPart : this.dragonParts()) {
+- if (enderDragonPart != entity
+- && enderDragonPart.parentMob != entity
+- && predicate.test(enderDragonPart)
+- && boundingBox.intersects(enderDragonPart.getBoundingBox())) {
+- list.add(enderDragonPart);
- }
- }
-+ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, except, box, predicate, ret);
++ // Paper start - rewrite chunk system
++ final List<Entity> ret = new java.util.ArrayList<>();
- return list;
++ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities(entity, boundingBox, ret, predicate);
++
++ ca.spottedleaf.moonrise.common.PlatformHooks.get().addToGetEntities((Level)(Object)this, entity, boundingBox, predicate, ret);
++
+ return ret;
+ // Paper end - rewrite chunk system
}
@Override
-@@ -1035,36 +1676,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE);
+@@ -1137,33 +1780,94 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ this.getEntities(entityTypeTest, bounds, predicate, output, Integer.MAX_VALUE);
}
-- public <T extends Entity> void getEntities(EntityTypeTest<Entity, T> filter, AABB box, Predicate<? super T> predicate, List<? super T> result, int limit) {
+- public <T extends Entity> void getEntities(
+- EntityTypeTest<Entity, T> entityTypeTest, AABB bounds, Predicate<? super T> predicate, List<? super T> output, int maxResults
+- ) {
+ // Paper start - rewrite chunk system
+ public <T extends Entity> void getEntities(final EntityTypeTest<Entity, T> entityTypeTest,
+ final AABB boundingBox, final Predicate<? super T> predicate,
+ final List<? super T> into, final int maxCount) {
Profiler.get().incrementCounter("getEntities");
-- this.getEntities().get(filter, box, (entity) -> {
+- this.getEntities().get(entityTypeTest, bounds, entity -> {
- if (predicate.test(entity)) {
-- result.add(entity);
-- if (result.size() >= limit) {
+- output.add(entity);
+- if (output.size() >= maxResults) {
- return AbortableIterationConsumer.Continuation.ABORT;
- }
+
@@ -30604,9 +30108,15 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
}
+ }
-- if (entity instanceof EnderDragon entityenderdragon) {
-- EnderDragonPart[] aentitycomplexpart = entityenderdragon.getSubEntities();
-- int j = aentitycomplexpart.length;
+- if (entity instanceof EnderDragon enderDragon) {
+- for (EnderDragonPart enderDragonPart : enderDragon.getSubEntities()) {
+- T entity1 = entityTypeTest.tryCast(enderDragonPart);
+- if (entity1 != null && predicate.test(entity1)) {
+- output.add(entity1);
+- if (output.size() >= maxResults) {
+- return AbortableIterationConsumer.Continuation.ABORT;
+- }
+- }
+ if (entityTypeTest == null) {
+ if (maxCount != Integer.MAX_VALUE) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)this).moonrise$getEntityLookup().getEntities((Entity)null, boundingBox, (List)into, (Predicate)predicate, maxCount);
@@ -30618,18 +30128,9 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
+ return;
+ }
+ }
-
-- for (int k = 0; k < j; ++k) {
-- EnderDragonPart entitycomplexpart = aentitycomplexpart[k];
-- T t0 = filter.tryCast(entitycomplexpart); // CraftBukkit - decompile error
++
+ final Class<? extends Entity> base = entityTypeTest.getBaseClass();
-
-- if (t0 != null && predicate.test(t0)) {
-- result.add(t0);
-- if (result.size() >= limit) {
-- return AbortableIterationConsumer.Continuation.ABORT;
-- }
-- }
++
+ final Predicate<? super T> modifiedPredicate;
+ if (predicate == null) {
+ modifiedPredicate = (final T obj) -> {
@@ -30692,7 +30193,7 @@ index 2a078293332efe4369f314ab021dfa16f63f7f3f..f477c5817f022ce7c4ad25e9b8274014
@Nullable
public abstract Entity getEntity(int id);
diff --git a/net/minecraft/world/level/LevelReader.java b/net/minecraft/world/level/LevelReader.java
-index 5eb8982678110fabb82a93c5ec67c666b7fde017..ade435de0af4ee3566fa4a490df53cddd2f6531c 100644
+index 2709803b9266ff4a2034d83321cd0ba4e30fc0aa..26c8c1e5598daf3550aef05b12218c47bda6618b 100644
--- a/net/minecraft/world/level/LevelReader.java
+++ b/net/minecraft/world/level/LevelReader.java
@@ -22,7 +22,18 @@ import net.minecraft.world.level.dimension.DimensionType;
@@ -30713,10 +30214,10 @@ index 5eb8982678110fabb82a93c5ec67c666b7fde017..ade435de0af4ee3566fa4a490df53cdd
+ // Paper end - rewrite chunk system
+
@Nullable
- ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create);
+ ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk);
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
-index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f81daa428 100644
+index 8b91574d4679f4e5a01b4bc3651069cd489b0336..fc08543bf5c8cbe338991795a9da28e997a5d9d1 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -64,6 +64,249 @@ public class ServerExplosion implements Explosion {
@@ -30967,61 +30468,60 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
+ }
+ // Paper end - collisions optimisations
- public ServerExplosion(ServerLevel world, @Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, Vec3 pos, float power, boolean createFire, Explosion.BlockInteraction destructionType) {
- this.level = world;
-@@ -127,65 +370,101 @@ public class ServerExplosion implements Explosion {
+ public ServerExplosion(
+ ServerLevel level,
+@@ -135,63 +378,102 @@ public class ServerExplosion implements Explosion {
}
private List<BlockPos> calculateExplodedPositions() {
-- Set<BlockPos> set = new HashSet();
-- boolean flag = true;
--
-- for (int i = 0; i < 16; ++i) {
-- for (int j = 0; j < 16; ++j) {
-- for (int k = 0; k < 16; ++k) {
-- if (i == 0 || i == 15 || j == 0 || j == 15 || k == 0 || k == 15) {
-- double d0 = (double) ((float) i / 15.0F * 2.0F - 1.0F);
-- double d1 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
-- double d2 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
-- double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
--
-- d0 /= d3;
-- d1 /= d3;
-- d2 /= d3;
+- Set<BlockPos> set = new HashSet<>();
+- int i = 16;
+-
+- for (int i1 = 0; i1 < 16; i1++) {
+- for (int i2 = 0; i2 < 16; i2++) {
+- for (int i3 = 0; i3 < 16; i3++) {
+- if (i1 == 0 || i1 == 15 || i2 == 0 || i2 == 15 || i3 == 0 || i3 == 15) {
+- double d = i1 / 15.0F * 2.0F - 1.0F;
+- double d1 = i2 / 15.0F * 2.0F - 1.0F;
+- double d2 = i3 / 15.0F * 2.0F - 1.0F;
+- double squareRoot = Math.sqrt(d * d + d1 * d1 + d2 * d2);
+- d /= squareRoot;
+- d1 /= squareRoot;
+- d2 /= squareRoot;
- float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
-- double d4 = this.center.x;
-- double d5 = this.center.y;
-- double d6 = this.center.z;
+- double d3 = this.center.x;
+- double d4 = this.center.y;
+- double d5 = this.center.z;
-
- for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
-- BlockPos blockposition = BlockPos.containing(d4, d5, d6);
-- BlockState iblockdata = this.level.getBlockState(blockposition);
-- if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
-- FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions
--
-- if (!this.level.isInWorldBounds(blockposition)) {
+- BlockPos blockPos = BlockPos.containing(d3, d4, d5);
+- BlockState blockState = this.level.getBlockState(blockPos);
+- if (!blockState.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
+- FluidState fluidState = blockState.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions
+- if (!this.level.isInWorldBounds(blockPos)) {
- break;
- }
+ // Paper start - collision optimisations
+ final ObjectArrayList<BlockPos> ret = new ObjectArrayList<>();
-- Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockposition, iblockdata, fluid);
-+ final Vec3 center = this.center;
-
-- if (optional.isPresent()) {
-- f -= ((Float) optional.get() + 0.3F) * 0.3F;
+- Optional<Float> blockExplosionResistance = this.damageCalculator
+- .getBlockExplosionResistance(this, this.level, blockPos, blockState, fluidState);
+- if (blockExplosionResistance.isPresent()) {
+- f -= (blockExplosionResistance.get() + 0.3F) * 0.3F;
- }
-+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache = this.directMappedBlockCache;
++ final Vec3 center = this.center;
-- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) {
-- set.add(blockposition);
+- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockPos, blockState, f)) {
+- set.add(blockPos);
- // Paper start - prevent headless pistons from forming
-- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
-- net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(blockposition);
+- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && blockState.getBlock() == Blocks.MOVING_PISTON) {
+- net.minecraft.world.level.block.entity.BlockEntity extension = this.level.getBlockEntity(blockPos);
- if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) {
-- net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
-- set.add(blockposition.relative(direction.getOpposite()));
+- net.minecraft.core.Direction direction = blockState.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
+- set.add(blockPos.relative(direction.getOpposite()));
- }
++ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[] blockCache = this.directMappedBlockCache;
++
+ // use initial cache value that is most likely to be used: the source position
+ final ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache initialCache;
+ {
@@ -31097,10 +30597,10 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
}
- // Paper end - prevent headless pistons from forming
}
--
-- d4 += d0 * 0.30000001192092896D;
-- d5 += d1 * 0.30000001192092896D;
-- d6 += d2 * 0.30000001192092896D;
+
+- d3 += d * 0.3F;
+- d4 += d1 * 0.3F;
+- d5 += d2 * 0.3F;
+ // Paper end - prevent headless pistons from forming
}
}
@@ -31114,13 +30614,13 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
+ } while (power > 0.0f);
}
-- return new ObjectArrayList(set);
+- return new ObjectArrayList<>(set);
+ return ret;
+ // Paper end - collision optimisations
}
private void hurtEntities() {
-@@ -391,6 +670,14 @@ public class ServerExplosion implements Explosion {
+@@ -372,6 +654,14 @@ public class ServerExplosion implements Explosion {
return;
}
// CraftBukkit end
@@ -31132,10 +30632,10 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
+ this.directMappedBlockCache = new ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
+ this.mutablePos = new BlockPos.MutableBlockPos();
+ // Paper end - collision optimisations
- this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center);
+ this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center);
List<BlockPos> list = this.calculateExplodedPositions();
-
-@@ -406,6 +693,13 @@ public class ServerExplosion implements Explosion {
+ this.hurtEntities();
+@@ -385,6 +675,13 @@ public class ServerExplosion implements Explosion {
if (this.fire) {
this.createFire(list);
}
@@ -31146,10 +30646,10 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
+ this.directMappedBlockCache = null;
+ this.mutablePos = null;
+ // Paper end - collision optimisations
-
}
-@@ -499,12 +793,12 @@ public class ServerExplosion implements Explosion {
+ private static void addOrAppendStack(List<ServerExplosion.StackCollector> stackCollectors, ItemStack stack, BlockPos pos) {
+@@ -475,12 +772,12 @@ public class ServerExplosion implements Explosion {
// Paper start - Optimize explosions
private float getBlockDensity(Vec3 vec3d, Entity entity) {
if (!this.level.paperConfig().environment.optimizeExplosions) {
@@ -31165,72 +30665,72 @@ index b8ffe547ad29645b65c3df8bd6ccb7c20985711d..685ccfb73bf7125585ef90b6a0f51b2f
}
diff --git a/net/minecraft/world/level/biome/Biome.java b/net/minecraft/world/level/biome/Biome.java
-index 9f86b69d8c93a63e0b408ea52519f1fc2e798226..78afd8e51e03cd53c12b64db8a817da457f81bef 100644
+index ea521e1d636b8ffdeb22882dfc8875b2ddbd8da1..7b666bbeefe296e7fdbadcc72dbf9e602f73e925 100644
--- a/net/minecraft/world/level/biome/Biome.java
+++ b/net/minecraft/world/level/biome/Biome.java
-@@ -113,20 +113,7 @@ public final class Biome {
+@@ -117,20 +117,7 @@ public final class Biome {
@Deprecated
- public float getTemperature(BlockPos blockPos, int seaLevel) {
-- long l = blockPos.asLong();
-- Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get();
-- float f = long2FloatLinkedOpenHashMap.get(l);
+ public float getTemperature(BlockPos pos, int seaLevel) {
+- long packedBlockPos = pos.asLong();
+- Long2FloatLinkedOpenHashMap map = this.temperatureCache.get();
+- float f = map.get(packedBlockPos);
- if (!Float.isNaN(f)) {
- return f;
- } else {
-- float g = this.getHeightAdjustedTemperature(blockPos, seaLevel);
-- if (long2FloatLinkedOpenHashMap.size() == 1024) {
-- long2FloatLinkedOpenHashMap.removeFirstFloat();
+- float heightAdjustedTemperature = this.getHeightAdjustedTemperature(pos, seaLevel);
+- if (map.size() == 1024) {
+- map.removeFirstFloat();
- }
-
-- long2FloatLinkedOpenHashMap.put(l, g);
-- return g;
+- map.put(packedBlockPos, heightAdjustedTemperature);
+- return heightAdjustedTemperature;
- }
-+ return this.getHeightAdjustedTemperature(blockPos, seaLevel); // Paper - optimise random ticking
++ return this.getHeightAdjustedTemperature(pos, seaLevel); // Paper - optimise random ticking
}
- public boolean shouldFreeze(LevelReader world, BlockPos blockPos) {
+ public boolean shouldFreeze(LevelReader level, BlockPos pos) {
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
-index 01352cc83b25eb0e30b7e0ff521fc7c1b3d5155b..90f8360f547ce709fd13ee34f8e67d8bfa94b498 100644
+index 8d98cba3830dc5dfb5cae9a6f5fedfffee0d2cd8..73962e79a0f3d892e3155443a1b84508b0f4042e 100644
--- a/net/minecraft/world/level/biome/BiomeManager.java
+++ b/net/minecraft/world/level/biome/BiomeManager.java
@@ -98,8 +98,7 @@ public class BiomeManager {
}
- private static double getFiddle(long l) {
-- double d = (double)Math.floorMod(l >> 24, 1024) / 1024.0;
+ private static double getFiddle(long seed) {
+- double d = Math.floorMod(seed >> 24, 1024) / 1024.0;
- return (d - 0.5) * 0.9;
-+ return (double)(((l >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction
++ return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction
}
public interface NoiseBiomeSource {
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
-index 1aa69f4a7005242925124c74b8229e6fa7362717..c0b1f903962b25d8ff6c2b4fcd2be0e45de09b35 100644
+index 3eedc6c2a1325a0fd1baa14e246aeda27de4117d..34177f27680612055526553c849777067882ad74 100644
--- a/net/minecraft/world/level/block/Block.java
+++ b/net/minecraft/world/level/block/Block.java
-@@ -271,7 +271,7 @@ public class Block extends BlockBehaviour implements ItemLike {
+@@ -259,7 +259,7 @@ public class Block extends BlockBehaviour implements ItemLike {
}
public static boolean isShapeFullBlock(VoxelShape shape) {
-- return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
+- return SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
+ return ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape).moonrise$isFullBlock(); // Paper - optimise collisions
}
- public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {}
+ public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
-index b1101156b281d800f18b25208018722bbecded9f..8c0f332a1a0918f60226d969918ae7fe4fe74166 100644
+index e0c3d8923f56c059b5d6111ab2ff01be3566f6d9..73b913da595e7ad2de8f363f342de98f6c647b71 100644
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
-@@ -797,7 +797,7 @@ public abstract class BlockBehaviour implements FeatureElement {
- boolean test(BlockState state, BlockGetter world, BlockPos pos);
+@@ -417,7 +417,7 @@ public abstract class BlockBehaviour implements FeatureElement {
+ return this.properties.destroyTime;
}
- public abstract static class BlockStateBase extends StateHolder<Block, BlockState> {
+ public abstract static class BlockStateBase extends StateHolder<Block, BlockState> implements ca.spottedleaf.moonrise.patches.starlight.blockstate.StarlightAbstractBlockState, ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState { // Paper - rewrite chunk system // Paper - optimise collisions
-
private static final Direction[] DIRECTIONS = Direction.values();
- private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = (VoxelShape[]) Util.make(new VoxelShape[BlockBehaviour.BlockStateBase.DIRECTIONS.length], (avoxelshape) -> {
-@@ -841,6 +841,76 @@ public abstract class BlockBehaviour implements FeatureElement {
+ private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = Util.make(new VoxelShape[DIRECTIONS.length], shape -> Arrays.fill(shape, Shapes.empty()));
+ private static final VoxelShape[] FULL_BLOCK_OCCLUSION_SHAPES = Util.make(
+@@ -456,6 +456,76 @@ public abstract class BlockBehaviour implements FeatureElement {
private boolean propagatesSkylightDown;
private int lightBlock;
@@ -31304,13 +30804,13 @@ index b1101156b281d800f18b25208018722bbecded9f..8c0f332a1a0918f60226d969918ae7fe
+ }
+ // Paper end - optimise collisions
+
- protected BlockStateBase(Block block, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<BlockState> codec) {
- super(block, propertyMap, codec);
- this.fluidState = Fluids.EMPTY.defaultFluidState();
-@@ -925,6 +995,41 @@ public abstract class BlockBehaviour implements FeatureElement {
+ protected BlockStateBase(Block owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> values, MapCodec<BlockState> propertiesCodec) {
+ super(owner, values, propertiesCodec);
+ BlockBehaviour.Properties properties = owner.properties;
+@@ -534,6 +604,41 @@ public abstract class BlockBehaviour implements FeatureElement {
- this.propagatesSkylightDown = ((Block) this.owner).propagatesSkylightDown(this.asState());
- this.lightBlock = ((Block) this.owner).getLightBlock(this.asState());
+ this.propagatesSkylightDown = this.owner.propagatesSkylightDown(this.asState());
+ this.lightBlock = this.owner.getLightBlock(this.asState());
+ // Paper start - rewrite chunk system
+ this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion;
+ // Paper end - rewrite chunk system
@@ -31350,7 +30850,7 @@ index b1101156b281d800f18b25208018722bbecded9f..8c0f332a1a0918f60226d969918ae7fe
public Block getBlock() {
diff --git a/net/minecraft/world/level/block/state/StateHolder.java b/net/minecraft/world/level/block/state/StateHolder.java
-index 422b364764e0df16ca250b4939d7b226e69c0840..815ee11aa5ed3448ff255e9c36d769478de477bd 100644
+index 2f2dbf02a9732a7e640a6c730d4fc1443e723933..098518383d2c07491e047749ce3a834e98b85b1d 100644
--- a/net/minecraft/world/level/block/state/StateHolder.java
+++ b/net/minecraft/world/level/block/state/StateHolder.java
@@ -15,7 +15,7 @@ import java.util.stream.Collectors;
@@ -31381,10 +30881,10 @@ index 422b364764e0df16ca250b4939d7b226e69c0840..815ee11aa5ed3448ff255e9c36d76947
+ }
+ // Paper end - optimise blockstate property access
+
- protected StateHolder(O owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<S> codec) {
+ protected StateHolder(O owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> values, MapCodec<S> propertiesCodec) {
this.owner = owner;
- this.values = propertyMap;
- this.propertiesCodec = codec;
+ this.values = values;
+ this.propertiesCodec = propertiesCodec;
+ // Paper start - optimise blockstate property access
+ this.optimisedTable = new ca.spottedleaf.moonrise.patches.blockstate_propertyaccess.util.ZeroCollidingReferenceStateTable<>(this.values.keySet());
+ this.tableIndex = this.optimisedTable.getIndex((StateHolder<O, S>)(Object)this);
@@ -31460,45 +30960,49 @@ index 422b364764e0df16ca250b4939d7b226e69c0840..815ee11aa5ed3448ff255e9c36d76947
+ // Paper end - optimise blockstate property access
}
- private <T extends Comparable<T>, V extends T> S setValueInternal(Property<T> property, V newValue, Comparable<?> oldValue) {
-@@ -125,18 +148,27 @@ public abstract class StateHolder<O, S> {
+ private <T extends Comparable<T>, V extends T> S setValueInternal(Property<T> property, V value, Comparable<?> comparable) {
+@@ -125,21 +148,27 @@ public abstract class StateHolder<O, S> {
}
- public void populateNeighbours(Map<Map<Property<?>, Comparable<?>>, S> states) {
+ public void populateNeighbours(Map<Map<Property<?>, Comparable<?>>, S> possibleStateMap) {
- if (this.neighbours != null) {
- throw new IllegalStateException();
- } else {
- Map<Property<?>, S[]> map = new Reference2ObjectArrayMap<>(this.values.size());
+-
+- for (Entry<Property<?>, Comparable<?>> entry : this.values.entrySet()) {
+- Property<?> property = entry.getKey();
+- map.put(
+- property,
+- (S[]) property.getPossibleValues().stream().map(comparable -> possibleStateMap.get(this.makeNeighbourValues(property, comparable))).toArray()
+- );
+- }
+ // Paper start - optimise blockstate property access
-+ final Map<Map<Property<?>, Comparable<?>>, S> map = states;
++ final Map<Map<Property<?>, Comparable<?>>, S> map = possibleStateMap;
+ if (this.optimisedTable.isLoaded()) {
+ return;
+ }
+ this.optimisedTable.loadInTable(map);
-- for (Entry<Property<?>, Comparable<?>> entry : this.values.entrySet()) {
-- Property<?> property = entry.getKey();
-- map.put(property, property.getPossibleValues().stream().map(value -> states.get(this.makeNeighbourValues(property, value))).toArray());
-- }
+- this.neighbours = map;
+ // de-duplicate the tables
+ for (final Map.Entry<Map<Property<?>, Comparable<?>>, S> entry : map.entrySet()) {
+ final S value = entry.getValue();
+ ((StateHolder<O, S>)value).optimisedTable = this.optimisedTable;
-+ }
-
-- this.neighbours = map;
+ }
++
+ // remove values arrays
+ for (final Map.Entry<Map<Property<?>, Comparable<?>>, S> entry : map.entrySet()) {
+ final S value = entry.getValue();
+ ((StateHolder<O, S>)value).values = null;
- }
++ }
+
+ return;
+ // Paper end optimise blockstate property access
}
private Map<Property<?>, Comparable<?>> makeNeighbourValues(Property<?> property, Comparable<?> value) {
-@@ -146,7 +178,11 @@ public abstract class StateHolder<O, S> {
+@@ -149,7 +178,11 @@ public abstract class StateHolder<O, S> {
}
public Map<Property<?>, Comparable<?>> getValues() {
@@ -31510,9 +31014,9 @@ index 422b364764e0df16ca250b4939d7b226e69c0840..815ee11aa5ed3448ff255e9c36d76947
+ // Paper end - optimise blockstate property access
}
- protected static <O, S extends StateHolder<O, S>> Codec<S> codec(Codec<O> codec, Function<O, S> ownerToStateFunction) {
+ protected static <O, S extends StateHolder<O, S>> Codec<S> codec(Codec<O> propertyMap, Function<O, S> holderFunction) {
diff --git a/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/net/minecraft/world/level/block/state/properties/BooleanProperty.java
-index ea76aa490358e9e1d13350ba0ea246ec2c423894..98058505d36baf74008da08339afc196713b14a7 100644
+index 40c83ff614169be8ab988f3ab476eca93acee28d..654f14e0fd1920ec94300649719c2460918899e2 100644
--- a/net/minecraft/world/level/block/state/properties/BooleanProperty.java
+++ b/net/minecraft/world/level/block/state/properties/BooleanProperty.java
@@ -3,13 +3,23 @@ package net.minecraft.world.level.block.state.properties;
@@ -31541,7 +31045,7 @@ index ea76aa490358e9e1d13350ba0ea246ec2c423894..98058505d36baf74008da08339afc196
@Override
diff --git a/net/minecraft/world/level/block/state/properties/EnumProperty.java b/net/minecraft/world/level/block/state/properties/EnumProperty.java
-index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5640127a7 100644
+index c56728863a084a5e1f6e6d9489d00bb0c83af168..1d785b7bb046ef291342efa3ede6cdeb460f12fb 100644
--- a/net/minecraft/world/level/block/state/properties/EnumProperty.java
+++ b/net/minecraft/world/level/block/state/properties/EnumProperty.java
@@ -10,11 +10,39 @@ import java.util.function.Predicate;
@@ -31582,8 +31086,8 @@ index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5
+ }
+ // Paper end - optimise blockstate property access
+
- private EnumProperty(String name, Class<T> type, List<T> values) {
- super(name, type);
+ private EnumProperty(String name, Class<T> clazz, List<T> values) {
+ super(name, clazz);
if (values.isEmpty()) {
@@ -37,6 +65,7 @@ public final class EnumProperty<T extends Enum<T> & StringRepresentable> extends
@@ -31594,7 +31098,7 @@ index 85a197232be9377c0313ec00e8f935551e2c60e0..30b2fce9e47ffcc3de1542b1d0f073f5
@Override
diff --git a/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/net/minecraft/world/level/block/state/properties/IntegerProperty.java
-index 55a87592a99105dbf57b26fb6ccba695295fce24..986365acc9983331a7982ea2e1eac2b0efe1506d 100644
+index 28a15908420cb239c317d58f7e3a1df3c6278b33..b7543eb5a8f87bc7bd275ed9d46a68072c1e57b5 100644
--- a/net/minecraft/world/level/block/state/properties/IntegerProperty.java
+++ b/net/minecraft/world/level/block/state/properties/IntegerProperty.java
@@ -5,11 +5,33 @@ import java.util.List;
@@ -31641,7 +31145,7 @@ index 55a87592a99105dbf57b26fb6ccba695295fce24..986365acc9983331a7982ea2e1eac2b0
@Override
diff --git a/net/minecraft/world/level/block/state/properties/Property.java b/net/minecraft/world/level/block/state/properties/Property.java
-index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276f0386e4d 100644
+index 92350434746f06bbf4a161c6bc42602de7b45220..1c24f38d21da1be9740512981f219924c5d3cf76 100644
--- a/net/minecraft/world/level/block/state/properties/Property.java
+++ b/net/minecraft/world/level/block/state/properties/Property.java
@@ -10,7 +10,7 @@ import java.util.stream.Stream;
@@ -31685,15 +31189,15 @@ index fcf04c5c58ff35d38c5bf0df562ae2f8dc98a0ee..0b116160924300a9d62ad5948bfaf276
+ public abstract int moonrise$getIdFor(final T value);
+ // Paper end - optimise blockstate property access
+
- protected Property(String name, Class<T> type) {
- this.clazz = type;
+ protected Property(String name, Class<T> clazz) {
+ this.clazz = clazz;
this.name = name;
+ this.id = ID_GENERATOR.getAndIncrement(); // Paper - optimise blockstate property access
}
public Property.Value<T> value(T value) {
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
-index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95c9ac2dbb 100644
+index bc688ad1097ef4159dfc5f96d963a9fa63262e20..6e0210f32c679e3a33256cb05dc282f2e8b7d856 100644
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick;
@@ -31702,10 +31206,10 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
-public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess {
+public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk { // Paper - rewrite chunk system
-
public static final int NO_FILLED_SECTION = -1;
private static final Logger LOGGER = LogUtils.getLogger();
-@@ -77,7 +77,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+ private static final LongSet EMPTY_REFERENCE_SET = new LongOpenHashSet();
+@@ -75,7 +75,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
@Nullable
protected BlendingData blendingData;
public final Map<Heightmap.Types, Heightmap> heightmaps = Maps.newEnumMap(Heightmap.Types.class);
@@ -31714,9 +31218,9 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
private final Map<Structure, StructureStart> structureStarts = Maps.newHashMap();
private final Map<Structure, LongSet> structuresRefences = Maps.newHashMap();
protected final Map<BlockPos, CompoundTag> pendingBlockEntities = Maps.newHashMap();
-@@ -90,6 +90,57 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
- public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(ChunkAccess.DATA_TYPE_REGISTRY);
+@@ -88,6 +88,57 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
// CraftBukkit end
+ public final Registry<Biome> biomeRegistry; // CraftBukkit
+ // Paper start - rewrite chunk system
+ private volatile ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles;
@@ -31769,22 +31273,22 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
+ private final int maxSection;
+ // Paper end - get block chunk optimisation
+
- public ChunkAccess(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry<Biome> biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] sectionArray, @Nullable BlendingData blendingData) {
- this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups
- this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key
-@@ -99,7 +150,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+ public ChunkAccess(
+ ChunkPos chunkPos,
+ UpgradeData upgradeData,
+@@ -105,7 +156,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
this.inhabitedTime = inhabitedTime;
- this.postProcessing = new ShortList[heightLimitView.getSectionsCount()];
+ this.postProcessing = new ShortList[levelHeightAccessor.getSectionsCount()];
this.blendingData = blendingData;
-- this.skyLightSources = new ChunkSkyLightSources(heightLimitView);
+- this.skyLightSources = new ChunkSkyLightSources(levelHeightAccessor);
+ // Paper - rewrite chunk system
- if (sectionArray != null) {
- if (this.sections.length == sectionArray.length) {
- System.arraycopy(sectionArray, 0, this.sections, 0, this.sections.length);
-@@ -111,6 +162,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+ if (sections != null) {
+ if (this.sections.length == sections.length) {
+ System.arraycopy(sections, 0, this.sections, 0, this.sections.length);
+@@ -116,6 +167,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+
this.replaceMissingSections(biomeRegistry, this.sections); // Paper - Anti-Xray - make it a non-static method
- // CraftBukkit start
- this.biomeRegistry = biomeRegistry;
+ this.biomeRegistry = biomeRegistry; // Craftbukkit
+ // Paper start - rewrite chunk system
+ if (!((Object)this instanceof ImposterProtoChunk)) {
+ this.starlight$setBlockNibbles(ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine.getFilledEmptyLight(heightLimitView));
@@ -31796,30 +31300,26 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
+ this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(levelHeightAccessor);
+ // Paper end - get block chunk optimisation
}
- public final Registry<Biome> biomeRegistry;
- // CraftBukkit end
-@@ -457,22 +518,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+
+ private void replaceMissingSections(Registry<Biome> biomeRegistry, LevelChunkSection[] sections) { // Paper - Anti-Xray - make it a non-static method
+@@ -442,18 +503,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
@Override
- public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ) {
+ public Holder<Biome> getNoiseBiome(int x, int y, int z) {
- try {
-- int l = QuartPos.fromBlock(this.getMinY());
-- int i1 = l + QuartPos.fromBlock(this.getHeight()) - 1;
-- int j1 = Mth.clamp(biomeY, l, i1);
-- int k1 = this.getSectionIndex(QuartPos.toBlock(j1));
--
-- return this.sections[k1].getNoiseBiome(biomeX & 3, j1 & 3, biomeZ & 3);
-- } catch (Throwable throwable) {
-- CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting biome");
-- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Biome being got");
--
-- crashreportsystemdetails.setDetail("Location", () -> {
-- return CrashReportCategory.formatLocation(this, biomeX, biomeY, biomeZ);
-- });
-- throw new ReportedException(crashreport);
+- int quartPosMinY = QuartPos.fromBlock(this.getMinY());
+- int i = quartPosMinY + QuartPos.fromBlock(this.getHeight()) - 1;
+- int i1 = Mth.clamp(y, quartPosMinY, i);
+- int sectionIndex = this.getSectionIndex(QuartPos.toBlock(i1));
+- return this.sections[sectionIndex].getNoiseBiome(x & 3, i1 & 3, z & 3);
+- } catch (Throwable var8) {
+- CrashReport crashReport = CrashReport.forThrowable(var8, "Getting biome");
+- CrashReportCategory crashReportCategory = crashReport.addCategory("Biome being got");
+- crashReportCategory.setDetail("Location", () -> CrashReportCategory.formatLocation(this, x, y, z));
+- throw new ReportedException(crashReport);
+ // Paper start - get block chunk optimisation
-+ int sectionY = (biomeY >> 2) - this.minSection;
-+ int rel = biomeY & 3;
++ int sectionY = (y >> 2) - this.minSection;
++ int rel = y & 3;
+
+ final LevelChunkSection[] sections = this.sections;
+
@@ -31831,12 +31331,12 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
+ rel = 3;
}
+
-+ return sections[sectionY].getNoiseBiome(biomeX & 3, rel, biomeZ & 3);
++ return sections[sectionY].getNoiseBiome(x & 3, rel, z & 3);
+ // Paper end - get block chunk optimisation
}
-
// CraftBukkit start
-@@ -529,12 +590,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
+ public void setBiome(int i, int j, int k, Holder<Biome> biome) {
+@@ -507,12 +572,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
}
public void initializeLightSources() {
@@ -31850,31 +31350,31 @@ index 9d240aa87101662480cdd510839e017aa9c58fcd..f87abb22dd161b2b74401086de80dc95
+ return null; // Paper - rewrite chunk system
}
- public static record PackedTicks(List<SavedTick<Block>> blocks, List<SavedTick<Fluid>> fluids) {
+ public record PackedTicks(List<SavedTick<Block>> blocks, List<SavedTick<Fluid>> fluids) {
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
-index ca6928f959eb63ac9183ba6c95738609839a7d32..e0cb360ece042c4fc6aa0d10106923fe25288f5c 100644
+index 89f027f0edf2ca59966efe209e567108665cbe0c..7944c2bb854ee52a55d7c54e5f814e87d709e70e 100644
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
-@@ -120,7 +120,7 @@ public abstract class ChunkGenerator {
+@@ -116,7 +116,7 @@ public abstract class ChunkGenerator {
return CompletableFuture.supplyAsync(() -> {
- chunk.fillBiomesFromNoise(this.biomeSource, noiseConfig.sampler());
+ chunk.fillBiomesFromNoise(this.biomeSource, randomState.sampler());
return chunk;
- }, Util.backgroundExecutor().forName("init_biomes"));
+ }, Runnable::run); // Paper - rewrite chunk system
}
- public abstract void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk);
+ public abstract void applyCarvers(
@@ -315,7 +315,7 @@ public abstract class ChunkGenerator {
- return Pair.of(placement.getLocatePos(pos), holder);
- }
-
-- ChunkAccess ichunkaccess = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS);
-+ ChunkAccess ichunkaccess = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader)world).moonrise$syncLoadNonFull(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS); // Paper - rewrite chunk system
+ return Pair.of(placement.getLocatePos(chunkPos), holder);
+ }
- structurestart = structureAccessor.getStartForStructure(SectionPos.bottomOf(ichunkaccess), (Structure) holder.value(), ichunkaccess);
- } while (structurestart == null);
+- ChunkAccess chunk = level.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.STRUCTURE_STARTS);
++ ChunkAccess chunk = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevelReader)level).moonrise$syncLoadNonFull(chunkPos.x, chunkPos.z, ChunkStatus.STRUCTURE_STARTS); // Paper - rewrite chunk system
+ StructureStart startForStructure = structureManager.getStartForStructure(SectionPos.bottomOf(chunk), holder.value(), chunk);
+ if (startForStructure != null && startForStructure.isValid() && (!skipKnownStructures || tryAddReference(structureManager, startForStructure))) {
+ return Pair.of(placement.getLocatePos(startForStructure.getChunkPos()), holder);
diff --git a/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/net/minecraft/world/level/chunk/EmptyLevelChunk.java
-index dcc0acd259920463a4464213b9a5e793603852f9..ef4161884574d3d137e12591d983dc95a960cb19 100644
+index ec128412e4a0d3d21e3b6abea8cd06c03656f00c..07b7e82c7d24f52c0251e09195451841d47883c9 100644
--- a/net/minecraft/world/level/chunk/EmptyLevelChunk.java
+++ b/net/minecraft/world/level/chunk/EmptyLevelChunk.java
@@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState;
@@ -31885,9 +31385,9 @@ index dcc0acd259920463a4464213b9a5e793603852f9..ef4161884574d3d137e12591d983dc95
+public class EmptyLevelChunk extends LevelChunk implements ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk { // Paper - rewrite chunk system
private final Holder<Biome> biome;
- public EmptyLevelChunk(Level world, ChunkPos pos, Holder<Biome> biomeEntry) {
+ public EmptyLevelChunk(Level level, ChunkPos pos, Holder<Biome> biome) {
@@ -21,6 +21,40 @@ public class EmptyLevelChunk extends LevelChunk {
- this.biome = biomeEntry;
+ this.biome = biome;
}
+ // Paper start - rewrite chunk system
@@ -31928,7 +31428,7 @@ index dcc0acd259920463a4464213b9a5e793603852f9..ef4161884574d3d137e12591d983dc95
public BlockState getBlockState(BlockPos pos) {
return Blocks.VOID_AIR.defaultBlockState();
diff --git a/net/minecraft/world/level/chunk/HashMapPalette.java b/net/minecraft/world/level/chunk/HashMapPalette.java
-index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5708f2c4a 100644
+index 7cd5d42e0c28033ee80f18bd0031ed1241fb7aae..718d00a386f32423db9f6d6c95b4a20698b976f5 100644
--- a/net/minecraft/world/level/chunk/HashMapPalette.java
+++ b/net/minecraft/world/level/chunk/HashMapPalette.java
@@ -8,12 +8,19 @@ import net.minecraft.network.FriendlyByteBuf;
@@ -31949,11 +31449,11 @@ index 98dbeaf8bde15940e5b5d5d1f13fd4bb32f0a10d..7beea075b5a7ef738a4ac0558b99f4c5
+ }
+ // Paper end - optimise palette reads
+
- public HashMapPalette(IdMap<T> idList, int bits, PaletteResize<T> listener, List<T> entries) {
- this(idList, bits, listener);
- entries.forEach(this.values::add);
+ public HashMapPalette(IdMap<T> registry, int bits, PaletteResize<T> resizeHandler, List<T> values) {
+ this(registry, bits, resizeHandler);
+ values.forEach(this.values::add);
diff --git a/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
-index f38700e5fbeeb8a913272d4464b8aa325d511dac..1eb8022f3e31603322e6c56516304afc9a11bbec 100644
+index e7c0f4da8508fbca467326f475668d66454d7b77..41856c98d97e7eb0782f8e441b9a269a47ed1914 100644
--- a/net/minecraft/world/level/chunk/ImposterProtoChunk.java
+++ b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
@@ -30,7 +30,7 @@ import net.minecraft.world.level.material.FluidState;
@@ -31966,7 +31466,7 @@ index f38700e5fbeeb8a913272d4464b8aa325d511dac..1eb8022f3e31603322e6c56516304afc
private final boolean allowWrites;
@@ -46,6 +46,48 @@ public class ImposterProtoChunk extends ProtoChunk {
- this.allowWrites = propagateToWrapped;
+ this.allowWrites = allowWrites;
}
+ // Paper start - rewrite chunk system
@@ -32015,34 +31515,19 @@ index f38700e5fbeeb8a913272d4464b8aa325d511dac..1eb8022f3e31603322e6c56516304afc
@Override
public BlockEntity getBlockEntity(BlockPos pos) {
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
-index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf191005112080b 100644
+index d1d0dc13eecb0e0eb3a7839b570a5fe7f62f3fba..72c0e031443ca42c2cfafddea9e04cfa4f93a0eb 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -55,7 +55,7 @@ import net.minecraft.world.ticks.LevelChunkTicks;
+@@ -52,7 +52,7 @@ import net.minecraft.world.ticks.LevelChunkTicks;
import net.minecraft.world.ticks.TickContainerAccess;
import org.slf4j.Logger;
-public class LevelChunk extends ChunkAccess {
+public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk, ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk, ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk { // Paper - rewrite chunk system // Paper - get block chunk optimisation
-
static final Logger LOGGER = LogUtils.getLogger();
private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() {
-@@ -114,6 +114,14 @@ public class LevelChunk extends ChunkAccess {
- this.postLoad = entityLoader;
- this.blockTicks = blockTickScheduler;
- this.fluidTicks = fluidTickScheduler;
-+ // Paper start - get block chunk optimisation
-+ this.minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level);
-+ this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(level);
-+
-+ final boolean empty = ((Object)this instanceof EmptyLevelChunk);
-+ this.debug = !empty && this.level.isDebug();
-+ this.defaultBlockState = empty ? VOID_AIR_BLOCKSTATE : AIR_BLOCKSTATE;
-+ // Paper end - get block chunk optimisation
- }
-
- // CraftBukkit start
-@@ -124,6 +132,39 @@ public class LevelChunk extends ChunkAccess {
+ @Override
+@@ -93,6 +93,39 @@ public class LevelChunk extends ChunkAccess {
// Paper start
boolean loadedTicketLevel;
// Paper end
@@ -32080,19 +31565,34 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
+ }
+ // Paper end - get block chunk optimisation
- public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) {
- this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData());
-@@ -157,13 +198,19 @@ public class LevelChunk extends ChunkAccess {
+ public LevelChunk(Level level, ChunkPos pos) {
+ this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null);
+@@ -122,6 +155,14 @@ public class LevelChunk extends ChunkAccess {
+ this.postLoad = postLoad;
+ this.blockTicks = blockTicks;
+ this.fluidTicks = fluidTicks;
++ // Paper start - get block chunk optimisation
++ this.minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level);
++ this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(level);
++
++ final boolean empty = ((Object)this instanceof EmptyLevelChunk);
++ this.debug = !empty && this.level.isDebug();
++ this.defaultBlockState = empty ? VOID_AIR_BLOCKSTATE : AIR_BLOCKSTATE;
++ // Paper end - get block chunk optimisation
+ }
+
+ public LevelChunk(ServerLevel level, ProtoChunk chunk, @Nullable LevelChunk.PostLoadProcessor postLoad) {
+@@ -159,13 +200,19 @@ public class LevelChunk extends ChunkAccess {
}
}
-- this.skyLightSources = protoChunk.skyLightSources;
+- this.skyLightSources = chunk.skyLightSources;
+ // Paper - rewrite chunk system
- this.setLightCorrect(protoChunk.isLightCorrect());
+ this.setLightCorrect(chunk.isLightCorrect());
this.markUnsaved();
this.needsDecoration = true; // CraftBukkit
// CraftBukkit start
- this.persistentDataContainer = protoChunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading.
+ this.persistentDataContainer = chunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading.
// CraftBukkit end
+ // Paper start - rewrite chunk system
+ this.starlight$setBlockNibbles(((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)protoChunk).starlight$getBlockNibbles());
@@ -32103,16 +31603,16 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
}
public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) {
-@@ -366,7 +413,7 @@ public class LevelChunk extends ChunkAccess {
- ProfilerFiller gameprofilerfiller = Profiler.get();
-
- gameprofilerfiller.push("updateSkyLightSources");
-- this.skyLightSources.update(this, j, i, l);
+@@ -341,7 +388,7 @@ public class LevelChunk extends ChunkAccess {
+ if (LightEngine.hasDifferentLightProperties(blockState, state)) {
+ ProfilerFiller profilerFiller = Profiler.get();
+ profilerFiller.push("updateSkyLightSources");
+- this.skyLightSources.update(this, i, y, i2);
+ // Paper - rewrite chunk system
- gameprofilerfiller.popPush("queueCheckLight");
- this.level.getChunkSource().getLightEngine().checkBlock(blockposition);
- gameprofilerfiller.pop();
-@@ -632,11 +679,12 @@ public class LevelChunk extends ChunkAccess {
+ profilerFiller.popPush("queueCheckLight");
+ this.level.getChunkSource().getLightEngine().checkBlock(pos);
+ profilerFiller.pop();
+@@ -573,11 +620,12 @@ public class LevelChunk extends ChunkAccess {
// CraftBukkit start
public void loadCallback() {
@@ -32126,7 +31626,7 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
if (server != null) {
/*
* If it's a new world, the first few chunks are generated inside
-@@ -645,6 +693,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -586,6 +634,7 @@ public class LevelChunk extends ChunkAccess {
*/
org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this);
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration));
@@ -32134,7 +31634,7 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
if (this.needsDecoration) {
this.needsDecoration = false;
-@@ -671,13 +720,15 @@ public class LevelChunk extends ChunkAccess {
+@@ -612,13 +661,15 @@ public class LevelChunk extends ChunkAccess {
}
public void unloadCallback() {
@@ -32152,7 +31652,7 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
// Paper start
this.loadedTicketLevel = false;
// Paper end
-@@ -685,8 +736,31 @@ public class LevelChunk extends ChunkAccess {
+@@ -626,8 +677,31 @@ public class LevelChunk extends ChunkAccess {
@Override
public boolean isUnsaved() {
@@ -32185,7 +31685,7 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
// CraftBukkit end
public boolean isEmpty() {
-@@ -794,6 +868,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -706,6 +780,7 @@ public class LevelChunk extends ChunkAccess {
this.pendingBlockEntities.clear();
this.upgradeData.upgrade(this);
@@ -32194,7 +31694,7 @@ index 0ade64bbdec563e555c981cee2208e6c72afe249..134d63076f231791988e67a5bdf19100
@Nullable
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
-index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef63cdb8511 100644
+index fc21c3268c4b4fda2933d71f0913db28e3796653..2ff691bcd32f587e8add2d8eda7e7339ccbde6e8 100644
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks;
@@ -32203,10 +31703,10 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
-public class LevelChunkSection {
+public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection { // Paper - block counting
-
public static final int SECTION_WIDTH = 16;
public static final int SECTION_HEIGHT = 16;
-@@ -25,6 +25,30 @@ public class LevelChunkSection {
+ public static final int SECTION_SIZE = 4096;
+@@ -24,6 +24,30 @@ public class LevelChunkSection {
public final PalettedContainer<BlockState> states;
private PalettedContainer<Holder<Biome>> biomes; // CraftBukkit - read/write
@@ -32237,7 +31737,7 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
private LevelChunkSection(LevelChunkSection section) {
this.nonEmptyBlockCount = section.nonEmptyBlockCount;
this.tickingBlockCount = section.tickingBlockCount;
-@@ -67,6 +91,45 @@ public class LevelChunkSection {
+@@ -69,6 +93,45 @@ public class LevelChunkSection {
return this.setBlockState(x, y, z, state, true);
}
@@ -32280,37 +31780,48 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
+ }
+ // Paper end - block counting
+
- public BlockState setBlockState(int x, int y, int z, BlockState state, boolean lock) {
- BlockState iblockdata1;
-
+ public BlockState setBlockState(int x, int y, int z, BlockState state, boolean useLocks) {
+ BlockState blockState;
+ if (useLocks) {
@@ -86,7 +149,7 @@ public class LevelChunkSection {
}
}
-- if (!fluid.isEmpty()) {
-+ if (!!fluid.isRandomlyTicking()) { // Paper - block counting
- --this.tickingFluidCount;
+- if (!fluidState.isEmpty()) {
++ if (!!fluidState.isRandomlyTicking()) { // Paper - block counting
+ this.tickingFluidCount--;
}
@@ -97,10 +160,12 @@ public class LevelChunkSection {
}
}
-- if (!fluid1.isEmpty()) {
-+ if (!!fluid1.isRandomlyTicking()) { // Paper - block counting
- ++this.tickingFluidCount;
+- if (!fluidState1.isEmpty()) {
++ if (!!fluidState1.isRandomlyTicking()) { // Paper - block counting
+ this.tickingFluidCount++;
}
-+ this.updateBlockCallback(x, y, z, state, iblockdata1); // Paper - block counting
++ this.updateBlockCallback(x, y, z, state, blockState); // Paper - block counting
+
- return iblockdata1;
+ return blockState;
}
-@@ -121,40 +186,70 @@ public class LevelChunkSection {
+@@ -121,35 +186,70 @@ public class LevelChunkSection {
}
public void recalcBlockCounts() {
-- class a implements PalettedContainer.CountConsumer<BlockState> {
+- class BlockCounter implements PalettedContainer.CountConsumer<BlockState> {
+- public int nonEmptyBlockCount;
+- public int tickingBlockCount;
+- public int tickingFluidCount;
+-
+- @Override
+- public void accept(BlockState state, int count) {
+- FluidState fluidState = state.getFluidState();
+- if (!state.isAir()) {
+- this.nonEmptyBlockCount += count;
+- if (state.isRandomlyTicking()) {
+- this.tickingBlockCount += count;
+ // Paper start - block counting
+ // reset, then recalculate
+ this.nonEmptyBlockCount = (short)0;
@@ -32338,13 +31849,9 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
+ final int paletteIdx = entry.getIntKey();
+ final it.unimi.dsi.fastutil.shorts.ShortArrayList coordinates = entry.getValue();
+ final int paletteCount = coordinates.size();
-
-- public int nonEmptyBlockCount;
-- public int tickingBlockCount;
-- public int tickingFluidCount;
++
+ final BlockState state = palette.valueFor(paletteIdx);
-
-- a(final LevelChunkSection chunksection) {}
++
+ if (state.isAir()) {
+ continue;
+ }
@@ -32359,49 +31866,43 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
+ final int rawLen = raw.length;
+
+ final ca.spottedleaf.moonrise.common.list.ShortList tickingBlocks = this.tickingBlocks;
-
-- public void accept(BlockState iblockdata, int i) {
-- FluidState fluid = iblockdata.getFluidState();
++
+ tickingBlocks.setMinCapacity(Math.min((rawLen + tickingBlocks.size()) * 3 / 2, 16*16*16));
-
-- if (!iblockdata.isAir()) {
-- this.nonEmptyBlockCount += i;
-- if (iblockdata.isRandomlyTicking()) {
-- this.tickingBlockCount += i;
++
+ java.util.Objects.checkFromToIndex(0, paletteCount, raw.length);
+ for (int i = 0; i < paletteCount; ++i) {
+ tickingBlocks.add(raw[i]);
}
}
+- if (!fluidState.isEmpty()) {
+- this.nonEmptyBlockCount += count;
+- if (fluidState.isRandomlyTicking()) {
+- this.tickingFluidCount += count;
+ final FluidState fluid = state.getFluidState();
+
- if (!fluid.isEmpty()) {
-- this.nonEmptyBlockCount += i;
++ if (!fluid.isEmpty()) {
+ //this.nonEmptyBlockCount += count; // fix vanilla bug: make non-empty block count correct
- if (fluid.isRandomlyTicking()) {
-- this.tickingFluidCount += i;
++ if (fluid.isRandomlyTicking()) {
+ this.tickingFluidCount += (short)paletteCount;
}
}
--
}
}
-
-- a a0 = new a(this);
--
-- this.states.count(a0);
-- this.nonEmptyBlockCount = (short) a0.nonEmptyBlockCount;
-- this.tickingBlockCount = (short) a0.tickingBlockCount;
-- this.tickingFluidCount = (short) a0.tickingFluidCount;
+- BlockCounter blockCounter = new BlockCounter();
+- this.states.count(blockCounter);
+- this.nonEmptyBlockCount = (short)blockCounter.nonEmptyBlockCount;
+- this.tickingBlockCount = (short)blockCounter.tickingBlockCount;
+- this.tickingFluidCount = (short)blockCounter.tickingFluidCount;
+ // Paper end - block counting
}
public PalettedContainer<BlockState> getStates() {
-@@ -172,6 +267,11 @@ public class LevelChunkSection {
-
- datapaletteblock.read(buf);
- this.biomes = datapaletteblock;
+@@ -166,6 +266,11 @@ public class LevelChunkSection {
+ PalettedContainer<Holder<Biome>> palettedContainer = this.biomes.recreate();
+ palettedContainer.read(buffer);
+ this.biomes = palettedContainer;
+ // Paper start - block counting
+ this.isClient = true;
+ // force has special colliding blocks to be true
@@ -32409,9 +31910,9 @@ index 3dab36d00ea48101807ba40c7a7358b7eed12747..e4ae25c83ab9dd1aaa530a5456275ef6
+ // Paper end - block counting
}
- public void readBiomes(FriendlyByteBuf buf) {
+ public void readBiomes(FriendlyByteBuf buffer) {
diff --git a/net/minecraft/world/level/chunk/LinearPalette.java b/net/minecraft/world/level/chunk/LinearPalette.java
-index bc4d9452bbeb05a691fd285603e49491f41d3ad2..f8d9892970c9092f7cc84434d4fbf34354ce1195 100644
+index 5ae2f38dc613ac6129af49084980d064f14ff153..2073f6ff41aa570102621d183ee890b076267d54 100644
--- a/net/minecraft/world/level/chunk/LinearPalette.java
+++ b/net/minecraft/world/level/chunk/LinearPalette.java
@@ -7,13 +7,20 @@ import net.minecraft.network.FriendlyByteBuf;
@@ -32433,11 +31934,11 @@ index bc4d9452bbeb05a691fd285603e49491f41d3ad2..f8d9892970c9092f7cc84434d4fbf343
+ }
+ // Paper end - optimise palette reads
+
- private LinearPalette(IdMap<T> idList, int bits, PaletteResize<T> listener, List<T> list) {
- this.registry = idList;
+ private LinearPalette(IdMap<T> registry, int bits, PaletteResize<T> resizeHandler, List<T> values) {
+ this.registry = registry;
this.values = (T[])(new Object[1 << bits]);
diff --git a/net/minecraft/world/level/chunk/Palette.java b/net/minecraft/world/level/chunk/Palette.java
-index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be2f08ecd1 100644
+index b4b973e453a093dcc04a6b7257883aa0065e2a89..a80b2e9dceea423180a9c390d1970317dff4f1b0 100644
--- a/net/minecraft/world/level/chunk/Palette.java
+++ b/net/minecraft/world/level/chunk/Palette.java
@@ -5,7 +5,7 @@ import java.util.function.Predicate;
@@ -32446,23 +31947,23 @@ index b8922e4a13df535cdc5701e893a6e460b33ff90d..100807f8b8337f56f49cdb818ccc75be
-public interface Palette<T> {
+public interface Palette<T> extends ca.spottedleaf.moonrise.patches.fast_palette.FastPalette<T> { // Paper - optimise palette reads
- int idFor(T object);
+ int idFor(T state);
- boolean maybeHas(Predicate<T> predicate);
+ boolean maybeHas(Predicate<T> filter);
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
-index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48a1cc6873 100644
+index a6028a54c75de068515e95913b21160ab4326985..f5da433050fd3060e0335d4002d520ebe8cd691f 100644
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
@@ -29,7 +29,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- private final PaletteResize<T> dummyPaletteResize = (newSize, added) -> 0;
+ private final PaletteResize<T> dummyPaletteResize = (bits, objectAdded) -> 0;
public final IdMap<T> registry;
private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values
- private volatile PalettedContainer.Data<T> data;
+ public volatile PalettedContainer.Data<T> data; // Paper - optimise collisions - public
private final PalettedContainer.Strategy strategy;
- // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
+ //private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
-@@ -77,6 +77,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+@@ -75,6 +75,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
);
}
@@ -32494,9 +31995,9 @@ index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48
+ // Paper end - optimise palette reads
+
// Paper start - Anti-Xray - Add preset values
- @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap<T> idList, PalettedContainer.Strategy paletteProvider, PalettedContainer.Configuration<T> dataProvider, BitStorage storage, List<T> paletteEntries) { this(idList, paletteProvider, dataProvider, storage, paletteEntries, null, null); }
- public PalettedContainer(
-@@ -113,6 +140,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ @Deprecated @io.papermc.paper.annotation.DoNotUse
+ public PalettedContainer(IdMap<T> registry, PalettedContainer.Strategy strategy, PalettedContainer.Configuration<T> configuration, BitStorage storage, List<T> values) {
+@@ -109,6 +136,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
}
// Paper end
@@ -32504,47 +32005,47 @@ index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48
}
// Paper start - Anti-Xray - Add preset values
-@@ -122,6 +150,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- this.registry = idList;
- this.strategy = paletteProvider;
+@@ -118,6 +146,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ this.registry = registry;
+ this.strategy = strategy;
this.data = data;
+ this.updateData(this.data); // Paper - optimise palette reads
}
- private PalettedContainer(PalettedContainer<T> container, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values
-@@ -140,6 +169,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- this.registry = idList;
+ private PalettedContainer(PalettedContainer<T> other, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values
+@@ -139,6 +168,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ this.registry = registry;
this.data = this.createOrReuseData(null, 0);
- this.data.palette.idFor(object);
+ this.data.palette.idFor(palette);
+ this.updateData(this.data); // Paper - optimise palette reads
}
- private PalettedContainer.Data<T> createOrReuseData(@Nullable PalettedContainer.Data<T> previousData, int bits) {
-@@ -166,6 +196,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- data2.copyFrom(data.palette, data.storage);
- this.data = data2;
+ private PalettedContainer.Data<T> createOrReuseData(@Nullable PalettedContainer.Data<T> data, int id) {
+@@ -163,6 +193,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ this.data = data1;
+ // Paper start - Anti-Xray
this.addPresetValues();
+ this.updateData(this.data); // Paper - optimise palette reads
- return object == null ? -1 : data2.palette.idFor(object);
- // Paper end
+ return objectAdded == null ? -1 : data1.palette.idFor(objectAdded);
}
-@@ -198,9 +229,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ private void addPresetValues() {
+@@ -192,9 +223,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
}
- private synchronized T getAndSet(int index, T value) { // Paper - synchronize
-- int i = this.data.palette.idFor(value);
-- int j = this.data.storage.getAndSet(index, i);
-- return this.data.palette.valueFor(j);
+ private T getAndSet(int index, T state) {
+- int i = this.data.palette.idFor(state);
+- int andSet = this.data.storage.getAndSet(index, i);
+- return this.data.palette.valueFor(andSet);
+ // Paper start - optimise palette reads
-+ final int paletteIdx = this.data.palette.idFor(value);
++ final int paletteIdx = this.data.palette.idFor(state);
+ final PalettedContainer.Data<T> data = this.data;
+ final int prev = data.storage.getAndSet(index, paletteIdx);
+ return this.readPalette(data, prev);
+ // Paper end - optimise palette reads
}
- public void set(int x, int y, int z, T value) {
-@@ -223,9 +257,11 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ public synchronized void set(int x, int y, int z, T state) { // Paper - synchronize
+@@ -217,9 +251,11 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
return this.get(this.strategy.getIndex(x, y, z));
}
@@ -32559,19 +32060,19 @@ index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48
}
@Override
-@@ -246,6 +282,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- buf.readLongArray(data.storage.getRaw());
+@@ -240,6 +276,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ buffer.readLongArray(data.storage.getRaw());
this.data = data;
this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server)
+ this.updateData(this.data); // Paper - optimise palette reads
} finally {
this.release();
}
-@@ -394,7 +431,44 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
- void accept(T object, int count);
+@@ -390,7 +427,44 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
+ void accept(T state, int count);
}
-- static record Data<T>(PalettedContainer.Configuration<T> configuration, BitStorage storage, Palette<T> palette) {
+- record Data<T>(PalettedContainer.Configuration<T> configuration, BitStorage storage, Palette<T> palette) {
+ // Paper start - optimise palette reads
+ public static final class Data<T> implements ca.spottedleaf.moonrise.patches.fast_palette.FastPaletteData<T> {
+
@@ -32610,24 +32111,24 @@ index 69d6f203366df658e1ade55d917f0aa2b8a49be9..8b84bf2272556ac3321cbf16361d7f48
+ }
+ // Paper end - optimise palette reads
+
- public void copyFrom(Palette<T> palette, BitStorage storage) {
- for (int i = 0; i < storage.getSize(); i++) {
- T object = palette.valueFor(storage.get(i));
+ public void copyFrom(Palette<T> palette, BitStorage bitStorage) {
+ for (int i = 0; i < bitStorage.getSize(); i++) {
+ T object = palette.valueFor(bitStorage.get(i));
diff --git a/net/minecraft/world/level/chunk/ProtoChunk.java b/net/minecraft/world/level/chunk/ProtoChunk.java
-index 15e14f5d006389c823fa6baf8c1a4f22804d4aa8..759adee51bad99bd4bbee4f44247e8c8486cfbd6 100644
+index 8c333d7f390d823a7c7f303e2f444f52ec16f799..e66239e2da91bd3ddf358d239be796719c0da327 100644
--- a/net/minecraft/world/level/chunk/ProtoChunk.java
+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
-@@ -149,7 +149,7 @@ public class ProtoChunk extends ChunkAccess {
+@@ -151,7 +151,7 @@ public class ProtoChunk extends ChunkAccess {
}
if (LightEngine.hasDifferentLightProperties(blockState, state)) {
-- this.skyLightSources.update(this, m, j, o);
+- this.skyLightSources.update(this, relativeBlockPosX, y, relativeBlockPosZ);
+ // Paper - rewrite chunk system
this.lightEngine.checkBlock(pos);
}
}
diff --git a/net/minecraft/world/level/chunk/SingleValuePalette.java b/net/minecraft/world/level/chunk/SingleValuePalette.java
-index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce7895529918073c 100644
+index bc84910dbc688331efaea76972a6625014ff76f5..2ffae24b0cb1a20c7d5a8520f1b5197c2cedea11 100644
--- a/net/minecraft/world/level/chunk/SingleValuePalette.java
+++ b/net/minecraft/world/level/chunk/SingleValuePalette.java
@@ -8,12 +8,24 @@ import net.minecraft.network.FriendlyByteBuf;
@@ -32653,16 +32154,16 @@ index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce789552
+ }
+ // Paper end - optimise palette reads
+
- public SingleValuePalette(IdMap<T> idList, PaletteResize<T> listener, List<T> entries) {
- this.registry = idList;
- this.resizeHandler = listener;
+ public SingleValuePalette(IdMap<T> registry, PaletteResize<T> resizeHandler, List<T> value) {
+ this.registry = registry;
+ this.resizeHandler = resizeHandler;
@@ -33,6 +45,11 @@ public class SingleValuePalette<T> implements Palette<T> {
- return this.resizeHandler.onResize(1, object);
+ return this.resizeHandler.onResize(1, state);
} else {
- this.value = object;
+ this.value = state;
+ // Paper start - optimise palette reads
+ if (this.rawPalette != null) {
-+ this.rawPalette[0] = object;
++ this.rawPalette[0] = state;
+ }
+ // Paper end - optimise palette reads
return 0;
@@ -32670,8 +32171,8 @@ index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce789552
}
@@ -58,6 +75,11 @@ public class SingleValuePalette<T> implements Palette<T> {
@Override
- public void read(FriendlyByteBuf buf) {
- this.value = this.registry.byIdOrThrow(buf.readVarInt());
+ public void read(FriendlyByteBuf buffer) {
+ this.value = this.registry.byIdOrThrow(buffer.readVarInt());
+ // Paper start - optimise palette reads
+ if (this.rawPalette != null) {
+ this.rawPalette[0] = this.value;
@@ -32681,7 +32182,7 @@ index a45e6410600afc5464e5d29932c193786ce0a6fb..a1ba68c95c2cdebdc0d7782cce789552
@Override
diff --git a/net/minecraft/world/level/chunk/status/ChunkPyramid.java b/net/minecraft/world/level/chunk/status/ChunkPyramid.java
-index b1058bf0dcda544a074f4d3772d7899b94f98927..b7bf82f6b6023bd628d3e7ea84d2d6755a0d931a 100644
+index 9c6f4aa173fa25f9c8a3852d91a4585e069236b6..b14001afe0bf841dac7d0a1d1568fd10f6086237 100644
--- a/net/minecraft/world/level/chunk/status/ChunkPyramid.java
+++ b/net/minecraft/world/level/chunk/status/ChunkPyramid.java
@@ -54,7 +54,7 @@ public record ChunkPyramid(ImmutableList<ChunkStep> steps) {
@@ -32694,7 +32195,7 @@ index b1058bf0dcda544a074f4d3772d7899b94f98927..b7bf82f6b6023bd628d3e7ea84d2d675
.step(ChunkStatus.FULL, builder -> builder.setTask(ChunkStatusTasks::full))
.build();
diff --git a/net/minecraft/world/level/chunk/status/ChunkStatus.java b/net/minecraft/world/level/chunk/status/ChunkStatus.java
-index 4f84ff9cdb3303251e035a12ce9d8b9a0b58f46e..d80b7d555e02d1d4b82945373d383eaedbf4b976 100644
+index 7a64b00ff31d1273d0b0b9a3cfd43808c88ef46a..c9d8a1c0a75c34ccd9f5cead02cccd776276f3cb 100644
--- a/net/minecraft/world/level/chunk/status/ChunkStatus.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStatus.java
@@ -11,7 +11,7 @@ import net.minecraft.resources.ResourceLocation;
@@ -32706,7 +32207,7 @@ index 4f84ff9cdb3303251e035a12ce9d8b9a0b58f46e..d80b7d555e02d1d4b82945373d383eae
public static final int MAX_STRUCTURE_DISTANCE = 8;
private static final EnumSet<Heightmap.Types> WORLDGEN_HEIGHTMAPS = EnumSet.of(Heightmap.Types.OCEAN_FLOOR_WG, Heightmap.Types.WORLD_SURFACE_WG);
public static final EnumSet<Heightmap.Types> FINAL_HEIGHTMAPS = EnumSet.of(
-@@ -51,8 +51,68 @@ public class ChunkStatus {
+@@ -51,8 +51,70 @@ public class ChunkStatus {
return list;
}
@@ -32764,50 +32265,52 @@ index 4f84ff9cdb3303251e035a12ce9d8b9a0b58f46e..d80b7d555e02d1d4b82945373d383eae
+ // Paper end - rewrite chunk system
+
@VisibleForTesting
- protected ChunkStatus(@Nullable ChunkStatus previous, EnumSet<Heightmap.Types> heightMapTypes, ChunkType chunkType) {
+ protected ChunkStatus(@Nullable ChunkStatus parent, EnumSet<Heightmap.Types> heightmapsAfter, ChunkType chunkType) {
++ // Paper start - rewrite chunk system
+ this.isParallelCapable = false;
+ this.writeRadius = -1;
+ this.nextStatus = (ChunkStatus)(Object)this;
-+ if (previous != null) {
-+ previous.nextStatus = (ChunkStatus)(Object)this;
++ if (parent != null) {
++ parent.nextStatus = (ChunkStatus)(Object)this;
+ }
+ this.warnedAboutNoImmediateComplete = new java.util.concurrent.atomic.AtomicBoolean();
- this.parent = previous == null ? this : previous;
++ // Paper end - rewrite chunk system
+ this.parent = parent == null ? this : parent;
this.chunkType = chunkType;
- this.heightmapsAfter = heightMapTypes;
+ this.heightmapsAfter = heightmapsAfter;
diff --git a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
-index 3d8a35d8cf29447ee7ac750dbc6ffcdb0f89b81b..9a3900e970f22892d8a3da8a28f922aa9b62765f 100644
+index c953bc93de8a42bcc12b7e8f46b3ae804e54964e..2ccbdfdcf81556306e098277ecf119d5fd02138c 100644
--- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
-@@ -152,7 +152,7 @@ public class ChunkStatusTasks {
- chunk1 = protochunkextension.getWrapped();
+@@ -182,7 +182,7 @@ public class ChunkStatusTasks {
+ if (protoChunk instanceof ImposterProtoChunk imposterProtoChunk) {
+ wrapped = imposterProtoChunk.getWrapped();
} else {
- chunk1 = new LevelChunk(worldserver, protochunk, ($) -> { // Paper - decompile fix
-- ChunkStatusTasks.postLoadProtoChunk(worldserver, protochunk.getEntities());
-+ ChunkStatusTasks.postLoadProtoChunk(worldserver, protochunk.getEntities(), protochunk.getPos()); // Paper - rewrite chunk system
- });
- generationchunkholder.replaceProtoChunk(new ImposterProtoChunk(chunk1, false));
+- wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities()));
++ wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities(), protoChunk.getPos())); // Paper - rewrite chunk system
+ generationChunkHolder.replaceProtoChunk(new ImposterProtoChunk(wrapped, false));
}
-@@ -168,7 +168,7 @@ public class ChunkStatusTasks {
- }, context.mainThreadExecutor());
+
+@@ -196,7 +196,7 @@ public class ChunkStatusTasks {
+ }, worldGenContext.mainThreadExecutor());
}
-- public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> entities) { // Paper - public
-+ public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> entities, ChunkPos pos) { // Paper - public // Paper - rewrite chunk system - add ChunkPos param
- if (!entities.isEmpty()) {
+- public static void postLoadProtoChunk(ServerLevel level, List<CompoundTag> entityTags) { // Paper - public
++ public static void postLoadProtoChunk(ServerLevel level, List<CompoundTag> entityTags, ChunkPos pos) { // Paper - public // Paper - rewrite chunk system - add ChunkPos param
+ if (!entityTags.isEmpty()) {
// CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
- world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> {
-@@ -180,7 +180,7 @@ public class ChunkStatusTasks {
+ level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD).filter((entity) -> {
+@@ -208,7 +208,7 @@ public class ChunkStatusTasks {
}
- checkDupeUUID(world, entity); // Paper - duplicate uuid resolving
+ checkDupeUUID(level, entity); // Paper - duplicate uuid resolving
return !needsRemoval;
- }));
+ }), pos); // Paper - rewrite chunk system
// CraftBukkit end
}
-
+ }
diff --git a/net/minecraft/world/level/chunk/status/ChunkStep.java b/net/minecraft/world/level/chunk/status/ChunkStep.java
-index 3d37a0372cdd99e806a9651cc1cabaefa9338065..f9aad1b8c02b70e620efdc2a58cadf4fff0f3ed5 100644
+index 7a4d299d2ce36982204e30de9278ddfd5b37c3df..b8348976e80578d9eff64eea68c04c603fed49ad 100644
--- a/net/minecraft/world/level/chunk/status/ChunkStep.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStep.java
@@ -11,9 +11,50 @@ import net.minecraft.util.profiling.jfr.callback.ProfiledDuration;
@@ -32864,7 +32367,7 @@ index 3d37a0372cdd99e806a9651cc1cabaefa9338065..f9aad1b8c02b70e620efdc2a58cadf4f
public int getAccumulatedRadiusOf(ChunkStatus status) {
return status == this.targetStatus ? 0 : this.accumulatedDependencies.getRadiusOf(status);
}
-@@ -39,6 +80,56 @@ public record ChunkStep(
+@@ -40,6 +81,56 @@ public record ChunkStep(
return chunk;
}
@@ -32922,16 +32425,15 @@ index 3d37a0372cdd99e806a9651cc1cabaefa9338065..f9aad1b8c02b70e620efdc2a58cadf4f
private final ChunkStatus status;
@Nullable
diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
-index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a067109819f 100644
+index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1c3b75ba6 100644
--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java
+++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
-@@ -28,21 +28,31 @@ import net.minecraft.world.level.dimension.LevelStem;
+@@ -22,20 +22,30 @@ import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler;
import net.minecraft.world.level.storage.DimensionDataStorage;
-public class ChunkStorage implements AutoCloseable {
+public class ChunkStorage implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkStorage { // Paper - rewrite chunk system
-
public static final int LAST_MONOLYTH_STRUCTURE_DATA_VERSION = 1493;
- private final IOWorker worker;
+ // Paper - rewrite chunk system
@@ -32949,29 +32451,29 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a06
+ }
+ // Paper end - rewrite chunk system
+
- public ChunkStorage(RegionStorageInfo storageKey, Path directory, DataFixer dataFixer, boolean dsync) {
- this.fixerUpper = dataFixer;
-- this.worker = new IOWorker(storageKey, directory, dsync);
-+ this.storage = new IOWorker(storageKey, directory, dsync).storage; // Paper - rewrite chunk system
+ public ChunkStorage(RegionStorageInfo info, Path folder, DataFixer fixerUpper, boolean sync) {
+ this.fixerUpper = fixerUpper;
+- this.worker = new IOWorker(info, folder, sync);
++ this.storage = new IOWorker(info, folder, sync).storage; // Paper - rewrite chunk system
}
- public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) {
-- return this.worker.isOldChunkAround(chunkPos, checkRadius);
+ public boolean isOldChunkAround(ChunkPos pos, int radius) {
+- return this.worker.isOldChunkAround(pos, radius);
+ return true; // Paper - rewrite chunk system
}
// CraftBukkit start
-@@ -102,7 +112,9 @@ public class ChunkStorage implements AutoCloseable {
- if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
- LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier);
-
-+ synchronized (persistentstructurelegacy) { // Paper - rewrite chunk system
- nbttagcompound = persistentstructurelegacy.updateFromLegacy(nbttagcompound);
-+ } // Paper - rewrite chunk system
+@@ -99,7 +109,9 @@ public class ChunkStorage implements AutoCloseable {
+ chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter
+ if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) {
+ LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage);
++ synchronized (legacyStructureHandler) { // Paper - rewrite chunk system
+ chunkData = legacyStructureHandler.updateFromLegacy(chunkData);
++ }
}
}
-@@ -169,7 +181,13 @@ public class ChunkStorage implements AutoCloseable {
+@@ -163,7 +175,13 @@ public class ChunkStorage implements AutoCloseable {
}
public CompletableFuture<Optional<CompoundTag>> read(ChunkPos chunkPos) {
@@ -32985,15 +32487,15 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a06
+ // Paper end - rewrite chunk system
}
- public CompletableFuture<Void> write(ChunkPos chunkPos, Supplier<CompoundTag> nbtSupplier) {
-@@ -185,29 +203,54 @@ public class ChunkStorage implements AutoCloseable {
+ public CompletableFuture<Void> write(ChunkPos pos, Supplier<CompoundTag> tagSupplier) {
+@@ -179,29 +197,54 @@ public class ChunkStorage implements AutoCloseable {
};
// Paper end - guard against possible chunk pos desync
- this.handleLegacyStructureIndex(chunkPos);
-- return this.worker.store(chunkPos, guardedPosCheck); // Paper - guard against possible chunk pos desync
+ this.handleLegacyStructureIndex(pos);
+- return this.worker.store(pos, guardedPosCheck); // Paper - guard against possible chunk pos desync
+ // Paper start - rewrite chunk system
+ try {
-+ this.storage.write(chunkPos, guardedPosCheck.get());
++ this.storage.write(pos, guardedPosCheck.get());
+ return CompletableFuture.completedFuture(null);
+ } catch (final Throwable throwable) {
+ return CompletableFuture.failedFuture(throwable);
@@ -33007,7 +32509,6 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a06
this.legacyStructureHandler.removeIndex(chunkPos.toLong());
+ } // Paper - rewrite chunk system
}
-
}
public void flushWorker() {
@@ -33021,6 +32522,7 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a06
+ // Paper end - rewrite chunk system
}
+ @Override
public void close() throws IOException {
- this.worker.close();
+ this.storage.close(); // Paper - rewrite chunk system
@@ -33048,26 +32550,26 @@ index 092f7b6bba4e1291f76c2c09155f33803e93eb04..46f4b6706a1ca24ff6fc28960ad01a06
}
}
diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java
-index a0cbccd2cf1ac785745d86c42b6f58fb8bad7ffa..16ca1c8672e5f0a27f8a30498c754a81cdec5191 100644
+index c3c9771138cb1712ea429d8c45596220830314eb..da05fb780c55381a7a08ced51d01764a645740b2 100644
--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
@@ -71,12 +71,12 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
}
}
-- private static ChunkPos readChunkPos(CompoundTag chunkNbt) {
-+ public static ChunkPos readChunkPos(CompoundTag chunkNbt) { // Paper - public
- int[] is = chunkNbt.getIntArray("Position");
- return new ChunkPos(is[0], is[1]);
+- private static ChunkPos readChunkPos(CompoundTag tag) {
++ public static ChunkPos readChunkPos(CompoundTag tag) { // Paper - public
+ int[] intArray = tag.getIntArray("Position");
+ return new ChunkPos(intArray[0], intArray[1]);
}
-- private static void writeChunkPos(CompoundTag chunkNbt, ChunkPos pos) {
-+ public static void writeChunkPos(CompoundTag chunkNbt, ChunkPos pos) { // Paper - public
- chunkNbt.put("Position", new IntArrayTag(new int[]{pos.x, pos.z}));
+- private static void writeChunkPos(CompoundTag tag, ChunkPos pos) {
++ public static void writeChunkPos(CompoundTag tag, ChunkPos pos) { // Paper - public
+ tag.put("Position", new IntArrayTag(new int[]{pos.x, pos.z}));
}
diff --git a/net/minecraft/world/level/chunk/storage/IOWorker.java b/net/minecraft/world/level/chunk/storage/IOWorker.java
-index 1f2997cf5367200084f32c437f77040c8c6a18e6..a8a9e59a9721a76e34f78c1baa5026e5fe1d2bda 100644
+index 889e188e920edb284f04b264bcdd06146f54a4cb..2199a9e2a0141c646d108f2687a27f1d165453c5 100644
--- a/net/minecraft/world/level/chunk/storage/IOWorker.java
+++ b/net/minecraft/world/level/chunk/storage/IOWorker.java
@@ -30,7 +30,7 @@ public class IOWorker implements ChunkScanAccess, AutoCloseable {
@@ -33080,21 +32582,21 @@ index 1f2997cf5367200084f32c437f77040c8c6a18e6..a8a9e59a9721a76e34f78c1baa5026e5
private final Long2ObjectLinkedOpenHashMap<CompletableFuture<BitSet>> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>();
private static final int REGION_CACHE_SIZE = 1024;
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
-index 863960ead8deaa0553be1c98e4fa09f07fcb8ef0..057875cbbdc92ba49b429f9a129514760edb32a2 100644
+index 7491644233d52dc56d83de5ad3373f6a9a455378..b76f0fcecd3de1e7a802a6006c8851d94ba35329 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
-@@ -28,7 +28,7 @@ import net.minecraft.nbt.NbtIo; // Paper
+@@ -23,7 +23,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler;
import net.minecraft.world.level.ChunkPos;
import org.slf4j.Logger;
-public class RegionFile implements AutoCloseable {
+public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system
-
private static final Logger LOGGER = LogUtils.getLogger();
private static final int SECTOR_BYTES = 4096;
-@@ -52,6 +52,21 @@ public class RegionFile implements AutoCloseable {
@VisibleForTesting
- protected final RegionBitmap usedSectors;
+@@ -46,6 +46,21 @@ public class RegionFile implements AutoCloseable {
+ @VisibleForTesting
+ protected final RegionBitmap usedSectors = new RegionBitmap();
+ // Paper start - rewrite chunk system
+ @Override
@@ -33111,33 +32613,32 @@ index 863960ead8deaa0553be1c98e4fa09f07fcb8ef0..057875cbbdc92ba49b429f9a12951476
+ }
+ // Paper end - rewrite chunk system
+
- public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException {
- this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format
+ public RegionFile(RegionStorageInfo info, Path path, Path externalFileDir, boolean sync) throws IOException {
+ this(info, path, externalFileDir, RegionFileVersion.getCompressionFormat(), sync); // Paper - Configurable region compression format
}
-@@ -224,6 +239,16 @@ public class RegionFile implements AutoCloseable {
+@@ -205,6 +220,16 @@ public class RegionFile implements AutoCloseable {
@Nullable
- private DataInputStream createExternalChunkInputStream(ChunkPos pos, byte flags) throws IOException {
+ private DataInputStream createExternalChunkInputStream(ChunkPos chunkPos, byte versionByte) throws IOException {
+ // Paper start - rewrite chunk system
-+ final DataInputStream is = this.createExternalChunkInputStream0(pos, flags);
++ final DataInputStream is = this.createExternalChunkInputStream0(chunkPos, versionByte);
+ if (is == null) {
+ return is;
+ }
+ return new ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker(is);
+ }
+ @Nullable
-+ private DataInputStream createExternalChunkInputStream0(ChunkPos pos, byte flags) throws IOException {
++ private DataInputStream createExternalChunkInputStream0(ChunkPos chunkPos, byte versionByte) throws IOException {
+ // Paper end - rewrite chunk system
- Path path = this.getExternalChunkPath(pos);
-
- if (!Files.isRegularFile(path, new LinkOption[0])) {
-@@ -514,10 +539,29 @@ public class RegionFile implements AutoCloseable {
-
+ Path externalChunkPath = this.getExternalChunkPath(chunkPos);
+ if (!Files.isRegularFile(externalChunkPath)) {
+ LOGGER.error("External chunk path {} is not file", externalChunkPath);
+@@ -399,9 +424,28 @@ public class RegionFile implements AutoCloseable {
+ }
}
- // Paper end
-- private class ChunkBuffer extends ByteArrayOutputStream {
-+ private class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system
+- class ChunkBuffer extends ByteArrayOutputStream {
++ class ChunkBuffer extends ByteArrayOutputStream implements ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemChunkBuffer { // Paper - rewrite chunk system
private final ChunkPos pos;
+ // Paper start - rewrite chunk system
@@ -33159,36 +32660,36 @@ index 863960ead8deaa0553be1c98e4fa09f07fcb8ef0..057875cbbdc92ba49b429f9a12951476
+ }
+ // Paper end - rewrite chunk system
+
- public ChunkBuffer(final ChunkPos chunkcoordintpair) {
+ public ChunkBuffer(final ChunkPos pos) {
super(8096);
super.write(0);
-@@ -534,7 +578,7 @@ public class RegionFile implements AutoCloseable {
-
+@@ -418,7 +462,7 @@ public class RegionFile implements AutoCloseable {
+ int i = this.count - 5 + 1;
JvmProfiler.INSTANCE.onRegionFileWrite(RegionFile.this.info, this.pos, RegionFile.this.version, i);
- bytebuffer.putInt(0, i);
-- RegionFile.this.write(this.pos, bytebuffer);
-+ if (this.writeOnClose) { RegionFile.this.write(this.pos, bytebuffer); } // Paper - rewrite chunk system
+ byteBuffer.putInt(0, i);
+- RegionFile.this.write(this.pos, byteBuffer);
++ if (this.writeOnClose) { RegionFile.this.write(this.pos, byteBuffer); } // Paper - rewrite chunk system
}
}
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3306a32e3 100644
+index 51bf310423013d0ae9d3202d66e36a053a767197..2661a21703994a18c4a9a44fba0f6931fd37151e 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-@@ -17,7 +17,7 @@ import net.minecraft.nbt.StreamTagVisitor;
+@@ -14,7 +14,7 @@ import net.minecraft.nbt.StreamTagVisitor;
import net.minecraft.util.ExceptionCollector;
import net.minecraft.world.level.ChunkPos;
-public final class RegionFileStorage implements AutoCloseable {
-+public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage { // Paper - rewrite chunk system
-
++public final class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.io.ChunkSystemRegionFileStorage { // Paper - rewrite chunk system
public static final String ANVIL_EXTENSION = ".mca";
private static final int MAX_CACHE_SIZE = 256;
-@@ -26,33 +26,219 @@ public final class RegionFileStorage implements AutoCloseable {
+ public final Long2ObjectLinkedOpenHashMap<RegionFile> regionCache = new Long2ObjectLinkedOpenHashMap<>();
+@@ -22,29 +22,218 @@ public final class RegionFileStorage implements AutoCloseable {
private final Path folder;
private final boolean sync;
-- RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) {
+- RegionFileStorage(RegionStorageInfo info, Path folder, boolean sync) {
+ // Paper start - rewrite chunk system
+ private static final int REGION_SHIFT = 5;
+ private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
@@ -33359,34 +32860,31 @@ index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3
+ }
+ }
+ // Paper end - rewrite chunk system
-+
-+ protected RegionFileStorage(RegionStorageInfo storageKey, Path directory, boolean dsync) { // Paper - protected
- this.folder = directory;
- this.sync = dsync;
- this.info = storageKey;
- }
-
-- private RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
-- long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
-- RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i);
+ // Paper start - rewrite chunk system
+ public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException {
+ return this.getRegionFile(chunkcoordintpair, false);
+ }
+ // Paper end - rewrite chunk system
++
++ protected RegionFileStorage(RegionStorageInfo info, Path folder, boolean sync) { // Paper - protected
+ this.folder = folder;
+ this.sync = sync;
+ this.info = info;
+ }
-- if (regionfile != null) {
-- return regionfile;
+ @org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
+- long packedChunkPos = ChunkPos.asLong(chunkPos.getRegionX(), chunkPos.getRegionZ());
+- RegionFile regionFile = this.regionCache.getAndMoveToFirst(packedChunkPos);
+- if (regionFile != null) {
+- return regionFile;
- } else {
- if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable
-- ((RegionFile) this.regionCache.removeLast()).close();
-+ public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public
+ // Paper start - rewrite chunk system
+ if (existingOnly) {
-+ return this.moonrise$getRegionFileIfExists(chunkcoordintpair.x, chunkcoordintpair.z);
++ return this.moonrise$getRegionFileIfExists(chunkPos.x, chunkPos.z);
+ }
+ synchronized (this) {
-+ final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT);
++ final long key = ChunkPos.asLong(chunkPos.x >> REGION_SHIFT, chunkPos.z >> REGION_SHIFT);
+
+ RegionFile ret = this.regionCache.getAndMoveToFirst(key);
+ if (ret != null) {
@@ -33394,22 +32892,20 @@ index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3
+ }
+
+ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper
-+ this.regionCache.removeLast().close();
+ this.regionCache.removeLast().close();
}
-+ final Path regionPath = this.folder.resolve(getRegionFileName(chunkcoordintpair.x, chunkcoordintpair.z));
++ final Path regionPath = this.folder.resolve(getRegionFileName(chunkPos.x, chunkPos.z));
+
+ this.createRegionFile(key);
+
FileUtil.createDirectoriesSafe(this.folder);
-- Path path = this.folder;
-- int j = chunkcoordintpair.getRegionX();
-- Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca");
-- if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit
-- RegionFile regionfile1 = new RegionFile(this.info, path1, this.folder, this.sync);
-
-- this.regionCache.putAndMoveToFirst(i, regionfile1);
-- return regionfile1;
+- Path path = this.folder.resolve("r." + chunkPos.getRegionX() + "." + chunkPos.getRegionZ() + ".mca");
+- if (existingOnly && !java.nio.file.Files.exists(path)) return null; // CraftBukkit
+- RegionFile regionFile1 = new RegionFile(this.info, path, this.folder, this.sync);
+- this.regionCache.putAndMoveToFirst(packedChunkPos, regionFile1);
+- return regionFile1;
++
+ ret = new RegionFile(this.info, regionPath, this.folder, this.sync);
+
+ this.regionCache.putAndMoveToFirst(key, ret);
@@ -33420,37 +32916,34 @@ index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3
}
// Paper start
-@@ -175,8 +361,14 @@ public final class RegionFileStorage implements AutoCloseable {
-
+@@ -126,8 +315,14 @@ public final class RegionFileStorage implements AutoCloseable {
+ }
}
-- protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
-- RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
-+ public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - rewrite chunk system - public
-+ RegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system
+- protected void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException {
+- RegionFile regionFile = this.getRegionFile(chunkPos, false); // CraftBukkit
++ public void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException { // Paper - rewrite chunk system - public
++ RegionFile regionFile = this.getRegionFile(chunkPos, chunkData == null); // CraftBukkit // Paper - rewrite chunk system
+ // Paper start - rewrite chunk system
-+ if (regionfile == null) {
++ if (regionFile == null) {
+ // if the RegionFile doesn't exist, no point in deleting from it
+ return;
+ }
+ // Paper end - rewrite chunk system
+ if (chunkData == null) {
+ regionFile.clear(chunkPos);
+ } else {
+@@ -140,23 +335,36 @@ public final class RegionFileStorage implements AutoCloseable {
- if (nbt == null) {
- regionfile.clear(pos);
-@@ -206,30 +398,37 @@ public final class RegionFileStorage implements AutoCloseable {
- }
-
+ @Override
public void close() throws IOException {
-- ExceptionCollector<IOException> exceptionsuppressor = new ExceptionCollector<>();
-- ObjectIterator objectiterator = this.regionCache.values().iterator();
--
-- while (objectiterator.hasNext()) {
-- RegionFile regionfile = (RegionFile) objectiterator.next();
+- ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
-
+- for (RegionFile regionFile : this.regionCache.values()) {
- try {
-- regionfile.close();
-- } catch (IOException ioexception) {
-- exceptionsuppressor.add(ioexception);
+- regionFile.close();
+- } catch (IOException var5) {
+- exceptionCollector.add(var5);
+ // Paper start - rewrite chunk system
+ synchronized (this) {
+ final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
@@ -33461,19 +32954,16 @@ index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3
+ exceptionCollector.add(ex);
+ }
}
-- }
-
-- exceptionsuppressor.throwIfPresent();
+ exceptionCollector.throwIfPresent();
-+ }
+ }
+-
+- exceptionCollector.throwIfPresent();
+ // Paper end - rewrite chunk system
}
public void flush() throws IOException {
-- ObjectIterator objectiterator = this.regionCache.values().iterator();
--
-- while (objectiterator.hasNext()) {
-- RegionFile regionfile = (RegionFile) objectiterator.next();
+- for (RegionFile regionFile : this.regionCache.values()) {
+- regionFile.flush();
+ // Paper start - rewrite chunk system
+ synchronized (this) {
+ final ExceptionCollector<IOException> exceptionCollector = new ExceptionCollector<>();
@@ -33484,16 +32974,15 @@ index e6abe35d6c43b7f76cf3da129ec9552e7b82453e..fdf8e18d24442178b52397acb482ffa3
+ exceptionCollector.add(ex);
+ }
+ }
-
-- regionfile.flush();
++
+ exceptionCollector.throwIfPresent();
}
+ // Paper end - rewrite chunk system
-
}
+ public RegionStorageInfo info() {
diff --git a/net/minecraft/world/level/chunk/storage/SectionStorage.java b/net/minecraft/world/level/chunk/storage/SectionStorage.java
-index 75b2cf0e13c23a8348b7ff55e72e5ee755aa7460..c3beb7fcad46a917d2b61bd0a0e98e5106056728 100644
+index 7dc1ffffd9d0fec54dbc254c154ee85ee750174d..778bd73a938c94ecb85ca0f8b686ff4e1baee040 100644
--- a/net/minecraft/world/level/chunk/storage/SectionStorage.java
+++ b/net/minecraft/world/level/chunk/storage/SectionStorage.java
@@ -40,10 +40,10 @@ import net.minecraft.world.level.ChunkPos;
@@ -33526,26 +33015,26 @@ index 75b2cf0e13c23a8348b7ff55e72e5ee755aa7460..c3beb7fcad46a917d2b61bd0a0e98e51
+ // Paper end - rewrite chunk system
+
public SectionStorage(
- SimpleRegionStorage storageAccess,
+ SimpleRegionStorage simpleRegionStorage,
Codec<P> codec,
@@ -67,7 +79,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
- ChunkIOErrorReporter errorHandler,
- LevelHeightAccessor world
+ ChunkIOErrorReporter errorReporter,
+ LevelHeightAccessor levelHeightAccessor
) {
-- this.simpleRegionStorage = storageAccess;
+- this.simpleRegionStorage = simpleRegionStorage;
+ // Paper - rewrite chunk system
this.codec = codec;
- this.packer = serializer;
- this.unpacker = deserializer;
+ this.packer = packer;
+ this.unpacker = unpacker;
@@ -75,6 +87,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
- this.registryAccess = registryManager;
- this.errorReporter = errorHandler;
- this.levelHeightAccessor = world;
-+ this.regionStorage = storageAccess.worker.storage; // Paper - rewrite chunk system
+ this.registryAccess = registryAccess;
+ this.errorReporter = errorReporter;
+ this.levelHeightAccessor = levelHeightAccessor;
++ this.regionStorage = simpleRegionStorage.worker.storage; // Paper - rewrite chunk system
}
- protected void tick(BooleanSupplier shouldKeepTicking) {
-@@ -188,64 +201,15 @@ public class SectionStorage<R, P> implements AutoCloseable {
+ protected void tick(BooleanSupplier aheadOfTime) {
+@@ -188,65 +201,15 @@ public class SectionStorage<R, P> implements AutoCloseable {
}
private CompletableFuture<Optional<SectionStorage.PackedChunk<P>>> tryRead(ChunkPos chunkPos) {
@@ -33553,43 +33042,44 @@ index 75b2cf0e13c23a8348b7ff55e72e5ee755aa7460..c3beb7fcad46a917d2b61bd0a0e98e51
- return this.simpleRegionStorage
- .read(chunkPos)
- .thenApplyAsync(
-- chunkNbt -> chunkNbt.map(
-- nbt -> SectionStorage.PackedChunk.parse(this.codec, registryOps, nbt, this.simpleRegionStorage, this.levelHeightAccessor)
-- ),
+- optional -> optional.map(
+- compoundTag -> SectionStorage.PackedChunk.parse(this.codec, registryOps, compoundTag, this.simpleRegionStorage, this.levelHeightAccessor)
+- ),
- Util.backgroundExecutor().forName("parseSection")
- )
-- .exceptionally(throwable -> {
-- if (throwable instanceof CompletionException) {
-- throwable = throwable.getCause();
+- .exceptionally(cause -> {
+- if (cause instanceof CompletionException) {
+- cause = cause.getCause();
- }
-
-- if (throwable instanceof IOException iOException) {
-- LOGGER.error("Error reading chunk {} data from disk", chunkPos, iOException);
-- this.errorReporter.reportChunkLoadFailure(iOException, this.simpleRegionStorage.storageInfo(), chunkPos);
+- if (cause instanceof IOException ioException) {
+- LOGGER.error("Error reading chunk {} data from disk", chunkPos, ioException);
+- this.errorReporter.reportChunkLoadFailure(ioException, this.simpleRegionStorage.storageInfo(), chunkPos);
- return Optional.empty();
- } else {
-- throw new CompletionException(throwable);
+- throw new CompletionException(cause);
- }
- });
+ throw new IllegalStateException("Only chunk system can write state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system
}
- private void unpackChunk(ChunkPos chunkPos, @Nullable SectionStorage.PackedChunk<P> result) {
-- if (result == null) {
-- for (int i = this.levelHeightAccessor.getMinSectionY(); i <= this.levelHeightAccessor.getMaxSectionY(); i++) {
-- this.storage.put(getKey(chunkPos, i), Optional.empty());
+ private void unpackChunk(ChunkPos pos, @Nullable SectionStorage.PackedChunk<P> packedChunk) {
+- if (packedChunk == null) {
+- for (int sectionY = this.levelHeightAccessor.getMinSectionY(); sectionY <= this.levelHeightAccessor.getMaxSectionY(); sectionY++) {
+- this.storage.put(getKey(pos, sectionY), Optional.empty());
- }
- } else {
-- boolean bl = result.versionChanged();
+- boolean versionChanged = packedChunk.versionChanged();
-
-- for (int j = this.levelHeightAccessor.getMinSectionY(); j <= this.levelHeightAccessor.getMaxSectionY(); j++) {
-- long l = getKey(chunkPos, j);
-- Optional<R> optional = Optional.ofNullable(result.sectionsByY.get(j)).map(section -> this.unpacker.apply((P)section, () -> this.setDirty(l)));
-- this.storage.put(l, optional);
+- for (int sectionY1 = this.levelHeightAccessor.getMinSectionY(); sectionY1 <= this.levelHeightAccessor.getMaxSectionY(); sectionY1++) {
+- long key = getKey(pos, sectionY1);
+- Optional<R> optional = Optional.ofNullable(packedChunk.sectionsByY.get(sectionY1))
+- .map(object -> this.unpacker.apply((P)object, () -> this.setDirty(key)));
+- this.storage.put(key, optional);
- optional.ifPresent(object -> {
-- this.onSectionLoad(l);
-- if (bl) {
-- this.setDirty(l);
+- this.onSectionLoad(key);
+- if (versionChanged) {
+- this.setDirty(key);
- }
- });
- }
@@ -33612,17 +33102,17 @@ index 75b2cf0e13c23a8348b7ff55e72e5ee755aa7460..c3beb7fcad46a917d2b61bd0a0e98e51
+ throw new IllegalStateException("Only chunk system can write state, offending class:" + this.getClass().getName()); // Paper - rewrite chunk system
}
- private <T> Dynamic<T> writeChunk(ChunkPos chunkPos, DynamicOps<T> ops) {
-@@ -281,7 +245,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
- protected void onSectionLoad(long pos) {
+ private <T> Dynamic<T> writeChunk(ChunkPos pos, DynamicOps<T> ops) {
+@@ -282,7 +245,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
+ protected void onSectionLoad(long sectionKey) {
}
-- protected void setDirty(long pos) {
-+ public void setDirty(long pos) { // Paper - public
- Optional<R> optional = this.storage.get(pos);
+- protected void setDirty(long sectionPos) {
++ public void setDirty(long sectionPos) { // Paper - public
+ Optional<R> optional = this.storage.get(sectionPos);
if (optional != null && !optional.isEmpty()) {
- this.dirtyChunks.add(ChunkPos.asLong(SectionPos.x(pos), SectionPos.z(pos)));
-@@ -302,7 +266,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
+ this.dirtyChunks.add(ChunkPos.asLong(SectionPos.x(sectionPos), SectionPos.z(sectionPos)));
+@@ -303,7 +266,7 @@ public class SectionStorage<R, P> implements AutoCloseable {
@Override
public void close() throws IOException {
@@ -33630,27 +33120,27 @@ index 75b2cf0e13c23a8348b7ff55e72e5ee755aa7460..c3beb7fcad46a917d2b61bd0a0e98e51
+ this.moonrise$close(); // Paper - rewrite chunk system
}
- static record PackedChunk<T>(Int2ObjectMap<T> sectionsByY, boolean versionChanged) {
+ record PackedChunk<T>(Int2ObjectMap<T> sectionsByY, boolean versionChanged) {
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
-index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77fab826cd7 100644
+index cf6e2053d81f7b0f8c8e58b9c0fad3285ebc047d..e8aafbd4bd9eaba4aaa448333b37c30a8dd719bf 100644
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
-@@ -129,7 +129,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- long j = nbt.getLong("InhabitedTime");
- ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getString("Status"));
- UpgradeData chunkconverter = nbt.contains("UpgradeData", 10) ? new UpgradeData(nbt.getCompound("UpgradeData"), world) : UpgradeData.EMPTY;
-- boolean flag = nbt.getBoolean("isLightOn");
-+ boolean flag = chunkstatus.isOrAfter(ChunkStatus.LIGHT) && (nbt.get("isLightOn") != null && nbt.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG) == ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION); // Paper - starlight
- DataResult dataresult;
- Logger logger;
- BlendingData.Packed blendingdata_d;
-@@ -246,7 +246,17 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- DataLayer nibblearray = nbttagcompound3.contains("BlockLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("BlockLight")) : null;
- DataLayer nibblearray1 = nbttagcompound3.contains("SkyLight", 7) ? new DataLayer(nbttagcompound3.getByteArray("SkyLight")) : null;
-
-- list4.add(new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1));
+@@ -148,7 +148,7 @@ public record SerializableChunkData(
+ UpgradeData upgradeData = tag.contains("UpgradeData", 10)
+ ? new UpgradeData(tag.getCompound("UpgradeData"), levelHeightAccessor)
+ : UpgradeData.EMPTY;
+- boolean _boolean = tag.getBoolean("isLightOn");
++ boolean _boolean = chunkstatus.isOrAfter(ChunkStatus.LIGHT) && (nbt.get("isLightOn") != null && nbt.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG) == ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION); // Paper - starlight
+ BlendingData.Packed packed;
+ if (tag.contains("blending_data", 10)) {
+ packed = BlendingData.Packed.CODEC.parse(NbtOps.INSTANCE, tag.getCompound("blending_data")).resultOrPartial(LOGGER::error).orElse(null);
+@@ -249,7 +249,17 @@ public record SerializableChunkData(
+
+ DataLayer dataLayer = compound2.contains("BlockLight", 7) ? new DataLayer(compound2.getByteArray("BlockLight")) : null;
+ DataLayer dataLayer1 = compound2.contains("SkyLight", 7) ? new DataLayer(compound2.getByteArray("SkyLight")) : null;
+- list8.add(new SerializableChunkData.SectionData(_byte, levelChunkSection, dataLayer, dataLayer1));
+ // Paper start - starlight
-+ SerializableChunkData.SectionData serializableChunkData = new SerializableChunkData.SectionData(b0, chunksection, nibblearray, nibblearray1);
++ SerializableChunkData.SectionData serializableChunkData = new SerializableChunkData.SectionData(_byte, levelChunkSection, dataLayer, dataLayer1);
+ if (sectionData.contains(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.BLOCKLIGHT_STATE_TAG, Tag.TAG_ANY_NUMERIC)) {
+ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)serializableChunkData).starlight$setBlockLightState(sectionData.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.BLOCKLIGHT_STATE_TAG));
+ }
@@ -33658,12 +33148,12 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+ if (sectionData.contains(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.SKYLIGHT_STATE_TAG, Tag.TAG_ANY_NUMERIC)) {
+ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)serializableChunkData).starlight$setSkyLightState(sectionData.getInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.SKYLIGHT_STATE_TAG));
+ }
-+ list4.add(serializableChunkData);
++ list8.add(serializableChunkData);
+ // Paper end - starlight
}
- // CraftBukkit - ChunkBukkitValues
-@@ -254,6 +264,59 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
+ return new SerializableChunkData(
+@@ -276,6 +286,59 @@ public record SerializableChunkData(
}
}
@@ -33720,56 +33210,59 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+ }
+ // Paper end - starlight
+
- public ProtoChunk read(ServerLevel world, PoiManager poiStorage, RegionStorageInfo key, ChunkPos expectedPos) {
- if (!Objects.equals(expectedPos, this.chunkPos)) {
- SerializableChunkData.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{expectedPos, expectedPos, this.chunkPos});
-@@ -275,7 +338,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
-
- if (serializablechunkdata_b.chunkSection != null) {
- achunksection[world.getSectionIndexFromSectionY(serializablechunkdata_b.y)] = serializablechunkdata_b.chunkSection;
-- poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection);
-+ //poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); // Paper - rewrite chunk system
+ public ProtoChunk read(ServerLevel level, PoiManager poiManager, RegionStorageInfo regionStorageInfo, ChunkPos pos) {
+ if (!Objects.equals(pos, this.chunkPos)) {
+ LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", pos, pos, this.chunkPos);
+@@ -294,7 +357,7 @@ public record SerializableChunkData(
+ SectionPos sectionPos = SectionPos.of(pos, sectionData.y);
+ if (sectionData.chunkSection != null) {
+ levelChunkSections[level.getSectionIndexFromSectionY(sectionData.y)] = sectionData.chunkSection;
+- poiManager.checkConsistencyWithBlocks(sectionPos, sectionData.chunkSection);
++ //poiManager.checkConsistencyWithBlocks(sectionPos, sectionData.chunkSection); // Paper - rewrite chunk system
}
- boolean flag2 = serializablechunkdata_b.blockLight != null;
-@@ -352,7 +415,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
+ boolean flag1 = sectionData.blockLight != null;
+@@ -376,7 +439,7 @@ public record SerializableChunkData(
}
- if (chunktype == ChunkType.LEVELCHUNK) {
-- return new ImposterProtoChunk((LevelChunk) object, false);
-+ return this.loadStarlightLightData(world, new ImposterProtoChunk((LevelChunk) object, false)); // Paper - starlight
+ if (chunkType == ChunkType.LEVELCHUNK) {
+- return new ImposterProtoChunk((LevelChunk)chunkAccess, false);
++ return this.loadStarlightLightData(new ImposterProtoChunk((LevelChunk)chunkAccess, false)); // Paper - starlight
} else {
- ProtoChunk protochunk1 = (ProtoChunk) object;
- Iterator iterator2 = this.entities.iterator();
-@@ -382,7 +445,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- protochunk1.setCarvingMask(new CarvingMask(this.carvingMask, ((ChunkAccess) object).getMinY()));
+ ProtoChunk protoChunk1 = (ProtoChunk)chunkAccess;
+
+@@ -399,7 +462,7 @@ public record SerializableChunkData(
+ protoChunk1.setCarvingMask(new CarvingMask(this.carvingMask, chunkAccess.getMinY()));
}
-- return protochunk1;
-+ return this.loadStarlightLightData(world, protochunk1); // Paper - starlight
+- return protoChunk1;
++ return this.loadStarlightLightData(level, protoChunk1); // Paper - starlight
}
}
-@@ -405,24 +468,48 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- throw new IllegalArgumentException("Chunk can't be serialized: " + String.valueOf(chunk));
+@@ -427,22 +490,48 @@ public record SerializableChunkData(
+ throw new IllegalArgumentException("Chunk can't be serialized: " + chunk);
} else {
- ChunkPos chunkcoordintpair = chunk.getPos();
-- List<SerializableChunkData.SectionData> list = new ArrayList();
-+ List<SerializableChunkData.SectionData> list = new ArrayList(); final List<SerializableChunkData.SectionData> sections = list; // Paper - starlight - OBFHELPER
- LevelChunkSection[] achunksection = chunk.getSections();
- ThreadedLevelLightEngine lightenginethreaded = world.getChunkSource().getLightEngine();
-
-- for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
-- int j = chunk.getSectionIndexFromSectionY(i);
-- boolean flag = j >= 0 && j < achunksection.length;
-- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
-- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
-- DataLayer nibblearray2 = nibblearray != null && !nibblearray.isEmpty() ? nibblearray.copy() : null;
-- DataLayer nibblearray3 = nibblearray1 != null && !nibblearray1.isEmpty() ? nibblearray1.copy() : null;
+ ChunkPos pos = chunk.getPos();
+- List<SerializableChunkData.SectionData> list = new ArrayList<>();
++ List<SerializableChunkData.SectionData> list = new ArrayList<>(); final List<SerializableChunkData.SectionData> sectionsList = list; // Paper - starlight - OBFHELPER
+ LevelChunkSection[] sections = chunk.getSections();
+ LevelLightEngine lightEngine = level.getChunkSource().getLightEngine();
+
+- for (int lightSection = lightEngine.getMinLightSection(); lightSection < lightEngine.getMaxLightSection(); lightSection++) {
+- int sectionIndexFromSectionY = chunk.getSectionIndexFromSectionY(lightSection);
+- boolean flag = sectionIndexFromSectionY >= 0 && sectionIndexFromSectionY < sections.length;
+- DataLayer dataLayerData = lightEngine.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(pos, lightSection));
+- DataLayer dataLayerData1 = lightEngine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(pos, lightSection));
+- DataLayer dataLayer = dataLayerData != null && !dataLayerData.isEmpty() ? dataLayerData.copy() : null;
+- DataLayer dataLayer1 = dataLayerData1 != null && !dataLayerData1.isEmpty() ? dataLayerData1.copy() : null;
+- if (flag || dataLayer != null || dataLayer1 != null) {
+- LevelChunkSection levelChunkSection = flag ? sections[sectionIndexFromSectionY].copy() : null;
+- list.add(new SerializableChunkData.SectionData(lightSection, levelChunkSection, dataLayer, dataLayer1));
+ // Paper start - starlight
-+ final int minLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinLightSection(world);
-+ final int maxLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxLightSection(world);
-+ final int minBlockSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(world);
++ final int minLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinLightSection(level);
++ final int maxLightSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxLightSection(level);
++ final int minBlockSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(level);
+
+ final LevelChunkSection[] chunkSections = chunk.getSections();
+ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles = ((ca.spottedleaf.moonrise.patches.starlight.chunk.StarlightChunk)chunk).starlight$getBlockNibbles();
@@ -33778,17 +33271,14 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+ for (int lightSection = minLightSection; lightSection <= maxLightSection; ++lightSection) {
+ final int lightSectionIdx = lightSection - minLightSection;
+ final int blockSectionIdx = lightSection - minBlockSection;
-
-- if (flag || nibblearray2 != null || nibblearray3 != null) {
-- LevelChunkSection chunksection = flag ? achunksection[j].copy() : null;
++
+ final LevelChunkSection chunkSection = (blockSectionIdx >= 0 && blockSectionIdx < chunkSections.length) ? chunkSections[blockSectionIdx].copy() : null;
+ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState blockNibble = blockNibbles[lightSectionIdx].getSaveState();
+ final ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray.SaveState skyNibble = skyNibbles[lightSectionIdx].getSaveState();
-
-- list.add(new SerializableChunkData.SectionData(i, chunksection, nibblearray2, nibblearray3));
++
+ if (chunkSection == null && blockNibble == null && skyNibble == null) {
+ continue;
- }
++ }
+
+ final SerializableChunkData.SectionData sectionData = new SerializableChunkData.SectionData(
+ lightSection, chunkSection,
@@ -33802,27 +33292,25 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+
+ if (skyNibble != null) {
+ ((ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData)(Object)sectionData).starlight$setSkyLightState(skyNibble.state);
-+ }
+ }
+
-+ sections.add(sectionData);
++ sectionsList.add(sectionData);
}
+ // Paper end - starlight
- List<CompoundTag> list1 = new ArrayList(chunk.getBlockEntitiesPos().size());
- Iterator iterator = chunk.getBlockEntitiesPos().iterator();
-@@ -521,8 +608,8 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- Iterator iterator = this.sectionData.iterator();
+ List<CompoundTag> list1 = new ArrayList<>(chunk.getBlockEntitiesPos().size());
- while (iterator.hasNext()) {
-- SerializableChunkData.SectionData serializablechunkdata_b = (SerializableChunkData.SectionData) iterator.next();
-- CompoundTag nbttagcompound1 = new CompoundTag();
-+ SerializableChunkData.SectionData serializablechunkdata_b = (SerializableChunkData.SectionData) iterator.next(); final SerializableChunkData.SectionData sectionData = serializablechunkdata_b; // Paper - starlight - OBFHELPER
-+ CompoundTag nbttagcompound1 = new CompoundTag(); final CompoundTag sectionNBT = nbttagcompound1; // Paper - starlight - OBFHELPER
- LevelChunkSection chunksection = serializablechunkdata_b.chunkSection;
-
- if (chunksection != null) {
-@@ -538,6 +625,19 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- nbttagcompound1.putByteArray("SkyLight", serializablechunkdata_b.skyLight.getData());
+@@ -540,7 +629,7 @@ public record SerializableChunkData(
+ Codec<PalettedContainerRO<Holder<Biome>>> codec = makeBiomeCodec(this.biomeRegistry);
+
+ for (SerializableChunkData.SectionData sectionData : this.sectionData) {
+- CompoundTag compoundTag1 = new CompoundTag();
++ CompoundTag compoundTag1 = new CompoundTag(); final CompoundTag sectionNBT = compoundTag1; // Paper - starlight - OBFHELPER
+ LevelChunkSection levelChunkSection = sectionData.chunkSection;
+ if (levelChunkSection != null) {
+ compoundTag1.put("block_states", BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, levelChunkSection.getStates()).getOrThrow());
+@@ -555,6 +644,19 @@ public record SerializableChunkData(
+ compoundTag1.putByteArray("SkyLight", sectionData.skyLight.getData());
}
+ // Paper start - starlight
@@ -33838,29 +33326,29 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+ }
+ // Paper end - starlight
+
- if (!nbttagcompound1.isEmpty()) {
- nbttagcompound1.putByte("Y", (byte) serializablechunkdata_b.y);
- nbttaglist.add(nbttagcompound1);
-@@ -577,6 +677,14 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- nbttagcompound.put("ChunkBukkitValues", this.persistentDataContainer);
+ if (!compoundTag1.isEmpty()) {
+ compoundTag1.putByte("Y", (byte)sectionData.y);
+ listTag.add(compoundTag1);
+@@ -589,6 +691,14 @@ public record SerializableChunkData(
+ compoundTag.put("ChunkBukkitValues", this.persistentDataContainer);
}
// CraftBukkit end
+ // Paper start - starlight
+ if (this.lightCorrect && !this.chunkStatus.isBefore(net.minecraft.world.level.chunk.status.ChunkStatus.LIGHT)) {
+ // clobber vanilla value to force vanilla to relight
-+ nbttagcompound.putBoolean("isLightOn", false);
++ compoundTag.putBoolean("isLightOn", false);
+ // store our light version
-+ nbttagcompound.putInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG, ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION);
++ compoundTag.putInt(ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_VERSION_TAG, ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.STARLIGHT_LIGHT_VERSION);
+ }
+ // Paper end - starlight
- return nbttagcompound;
+ return compoundTag;
}
-@@ -763,7 +871,67 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
- return nbttaglist;
+@@ -747,6 +857,66 @@ public record SerializableChunkData(
+ }
}
-- public static record SectionData(int y, @Nullable LevelChunkSection chunkSection, @Nullable DataLayer blockLight, @Nullable DataLayer skyLight) {
+- public record SectionData(int y, @Nullable LevelChunkSection chunkSection, @Nullable DataLayer blockLight, @Nullable DataLayer skyLight) {
+ // Paper start - starlight - convert from record
+ public static final class SectionData implements ca.spottedleaf.moonrise.patches.starlight.storage.StarlightSectionData { // Paper - starlight - our diff
+ private final int y;
@@ -33922,11 +33410,10 @@ index 4bc7fa3324e9af3abce2acf960c7b0650aca2e36..0296f52fb2c871adbf2ce73a64d8f77f
+ return skyLight;
+ }
+ // Paper end - starlight - convert from record
-
}
-
+ }
diff --git a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
-index 578d270d5b7efb9ac8f5dde539170f6021e2b786..c5085ebf4e801837010f3750c5e89576bb0c27a5 100644
+index 41ddaceb7485626b1f2ee258c2142eb3114c106e..f883c6400281788982403d0af3ee28613e9a29b1 100644
--- a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
+++ b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
@@ -14,7 +14,7 @@ import net.minecraft.util.datafix.DataFixTypes;
@@ -33939,7 +33426,7 @@ index 578d270d5b7efb9ac8f5dde539170f6021e2b786..c5085ebf4e801837010f3750c5e89576
private final DataFixTypes dataFixType;
diff --git a/net/minecraft/world/level/entity/EntityTickList.java b/net/minecraft/world/level/entity/EntityTickList.java
-index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2d9c609d9 100644
+index 342c83309b19c64d86e0dd97c1756c96be52772b..423779a2b690f387a4f0bd07b97b50e0baefda76 100644
--- a/net/minecraft/world/level/entity/EntityTickList.java
+++ b/net/minecraft/world/level/entity/EntityTickList.java
@@ -9,52 +9,38 @@ import javax.annotation.Nullable;
@@ -33960,9 +33447,9 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2
- this.passive.put(entry.getIntKey(), entry.getValue());
- }
-
-- Int2ObjectMap<Entity> int2ObjectMap = this.active;
+- Int2ObjectMap<Entity> map = this.active;
- this.active = this.passive;
-- this.passive = int2ObjectMap;
+- this.passive = map;
- }
+ // Paper - rewrite chunk system
}
@@ -33984,15 +33471,15 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2
+ return this.entities.contains(entity); // Paper - rewrite chunk system
}
- public void forEach(Consumer<Entity> action) {
+ public void forEach(Consumer<Entity> entity) {
- if (this.iterated != null) {
- throw new UnsupportedOperationException("Only one concurrent iteration supported");
- } else {
- this.iterated = this.active;
-
- try {
-- for (Entity entity : this.active.values()) {
-- action.accept(entity);
+- for (Entity entity1 : this.active.values()) {
+- entity.accept(entity1);
- }
- } finally {
- this.iterated = null;
@@ -34002,7 +33489,7 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2
+ final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator<Entity> iterator = this.entities.iterator();
+ try {
+ while (iterator.hasNext()) {
-+ action.accept(iterator.next());
++ entity.accept(iterator.next());
}
+ } finally {
+ iterator.finishedIterating();
@@ -34011,29 +33498,29 @@ index 74a285b8b018a9c94ccea519f1ce8b9e2ef3cb64..d8b4196adf955f8d414688dc451caac2
}
}
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
-index 1fcc2b287ed723cf51720f80e68f18f4a15cf429..3f39d6c786d9dfdd9ad591e08ff05fcbb41a1df6 100644
+index b50de067a2a968926bdda4174e42f2973c84ff8b..8b81257328771ad23b90d7670f13713f93eefa96 100644
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
-@@ -86,7 +86,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
+@@ -78,7 +78,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
return CompletableFuture.supplyAsync(() -> {
- this.doCreateBiomes(blender, noiseConfig, structureAccessor, chunk);
+ this.doCreateBiomes(blender, randomState, structureManager, chunk);
return chunk;
- }, Util.backgroundExecutor().forName("init_biomes"));
+ }, Runnable::run); // Paper - rewrite chunk system
}
- private void doCreateBiomes(Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk) {
-@@ -311,7 +311,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
+ private void doCreateBiomes(Blender blender, RandomState random, StructureManager structureManager, ChunkAccess chunk) {
+@@ -318,7 +318,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
}
- return ichunkaccess1;
+ return var20;
- }, Util.backgroundExecutor().forName("wgen_fill_noise"));
+ }, Runnable::run); // Paper - rewrite chunk system
}
- private ChunkAccess doFill(Blender blender, StructureManager structureAccessor, RandomState noiseConfig, ChunkAccess chunk, int minimumCellY, int cellHeight) {
+ private ChunkAccess doFill(Blender blender, StructureManager structureManager, RandomState random, ChunkAccess chunk, int minCellY, int cellCountY) {
diff --git a/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/net/minecraft/world/level/levelgen/structure/StructureCheck.java
-index c3586281c9594769593a6027ea0a78f7c76c0262..decdb275e83fa6244aa3a24458872b42c49d04ed 100644
+index 06b54c0bec4031689d5c2da5cfea4ef28dbd16bc..f7dc4957b38878ddd3bfc7546be8a4e0af65c807 100644
--- a/net/minecraft/world/level/levelgen/structure/StructureCheck.java
+++ b/net/minecraft/world/level/levelgen/structure/StructureCheck.java
@@ -47,8 +47,13 @@ public class StructureCheck {
@@ -34051,63 +33538,63 @@ index c3586281c9594769593a6027ea0a78f7c76c0262..decdb275e83fa6244aa3a24458872b42
+ // Paper end - rewrite chunk system
public StructureCheck(
- ChunkScanAccess chunkIoWorker,
+ ChunkScanAccess storageAccess,
@@ -90,7 +95,7 @@ public class StructureCheck {
- public StructureCheckResult checkStart(ChunkPos pos, Structure type, StructurePlacement placement, boolean skipReferencedStructures) {
- long l = pos.toLong();
-- Object2IntMap<Structure> object2IntMap = this.loadedChunks.get(l);
-+ Object2IntMap<Structure> object2IntMap = this.loadedChunksSafe.get(l); // Paper - rewrite chunk system
- if (object2IntMap != null) {
- return this.checkStructureInfo(object2IntMap, type, skipReferencedStructures);
+ public StructureCheckResult checkStart(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) {
+ long packedChunkPos = chunkPos.toLong();
+- Object2IntMap<Structure> map = this.loadedChunks.get(packedChunkPos);
++ Object2IntMap<Structure> map = this.loadedChunksSafe.get(packedChunkPos); // Paper - rewrite chunk system
+ if (map != null) {
+ return this.checkStructureInfo(map, structure, skipKnownStructures);
} else {
@@ -100,9 +105,11 @@ public class StructureCheck {
- } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed, this.getSaltOverride(type))) { // Paper - add missing structure seed configs
+ } else if (!placement.applyAdditionalChunkRestrictions(chunkPos.x, chunkPos.z, this.seed, this.getSaltOverride(structure))) { // Paper - add missing structure seed configs
return StructureCheckResult.START_NOT_PRESENT;
} else {
-- boolean bl = this.featureChecks
-- .computeIfAbsent(type, structure2 -> new Long2BooleanOpenHashMap())
-- .computeIfAbsent(l, chunkPos -> this.canCreateStructure(pos, type));
+- boolean flag = this.featureChecks
+- .computeIfAbsent(structure, structure1 -> new Long2BooleanOpenHashMap())
+- .computeIfAbsent(packedChunkPos, l -> this.canCreateStructure(chunkPos, structure));
+ // Paper start - rewrite chunk system
-+ boolean bl = this.featureChecksSafe
-+ .computeIfAbsent(type, structure2 -> new ca.spottedleaf.moonrise.common.map.SynchronisedLong2BooleanMap(PER_FEATURE_CHECK_LIMIT))
-+ .getOrCompute(l, chunkPos -> this.canCreateStructure(pos, type));
++ boolean flag = this.featureChecksSafe
++ .computeIfAbsent(structure, structure1 -> new ca.spottedleaf.moonrise.common.map.SynchronisedLong2BooleanMap(PER_FEATURE_CHECK_LIMIT))
++ .getOrCompute(packedChunkPos, l -> this.canCreateStructure(chunkPos, structure));
+ // Paper end - rewrite chunk system
- return !bl ? StructureCheckResult.START_NOT_PRESENT : StructureCheckResult.CHUNK_LOAD_NEEDED;
+ return !flag ? StructureCheckResult.START_NOT_PRESENT : StructureCheckResult.CHUNK_LOAD_NEEDED;
}
}
@@ -228,15 +235,25 @@ public class StructureCheck {
}
- private void storeFullResults(long pos, Object2IntMap<Structure> referencesByStructure) {
-- this.loadedChunks.put(pos, deduplicateEmptyMap(referencesByStructure));
-- this.featureChecks.values().forEach(generationPossibilityByChunkPos -> generationPossibilityByChunkPos.remove(pos));
+ private void storeFullResults(long chunkPos, Object2IntMap<Structure> structureChunks) {
+- this.loadedChunks.put(chunkPos, deduplicateEmptyMap(structureChunks));
+- this.featureChecks.values().forEach(map -> map.remove(chunkPos));
+ // Paper start - rewrite chunk system
-+ this.loadedChunksSafe.put(pos, deduplicateEmptyMap(referencesByStructure));
++ this.loadedChunksSafe.put(chunkPos, deduplicateEmptyMap(structureChunks));
+ // once we insert into loadedChunks, we don't really need to be very careful about removing everything
+ // from this map, as everything that checks this map uses loadedChunks first
+ // so, one way or another it's a race condition that doesn't matter
+ for (ca.spottedleaf.moonrise.common.map.SynchronisedLong2BooleanMap value : this.featureChecksSafe.values()) {
-+ value.remove(pos);
++ value.remove(chunkPos);
+ }
+ // Paper end - rewrite chunk system
}
public void incrementReference(ChunkPos pos, Structure structure) {
-- this.loadedChunks.compute(pos.toLong(), (posx, referencesByStructure) -> {
-- if (referencesByStructure == null || referencesByStructure.isEmpty()) {
-+ this.loadedChunksSafe.compute(pos.toLong(), (posx, referencesByStructure) -> { // Paper start - rewrite chunk system
-+ if (referencesByStructure == null) {
- referencesByStructure = new Object2IntOpenHashMap<>();
+- this.loadedChunks.compute(pos.toLong(), (_long, map) -> {
+- if (map == null || map.isEmpty()) {
++ this.loadedChunksSafe.compute(pos.toLong(), (_long, map) -> { // Paper start - rewrite chunk system
++ if (map == null) {
+ map = new Object2IntOpenHashMap<>();
+ } else {
-+ referencesByStructure = referencesByStructure instanceof Object2IntOpenHashMap<Structure> fastClone ? fastClone.clone() : new Object2IntOpenHashMap<>(referencesByStructure);
++ map = map instanceof Object2IntOpenHashMap<Structure> fastClone ? fastClone.clone() : new Object2IntOpenHashMap<>(map);
}
+ // Paper end - rewrite chunk system
- referencesByStructure.computeInt(structure, (feature, references) -> references == null ? 1 : references + 1);
- return referencesByStructure;
+ map.computeInt(structure, (structure1, integer) -> integer == null ? 1 : integer + 1);
+ return map;
diff --git a/net/minecraft/world/level/lighting/LevelLightEngine.java b/net/minecraft/world/level/lighting/LevelLightEngine.java
-index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede341297bc58dba 100644
+index ca23af013967b50420ebee178878ea79333de53b..83c3ec06be51f632b7c1b682cfa8dce73ff7e0c0 100644
--- a/net/minecraft/world/level/lighting/LevelLightEngine.java
+++ b/net/minecraft/world/level/lighting/LevelLightEngine.java
@@ -9,151 +9,111 @@ import net.minecraft.world.level.LightLayer;
@@ -34148,15 +33635,15 @@ index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede34129
+ }
+ // Paper end - rewrite chunk system
- public LevelLightEngine(LightChunkGetter chunkProvider, boolean hasBlockLight, boolean hasSkyLight) {
- this.levelHeightAccessor = chunkProvider.getLevel();
-- this.blockEngine = hasBlockLight ? new BlockLightEngine(chunkProvider) : null;
-- this.skyEngine = hasSkyLight ? new SkyLightEngine(chunkProvider) : null;
+ public LevelLightEngine(LightChunkGetter lightChunkGetter, boolean blockLight, boolean skyLight) {
+ this.levelHeightAccessor = lightChunkGetter.getLevel();
+- this.blockEngine = blockLight ? new BlockLightEngine(lightChunkGetter) : null;
+- this.skyEngine = skyLight ? new SkyLightEngine(lightChunkGetter) : null;
+ // Paper start - rewrite chunk system
-+ if (chunkProvider.getLevel() instanceof net.minecraft.world.level.Level) {
-+ this.lightEngine = new ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface(chunkProvider, hasSkyLight, hasBlockLight, (LevelLightEngine)(Object)this);
++ if (lightChunkGetter.getLevel() instanceof net.minecraft.world.level.Level) {
++ this.lightEngine = new ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface(lightChunkGetter, skyLight, blockLight, (LevelLightEngine)(Object)this);
+ } else {
-+ this.lightEngine = new ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface(null, hasSkyLight, hasBlockLight, (LevelLightEngine)(Object)this);
++ this.lightEngine = new ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface(null, skyLight, blockLight, (LevelLightEngine)(Object)this);
+ }
+ // Paper end - rewrite chunk system
}
@@ -34206,25 +33693,25 @@ index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede34129
}
@Override
- public void updateSectionStatus(SectionPos pos, boolean notReady) {
+ public void updateSectionStatus(SectionPos pos, boolean isEmpty) {
- if (this.blockEngine != null) {
-- this.blockEngine.updateSectionStatus(pos, notReady);
+- this.blockEngine.updateSectionStatus(pos, isEmpty);
- }
-
- if (this.skyEngine != null) {
-- this.skyEngine.updateSectionStatus(pos, notReady);
+- this.skyEngine.updateSectionStatus(pos, isEmpty);
- }
+ this.lightEngine.sectionChange(pos, notReady); // Paper - rewrite chunk system
}
@Override
- public void setLightEnabled(ChunkPos pos, boolean retainData) {
+ public void setLightEnabled(ChunkPos chunkPos, boolean lightEnabled) {
- if (this.blockEngine != null) {
-- this.blockEngine.setLightEnabled(pos, retainData);
+- this.blockEngine.setLightEnabled(chunkPos, lightEnabled);
- }
-
- if (this.skyEngine != null) {
-- this.skyEngine.setLightEnabled(pos, retainData);
+- this.skyEngine.setLightEnabled(chunkPos, lightEnabled);
- }
+ // Paper - rewrite chunk system
}
@@ -34241,82 +33728,82 @@ index 8d90e783967280025d711c709facbcc87f611f8a..987e3397503cd07d3a2f172cede34129
+ // Paper - rewrite chunk system
}
- public LayerLightEventListener getLayerListener(LightLayer lightType) {
-- if (lightType == LightLayer.BLOCK) {
+ public LayerLightEventListener getLayerListener(LightLayer type) {
+- if (type == LightLayer.BLOCK) {
- return (LayerLightEventListener)(this.blockEngine == null ? LayerLightEventListener.DummyLightLayerEventListener.INSTANCE : this.blockEngine);
- } else {
- return (LayerLightEventListener)(this.skyEngine == null ? LayerLightEventListener.DummyLightLayerEventListener.INSTANCE : this.skyEngine);
- }
-+ return lightType == LightLayer.BLOCK ? this.lightEngine.getBlockReader() : this.lightEngine.getSkyReader(); // Paper - rewrite chunk system
++ return type == LightLayer.BLOCK ? this.lightEngine.getBlockReader() : this.lightEngine.getSkyReader(); // Paper - rewrite chunk system
}
- public String getDebugData(LightLayer lightType, SectionPos pos) {
-- if (lightType == LightLayer.BLOCK) {
+ public String getDebugData(LightLayer lightLayer, SectionPos sectionPos) {
+- if (lightLayer == LightLayer.BLOCK) {
- if (this.blockEngine != null) {
-- return this.blockEngine.getDebugData(pos.asLong());
+- return this.blockEngine.getDebugData(sectionPos.asLong());
- }
- } else if (this.skyEngine != null) {
-- return this.skyEngine.getDebugData(pos.asLong());
+- return this.skyEngine.getDebugData(sectionPos.asLong());
- }
-
- return "n/a";
+ return "n/a"; // Paper - rewrite chunk system
}
- public LayerLightSectionStorage.SectionType getDebugSectionType(LightLayer lightType, SectionPos pos) {
-- if (lightType == LightLayer.BLOCK) {
+ public LayerLightSectionStorage.SectionType getDebugSectionType(LightLayer lightLayer, SectionPos sectionPos) {
+- if (lightLayer == LightLayer.BLOCK) {
- if (this.blockEngine != null) {
-- return this.blockEngine.getDebugSectionType(pos.asLong());
+- return this.blockEngine.getDebugSectionType(sectionPos.asLong());
- }
- } else if (this.skyEngine != null) {
-- return this.skyEngine.getDebugSectionType(pos.asLong());
+- return this.skyEngine.getDebugSectionType(sectionPos.asLong());
- }
-
- return LayerLightSectionStorage.SectionType.EMPTY;
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system
}
- public void queueSectionData(LightLayer lightType, SectionPos pos, @Nullable DataLayer nibbles) {
-- if (lightType == LightLayer.BLOCK) {
+ public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer) {
+- if (lightLayer == LightLayer.BLOCK) {
- if (this.blockEngine != null) {
-- this.blockEngine.queueSectionData(pos.asLong(), nibbles);
+- this.blockEngine.queueSectionData(sectionPos.asLong(), dataLayer);
- }
- } else if (this.skyEngine != null) {
-- this.skyEngine.queueSectionData(pos.asLong(), nibbles);
+- this.skyEngine.queueSectionData(sectionPos.asLong(), dataLayer);
- }
+ // Paper - rewrite chunk system
}
- public void retainData(ChunkPos pos, boolean retainData) {
+ public void retainData(ChunkPos pos, boolean retain) {
- if (this.blockEngine != null) {
-- this.blockEngine.retainData(pos, retainData);
+- this.blockEngine.retainData(pos, retain);
- }
-
- if (this.skyEngine != null) {
-- this.skyEngine.retainData(pos, retainData);
+- this.skyEngine.retainData(pos, retain);
- }
+ // Paper - rewrite chunk system
}
- public int getRawBrightness(BlockPos pos, int ambientDarkness) {
-- int i = this.skyEngine == null ? 0 : this.skyEngine.getLightValue(pos) - ambientDarkness;
-- int j = this.blockEngine == null ? 0 : this.blockEngine.getLightValue(pos);
-- return Math.max(j, i);
-+ return this.lightEngine.getRawBrightness(pos, ambientDarkness); // Paper - rewrite chunk system
+ public int getRawBrightness(BlockPos blockPos, int amount) {
+- int i = this.skyEngine == null ? 0 : this.skyEngine.getLightValue(blockPos) - amount;
+- int i1 = this.blockEngine == null ? 0 : this.blockEngine.getLightValue(blockPos);
+- return Math.max(i1, i);
++ return this.lightEngine.getRawBrightness(blockPos, amount); // Paper - rewrite chunk system
}
- public boolean lightOnInColumn(long sectionPos) {
+ public boolean lightOnInColumn(long columnPos) {
- return this.blockEngine == null
-- || this.blockEngine.storage.lightOnInColumn(sectionPos) && (this.skyEngine == null || this.skyEngine.storage.lightOnInColumn(sectionPos));
+- || this.blockEngine.storage.lightOnInColumn(columnPos) && (this.skyEngine == null || this.skyEngine.storage.lightOnInColumn(columnPos));
+ throw new UnsupportedOperationException(); // Paper - rewrite chunk system // Paper - not implemented on server
}
public int getLightSectionCount() {
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
-index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1 100644
+index b9ad980b9a203bbc295f780bf54941f19a2f6525..19beef65b292c474f3a25b6c3ff679e31c17c7f4 100644
--- a/net/minecraft/world/level/material/FlowingFluid.java
+++ b/net/minecraft/world/level/material/FlowingFluid.java
-@@ -55,6 +55,48 @@ public abstract class FlowingFluid extends Fluid {
+@@ -45,6 +45,48 @@ public abstract class FlowingFluid extends Fluid {
});
private final Map<FluidState, VoxelShape> shapes = Maps.newIdentityHashMap();
@@ -34362,97 +33849,97 @@ index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c
+ }
+ // Paper end - fluid method optimisations
+
- public FlowingFluid() {}
-
@Override
-@@ -246,65 +288,70 @@ public abstract class FlowingFluid extends Fluid {
+ protected void createFluidStateDefinition(StateDefinition.Builder<Fluid, FluidState> builder) {
+ builder.add(FALLING);
+@@ -209,61 +251,71 @@ public abstract class FlowingFluid extends Fluid {
}
}
-- private static boolean canPassThroughWall(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState) {
-- VoxelShape voxelshape = fromState.getCollisionShape(world, fromPos);
+- private static boolean canPassThroughWall(
+- Direction direction, BlockGetter level, BlockPos pos, BlockState state, BlockPos spreadPos, BlockState spreadState
+- ) {
+- VoxelShape collisionShape = spreadState.getCollisionShape(level, spreadPos);
+- if (collisionShape == Shapes.block()) {
+- return false;
+- } else {
+- VoxelShape collisionShape1 = state.getCollisionShape(level, pos);
+- if (collisionShape1 == Shapes.block()) {
+- return false;
+- } else if (collisionShape1 == Shapes.empty() && collisionShape == Shapes.empty()) {
+- return true;
+- } else {
+- Object2ByteLinkedOpenHashMap<FlowingFluid.BlockStatePairKey> map;
+- if (!state.getBlock().hasDynamicShape() && !spreadState.getBlock().hasDynamicShape()) {
+- map = OCCLUSION_CACHE.get();
+- } else {
+- map = null;
+- }
+ // Paper start - fluid method optimisations
+ private static boolean canPassThroughWall(final Direction direction, final BlockGetter level,
-+ final BlockPos fromPos, final BlockState fromState,
-+ final BlockPos toPos, final BlockState toState) {
++ final BlockPos fromPos, final BlockState fromState,
++ final BlockPos toPos, final BlockState toState) {
+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$emptyCollisionShape() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$emptyCollisionShape()) {
+ // don't even try to cache simple cases
+ return true;
+ }
-- if (voxelshape == Shapes.block()) {
-+ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) {
-+ // don't even try to cache simple cases
- return false;
-- } else {
-- VoxelShape voxelshape1 = state.getCollisionShape(world, pos);
--
-- if (voxelshape1 == Shapes.block()) {
-- return false;
-- } else if (voxelshape1 == Shapes.empty() && voxelshape == Shapes.empty()) {
-- return true;
-- } else {
-- Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap;
--
-- if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
-- object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FlowingFluid.OCCLUSION_CACHE.get();
+- FlowingFluid.BlockStatePairKey blockStatePairKey;
+- if (map != null) {
+- blockStatePairKey = new FlowingFluid.BlockStatePairKey(state, spreadState, direction);
+- byte andMoveToFirst = map.getAndMoveToFirst(blockStatePairKey);
+- if (andMoveToFirst != 127) {
+- return andMoveToFirst != 0;
+- }
- } else {
-- object2bytelinkedopenhashmap = null;
+- blockStatePairKey = null;
- }
++ if (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$occludesFullBlock()) {
++ // don't even try to cache simple cases
++ return false;
+ }
-- FlowingFluid.BlockStatePairKey fluidtypeflowing_a;
+- boolean flag = !Shapes.mergedFaceOccludes(collisionShape1, collisionShape, direction);
+- if (map != null) {
+- if (map.size() == 200) {
+- map.removeLastByte();
+- }
+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey[] cache = ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$hasCache() & ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$hasCache() ?
+ COLLISION_OCCLUSION_CACHE.get() : null;
-- if (object2bytelinkedopenhashmap != null) {
-- fluidtypeflowing_a = new FlowingFluid.BlockStatePairKey(state, fromState, face);
-- byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(fluidtypeflowing_a);
+- map.putAndMoveToFirst(blockStatePairKey, (byte)(flag ? 1 : 0));
+- }
+ final int keyIndex
+ = (((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState)toState).moonrise$uniqueId2() ^ ((ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection)(Object)direction).moonrise$uniqueId())
+ & (COLLISION_OCCLUSION_CACHE_SIZE - 1);
-- if (b0 != 127) {
-- return b0 != 0;
-- }
-- } else {
-- fluidtypeflowing_a = null;
-- }
--
-- boolean flag = !Shapes.mergedFaceOccludes(voxelshape1, voxelshape, face);
+- return flag;
+ if (cache != null) {
+ final ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey cached = cache[keyIndex];
+ if (cached != null && cached.first() == fromState && cached.second() == toState && cached.direction() == direction) {
+ return cached.result();
-+ }
-+ }
-
-- if (object2bytelinkedopenhashmap != null) {
-- if (object2bytelinkedopenhashmap.size() == 200) {
-- object2bytelinkedopenhashmap.removeLastByte();
-- }
+ }
+ }
++
+ final VoxelShape shape1 = fromState.getCollisionShape(level, fromPos);
+ final VoxelShape shape2 = toState.getCollisionShape(level, toPos);
-
-- object2bytelinkedopenhashmap.putAndMoveToFirst(fluidtypeflowing_a, (byte) (flag ? 1 : 0));
-- }
++
+ final boolean result = !Shapes.mergedFaceOccludes(shape1, shape2, direction);
-
-- return flag;
-- }
++
+ if (cache != null) {
+ // we can afford to replace in-use keys more often due to the excessive caching the collision patch does in mergedFaceOccludes
+ cache[keyIndex] = new ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey(fromState, toState, direction, result);
- }
++ }
+
+ return result;
}
+ // Paper end - fluid method optimisations
++
public abstract Fluid getFlowing();
public FluidState getFlowing(int level, boolean falling) {
-- return (FluidState) ((FluidState) this.getFlowing().defaultFluidState().setValue(FlowingFluid.LEVEL, level)).setValue(FlowingFluid.FALLING, falling);
+- return this.getFlowing().defaultFluidState().setValue(LEVEL, Integer.valueOf(level)).setValue(FALLING, Boolean.valueOf(falling));
+ // Paper start - fluid method optimisations
+ final int amount = level;
+ if (!this.init) {
@@ -34466,7 +33953,7 @@ index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c
public abstract Fluid getSource();
public FluidState getSource(boolean falling) {
-- return (FluidState) this.getSource().defaultFluidState().setValue(FlowingFluid.FALLING, falling);
+- return this.getSource().defaultFluidState().setValue(FALLING, Boolean.valueOf(falling));
+ // Paper start - fluid method optimisations
+ if (!this.init) {
+ this.init();
@@ -34475,9 +33962,9 @@ index 261e5994d13f8bc30490b86691c80c0a21e7640a..f4fbcbb8ff6d2677af1a02a0801a323c
+ // Paper end - fluid method optimisations
}
- protected abstract boolean canConvertToSource(ServerLevel world);
+ protected abstract boolean canConvertToSource(ServerLevel level);
diff --git a/net/minecraft/world/level/material/FluidState.java b/net/minecraft/world/level/material/FluidState.java
-index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc1859379bfd805 100644
+index d2d71b22666639c003d86a6b6403fcbd2912c5af..481cb46973acb9785fdee5732e98aac560c6ec08 100644
--- a/net/minecraft/world/level/material/FluidState.java
+++ b/net/minecraft/world/level/material/FluidState.java
@@ -22,12 +22,30 @@ import net.minecraft.world.level.block.state.properties.Property;
@@ -34509,9 +33996,9 @@ index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc18593
+ }
+ // Paper end - fluid method optimisations
+
- public FluidState(Fluid fluid, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<FluidState> codec) {
- super(fluid, propertyMap, codec);
- this.isEmpty = fluid.isEmpty(); // Paper - Perf: moved from isEmpty()
+ public FluidState(Fluid owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> values, MapCodec<FluidState> propertiesCodec) {
+ super(owner, values, propertiesCodec);
+ this.isEmpty = owner.isEmpty(); // Paper - Perf: moved from isEmpty()
@@ -38,11 +56,11 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
@@ -34539,7 +34026,7 @@ index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc18593
+ return this.amount; // Paper - fluid method optimisations
}
- public boolean shouldRenderBackwardUpFace(BlockGetter world, BlockPos pos) {
+ public boolean shouldRenderBackwardUpFace(BlockGetter level, BlockPos pos) {
@@ -84,7 +102,7 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
@@ -34548,7 +34035,7 @@ index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc18593
+ return this.isRandomlyTicking; // Paper - fluid method optimisations
}
- public void randomTick(ServerLevel world, BlockPos pos, RandomSource random) {
+ public void randomTick(ServerLevel level, BlockPos pos, RandomSource random) {
@@ -96,7 +114,12 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
}
@@ -34564,31 +34051,31 @@ index 87adfe152abd1b8b4d547034576883c5d1cdf134..2d50d72bf026d0cf9c546a3c6fc18593
@Nullable
diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java
-index 5dc2674b537f4a61b2e21a21bdb2e8dc090d3a3c..6cf6d4ec7b9e43c7b2b4c0e2fb080964ff588130 100644
+index 047e1fd078d7f49a2547daeca9eec31306d25dd0..85148858db1fd5e9da8bbdde4b0d84110d80e373 100644
--- a/net/minecraft/world/phys/AABB.java
+++ b/net/minecraft/world/phys/AABB.java
-@@ -331,7 +331,7 @@ public class AABB {
+@@ -314,7 +314,7 @@ public class AABB {
}
@Nullable
-- private static Direction getDirection(
-+ public static Direction getDirection( // Paper - optimise collisions - public
- AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ
- ) {
- return getDirection(
+- private static Direction getDirection(AABB aabb, Vec3 start, double[] minDistance, @Nullable Direction facing, double deltaX, double deltaY, double deltaZ) {
++ public static Direction getDirection(AABB aabb, Vec3 start, double[] minDistance, @Nullable Direction facing, double deltaX, double deltaY, double deltaZ) { // Paper - optimise collisions - public
+ return getDirection(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ, start, minDistance, facing, deltaX, deltaY, deltaZ);
+ }
+
diff --git a/net/minecraft/world/phys/shapes/ArrayVoxelShape.java b/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
-index 4fee67f7214b464b9e09862778e3ef187fcb8b72..31a54af04ab072a433d6df9fe37beb12243fea80 100644
+index adb5f1be35d3a712499076719a1bb819ef52b9a8..39a634e1392239e17818a11750ba869ea7d195ce 100644
--- a/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
+++ b/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
@@ -20,7 +20,7 @@ public class ArrayVoxelShape extends VoxelShape {
);
}
-- ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xPoints, DoubleList yPoints, DoubleList zPoints) {
-+ public ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xPoints, DoubleList yPoints, DoubleList zPoints) { // Paper - optimise collisions - public
+- ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xs, DoubleList ys, DoubleList zs) {
++ public ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xs, DoubleList ys, DoubleList zs) { // Paper - optimise collisions - public
super(shape);
int i = shape.getXSize() + 1;
- int j = shape.getYSize() + 1;
+ int i1 = shape.getYSize() + 1;
@@ -34,6 +34,7 @@ public class ArrayVoxelShape extends VoxelShape {
new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape.")
);
@@ -34598,7 +34085,7 @@ index 4fee67f7214b464b9e09862778e3ef187fcb8b72..31a54af04ab072a433d6df9fe37beb12
@Override
diff --git a/net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape.java b/net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape.java
-index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f28cbaf30b 100644
+index 14a12bdaa428556fa7b0c43e37b79699ae2fcb92..3a56e4ad9b3cba0cdf4bc373f7d0457d8643fdc4 100644
--- a/net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape.java
+++ b/net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape.java
@@ -4,13 +4,13 @@ import java.util.BitSet;
@@ -34620,14 +34107,14 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ public int yMax; // Paper - optimise collisions - public
+ public int zMax; // Paper - optimise collisions - public
- public BitSetDiscreteVoxelShape(int sizeX, int sizeY, int sizeZ) {
- super(sizeX, sizeY, sizeZ);
+ public BitSetDiscreteVoxelShape(int xSize, int ySize, int zSize) {
+ super(xSize, ySize, zSize);
@@ -150,47 +150,109 @@ public final class BitSetDiscreteVoxelShape extends DiscreteVoxelShape {
return bitSetDiscreteVoxelShape;
}
-- protected static void forAllBoxes(DiscreteVoxelShape voxelSet, DiscreteVoxelShape.IntLineConsumer callback, boolean coalesce) {
-- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = new BitSetDiscreteVoxelShape(voxelSet);
+- protected static void forAllBoxes(DiscreteVoxelShape shape, DiscreteVoxelShape.IntLineConsumer consumer, boolean combine) {
+- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = new BitSetDiscreteVoxelShape(shape);
+ // Paper start - optimise collisions
+ public static void forAllBoxes(final DiscreteVoxelShape shape, final DiscreteVoxelShape.IntLineConsumer consumer, final boolean mergeAdjacent) {
+ // Paper - remove debug
@@ -34669,19 +34156,19 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ // this branch is actually important to optimise, as it affects uncached toAabbs() (which affects optimize())
- for (int i = 0; i < bitSetDiscreteVoxelShape.ySize; i++) {
-- for (int j = 0; j < bitSetDiscreteVoxelShape.xSize; j++) {
-- int k = -1;
+- for (int i1 = 0; i1 < bitSetDiscreteVoxelShape.xSize; i1++) {
+- int i2 = -1;
+ // only clone when we may write to it
+ bitset = ca.spottedleaf.moonrise.common.util.MixinWorkarounds.clone(bitset);
-- for (int l = 0; l <= bitSetDiscreteVoxelShape.zSize; l++) {
-- if (bitSetDiscreteVoxelShape.isFullWide(j, i, l)) {
-- if (coalesce) {
-- if (k == -1) {
-- k = l;
+- for (int i3 = 0; i3 <= bitSetDiscreteVoxelShape.zSize; i3++) {
+- if (bitSetDiscreteVoxelShape.isFullWide(i1, i, i3)) {
+- if (combine) {
+- if (i2 == -1) {
+- i2 = i3;
- }
- } else {
-- callback.consume(j, i, l, j + 1, i + 1, l + 1);
+- consumer.consume(i1, i, i3, i1 + 1, i + 1, i3 + 1);
+ for (int y = 0; y < sizeY; ++y, indexY += incY) {
+ indexX = indexY;
+ for (int x = 0; x < sizeX; ++x, indexX += incX) {
@@ -34696,14 +34183,14 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ if (lastSetZ == -1) {
+ lastSetZ = endIndex;
}
-- } else if (k != -1) {
-- int m = j;
-- int n = i;
-- bitSetDiscreteVoxelShape.clearZStrip(k, l, j, i);
+- } else if (i2 != -1) {
+- int i4 = i1;
+- int i5 = i;
+- bitSetDiscreteVoxelShape.clearZStrip(i2, i3, i1, i);
-
-- while (bitSetDiscreteVoxelShape.isZStripFull(k, l, m + 1, i)) {
-- bitSetDiscreteVoxelShape.clearZStrip(k, l, m + 1, i);
-- m++;
+- while (bitSetDiscreteVoxelShape.isZStripFull(i2, i3, i4 + 1, i)) {
+- bitSetDiscreteVoxelShape.clearZStrip(i2, i3, i4 + 1, i);
+- i4++;
+
+ ca.spottedleaf.moonrise.common.util.FlatBitsetUtil.clearRange(bitset, firstSetZ, lastSetZ);
+
@@ -34717,9 +34204,9 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ ca.spottedleaf.moonrise.common.util.FlatBitsetUtil.clearRange(bitset, neighbourIdxStart, neighbourIdxEnd);
}
-- while (bitSetDiscreteVoxelShape.isXZRectangleFull(j, m + 1, k, l, n + 1)) {
-- for (int o = j; o <= m; o++) {
-- bitSetDiscreteVoxelShape.clearZStrip(k, l, o, n + 1);
+- while (bitSetDiscreteVoxelShape.isXZRectangleFull(i1, i4 + 1, i2, i3, i5 + 1)) {
+- for (int i6 = i1; i6 <= i4; i6++) {
+- bitSetDiscreteVoxelShape.clearZStrip(i2, i3, i6, i5 + 1);
+ // try to merge neighbouring on the Y axis
+
+ int endY; // exclusive
@@ -34736,7 +34223,7 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ }
}
-- n++;
+- i5++;
+ ++endY;
+
+ // passed, so we can clear it
@@ -34746,8 +34233,8 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
+ }
}
-- callback.consume(j, i, k, m + 1, n + 1, l);
-- k = -1;
+- consumer.consume(i1, i, i2, i4 + 1, i5 + 1, i3);
+- i2 = -1;
+ consumer.consume(x, y, firstSetZ - indexX, endX, endY, lastSetZ - indexX);
+ zIdx = lastSetZ;
}
@@ -34757,22 +34244,22 @@ index e8f3307727e7e3da9a7629cafc6e1ee53790b75d..97ef481156ec5d821779f126ab98a8f2
}
+ // Paper end - optimise collisions
- private boolean isZStripFull(int z1, int z2, int x, int y) {
- return x < this.xSize && y < this.ySize && this.storage.nextClearBit(this.getIndex(x, y, z1)) >= this.getIndex(x, y, z2);
+ private boolean isZStripFull(int zMin, int zMax, int x, int y) {
+ return x < this.xSize && y < this.ySize && this.storage.nextClearBit(this.getIndex(x, y, zMin)) >= this.getIndex(x, y, zMax);
diff --git a/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/net/minecraft/world/phys/shapes/CubeVoxelShape.java
-index d812949c7329ae2696b38dc792fa011ba87decb9..7743495c7ec3fc5e17947144457cef7bbe0f4b38 100644
+index f6b6481591e009de80f6b6318d35f193aabb7df3..e9b5069dcd572966b2f5aa220cef30e7a328fa2c 100644
--- a/net/minecraft/world/phys/shapes/CubeVoxelShape.java
+++ b/net/minecraft/world/phys/shapes/CubeVoxelShape.java
@@ -7,6 +7,7 @@ import net.minecraft.util.Mth;
public final class CubeVoxelShape extends VoxelShape {
- protected CubeVoxelShape(DiscreteVoxelShape voxels) {
- super(voxels);
+ protected CubeVoxelShape(DiscreteVoxelShape shape) {
+ super(shape);
+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)this).moonrise$initCache(); // Paper - optimise collisions
}
@Override
diff --git a/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java b/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java
-index 01693ba050b12b9debcdaefceeff9cbcd503b369..fbe0c4b0fdbb992b7002f6afe1e74d63cbb420f2 100644
+index 4fc61b329ccb7c9aeb6105dc53d71545a3baea89..309a34f192f7737204ce7a5c3b4004bdd83842f2 100644
--- a/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java
+++ b/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java
@@ -3,12 +3,79 @@ package net.minecraft.world.phys.shapes;
@@ -34853,11 +34340,11 @@ index 01693ba050b12b9debcdaefceeff9cbcd503b369..fbe0c4b0fdbb992b7002f6afe1e74d63
+ }
+ // Paper end - optimise collisions
+
- protected DiscreteVoxelShape(int sizeX, int sizeY, int sizeZ) {
- if (sizeX >= 0 && sizeY >= 0 && sizeZ >= 0) {
- this.xSize = sizeX;
+ protected DiscreteVoxelShape(int xSize, int ySize, int zSize) {
+ if (xSize >= 0 && ySize >= 0 && zSize >= 0) {
+ this.xSize = xSize;
diff --git a/net/minecraft/world/phys/shapes/OffsetDoubleList.java b/net/minecraft/world/phys/shapes/OffsetDoubleList.java
-index 7ec02a7849437a18860aa0df7d9ddd71b2447d4c..5e45e49ab09344cb95736f4124b1c6e002ef5b82 100644
+index ac1488875537421b74f0c491c9b7a40e75539c92..9eb27eb8d6dcaad6ce02f8ce4546acc224c4196f 100644
--- a/net/minecraft/world/phys/shapes/OffsetDoubleList.java
+++ b/net/minecraft/world/phys/shapes/OffsetDoubleList.java
@@ -4,8 +4,8 @@ import it.unimi.dsi.fastutil.doubles.AbstractDoubleList;
@@ -34869,10 +34356,10 @@ index 7ec02a7849437a18860aa0df7d9ddd71b2447d4c..5e45e49ab09344cb95736f4124b1c6e0
+ public final DoubleList delegate; // Paper - optimise collisions - public
+ public final double offset; // Paper - optimise collisions - public
- public OffsetDoubleList(DoubleList oldList, double offset) {
- this.delegate = oldList;
+ public OffsetDoubleList(DoubleList delegate, double offset) {
+ this.delegate = delegate;
diff --git a/net/minecraft/world/phys/shapes/Shapes.java b/net/minecraft/world/phys/shapes/Shapes.java
-index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f175394c0 100644
+index e759221fb54aa510d2d8bbba47e1d794367aec6d..5665cfaae4fc9e72b77fd41e16e7f64460b099b0 100644
--- a/net/minecraft/world/phys/shapes/Shapes.java
+++ b/net/minecraft/world/phys/shapes/Shapes.java
@@ -16,9 +16,15 @@ public final class Shapes {
@@ -34932,9 +34419,9 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ // Paper start - optimise collisions
if (!(maxX - minX < 1.0E-7) && !(maxY - minY < 1.0E-7) && !(maxZ - minZ < 1.0E-7)) {
- int i = findBits(minX, maxX);
-- int j = findBits(minY, maxY);
-- int k = findBits(minZ, maxZ);
-- if (i < 0 || j < 0 || k < 0) {
+- int i1 = findBits(minY, maxY);
+- int i2 = findBits(minZ, maxZ);
+- if (i < 0 || i1 < 0 || i2 < 0) {
+ final int bitsX = findBits(minX, maxX);
+ final int bitsY = findBits(minY, maxY);
+ final int bitsZ = findBits(minZ, maxZ);
@@ -34967,22 +34454,22 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ minY == 0.0 && maxY == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minY, maxY }),
+ minZ == 0.0 && maxZ == 1.0 ? ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minZ, maxZ })
);
-- } else if (i == 0 && j == 0 && k == 0) {
+- } else if (i == 0 && i1 == 0 && i2 == 0) {
- return block();
- } else {
-- int l = 1 << i;
-- int m = 1 << j;
-- int n = 1 << k;
+- int i3 = 1 << i;
+- int i4 = 1 << i1;
+- int i5 = 1 << i2;
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.withFilledBounds(
-- l,
-- m,
-- n,
-- (int)Math.round(minX * (double)l),
-- (int)Math.round(minY * (double)m),
-- (int)Math.round(minZ * (double)n),
-- (int)Math.round(maxX * (double)l),
-- (int)Math.round(maxY * (double)m),
-- (int)Math.round(maxZ * (double)n)
+- i3,
+- i4,
+- i5,
+- (int)Math.round(minX * i3),
+- (int)Math.round(minY * i4),
+- (int)Math.round(minZ * i5),
+- (int)Math.round(maxX * i3),
+- (int)Math.round(maxY * i4),
+- (int)Math.round(maxZ * i5)
- );
- return new CubeVoxelShape(bitSetDiscreteVoxelShape);
}
@@ -34993,18 +34480,15 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ // Paper end - optimise collisions
}
- public static VoxelShape create(AABB box) {
-@@ -119,80 +152,54 @@ public final class Shapes {
- return join(first, second, BooleanOp.OR);
+ public static VoxelShape create(AABB aabb) {
+@@ -120,85 +153,52 @@ public final class Shapes {
}
-- public static VoxelShape or(VoxelShape first, VoxelShape... others) {
-- return Arrays.stream(others).reduce(first, Shapes::or);
-+ // Paper start - optimise collisions
-+ public static VoxelShape or(VoxelShape shape, VoxelShape... others) {
+ public static VoxelShape or(VoxelShape shape1, VoxelShape... others) {
+- return Arrays.stream(others).reduce(shape1, Shapes::or);
+ int size = others.length;
+ if (size == 0) {
-+ return shape;
++ return shape1;
+ }
+
+ // reduce complexity of joins by splitting the merges
@@ -35013,7 +34497,7 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ ++size;
+ final VoxelShape[] tmp = Arrays.copyOf(others, size);
+ // insert first shape
-+ tmp[size - 1] = shape;
++ tmp[size - 1] = shape1;
+
+ while (size > 1) {
+ int newSize = 0;
@@ -35038,88 +34522,94 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ // Paper end - optimise collisions
}
- public static VoxelShape join(VoxelShape first, VoxelShape second, BooleanOp function) {
-- return joinUnoptimized(first, second, function).optimize();
-+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.joinOptimized(first, second, function); // Paper - optimise collisions
+ public static VoxelShape join(VoxelShape shape1, VoxelShape shape2, BooleanOp function) {
+- return joinUnoptimized(shape1, shape2, function).optimize();
++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.joinOptimized(shape1, shape2, function); // Paper - optimise collisions
}
- public static VoxelShape joinUnoptimized(VoxelShape one, VoxelShape two, BooleanOp function) {
+ public static VoxelShape joinUnoptimized(VoxelShape shape1, VoxelShape shape2, BooleanOp function) {
- if (function.apply(false, false)) {
- throw (IllegalArgumentException)Util.pauseInIde(new IllegalArgumentException());
-- } else if (one == two) {
-- return function.apply(true, true) ? one : empty();
+- } else if (shape1 == shape2) {
+- return function.apply(true, true) ? shape1 : empty();
- } else {
-- boolean bl = function.apply(true, false);
-- boolean bl2 = function.apply(false, true);
-- if (one.isEmpty()) {
-- return bl2 ? two : empty();
-- } else if (two.isEmpty()) {
-- return bl ? one : empty();
+- boolean flag = function.apply(true, false);
+- boolean flag1 = function.apply(false, true);
+- if (shape1.isEmpty()) {
+- return flag1 ? shape2 : empty();
+- } else if (shape2.isEmpty()) {
+- return flag ? shape1 : empty();
- } else {
-- IndexMerger indexMerger = createIndexMerger(1, one.getCoords(Direction.Axis.X), two.getCoords(Direction.Axis.X), bl, bl2);
-- IndexMerger indexMerger2 = createIndexMerger(indexMerger.size() - 1, one.getCoords(Direction.Axis.Y), two.getCoords(Direction.Axis.Y), bl, bl2);
-- IndexMerger indexMerger3 = createIndexMerger(
-- (indexMerger.size() - 1) * (indexMerger2.size() - 1), one.getCoords(Direction.Axis.Z), two.getCoords(Direction.Axis.Z), bl, bl2
+- IndexMerger indexMerger = createIndexMerger(1, shape1.getCoords(Direction.Axis.X), shape2.getCoords(Direction.Axis.X), flag, flag1);
+- IndexMerger indexMerger1 = createIndexMerger(
+- indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), flag, flag1
+- );
+- IndexMerger indexMerger2 = createIndexMerger(
+- (indexMerger.size() - 1) * (indexMerger1.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), flag, flag1
- );
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.join(
-- one.shape, two.shape, indexMerger, indexMerger2, indexMerger3, function
+- shape1.shape, shape2.shape, indexMerger, indexMerger1, indexMerger2, function
- );
- return (VoxelShape)(indexMerger instanceof DiscreteCubeMerger
+- && indexMerger1 instanceof DiscreteCubeMerger
- && indexMerger2 instanceof DiscreteCubeMerger
-- && indexMerger3 instanceof DiscreteCubeMerger
- ? new CubeVoxelShape(bitSetDiscreteVoxelShape)
-- : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger2.getList(), indexMerger3.getList()));
+- : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger1.getList(), indexMerger2.getList()));
- }
- }
-+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.joinUnoptimized(one, two, function); // Paper - optimise collisions
++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.joinUnoptimized(shape1, shape2, function); // Paper - optimise collisions
}
- public static boolean joinIsNotEmpty(VoxelShape shape1, VoxelShape shape2, BooleanOp predicate) {
-- if (predicate.apply(false, false)) {
+ public static boolean joinIsNotEmpty(VoxelShape shape1, VoxelShape shape2, BooleanOp resultOperator) {
+- if (resultOperator.apply(false, false)) {
- throw (IllegalArgumentException)Util.pauseInIde(new IllegalArgumentException());
- } else {
-- boolean bl = shape1.isEmpty();
-- boolean bl2 = shape2.isEmpty();
-- if (!bl && !bl2) {
+- boolean isEmpty = shape1.isEmpty();
+- boolean isEmpty1 = shape2.isEmpty();
+- if (!isEmpty && !isEmpty1) {
- if (shape1 == shape2) {
-- return predicate.apply(true, true);
+- return resultOperator.apply(true, true);
- } else {
-- boolean bl3 = predicate.apply(true, false);
-- boolean bl4 = predicate.apply(false, true);
+- boolean flag = resultOperator.apply(true, false);
+- boolean flag1 = resultOperator.apply(false, true);
-
- for (Direction.Axis axis : AxisCycle.AXIS_VALUES) {
- if (shape1.max(axis) < shape2.min(axis) - 1.0E-7) {
-- return bl3 || bl4;
+- return flag || flag1;
- }
-
- if (shape2.max(axis) < shape1.min(axis) - 1.0E-7) {
-- return bl3 || bl4;
+- return flag || flag1;
- }
- }
-
-- IndexMerger indexMerger = createIndexMerger(1, shape1.getCoords(Direction.Axis.X), shape2.getCoords(Direction.Axis.X), bl3, bl4);
-- IndexMerger indexMerger2 = createIndexMerger(
-- indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), bl3, bl4
+- IndexMerger indexMerger = createIndexMerger(1, shape1.getCoords(Direction.Axis.X), shape2.getCoords(Direction.Axis.X), flag, flag1);
+- IndexMerger indexMerger1 = createIndexMerger(
+- indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), flag, flag1
- );
-- IndexMerger indexMerger3 = createIndexMerger(
-- (indexMerger.size() - 1) * (indexMerger2.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), bl3, bl4
+- IndexMerger indexMerger2 = createIndexMerger(
+- (indexMerger.size() - 1) * (indexMerger1.size() - 1),
+- shape1.getCoords(Direction.Axis.Z),
+- shape2.getCoords(Direction.Axis.Z),
+- flag,
+- flag1
- );
-- return joinIsNotEmpty(indexMerger, indexMerger2, indexMerger3, shape1.shape, shape2.shape, predicate);
+- return joinIsNotEmpty(indexMerger, indexMerger1, indexMerger2, shape1.shape, shape2.shape, resultOperator);
- }
- } else {
-- return predicate.apply(!bl, !bl2);
+- return resultOperator.apply(!isEmpty, !isEmpty1);
- }
- }
-+ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isJoinNonEmpty(shape1, shape2, predicate); // Paper - optimise collisions
++ return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isJoinNonEmpty(shape1, shape2, resultOperator); // Paper - optimise collisions
}
private static boolean joinIsNotEmpty(
-@@ -219,51 +226,116 @@ public final class Shapes {
- return maxDist;
+@@ -230,52 +230,116 @@ public final class Shapes {
+ return desiredOffset;
}
-- public static boolean blockOccudes(VoxelShape shape, VoxelShape neighbor, Direction direction) {
-- if (shape == block() && neighbor == block()) {
+- public static boolean blockOccudes(VoxelShape shape, VoxelShape adjacentShape, Direction side) {
+- if (shape == block() && adjacentShape == block()) {
+ // Paper start - optimise collisions
+ public static boolean blockOccudes(final VoxelShape first, final VoxelShape second, final Direction direction) {
+ final boolean firstBlock = first == BLOCK;
@@ -35127,7 +34617,7 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+
+ if (firstBlock & secondBlock) {
return true;
-- } else if (neighbor.isEmpty()) {
+- } else if (adjacentShape.isEmpty()) {
+ }
+
+ if (first.isEmpty() | second.isEmpty()) {
@@ -35140,14 +34630,14 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ if (newFirst.isEmpty()) {
return false;
- } else {
-- Direction.Axis axis = direction.getAxis();
-- Direction.AxisDirection axisDirection = direction.getAxisDirection();
-- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? shape : neighbor;
-- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? neighbor : shape;
+- Direction.Axis axis = side.getAxis();
+- Direction.AxisDirection axisDirection = side.getAxisDirection();
+- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? shape : adjacentShape;
+- VoxelShape voxelShape1 = axisDirection == Direction.AxisDirection.POSITIVE ? adjacentShape : shape;
- BooleanOp booleanOp = axisDirection == Direction.AxisDirection.POSITIVE ? BooleanOp.ONLY_FIRST : BooleanOp.ONLY_SECOND;
- return DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)
-- && DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)
-- && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), booleanOp);
+- && DoubleMath.fuzzyEquals(voxelShape1.min(axis), 0.0, 1.0E-7)
+- && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape1, axis, 0), booleanOp);
}
+ final VoxelShape newSecond = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$getFaceShapeClamped(direction.getOpposite());
+ if (newSecond.isEmpty()) {
@@ -35158,12 +34648,12 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ // Paper end - optimise collisions
}
-- public static boolean mergedFaceOccludes(VoxelShape one, VoxelShape two, Direction direction) {
-- if (one != block() && two != block()) {
-- Direction.Axis axis = direction.getAxis();
-- Direction.AxisDirection axisDirection = direction.getAxisDirection();
-- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? one : two;
-- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? two : one;
+- public static boolean mergedFaceOccludes(VoxelShape shape, VoxelShape adjacentShape, Direction side) {
+- if (shape != block() && adjacentShape != block()) {
+- Direction.Axis axis = side.getAxis();
+- Direction.AxisDirection axisDirection = side.getAxisDirection();
+- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? shape : adjacentShape;
+- VoxelShape voxelShape1 = axisDirection == Direction.AxisDirection.POSITIVE ? adjacentShape : shape;
- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)) {
- voxelShape = empty();
- }
@@ -35173,8 +34663,8 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ final AABB bounds1 = shape1.bounds();
+ final AABB bounds2 = shape2.bounds();
-- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)) {
-- voxelShape2 = empty();
+- if (!DoubleMath.fuzzyEquals(voxelShape1.min(axis), 0.0, 1.0E-7)) {
+- voxelShape1 = empty();
- }
+ final double minX = Math.min(bounds1.minX, bounds2.minX);
+ final double minY = Math.min(bounds1.minY, bounds2.minY);
@@ -35182,7 +34672,7 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
- return !joinIsNotEmpty(
- block(),
-- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR),
+- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape1, axis, 0), BooleanOp.OR),
- BooleanOp.ONLY_FIRST
- );
- } else {
@@ -35200,8 +34690,8 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ public static boolean mergedFaceOccludes(final VoxelShape first, final VoxelShape second, final Direction direction) {
+ // see if any of the shapes on their own occludes, only if cached
+ if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)first).moonrise$occludesFullBlockIfCached() || ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)second).moonrise$occludesFullBlockIfCached()) {
-+ return true;
-+ }
+ return true;
+ }
+
+ if (first.isEmpty() & second.isEmpty()) {
+ return false;
@@ -35214,8 +34704,8 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+
+ // see if any of the shapes on their own occludes, only if cached
+ if (((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)newFirst).moonrise$occludesFullBlockIfCached() || ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)newSecond).moonrise$occludesFullBlockIfCached()) {
- return true;
- }
++ return true;
++ }
+
+ final boolean firstEmpty = newFirst.isEmpty();
+ final boolean secondEmpty = newSecond.isEmpty();
@@ -35256,29 +34746,30 @@ index 76d7435e6fe81a3f1d24b35eae72d06232a1792b..ca3a2419252721bb3b3b719eb19afb5f
+ return ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape1).moonrise$occludesFullBlock();
+ }
-- public static boolean faceShapeOccludes(VoxelShape one, VoxelShape two) {
-- return one == block()
-- || two == block()
-- || (!one.isEmpty() || !two.isEmpty()) && !joinIsNotEmpty(block(), joinUnoptimized(one, two, BooleanOp.OR), BooleanOp.ONLY_FIRST);
+- public static boolean faceShapeOccludes(VoxelShape voxelShape1, VoxelShape voxelShape2) {
+- return voxelShape1 == block()
+- || voxelShape2 == block()
+- || (!voxelShape1.isEmpty() || !voxelShape2.isEmpty())
+- && !joinIsNotEmpty(block(), joinUnoptimized(voxelShape1, voxelShape2, BooleanOp.OR), BooleanOp.ONLY_FIRST);
+ return mergedMayOccludeBlock(shape1, shape2) && ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)shape1).moonrise$orUnoptimized(shape2)).moonrise$occludesFullBlock();
+ // Paper end - optimise collisions
}
@VisibleForTesting
diff --git a/net/minecraft/world/phys/shapes/SliceShape.java b/net/minecraft/world/phys/shapes/SliceShape.java
-index b07f1c58e00d232e7c83e6df3499e4b677645609..b88c71f27996d24d29048e06a69a004617eb53a2 100644
+index 79f7f04207891dd98cc0b2d93ecb2e07c8baa7b6..7ca12213c10f962ff597a8d51413a17b1827bbb4 100644
--- a/net/minecraft/world/phys/shapes/SliceShape.java
+++ b/net/minecraft/world/phys/shapes/SliceShape.java
@@ -12,6 +12,7 @@ public class SliceShape extends VoxelShape {
- super(makeSlice(shape.shape, axis, sliceWidth));
- this.delegate = shape;
+ super(makeSlice(delegate.shape, axis, index));
+ this.delegate = delegate;
this.axis = axis;
+ ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)this).moonrise$initCache(); // Paper - optimise collisions
}
- private static DiscreteVoxelShape makeSlice(DiscreteVoxelShape voxelSet, Direction.Axis axis, int sliceWidth) {
+ private static DiscreteVoxelShape makeSlice(DiscreteVoxelShape shape, Direction.Axis axis, int index) {
diff --git a/net/minecraft/world/phys/shapes/VoxelShape.java b/net/minecraft/world/phys/shapes/VoxelShape.java
-index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9cffc3071 100644
+index 006065c32baf3b1ddc5647196cb9f863c7969064..2c7e70675b62cb753447d2acebf2f36cdac74973 100644
--- a/net/minecraft/world/phys/shapes/VoxelShape.java
+++ b/net/minecraft/world/phys/shapes/VoxelShape.java
@@ -15,61 +15,546 @@ import net.minecraft.world.phys.AABB;
@@ -35706,8 +35197,8 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ }
+ // Paper end - optimise collisions
+
- protected VoxelShape(DiscreteVoxelShape voxels) {
- this.shape = voxels;
+ protected VoxelShape(DiscreteVoxelShape shape) {
+ this.shape = shape;
}
public double min(Direction.Axis axis) {
@@ -35777,11 +35268,11 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ // Paper start - optimise collisions
+ if (this.isEmpty) {
+ throw Util.pauseInIde(new UnsupportedOperationException("No bounds for empty shape."));
-+ }
+ }
+ AABB cached = this.cachedBounds;
+ if (cached != null) {
+ return cached;
- }
++ }
+
+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData shapeData = this.cachedShapeData;
+
@@ -35856,18 +35347,18 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ return this.isEmpty; // Paper - optimise collisions
}
- public VoxelShape move(Vec3 vec3d) {
-@@ -77,24 +562,96 @@ public abstract class VoxelShape {
+ public VoxelShape move(Vec3 offset) {
+@@ -77,20 +562,96 @@ public abstract class VoxelShape {
}
- public VoxelShape move(double x, double y, double z) {
+ public VoxelShape move(double xOffset, double yOffset, double zOffset) {
- return (VoxelShape)(this.isEmpty()
- ? Shapes.empty()
- : new ArrayVoxelShape(
- this.shape,
-- new OffsetDoubleList(this.getCoords(Direction.Axis.X), x),
-- new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y),
-- new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z)
+- new OffsetDoubleList(this.getCoords(Direction.Axis.X), xOffset),
+- new OffsetDoubleList(this.getCoords(Direction.Axis.Y), yOffset),
+- new OffsetDoubleList(this.getCoords(Direction.Axis.Z), zOffset)
- ));
+ // Paper start - optimise collisions
+ if (this.isEmpty) {
@@ -35876,14 +35367,14 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+
+ final ArrayVoxelShape ret = new ArrayVoxelShape(
+ this.shape,
-+ offsetList(this.rootCoordinatesX, this.offsetX + x),
-+ offsetList(this.rootCoordinatesY, this.offsetY + y),
-+ offsetList(this.rootCoordinatesZ, this.offsetZ + z)
++ offsetList(this.rootCoordinatesX, this.offsetX + xOffset),
++ offsetList(this.rootCoordinatesY, this.offsetY + yOffset),
++ offsetList(this.rootCoordinatesZ, this.offsetZ + zOffset)
+ );
+
+ final ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs cachedToAABBs = this.cachedToAABBs;
+ if (cachedToAABBs != null) {
-+ ((VoxelShape)(Object)ret).cachedToAABBs = ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs.offset(cachedToAABBs, x, y, z);
++ ((VoxelShape)(Object)ret).cachedToAABBs = ca.spottedleaf.moonrise.patches.collisions.shape.CachedToAABBs.offset(cachedToAABBs, xOffset, yOffset, zOffset);
+ }
+
+ return ret;
@@ -35892,11 +35383,7 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
public VoxelShape optimize() {
- VoxelShape[] voxelShapes = new VoxelShape[]{Shapes.empty()};
-- this.forAllBoxes(
-- (minX, minY, minZ, maxX, maxY, maxZ) -> voxelShapes[0] = Shapes.joinUnoptimized(
-- voxelShapes[0], Shapes.box(minX, minY, minZ, maxX, maxY, maxZ), BooleanOp.OR
-- )
-- );
+- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> voxelShapes[0] = Shapes.joinUnoptimized(voxelShapes[0], Shapes.box(x1, y1, z1, x2, y2, z2), BooleanOp.OR));
- return voxelShapes[0];
+ // Paper start - optimise collisions
+ if (this.isEmpty) {
@@ -35968,8 +35455,8 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ // Paper end - optimise collisions
}
- public void forAllEdges(Shapes.DoubleLineConsumer consumer) {
-@@ -131,9 +688,24 @@ public abstract class VoxelShape {
+ public void forAllEdges(Shapes.DoubleLineConsumer action) {
+@@ -122,9 +683,24 @@ public abstract class VoxelShape {
}
public List<AABB> toAabbs() {
@@ -35996,14 +35483,14 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ // Paper end - optimise collisions
}
- public double min(Direction.Axis axis, double from, double to) {
-@@ -155,46 +727,92 @@ public abstract class VoxelShape {
+ public double min(Direction.Axis axis, double primaryPosition, double secondaryPosition) {
+@@ -146,46 +722,92 @@ public abstract class VoxelShape {
}
- protected int findIndex(Direction.Axis axis, double coord) {
-- return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1;
+ protected int findIndex(Direction.Axis axis, double position) {
+- return Mth.binarySearch(0, this.shape.getSize(axis) + 1, value -> position < this.get(axis, value)) - 1;
+ // Paper start - optimise collisions
-+ final double value = coord;
++ final double value = position;
+ switch (axis) {
+ case X: {
+ final double[] values = this.rootCoordinatesX;
@@ -36031,68 +35518,66 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
}
@Nullable
-- public BlockHitResult clip(Vec3 start, Vec3 end, BlockPos pos) {
+ public BlockHitResult clip(Vec3 startVec, Vec3 endVec, BlockPos pos) {
- if (this.isEmpty()) {
-+ // Paper start - optimise collisions
-+ public BlockHitResult clip(final Vec3 from, final Vec3 to, final BlockPos offset) {
++ // Paper start - optimise collisions
+ if (this.isEmpty) {
return null;
- } else {
-- Vec3 vec3 = end.subtract(start);
+- Vec3 vec3 = endVec.subtract(startVec);
- if (vec3.lengthSqr() < 1.0E-7) {
- return null;
- } else {
-- Vec3 vec32 = start.add(vec3.scale(0.001));
+- Vec3 vec31 = startVec.add(vec3.scale(0.001));
- return this.shape
- .isFullWide(
-- this.findIndex(Direction.Axis.X, vec32.x - (double)pos.getX()),
-- this.findIndex(Direction.Axis.Y, vec32.y - (double)pos.getY()),
-- this.findIndex(Direction.Axis.Z, vec32.z - (double)pos.getZ())
+- this.findIndex(Direction.Axis.X, vec31.x - pos.getX()),
+- this.findIndex(Direction.Axis.Y, vec31.y - pos.getY()),
+- this.findIndex(Direction.Axis.Z, vec31.z - pos.getZ())
- )
-- ? new BlockHitResult(vec32, Direction.getApproximateNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true)
-- : AABB.clip(this.toAabbs(), start, end, pos);
+- ? new BlockHitResult(vec31, Direction.getApproximateNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true)
+- : AABB.clip(this.toAabbs(), startVec, endVec, pos);
+ }
+
-+ final Vec3 directionOpposite = to.subtract(from);
++ final Vec3 directionOpposite = endVec.subtract(startVec);
+ if (directionOpposite.lengthSqr() < ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON) {
+ return null;
+ }
+
-+ final Vec3 fromBehind = from.add(directionOpposite.scale(0.001));
-+ final double fromBehindOffsetX = fromBehind.x - (double)offset.getX();
-+ final double fromBehindOffsetY = fromBehind.y - (double)offset.getY();
-+ final double fromBehindOffsetZ = fromBehind.z - (double)offset.getZ();
++ final Vec3 fromBehind = startVec.add(directionOpposite.scale(0.001));
++ final double fromBehindOffsetX = fromBehind.x - (double) pos.getX();
++ final double fromBehindOffsetY = fromBehind.y - (double) pos.getY();
++ final double fromBehindOffsetZ = fromBehind.z - (double) pos.getZ();
+
+ final AABB singleAABB = this.singleAABBRepresentation;
+ if (singleAABB != null) {
+ if (singleAABB.contains(fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) {
-+ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true);
++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), pos, true);
}
-+ return clip(singleAABB, from, to, offset);
++ return clip(singleAABB, startVec, endVec, pos);
+ }
+
-+ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.strictlyContains((VoxelShape)(Object)this, fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) {
-+ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), offset, true);
++ if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.strictlyContains((VoxelShape) (Object) this, fromBehindOffsetX, fromBehindOffsetY, fromBehindOffsetZ)) {
++ return new BlockHitResult(fromBehind, Direction.getApproximateNearest(directionOpposite.x, directionOpposite.y, directionOpposite.z).getOpposite(), pos, true);
}
+
-+ return AABB.clip(((VoxelShape)(Object)this).toAabbs(), from, to, offset);
++ return AABB.clip(((VoxelShape) (Object) this).toAabbs(), startVec, endVec, pos);
+ // Paper end - optimise collisions
}
-- public Optional<Vec3> closestPointTo(Vec3 target) {
-- if (this.isEmpty()) {
+ // Paper start - optimise collisions
-+ public Optional<Vec3> closestPointTo(Vec3 point) {
+ public Optional<Vec3> closestPointTo(Vec3 point) {
+- if (this.isEmpty()) {
+ if (this.isEmpty) {
return Optional.empty();
- } else {
- Vec3[] vec3s = new Vec3[1];
-- this.forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> {
-- double d = Mth.clamp(target.x(), minX, maxX);
-- double e = Mth.clamp(target.y(), minY, maxY);
-- double f = Mth.clamp(target.z(), minZ, maxZ);
-- if (vec3s[0] == null || target.distanceToSqr(d, e, f) < target.distanceToSqr(vec3s[0])) {
-- vec3s[0] = new Vec3(d, e, f);
+- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> {
+- double d = Mth.clamp(point.x(), x1, x2);
+- double d1 = Mth.clamp(point.y(), y1, y2);
+- double d2 = Mth.clamp(point.z(), z1, z2);
+- if (vec3s[0] == null || point.distanceToSqr(d, d1, d2) < point.distanceToSqr(vec3s[0])) {
+- vec3s[0] = new Vec3(d, d1, d2);
- }
- });
- return Optional.of(vec3s[0]);
@@ -36119,35 +35604,33 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
+ // Paper end - optimise collisions
}
- public VoxelShape getFaceShape(Direction facing) {
-@@ -216,20 +834,24 @@ public abstract class VoxelShape {
- }
+ public VoxelShape getFaceShape(Direction side) {
+@@ -208,19 +830,23 @@ public abstract class VoxelShape {
}
-- private VoxelShape calculateFace(Direction facing) {
-- Direction.Axis axis = facing.getAxis();
+ private VoxelShape calculateFace(Direction side) {
+- Direction.Axis axis = side.getAxis();
- if (this.isCubeLikeAlong(axis)) {
- return this;
- } else {
-- Direction.AxisDirection axisDirection = facing.getAxisDirection();
+- Direction.AxisDirection axisDirection = side.getAxisDirection();
- int i = this.findIndex(axis, axisDirection == Direction.AxisDirection.POSITIVE ? 0.9999999 : 1.0E-7);
- SliceShape sliceShape = new SliceShape(this, axis, i);
- if (sliceShape.isEmpty()) {
- return Shapes.empty();
- } else {
- return (VoxelShape)(sliceShape.isCubeLike() ? Shapes.block() : sliceShape);
-+ private VoxelShape calculateFace(Direction direction) {
+ // Paper start - optimise collisions
-+ final Direction.Axis axis = direction.getAxis();
++ final Direction.Axis axis = side.getAxis();
+ switch (axis) {
+ case X: {
-+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesX, this.offsetX);
++ return this.calculateFaceDirect(side, axis, this.rootCoordinatesX, this.offsetX);
+ }
+ case Y: {
-+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesY, this.offsetY);
++ return this.calculateFaceDirect(side, axis, this.rootCoordinatesY, this.offsetY);
+ }
+ case Z: {
-+ return this.calculateFaceDirect(direction, axis, this.rootCoordinatesZ, this.offsetZ);
++ return this.calculateFaceDirect(side, axis, this.rootCoordinatesZ, this.offsetZ);
+ }
+ default: {
+ throw new IllegalStateException("Unknown axis: " + axis);
@@ -36157,12 +35640,12 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
}
protected boolean isCubeLike() {
-@@ -249,9 +871,30 @@ public abstract class VoxelShape {
- && DoubleMath.fuzzyEquals(doubleList.getDouble(1), 1.0, 1.0E-7);
+@@ -238,9 +864,30 @@ public abstract class VoxelShape {
+ return coords.size() == 2 && DoubleMath.fuzzyEquals(coords.getDouble(0), 0.0, 1.0E-7) && DoubleMath.fuzzyEquals(coords.getDouble(1), 1.0, 1.0E-7);
}
-- public double collide(Direction.Axis axis, AABB box, double maxDist) {
-- return this.collideX(AxisCycle.between(axis, Direction.Axis.X), box, maxDist);
+- public double collide(Direction.Axis movementAxis, AABB collisionBox, double desiredOffset) {
+- return this.collideX(AxisCycle.between(movementAxis, Direction.Axis.X), collisionBox, desiredOffset);
+ // Paper start - optimise collisions
+ public double collide(final Direction.Axis axis, final AABB source, final double source_move) {
+ if (this.isEmpty) {
@@ -36188,10 +35671,10 @@ index bcb79462c8b3309ae8701cba4753b27a9d22eb2e..6182f1d37c7a63479f6c6e7c37a7edc9
}
+ // Paper end - optimise collisions
- protected double collideX(AxisCycle axisCycle, AABB box, double maxDist) {
+ protected double collideX(AxisCycle movementAxis, AABB collisionBox, double desiredOffset) {
if (this.isEmpty()) {
diff --git a/net/minecraft/world/ticks/LevelChunkTicks.java b/net/minecraft/world/ticks/LevelChunkTicks.java
-index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2f26d593d 100644
+index 5b6bd88a5bbbce6cce351938418eba4326e41002..faf45ac459f7c25309d6ef6dce371d484a0dae7b 100644
--- a/net/minecraft/world/ticks/LevelChunkTicks.java
+++ b/net/minecraft/world/ticks/LevelChunkTicks.java
@@ -17,7 +17,7 @@ import net.minecraft.core.BlockPos;
@@ -36245,10 +35728,10 @@ index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2
return scheduledTick;
@@ -58,7 +82,7 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
@Override
- public void schedule(ScheduledTick<T> orderedTick) {
- if (this.ticksPerPosition.add(orderedTick)) {
-- this.scheduleUnchecked(orderedTick);
-+ this.scheduleUnchecked(orderedTick); this.dirty = true; // Paper - rewrite chunk system
+ public void schedule(ScheduledTick<T> tick) {
+ if (this.ticksPerPosition.add(tick)) {
+- this.scheduleUnchecked(tick);
++ this.scheduleUnchecked(tick); this.dirty = true; // Paper - rewrite chunk system
}
}
@@ -36264,327 +35747,16 @@ index 26620c06d26a2c0eb957fbadc6ac3d7a309bff46..3858c83c58e78435a6e29de84c33faa2
@@ -110,6 +134,7 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
}
- public ListTag save(long time, Function<T, String> typeToNameFunction) {
-+ this.lastSaved = time; // Paper - rewrite chunk system
+ public ListTag save(long gametime, Function<T, String> idGetter) {
++ this.lastSaved = gametime; // Paper - rewrite chunk system
ListTag listTag = new ListTag();
- for (SavedTick<T> savedTick : this.pack(time)) {
+ for (SavedTick<T> savedTick : this.pack(gametime)) {
@@ -121,6 +146,7 @@ public class LevelChunkTicks<T> implements SerializableTickContainer<T>, TickCon
- public void unpack(long time) {
+ public void unpack(long gameTime) {
if (this.pendingTicks != null) {
-+ this.lastSaved = time; // Paper - rewrite chunk system
++ this.lastSaved = gameTime; // Paper - rewrite chunk system
int i = -this.pendingTicks.size();
for (SavedTick<T> savedTick : this.pendingTicks) {
-diff --git a/org/bukkit/craftbukkit/CraftChunk.java b/org/bukkit/craftbukkit/CraftChunk.java
-index f3ab07e44e2e912ea66c6148cfdb2a4a528741b2..c2bffe3450ee9f768e00a23ec09df74d7a06d49b 100644
---- a/org/bukkit/craftbukkit/CraftChunk.java
-+++ b/org/bukkit/craftbukkit/CraftChunk.java
-@@ -83,6 +83,12 @@ public class CraftChunk implements Chunk {
- }
-
- public ChunkAccess getHandle(ChunkStatus chunkStatus) {
-+ // Paper start - rewrite chunk system
-+ net.minecraft.world.level.chunk.LevelChunk full = this.worldServer.getChunkIfLoaded(this.x, this.z);
-+ if (full != null) {
-+ return full;
-+ }
-+ // Paper end - rewrite chunk system
- ChunkAccess chunkAccess = this.worldServer.getChunk(this.x, this.z, chunkStatus);
-
- // SPIGOT-7332: Get unwrapped extension
-@@ -117,60 +123,12 @@ public class CraftChunk implements Chunk {
-
- @Override
- public boolean isEntitiesLoaded() {
-- return this.getCraftWorld().getHandle().entityManager.areEntitiesLoaded(ChunkPos.asLong(this.x, this.z));
-+ return this.getCraftWorld().getHandle().areEntitiesLoaded(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(this.x, this.z)); // Paper - rewrite chunk system
- }
-
- @Override
- public Entity[] getEntities() {
-- if (!this.isLoaded()) {
-- this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick
-- }
--
-- PersistentEntitySectionManager<net.minecraft.world.entity.Entity> entityManager = this.getCraftWorld().getHandle().entityManager;
-- long pair = ChunkPos.asLong(this.x, this.z);
--
-- if (entityManager.areEntitiesLoaded(pair)) {
-- return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream()
-- .map(net.minecraft.world.entity.Entity::getBukkitEntity)
-- .filter(Objects::nonNull).toArray(Entity[]::new);
-- }
--
-- entityManager.ensureChunkQueuedForLoad(pair); // Start entity loading
--
-- // SPIGOT-6772: Use entity mailbox and re-schedule entities if they get unloaded
-- ConsecutiveExecutor mailbox = ((EntityStorage) entityManager.permanentStorage).entityDeserializerQueue;
-- BooleanSupplier supplier = () -> {
-- // only execute inbox if our entities are not present
-- if (entityManager.areEntitiesLoaded(pair)) {
-- return true;
-- }
--
-- if (!entityManager.isPending(pair)) {
-- // Our entities got unloaded, this should normally not happen.
-- entityManager.ensureChunkQueuedForLoad(pair); // Re-start entity loading
-- }
--
-- // tick loading inbox, which loads the created entities to the world
-- // (if present)
-- entityManager.tick();
-- // check if our entities are loaded
-- return entityManager.areEntitiesLoaded(pair);
-- };
--
-- // now we wait until the entities are loaded,
-- // the converting from NBT to entity object is done on the main Thread which is why we wait
-- while (!supplier.getAsBoolean()) {
-- if (mailbox.size() != 0) {
-- mailbox.run();
-- } else {
-- Thread.yield();
-- LockSupport.parkNanos("waiting for entity loading", 100000L);
-- }
-- }
--
-- return entityManager.getEntities(new ChunkPos(this.x, this.z)).stream()
-- .map(net.minecraft.world.entity.Entity::getBukkitEntity)
-- .filter(Objects::nonNull).toArray(Entity[]::new);
-+ return this.getCraftWorld().getHandle().getChunkEntities(this.x, this.z); // Paper - rewrite chunk system
- }
-
- @Override
-diff --git a/org/bukkit/craftbukkit/CraftServer.java b/org/bukkit/craftbukkit/CraftServer.java
-index 5b64111bc8baca45ecc7bfa384e5f8a004163a0b..97b5d6ba2b19a7c730730c74175a29157aed1840 100644
---- a/org/bukkit/craftbukkit/CraftServer.java
-+++ b/org/bukkit/craftbukkit/CraftServer.java
-@@ -1448,7 +1448,7 @@ public final class CraftServer implements Server {
- // Paper - Put world into worldlist before initing the world; move up
-
- this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
-- internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
-+ // Paper - rewrite chunk system
-
- this.pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
- return internal.getWorld();
-@@ -1493,7 +1493,7 @@ public final class CraftServer implements Server {
- }
-
- handle.getChunkSource().close(save);
-- handle.entityManager.close(save); // SPIGOT-6722: close entityManager
-+ // Paper - rewrite chunk system
- handle.convertable.close();
- } catch (Exception ex) {
- this.getLogger().log(Level.SEVERE, null, ex);
-@@ -2531,7 +2531,7 @@ public final class CraftServer implements Server {
-
- @Override
- public boolean isPrimaryThread() {
-- return Thread.currentThread().equals(this.console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog)
-+ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThread(); // Paper - rewrite chunk system
- }
-
- // Paper start - Adventure
-diff --git a/org/bukkit/craftbukkit/CraftWorld.java b/org/bukkit/craftbukkit/CraftWorld.java
-index ca62105a0ff0aa69385cbf2018f8fe6a4bb69fd4..92d9f0ea8f7810ae20d3996f49aefa539b4bcb69 100644
---- a/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/org/bukkit/craftbukkit/CraftWorld.java
-@@ -507,15 +507,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
- if (playerChunk == null) return false;
-
-- playerChunk.getTickingChunkFuture().thenAccept(either -> {
-- either.ifSuccess(chunk -> {
-+ // Paper start - chunk system
-+ net.minecraft.world.level.chunk.LevelChunk chunk = playerChunk.getChunkToSend();
-+ if (chunk == null) {
-+ return false;
-+ }
-+ // Paper end - chunk system
- List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
-- if (playersInRange.isEmpty()) return;
-+ if (playersInRange.isEmpty()) return true; // Paper - chunk system
-
- FeatureHooks.sendChunkRefreshPackets(playersInRange, chunk);
-- });
-- });
--
-+ // Paper - chunk system
- return true;
- }
-
-@@ -618,20 +620,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- @Override
- public Collection<Plugin> getPluginChunkTickets(int x, int z) {
- DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
-- SortedArraySet<Ticket<?>> tickets = chunkDistanceManager.tickets.get(ChunkPos.asLong(x, z));
--
-- if (tickets == null) {
-- return Collections.emptyList();
-- }
-
-- ImmutableList.Builder<Plugin> ret = ImmutableList.builder();
-- for (Ticket<?> ticket : tickets) {
-- if (ticket.getType() == TicketType.PLUGIN_TICKET) {
-- ret.add((Plugin) ticket.key);
-- }
-- }
--
-- return ret.build();
-+ return chunkDistanceManager.moonrise$getChunkHolderManager().getPluginChunkTickets(x, z); // Paper - rewrite chunk system
- }
-
- @Override
-@@ -639,7 +629,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- Map<Plugin, ImmutableList.Builder<Chunk>> ret = new HashMap<>();
- DistanceManager chunkDistanceManager = this.world.getChunkSource().chunkMap.distanceManager;
-
-- for (Long2ObjectMap.Entry<SortedArraySet<Ticket<?>>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) {
-+ for (Long2ObjectMap.Entry<SortedArraySet<Ticket<?>>> chunkTickets : chunkDistanceManager.moonrise$getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { // Paper - rewrite chunk system
- long chunkKey = chunkTickets.getLongKey();
- SortedArraySet<Ticket<?>> tickets = chunkTickets.getValue();
-
-@@ -1342,12 +1332,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- @Override
- public int getViewDistance() {
-- return this.world.getChunkSource().chunkMap.serverViewDistance;
-+ return this.getHandle().moonrise$getPlayerChunkLoader().getAPIViewDistance(); // Paper - rewrite chunk system
- }
-
- @Override
- public int getSimulationDistance() {
-- return this.world.getChunkSource().chunkMap.getDistanceManager().simulationDistance;
-+ return this.getHandle().moonrise$getPlayerChunkLoader().getAPITickDistance(); // Paper - rewrite chunk system
- }
-
- public BlockMetadataStore getBlockMetadata() {
-@@ -2486,17 +2476,20 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- @Override
- public void setSimulationDistance(final int simulationDistance) {
-- throw new UnsupportedOperationException("Not implemented yet");
-+ if (simulationDistance < 2 || simulationDistance > 32) {
-+ throw new IllegalArgumentException("Simulation distance " + simulationDistance + " is out of range of [2, 32]");
-+ }
-+ this.getHandle().chunkSource.setSimulationDistance(simulationDistance); // Paper - rewrite chunk system
- }
-
- @Override
- public int getSendViewDistance() {
-- return this.getViewDistance();
-+ return this.getHandle().moonrise$getPlayerChunkLoader().getAPISendViewDistance(); // Paper - rewrite chunk system
- }
-
- @Override
- public void setSendViewDistance(final int viewDistance) {
-- throw new UnsupportedOperationException("Not implemented yet");
-+ this.getHandle().chunkSource.setSendViewDistance(viewDistance); // Paper - rewrite chunk system
- }
-
- // Paper start - implement pointers
-diff --git a/org/bukkit/craftbukkit/entity/CraftPlayer.java b/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index e9df37ff66700278bc94ea1e42135b92d97d03f7..6a647cab8b2e476987931486e290703b8726f2c7 100644
---- a/org/bukkit/craftbukkit/entity/CraftPlayer.java
-+++ b/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -3527,7 +3527,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-
- @Override
- public void setViewDistance(final int viewDistance) {
-- throw new UnsupportedOperationException("Not implemented yet");
-+ // Paper - rewrite chunk system - TODO do this better
-+ ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle())
-+ .moonrise$getViewDistanceHolder().setLoadViewDistance(viewDistance + 1);
- }
-
- @Override
-@@ -3537,7 +3539,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-
- @Override
- public void setSimulationDistance(final int simulationDistance) {
-- throw new UnsupportedOperationException("Not implemented yet");
-+ // Paper - rewrite chunk system - TODO do this better
-+ ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle())
-+ .moonrise$getViewDistanceHolder().setTickViewDistance(simulationDistance);
- }
-
- @Override
-@@ -3547,7 +3551,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-
- @Override
- public void setSendViewDistance(final int viewDistance) {
-- throw new UnsupportedOperationException("Not implemented yet");
-+ // Paper - rewrite chunk system - TODO do this better
-+ ((ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer)this.getHandle())
-+ .moonrise$getViewDistanceHolder().setSendViewDistance(viewDistance);
- }
-
- // Paper start - entity effect API
-diff --git a/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
-index 39377ba0739f9660567b38475f101672f7b5e035..c025a4ff42257a4e84f0f9574b84f6987ef8ac11 100644
---- a/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
-+++ b/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
-@@ -264,7 +264,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
- return ichunkaccess1;
- };
-
-- return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), net.minecraft.Util.backgroundExecutor()) : future.thenApply(function);
-+ return future == null ? CompletableFuture.supplyAsync(() -> function.apply(chunk), Runnable::run) : future.thenApply(function); // Paper - rewrite chunk system
- }
-
- @Override
-diff --git a/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
-index 54c4434662d057a08800918641b95708cda61207..37458e8fd5d57acbf90a6bea4e66797cb07f69fa 100644
---- a/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
-+++ b/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
-@@ -810,6 +810,13 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel {
- public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) {
- return this.handle.getChunkIfLoadedImmediately(x, z);
- }
-+
-+ // Paper start - rewrite chunk system
-+ @Override
-+ public java.util.List<net.minecraft.world.entity.Entity> moonrise$getHardCollidingEntities(final net.minecraft.world.entity.Entity entity, final net.minecraft.world.phys.AABB box, final java.util.function.Predicate<? super net.minecraft.world.entity.Entity> predicate) {
-+ return this.handle.moonrise$getHardCollidingEntities(entity, box, predicate);
-+ }
-+ // Paper end - rewrite chunk system
- // Paper end
- }
-
-diff --git a/org/spigotmc/AsyncCatcher.java b/org/spigotmc/AsyncCatcher.java
-index ef2598760458833021ef1bee92137f42c9fe591f..1f23e775eba1c34e01145bd91b0ce26fed6ca9de 100644
---- a/org/spigotmc/AsyncCatcher.java
-+++ b/org/spigotmc/AsyncCatcher.java
-@@ -9,7 +9,7 @@ public class AsyncCatcher
-
- public static void catchOp(String reason)
- {
-- if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread )
-+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) // Paper // Paper - rewrite chunk system
- {
- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper
- throw new IllegalStateException( "Asynchronous " + reason + "!" );
-diff --git a/org/spigotmc/WatchdogThread.java b/org/spigotmc/WatchdogThread.java
-index ad282d34919716b75acd10426cd071da9d064a51..529df2a41dd93d6e1505053bd04032dbf0cdaa31 100644
---- a/org/spigotmc/WatchdogThread.java
-+++ b/org/spigotmc/WatchdogThread.java
-@@ -8,7 +8,7 @@ import java.util.logging.Logger;
- import net.minecraft.server.MinecraftServer;
- import org.bukkit.Bukkit;
-
--public class WatchdogThread extends Thread
-+public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThread // Paper - rewrite chunk system
- {
-
- private static WatchdogThread instance;
-@@ -115,6 +115,7 @@ public class WatchdogThread extends Thread
- // Paper end - Different message for short timeout
- log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
-+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - rewrite chunk system
- WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
- log.log( Level.SEVERE, "------------------------------" );
- //