From 3d8d8bc0f7519f80bd61557e127947d37f3080d0 Mon Sep 17 00:00:00 2001 From: s809 <43530948+s809@users.noreply.github.com> Date: Sat, 18 Jan 2025 16:42:57 +0500 Subject: [PATCH] Add generation bounds --- .../distanthorizons/coreapi/ModInfo.java | 2 +- .../distanthorizons/core/config/Config.java | 26 +++++++++++++++++++ .../generation/RemoteWorldRetrievalQueue.java | 18 +++++++++++-- .../core/level/AbstractDhServerLevel.java | 11 ++++++++ .../AbstractFullDataNetworkRequestQueue.java | 6 ++--- .../client/SyncOnLoadRequestQueue.java | 6 ++++- .../multiplayer/config/SessionConfig.java | 6 +++++ 7 files changed, 68 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java b/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java index 55a31d08c..4b029dfec 100644 --- a/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java +++ b/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java @@ -31,7 +31,7 @@ public final class ModInfo public static final String DEDICATED_SERVER_INITIAL_PATH = "dedicated_server_initial"; /** Incremented every time any packets are added, changed or removed, with a few exceptions. */ - public static final int PROTOCOL_VERSION = 8; + public static final int PROTOCOL_VERSION = 9; public static final String WRAPPER_PACKET_PATH = "message"; /** The internal mod name */ diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index a8410fbcc..ac2b7c464 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -1577,6 +1577,32 @@ public class Config + "") .build(); + public static ConfigEntry generationBoundsX = new ConfigEntry.Builder() + .setChatCommandName("generation.bounds.x") + .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) + .setMinDefaultMax(Integer.MIN_VALUE, 0, Integer.MAX_VALUE) + .comment("" + + "Defines the X-coordinate of the central point for generation boundaries, in blocks. \n" + + "") + .build(); + public static ConfigEntry generationBoundsZ = new ConfigEntry.Builder() + .setChatCommandName("generation.bounds.z") + .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) + .setMinDefaultMax(Integer.MIN_VALUE, 0, Integer.MAX_VALUE) + .comment("" + + "Defines the Z-coordinate of the central point for generation boundaries, in blocks. \n" + + "") + .build(); + public static ConfigEntry generationBoundsRadius = new ConfigEntry.Builder() + .setChatCommandName("generation.bounds.radius") + .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) + .setMinDefaultMax(0, 0, Integer.MAX_VALUE) + .comment("" + + "Defines the radius around the central point within which generation is allowed, in blocks. \n" + + "If this value is set to 0, generation bounds are disabled." + + "") + .build(); + // Real-time updates public static ConfigEntry enableRealTimeUpdates = new ConfigEntry.Builder() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/RemoteWorldRetrievalQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/RemoteWorldRetrievalQueue.java index 4d30db140..9b913729d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/RemoteWorldRetrievalQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/RemoteWorldRetrievalQueue.java @@ -26,7 +26,7 @@ public class RemoteWorldRetrievalQueue extends AbstractFullDataNetworkRequestQue private int estimatedTotalChunkCount; private final RollingAverage rollingAverageChunkGenTimeInMs = new RollingAverage(1_000); - public RollingAverage getRollingAverageChunkGenTimeInMs() { return this.rollingAverageChunkGenTimeInMs; } + @Override public RollingAverage getRollingAverageChunkGenTimeInMs() { return this.rollingAverageChunkGenTimeInMs; } @@ -96,7 +96,21 @@ public class RemoteWorldRetrievalQueue extends AbstractFullDataNetworkRequestQue @Override protected int getRequestRateLimit() { return this.networkState.sessionConfig.getGenerationRequestRateLimit(); } @Override - protected int getMaxRequestDistance() { return this.networkState.sessionConfig.getMaxGenerationRequestDistance(); } + protected boolean isSectionAllowedToGenerate(long sectionPos, DhBlockPos2D targetPos) + { + if (this.networkState.sessionConfig.getGenerationBoundsRadius() > 0) + { + if (DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, new DhBlockPos2D( + this.networkState.sessionConfig.getGenerationBoundsX(), + this.networkState.sessionConfig.getGenerationBoundsZ() + )) > this.networkState.sessionConfig.getGenerationBoundsRadius()) + { + return false; + } + } + + return DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, targetPos) <= this.networkState.sessionConfig.getMaxGenerationRequestDistance() * 16; + } @Override protected String getQueueName() { return "World Remote Generation Queue"; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java index b91899535..b843c0135 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhServerLevel.java @@ -151,6 +151,17 @@ public abstract class AbstractDhServerLevel extends AbstractDhLevel implements I return; } + if (Config.Server.generationBoundsRadius.get() > 0) + { + if (DhSectionPos.getChebyshevSignedBlockDistance(message.sectionPos, new DhBlockPos2D( + Config.Server.generationBoundsX.get(), Config.Server.generationBoundsZ.get() + )) > Config.Server.generationBoundsRadius.get()) + { + message.sendResponse(new RequestOutOfRangeException("Section out of allowed bounds")); + return; + } + } + if (Config.Server.generateOnlyInHighestDetail.get() && DhSectionPos.getDetailLevel(message.sectionPos) != DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) { message.sendResponse(new SectionRequiresSplittingException("Only highest-detail sections are allowed")); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java index 906223315..d85029551 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java @@ -95,7 +95,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende //==================// protected abstract int getRequestRateLimit(); - protected abstract int getMaxRequestDistance(); + protected abstract boolean isSectionAllowedToGenerate(long sectionPos, DhBlockPos2D targetPos); protected abstract String getQueueName(); @@ -197,7 +197,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende long sectionPos = mapEntry.getKey(); RequestQueueEntry entry = mapEntry.getValue(); - if (DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, targetPos) > this.getMaxRequestDistance() * 16) + if (!this.isSectionAllowedToGenerate(sectionPos, targetPos)) { entry.future.cancel(false); this.pendingTasksSemaphore.release(); @@ -406,7 +406,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende { renderer.renderBox(new DebugRenderer.Box(mapEntry.getKey(), -32f, 64f, 0.05f, mapEntry.getValue().networkDataSourceFuture != null ? Color.red - : DhSectionPos.getChebyshevSignedBlockDistance(mapEntry.getKey(), Objects.requireNonNull(this.level.getTargetPosForGeneration())) <= this.getMaxRequestDistance() * 16 ? Color.gray + : this.isSectionAllowedToGenerate(mapEntry.getKey(), Objects.requireNonNull(this.level.getTargetPosForGeneration())) ? Color.gray : Color.darkGray )); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/SyncOnLoadRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/SyncOnLoadRequestQueue.java index ba04c6ba8..b6c63242f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/SyncOnLoadRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/SyncOnLoadRequestQueue.java @@ -3,6 +3,7 @@ package com.seibel.distanthorizons.core.multiplayer.client; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.generation.RemoteWorldRetrievalQueue; import com.seibel.distanthorizons.core.level.DhClientLevel; +import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; /** @@ -32,7 +33,10 @@ public class SyncOnLoadRequestQueue extends AbstractFullDataNetworkRequestQueue @Override protected int getRequestRateLimit() { return this.networkState.sessionConfig.getSyncOnLoginRateLimit(); } @Override - protected int getMaxRequestDistance() { return this.networkState.sessionConfig.getMaxSyncOnLoadDistance(); } + protected boolean isSectionAllowedToGenerate(long sectionPos, DhBlockPos2D targetPos) + { + return DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, targetPos) <= this.networkState.sessionConfig.getMaxSyncOnLoadDistance() * 16; + } @Override protected String getQueueName() { return "Sync On Login Queue"; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/config/SessionConfig.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/config/SessionConfig.java index 0076d0738..25a38bfc1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/config/SessionConfig.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/config/SessionConfig.java @@ -33,6 +33,9 @@ public class SessionConfig implements INetworkObject registerConfigEntry(Config.Common.WorldGenerator.enableDistantGeneration, Boolean::logicalAnd); registerConfigEntry(Config.Server.maxGenerationRequestDistance, Math::min); + registerConfigEntry(Config.Server.generationBoundsX, (x, y) -> x); + registerConfigEntry(Config.Server.generationBoundsZ, (x, y) -> x); + registerConfigEntry(Config.Server.generationBoundsRadius, (x, y) -> x); registerConfigEntry(Config.Server.generationRequestRateLimit, Math::min); registerConfigEntry(Config.Server.enableRealTimeUpdates, Boolean::logicalAnd); @@ -65,6 +68,9 @@ public class SessionConfig implements INetworkObject public boolean isDistantGenerationEnabled() { return this.getValue(Config.Common.WorldGenerator.enableDistantGeneration); } public int getMaxGenerationRequestDistance() { return this.getValue(Config.Server.maxGenerationRequestDistance); } + public Integer getGenerationBoundsX() { return this.getValue(Config.Server.generationBoundsX); } + public Integer getGenerationBoundsZ() { return this.getValue(Config.Server.generationBoundsZ); } + public Integer getGenerationBoundsRadius() { return this.getValue(Config.Server.generationBoundsRadius); } public int getGenerationRequestRateLimit() { return this.getValue(Config.Server.generationRequestRateLimit); } public boolean isRealTimeUpdatesEnabled() { return this.getValue(Config.Server.enableRealTimeUpdates); }