diff --git a/proxy/build.gradle b/proxy/build.gradle index 1901a221b..140e50405 100644 --- a/proxy/build.gradle +++ b/proxy/build.gradle @@ -38,6 +38,7 @@ dependencies { compile "org.apache.logging.log4j:log4j-core:${log4jVersion}" compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}" + compile 'net.sf.jopt-simple:jopt-simple:5.0.4' // command-line options compile 'net.minecrell:terminalconsoleappender:1.1.1' runtime 'net.java.dev.jna:jna:4.5.2' // Needed for JLine runtime 'com.lmax:disruptor:3.4.2' // Async loggers diff --git a/proxy/src/main/java/com/velocitypowered/proxy/ProxyOptions.java b/proxy/src/main/java/com/velocitypowered/proxy/ProxyOptions.java new file mode 100644 index 000000000..b2a12358d --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/ProxyOptions.java @@ -0,0 +1,44 @@ +package com.velocitypowered.proxy; + +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.io.IOException; +import java.util.Arrays; + +public final class ProxyOptions { + private static final Logger logger = LogManager.getLogger(ProxyOptions.class); + private final boolean help; + private final @Nullable Integer port; + + ProxyOptions(final String[] args) { + final OptionParser parser = new OptionParser(); + + final OptionSpec help = parser.acceptsAll(Arrays.asList("h", "help"), "Print help").forHelp(); + final OptionSpec port = parser.acceptsAll(Arrays.asList("p", "port"), "Specify the bind port to be used. The configuration bind port will be ignored.").withRequiredArg().ofType(Integer.class); + final OptionSet set = parser.parse(args); + + this.help = set.has(help); + this.port = port.value(set); + + if (this.help) { + try { + parser.printHelpOn(System.out); + } catch (final IOException e) { + logger.error("Could not print help", e); + } + } + } + + boolean isHelp() { + return this.help; + } + + public @Nullable Integer getPort() { + return this.port; + } +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/Velocity.java b/proxy/src/main/java/com/velocitypowered/proxy/Velocity.java index 0d3b64c15..8774c0b96 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/Velocity.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/Velocity.java @@ -17,7 +17,13 @@ public class Velocity { public static void main(String... args) { long startTime = System.currentTimeMillis(); - VelocityServer server = new VelocityServer(); + final ProxyOptions options = new ProxyOptions(args); + + if (options.isHelp()) { + return; + } + + VelocityServer server = new VelocityServer(options); server.start(); Runtime.getRuntime().addShutdownHook(new Thread(() -> server.shutdown(false), "Shutdown thread")); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index 52a850e53..339199141 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -70,6 +70,7 @@ public class VelocityServer implements ProxyServer { .registerTypeHierarchyAdapter(GameProfile.class, new GameProfileSerializer()) .create(); + private final ProxyOptions options; private @MonotonicNonNull ConnectionManager cm; private @MonotonicNonNull VelocityConfiguration configuration; private @MonotonicNonNull NettyHttpClient httpClient; @@ -88,6 +89,10 @@ public class VelocityServer implements ProxyServer { private @MonotonicNonNull VelocityScheduler scheduler; private final VelocityChannelRegistrar channelRegistrar = new VelocityChannelRegistrar(); + public VelocityServer(final ProxyOptions options) { + this.options = options; + } + public KeyPair getServerKeyPair() { if (serverKeyPair == null) { throw new AssertionError(); @@ -181,7 +186,13 @@ public class VelocityServer implements ProxyServer { // init console permissions after plugins are loaded console.setupPermissions(); - this.cm.bind(configuration.getBind()); + final Integer port = this.options.getPort(); + if (port != null) { + logger.debug("Overriding bind port to {} from command line option", port); + this.cm.bind(new InetSocketAddress(configuration.getBind().getHostString(), port)); + } else { + this.cm.bind(configuration.getBind()); + } if (configuration.isQueryEnabled()) { this.cm.queryBind(configuration.getBind().getHostString(), configuration.getQueryPort());