aboutsummaryrefslogtreecommitdiffhomepage
path: root/paper-server/patches/features/0001-Add-PaperHooks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'paper-server/patches/features/0001-Add-PaperHooks.patch')
-rw-r--r--paper-server/patches/features/0001-Add-PaperHooks.patch345
1 files changed, 342 insertions, 3 deletions
diff --git a/paper-server/patches/features/0001-Add-PaperHooks.patch b/paper-server/patches/features/0001-Add-PaperHooks.patch
index db8dd7f311..5df4d535a5 100644
--- a/paper-server/patches/features/0001-Add-PaperHooks.patch
+++ b/paper-server/patches/features/0001-Add-PaperHooks.patch
@@ -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) {
++
++ }
++}