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 2c5c1d4a3..82339b596 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 @@ -1574,9 +1574,10 @@ public class Config public static ConfigEntry maxDataTransferSpeed = new ConfigEntry.Builder() .setServersideShortName("maxDataTransferSpeed") - .setMinDefaultMax(1, 500, 1000000 /* 1 GB/s */) + .setMinDefaultMax(0, 500, 1000000 /* 1 GB/s */) .comment("" - + "Maximum speed for uploading LODs to the clients, in KB/s." + + "Maximum speed for uploading LODs to the clients, in KB/s.\n" + + "Value of 0 disables the limit." + "") .build(); 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 f0b7bd82c..790bffccc 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 @@ -29,7 +29,7 @@ public class SessionConfig implements INetworkObject static { - // Note: config values are ordered by serversideShortName when transmitted + // Note: config values are transmitted in the insertion order registerConfigEntry(Config.Server.realTimeUpdateDistanceRadiusInChunks, Math::min); @@ -41,7 +41,17 @@ public class SessionConfig implements INetworkObject registerConfigEntry(Config.Server.synchronizeOnLoad, (x, y) -> x && y); registerConfigEntry(Config.Server.syncOnLoadRateLimit, Math::min); - registerConfigEntry(Config.Server.maxDataTransferSpeed, Math::min); + registerConfigEntry(Config.Server.maxDataTransferSpeed, (x, y) -> { + if (x == 0 && y == 0) + { + return 0; + } + + return Math.min( + x > 0 ? x : Integer.MAX_VALUE, + y > 0 ? y : Integer.MAX_VALUE + ); + }); } public SessionConfig() {} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/fullData/FullDataPayloadSender.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/fullData/FullDataPayloadSender.java index d2e89190e..c969e34d9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/fullData/FullDataPayloadSender.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/fullData/FullDataPayloadSender.java @@ -15,6 +15,10 @@ public class FullDataPayloadSender implements AutoCloseable { private static final int TICK_RATE = 4; + /** 1 Mebibyte minus 576 bytes for other info */ + public static final int FULL_DATA_SPLIT_SIZE_IN_BYTES = 1_048_000; + + private static final Timer UPLOAD_TIMER = TimerUtil.CreateTimer("FullDataPayloadSender"); private final TimerTask tickTimerTask = TimerUtil.createTimerTask(this::tick); @@ -22,6 +26,7 @@ public class FullDataPayloadSender implements AutoCloseable private final IntSupplier maxKBpsSupplier; private final ConcurrentLinkedQueue transferQueue = new ConcurrentLinkedQueue<>(); + public FullDataPayloadSender(NetworkSession session, IntSupplier maxKBpsSupplier) { this.session = session; @@ -49,7 +54,11 @@ public class FullDataPayloadSender implements AutoCloseable private void tick() { - int bytesToSend = (this.maxKBpsSupplier.getAsInt() * 1000) / TICK_RATE; + int convertedMaxRate = this.maxKBpsSupplier.getAsInt(); + convertedMaxRate = convertedMaxRate > 0 ? convertedMaxRate : Integer.MAX_VALUE / 1000; + + // + 1 to account for rounding errors on values of < 4 + int bytesToSend = (convertedMaxRate * 1000) / TICK_RATE + 1; while (bytesToSend > 0) { PendingTransfer pendingTransfer = this.transferQueue.peek(); @@ -58,7 +67,7 @@ public class FullDataPayloadSender implements AutoCloseable return; } - int chunkSize = Math.min(bytesToSend, pendingTransfer.buffer.readableBytes()); + int chunkSize = Math.min(Math.min(bytesToSend, FULL_DATA_SPLIT_SIZE_IN_BYTES), pendingTransfer.buffer.readableBytes()); boolean isFirstChunk = pendingTransfer.buffer.readerIndex() == 0; FullDataSplitMessage chunkMessage = new FullDataSplitMessage(pendingTransfer.bufferId, pendingTransfer.buffer.readRetainedSlice(chunkSize), isFirstChunk); diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json index 3be0ebb7b..10236c0ca 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -692,7 +692,7 @@ "distanthorizons.config.server.maxDataTransferSpeed": "Maximum Data Transfer Speed, KB/s", "distanthorizons.config.server.maxDataTransferSpeed.@tooltip": - "Maximum speed for uploading LODs to the clients, in KB/s", + "Maximum speed for uploading LODs to the clients, in KB/s.\nValue of 0 disables the limit.",