From 52ffca95f4f8e4e5554cbaefbcc61e38e5018513 Mon Sep 17 00:00:00 2001 From: Wafarm Date: Sun, 16 Jun 2024 23:42:40 +0800 Subject: [PATCH] Allow setting forwarding mode separately for different servers --- .../proxy/config/VelocityConfiguration.java | 74 ++++++++++++++++--- .../backend/LoginSessionHandler.java | 6 +- .../backend/VelocityServerConnection.java | 2 +- .../connection/client/AuthSessionHandler.java | 4 +- .../client/HandshakeSessionHandler.java | 2 +- .../src/main/resources/default-velocity.toml | 5 +- 6 files changed, 73 insertions(+), 20 deletions(-) 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 11c65d527..6cd1dedd6 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -70,7 +70,7 @@ public class VelocityConfiguration implements ProxyConfig { @Expose private boolean preventClientProxyConnections = false; @Expose - private PlayerInfoForwarding playerInfoForwardingMode = PlayerInfoForwarding.NONE; + private PlayerInfoForwarding defaultPlayerInfoForwardingMode = PlayerInfoForwarding.NONE; private byte[] forwardingSecret = generateRandomString(12).getBytes(StandardCharsets.UTF_8); @Expose private boolean announceForge = false; @@ -113,7 +113,7 @@ public class VelocityConfiguration implements ProxyConfig { this.onlineMode = onlineMode; this.preventClientProxyConnections = preventClientProxyConnections; this.announceForge = announceForge; - this.playerInfoForwardingMode = playerInfoForwardingMode; + this.defaultPlayerInfoForwardingMode = playerInfoForwardingMode; this.forwardingSecret = forwardingSecret; this.onlineModeKickExistingPlayers = onlineModeKickExistingPlayers; this.pingPassthrough = pingPassthrough; @@ -151,22 +151,40 @@ public class VelocityConfiguration implements ProxyConfig { + "receive any support!"); } - switch (playerInfoForwardingMode) { + boolean requireForwardingSecret = false; + for (Map.Entry entry : servers.getServerForwardingModes().entrySet()) { + switch (entry.getValue()) { + case NONE: + logger.warn("Player info forwarding is disabled for " + entry.getKey() + "!" + + " All players will appear to be connecting from the proxy and will have offline-mode UUIDs."); + break; + case MODERN: + case BUNGEEGUARD: + requireForwardingSecret = true; + break; + default: + break; + } + } + + switch (defaultPlayerInfoForwardingMode) { 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."); + valid = false; + } + if (servers.getServers().isEmpty()) { logger.warn("You don't have any servers configured."); } @@ -293,8 +311,12 @@ public class VelocityConfiguration implements ProxyConfig { return preventClientProxyConnections; } - public PlayerInfoForwarding getPlayerInfoForwardingMode() { - return playerInfoForwardingMode; + public PlayerInfoForwarding getDefaultPlayerInfoForwardingMode() { + return defaultPlayerInfoForwardingMode; + } + + public PlayerInfoForwarding getServerPlayerInfoForwardingMode(String server) { + return servers.getServerForwardingModes().getOrDefault(server, defaultPlayerInfoForwardingMode); } public byte[] getForwardingSecret() { @@ -414,7 +436,7 @@ public class VelocityConfiguration implements ProxyConfig { .add("motd", motd) .add("showMaxPlayers", showMaxPlayers) .add("onlineMode", onlineMode) - .add("playerInfoForwardingMode", playerInfoForwardingMode) + .add("defaultPlayerInfoForwardingMode", defaultPlayerInfoForwardingMode) .add("forwardingSecret", forwardingSecret) .add("announceForge", announceForge) .add("servers", servers) @@ -572,6 +594,7 @@ public class VelocityConfiguration implements ProxyConfig { "minigames", "127.0.0.1:30068" ); private List attemptConnectionOrder = ImmutableList.of("lobby"); + private Map serverForwardingModes = ImmutableMap.of(); private Servers() { } @@ -579,9 +602,25 @@ public class VelocityConfiguration implements ProxyConfig { 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")) { throw new IllegalArgumentException( @@ -591,12 +630,14 @@ public class VelocityConfiguration implements ProxyConfig { } this.servers = ImmutableMap.copyOf(servers); this.attemptConnectionOrder = config.getOrElse("try", attemptConnectionOrder); + this.serverForwardingModes = ImmutableMap.copyOf(serverForwardingModes); } } - private Servers(Map servers, List attemptConnectionOrder) { + private Servers(Map servers, List attemptConnectionOrder, Map serverForwardingModes) { this.servers = servers; this.attemptConnectionOrder = attemptConnectionOrder; + this.serverForwardingModes = serverForwardingModes; } private Map getServers() { @@ -615,6 +656,14 @@ public class VelocityConfiguration implements ProxyConfig { this.attemptConnectionOrder = attemptConnectionOrder; } + public Map getServerForwardingModes() { + return serverForwardingModes; + } + + public void setServerForwardingModes(Map serverForwardingModes) { + this.serverForwardingModes = serverForwardingModes; + } + /** * TOML requires keys to match a regex of {@code [A-Za-z0-9_-]} unless it is wrapped in quotes; * however, the TOML parser returns the key with the quotes so we need to clean the server name @@ -632,6 +681,7 @@ public class VelocityConfiguration implements ProxyConfig { 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 a672c9174..8b14ea465 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 @@ -82,7 +82,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { public boolean handle(LoginPluginMessagePacket packet) { MinecraftConnection mc = serverConn.ensureConnected(); VelocityConfiguration configuration = server.getConfiguration(); - if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + if (configuration.getServerPlayerInfoForwardingMode(serverConn.getServerInfo().getName()) == PlayerInfoForwarding.MODERN && packet.getChannel().equals(PlayerDataForwarding.CHANNEL)) { int requestedForwardingVersion = PlayerDataForwarding.MODERN_DEFAULT; @@ -142,7 +142,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { @Override public boolean handle(ServerLoginSuccessPacket packet) { - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + if (server.getConfiguration().getServerPlayerInfoForwardingMode(serverConn.getServerInfo().getName()) == PlayerInfoForwarding.MODERN && !informationForwarded) { resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE, serverConn.getServer())); @@ -205,7 +205,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { @Override public void disconnected() { - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.LEGACY) { + if (server.getConfiguration().getServerPlayerInfoForwardingMode(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 edf3a9148..c8aaff9bb 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 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, private void startHandshake() { final MinecraftConnection mc = ensureConnected(); - PlayerInfoForwarding forwardingMode = server.getConfiguration().getPlayerInfoForwardingMode(); + PlayerInfoForwarding forwardingMode = server.getConfiguration().getServerPlayerInfoForwardingMode(registeredServer.getServerInfo().getName()); // Initiate the handshake. ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion(); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java index 77290584d..91ab92022 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java @@ -83,7 +83,7 @@ public class AuthSessionHandler implements MinecraftSessionHandler { public void activated() { // Some connection types may need to alter the game profile. profile = mcConnection.getType().addGameProfileTokensIfRequired(profile, - server.getConfiguration().getPlayerInfoForwardingMode()); + server.getConfiguration().getDefaultPlayerInfoForwardingMode()); GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(inbound, profile, onlineMode); final GameProfile finalProfile = profile; @@ -139,7 +139,7 @@ public class AuthSessionHandler implements MinecraftSessionHandler { } VelocityConfiguration configuration = server.getConfiguration(); UUID playerUniqueId = player.getUniqueId(); - if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) { + if (configuration.getDefaultPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) { playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername()); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java index fae6533db..d1f8be837 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java @@ -146,7 +146,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { // If the proxy is configured for modern forwarding, we must deny connections from 1.12.2 // and lower, otherwise IP information will never get forwarded. - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + if (server.getConfiguration().getDefaultPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && handshake.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) { // Bump connection into correct protocol state so that we can send the disconnect packet. connection.setState(StateRegistry.LOGIN); diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml index 3f4f6318c..be8a072d3 100644 --- a/proxy/src/main/resources/default-velocity.toml +++ b/proxy/src/main/resources/default-velocity.toml @@ -42,7 +42,7 @@ forwarding-secret-file = "forwarding.secret" # Announce whether or not your server supports Forge. If you run a modded server, we # suggest turning this on. -# +# # If your network runs one modpack consistently, consider using ping-passthrough = "mods" # instead for a nicer display in the server list. announce-forge = false @@ -76,6 +76,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 it like this +modern = { address = "127.0.0.1:30069", forwarding-mode = "MODERN" } + # In what order we should try servers when a player logs in or is kicked from a server. try = [ "lobby"