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>
This commit is contained in:
Julian Vennen 2023-04-23 03:33:23 +02:00 committed by GitHub
parent cb440b65ad
commit f39e689b83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 160 additions and 129 deletions

View file

@ -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();
}
}

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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
*

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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();

View file

@ -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();

View file

@ -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