diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index cecc440c9c..c232052b70 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -45,6 +45,7 @@ import com.velocitypowered.proxy.command.builtin.ServerCommand; import com.velocitypowered.proxy.command.builtin.ShutdownCommand; import com.velocitypowered.proxy.command.builtin.VelocityCommand; +import com.velocitypowered.proxy.config.LegacyConfigurationLoader; import com.velocitypowered.proxy.config.VelocityConfiguration; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.connection.player.resourcepack.VelocityResourcePackInfo; @@ -383,7 +384,7 @@ private void registerTranslations() { private void doStartupConfigLoad() { try { Path configPath = Path.of("velocity.toml"); - configuration = VelocityConfiguration.read(configPath); + configuration = LegacyConfigurationLoader.read(configPath); if (!configuration.validate()) { logger.error("Your configuration is invalid. Velocity will not start up until the errors " @@ -461,7 +462,7 @@ public boolean isShutdown() { */ public boolean reloadConfiguration() throws IOException { Path configPath = Path.of("velocity.toml"); - VelocityConfiguration newConfiguration = VelocityConfiguration.read(configPath); + VelocityConfiguration newConfiguration = LegacyConfigurationLoader.read(configPath); if (!newConfiguration.validate()) { return false; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/ConfigurationLoader.java b/proxy/src/main/java/com/velocitypowered/proxy/config/ConfigurationLoader.java new file mode 100644 index 0000000000..419f0a562c --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/ConfigurationLoader.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.config; + +/** + * Velocity Configurate Loader entry utils. + */ +public class ConfigurationLoader { + + private ConfigurationLoader() { + } + + + /** + * performs legacy configuration migration if needed. + * + * @return {@code true} if a migration was performed, {@code false} otherwise + */ + public static boolean migrateIfNeeded() { + return false; + } + + /** + * loads the velocity configuration. + * + * @return the loaded configuration + */ + public static VelocityConfiguration loadConfiguration() { + return null; + } +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/LegacyConfigurationLoader.java b/proxy/src/main/java/com/velocitypowered/proxy/config/LegacyConfigurationLoader.java new file mode 100644 index 0000000000..ab8f34898c --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/LegacyConfigurationLoader.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2024 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.config; + +import static com.velocitypowered.proxy.config.VelocityConfiguration.Servers.cleanServerName; +import static com.velocitypowered.proxy.config.VelocityConfiguration.generateRandomString; + +import com.electronwill.nightconfig.core.CommentedConfig; +import com.electronwill.nightconfig.core.UnmodifiableConfig; +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.velocitypowered.proxy.config.migration.ConfigurationMigration; +import com.velocitypowered.proxy.config.migration.ForwardingMigration; +import com.velocitypowered.proxy.config.migration.KeyAuthenticationMigration; +import com.velocitypowered.proxy.config.migration.MotdMigration; +import com.velocitypowered.proxy.config.migration.TransferIntegrationMigration; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Legacy configuration loader for Velocity. + */ +public class LegacyConfigurationLoader { + private static final Logger logger = LogManager.getLogger(LegacyConfigurationLoader.class); + + /** + * Reads the Velocity configuration from {@code path}. + * + * @param path the path to read from + * @return the deserialized Velocity configuration + * @throws IOException if we could not read from the {@code path}. + */ + @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", + justification = "I looked carefully and there's no way SpotBugs is right.") + public static VelocityConfiguration read(Path path) throws IOException { + URL defaultConfigLocation = VelocityConfiguration.class.getClassLoader() + .getResource("default-velocity.toml"); + if (defaultConfigLocation == null) { + throw new RuntimeException("Default configuration file does not exist."); + } + + // Create the forwarding-secret file on first-time startup if it doesn't exist + final Path defaultForwardingSecretPath = Path.of("forwarding.secret"); + if (Files.notExists(path) && Files.notExists(defaultForwardingSecretPath)) { + Files.writeString(defaultForwardingSecretPath, generateRandomString(12)); + } + + try (final CommentedFileConfig config = CommentedFileConfig.builder(path) + .defaultData(defaultConfigLocation) + .autosave() + .preserveInsertionOrder() + .sync() + .build() + ) { + config.load(); + + final ConfigurationMigration[] migrations = { + new ForwardingMigration(), + new KeyAuthenticationMigration(), + new MotdMigration(), + new TransferIntegrationMigration() + }; + + for (final ConfigurationMigration migration : migrations) { + if (migration.shouldMigrate(config)) { + migration.migrate(config, logger); + } + } + + String forwardingSecretString = System.getenv().getOrDefault( + "VELOCITY_FORWARDING_SECRET", ""); + if (forwardingSecretString.isEmpty()) { + final String forwardSecretFile = config.get("forwarding-secret-file"); + final Path secretPath = forwardSecretFile == null + ? defaultForwardingSecretPath + : Path.of(forwardSecretFile); + if (Files.exists(secretPath)) { + if (Files.isRegularFile(secretPath)) { + forwardingSecretString = String.join("", Files.readAllLines(secretPath)); + } else { + throw new RuntimeException( + "The file " + forwardSecretFile + " is not a valid file or it is a directory."); + } + } else { + throw new RuntimeException("The forwarding-secret-file does not exist."); + } + } + final byte[] forwardingSecret = forwardingSecretString.getBytes(StandardCharsets.UTF_8); + final String motd = config.getOrElse("motd", "<#09add3>A Velocity Server"); + + // Read the rest of the config + final CommentedConfig serversConfig = config.get("servers"); + final CommentedConfig forcedHostsConfig = config.get("forced-hosts"); + final CommentedConfig advancedConfig = config.get("advanced"); + final CommentedConfig queryConfig = config.get("query"); + final CommentedConfig metricsConfig = config.get("metrics"); + final PlayerInfoForwarding forwardingMode = config.getEnumOrElse( + "player-info-forwarding-mode", PlayerInfoForwarding.NONE); + final PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough", + PingPassthroughMode.DISABLED); + + final String bind = config.getOrElse("bind", "0.0.0.0:25565"); + final int maxPlayers = config.getIntOrElse("show-max-players", 500); + final boolean onlineMode = config.getOrElse("online-mode", true); + final boolean forceKeyAuthentication = config.getOrElse("force-key-authentication", true); + final boolean announceForge = config.getOrElse("announce-forge", true); + final boolean preventClientProxyConnections = config.getOrElse( + "prevent-client-proxy-connections", false); + final boolean kickExisting = config.getOrElse("kick-existing-players", false); + final boolean enablePlayerAddressLogging = config.getOrElse( + "enable-player-address-logging", true); + + // Throw an exception if the forwarding-secret file is empty and the proxy is using a + // forwarding mode that requires it. + if (forwardingSecret.length == 0 + && (forwardingMode == PlayerInfoForwarding.MODERN + || forwardingMode == PlayerInfoForwarding.BUNGEEGUARD)) { + throw new RuntimeException("The forwarding-secret file must not be empty."); + } + + return new VelocityConfiguration( + bind, + motd, + maxPlayers, + onlineMode, + preventClientProxyConnections, + announceForge, + forwardingMode, + forwardingSecret, + kickExisting, + pingPassthroughMode, + enablePlayerAddressLogging, + readServers(serversConfig), + readForcedHosts(forcedHostsConfig), + readAdvanced(advancedConfig), + readQuery(queryConfig), + readMetrics(metricsConfig), + forceKeyAuthentication + ); + } + } + + + private static VelocityConfiguration.Servers readServers(CommentedConfig config) { + if (config != null) { + Map servers = new HashMap<>(); + for (UnmodifiableConfig.Entry entry : config.entrySet()) { + if (entry.getValue() instanceof String) { + servers.put(cleanServerName(entry.getKey()), entry.getValue()); + } else { + if (!entry.getKey().equalsIgnoreCase("try")) { + throw new IllegalArgumentException( + "Server entry " + entry.getKey() + " is not a string!"); + } + } + } + return new VelocityConfiguration.Servers(ImmutableMap.copyOf(servers), + config.getOrElse("try", ImmutableList.of("lobby"))); + } + return new VelocityConfiguration.Servers(); + } + + private static VelocityConfiguration.ForcedHosts readForcedHosts(CommentedConfig config) { + if (config != null) { + Map> forcedHosts = new HashMap<>(); + for (UnmodifiableConfig.Entry entry : config.entrySet()) { + if (entry.getValue() instanceof String) { + forcedHosts.put(entry.getKey().toLowerCase(Locale.ROOT), + ImmutableList.of(entry.getValue())); + } else if (entry.getValue() instanceof List) { + forcedHosts.put(entry.getKey().toLowerCase(Locale.ROOT), + ImmutableList.copyOf((List) entry.getValue())); + } else { + throw new IllegalStateException( + "Invalid value of type " + entry.getValue().getClass() + " in forced hosts!"); + } + } + return new VelocityConfiguration.ForcedHosts(forcedHosts); + } + return new VelocityConfiguration.ForcedHosts(); + } + + private static VelocityConfiguration.Advanced readAdvanced(CommentedConfig config) { + if (config != null) { + int compressionThreshold = config.getIntOrElse("compression-threshold", 256); + int compressionLevel = config.getIntOrElse("compression-level", -1); + int loginRatelimit = config.getIntOrElse("login-ratelimit", 3000); + int connectionTimeout = config.getIntOrElse("connection-timeout", 5000); + int readTimeout = config.getIntOrElse("read-timeout", 30000); + boolean proxyProtocol = false; + if (config.contains("haproxy-protocol")) { + proxyProtocol = config.getOrElse("haproxy-protocol", false); + } else { + proxyProtocol = config.getOrElse("proxy-protocol", false); + } + boolean tcpFastOpen = config.getOrElse("tcp-fast-open", false); + boolean bungeePluginMessageChannel = config.getOrElse("bungee-plugin-message-channel", true); + boolean showPingRequests = config.getOrElse("show-ping-requests", false); + boolean failoverOnUnexpectedServerDisconnect = config + .getOrElse("failover-on-unexpected-server-disconnect", true); + boolean announceProxyCommands = config.getOrElse("announce-proxy-commands", true); + boolean logCommandExecutions = config.getOrElse("log-command-executions", false); + boolean logPlayerConnections = config.getOrElse("log-player-connections", true); + boolean acceptTransfers = config.getOrElse("accepts-transfers", false); + return new VelocityConfiguration.Advanced(compressionThreshold, compressionLevel, + loginRatelimit, connectionTimeout, readTimeout, proxyProtocol, tcpFastOpen, + bungeePluginMessageChannel, showPingRequests, failoverOnUnexpectedServerDisconnect, + announceProxyCommands, logCommandExecutions, logPlayerConnections, acceptTransfers); + } + return new VelocityConfiguration.Advanced(); + } + + private static VelocityConfiguration.Query readQuery(CommentedConfig config) { + if (config != null) { + boolean queryEnabled = config.getOrElse("enabled", false); + int queryPort = config.getIntOrElse("port", 25565); + String queryMap = config.getOrElse("map", "Velocity"); + boolean showPlugins = config.getOrElse("show-plugins", false); + return new VelocityConfiguration.Query(queryEnabled, queryPort, queryMap, showPlugins); + } + return new VelocityConfiguration.Query(); + } + + private static VelocityConfiguration.Metrics readMetrics(CommentedConfig config) { + if (config != null) { + boolean enabled = config.getOrElse("enabled", true); + return new VelocityConfiguration.Metrics(enabled); + } + return new VelocityConfiguration.Metrics(); + } + +} 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 9c2e1e8280..ab9b6dc81f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -17,32 +17,19 @@ package com.velocitypowered.proxy.config; -import com.electronwill.nightconfig.core.CommentedConfig; -import com.electronwill.nightconfig.core.UnmodifiableConfig; -import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.Expose; import com.velocitypowered.api.proxy.config.ProxyConfig; import com.velocitypowered.api.util.Favicon; -import com.velocitypowered.proxy.config.migration.ConfigurationMigration; -import com.velocitypowered.proxy.config.migration.ForwardingMigration; -import com.velocitypowered.proxy.config.migration.KeyAuthenticationMigration; -import com.velocitypowered.proxy.config.migration.MotdMigration; -import com.velocitypowered.proxy.config.migration.TransferIntegrationMigration; import com.velocitypowered.proxy.util.AddressUtil; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.io.IOException; import java.net.InetSocketAddress; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.security.SecureRandom; -import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Random; @@ -51,10 +38,12 @@ import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; /** * Velocity's configuration. */ +@ConfigSerializable public class VelocityConfiguration implements ProxyConfig { private static final Logger logger = LogManager.getLogger(VelocityConfiguration.class); @@ -93,7 +82,7 @@ public class VelocityConfiguration implements ProxyConfig { private boolean forceKeyAuthentication = true; // Added in 1.19 private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced, - Query query, Metrics metrics) { + Query query, Metrics metrics) { this.servers = servers; this.forcedHosts = forcedHosts; this.advanced = advanced; @@ -101,12 +90,14 @@ private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced this.metrics = metrics; } - private VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode, - boolean preventClientProxyConnections, boolean announceForge, - PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret, - boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough, - boolean enablePlayerAddressLogging, Servers servers, ForcedHosts forcedHosts, - Advanced advanced, Query query, Metrics metrics, boolean forceKeyAuthentication) { + VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode, + boolean preventClientProxyConnections, boolean announceForge, + PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret, + boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough, + boolean enablePlayerAddressLogging, Servers servers, + ForcedHosts forcedHosts, + Advanced advanced, Query query, Metrics metrics, + boolean forceKeyAuthentication) { this.bind = bind; this.motd = motd; this.showMaxPlayers = showMaxPlayers; @@ -427,123 +418,6 @@ public String toString() { .toString(); } - /** - * Reads the Velocity configuration from {@code path}. - * - * @param path the path to read from - * @return the deserialized Velocity configuration - * @throws IOException if we could not read from the {@code path}. - */ - @SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", - justification = "I looked carefully and there's no way SpotBugs is right.") - public static VelocityConfiguration read(Path path) throws IOException { - URL defaultConfigLocation = VelocityConfiguration.class.getClassLoader() - .getResource("default-velocity.toml"); - if (defaultConfigLocation == null) { - throw new RuntimeException("Default configuration file does not exist."); - } - - // Create the forwarding-secret file on first-time startup if it doesn't exist - final Path defaultForwardingSecretPath = Path.of("forwarding.secret"); - if (Files.notExists(path) && Files.notExists(defaultForwardingSecretPath)) { - Files.writeString(defaultForwardingSecretPath, generateRandomString(12)); - } - - try (final CommentedFileConfig config = CommentedFileConfig.builder(path) - .defaultData(defaultConfigLocation) - .autosave() - .preserveInsertionOrder() - .sync() - .build() - ) { - config.load(); - - final ConfigurationMigration[] migrations = { - new ForwardingMigration(), - new KeyAuthenticationMigration(), - new MotdMigration(), - new TransferIntegrationMigration() - }; - - for (final ConfigurationMigration migration : migrations) { - if (migration.shouldMigrate(config)) { - migration.migrate(config, logger); - } - } - - String forwardingSecretString = System.getenv().getOrDefault( - "VELOCITY_FORWARDING_SECRET", ""); - if (forwardingSecretString.isEmpty()) { - final String forwardSecretFile = config.get("forwarding-secret-file"); - final Path secretPath = forwardSecretFile == null - ? defaultForwardingSecretPath - : Path.of(forwardSecretFile); - if (Files.exists(secretPath)) { - if (Files.isRegularFile(secretPath)) { - forwardingSecretString = String.join("", Files.readAllLines(secretPath)); - } else { - throw new RuntimeException( - "The file " + forwardSecretFile + " is not a valid file or it is a directory."); - } - } else { - throw new RuntimeException("The forwarding-secret-file does not exist."); - } - } - final byte[] forwardingSecret = forwardingSecretString.getBytes(StandardCharsets.UTF_8); - final String motd = config.getOrElse("motd", "<#09add3>A Velocity Server"); - - // Read the rest of the config - final CommentedConfig serversConfig = config.get("servers"); - final CommentedConfig forcedHostsConfig = config.get("forced-hosts"); - final CommentedConfig advancedConfig = config.get("advanced"); - final CommentedConfig queryConfig = config.get("query"); - final CommentedConfig metricsConfig = config.get("metrics"); - final PlayerInfoForwarding forwardingMode = config.getEnumOrElse( - "player-info-forwarding-mode", PlayerInfoForwarding.NONE); - final PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough", - PingPassthroughMode.DISABLED); - - final String bind = config.getOrElse("bind", "0.0.0.0:25565"); - final int maxPlayers = config.getIntOrElse("show-max-players", 500); - final boolean onlineMode = config.getOrElse("online-mode", true); - final boolean forceKeyAuthentication = config.getOrElse("force-key-authentication", true); - final boolean announceForge = config.getOrElse("announce-forge", true); - final boolean preventClientProxyConnections = config.getOrElse( - "prevent-client-proxy-connections", false); - final boolean kickExisting = config.getOrElse("kick-existing-players", false); - final boolean enablePlayerAddressLogging = config.getOrElse( - "enable-player-address-logging", true); - - // Throw an exception if the forwarding-secret file is empty and the proxy is using a - // forwarding mode that requires it. - if (forwardingSecret.length == 0 - && (forwardingMode == PlayerInfoForwarding.MODERN - || forwardingMode == PlayerInfoForwarding.BUNGEEGUARD)) { - throw new RuntimeException("The forwarding-secret file must not be empty."); - } - - return new VelocityConfiguration( - bind, - motd, - maxPlayers, - onlineMode, - preventClientProxyConnections, - announceForge, - forwardingMode, - forwardingSecret, - kickExisting, - pingPassthroughMode, - enablePlayerAddressLogging, - new Servers(serversConfig), - new ForcedHosts(forcedHostsConfig), - new Advanced(advancedConfig), - new Query(queryConfig), - new Metrics(metricsConfig), - forceKeyAuthentication - ); - } - } - /** * Generates a Random String. * @@ -564,7 +438,7 @@ public boolean isOnlineModeKickExistingPlayers() { return onlineModeKickExistingPlayers; } - private static class Servers { + static class Servers { private Map servers = ImmutableMap.of( "lobby", "127.0.0.1:30066", @@ -573,28 +447,10 @@ private static class Servers { ); private List attemptConnectionOrder = ImmutableList.of("lobby"); - private Servers() { - } - - private Servers(CommentedConfig config) { - if (config != null) { - Map servers = new HashMap<>(); - for (UnmodifiableConfig.Entry entry : config.entrySet()) { - if (entry.getValue() instanceof String) { - servers.put(cleanServerName(entry.getKey()), entry.getValue()); - } else { - if (!entry.getKey().equalsIgnoreCase("try")) { - throw new IllegalArgumentException( - "Server entry " + entry.getKey() + " is not a string!"); - } - } - } - this.servers = ImmutableMap.copyOf(servers); - this.attemptConnectionOrder = config.getOrElse("try", attemptConnectionOrder); - } + Servers() { } - private Servers(Map servers, List attemptConnectionOrder) { + Servers(Map servers, List attemptConnectionOrder) { this.servers = servers; this.attemptConnectionOrder = attemptConnectionOrder; } @@ -623,7 +479,7 @@ public void setAttemptConnectionOrder(List attemptConnectionOrder) { * @param name the server name to clean * @return the cleaned server name */ - private String cleanServerName(String name) { + static String cleanServerName(String name) { return name.replace("\"", ""); } @@ -636,7 +492,7 @@ public String toString() { } } - private static class ForcedHosts { + static class ForcedHosts { private Map> forcedHosts = ImmutableMap.of( "lobby.example.com", ImmutableList.of("lobby"), @@ -644,29 +500,10 @@ private static class ForcedHosts { "minigames.example.com", ImmutableList.of("minigames") ); - private ForcedHosts() { - } - - private ForcedHosts(CommentedConfig config) { - if (config != null) { - Map> forcedHosts = new HashMap<>(); - for (UnmodifiableConfig.Entry entry : config.entrySet()) { - if (entry.getValue() instanceof String) { - forcedHosts.put(entry.getKey().toLowerCase(Locale.ROOT), - ImmutableList.of(entry.getValue())); - } else if (entry.getValue() instanceof List) { - forcedHosts.put(entry.getKey().toLowerCase(Locale.ROOT), - ImmutableList.copyOf((List) entry.getValue())); - } else { - throw new IllegalStateException( - "Invalid value of type " + entry.getValue().getClass() + " in forced hosts!"); - } - } - this.forcedHosts = ImmutableMap.copyOf(forcedHosts); - } + ForcedHosts() { } - private ForcedHosts(Map> forcedHosts) { + ForcedHosts(Map> forcedHosts) { this.forcedHosts = forcedHosts; } @@ -686,7 +523,7 @@ public String toString() { } } - private static class Advanced { + static class Advanced { @Expose private int compressionThreshold = 256; @@ -717,33 +554,31 @@ private static class Advanced { @Expose private boolean acceptTransfers = false; - private Advanced() { + Advanced() { } - private Advanced(CommentedConfig config) { - if (config != null) { - this.compressionThreshold = config.getIntOrElse("compression-threshold", 256); - this.compressionLevel = config.getIntOrElse("compression-level", -1); - this.loginRatelimit = config.getIntOrElse("login-ratelimit", 3000); - this.connectionTimeout = config.getIntOrElse("connection-timeout", 5000); - this.readTimeout = config.getIntOrElse("read-timeout", 30000); - if (config.contains("haproxy-protocol")) { - this.proxyProtocol = config.getOrElse("haproxy-protocol", false); - } else { - this.proxyProtocol = config.getOrElse("proxy-protocol", false); - } - this.tcpFastOpen = config.getOrElse("tcp-fast-open", false); - this.bungeePluginMessageChannel = config.getOrElse("bungee-plugin-message-channel", true); - this.showPingRequests = config.getOrElse("show-ping-requests", false); - this.failoverOnUnexpectedServerDisconnect = config - .getOrElse("failover-on-unexpected-server-disconnect", true); - this.announceProxyCommands = config.getOrElse("announce-proxy-commands", true); - this.logCommandExecutions = config.getOrElse("log-command-executions", false); - this.logPlayerConnections = config.getOrElse("log-player-connections", true); - this.acceptTransfers = config.getOrElse("accepts-transfers", false); - } + Advanced(int compressionThreshold, int compressionLevel, int loginRatelimit, + int connectionTimeout, int readTimeout, boolean proxyProtocol, boolean tcpFastOpen, + boolean bungeePluginMessageChannel, boolean showPingRequests, + boolean failoverOnUnexpectedServerDisconnect, boolean announceProxyCommands, + boolean logCommandExecutions, boolean logPlayerConnections, boolean acceptTransfers) { + this.compressionThreshold = compressionThreshold; + this.compressionLevel = compressionLevel; + this.loginRatelimit = loginRatelimit; + this.connectionTimeout = connectionTimeout; + this.readTimeout = readTimeout; + this.proxyProtocol = proxyProtocol; + this.tcpFastOpen = tcpFastOpen; + this.bungeePluginMessageChannel = bungeePluginMessageChannel; + this.showPingRequests = showPingRequests; + this.failoverOnUnexpectedServerDisconnect = failoverOnUnexpectedServerDisconnect; + this.announceProxyCommands = announceProxyCommands; + this.logCommandExecutions = logCommandExecutions; + this.logPlayerConnections = logPlayerConnections; + this.acceptTransfers = acceptTransfers; } + public int getCompressionThreshold() { return compressionThreshold; } @@ -825,7 +660,7 @@ public String toString() { } } - private static class Query { + static class Query { @Expose private boolean queryEnabled = false; @@ -836,25 +671,16 @@ private static class Query { @Expose private boolean showPlugins = false; - private Query() { + Query() { } - private Query(boolean queryEnabled, int queryPort, String queryMap, boolean showPlugins) { + Query(boolean queryEnabled, int queryPort, String queryMap, boolean showPlugins) { this.queryEnabled = queryEnabled; this.queryPort = queryPort; this.queryMap = queryMap; this.showPlugins = showPlugins; } - private Query(CommentedConfig config) { - if (config != null) { - this.queryEnabled = config.getOrElse("enabled", false); - this.queryPort = config.getIntOrElse("port", 25565); - this.queryMap = config.getOrElse("map", "Velocity"); - this.showPlugins = config.getOrElse("show-plugins", false); - } - } - public boolean isQueryEnabled() { return queryEnabled; } @@ -889,10 +715,11 @@ public static class Metrics { private boolean enabled = true; - private Metrics(CommentedConfig toml) { - if (toml != null) { - this.enabled = toml.getOrElse("enabled", true); - } + Metrics() { + } + + Metrics(boolean enabled) { + this.enabled = enabled; } public boolean isEnabled() {