--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
@@ -5,6 +5,7 @@
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.mojang.logging.LogUtils;
+import com.mojang.serialization.DataResult;
 import com.mojang.serialization.Dynamic;
 import com.mojang.serialization.JsonOps;
 import java.nio.charset.StandardCharsets;
@@ -12,6 +13,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.UUID;
@@ -41,10 +43,16 @@
 import net.minecraft.world.level.levelgen.presets.WorldPresets;
 import org.slf4j.Logger;
 
+// CraftBukkit start
+import joptsimple.OptionSet;
+// CraftBukkit end
+
 public class DedicatedServerProperties extends Settings<DedicatedServerProperties> {
+
     static final Logger LOGGER = LogUtils.getLogger();
     private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$");
     private static final Splitter COMMA_SPLITTER = Splitter.on(',').trimResults();
+    public final boolean debug = this.get("debug", false); // CraftBukkit
     public final boolean onlineMode = this.get("online-mode", true);
     public final boolean preventProxyConnections = this.get("prevent-proxy-connections", false);
     public final String serverIp = this.get("server-ip", "");
@@ -56,85 +64,129 @@
     public final String bugReportLink = this.get("bug-report-link", "");
     public final boolean forceGameMode = this.get("force-gamemode", false);
     public final boolean enforceWhitelist = this.get("enforce-whitelist", false);
-    public final Difficulty difficulty = this.get(
-        "difficulty", dispatchNumberOrString(Difficulty::byId, Difficulty::byName), Difficulty::getKey, Difficulty.EASY
-    );
-    public final GameType gamemode = this.get("gamemode", dispatchNumberOrString(GameType::byId, GameType::byName), GameType::getName, GameType.SURVIVAL);
-    public final String levelName = this.get("level-name", "world");
-    public final int serverPort = this.get("server-port", 25565);
+    public final Difficulty difficulty;
+    public final GameType gamemode;
+    public final String levelName;
+    public final int serverPort;
     @Nullable
-    public final Boolean announcePlayerAchievements = this.getLegacyBoolean("announce-player-achievements");
-    public final boolean enableQuery = this.get("enable-query", false);
-    public final int queryPort = this.get("query.port", 25565);
-    public final boolean enableRcon = this.get("enable-rcon", false);
-    public final int rconPort = this.get("rcon.port", 25575);
-    public final String rconPassword = this.get("rcon.password", "");
-    public final boolean hardcore = this.get("hardcore", false);
-    public final boolean allowNether = this.get("allow-nether", true);
-    public final boolean spawnMonsters = this.get("spawn-monsters", true);
-    public final boolean useNativeTransport = this.get("use-native-transport", true);
-    public final boolean enableCommandBlock = this.get("enable-command-block", false);
-    public final int spawnProtection = this.get("spawn-protection", 16);
-    public final int opPermissionLevel = this.get("op-permission-level", 4);
-    public final int functionPermissionLevel = this.get("function-permission-level", 2);
-    public final long maxTickTime = this.get("max-tick-time", TimeUnit.MINUTES.toMillis(1L));
-    public final int maxChainedNeighborUpdates = this.get("max-chained-neighbor-updates", 1000000);
-    public final int rateLimitPacketsPerSecond = this.get("rate-limit", 0);
-    public final int viewDistance = this.get("view-distance", 10);
-    public final int simulationDistance = this.get("simulation-distance", 10);
-    public final int maxPlayers = this.get("max-players", 20);
-    public final int networkCompressionThreshold = this.get("network-compression-threshold", 256);
-    public final boolean broadcastRconToOps = this.get("broadcast-rcon-to-ops", true);
-    public final boolean broadcastConsoleToOps = this.get("broadcast-console-to-ops", true);
-    public final int maxWorldSize = this.get("max-world-size", maxWorldSize -> Mth.clamp(maxWorldSize, 1, 29999984), 29999984);
-    public final boolean syncChunkWrites = this.get("sync-chunk-writes", true);
-    public final String regionFileComression = this.get("region-file-compression", "deflate");
-    public final boolean enableJmxMonitoring = this.get("enable-jmx-monitoring", false);
-    public final boolean enableStatus = this.get("enable-status", true);
-    public final boolean hideOnlinePlayers = this.get("hide-online-players", false);
-    public final int entityBroadcastRangePercentage = this.get("entity-broadcast-range-percentage", percentage -> Mth.clamp(percentage, 10, 1000), 100);
-    public final String textFilteringConfig = this.get("text-filtering-config", "");
+    public final Boolean announcePlayerAchievements;
+    public final boolean enableQuery;
+    public final int queryPort;
+    public final boolean enableRcon;
+    public final int rconPort;
+    public final String rconPassword;
+    public final boolean hardcore;
+    public final boolean allowNether;
+    public final boolean spawnMonsters;
+    public final boolean useNativeTransport;
+    public final boolean enableCommandBlock;
+    public final int spawnProtection;
+    public final int opPermissionLevel;
+    public final int functionPermissionLevel;
+    public final long maxTickTime;
+    public final int maxChainedNeighborUpdates;
+    public final int rateLimitPacketsPerSecond;
+    public final int viewDistance;
+    public final int simulationDistance;
+    public final int maxPlayers;
+    public final int networkCompressionThreshold;
+    public final boolean broadcastRconToOps;
+    public final boolean broadcastConsoleToOps;
+    public final int maxWorldSize;
+    public final boolean syncChunkWrites;
+    public final String regionFileComression;
+    public final boolean enableJmxMonitoring;
+    public final boolean enableStatus;
+    public final boolean hideOnlinePlayers;
+    public final int entityBroadcastRangePercentage;
+    public final String textFilteringConfig;
     public final Optional<MinecraftServer.ServerResourcePackInfo> serverResourcePackInfo;
     public final DataPackConfig initialDataPackConfiguration;
-    public final Settings<DedicatedServerProperties>.MutableValue<Integer> playerIdleTimeout = this.getMutable("player-idle-timeout", 0);
-    public final Settings<DedicatedServerProperties>.MutableValue<Boolean> whiteList = this.getMutable("white-list", false);
-    public final boolean enforceSecureProfile = this.get("enforce-secure-profile", true);
-    public final boolean logIPs = this.get("log-ips", true);
+    public final Settings<DedicatedServerProperties>.MutableValue<Integer> playerIdleTimeout;
+    public final Settings<DedicatedServerProperties>.MutableValue<Boolean> whiteList;
+    public final boolean enforceSecureProfile;
+    public final boolean logIPs;
     private final DedicatedServerProperties.WorldDimensionData worldDimensionData;
     public final WorldOptions worldOptions;
-    public boolean acceptsTransfers = this.get("accepts-transfers", false);
+    public boolean acceptsTransfers;
 
-    public DedicatedServerProperties(Properties properties) {
-        super(properties);
-        String string = this.get("level-seed", "");
-        boolean bl = this.get("generate-structures", true);
-        long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed());
-        this.worldOptions = new WorldOptions(l, bl, false);
-        this.worldDimensionData = new DedicatedServerProperties.WorldDimensionData(
-            this.get("generator-settings", generatorSettings -> GsonHelper.parse(!generatorSettings.isEmpty() ? generatorSettings : "{}"), new JsonObject()),
-            this.get("level-type", type -> type.toLowerCase(Locale.ROOT), WorldPresets.NORMAL.location().toString())
-        );
-        this.serverResourcePackInfo = getServerPackInfo(
-            this.get("resource-pack-id", ""),
-            this.get("resource-pack", ""),
-            this.get("resource-pack-sha1", ""),
-            this.getLegacyString("resource-pack-hash"),
-            this.get("require-resource-pack", false),
-            this.get("resource-pack-prompt", "")
-        );
-        this.initialDataPackConfiguration = getDatapackConfig(
-            this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())),
-            this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled()))
-        );
+    public final String rconIp; // Paper - Configurable rcon ip
+
+    // CraftBukkit start
+    public DedicatedServerProperties(Properties properties, OptionSet optionset) {
+        super(properties, optionset);
+        // CraftBukkit end
+        this.difficulty = (Difficulty) this.get("difficulty", dispatchNumberOrString(Difficulty::byId, Difficulty::byName), Difficulty::getKey, Difficulty.EASY);
+        this.gamemode = (GameType) this.get("gamemode", dispatchNumberOrString(GameType::byId, GameType::byName), GameType::getName, GameType.SURVIVAL);
+        this.levelName = this.get("level-name", "world");
+        this.serverPort = this.get("server-port", 25565);
+        this.announcePlayerAchievements = this.getLegacyBoolean("announce-player-achievements");
+        this.enableQuery = this.get("enable-query", false);
+        this.queryPort = this.get("query.port", 25565);
+        this.enableRcon = this.get("enable-rcon", false);
+        this.rconPort = this.get("rcon.port", 25575);
+        this.rconPassword = this.get("rcon.password", "");
+        this.hardcore = this.get("hardcore", false);
+        this.allowNether = this.get("allow-nether", true);
+        this.spawnMonsters = this.get("spawn-monsters", true);
+        this.useNativeTransport = this.get("use-native-transport", true);
+        this.enableCommandBlock = this.get("enable-command-block", false);
+        this.spawnProtection = this.get("spawn-protection", 16);
+        this.opPermissionLevel = this.get("op-permission-level", 4);
+        this.functionPermissionLevel = this.get("function-permission-level", 2);
+        this.maxTickTime = this.get("max-tick-time", TimeUnit.MINUTES.toMillis(1L));
+        this.maxChainedNeighborUpdates = this.get("max-chained-neighbor-updates", 1000000);
+        this.rateLimitPacketsPerSecond = this.get("rate-limit", 0);
+        this.viewDistance = this.get("view-distance", 10);
+        this.simulationDistance = this.get("simulation-distance", 10);
+        this.maxPlayers = this.get("max-players", 20);
+        this.networkCompressionThreshold = this.get("network-compression-threshold", 256);
+        this.broadcastRconToOps = this.get("broadcast-rcon-to-ops", true);
+        this.broadcastConsoleToOps = this.get("broadcast-console-to-ops", true);
+        this.maxWorldSize = this.get("max-world-size", (integer) -> {
+            return Mth.clamp(integer, 1, 29999984);
+        }, 29999984);
+        this.syncChunkWrites = this.get("sync-chunk-writes", true) && Boolean.getBoolean("Paper.enable-sync-chunk-writes"); // Paper - Hide sync chunk writes behind flag
+        this.regionFileComression = this.get("region-file-compression", "deflate");
+        this.enableJmxMonitoring = this.get("enable-jmx-monitoring", false);
+        this.enableStatus = this.get("enable-status", true);
+        this.hideOnlinePlayers = this.get("hide-online-players", false);
+        this.entityBroadcastRangePercentage = this.get("entity-broadcast-range-percentage", (integer) -> {
+            return Mth.clamp(integer, 10, 1000);
+        }, 100);
+        this.textFilteringConfig = this.get("text-filtering-config", "");
+        this.playerIdleTimeout = this.getMutable("player-idle-timeout", 0);
+        this.whiteList = this.getMutable("white-list", false);
+        this.enforceSecureProfile = this.get("enforce-secure-profile", true);
+        this.logIPs = this.get("log-ips", true);
+        this.acceptsTransfers = this.get("accepts-transfers", false);
+        String s = this.get("level-seed", "");
+        boolean flag = this.get("generate-structures", true);
+        long i = WorldOptions.parseSeed(s).orElse(WorldOptions.randomSeed());
+
+        this.worldOptions = new WorldOptions(i, flag, false);
+        this.worldDimensionData = new DedicatedServerProperties.WorldDimensionData((JsonObject) this.get("generator-settings", (s1) -> {
+            return GsonHelper.parse(!s1.isEmpty() ? s1 : "{}");
+        }, new JsonObject()), (String) this.get("level-type", (s1) -> {
+            return s1.toLowerCase(Locale.ROOT);
+        }, WorldPresets.NORMAL.location().toString()));
+        this.serverResourcePackInfo = DedicatedServerProperties.getServerPackInfo(this.get("resource-pack-id", ""), this.get("resource-pack", ""), this.get("resource-pack-sha1", ""), this.getLegacyString("resource-pack-hash"), this.get("require-resource-pack", false), this.get("resource-pack-prompt", ""));
+        this.initialDataPackConfiguration = DedicatedServerProperties.getDatapackConfig(this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())), this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled())));
+        // Paper start - Configurable rcon ip
+        final String rconIp = this.getStringRaw("rcon.ip");
+        this.rconIp = rconIp == null ? this.serverIp : rconIp;
+        // Paper end - Configurable rcon ip
     }
 
-    public static DedicatedServerProperties fromFile(Path path) {
-        return new DedicatedServerProperties(loadFromFile(path));
+    // CraftBukkit start
+    public static DedicatedServerProperties fromFile(Path path, OptionSet optionset) {
+        return new DedicatedServerProperties(loadFromFile(path), optionset);
     }
 
     @Override
-    protected DedicatedServerProperties reload(RegistryAccess registryAccess, Properties properties) {
-        return new DedicatedServerProperties(properties);
+    public DedicatedServerProperties reload(RegistryAccess iregistrycustom, Properties properties, OptionSet optionset) {
+        return new DedicatedServerProperties(properties, optionset);
+        // CraftBukkit end
     }
 
     @Nullable
@@ -142,63 +194,62 @@
         if (!Strings.isNullOrEmpty(prompt)) {
             try {
                 return Component.Serializer.fromJson(prompt, RegistryAccess.EMPTY);
-            } catch (Exception var2) {
-                LOGGER.warn("Failed to parse resource pack prompt '{}'", prompt, var2);
+            } catch (Exception exception) {
+                DedicatedServerProperties.LOGGER.warn("Failed to parse resource pack prompt '{}'", prompt, exception);
             }
         }
 
         return null;
     }
 
-    private static Optional<MinecraftServer.ServerResourcePackInfo> getServerPackInfo(
-        String id, String url, String sha1, @Nullable String hash, boolean required, String prompt
-    ) {
+    private static Optional<MinecraftServer.ServerResourcePackInfo> getServerPackInfo(String id, String url, String sha1, @Nullable String hash, boolean required, String prompt) {
         if (url.isEmpty()) {
             return Optional.empty();
         } else {
-            String string;
+            String s5;
+
             if (!sha1.isEmpty()) {
-                string = sha1;
+                s5 = sha1;
                 if (!Strings.isNullOrEmpty(hash)) {
-                    LOGGER.warn("resource-pack-hash is deprecated and found along side resource-pack-sha1. resource-pack-hash will be ignored.");
+                    DedicatedServerProperties.LOGGER.warn("resource-pack-hash is deprecated and found along side resource-pack-sha1. resource-pack-hash will be ignored.");
                 }
             } else if (!Strings.isNullOrEmpty(hash)) {
-                LOGGER.warn("resource-pack-hash is deprecated. Please use resource-pack-sha1 instead.");
-                string = hash;
+                DedicatedServerProperties.LOGGER.warn("resource-pack-hash is deprecated. Please use resource-pack-sha1 instead.");
+                s5 = hash;
             } else {
-                string = "";
+                s5 = "";
             }
 
-            if (string.isEmpty()) {
-                LOGGER.warn(
-                    "You specified a resource pack without providing a sha1 hash. Pack will be updated on the client only if you change the name of the pack."
-                );
-            } else if (!SHA1.matcher(string).matches()) {
-                LOGGER.warn("Invalid sha1 for resource-pack-sha1");
+            if (s5.isEmpty()) {
+                DedicatedServerProperties.LOGGER.warn("You specified a resource pack without providing a sha1 hash. Pack will be updated on the client only if you change the name of the pack.");
+            } else if (!DedicatedServerProperties.SHA1.matcher(s5).matches()) {
+                DedicatedServerProperties.LOGGER.warn("Invalid sha1 for resource-pack-sha1");
             }
 
-            Component component = parseResourcePackPrompt(prompt);
-            UUID uUID;
+            Component ichatbasecomponent = DedicatedServerProperties.parseResourcePackPrompt(prompt);
+            UUID uuid;
+
             if (id.isEmpty()) {
-                uUID = UUID.nameUUIDFromBytes(url.getBytes(StandardCharsets.UTF_8));
-                LOGGER.warn("resource-pack-id missing, using default of {}", uUID);
+                uuid = UUID.nameUUIDFromBytes(url.getBytes(StandardCharsets.UTF_8));
+                DedicatedServerProperties.LOGGER.warn("resource-pack-id missing, using default of {}", uuid);
             } else {
                 try {
-                    uUID = UUID.fromString(id);
-                } catch (IllegalArgumentException var10) {
-                    LOGGER.warn("Failed to parse '{}' into UUID", id);
+                    uuid = UUID.fromString(id);
+                } catch (IllegalArgumentException illegalargumentexception) {
+                    DedicatedServerProperties.LOGGER.warn("Failed to parse '{}' into UUID", id);
                     return Optional.empty();
                 }
             }
 
-            return Optional.of(new MinecraftServer.ServerResourcePackInfo(uUID, url, string, required, component));
+            return Optional.of(new MinecraftServer.ServerResourcePackInfo(uuid, url, s5, required, ichatbasecomponent));
         }
     }
 
     private static DataPackConfig getDatapackConfig(String enabled, String disabled) {
-        List<String> list = COMMA_SPLITTER.splitToList(enabled);
-        List<String> list2 = COMMA_SPLITTER.splitToList(disabled);
-        return new DataPackConfig(list, list2);
+        List<String> list = DedicatedServerProperties.COMMA_SPLITTER.splitToList(enabled);
+        List<String> list1 = DedicatedServerProperties.COMMA_SPLITTER.splitToList(disabled);
+
+        return new DataPackConfig(list, list1);
     }
 
     public WorldDimensions createDimensions(RegistryAccess dynamicRegistry) {
@@ -206,35 +257,43 @@
     }
 
     public static record WorldDimensionData(JsonObject generatorSettings, String levelType) {
-        private static final Map<String, ResourceKey<WorldPreset>> LEGACY_PRESET_NAMES = Map.of(
-            "default", WorldPresets.NORMAL, "largebiomes", WorldPresets.LARGE_BIOMES
-        );
+
+        private static final Map<String, ResourceKey<WorldPreset>> LEGACY_PRESET_NAMES = Map.of("default", WorldPresets.NORMAL, "largebiomes", WorldPresets.LARGE_BIOMES);
 
         public WorldDimensions create(RegistryAccess dynamicRegistryManager) {
-            Registry<WorldPreset> registry = dynamicRegistryManager.registryOrThrow(Registries.WORLD_PRESET);
-            Holder.Reference<WorldPreset> reference = registry.getHolder(WorldPresets.NORMAL)
-                .or(() -> registry.holders().findAny())
-                .orElseThrow(() -> new IllegalStateException("Invalid datapack contents: can't find default preset"));
-            Holder<WorldPreset> holder = Optional.ofNullable(ResourceLocation.tryParse(this.levelType))
-                .map(levelTypeId -> ResourceKey.create(Registries.WORLD_PRESET, levelTypeId))
-                .or(() -> Optional.ofNullable(LEGACY_PRESET_NAMES.get(this.levelType)))
-                .flatMap(registry::getHolder)
-                .orElseGet(() -> {
-                    DedicatedServerProperties.LOGGER.warn("Failed to parse level-type {}, defaulting to {}", this.levelType, reference.key().location());
-                    return reference;
-                });
-            WorldDimensions worldDimensions = holder.value().createWorldDimensions();
+            Registry<WorldPreset> iregistry = dynamicRegistryManager.registryOrThrow(Registries.WORLD_PRESET);
+            Holder.Reference<WorldPreset> holder_c = (Holder.Reference) iregistry.getHolder(WorldPresets.NORMAL).or(() -> {
+                return iregistry.holders().findAny();
+            }).orElseThrow(() -> {
+                return new IllegalStateException("Invalid datapack contents: can't find default preset");
+            });
+            Optional<ResourceKey<WorldPreset>> optional = Optional.ofNullable(ResourceLocation.tryParse(this.levelType)).map((minecraftkey) -> { // CraftBukkit - decompile error
+                return ResourceKey.create(Registries.WORLD_PRESET, minecraftkey);
+            }).or(() -> {
+                return Optional.ofNullable(DedicatedServerProperties.WorldDimensionData.LEGACY_PRESET_NAMES.get(this.levelType)); // CraftBukkit - decompile error
+            });
+
+            Objects.requireNonNull(iregistry);
+            Holder<WorldPreset> holder = (Holder) optional.flatMap(iregistry::getHolder).orElseGet(() -> {
+                DedicatedServerProperties.LOGGER.warn("Failed to parse level-type {}, defaulting to {}", this.levelType, holder_c.key().location());
+                return holder_c;
+            });
+            WorldDimensions worlddimensions = ((WorldPreset) holder.value()).createWorldDimensions();
+
             if (holder.is(WorldPresets.FLAT)) {
-                RegistryOps<JsonElement> registryOps = dynamicRegistryManager.createSerializationContext(JsonOps.INSTANCE);
-                Optional<FlatLevelGeneratorSettings> optional = FlatLevelGeneratorSettings.CODEC
-                    .parse(new Dynamic<>(registryOps, this.generatorSettings()))
-                    .resultOrPartial(DedicatedServerProperties.LOGGER::error);
-                if (optional.isPresent()) {
-                    return worldDimensions.replaceOverworldGenerator(dynamicRegistryManager, new FlatLevelSource(optional.get()));
+                RegistryOps<JsonElement> registryops = dynamicRegistryManager.createSerializationContext(JsonOps.INSTANCE);
+                DataResult<FlatLevelGeneratorSettings> dataresult = FlatLevelGeneratorSettings.CODEC.parse(new Dynamic(registryops, this.generatorSettings())); // CraftBukkit - decompile error
+                Logger logger = DedicatedServerProperties.LOGGER;
+
+                Objects.requireNonNull(logger);
+                Optional<FlatLevelGeneratorSettings> optional1 = dataresult.resultOrPartial(logger::error);
+
+                if (optional1.isPresent()) {
+                    return worlddimensions.replaceOverworldGenerator(dynamicRegistryManager, new FlatLevelSource((FlatLevelGeneratorSettings) optional1.get()));
                 }
             }
 
-            return worldDimensions;
+            return worlddimensions;
         }
     }
 }
