mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-22 22:45:04 +01:00
Feature: Allow setting a different port in the motd (#4293)
* Allow changing the broadcasted port using a system property. This may be needed if the port Geyser runs on & the port Bedrock players connect on do not match - e.g. due to port forwarding/different routing. * initial stab at making the broadcast port an (unsafe) config option * Automatically set broadcast port to be the bind port unless manually overridden * Warn about broadcast port mismatch * Use 0 instead of -1 as indicator to broadcast the port geyser is running on
This commit is contained in:
parent
3f577f4128
commit
61b3ffd0de
7 changed files with 81 additions and 19 deletions
|
@ -50,6 +50,14 @@ public interface BedrockListener {
|
||||||
*/
|
*/
|
||||||
int port();
|
int port();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the broadcast port that's sent to Bedrock clients with the motd.
|
||||||
|
* This is the port that Bedrock clients will connect with. It usually does not differ from the listening port.
|
||||||
|
*
|
||||||
|
* @return the broadcast port
|
||||||
|
*/
|
||||||
|
int broadcastPort();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the primary MOTD shown to Bedrock players if a ping passthrough setting is not enabled.
|
* Gets the primary MOTD shown to Bedrock players if a ping passthrough setting is not enabled.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -314,6 +314,22 @@ public class GeyserImpl implements GeyserApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String broadcastPort = System.getProperty("geyserBroadcastPort", "");
|
||||||
|
if (!broadcastPort.isEmpty()) {
|
||||||
|
int parsedPort;
|
||||||
|
try {
|
||||||
|
parsedPort = Integer.parseInt(broadcastPort);
|
||||||
|
if (parsedPort < 1 || parsedPort > 65535) {
|
||||||
|
throw new NumberFormatException("The broadcast port must be between 1 and 65535 inclusive!");
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.error(String.format("Invalid broadcast port: %s! Defaulting to configured port.", broadcastPort + " (" + e.getMessage() + ")"));
|
||||||
|
parsedPort = config.getBedrock().port();
|
||||||
|
}
|
||||||
|
config.getBedrock().setBroadcastPort(parsedPort);
|
||||||
|
logger.info("Broadcast port set from system property: " + parsedPort);
|
||||||
|
}
|
||||||
|
|
||||||
boolean floodgatePresent = bootstrap.testFloodgatePluginPresent();
|
boolean floodgatePresent = bootstrap.testFloodgatePluginPresent();
|
||||||
if (config.getRemote().authType() == AuthType.FLOODGATE && !floodgatePresent) {
|
if (config.getRemote().authType() == AuthType.FLOODGATE && !floodgatePresent) {
|
||||||
logger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " "
|
logger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " "
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.api.util.PlatformType;
|
import org.geysermc.geyser.api.util.PlatformType;
|
||||||
import org.geysermc.geyser.command.GeyserCommand;
|
import org.geysermc.geyser.command.GeyserCommand;
|
||||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||||
|
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
import org.geysermc.geyser.util.LoopbackUtil;
|
import org.geysermc.geyser.util.LoopbackUtil;
|
||||||
|
@ -84,7 +85,7 @@ public class ConnectionTestCommand extends GeyserCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
port = 19132;
|
port = geyser.getConfig().getBedrock().broadcastPort();
|
||||||
}
|
}
|
||||||
String ip = fullAddress[0];
|
String ip = fullAddress[0];
|
||||||
|
|
||||||
|
@ -112,30 +113,41 @@ public class ConnectionTestCommand extends GeyserCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue: do the ports not line up?
|
GeyserConfiguration config = geyser.getConfig();
|
||||||
if (port != geyser.getConfig().getBedrock().port()) {
|
|
||||||
|
// Issue: do the ports not line up? We only check this if players don't override the broadcast port - if they do, they (hopefully) know what they're doing
|
||||||
|
if (config.getBedrock().broadcastPort() == config.getBedrock().port()) {
|
||||||
|
if (port != config.getBedrock().port()) {
|
||||||
if (fullAddress.length == 2) {
|
if (fullAddress.length == 2) {
|
||||||
sender.sendMessage("The port you are testing with (" + port + ") is not the same as you set in your Geyser configuration ("
|
sender.sendMessage("The port you are testing with (" + port + ") is not the same as you set in your Geyser configuration ("
|
||||||
+ geyser.getConfig().getBedrock().port() + ")");
|
+ config.getBedrock().port() + ")");
|
||||||
sender.sendMessage("Re-run the command with the port in the config, or change the `bedrock` `port` in the config.");
|
sender.sendMessage("Re-run the command with the port in the config, or change the `bedrock` `port` in the config.");
|
||||||
if (geyser.getConfig().getBedrock().isCloneRemotePort()) {
|
if (config.getBedrock().isCloneRemotePort()) {
|
||||||
sender.sendMessage("You have `clone-remote-port` enabled. This option ignores the `bedrock` `port` in the config, and uses the Java server port instead.");
|
sender.sendMessage("You have `clone-remote-port` enabled. This option ignores the `bedrock` `port` in the config, and uses the Java server port instead.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("You did not specify the port to check (add it with \":<port>\"), " +
|
sender.sendMessage("You did not specify the port to check (add it with \":<port>\"), " +
|
||||||
"and the default port 19132 does not match the port in your Geyser configuration ("
|
"and the default port 19132 does not match the port in your Geyser configuration ("
|
||||||
+ geyser.getConfig().getBedrock().port() + ")!");
|
+ config.getBedrock().port() + ")!");
|
||||||
sender.sendMessage("Re-run the command with that port, or change the port in the config under `bedrock` `port`.");
|
sender.sendMessage("Re-run the command with that port, or change the port in the config under `bedrock` `port`.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (config.getBedrock().broadcastPort() != port) {
|
||||||
|
sender.sendMessage("The port you are testing with (" + port + ") is not the same as the broadcast port set in your Geyser configuration ("
|
||||||
|
+ config.getBedrock().broadcastPort() + "). ");
|
||||||
|
sender.sendMessage("You ONLY need to change the broadcast port if clients connects with a port different from the port Geyser is running on.");
|
||||||
|
sender.sendMessage("Re-run the command with the port in the config, or change the `bedrock` `broadcast-port` in the config.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Issue: is the `bedrock` `address` in the config different?
|
// Issue: is the `bedrock` `address` in the config different?
|
||||||
if (!geyser.getConfig().getBedrock().address().equals("0.0.0.0")) {
|
if (!config.getBedrock().address().equals("0.0.0.0")) {
|
||||||
sender.sendMessage("The address specified in `bedrock` `address` is not \"0.0.0.0\" - this may cause issues unless this is deliberate and intentional.");
|
sender.sendMessage("The address specified in `bedrock` `address` is not \"0.0.0.0\" - this may cause issues unless this is deliberate and intentional.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue: did someone turn on enable-proxy-protocol, and they didn't mean it?
|
// Issue: did someone turn on enable-proxy-protocol, and they didn't mean it?
|
||||||
if (geyser.getConfig().getBedrock().isEnableProxyProtocol()) {
|
if (config.getBedrock().isEnableProxyProtocol()) {
|
||||||
sender.sendMessage("You have the `enable-proxy-protocol` setting enabled. " +
|
sender.sendMessage("You have the `enable-proxy-protocol` setting enabled. " +
|
||||||
"Unless you're deliberately using additional software that REQUIRES this setting, you may not need it enabled.");
|
"Unless you're deliberately using additional software that REQUIRES this setting, you may not need it enabled.");
|
||||||
}
|
}
|
||||||
|
@ -166,7 +178,7 @@ public class ConnectionTestCommand extends GeyserCommand {
|
||||||
String connectionTestMotd = "Geyser Connection Test " + randomStr;
|
String connectionTestMotd = "Geyser Connection Test " + randomStr;
|
||||||
CONNECTION_TEST_MOTD = connectionTestMotd;
|
CONNECTION_TEST_MOTD = connectionTestMotd;
|
||||||
|
|
||||||
sender.sendMessage("Testing server connection now. Please wait...");
|
sender.sendMessage("Testing server connection to " + ip + " with port: " + port + " now. Please wait...");
|
||||||
JsonNode output;
|
JsonNode output;
|
||||||
try {
|
try {
|
||||||
String hostname = URLEncoder.encode(ip, StandardCharsets.UTF_8);
|
String hostname = URLEncoder.encode(ip, StandardCharsets.UTF_8);
|
||||||
|
|
|
@ -122,6 +122,8 @@ public interface GeyserConfiguration {
|
||||||
|
|
||||||
void setPort(int port);
|
void setPort(int port);
|
||||||
|
|
||||||
|
void setBroadcastPort(int broadcastPort);
|
||||||
|
|
||||||
boolean isCloneRemotePort();
|
boolean isCloneRemotePort();
|
||||||
|
|
||||||
int getCompressionLevel();
|
int getCompressionLevel();
|
||||||
|
|
|
@ -172,6 +172,15 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@JsonProperty("broadcast-port")
|
||||||
|
private int broadcastPort = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int broadcastPort() {
|
||||||
|
return broadcastPort;
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@JsonProperty("clone-remote-port")
|
@JsonProperty("clone-remote-port")
|
||||||
private boolean cloneRemotePort = false;
|
private boolean cloneRemotePort = false;
|
||||||
|
|
|
@ -102,6 +102,11 @@ public final class GeyserServer {
|
||||||
|
|
||||||
private ChannelFuture bootstrapFuture;
|
private ChannelFuture bootstrapFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The port to broadcast in the pong. This can be different from the port the server is bound to, e.g. due to port forwarding.
|
||||||
|
*/
|
||||||
|
private final int broadcastPort;
|
||||||
|
|
||||||
public GeyserServer(GeyserImpl geyser, int threadCount) {
|
public GeyserServer(GeyserImpl geyser, int threadCount) {
|
||||||
this.geyser = geyser;
|
this.geyser = geyser;
|
||||||
this.group = TRANSPORT.eventLoopGroupFactory().apply(threadCount);
|
this.group = TRANSPORT.eventLoopGroupFactory().apply(threadCount);
|
||||||
|
@ -115,6 +120,13 @@ public final class GeyserServer {
|
||||||
} else {
|
} else {
|
||||||
this.proxiedAddresses = null;
|
this.proxiedAddresses = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's set to 0 only if no system property or manual config value was set
|
||||||
|
if (geyser.getConfig().getBedrock().broadcastPort() == 0) {
|
||||||
|
geyser.getConfig().getBedrock().setBroadcastPort(geyser.getConfig().getBedrock().port());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.broadcastPort = geyser.getConfig().getBedrock().broadcastPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> bind(InetSocketAddress address) {
|
public CompletableFuture<Void> bind(InetSocketAddress address) {
|
||||||
|
@ -243,8 +255,8 @@ public final class GeyserServer {
|
||||||
.nintendoLimited(false)
|
.nintendoLimited(false)
|
||||||
.protocolVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion())
|
.protocolVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion())
|
||||||
.version(GameProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion()) // Required to not be empty as of 1.16.210.59. Can only contain . and numbers.
|
.version(GameProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion()) // Required to not be empty as of 1.16.210.59. Can only contain . and numbers.
|
||||||
.ipv4Port(this.geyser.getConfig().getBedrock().port())
|
.ipv4Port(this.broadcastPort)
|
||||||
.ipv6Port(this.geyser.getConfig().getBedrock().port())
|
.ipv6Port(this.broadcastPort)
|
||||||
.serverId(bootstrapFuture.channel().config().getOption(RakChannelOption.RAK_GUID));
|
.serverId(bootstrapFuture.channel().config().getOption(RakChannelOption.RAK_GUID));
|
||||||
|
|
||||||
if (config.isPassthroughMotd() && pingInfo != null && pingInfo.getDescription() != null) {
|
if (config.isPassthroughMotd() && pingInfo != null && pingInfo.getDescription() != null) {
|
||||||
|
|
|
@ -30,6 +30,9 @@ bedrock:
|
||||||
# How much to compress network traffic to the Bedrock client. The higher the number, the more CPU usage used, but
|
# How much to compress network traffic to the Bedrock client. The higher the number, the more CPU usage used, but
|
||||||
# the smaller the bandwidth used. Does not have any effect below -1 or above 9. Set to -1 to disable.
|
# the smaller the bandwidth used. Does not have any effect below -1 or above 9. Set to -1 to disable.
|
||||||
compression-level: 6
|
compression-level: 6
|
||||||
|
# The port to broadcast to Bedrock clients with the MOTD that they should use to connect to the server.
|
||||||
|
# DO NOT uncomment and change this unless Geyser runs on a different internal port than the one that is used to connect.
|
||||||
|
# broadcast-port: 19132
|
||||||
# Whether to enable PROXY protocol or not for clients. You DO NOT WANT this feature unless you run UDP reverse proxy
|
# Whether to enable PROXY protocol or not for clients. You DO NOT WANT this feature unless you run UDP reverse proxy
|
||||||
# in front of your Geyser instance.
|
# in front of your Geyser instance.
|
||||||
enable-proxy-protocol: false
|
enable-proxy-protocol: false
|
||||||
|
|
Loading…
Reference in a new issue