From f39e689b83c1be89ec4f51ab9fc60b9c419b7b99 Mon Sep 17 00:00:00 2001
From: Julian Vennen <julian@aternos.org>
Date: Sun, 23 Apr 2023 03:33:23 +0200
Subject: [PATCH] Implement System properties to set the udp port and address
 #3597 (#3689)

* System property stuff

* Add geyserUdpPort/Address system properties as overrides for pluginUdpPort/Address

* Fix formatting for if-else statements

---------

Co-authored-by: Camotoy <20743703+Camotoy@users.noreply.github.com>
---
 .../bungeecord/GeyserBungeePlugin.java        | 40 +++++------
 .../platform/fabric/GeyserFabricMod.java      | 26 ++++---
 .../platform/spigot/GeyserSpigotPlugin.java   | 60 ++++------------
 .../platform/sponge/GeyserSpongePlugin.java   | 30 ++++----
 .../standalone/GeyserStandaloneBootstrap.java | 12 ++++
 .../velocity/GeyserVelocityPlugin.java        | 29 ++++----
 .../org/geysermc/geyser/GeyserBootstrap.java  | 11 +++
 .../java/org/geysermc/geyser/GeyserImpl.java  | 70 ++++++++++++++++---
 .../configuration/GeyserConfiguration.java    |  7 ++
 .../GeyserJacksonConfiguration.java           |  4 +-
 10 files changed, 160 insertions(+), 129 deletions(-)

diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
index dc7602163..518e461cb 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
@@ -45,6 +45,7 @@ import org.geysermc.geyser.ping.IGeyserPingPassthrough;
 import org.geysermc.geyser.platform.bungeecord.command.GeyserBungeeCommandExecutor;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.util.FileUtils;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
 import java.io.IOException;
@@ -55,6 +56,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Optional;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
@@ -116,26 +118,6 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
             return;
         }
 
-        if (getProxy().getConfig().getListeners().size() == 1) {
-            ListenerInfo listener = getProxy().getConfig().getListeners().toArray(new ListenerInfo[0])[0];
-
-            InetSocketAddress javaAddr = listener.getHost();
-
-            // By default this should be localhost but may need to be changed in some circumstances
-            if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
-                this.geyserConfig.setAutoconfiguredRemote(true);
-                // Don't use localhost if not listening on all interfaces
-                if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
-                    this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
-                }
-                this.geyserConfig.getRemote().setPort(javaAddr.getPort());
-            }
-
-            if (geyserConfig.getBedrock().isCloneRemotePort()) {
-                geyserConfig.getBedrock().setPort(javaAddr.getPort());
-            }
-        }
-
         // Force-disable query if enabled, or else Geyser won't enable
         for (ListenerInfo info : getProxy().getConfig().getListeners()) {
             if (info.isQueryEnabled() && info.getQueryPort() == geyserConfig.getBedrock().port()) {
@@ -274,4 +256,22 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
     public SocketAddress getSocketAddress() {
         return this.geyserInjector.getServerSocketAddress();
     }
+
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        return findCompatibleListener().map(InetSocketAddress::getHostString).orElse("");
+    }
+
+    @Override
+    public int getServerPort() {
+        return findCompatibleListener().stream().mapToInt(InetSocketAddress::getPort).findFirst().orElse(-1);
+    }
+
+    private Optional<InetSocketAddress> findCompatibleListener() {
+        return getProxy().getConfig().getListeners().stream()
+                .filter(info -> info.getSocketAddress() instanceof InetSocketAddress)
+                .map(info -> (InetSocketAddress) info.getSocketAddress())
+                .findFirst();
+    }
 }
diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java
index e5ff4b577..355777da1 100644
--- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java
+++ b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java
@@ -53,6 +53,7 @@ import org.geysermc.geyser.platform.fabric.command.GeyserFabricCommandExecutor;
 import org.geysermc.geyser.platform.fabric.world.GeyserFabricWorldManager;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.util.FileUtils;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.File;
@@ -138,20 +139,6 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap {
     public void startGeyser(MinecraftServer server) {
         this.server = server;
 
-        if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
-            this.geyserConfig.setAutoconfiguredRemote(true);
-            String ip = server.getLocalIp();
-            int port = ((GeyserServerPortGetter) server).geyser$getServerPort();
-            if (ip != null && !ip.isEmpty() && !ip.equals("0.0.0.0")) {
-                this.geyserConfig.getRemote().setAddress(ip);
-            }
-            this.geyserConfig.getRemote().setPort(port);
-        }
-
-        if (geyserConfig.getBedrock().isCloneRemotePort()) {
-            geyserConfig.getBedrock().setPort(geyserConfig.getRemote().port());
-        }
-
         Optional<ModContainer> floodgate = FabricLoader.getInstance().getModContainer("floodgate");
         boolean floodgatePresent = floodgate.isPresent();
         if (geyserConfig.getRemote().authType() == AuthType.FLOODGATE && !floodgatePresent) {
@@ -242,6 +229,17 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap {
         return this.server.getServerVersion();
     }
 
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        return this.server.getLocalIp();
+    }
+
+    @Override
+    public int getServerPort() {
+        return ((GeyserServerPortGetter) server).geyser$getServerPort();
+    }
+
     @Nullable
     @Override
     public InputStream getResourceOrNull(String resource) {
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
index 1be2eb32a..88b006851 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
@@ -65,6 +65,7 @@ import org.geysermc.geyser.platform.spigot.world.GeyserSpigotBlockPlaceListener;
 import org.geysermc.geyser.platform.spigot.world.manager.*;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.util.FileUtils;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
 import java.io.IOException;
@@ -170,20 +171,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
             return;
         }
 
-        // By default this should be localhost but may need to be changed in some circumstances
-        if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
-            geyserConfig.setAutoconfiguredRemote(true);
-            // Don't use localhost if not listening on all interfaces
-            if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) {
-                geyserConfig.getRemote().setAddress(Bukkit.getIp());
-            }
-            geyserConfig.getRemote().setPort(Bukkit.getPort());
-        }
-
-        if (geyserConfig.getBedrock().isCloneRemotePort()) {
-            geyserConfig.getBedrock().setPort(Bukkit.getPort());
-        }
-
         if (geyserConfig.getRemote().authType() == AuthType.FLOODGATE && Bukkit.getPluginManager().getPlugin("floodgate") == null) {
             geyserLogger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
             this.getPluginLoader().disablePlugin(this);
@@ -431,40 +418,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
         return this.geyserInjector.getServerSocketAddress();
     }
 
-    public boolean isCompatible(String version, String whichVersion) {
-        int[] currentVersion = parseVersion(version);
-        int[] otherVersion = parseVersion(whichVersion);
-        int length = Math.max(currentVersion.length, otherVersion.length);
-        for (int index = 0; index < length; index = index + 1) {
-            int self = (index < currentVersion.length) ? currentVersion[index] : 0;
-            int other = (index < otherVersion.length) ? otherVersion[index] : 0;
-
-            if (self != other) {
-                return (self - other) > 0;
-            }
-        }
-        return true;
-    }
-
-    private int[] parseVersion(String versionParam) {
-        versionParam = (versionParam == null) ? "" : versionParam;
-        if (versionParam.contains("(MC: ")) {
-            versionParam = versionParam.split("\\(MC: ")[1];
-            versionParam = versionParam.split("\\)")[0];
-        }
-        String[] stringArray = versionParam.split("[_.-]");
-        int[] temp = new int[stringArray.length];
-        for (int index = 0; index <= (stringArray.length - 1); index = index + 1) {
-            String t = stringArray[index].replaceAll("\\D", "");
-            try {
-                temp[index] = Integer.parseInt(t);
-            } catch (NumberFormatException ex) {
-                temp[index] = 0;
-            }
-        }
-        return temp;
-    }
-
     /**
      * @return the server version before ViaVersion finishes initializing
      */
@@ -494,4 +447,15 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
         // All mapping data is null, which means client and server block states are the same
         return false;
     }
+
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        return Bukkit.getIp();
+    }
+
+    @Override
+    public int getServerPort() {
+        return Bukkit.getPort();
+    }
 }
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
index 1f9541631..a87b51820 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
@@ -41,6 +41,7 @@ import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandManager;
 import org.geysermc.geyser.util.FileUtils;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandExecutor;
+import org.jetbrains.annotations.NotNull;
 import org.spongepowered.api.Server;
 import org.spongepowered.api.Sponge;
 import org.spongepowered.api.config.ConfigDir;
@@ -179,24 +180,6 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
             return;
         }
 
-        if (Sponge.server().boundAddress().isPresent()) {
-            InetSocketAddress javaAddr = Sponge.server().boundAddress().get();
-
-            // By default this should be 127.0.0.1 but may need to be changed in some circumstances
-            if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
-                this.geyserConfig.setAutoconfiguredRemote(true);
-                // Don't change the ip if its listening on all interfaces
-                if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
-                    this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
-                }
-                geyserConfig.getRemote().setPort(javaAddr.getPort());
-            }
-        }
-
-        if (geyserConfig.getBedrock().isCloneRemotePort()) {
-            geyserConfig.getBedrock().setPort(geyserConfig.getRemote().port());
-        }
-
         GeyserImpl.start();
 
         if (geyserConfig.isLegacyPingPassthrough()) {
@@ -245,4 +228,15 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
     public String getMinecraftServerVersion() {
         return Sponge.platform().minecraftVersion().name();
     }
+
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        return Sponge.server().boundAddress().map(InetSocketAddress::getHostString).orElse("");
+    }
+
+    @Override
+    public int getServerPort() {
+        return Sponge.server().boundAddress().stream().mapToInt(InetSocketAddress::getPort).findFirst().orElse(-1);
+    }
 }
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
index 5cbbab9d4..e99ba98bc 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
@@ -51,6 +51,7 @@ import org.geysermc.geyser.platform.standalone.gui.GeyserStandaloneGUI;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.util.FileUtils;
 import org.geysermc.geyser.util.LoopbackUtil;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
 import java.io.IOException;
@@ -291,6 +292,17 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
         return new GeyserStandaloneDumpInfo(this);
     }
 
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public int getServerPort() {
+        throw new IllegalStateException();
+    }
+
     /**
      * Get the {@link BeanPropertyDefinition}s for the given class
      *
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
index 5ac09416c..41e797d48 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
@@ -50,12 +50,12 @@ import org.geysermc.geyser.ping.IGeyserPingPassthrough;
 import org.geysermc.geyser.platform.velocity.command.GeyserVelocityCommandExecutor;
 import org.geysermc.geyser.text.GeyserLocale;
 import org.geysermc.geyser.util.FileUtils;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -111,22 +111,6 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
             return;
         }
 
-        InetSocketAddress javaAddr = proxyServer.getBoundAddress();
-
-        // By default this should be localhost but may need to be changed in some circumstances
-        if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) {
-            this.geyserConfig.setAutoconfiguredRemote(true);
-            // Don't use localhost if not listening on all interfaces
-            if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) {
-                this.geyserConfig.getRemote().setAddress(javaAddr.getHostString());
-            }
-            geyserConfig.getRemote().setPort(javaAddr.getPort());
-        }
-
-        if (geyserConfig.getBedrock().isCloneRemotePort()) {
-            geyserConfig.getBedrock().setPort(javaAddr.getPort());
-        }
-
         this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode());
         GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
 
@@ -247,4 +231,15 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
     public SocketAddress getSocketAddress() {
         return this.geyserInjector.getServerSocketAddress();
     }
+
+    @NotNull
+    @Override
+    public String getServerBindAddress() {
+        return proxyServer.getBoundAddress().getHostString();
+    }
+
+    @Override
+    public int getServerPort() {
+        return proxyServer.getBoundAddress().getPort();
+    }
 }
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
index 261c7416b..46abf4f1e 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
@@ -158,4 +158,15 @@ public interface GeyserBootstrap {
         }
         return stream;
     }
+
+    /**
+     * @return the bind address being used by the Java server.
+     */
+    @Nonnull
+    String getServerBindAddress();
+
+    /**
+     * @return the listening port being used by the Java server. -1 if can't be found
+     */
+    int getServerPort();
 }
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
index 78d538422..4d7958e16 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
@@ -261,16 +261,68 @@ public class GeyserImpl implements GeyserApi {
 
         ResourcePack.loadPacks();
 
-        if (platformType != PlatformType.STANDALONE && config.getRemote().address().equals("auto")) {
-            // Set the remote address to localhost since that is where we are always connecting
-            try {
-                config.getRemote().setAddress(InetAddress.getLocalHost().getHostAddress());
-            } catch (UnknownHostException ex) {
-                logger.debug("Unknown host when trying to find localhost.");
-                if (config.isDebugMode()) {
-                    ex.printStackTrace();
+        String geyserUdpPort = System.getProperty("geyserUdpPort", "");
+        String pluginUdpPort = geyserUdpPort.isEmpty() ? System.getProperty("pluginUdpPort", "") : geyserUdpPort;
+        if ("-1".equals(pluginUdpPort)) {
+            throw new UnsupportedOperationException("This hosting/service provider does not support applications running on the UDP port");
+        }
+        boolean portPropertyApplied = false;
+        String pluginUdpAddress = System.getProperty("geyserUdpAddress", System.getProperty("pluginUdpAddress", ""));
+
+        if (platformType != PlatformType.STANDALONE) {
+            int javaPort = bootstrap.getServerPort();
+            if (config.getRemote().address().equals("auto")) {
+                config.setAutoconfiguredRemote(true);
+                String serverAddress = bootstrap.getServerBindAddress();
+                if (!serverAddress.isEmpty() && !"0.0.0.0".equals(serverAddress)) {
+                    config.getRemote().setAddress(serverAddress);
+                } else {
+                    // Set the remote address to localhost since that is where we are always connecting
+                    try {
+                        config.getRemote().setAddress(InetAddress.getLocalHost().getHostAddress());
+                    } catch (UnknownHostException ex) {
+                        logger.debug("Unknown host when trying to find localhost.");
+                        if (config.isDebugMode()) {
+                            ex.printStackTrace();
+                        }
+                        config.getRemote().setAddress(InetAddress.getLoopbackAddress().getHostAddress());
+                    }
+                }
+                if (javaPort != -1) {
+                    config.getRemote().setPort(javaPort);
+                }
+            }
+
+            boolean forceMatchServerPort = "server".equals(pluginUdpPort);
+            if ((config.getBedrock().isCloneRemotePort() || forceMatchServerPort) && javaPort != -1) {
+                config.getBedrock().setPort(javaPort);
+                if (forceMatchServerPort) {
+                    if (geyserUdpPort.isEmpty()) {
+                        logger.info("Port set from system generic property to match Java server.");
+                    } else {
+                        logger.info("Port set from system property to match Java server.");
+                    }
+                    portPropertyApplied = true;
+                }
+            }
+
+            if ("server".equals(pluginUdpAddress)) {
+                String address = bootstrap.getServerBindAddress();
+                if (!address.isEmpty()) {
+                    config.getBedrock().setAddress(address);
+                }
+            } else if (!pluginUdpAddress.isEmpty()) {
+                config.getBedrock().setAddress(pluginUdpAddress);
+            }
+
+            if (!portPropertyApplied && !pluginUdpPort.isEmpty()) {
+                int port = Integer.parseInt(pluginUdpPort);
+                config.getBedrock().setPort(port);
+                if (geyserUdpPort.isEmpty()) {
+                    logger.info("Port set from generic system property: " + port);
+                } else {
+                    logger.info("Port set from system property: " + port);
                 }
-                config.getRemote().setAddress(InetAddress.getLoopbackAddress().getHostAddress());
             }
         }
         String remoteAddress = config.getRemote().address();
diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
index ea4c31876..2b0f193a7 100644
--- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
+++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
@@ -38,6 +38,10 @@ import java.util.List;
 import java.util.Map;
 
 public interface GeyserConfiguration {
+    /**
+     * If the config was originally 'auto' before the values changed
+     */
+    void setAutoconfiguredRemote(boolean autoconfiguredRemote);
 
     // Modify this when you introduce breaking changes into the config
     int CURRENT_CONFIG_VERSION = 4;
@@ -116,6 +120,9 @@ public interface GeyserConfiguration {
     int getPendingAuthenticationTimeout();
 
     interface IBedrockConfiguration extends BedrockListener {
+        void setAddress(String address);
+
+        void setPort(int port);
 
         boolean isCloneRemotePort();
 
diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
index bbfa37ec2..e096d58fa 100644
--- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
+++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
@@ -53,9 +53,6 @@ import java.util.stream.Collectors;
 @SuppressWarnings("FieldMayBeFinal") // Jackson requires that the fields are not final
 public abstract class GeyserJacksonConfiguration implements GeyserConfiguration {
 
-    /**
-     * If the config was originally 'auto' before the values changed
-     */
     @Setter
     private boolean autoconfiguredRemote = false;
 
@@ -163,6 +160,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
     public static class BedrockConfiguration implements IBedrockConfiguration {
         @AsteriskSerializer.Asterisk(isIp = true)
         @JsonProperty("address")
+        @Setter
         private String address = "0.0.0.0";
 
         @Override