diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 8a3c8ee999..487d915dd0 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -180,22 +180,41 @@ public boolean validate() { + "receive any support!"); } + boolean requireForwardingSecret = false; + for (Map.Entry entry : servers.getServerForwardingModes().entrySet()) { + switch (entry.getValue()) { + case NONE: + logger.warn("Player info forwarding is disabled for {}!" + + " All players will appear to be connecting from the proxy and will have offline-mode UUIDs.", entry.getKey()); + break; + case MODERN: + case BUNGEEGUARD: + requireForwardingSecret = true; + break; + default: + break; + } + } + switch (playerInfoForwardingMode) { case NONE: - logger.warn("Player info forwarding is disabled! All players will appear to be connecting " + logger.warn("Player info forwarding is disabled by default! All players will appear to be connecting " + "from the proxy and will have offline-mode UUIDs."); break; case MODERN: case BUNGEEGUARD: - if (forwardingSecret == null || forwardingSecret.length == 0) { - logger.error("You don't have a forwarding secret set. This is required for security."); - valid = false; - } + requireForwardingSecret = true; break; default: break; } + if (requireForwardingSecret && (forwardingSecret == null || forwardingSecret.length == 0)) { + logger.error("You don't have a forwarding secret set. This is required for security. " + + "See https://docs.papermc.io/velocity for more details."); + valid = false; + } + if (servers.getServers().isEmpty()) { logger.warn("You don't have any servers configured."); } @@ -326,6 +345,10 @@ public PlayerInfoForwarding getPlayerInfoForwardingMode() { return playerInfoForwardingMode; } + public PlayerInfoForwarding getServerForwardingMode(String server) { + return servers.getServerForwardingModes().getOrDefault(server, playerInfoForwardingMode); + } + public byte[] getForwardingSecret() { return forwardingSecret.clone(); } @@ -681,6 +704,7 @@ private static class Servers { "minigames", "127.0.0.1:30068" ); private List attemptConnectionOrder = ImmutableList.of("lobby"); + private Map serverForwardingModes = ImmutableMap.of(); private boolean enableDynamicFallbacks = false; @@ -690,9 +714,25 @@ private Servers() { private Servers(CommentedConfig config) { if (config != null) { Map servers = new HashMap<>(); + Map serverForwardingModes = new HashMap<>(); for (UnmodifiableConfig.Entry entry : config.entrySet()) { if (entry.getValue() instanceof String) { servers.put(cleanServerName(entry.getKey()), entry.getValue()); + } else if (entry.getValue() instanceof UnmodifiableConfig) { + UnmodifiableConfig unmodifiableConfig = entry.getValue(); + String name = entry.getKey(); + + String address = unmodifiableConfig.get("address"); + if (address == null) { + throw new IllegalArgumentException("Server " + name + " doesn't have an address!"); + } + + PlayerInfoForwarding mode = unmodifiableConfig.getEnum("forwarding-mode", PlayerInfoForwarding.class); + if (mode != null) { + serverForwardingModes.put(name, mode); + } + + servers.put(name, address); } else { if (!entry.getKey().equalsIgnoreCase("try") && !entry.getKey().equalsIgnoreCase("enable-dynamic-fallbacks")) { throw new IllegalArgumentException( @@ -706,7 +746,7 @@ private Servers(CommentedConfig config) { } } - private Servers(Map servers, List attemptConnectionOrder) { + private Servers(Map servers, List attemptConnectionOrder, Map serverForwardingModes) { this.servers = servers; this.attemptConnectionOrder = attemptConnectionOrder; } @@ -729,6 +769,15 @@ public boolean isEnableDynamicFallbacks() { public void setAttemptConnectionOrder(List attemptConnectionOrder) { this.attemptConnectionOrder = attemptConnectionOrder; + this.serverForwardingModes = ImmutableMap.copyOf(serverForwardingModes); + } + + public Map getServerForwardingModes() { + return serverForwardingModes; + } + + public void setServerForwardingModes(Map serverForwardingModes) { + this.serverForwardingModes = serverForwardingModes; } /** @@ -748,6 +797,7 @@ public String toString() { return "Servers{" + "servers=" + servers + ", attemptConnectionOrder=" + attemptConnectionOrder + + ", serverForwardingModes=" + serverForwardingModes + '}'; } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 2dd85fce4e..4b4f146c34 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -84,7 +84,7 @@ public boolean handle(EncryptionRequestPacket packet) { public boolean handle(LoginPluginMessagePacket packet) { MinecraftConnection mc = serverConn.ensureConnected(); VelocityConfiguration configuration = server.getConfiguration(); - if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + if (configuration.getServerForwardingMode(serverConn.getServerInfo().getName()) == PlayerInfoForwarding.MODERN && packet.getChannel().equals(PlayerDataForwarding.CHANNEL)) { int requestedForwardingVersion = PlayerDataForwarding.MODERN_DEFAULT; @@ -144,7 +144,8 @@ public boolean handle(SetCompressionPacket packet) { @Override public boolean handle(ServerLoginSuccessPacket packet) { - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && !informationForwarded) { + if (server.getConfiguration().getServerForwardingMode(serverConn.getServerInfo().getName()) == PlayerInfoForwarding.MODERN + && !informationForwarded) { resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE, serverConn.getServer())); serverConn.disconnect(); return true; @@ -203,7 +204,7 @@ public void exception(Throwable throwable) { @Override public void disconnected() { - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.LEGACY) { + if (server.getConfiguration().getServerForwardingMode(serverConn.getServerInfo().getName()) == PlayerInfoForwarding.LEGACY) { resultFuture.completeExceptionally(new QuietRuntimeException( """ The connection to the remote server was unexpectedly closed. diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index 24d7981ae4..a3e22503ea 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -163,7 +163,7 @@ private String createBungeeGuardForwardingAddress(byte[] forwardingSecret) { private void startHandshake() { final MinecraftConnection mc = ensureConnected(); - PlayerInfoForwarding forwardingMode = server.getConfiguration().getPlayerInfoForwardingMode(); + PlayerInfoForwarding forwardingMode = server.getConfiguration().getServerForwardingMode(registeredServer.getServerInfo().getName()); // Initiate the handshake. ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion(); diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml index 839511bd31..6e61e37442 100644 --- a/proxy/src/main/resources/default-velocity.toml +++ b/proxy/src/main/resources/default-velocity.toml @@ -104,6 +104,9 @@ lobby = "127.0.0.1:30066" factions = "127.0.0.1:30067" minigames = "127.0.0.1:30068" +# If you need a different forwarding mode, specify as shown: +minigames = { address = "127.0.0.1:30068", forwarding-mode = "MODERN" } + # In what order we should try servers when a player logs in or is kicked from a server. try = [ "lobby"