Migrate ChunkSystem class to PaperHooks
This commit is contained in:
@@ -6,13 +6,14 @@ Subject: [PATCH] Add PaperHooks
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..834c5ce238c7adb0164a6282582d709348ef96cc
|
||||
index 0000000000000000000000000000000000000000..2988c418b34d6f699a9c24406cfd6949465b64f0
|
||||
--- /dev/null
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -0,0 +1,240 @@
|
||||
@@ -0,0 +1,241 @@
|
||||
+package ca.spottedleaf.moonrise.paper;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.PlatformHooks;
|
||||
+import ca.spottedleaf.moonrise.paper.util.BaseChunkSystemHooks;
|
||||
+import com.mojang.datafixers.DSL;
|
||||
+import com.mojang.datafixers.DataFixer;
|
||||
+import com.mojang.serialization.Dynamic;
|
||||
@@ -39,7 +40,7 @@ index 0000000000000000000000000000000000000000..834c5ce238c7adb0164a6282582d7093
|
||||
+import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
+
|
||||
+public final class PaperHooks implements PlatformHooks {
|
||||
+public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks {
|
||||
+
|
||||
+ @Override
|
||||
+ public String getBrand() {
|
||||
@@ -250,3 +251,341 @@ index 0000000000000000000000000000000000000000..834c5ce238c7adb0164a6282582d7093
|
||||
+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..34b45bc11124efb22f0f3ae5b2ad8f445c719476
|
||||
--- /dev/null
|
||||
+++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
|
||||
@@ -0,0 +1,332 @@
|
||||
+package ca.spottedleaf.moonrise.paper.util;
|
||||
+
|
||||
+import ca.spottedleaf.concurrentutil.util.Priority;
|
||||
+import com.mojang.logging.LogUtils;
|
||||
+import net.minecraft.server.level.ChunkHolder;
|
||||
+import net.minecraft.server.level.ChunkResult;
|
||||
+import net.minecraft.server.level.FullChunkStatus;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.TicketType;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkPyramid;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
+import net.minecraft.world.level.chunk.status.ChunkStep;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.slf4j.Logger;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+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 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);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
|
||||
+ this.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);
|
||||
+ }
|
||||
+
|
||||
+ @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) {
|
||||
+ this.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
||||
+ return;
|
||||
+ }
|
||||
+ 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)) {
|
||||
+ BaseChunkSystemHooks.this.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
||||
+ } else {
|
||||
+ if (onComplete != null) {
|
||||
+ onComplete.accept(null);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @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(++this.chunkLoadCounter) : null;
|
||||
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
+
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ }
|
||||
+ level.chunkSource.runDistanceManagerUpdates();
|
||||
+
|
||||
+ final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> {
|
||||
+ try {
|
||||
+ if (onComplete != null) {
|
||||
+ onComplete.accept(chunk);
|
||||
+ }
|
||||
+ } catch (final Throwable thr) {
|
||||
+ LOGGER.error("Exception handling chunk load callback", thr);
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
+ } finally {
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ 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 CompletableFuture<ChunkResult<ChunkAccess>> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap);
|
||||
+
|
||||
+ if (loadFuture.isDone()) {
|
||||
+ loadCallback.accept(loadFuture.join().orElse(null));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ loadFuture.whenCompleteAsync((final ChunkResult<ChunkAccess> result, final Throwable thr) -> {
|
||||
+ if (thr != null) {
|
||||
+ loadCallback.accept(null);
|
||||
+ return;
|
||||
+ }
|
||||
+ loadCallback.accept(result.orElse(null));
|
||||
+ }, (final Runnable r) -> {
|
||||
+ BaseChunkSystemHooks.this.scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @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 (!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(++this.chunkLoadCounter) : null;
|
||||
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
+
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ }
|
||||
+ level.chunkSource.runDistanceManagerUpdates();
|
||||
+
|
||||
+ final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> {
|
||||
+ try {
|
||||
+ if (onComplete != null) {
|
||||
+ onComplete.accept(chunk);
|
||||
+ }
|
||||
+ } catch (final Throwable thr) {
|
||||
+ LOGGER.error("Exception handling chunk load callback", thr);
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
+ } finally {
|
||||
+ if (addTicket) {
|
||||
+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
|
||||
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ 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 CompletableFuture<ChunkResult<LevelChunk>> tickingState;
|
||||
+ switch (toStatus) {
|
||||
+ case FULL: {
|
||||
+ tickingState = holder.getFullChunkFuture();
|
||||
+ break;
|
||||
+ }
|
||||
+ case BLOCK_TICKING: {
|
||||
+ tickingState = holder.getTickingChunkFuture();
|
||||
+ break;
|
||||
+ }
|
||||
+ case ENTITY_TICKING: {
|
||||
+ tickingState = holder.getEntityTickingChunkFuture();
|
||||
+ break;
|
||||
+ }
|
||||
+ default: {
|
||||
+ throw new IllegalStateException("Cannot reach here");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (tickingState.isDone()) {
|
||||
+ loadCallback.accept(tickingState.join().orElse(null));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tickingState.whenCompleteAsync((final ChunkResult<LevelChunk> result, final Throwable thr) -> {
|
||||
+ if (thr != null) {
|
||||
+ loadCallback.accept(null);
|
||||
+ return;
|
||||
+ }
|
||||
+ loadCallback.accept(result.orElse(null));
|
||||
+ }, (final Runnable r) -> {
|
||||
+ BaseChunkSystemHooks.this.scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
|
||||
+ return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
|
||||
+ return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getVisibleChunkHolderCount(final ServerLevel level) {
|
||||
+ return level.chunkSource.chunkMap.visibleChunkMap.size();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getUpdatingChunkHolderCount(final ServerLevel level) {
|
||||
+ return level.chunkSource.chunkMap.updatingChunkMap.size();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasAnyChunkHolders(final ServerLevel level) {
|
||||
+ return this.getUpdatingChunkHolderCount(level) != 0;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) {
|
||||
+ return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getSendViewDistance(final ServerPlayer player) {
|
||||
+ return this.getViewDistance(player);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getViewDistance(final ServerPlayer player) {
|
||||
+ final ServerLevel level = player.serverLevel();
|
||||
+ if (level == null) {
|
||||
+ return Bukkit.getViewDistance();
|
||||
+ }
|
||||
+ return level.chunkSource.chunkMap.serverViewDistance;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTickViewDistance(final ServerPlayer player) {
|
||||
+ final ServerLevel level = player.serverLevel();
|
||||
+ if (level == null) {
|
||||
+ return Bukkit.getSimulationDistance();
|
||||
+ }
|
||||
+ return level.chunkSource.chunkMap.distanceManager.simulationDistance;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void updateMaps(final ServerLevel world, final ServerPlayer player) {
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30560,10 +30560,10 @@ index 0000000000000000000000000000000000000000..5a6536377c9c1e1753e930ff2a6bb98e
|
||||
+ }
|
||||
+}
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
index 834c5ce238c7adb0164a6282582d709348ef96cc..11cfe9cc29666ce3a6a40281069fb9eb4fa0ded2 100644
|
||||
index 0e21efc60e7dd7d348fd024d713772069951ccd4..504a5f8626b42817f04088e2539a6941cd9c6d9d 100644
|
||||
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -203,6 +203,43 @@ public final class PaperHooks implements PlatformHooks {
|
||||
@@ -204,6 +204,43 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo
|
||||
@Override
|
||||
public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
|
||||
final int fromVersion, final int toVersion) {
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
+ 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);
|
||||
+ }
|
||||
+ });
|
||||
+ });
|
||||
@@ -111,7 +111,7 @@
|
||||
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(UNLOADED_LEVEL_CHUNK);
|
||||
@@ -126,7 +126,7 @@
|
||||
+ 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
|
||||
@@ -137,7 +137,7 @@
|
||||
- this.tickingChunkFuture.complete(UNLOADED_LEVEL_CHUNK);
|
||||
+ // 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
|
||||
@@ -152,7 +152,7 @@
|
||||
+ 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
|
||||
@@ -163,7 +163,7 @@
|
||||
- this.entityTickingChunkFuture.complete(UNLOADED_LEVEL_CHUNK);
|
||||
+ // 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
|
||||
|
||||
@@ -74,10 +74,10 @@
|
||||
);
|
||||
stringBuilder.append("Updating:").append(System.lineSeparator());
|
||||
- this.updatingChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getUpdatingChunkHolders(this.level).forEach(consumer); // Paper
|
||||
stringBuilder.append("Visible:").append(System.lineSeparator());
|
||||
- this.visibleChunkMap.values().forEach(consumer);
|
||||
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level).forEach(consumer); // Paper
|
||||
CrashReport crashReport = CrashReport.forThrowable(exception, "Chunk loading");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk loading");
|
||||
crashReportCategory.setDetail("Details", details);
|
||||
@@ -86,7 +86,7 @@
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
if (flush) {
|
||||
- List<ChunkHolder> list = this.visibleChunkMap
|
||||
- .values()
|
||||
+ List<ChunkHolder> list = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level) // Paper - moonrise
|
||||
+ List<ChunkHolder> list = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level) // Paper - moonrise
|
||||
+ //.values() // Paper - moonrise
|
||||
.stream()
|
||||
.filter(ChunkHolder::wasAccessibleSinceLastSave)
|
||||
@@ -107,7 +107,7 @@
|
||||
long millis = Util.getMillis();
|
||||
|
||||
- for (ChunkHolder chunkHolder : this.visibleChunkMap.values()) {
|
||||
+ for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level)) { // Paper
|
||||
+ for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper
|
||||
this.saveChunkIfNeeded(chunkHolder, millis);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@
|
||||
public boolean hasWork() {
|
||||
return this.lightEngine.hasLightWork()
|
||||
|| !this.pendingUnloads.isEmpty()
|
||||
+ || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) // Paper - moonrise
|
||||
+ || ca.spottedleaf.moonrise.common.PlatformHooks.get().hasAnyChunkHolders(this.level) // Paper - moonrise
|
||||
|| !this.updatingChunkMap.isEmpty()
|
||||
|| this.poiManager.hasWork()
|
||||
|| !this.toDrop.isEmpty()
|
||||
@@ -127,7 +127,7 @@
|
||||
+ // Paper start
|
||||
+ boolean removed;
|
||||
+ if ((removed = this.pendingUnloads.remove(chunkPos, chunkHolder)) && latestChunk != null) {
|
||||
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ // Paper end
|
||||
if (latestChunk instanceof LevelChunk levelChunk) {
|
||||
levelChunk.setLoaded(false);
|
||||
@@ -138,7 +138,7 @@
|
||||
this.nextChunkSaveTime.remove(latestChunk.getPos().toLong());
|
||||
- }
|
||||
+ } else if (removed) { // Paper start
|
||||
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().onChunkHolderDelete(this.level, chunkHolder);
|
||||
+ } // Paper end
|
||||
}
|
||||
}, this.unloadQueue::add).whenComplete((_void, error) -> {
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
public int size() {
|
||||
- return this.visibleChunkMap.size();
|
||||
+ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper
|
||||
+ return ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolderCount(this.level); // Paper
|
||||
}
|
||||
|
||||
public net.minecraft.server.level.DistanceManager getDistanceManager() {
|
||||
@@ -157,7 +157,7 @@
|
||||
|
||||
protected Iterable<ChunkHolder> getChunks() {
|
||||
- return Iterables.unmodifiableIterable(this.visibleChunkMap.values());
|
||||
+ return Iterables.unmodifiableIterable(ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper
|
||||
+ return Iterables.unmodifiableIterable(ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)); // Paper
|
||||
}
|
||||
|
||||
void dumpChunks(Writer writer) throws IOException {
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||
- for (Entry<ChunkHolder> entry : this.visibleChunkMap.long2ObjectEntrySet()) {
|
||||
- long longKey = entry.getLongKey();
|
||||
+ for (ChunkHolder entry : ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level)) { // Paper - Moonrise
|
||||
+ for (ChunkHolder entry : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.level)) { // Paper - Moonrise
|
||||
+ long longKey = entry.pos.toLong(); // Paper - Moonrise
|
||||
ChunkPos chunkPos = new ChunkPos(longKey);
|
||||
- ChunkHolder chunkHolder = entry.getValue();
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
+
|
||||
+ for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
|
||||
+ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
|
||||
+ ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(
|
||||
+ ca.spottedleaf.moonrise.common.PlatformHooks.get().scheduleChunkLoad(
|
||||
+ this, cx, cz, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true, priority, consumer
|
||||
+ );
|
||||
+ }
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
+ // I don't want to know why this is a generic type.
|
||||
+ Entity entityCasted = (Entity)entity;
|
||||
+ boolean wasRemoved = entityCasted.isRemoved();
|
||||
+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, worldGenSpawned, true);
|
||||
+ boolean screened = ca.spottedleaf.moonrise.common.PlatformHooks.get().screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, worldGenSpawned, true);
|
||||
+ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) {
|
||||
+ // removed by callback
|
||||
+ return false;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
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 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) {
|
||||
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) {
|
||||
if (gen) {
|
||||
scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
} else {
|
||||
if (onComplete != null) {
|
||||
onComplete.accept(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}, 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);
|
||||
|
||||
if (addTicket) {
|
||||
level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
}
|
||||
level.chunkSource.runDistanceManagerUpdates();
|
||||
|
||||
final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> {
|
||||
try {
|
||||
if (onComplete != null) {
|
||||
onComplete.accept(chunk);
|
||||
}
|
||||
} catch (final Throwable thr) {
|
||||
LOGGER.error("Exception handling chunk load callback", thr);
|
||||
com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
} finally {
|
||||
if (addTicket) {
|
||||
level.chunkSource.addTicketAtLevel(net.minecraft.server.level.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));
|
||||
|
||||
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);
|
||||
|
||||
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) -> {
|
||||
if (thr != null) {
|
||||
loadCallback.accept(null);
|
||||
return;
|
||||
}
|
||||
loadCallback.accept(result.orElse(null));
|
||||
}, (final Runnable r) -> {
|
||||
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) {
|
||||
// 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);
|
||||
}, 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);
|
||||
|
||||
if (addTicket) {
|
||||
level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
|
||||
}
|
||||
level.chunkSource.runDistanceManagerUpdates();
|
||||
|
||||
final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> {
|
||||
try {
|
||||
if (onComplete != null) {
|
||||
onComplete.accept(chunk);
|
||||
}
|
||||
} catch (final Throwable thr) {
|
||||
LOGGER.error("Exception handling chunk load callback", thr);
|
||||
com.destroystokyo.paper.util.SneakyThrow.sneaky(thr);
|
||||
} finally {
|
||||
if (addTicket) {
|
||||
level.chunkSource.addTicketAtLevel(net.minecraft.server.level.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));
|
||||
|
||||
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;
|
||||
switch (toStatus) {
|
||||
case FULL: {
|
||||
tickingState = holder.getFullChunkFuture();
|
||||
break;
|
||||
}
|
||||
case BLOCK_TICKING: {
|
||||
tickingState = holder.getTickingChunkFuture();
|
||||
break;
|
||||
}
|
||||
case ENTITY_TICKING: {
|
||||
tickingState = holder.getEntityTickingChunkFuture();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new IllegalStateException("Cannot reach here");
|
||||
}
|
||||
}
|
||||
|
||||
if (tickingState.isDone()) {
|
||||
loadCallback.accept(tickingState.join().orElse(null));
|
||||
return;
|
||||
}
|
||||
|
||||
tickingState.whenCompleteAsync((final net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.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);
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
return level.chunkSource.chunkMap.visibleChunkMap.size();
|
||||
}
|
||||
|
||||
public static 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) {
|
||||
|
||||
}
|
||||
|
||||
public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
public static 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) {
|
||||
final ServerLevel level = player.serverLevel();
|
||||
if (level == null) {
|
||||
return org.bukkit.Bukkit.getViewDistance();
|
||||
}
|
||||
return level.chunkSource.chunkMap.serverViewDistance;
|
||||
}
|
||||
|
||||
public static int getTickViewDistance(final ServerPlayer player) {
|
||||
final ServerLevel level = player.serverLevel();
|
||||
if (level == null) {
|
||||
return org.bukkit.Bukkit.getSimulationDistance();
|
||||
}
|
||||
return level.chunkSource.chunkMap.distanceManager.simulationDistance;
|
||||
}
|
||||
|
||||
private ChunkSystem() {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -216,7 +216,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public int getTileEntityCount() {
|
||||
// We don't use the full world tile entity list, so we must iterate chunks
|
||||
int size = 0;
|
||||
for (ChunkHolder playerchunk : ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.world)) {
|
||||
for (ChunkHolder playerchunk : ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.world)) {
|
||||
net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk();
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
@@ -405,7 +405,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return chunk instanceof ImposterProtoChunk || chunk instanceof net.minecraft.world.level.chunk.LevelChunk;
|
||||
}
|
||||
final java.util.concurrent.CompletableFuture<ChunkAccess> future = new java.util.concurrent.CompletableFuture<>();
|
||||
ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(
|
||||
ca.spottedleaf.moonrise.common.PlatformHooks.get().scheduleChunkLoad(
|
||||
this.world, x, z, false, ChunkStatus.EMPTY, true, ca.spottedleaf.concurrentutil.util.Priority.NORMAL, future::complete
|
||||
);
|
||||
world.getChunkSource().mainThreadProcessor.managedBlock(future::isDone);
|
||||
@@ -420,7 +420,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public Chunk[] getLoadedChunks() {
|
||||
List<ChunkHolder> chunks = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.world); // Paper
|
||||
List<ChunkHolder> chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.world); // Paper
|
||||
return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new);
|
||||
}
|
||||
|
||||
@@ -2447,7 +2447,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public void getChunkAtAsync(int x, int z, boolean gen, boolean urgent, @NotNull Consumer<? super Chunk> cb) {
|
||||
warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper
|
||||
ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(
|
||||
ca.spottedleaf.moonrise.common.PlatformHooks.get().scheduleChunkLoad(
|
||||
this.getHandle(), x, z, gen, ChunkStatus.FULL, true,
|
||||
urgent ? ca.spottedleaf.concurrentutil.util.Priority.HIGHER : ca.spottedleaf.concurrentutil.util.Priority.NORMAL,
|
||||
(ChunkAccess chunk) -> {
|
||||
|
||||
@@ -3522,7 +3522,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public int getViewDistance() {
|
||||
return ca.spottedleaf.moonrise.common.util.ChunkSystem.getViewDistance(this.getHandle());
|
||||
return ca.spottedleaf.moonrise.common.PlatformHooks.get().getViewDistance(this.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3532,7 +3532,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public int getSimulationDistance() {
|
||||
return ca.spottedleaf.moonrise.common.util.ChunkSystem.getTickViewDistance(this.getHandle());
|
||||
return ca.spottedleaf.moonrise.common.PlatformHooks.get().getTickViewDistance(this.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3542,7 +3542,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public int getSendViewDistance() {
|
||||
return ca.spottedleaf.moonrise.common.util.ChunkSystem.getSendViewDistance(this.getHandle());
|
||||
return ca.spottedleaf.moonrise.common.PlatformHooks.get().getSendViewDistance(this.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user