diff --git a/.editorconfig b/.editorconfig index 2228be96c..4661e28bb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -537,7 +537,7 @@ ij_groovy_wrap_chain_calls_after_dot = false ij_groovy_wrap_long_lines = false [{*.har,*.json,*.png.mcmeta,mcmod.info,pack.mcmeta}] -indent_size = 4 +indent_size = 2 ij_json_array_wrapping = split_into_lines ij_json_keep_blank_lines_in_code = 0 ij_json_keep_indents_on_empty_lines = false diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java index cc45ea3dc..4035ab5ee 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java @@ -75,9 +75,7 @@ public class ClientPluginChannelApi private void onCurrentLevelKeyMessage(CurrentLevelKeyMessage msg) { - // prefix@namespace:path - // 1-50 characters in total, all parts except namespace can be omitted - if (!msg.levelKey.matches("^(?=.{1,50}$)([a-zA-Z0-9-_]+@)?[a-zA-Z0-9-_]+(:[a-zA-Z0-9-_]+)?$")) + if (!msg.levelKey.matches(CurrentLevelKeyMessage.VALIDATION_REGEX)) { throw new IllegalArgumentException("Server sent invalid level key."); } 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 063579181..0933b0c53 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 @@ -34,6 +34,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.util.StringUtil; @@ -64,7 +65,7 @@ public class Config public static ConfigCategory client = new ConfigCategory.Builder().set(Client.class).build(); - + @SuppressWarnings("ConcatenationWithEmptyString") public static class Client { public static ConfigEntry quickEnableRendering = new ConfigEntry.Builder() @@ -1007,24 +1008,6 @@ public class Config public static class ServerNetworking { public static ConfigUIComment generalSectionNote = new ConfigUIComment(); - public static ConfigEntry enableServerNetworking = new ConfigEntry.Builder() - .setServersideShortName("enableServerNetworking") - .set(true) - .comment("" - + "WARNING!\n" - + "Server-client networking is not yet fully implemented!\n" - + "Both the server and client must be running the server-side fork with this option enabled\n" - + "for Distant Horizons data to be transceived.\n" - + "\n" - + "If true, the server and client will attempt to communicate to transceive Distant Horizons data.\n" - + "This allows for further distant generation and LOD updates on all clients.\n" - + "\n" - + "This should only be used on trusted servers with trusted players!\n" - + "") - .setSide(EConfigEntryRelevantSide.BOTH) - .build(); - - public static ConfigEntry sendLevelKeys = new ConfigEntry.Builder() .setServersideShortName("sendLevelKeys") .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) @@ -1037,7 +1020,6 @@ public class Config .build(); public static ConfigEntry levelKeyPrefix = new ConfigEntry.Builder() .setServersideShortName("levelKeyPrefix") - .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) .set(getDefaultLevelKeyPrefix()) .comment("" + "Prefix of the level keys sent to the clients.\n" @@ -1756,13 +1738,15 @@ public class Config private static String getDefaultLevelKeyPrefix() { IMinecraftSharedWrapper mcWrapper = SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class); - if (mcWrapper.isDedicatedServer() && mcWrapper.isWorldNew()) + if (mcWrapper.isDedicatedServer()) { - return "server" + ThreadLocalRandom.current().nextInt(1, 1000); + return mcWrapper.isWorldNew() + ? "server" + ThreadLocalRandom.current().nextInt(1, 1000) + : ""; } else { - return ""; + return SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class).getUsername(); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/CurrentLevelKeyMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/CurrentLevelKeyMessage.java index 50d05fd3c..68539bfc9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/CurrentLevelKeyMessage.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/CurrentLevelKeyMessage.java @@ -6,6 +6,15 @@ import io.netty.buffer.ByteBuf; public class CurrentLevelKeyMessage extends AbstractNetworkMessage { + public static final int MAX_LENGTH = 150; + + public static final String PART_ALLOWED_CHARS_REGEX = "a-zA-Z0-9-_"; + + // prefix@namespace:path + // 1-150 characters in total, all parts except namespace can be omitted + public static final String VALIDATION_REGEX = "^(?=.{1,$MAX_LENGTH}$)([$PART_ALLOWED_CHARS_REGEX]+@)?[$PART_ALLOWED_CHARS_REGEX]+(:[$PART_ALLOWED_CHARS_REGEX]+)?$"; + + public String levelKey; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java index 52dd7e0d8..bec5ddcff 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java @@ -76,6 +76,8 @@ public interface IMinecraftClientWrapper extends IBindable UUID getPlayerUUID(); + String getUsername(); + DhBlockPos getPlayerBlockPos(); DhChunkPos getPlayerChunkPos(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java index 64577497d..2d9527eb4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/world/IServerLevelWrapper.java @@ -19,7 +19,11 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.world; +import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.network.messages.base.CurrentLevelKeyMessage; +import com.seibel.distanthorizons.core.world.EWorldEnvironment; + import java.io.File; public interface IServerLevelWrapper extends ILevelWrapper @@ -33,9 +37,23 @@ public interface IServerLevelWrapper extends ILevelWrapper if (Config.Client.Advanced.Multiplayer.ServerNetworking.sendLevelKeys.get()) { String levelKeyPrefix = Config.Client.Advanced.Multiplayer.ServerNetworking.levelKeyPrefix.get(); + + if (SharedApi.getEnvironment() == EWorldEnvironment.CLIENT_SERVER) + { + String cleanWorldFolderName = this.getMcSaveFolder().getParentFile().getName() + .replaceAll("[^" + CurrentLevelKeyMessage.PART_ALLOWED_CHARS_REGEX + " ]", "") + .replaceAll(" ", "_"); + levelKeyPrefix += (!levelKeyPrefix.isEmpty() ? "_" : "") + cleanWorldFolderName; + } + if (!levelKeyPrefix.isEmpty()) { - return levelKeyPrefix + "@" + dimensionName; + String mainPart = "@" + dimensionName; + + return levelKeyPrefix.substring(0, Math.min( + CurrentLevelKeyMessage.MAX_LENGTH - mainPart.length(), + levelKeyPrefix.length() + )) + mainPart; } } 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 7e5f9bede..3dab8e8bd 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -413,8 +413,7 @@ "distanthorizons.config.client.advanced.multiplayer.serverNetworking": "Server Networking", "distanthorizons.config.client.advanced.multiplayer.serverNetworking.generalSectionNote": " \u25cf General", - "distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableServerNetworking": "Enable Server Networking", - "distanthorizons.config.client.advanced.multiplayer.serverNetworking.enableServerNetworking.@tooltip": "§6Attention:§r this feature is not fully implemented. \n\nIf true Distant Horizons will attempt to communicate with the connected \nserver in order to load LODs outside your vanilla render distance. \n\nNote: This requires DH to be installed on the server in order to function.", + "distanthorizons.config.client.advanced.multiplayer.serverNetworking.levelKeyPrefix": "Level Key Prefix", "distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationSectionNote": " \u25cf Generation", "distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestRateLimit": "Rate Limit for Generation Requests", "distanthorizons.config.client.advanced.multiplayer.serverNetworking.generationRequestRateLimit.@tooltip": "How many LOD generation requests per second should a client send? \nAlso limits the amount of player's requests allowed to stay in the server's queue.",