diff --git a/build.gradle b/build.gradle index 8410bf59..2597897a 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,6 @@ dependencies { includeInJar "com.formdev:flatlaf-extras:3.7.1" includeInJar "org.apache.commons:commons-lang3:3.20.0" includeInJar "commons-io:commons-io:2.22.0" - includeInJar "net.sf.jopt-simple:jopt-simple:5.0.4" includeInJar "org.apache.logging.log4j:log4j-core:2.25.4" includeInJar "org.apache.logging.log4j:log4j-slf4j2-impl:2.25.4" includeInJar "org.jline:jansi:4.0.14" @@ -106,7 +105,7 @@ dependencies { includeInJar "dev.kastle.webrtc:webrtc-java:1.0.3:$it" } includeInJar "gs.mclo:api:6.2.1" - includeInJar "net.lenni0451:optconfig:1.1.1" + includeInJar "net.lenni0451.optconfig:cli:2.0.0-20260504.192228-9" includeInJarJ8(compileOnly("xyz.wagyourtail.jvmdowngrader:jvmdowngrader:1.3.6")) includeInJarJ8 "xyz.wagyourtail.jvmdowngrader:jvmdowngrader-java-api:1.3.6:downgraded-8" diff --git a/src/main/java/net/raphimc/viaproxy/ViaProxy.java b/src/main/java/net/raphimc/viaproxy/ViaProxy.java index 33609475..8ddae7a9 100644 --- a/src/main/java/net/raphimc/viaproxy/ViaProxy.java +++ b/src/main/java/net/raphimc/viaproxy/ViaProxy.java @@ -44,6 +44,7 @@ import net.raphimc.viaproxy.plugins.events.ProxyStopEvent; import net.raphimc.viaproxy.plugins.events.ViaProxyLoadedEvent; import net.raphimc.viaproxy.protocoltranslator.ProtocolTranslator; +import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyCLIConfig; import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; import net.raphimc.viaproxy.proxy.client2proxy.Client2ProxyChannelInitializer; import net.raphimc.viaproxy.proxy.client2proxy.Client2ProxyHandler; @@ -232,7 +233,11 @@ public static void injectedMain(final String injectionMethod, final String[] arg viaProxyConfigFile = new File(ViaProxy.getCwd(), "viaproxy.yml"); } final boolean firstStart = !viaProxyConfigFile.exists(); - CONFIG = ViaProxyConfig.create(viaProxyConfigFile); + if (useCLI) { + CONFIG = ViaProxyCLIConfig.create(viaProxyConfigFile); + } else { + CONFIG = ViaProxyConfig.create(viaProxyConfigFile); + } if (useUI) { progressConsumer.accept("Loading GUI"); @@ -256,7 +261,7 @@ public static void injectedMain(final String injectionMethod, final String[] arg final String[] cliArgs = new String[args.length - 1]; System.arraycopy(args, 1, cliArgs, 0, cliArgs.length); try { - CONFIG.loadFromArguments(cliArgs); + ((ViaProxyCLIConfig) CONFIG).loadFromArguments(cliArgs); } catch (Throwable e) { throw new RuntimeException("Failed to load CLI arguments", e); } @@ -284,8 +289,8 @@ public static void startProxy() { Logger.LOGGER.info("Starting proxy server"); currentProxyServer = new NetServer(new Client2ProxyChannelInitializer(() -> EVENT_MANAGER.call(new Client2ProxyHandlerCreationEvent(new Client2ProxyHandler(), false)).getHandler())); EVENT_MANAGER.call(new ProxyStartEvent()); - Logger.LOGGER.info("Binding proxy server to " + AddressUtil.toString(CONFIG.getBindAddress())); - currentProxyServer.bind(CONFIG.getBindAddress(), false); + Logger.LOGGER.info("Binding proxy server to " + AddressUtil.toString(CONFIG.getFrontend().getBindAddress())); + currentProxyServer.bind(CONFIG.getFrontend().getBindAddress(), false); } catch (Throwable e) { currentProxyServer = null; throw e; diff --git a/src/main/java/net/raphimc/viaproxy/cli/BetterHelpFormatter.java b/src/main/java/net/raphimc/viaproxy/cli/BetterHelpFormatter.java deleted file mode 100644 index cc8c7a46..00000000 --- a/src/main/java/net/raphimc/viaproxy/cli/BetterHelpFormatter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy - * Copyright (C) 2021-2026 RK_01/RaphiMC and 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 net.raphimc.viaproxy.cli; - -import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; -import joptsimple.BuiltinHelpFormatter; -import joptsimple.OptionDescriptor; -import joptsimple.internal.Classes; -import joptsimple.internal.Strings; - -import java.util.List; - -public class BetterHelpFormatter extends BuiltinHelpFormatter { - - public BetterHelpFormatter() { - super(120, 2); - } - - @Override - protected String extractTypeIndicator(OptionDescriptor descriptor) { - String indicator = descriptor.argumentTypeIndicator(); - if (indicator != null) { - indicator = indicator.substring(indicator.indexOf('$') + 1); - if (indicator.startsWith("[")) { - return indicator.substring(1, indicator.length() - 1); - } - } - return !Strings.isNullOrEmpty(indicator) && !String.class.getName().equals(indicator) ? Classes.shortNameOf(indicator) : "String"; - } - - @Override - protected String createDefaultValuesDisplay(List defaultValues) { - if (defaultValues.size() == 1) { - Object value = defaultValues.get(0); - if (value instanceof ProtocolVersion version) { - return version.getName(); - } else if (value instanceof String) { - return "\"" + value + "\""; - } - - return value.toString(); - } - - return defaultValues.toString(); - } - -} diff --git a/src/main/java/net/raphimc/viaproxy/cli/ConsoleFormatter.java b/src/main/java/net/raphimc/viaproxy/cli/ConsoleFormatter.java index 9731763a..cf4734b9 100644 --- a/src/main/java/net/raphimc/viaproxy/cli/ConsoleFormatter.java +++ b/src/main/java/net/raphimc/viaproxy/cli/ConsoleFormatter.java @@ -17,88 +17,22 @@ */ package net.raphimc.viaproxy.cli; -public class ConsoleFormatter { - - private static final String PREFIX = "\033["; - private static final String SUFFIX = "m"; +import net.lenni0451.mcstructs.text.TextComponent; +import net.lenni0451.mcstructs.text.stringformat.StringFormat; +import net.lenni0451.mcstructs.text.stringformat.handling.ColorHandling; +import net.lenni0451.mcstructs.text.stringformat.handling.SerializerUnknownHandling; - public static String convert(final String s) { - StringBuilder out = new StringBuilder(); - char[] chars = s.toCharArray(); - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - char next = i + 1 < chars.length ? chars[i + 1] : '\0'; - if (c == '§') { - if (next != '\0') { - if (isColor(next)) out.append(convertToAnsi('r')); - out.append(convertToAnsi(next)); - i++; - } - } else { - out.append(c); - } - } - return out + convertToAnsi('r'); - } +public class ConsoleFormatter { - //The ANSI codes are an approximation. True color is used to get the exact color. - private static String convertToAnsi(final char color) { - switch (Character.toLowerCase(color)) { - case '0': //Black - return PREFIX + getColor("30", 0x00_00_00) + SUFFIX; - case '1': //Dark Blue - return PREFIX + getColor("34", 0x00_00_AA) + SUFFIX; - case '2': //Dark Green - return PREFIX + getColor("32", 0x00_AA_00) + SUFFIX; - case '3': //Dark Aqua - return PREFIX + getColor("36", 0x00_AA_AA) + SUFFIX; - case '4': //Dark Red - return PREFIX + getColor("31", 0xAA_00_00) + SUFFIX; - case '5': //Dark Purple - return PREFIX + getColor("35", 0xAA_00_AA) + SUFFIX; - case '6': //Gold - return PREFIX + getColor("33", 0xFF_AA_00) + SUFFIX; - case '7': //Gray - return PREFIX + getColor("37", 0xAA_AA_AA) + SUFFIX; - case '8': //Dark Gray - return PREFIX + getColor("90", 0x55_55_55) + SUFFIX; - case '9': //Blue - return PREFIX + getColor("94", 0x55_55_FF) + SUFFIX; - case 'a': //Green - return PREFIX + getColor("92", 0x55_FF_55) + SUFFIX; - case 'b': //Aqua - return PREFIX + getColor("96", 0x55_FF_FF) + SUFFIX; - case 'c': //Red - return PREFIX + getColor("91", 0xFF_55_55) + SUFFIX; - case 'd': //Light Purple - return PREFIX + getColor("95", 0xFF_55_FF) + SUFFIX; - case 'e': //Yellow - return PREFIX + getColor("93", 0xFF_FF_55) + SUFFIX; - case 'f': //White - return PREFIX + getColor("97", 0xFF_FF_FF) + SUFFIX; - case 'k': //Obfuscated - return ""; //Not supported in terminal - case 'l': //Bold - return PREFIX + "1" + SUFFIX; - case 'm': //Strikethrough - return PREFIX + "9" + SUFFIX; - case 'n': //Underline - return PREFIX + "4" + SUFFIX; - case 'o': //Italic - return PREFIX + "3" + SUFFIX; - case 'r': //Reset - default: - return PREFIX + 0 + SUFFIX; - } - } + private static final StringFormat VANILLA_FORMAT = StringFormat.vanilla(); + private static final StringFormat ANSI_FORMAT = StringFormat.ansi(); - private static boolean isColor(char color) { - color = Character.toLowerCase(color); - return color >= '0' && color <= '9' || color >= 'a' && color <= 'f'; + public static String convert(final String legacyString) { + return VANILLA_FORMAT.convertTo(legacyString, ANSI_FORMAT); } - private static String getColor(final String ansi, final int rgb) { - return String.format("38;2;%d;%d;%d", (rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255); + public static String convert(final TextComponent component) { + return ANSI_FORMAT.toString(component, ColorHandling.RESET, SerializerUnknownHandling.IGNORE); } } diff --git a/src/main/java/net/raphimc/viaproxy/cli/HelpRequestedException.java b/src/main/java/net/raphimc/viaproxy/cli/HelpRequestedException.java deleted file mode 100644 index 572afbb7..00000000 --- a/src/main/java/net/raphimc/viaproxy/cli/HelpRequestedException.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy - * Copyright (C) 2021-2026 RK_01/RaphiMC and 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 net.raphimc.viaproxy.cli; - -public class HelpRequestedException extends RuntimeException { -} diff --git a/src/main/java/net/raphimc/viaproxy/cli/command/impl/AccountCommand.java b/src/main/java/net/raphimc/viaproxy/cli/command/impl/AccountCommand.java index 14f2ee1c..27b41418 100644 --- a/src/main/java/net/raphimc/viaproxy/cli/command/impl/AccountCommand.java +++ b/src/main/java/net/raphimc/viaproxy/cli/command/impl/AccountCommand.java @@ -55,14 +55,14 @@ public void register(LiteralArgumentBuilder builder) { ctx.getSource().sendMessage("No accounts added yet."); } else { for (int i = 0; i < accounts.size(); i++) { - boolean isSelected = ViaProxy.getConfig().getAccount() == accounts.get(i); + boolean isSelected = ViaProxy.getConfig().getProxy().getAccount() == accounts.get(i); ctx.getSource().sendMessage("[" + i + "] " + accounts.get(i).getDisplayString() + (isSelected ? " <--" : "")); } } return 1; })); builder.then(literal("deselect").executes(ctx -> { - ViaProxy.getConfig().setAccount(null); + ViaProxy.getConfig().getProxy().setAccount(null); ctx.getSource().sendMessage("Deselected current account."); return 1; })); @@ -78,7 +78,7 @@ public void register(LiteralArgumentBuilder builder) { return 0; } Account account = ViaProxy.getSaveManager().accountsSave.getAccounts().get(index); - ViaProxy.getConfig().setAccount(account); + ViaProxy.getConfig().getProxy().setAccount(account); ctx.getSource().sendMessage("Selected account " + index + ": " + account.getDisplayString() + "."); return 1; }))); @@ -111,8 +111,8 @@ public void register(LiteralArgumentBuilder builder) { Account account = ViaProxy.getSaveManager().accountsSave.getAccounts().get(index); ViaProxy.getSaveManager().accountsSave.removeAccount(account); ViaProxy.getSaveManager().save(); - if (ViaProxy.getConfig().getAccount() == account) { - ViaProxy.getConfig().setAccount(null); + if (ViaProxy.getConfig().getProxy().getAccount() == account) { + ViaProxy.getConfig().getProxy().setAccount(null); } ctx.getSource().sendMessage("Removed account " + index + ": " + account.getDisplayString() + "."); return 1; diff --git a/src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_20To1_20_2.java b/src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_20To1_20_2.java index 8a71bb6e..1acf3094 100644 --- a/src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_20To1_20_2.java +++ b/src/main/java/net/raphimc/viaproxy/injection/mixins/MixinProtocol1_20To1_20_2.java @@ -32,7 +32,7 @@ public abstract class MixinProtocol1_20To1_20_2 { @Inject(method = "lambda$queueServerboundPacket$12", at = @At("HEAD"), cancellable = true) private static void dontQueueConfigPackets(ServerboundPackets1_20_2 packetType, PacketWrapper wrapper, CallbackInfo ci) { - if (ViaProxy.getConfig().shouldSkipConfigStatePacketQueue()) { + if (ViaProxy.getConfig().getProxy().shouldSkipConfigStatePacketQueue()) { ci.cancel(); switch (packetType) { case CUSTOM_PAYLOAD -> wrapper.setPacketType(ServerboundPackets1_19_4.CUSTOM_PAYLOAD); diff --git a/src/main/java/net/raphimc/viaproxy/plugins/events/PostOptionsParseEvent.java b/src/main/java/net/raphimc/viaproxy/plugins/events/PostOptionsParseEvent.java deleted file mode 100644 index e80ef24a..00000000 --- a/src/main/java/net/raphimc/viaproxy/plugins/events/PostOptionsParseEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy - * Copyright (C) 2021-2026 RK_01/RaphiMC and 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 net.raphimc.viaproxy.plugins.events; - -import joptsimple.OptionSet; - -public class PostOptionsParseEvent { - - private final OptionSet options; - - public PostOptionsParseEvent(final OptionSet options) { - this.options = options; - } - - public OptionSet getOptions() { - return this.options; - } - -} diff --git a/src/main/java/net/raphimc/viaproxy/plugins/events/PreOptionsParseEvent.java b/src/main/java/net/raphimc/viaproxy/plugins/events/PreOptionsParseEvent.java deleted file mode 100644 index 4b1bce34..00000000 --- a/src/main/java/net/raphimc/viaproxy/plugins/events/PreOptionsParseEvent.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy - * Copyright (C) 2021-2026 RK_01/RaphiMC and 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 net.raphimc.viaproxy.plugins.events; - -import joptsimple.OptionParser; - -public class PreOptionsParseEvent { - - private final OptionParser parser; - - public PreOptionsParseEvent(final OptionParser parser) { - this.parser = parser; - } - - public OptionParser getParser() { - return this.parser; - } - -} diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaCodec.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaCodec.java index 3fdb636c..21c2c3bd 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaCodec.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaCodec.java @@ -31,7 +31,7 @@ public ViaProxyViaCodec(UserConnection user) { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (ViaProxy.getConfig().shouldIgnoreProtocolTranslationErrors()) { + if (ViaProxy.getConfig().getAdvanced().shouldIgnoreProtocolTranslationErrors()) { try { super.channelRead(ctx, msg); } catch (Throwable e) { diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyClassicMPPassProvider.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyClassicMPPassProvider.java index b2e1f33b..5bb74747 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyClassicMPPassProvider.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyClassicMPPassProvider.java @@ -27,6 +27,7 @@ import net.raphimc.vialegacy.protocol.release.r1_2_4_5tor1_3_1_2.provider.OldAuthProvider; import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.proxy.session.ProxyConnection; +import net.raphimc.viaproxy.saves.impl.accounts.ClassicAccount; import java.nio.charset.StandardCharsets; import java.util.HexFormat; @@ -36,10 +37,9 @@ public class ViaProxyClassicMPPassProvider extends ClassicMPPassProvider { @Override public String getMpPass(UserConnection user) { - final String mppass = ProxyConnection.fromUserConnection(user).getUserOptions().classicMpPass(); - if (mppass != null && !mppass.isBlank()) { - return mppass; - } else if (ViaProxy.getConfig().useBetacraftAuth()) { + if (ProxyConnection.fromUserConnection(user).getUserOptions().account() instanceof ClassicAccount classicAccount) { + return classicAccount.getMppass(); + } else if (ViaProxy.getConfig().getBackend().useBetaCraftAuth()) { try { final HttpClient httpClient = new HttpClient(); String externalIp; diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ConsoleCommandSender.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ConsoleCommandSender.java index a1a279af..0f047e49 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ConsoleCommandSender.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ConsoleCommandSender.java @@ -28,12 +28,12 @@ public class ConsoleCommandSender implements ViaCommandSender { private static final UUID CONSOLE_UUID = new UUID(0, 0); @Override - public boolean hasPermission(String permission) { + public boolean hasPermission(final String permission) { return true; } @Override - public void sendMessage(String msg) { + public void sendMessage(final String msg) { Via.getPlatform().getLogger().info(ConsoleFormatter.convert(msg)); } diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyCLIConfig.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyCLIConfig.java new file mode 100644 index 00000000..71047843 --- /dev/null +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyCLIConfig.java @@ -0,0 +1,105 @@ +/* + * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy + * Copyright (C) 2021-2026 RK_01/RaphiMC and 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 net.raphimc.viaproxy.protocoltranslator.viaproxy; + +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.lenni0451.optconfig.CLIConfigLoader; +import net.lenni0451.optconfig.ConfigContext; +import net.lenni0451.optconfig.ConfigLoader; +import net.lenni0451.optconfig.annotations.*; +import net.lenni0451.optconfig.cli.model.HelpOptions; +import net.lenni0451.optconfig.cli.model.LoadedOptions; +import net.lenni0451.optconfig.exceptions.CLIMissingOptionValueException; +import net.lenni0451.optconfig.exceptions.CLIParserException; +import net.lenni0451.optconfig.exceptions.InvalidSerializedObjectException; +import net.lenni0451.optconfig.provider.ConfigProvider; +import net.raphimc.viaproxy.util.logging.Logger; + +import java.io.File; + +@OptConfig +@CheckSuperclass(useParentAnnotation = true) +public class ViaProxyCLIConfig extends ViaProxyConfig { + + private ConfigContext configContext; + + @Hidden + @Option("help") + @Description("Displays a help message with a list of all available options") + private boolean help = false; + + @Hidden + @Option("extended-help") + @Description("Displays an extended help message with detailed descriptions of the options") + private boolean extendedHelp = false; + + @Hidden + @Option("list-versions") + @Description("Lists all supported backend server versions and exits") + private boolean listVersions = false; + + public static ViaProxyCLIConfig create(final File configFile) { + final ConfigLoader configLoader = new ConfigLoader<>(ViaProxyCLIConfig.class); + configLoader.getConfigOptions().setRewriteConfig(true).setDeserializerExceptionHandler((option, exception) -> Logger.LOGGER.warn("Failed to deserialize option '{}'. Resetting it. Error: {}", option, exception.getMessage())); + try { + return configLoader.load(ConfigProvider.file(configFile)).getConfigInstance(); + } catch (Throwable e) { + throw new RuntimeException("Failed to load config", e); + } + } + + public void loadFromArguments(final String[] args) { + this.configContext.getConfigLoader().getConfigOptions().setResetInvalidOptions(false); + final CLIConfigLoader cliConfigLoader = new CLIConfigLoader<>(this.configContext); + try { + final LoadedOptions loadedOptions = cliConfigLoader.loadCLIOptions(args, true); + if (this.help || this.extendedHelp) { + throw new HelpRequestedException(); + } else if (this.listVersions) { + Logger.LOGGER.info("=== Supported backend server versions ==="); + for (ProtocolVersion version : ProtocolVersion.getProtocols()) { + Logger.LOGGER.info(version.getName()); + } + Logger.LOGGER.info("==================================="); + System.exit(0); + } + + if (loadedOptions.options().contains("minecraft-account-index") && !loadedOptions.options().contains("auth-method")) { + this.getBackend().setAuthMethod(AuthMethod.ACCOUNT); + } + return; + } catch (CLIParserException | CLIMissingOptionValueException | InvalidSerializedObjectException e) { + Logger.LOGGER.fatal("Error parsing CLI options: {}", e.getMessage()); + } catch (HelpRequestedException ignored) { + } + + cliConfigLoader.printCLIHelp(Logger.SYSOUT, HelpOptions.DEFAULT.withShowDescription(this.extendedHelp).withShowDepends(false).withShowBooleanType(true)); + if (!this.extendedHelp) { + Logger.LOGGER.info("For a more detailed description of the options, use --extended-help or refer to the viaproxy.yml file."); + } + System.exit(1); + } + + @Override + public void save() { + } + + private static class HelpRequestedException extends Exception { + } + +} diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyConfig.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyConfig.java index 06e50c0a..71c70499 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyConfig.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/viaproxy/ViaProxyConfig.java @@ -18,27 +18,16 @@ package net.raphimc.viaproxy.protocoltranslator.viaproxy; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; -import joptsimple.OptionException; -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import joptsimple.OptionSpec; import net.lenni0451.optconfig.ConfigContext; import net.lenni0451.optconfig.ConfigLoader; import net.lenni0451.optconfig.annotations.*; -import net.lenni0451.optconfig.index.ClassIndexer; -import net.lenni0451.optconfig.index.ConfigType; -import net.lenni0451.optconfig.index.types.ConfigOption; -import net.lenni0451.optconfig.index.types.SectionIndex; +import net.lenni0451.optconfig.annotations.cli.CLIAliases; +import net.lenni0451.optconfig.annotations.cli.CLIName; +import net.lenni0451.optconfig.migrate.ConfigMigrator; import net.lenni0451.optconfig.provider.ConfigProvider; -import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.cli.BetterHelpFormatter; -import net.raphimc.viaproxy.cli.HelpRequestedException; -import net.raphimc.viaproxy.plugins.events.PostOptionsParseEvent; -import net.raphimc.viaproxy.plugins.events.PreOptionsParseEvent; import net.raphimc.viaproxy.protocoltranslator.ProtocolTranslator; import net.raphimc.viaproxy.saves.impl.accounts.Account; import net.raphimc.viaproxy.util.AddressUtil; -import net.raphimc.viaproxy.util.Proxy; import net.raphimc.viaproxy.util.config.*; import net.raphimc.viaproxy.util.logging.Logger; @@ -46,186 +35,32 @@ import java.net.SocketAddress; import java.util.HashMap; import java.util.Map; -import java.util.Stack; -@OptConfig(header = "ViaProxy configuration file", version = 1) +@OptConfig(header = "ViaProxy configuration file", version = 2) +@Migrator(from = 1, to = 2, migrator = ViaProxyConfig.Migrator1To2.class) public class ViaProxyConfig { private ConfigContext configContext; - @NotReloadable - @Option("bind-address") - @Description("The address ViaProxy should listen for connections.") - @TypeSerializer(SocketAddressTypeSerializer.class) - private SocketAddress bindAddress = AddressUtil.parse("0.0.0.0:25568", null); - - @Option(value = "target-address", dependencies = "target-version") - @Description("The address of the server ViaProxy should connect to.") - @TypeSerializer(TargetAddressTypeSerializer.class) - private SocketAddress targetAddress = AddressUtil.parse("127.0.0.1:25565", null); - - @Option("target-version") - @Description("The version ViaProxy should translate to. (See ViaProxy GUI for a list of versions)") - @TypeSerializer(ProtocolVersionTypeSerializer.class) - private ProtocolVersion targetVersion = ProtocolTranslator.AUTO_DETECT_PROTOCOL; - - @Option("connect-timeout") - @Description("The connect timeout for backend server connections in milliseconds.") - private int connectTimeout = 8000; - - @Option("proxy-online-mode") - @Description({ - "Proxy Online Mode allows you to see skins on online mode servers and use the signed chat features.", - "Enabling Proxy Online Mode requires your client to have a valid minecraft account." - }) - private boolean proxyOnlineMode = false; - - @Option("auth-method") - @Description({ - "The authentication method to use for joining the target server.", - "none: No authentication (Offline mode)", - "account: Use an account for joining the target server. (Has to be configured in ViaProxy GUI)" - }) - private AuthMethod authMethod = AuthMethod.NONE; - - @Option(value = "minecraft-account-index", dependencies = "auth-method") - @Description("The GUI account list index (0 indexed) of the account if the auth method is set to account.") - @TypeSerializer(AccountTypeSerializer.class) - private Account account = null; - - @Option("betacraft-auth") - @Description({ - "Use BetaCraft authentication for classic servers.", - "Enabling BetaCraft Auth allows you to join classic servers which have online mode enabled." - }) - private boolean betacraftAuth = false; - - @Option("backend-proxy-url") - @Description({ - "URL of a SOCKS(4/5)/HTTP(S) proxy which will be used for backend server connections. Leave empty to connect directly.", - "Supported formats:", - "- type://address:port", - "- type://username:password@address:port" - }) - @TypeSerializer(ProxyTypeSerializer.class) - private Proxy backendProxy = null; - - @Option("backend-haproxy") - @Description("Send HAProxy protocol messages to the target server.") - private boolean backendHaProxy = false; - - @Option("frontend-haproxy") - @Description("Read HAProxy protocol messages from client connections.") - private boolean frontendHaProxy = false; - - @Option("chat-signing") - @Description("Enables sending signed chat messages on >= 1.19 servers.") - private boolean chatSigning = true; - - @Option("compression-threshold") - @Description("The threshold for packet compression. Packets larger than this size will be compressed. (-1 to disable)") - private int compressionThreshold = 256; - - @Option("allow-beta-pinging") - @Description("Enabling this will allow you to ping <= b1.7.3 servers. This may cause issues with servers that block too frequent connections.") - private boolean allowBetaPinging = false; - - @Option("ignore-protocol-translation-errors") - @Description({ - "Enabling this will prevent getting disconnected from the server when a packet translation error occurs and instead only print the error in the console.", - "This may cause issues depending on the type of packet which failed to translate." - }) - private boolean ignoreProtocolTranslationErrors = false; - - @Option("suppress-client-protocol-errors") - @Description({ - "Enabling this will suppress client protocol errors to prevent lag when ViaProxy is getting spammed with invalid packets.", - "This may cause issues with debugging client connection issues because no error messages will be printed." - }) - private boolean suppressClientProtocolErrors = false; - - @Option("allow-legacy-client-passthrough") - @Description("Allow <= 1.6.4 clients to connect through ViaProxy to the target server. (No protocol translation or packet handling)") - private boolean allowLegacyClientPassthrough = false; - - @Option("bungeecord-player-info-passthrough") - @Description({ - "Allow additional information like player ip, player uuid to be passed through to the backend server.", - "This is typically used by proxies like BungeeCord and requires support from the backend server as well." - }) - private boolean bungeecordPlayerInfoPassthrough = false; - - @Option("rewrite-handshake-packet") - @Description({ - "Enabling this will rewrite the address in the handshake packet to a value the vanilla client would have sent when connecting directly to the target server.", - "This should be left enabled unless you are a server owner and you need the original address on the backend server." - }) - private boolean rewriteHandshakePacket = true; - - @Option("rewrite-transfer-packets") - @Description({ - "Enabling this will rewrite transfer packets to point back to ViaProxy. This allows ViaProxy to perform protocol translation when forwarding the player to the actual server from the transfer packet.", - "This should be left enabled unless you are a server owner and the servers you are transferring to perform their own protocol translation." - }) - private boolean rewriteTransferPackets = true; - - @Option("custom-motd") - @Description("Custom MOTD to send when clients ping the proxy. Leave empty to use the target server's MOTD.") - private String customMotd = ""; - - @Option("custom-favicon-path") - @Description("Relative file path to a custom favicon to send when clients ping the proxy. Leave empty to use the target server's favicon.") - private String customFaviconPath = ""; - - @Option("resource-pack-url") - @Description({"URL of a resource pack which clients can optionally download when connecting to the server. Leave empty to disable.", "Example: http://example.com/resourcepack.zip"}) - private String resourcePackUrl = ""; - - @Option("wildcard-domain-handling") - @Description({ - "Allows clients to specify a target server and version using wildcard domains.", - "none: No wildcard domain handling.", - "public: Public wildcard domain handling. Intended for usage by external clients. (Example: address_port_version.viaproxy.127.0.0.1.nip.io)", - "internal: Internal wildcard domain handling. Intended for local usage by custom clients. (Example: original-handshake-address\\7address:port\\7version\\7classic-mppass)" - }) - private WildcardDomainHandling wildcardDomainHandling = WildcardDomainHandling.NONE; - - @Option("simple-voice-chat-support") - @Description("Enables handling and rewriting of Simple Voice Chat mod packets.") - private boolean simpleVoiceChatSupport = false; - - @Option("fix-fabric-particle-api") - @Description({ - "Fixes an issue where the Fabric Particle API causes disconnects when both the client and server have the mod installed and both are 1.21.5+.", - "See https://github.com/ViaVersion/ViaFabric/issues/428" - }) - private boolean fixFabricParticleApi = true; - - @Option("fake-accept-resource-packs") - @Description({ - "Accepts resource packs from the server without showing a prompt to the client.", - "This is required for servers that require a resource pack, but the client can't load it due to version differences." - }) - private boolean fakeAcceptResourcePacks = false; - - @Option("skip-config-state-packet-queue") - @Description({ - "Fixes potential join issues on <= 1.20.1 quilt/fabric servers.", - "It's recommended to only enable this if you are experiencing issues with the config state packet queue (See above issue)." - }) - private boolean skipConfigStatePacketQueue = false; - - @Option("log-ips") - @Description("Disable this if you want to hide IP addresses in the console and log files.") - private boolean logIps = true; - - @Option("log-client-status-requests") - @Description("Enable this if you want to see client status requests in the console and log files.") - private boolean logClientStatusRequests = false; + @Option("frontend") + @Description("These options affect the behavior of the proxy related to client connections.") + private final Frontend frontend = new Frontend(); + + @Option("proxy") + @Description("These options affect the general behavior of the proxy.") + private final Proxy proxy = new Proxy(); + + @Option("backend") + @Description("These options affect the behavior of the proxy related to server connections.") + private final Backend backend = new Backend(); + + @Option("advanced") + @Description("These options are for advanced users and typically shouldn't be changed.") + private final Advanced advanced = new Advanced(); public static ViaProxyConfig create(final File configFile) { final ConfigLoader configLoader = new ConfigLoader<>(ViaProxyConfig.class); - configLoader.getConfigOptions().setResetInvalidOptions(true).setRewriteConfig(true).setCommentSpacing(1); + configLoader.getConfigOptions().setRewriteConfig(true).setDeserializerExceptionHandler((option, exception) -> Logger.LOGGER.warn("Failed to deserialize option '{}'. Resetting it. Error: {}", option, exception.getMessage())); try { return configLoader.load(ConfigProvider.file(configFile)).getConfigInstance(); } catch (Throwable e) { @@ -233,406 +68,953 @@ public static ViaProxyConfig create(final File configFile) { } } - @SuppressWarnings("UnstableApiUsage") - public void loadFromArguments(final String[] args) throws Exception { - final OptionParser optionParser = new OptionParser(); - final OptionSpec optionHelp = optionParser.accepts("help").forHelp(); - final OptionSpec optionListVersions = optionParser.accepts("list-versions", "Lists all supported server/target versions").forHelp(); + public void save() { + try { + this.configContext.save(); + } catch (Throwable e) { + throw new RuntimeException("Failed to save config", e); + } + } - final Map, ConfigOption> optionMap = new HashMap<>(); - final Stack stack = new Stack<>(); - final ConfigLoader configLoader = new ConfigLoader<>(ViaProxyConfig.class); - stack.push(ClassIndexer.indexClass(ConfigType.INSTANCED, ViaProxyConfig.class, configLoader.getConfigOptions().getClassAccessFactory())); - while (!stack.isEmpty()) { - final SectionIndex index = stack.pop(); - stack.addAll(index.getSubSections().values()); + public Frontend getFrontend() { + return this.frontend; + } + + public Proxy getProxy() { + return this.proxy; + } + + public Backend getBackend() { + return this.backend; + } + + public Advanced getAdvanced() { + return this.advanced; + } + + @Section + public class Frontend { + + @Option("bind-address") + @CLIName(value = "bind-address", omitSection = true) + @Description("The address on which ViaProxy should listen for clients.") + @TypeSerializer(SocketAddressTypeSerializer.class) + private SocketAddress bindAddress = AddressUtil.parse("0.0.0.0:25568", null); + + @Option("online-mode") + @CLIName(value = "frontend-online-mode", omitSection = true) + @CLIAliases(value = "proxy-online-mode", hidden = true) + @Description({ + "Enabling Online Mode allows clients see skins on online mode servers and use the signed chat features.", + "This requires clients to use a valid Minecraft account." + }) + private boolean onlineMode = false; + + @Option("haproxy") + @CLIName(value = "frontend-haproxy", omitSection = true) + @Description("Read HAProxy protocol messages from clients.") + private boolean haProxy = false; + + @Option("compression-threshold") + @CLIName(value = "compression-threshold", omitSection = true) + @Description("The threshold for packet compression. Packets larger than this size will be compressed. (-1 to disable)") + private int compressionThreshold = 256; + + @Option("suppress-packet-errors") + @CLIName(value = "suppress-client-packet-errors", omitSection = true) + @CLIAliases(value = "suppress-client-protocol-errors", hidden = true) + @Description({ + "Enabling this will suppress packet errors to prevent lag when ViaProxy is getting spammed with invalid packets.", + "This may cause issues with debugging client connection issues because no error messages will be printed." + }) + private boolean suppressPacketErrors = false; + + @Option("motd") + @Description("These options allow you to override parts of the backend server's MotD.") + private final MotD motd = new MotD(); + + @Option("resource-pack-url") + @CLIName(value = "resource-pack-url", omitSection = true) + @Description({ + "URL of a resource pack which will be sent to clients. Leave empty to disable.", + "Example: https://example.com/resourcepack.zip" + }) + private String resourcePackUrl = ""; + + @Option("wildcard-domain-handling") + @CLIName(value = "wildcard-domain-handling", omitSection = true) + @Description({ + "Allows clients to specify a target server and version using wildcard domains.", + "none: No wildcard domain handling.", + "public: Public wildcard domain handling. Intended for usage by external clients. (Example: address_port_version.viaproxy.127.0.0.1.nip.io)", + "internal: Internal wildcard domain handling. Intended for local usage by custom clients. (Example: original-handshake-address\\7address:port\\7version)" + }) + private WildcardDomainHandling wildcardDomainHandling = WildcardDomainHandling.NONE; + + @Option("log-client-status-requests") + @CLIName(value = "log-client-status-requests", omitSection = true) + @Description("Enable this if you want to see client status requests in the console and log files.") + private boolean logClientStatusRequests = false; + + public SocketAddress getBindAddress() { + return this.bindAddress; + } - for (ConfigOption option : index.getOptions()) { - if (index.getSubSections().containsKey(option)) continue; + public void setBindAddress(final SocketAddress bindAddress) { + this.bindAddress = bindAddress; + ViaProxyConfig.this.save(); + } - Object defaultValue = option.getFieldAccess().getValue(this); - if (option.getTypeSerializer() != null) { - defaultValue = option.createTypeSerializer(configLoader, ViaProxyConfig.class, this).serialize(defaultValue); - } - final OptionSpec cliOption = optionParser.accepts(option.getName()).withRequiredArg().ofType((Class) defaultValue.getClass()).defaultsTo(defaultValue); - optionMap.put(cliOption, option); - } + public boolean isOnlineMode() { + return this.onlineMode; } - try { - ViaProxy.EVENT_MANAGER.call(new PreOptionsParseEvent(optionParser)); - final OptionSet options = optionParser.parse(args); - if (options.has(optionHelp)) { - throw new HelpRequestedException(); - } else if (options.has(optionListVersions)) { - Logger.LOGGER.info("=== Supported Server Versions ==="); - for (ProtocolVersion version : ProtocolVersion.getProtocols()) { - Logger.LOGGER.info(version.getName()); - } - Logger.LOGGER.info("==================================="); - System.exit(0); + public void setOnlineMode(final boolean onlineMode) { + this.onlineMode = onlineMode; + ViaProxyConfig.this.save(); + } + + public boolean useHaProxy() { + return this.haProxy; + } + + public void setHaProxy(final boolean haProxy) { + this.haProxy = haProxy; + ViaProxyConfig.this.save(); + } + + public int getCompressionThreshold() { + return this.compressionThreshold; + } + + public void setCompressionThreshold(final int compressionThreshold) { + this.compressionThreshold = compressionThreshold; + ViaProxyConfig.this.save(); + } + + public boolean shouldSuppressPacketErrors() { + return this.suppressPacketErrors; + } + + public void setSuppressPacketErrors(final boolean suppressPacketErrors) { + this.suppressPacketErrors = suppressPacketErrors; + ViaProxyConfig.this.save(); + } + + public MotD getMotd() { + return this.motd; + } + + public String getResourcePackUrl() { + return this.resourcePackUrl; + } + + public void setResourcePackUrl(final String resourcePackUrl) { + this.resourcePackUrl = resourcePackUrl; + ViaProxyConfig.this.save(); + } + + public WildcardDomainHandling getWildcardDomainHandling() { + return this.wildcardDomainHandling; + } + + public void setWildcardDomainHandling(final WildcardDomainHandling wildcardDomainHandling) { + this.wildcardDomainHandling = wildcardDomainHandling; + ViaProxyConfig.this.save(); + } + + public boolean shouldLogClientStatusRequests() { + return this.logClientStatusRequests; + } + + public void setLogClientStatusRequests(final boolean logClientStatusRequests) { + this.logClientStatusRequests = logClientStatusRequests; + ViaProxyConfig.this.save(); + } + + @Section + public class MotD { + + @Option("description") + @CLIName(value = "custom-motd-description", omitSection = true) + @CLIAliases(value = "custom-motd", hidden = true) + @Description("Custom description. Leave empty to use the backend server's description.") + private String description = ""; + + @Option("favicon-path") + @CLIName(value = "custom-motd-favicon-path", omitSection = true) + @CLIAliases(value = "custom-favicon-path", hidden = true) + @Description("Relative file path to a custom favicon. Leave empty to use the backend server's favicon.") + private String faviconPath = ""; + + public boolean hasAnyNonBlankOption() { + return !this.description.isBlank() || !this.faviconPath.isBlank(); + } + + public String getDescription() { + return this.description; + } + + public void setDescription(final String description) { + this.description = description; + ViaProxyConfig.this.save(); + } + + public String getFaviconPath() { + return this.faviconPath; } - if (options.has("minecraft-account-index")) { - this.authMethod = AuthMethod.ACCOUNT; + public void setFaviconPath(final String faviconPath) { + this.faviconPath = faviconPath; + ViaProxyConfig.this.save(); } - for (Map.Entry, ConfigOption> entry : optionMap.entrySet()) { - final ConfigOption option = entry.getValue(); - if (options.has(entry.getKey())) { - Object value = options.valueOf(entry.getKey()); - if (option.getTypeSerializer() != null) { - value = option.createTypeSerializer(configLoader, ViaProxyConfig.class, this).deserialize((Class) option.getFieldAccess().getType(), value); - } - if (option.getValidator() != null) { - value = option.getValidator().invoke(this, value); - } - option.getFieldAccess().setValue(this, value); + + } + + } + + @Section + public class Proxy { + + @Option("minecraft-account-index") + @CLIName(value = "minecraft-account-index", omitSection = true) + @Description("The GUI account list index (0 indexed) of the selected account.") + @TypeSerializer(AccountTypeSerializer.class) + private Account account = null; + + @Option("bungeecord-player-info-passthrough") + @CLIName(value = "bungeecord-player-info-passthrough", omitSection = true) + @Description({ + "Allow additional information like player ip, player uuid to be passed through to the backend server.", + "This is typically used by proxies like BungeeCord and requires support from the backend server as well." + }) + private boolean bungeeCordPlayerInfoPassthrough = false; + + @Option("allow-legacy-client-passthrough") + @CLIName(value = "allow-legacy-client-passthrough", omitSection = true) + @Description("Allow <= 1.6.4 clients to connect through ViaProxy to the backend server. (No protocol translation or packet handling)") + private boolean allowLegacyClientPassthrough = false; + + @Option("chat-signing") + @CLIName(value = "chat-signing", omitSection = true) + @Description("Enables sending signed chat messages on >= 1.19 servers.") + private boolean chatSigning = true; + + @Option("rewrite-handshake-packet") + @CLIName(value = "rewrite-handshake-packet", omitSection = true) + @Description({ + "Enabling this will rewrite the address in the handshake packet to a value the vanilla client would have sent when connecting directly to the backend server.", + "This should be left enabled unless you are a server owner and you need the original address on the backend server." + }) + private boolean rewriteHandshakePacket = true; + + @Option("rewrite-transfer-packets") + @CLIName(value = "rewrite-transfer-packets", omitSection = true) + @Description({ + "Enabling this will rewrite transfer packets to point back to ViaProxy. This allows ViaProxy to perform protocol translation when forwarding the player to the actual server from the transfer packet.", + "This should be left enabled unless you are a server owner and the servers you are transferring to perform their own protocol translation." + }) + private boolean rewriteTransferPackets = true; + + @Option("fake-accept-resource-packs") + @CLIName(value = "fake-accept-resource-packs", omitSection = true) + @Description({ + "Accepts resource packs from the server without showing a prompt to clients.", + "This is required if the server requires a resource pack, but the client can't load it due to version differences." + }) + private boolean fakeAcceptResourcePacks = false; + + @Option("simple-voice-chat-support") + @CLIName(value = "simple-voice-chat-support", omitSection = true) + @Description("Enables handling and rewriting of Simple Voice Chat mod packets.") + private boolean simpleVoiceChatSupport = false; + + @Option("fix-fabric-particle-api") + @CLIName(value = "fix-fabric-particle-api", omitSection = true) + @Description({ + "Fixes an issue where the Fabric Particle API causes disconnects when both the client and server have the mod installed and both are 1.21.5+.", + "See https://github.com/ViaVersion/ViaFabric/issues/428" + }) + private boolean fixFabricParticleApi = true; + + @Option("skip-config-state-packet-queue") + @CLIName(value = "skip-config-state-packet-queue", omitSection = true) + @Description({ + "Fixes potential join issues on <= 1.20.1 quilt/fabric servers.", + "It's recommended to only enable this if you are experiencing issues with the config state packet queue." + }) + private boolean skipConfigStatePacketQueue = false; + + @Option("log-ips") + @CLIName(value = "log-ips", omitSection = true) + @Description("Disable this if you want to hide IP addresses in the console and log files.") + private boolean logIps = true; + + public Account getAccount() { + return this.account; + } + + public void setAccount(final Account account) { + this.account = account; + ViaProxyConfig.this.save(); + } + + public boolean shouldPassthroughBungeeCordPlayerInfo() { + return this.bungeeCordPlayerInfoPassthrough; + } + + public void setPassthroughBungeeCordPlayerInfo(final boolean bungeeCordPlayerInfoPassthrough) { + this.bungeeCordPlayerInfoPassthrough = bungeeCordPlayerInfoPassthrough; + ViaProxyConfig.this.save(); + } + + public boolean shouldAllowLegacyClientPassthrough() { + return this.allowLegacyClientPassthrough; + } + + public void setAllowLegacyClientPassthrough(final boolean allowLegacyClientPassthrough) { + this.allowLegacyClientPassthrough = allowLegacyClientPassthrough; + ViaProxyConfig.this.save(); + } + + public boolean useChatSigning() { + return this.chatSigning; + } + + public void setChatSigning(final boolean chatSigning) { + this.chatSigning = chatSigning; + ViaProxyConfig.this.save(); + } + + public boolean shouldRewriteHandshakePacket() { + return this.rewriteHandshakePacket; + } + + public void setRewriteHandshakePacket(final boolean rewriteHandshakePacket) { + this.rewriteHandshakePacket = rewriteHandshakePacket; + ViaProxyConfig.this.save(); + } + + public boolean shouldRewriteTransferPackets() { + return this.rewriteTransferPackets; + } + + public void setRewriteTransferPackets(final boolean rewriteTransferPackets) { + this.rewriteTransferPackets = rewriteTransferPackets; + ViaProxyConfig.this.save(); + } + + public boolean shouldFakeAcceptResourcePacks() { + return this.fakeAcceptResourcePacks; + } + + public void setFakeAcceptResourcePacks(final boolean fakeAcceptResourcePacks) { + this.fakeAcceptResourcePacks = fakeAcceptResourcePacks; + ViaProxyConfig.this.save(); + } + + public boolean shouldSupportSimpleVoiceChat() { + return this.simpleVoiceChatSupport; + } + + public void setSimpleVoiceChatSupport(final boolean simpleVoiceChatSupport) { + this.simpleVoiceChatSupport = simpleVoiceChatSupport; + ViaProxyConfig.this.save(); + } + + public boolean shouldFixFabricParticleApi() { + return this.fixFabricParticleApi; + } + + public void setFixFabricParticleApi(final boolean fixFabricParticleApi) { + this.fixFabricParticleApi = fixFabricParticleApi; + ViaProxyConfig.this.save(); + } + + public boolean shouldSkipConfigStatePacketQueue() { + return this.skipConfigStatePacketQueue; + } + + public void setSkipConfigStatePacketQueue(final boolean skipConfigStatePacketQueue) { + this.skipConfigStatePacketQueue = skipConfigStatePacketQueue; + ViaProxyConfig.this.save(); + } + + public boolean shouldLogIps() { + return this.logIps; + } + + public void setLogIps(final boolean logIps) { + this.logIps = logIps; + ViaProxyConfig.this.save(); + } + + } + + @Section + public class Backend { + + @Option(value = "address", dependencies = "version") + @CLIName(value = "backend-address", omitSection = true) + @CLIAliases(value = "target-address", hidden = true) + @Description("The address of the server ViaProxy should connect to.") + @TypeSerializer(BackendAddressTypeSerializer.class) + private SocketAddress address = AddressUtil.parse("127.0.0.1:25565", null); + + @Option("version") + @CLIName(value = "backend-version", omitSection = true) + @CLIAliases(value = "target-version", hidden = true) + @Description("The version ViaProxy should translate to. (See ViaProxy GUI for a list of versions)") + @TypeSerializer(ProtocolVersionTypeSerializer.class) + private ProtocolVersion version = ProtocolTranslator.AUTO_DETECT_PROTOCOL; + + @Option("connect-timeout") + @CLIName(value = "connect-timeout", omitSection = true) + @Description("The connect timeout in milliseconds.") + private int connectTimeout = 8000; + + @Option("auth-method") + @CLIName(value = "auth-method", omitSection = true) + @Description({ + "The authentication method to use for joining the server.", + "none: No authentication (Offline mode)", + "account: Use an account (Has to be configured in ViaProxy GUI)" + }) + private AuthMethod authMethod = AuthMethod.NONE; + + @Option("betacraft-auth") + @CLIName(value = "betacraft-auth", omitSection = true) + @Description({ + "Use BetaCraft authentication for joining classic servers.", + "This allows clients to join classic servers which have online mode enabled." + }) + private boolean betaCraftAuth = false; + + @Option("allow-beta-pinging") + @CLIName(value = "allow-beta-pinging", omitSection = true) + @Description("Enabling this allows clients to ping <= b1.7.3 servers. This may cause issues if the server blocks too frequent connections.") + private boolean allowBetaPinging = false; + + @Option("haproxy") + @CLIName(value = "backend-haproxy", omitSection = true) + @Description("Send HAProxy protocol messages to the server.") + private boolean haProxy = false; + + @Option("proxy-url") + @CLIName(value = "backend-proxy-url", omitSection = true) + @Description({ + "URL of a SOCKS(4/5)/HTTP(S) proxy through which connections will be made. Leave empty to connect directly.", + "Supported formats:", + "- type://address:port", + "- type://username:password@address:port" + }) + @TypeSerializer(ProxyTypeSerializer.class) + private net.raphimc.viaproxy.util.Proxy proxy = null; + + public SocketAddress getAddress() { + return this.address; + } + + public void setAddress(final SocketAddress address) { + this.address = address; + ViaProxyConfig.this.save(); + } + + public ProtocolVersion getVersion() { + return this.version; + } + + public void setVersion(final ProtocolVersion version) { + this.version = version; + ViaProxyConfig.this.save(); + } + + public int getConnectTimeout() { + return this.connectTimeout; + } + + public void setConnectTimeout(final int connectTimeout) { + this.connectTimeout = connectTimeout; + ViaProxyConfig.this.save(); + } + + public AuthMethod getAuthMethod() { + return this.authMethod; + } + + public void setAuthMethod(final AuthMethod authMethod) { + this.authMethod = authMethod; + ViaProxyConfig.this.save(); + } + + public boolean useBetaCraftAuth() { + return this.betaCraftAuth; + } + + public void setBetaCraftAuth(final boolean betaCraftAuth) { + this.betaCraftAuth = betaCraftAuth; + ViaProxyConfig.this.save(); + } + + public boolean shouldAllowBetaPinging() { + return this.allowBetaPinging; + } + + public void setAllowBetaPinging(final boolean allowBetaPinging) { + this.allowBetaPinging = allowBetaPinging; + ViaProxyConfig.this.save(); + } + + public boolean useHaProxy() { + return this.haProxy; + } + + public void setHaProxy(final boolean haProxy) { + this.haProxy = haProxy; + ViaProxyConfig.this.save(); + } + + public net.raphimc.viaproxy.util.Proxy getProxy() { + return this.proxy; + } + + public void setProxy(final net.raphimc.viaproxy.util.Proxy proxy) { + this.proxy = proxy; + ViaProxyConfig.this.save(); + } + + @Validator("version") + private ProtocolVersion validateVersion(final ProtocolVersion backendVersion) { + if (backendVersion != null) { + return backendVersion; + } else { + Logger.LOGGER.warn("Invalid backend version. Defaulting to auto detect."); + Logger.LOGGER.warn("=== Supported backend server versions ==="); + for (ProtocolVersion version : ProtocolVersion.getProtocols()) { + Logger.LOGGER.warn(version.getName()); } + Logger.LOGGER.warn("==================================="); + return ProtocolTranslator.AUTO_DETECT_PROTOCOL; } + } - ViaProxy.EVENT_MANAGER.call(new PostOptionsParseEvent(options)); - return; - } catch (OptionException e) { - Logger.LOGGER.fatal("Error parsing CLI options: " + e.getMessage()); - } catch (HelpRequestedException ignored) { + } + + @Section + public class Advanced { + + @Option("ignore-protocol-translation-errors") + @CLIName(value = "ignore-protocol-translation-errors", omitSection = true) + @Description({ + "Enabling this will prevent getting disconnected when a packet translation error occurs and instead only print the error in the console.", + "This may cause issues depending on the type of packet which failed to translate." + }) + private boolean ignoreProtocolTranslationErrors = false; + + public boolean shouldIgnoreProtocolTranslationErrors() { + return this.ignoreProtocolTranslationErrors; + } + + public void setIgnoreProtocolTranslationErrors(final boolean ignoreProtocolTranslationErrors) { + this.ignoreProtocolTranslationErrors = ignoreProtocolTranslationErrors; + ViaProxyConfig.this.save(); } - optionParser.formatHelpWith(new BetterHelpFormatter()); - optionParser.printHelpOn(Logger.SYSOUT); - Logger.LOGGER.info("For a more detailed description of the options, please refer to the viaproxy.yml file."); - System.exit(1); } - public void save() { - try { - this.configContext.save(); - } catch (Throwable e) { - throw new RuntimeException("Failed to save config", e); + public enum AuthMethod { + + /** + * Use an account (Has to be configured in ViaProxy GUI) + */ + ACCOUNT("tab.general.minecraft_account.option_select_account"), + /** + * No authentication (Offline mode) + */ + NONE("tab.general.minecraft_account.option_no_account"); + + private final String guiTranslationKey; + + AuthMethod(final String guiTranslationKey) { + this.guiTranslationKey = guiTranslationKey; + } + + public String getGuiTranslationKey() { + return this.guiTranslationKey; + } + + } + + public enum WildcardDomainHandling { + + /** + * No wildcard domain handling + */ + NONE, + /** + * Public wildcard domain handling + */ + PUBLIC, + /** + * Internal wildcard domain handling + */ + INTERNAL, + + } + + static class Migrator1To2 implements ConfigMigrator { + + @Override + public void migrate(final int currentVersion, final Map loadedValues) { + this.move(loadedValues, "bind-address", "frontend", "bind-address"); + this.move(loadedValues, "target-address", "backend", "address"); + this.move(loadedValues, "target-version", "backend", "version"); + this.move(loadedValues, "connect-timeout", "backend", "connect-timeout"); + this.move(loadedValues, "proxy-online-mode", "frontend", "online-mode"); + this.move(loadedValues, "auth-method", "backend", "auth-method"); + this.move(loadedValues, "minecraft-account-index", "proxy", "minecraft-account-index"); + this.move(loadedValues, "betacraft-auth", "backend", "betacraft-auth"); + this.move(loadedValues, "backend-proxy-url", "backend", "proxy-url"); + this.move(loadedValues, "backend-haproxy", "backend", "haproxy"); + this.move(loadedValues, "frontend-haproxy", "frontend", "haproxy"); + this.move(loadedValues, "chat-signing", "proxy", "chat-signing"); + this.move(loadedValues, "compression-threshold", "frontend", "compression-threshold"); + this.move(loadedValues, "allow-beta-pinging", "backend", "allow-beta-pinging"); + this.move(loadedValues, "ignore-protocol-translation-errors", "advanced", "ignore-protocol-translation-errors"); + this.move(loadedValues, "suppress-client-protocol-errors", "proxy", "suppress-packet-errors"); + this.move(loadedValues, "allow-legacy-client-passthrough", "proxy", "allow-legacy-client-passthrough"); + this.move(loadedValues, "bungeecord-player-info-passthrough", "proxy", "bungeecord-player-info-passthrough"); + this.move(loadedValues, "rewrite-handshake-packet", "proxy", "rewrite-handshake-packet"); + this.move(loadedValues, "rewrite-transfer-packets", "proxy", "rewrite-transfer-packets"); + this.move(loadedValues, "custom-motd", "frontend", "motd", "description"); + this.move(loadedValues, "custom-favicon-path", "frontend", "motd", "favicon-path"); + this.move(loadedValues, "resource-pack-url", "frontend", "resource-pack-url"); + this.move(loadedValues, "wildcard-domain-handling", "frontend", "wildcard-domain-handling"); + this.move(loadedValues, "simple-voice-chat-support", "proxy", "simple-voice-chat-support"); + this.move(loadedValues, "fix-fabric-particle-api", "proxy", "fix-fabric-particle-api"); + this.move(loadedValues, "fake-accept-resource-packs", "proxy", "fake-accept-resource-packs"); + this.move(loadedValues, "skip-config-state-packet-queue", "proxy", "skip-config-state-packet-queue"); + this.move(loadedValues, "log-ips", "proxy", "log-ips"); + this.move(loadedValues, "log-client-status-requests", "frontend", "log-client-status-requests"); + } + + private void move(final Map loadedValues, final String oldKey, final String newSection, final String newKey) { + if (loadedValues.containsKey(oldKey)) { + final Object value = loadedValues.remove(oldKey); + final Map sectionMap = (Map) loadedValues.computeIfAbsent(newSection, k -> new HashMap<>()); + sectionMap.put(newKey, value); + } + } + + private void move(final Map loadedValues, final String oldKey, final String newSection, final String newSubSection, final String newKey) { + if (loadedValues.containsKey(oldKey)) { + final Object value = loadedValues.remove(oldKey); + final Map sectionMap = (Map) loadedValues.computeIfAbsent(newSection, k -> new HashMap<>()); + final Map subSectionMap = (Map) sectionMap.computeIfAbsent(newSubSection, k -> new HashMap<>()); + subSectionMap.put(newKey, value); + } } + } + @Deprecated(forRemoval = true) public SocketAddress getBindAddress() { - return this.bindAddress; + return this.getFrontend().getBindAddress(); } + @Deprecated(forRemoval = true) public void setBindAddress(final SocketAddress bindAddress) { - this.bindAddress = bindAddress; - this.save(); + this.getFrontend().setBindAddress(bindAddress); } + @Deprecated(forRemoval = true) public SocketAddress getTargetAddress() { - return this.targetAddress; + return this.getBackend().getAddress(); } + @Deprecated(forRemoval = true) public void setTargetAddress(final SocketAddress targetAddress) { - this.targetAddress = targetAddress; - this.save(); + this.getBackend().setAddress(targetAddress); } + @Deprecated(forRemoval = true) public ProtocolVersion getTargetVersion() { - return this.targetVersion; + return this.getBackend().getVersion(); } + @Deprecated(forRemoval = true) public void setTargetVersion(final ProtocolVersion targetVersion) { - this.targetVersion = targetVersion; - this.save(); + this.getBackend().setVersion(targetVersion); } + @Deprecated(forRemoval = true) public int getConnectTimeout() { - return this.connectTimeout; + return this.getBackend().getConnectTimeout(); } + @Deprecated(forRemoval = true) public void setConnectTimeout(final int connectTimeout) { - this.connectTimeout = connectTimeout; - this.save(); + this.getBackend().setConnectTimeout(connectTimeout); } + @Deprecated(forRemoval = true) public boolean isProxyOnlineMode() { - return this.proxyOnlineMode; + return this.getFrontend().isOnlineMode(); } + @Deprecated(forRemoval = true) public void setProxyOnlineMode(final boolean proxyOnlineMode) { - this.proxyOnlineMode = proxyOnlineMode; - this.save(); + this.getFrontend().setOnlineMode(proxyOnlineMode); } + @Deprecated(forRemoval = true) public AuthMethod getAuthMethod() { - return this.authMethod; + return this.getBackend().getAuthMethod(); } + @Deprecated(forRemoval = true) public void setAuthMethod(final AuthMethod authMethod) { - this.authMethod = authMethod; - this.save(); + this.getBackend().setAuthMethod(authMethod); } + @Deprecated(forRemoval = true) public Account getAccount() { - return this.account; + return this.getProxy().getAccount(); } + @Deprecated(forRemoval = true) public void setAccount(final Account account) { - this.account = account; - this.save(); + this.getProxy().setAccount(account); } + @Deprecated(forRemoval = true) public boolean useBetacraftAuth() { - return this.betacraftAuth; + return this.getBackend().useBetaCraftAuth(); } + @Deprecated(forRemoval = true) public void setBetacraftAuth(final boolean betacraftAuth) { - this.betacraftAuth = betacraftAuth; - this.save(); + this.getBackend().setBetaCraftAuth(betacraftAuth); } - public Proxy getBackendProxy() { - return this.backendProxy; + @Deprecated(forRemoval = true) + public net.raphimc.viaproxy.util.Proxy getBackendProxy() { + return this.getBackend().getProxy(); } - public void setBackendProxy(final Proxy backendProxy) { - this.backendProxy = backendProxy; - this.save(); + @Deprecated(forRemoval = true) + public void setBackendProxy(final net.raphimc.viaproxy.util.Proxy backendProxy) { + this.getBackend().setProxy(backendProxy); } + @Deprecated(forRemoval = true) public boolean useBackendHaProxy() { - return this.backendHaProxy; + return this.getBackend().useHaProxy(); } + @Deprecated(forRemoval = true) public void setBackendHaProxy(final boolean backendHaProxy) { - this.backendHaProxy = backendHaProxy; - this.save(); + this.getBackend().setHaProxy(backendHaProxy); } + @Deprecated(forRemoval = true) public boolean useFrontendHaProxy() { - return this.frontendHaProxy; + return this.getFrontend().useHaProxy(); } + @Deprecated(forRemoval = true) public void setFrontendHaProxy(final boolean frontendHaProxy) { - this.frontendHaProxy = frontendHaProxy; - this.save(); + this.getFrontend().setHaProxy(frontendHaProxy); } + @Deprecated(forRemoval = true) public boolean shouldSignChat() { - return this.chatSigning; + return this.getProxy().useChatSigning(); } + @Deprecated(forRemoval = true) public void setChatSigning(final boolean chatSigning) { - this.chatSigning = chatSigning; - this.save(); + this.getProxy().setChatSigning(chatSigning); } + @Deprecated(forRemoval = true) public int getCompressionThreshold() { - return this.compressionThreshold; + return this.getFrontend().getCompressionThreshold(); } + @Deprecated(forRemoval = true) public void setCompressionThreshold(final int compressionThreshold) { - this.compressionThreshold = compressionThreshold; - this.save(); + this.getFrontend().setCompressionThreshold(compressionThreshold); } + @Deprecated(forRemoval = true) public boolean shouldAllowBetaPinging() { - return this.allowBetaPinging; + return this.getBackend().shouldAllowBetaPinging(); } + @Deprecated(forRemoval = true) public void setAllowBetaPinging(final boolean allowBetaPinging) { - this.allowBetaPinging = allowBetaPinging; - this.save(); + this.getBackend().setAllowBetaPinging(allowBetaPinging); } + @Deprecated(forRemoval = true) public boolean shouldIgnoreProtocolTranslationErrors() { - return this.ignoreProtocolTranslationErrors; + return this.getAdvanced().shouldIgnoreProtocolTranslationErrors(); } + @Deprecated(forRemoval = true) public void setIgnoreProtocolTranslationErrors(final boolean ignoreProtocolTranslationErrors) { - this.ignoreProtocolTranslationErrors = ignoreProtocolTranslationErrors; - this.save(); + this.getAdvanced().setIgnoreProtocolTranslationErrors(ignoreProtocolTranslationErrors); } + @Deprecated(forRemoval = true) public boolean shouldSuppressClientProtocolErrors() { - return this.suppressClientProtocolErrors; + return this.getFrontend().shouldSuppressPacketErrors(); } + @Deprecated(forRemoval = true) public void setSuppressClientProtocolErrors(final boolean suppressClientProtocolErrors) { - this.suppressClientProtocolErrors = suppressClientProtocolErrors; - this.save(); + this.getFrontend().setSuppressPacketErrors(suppressClientProtocolErrors); } + @Deprecated(forRemoval = true) public boolean shouldAllowLegacyClientPassthrough() { - return this.allowLegacyClientPassthrough; + return this.getProxy().shouldAllowLegacyClientPassthrough(); } + @Deprecated(forRemoval = true) public void setAllowLegacyClientPassthrough(final boolean allowLegacyClientPassthrough) { - this.allowLegacyClientPassthrough = allowLegacyClientPassthrough; - this.save(); + this.getProxy().setAllowLegacyClientPassthrough(allowLegacyClientPassthrough); } + @Deprecated(forRemoval = true) public boolean shouldPassthroughBungeecordPlayerInfo() { - return this.bungeecordPlayerInfoPassthrough; + return this.getProxy().shouldPassthroughBungeeCordPlayerInfo(); } + @Deprecated(forRemoval = true) public void setPassthroughBungeecordPlayerInfo(final boolean bungeecordPlayerInfoPassthrough) { - this.bungeecordPlayerInfoPassthrough = bungeecordPlayerInfoPassthrough; - this.save(); + this.getProxy().setPassthroughBungeeCordPlayerInfo(bungeecordPlayerInfoPassthrough); } + @Deprecated(forRemoval = true) public boolean shouldRewriteHandshakePacket() { - return this.rewriteHandshakePacket; + return this.getProxy().shouldRewriteHandshakePacket(); } + @Deprecated(forRemoval = true) public void setRewriteHandshakePacket(final boolean rewriteHandshakePacket) { - this.rewriteHandshakePacket = rewriteHandshakePacket; - this.save(); + this.getProxy().setRewriteHandshakePacket(rewriteHandshakePacket); } + @Deprecated(forRemoval = true) public boolean shouldRewriteTransferPackets() { - return this.rewriteTransferPackets; + return this.getProxy().shouldRewriteTransferPackets(); } + @Deprecated(forRemoval = true) public void setRewriteTransferPackets(final boolean rewriteTransferPackets) { - this.rewriteTransferPackets = rewriteTransferPackets; - this.save(); + this.getProxy().setRewriteTransferPackets(rewriteTransferPackets); } + @Deprecated(forRemoval = true) public String getCustomMotd() { - return this.customMotd; + return this.getFrontend().getMotd().getDescription(); } + @Deprecated(forRemoval = true) public void setCustomMotd(final String customMotd) { - this.customMotd = customMotd; - this.save(); + this.getFrontend().getMotd().setDescription(customMotd); } + @Deprecated(forRemoval = true) public String getCustomFaviconPath() { - return this.customFaviconPath; + return this.getFrontend().getMotd().getFaviconPath(); } + @Deprecated(forRemoval = true) public void setCustomFaviconPath(final String customFaviconPath) { - this.customFaviconPath = customFaviconPath; - this.save(); + this.getFrontend().getMotd().setFaviconPath(customFaviconPath); } + @Deprecated(forRemoval = true) public String getResourcePackUrl() { - return this.resourcePackUrl; + return this.getFrontend().getResourcePackUrl(); } + @Deprecated(forRemoval = true) public void setResourcePackUrl(final String resourcePackUrl) { - this.resourcePackUrl = resourcePackUrl; - this.save(); + this.getFrontend().setResourcePackUrl(resourcePackUrl); } + @Deprecated(forRemoval = true) public WildcardDomainHandling getWildcardDomainHandling() { - return this.wildcardDomainHandling; + return this.getFrontend().getWildcardDomainHandling(); } + @Deprecated(forRemoval = true) public void setWildcardDomainHandling(final WildcardDomainHandling wildcardDomainHandling) { - this.wildcardDomainHandling = wildcardDomainHandling; - this.save(); + this.getFrontend().setWildcardDomainHandling(wildcardDomainHandling); } + @Deprecated(forRemoval = true) public boolean shouldSupportSimpleVoiceChat() { - return this.simpleVoiceChatSupport; + return this.getProxy().shouldSupportSimpleVoiceChat(); } + @Deprecated(forRemoval = true) public void setSimpleVoiceChatSupport(final boolean simpleVoiceChatSupport) { - this.simpleVoiceChatSupport = simpleVoiceChatSupport; - this.save(); + this.getProxy().setSimpleVoiceChatSupport(simpleVoiceChatSupport); } + @Deprecated(forRemoval = true) public boolean shouldFixFabricParticleApi() { - return this.fixFabricParticleApi; + return this.getProxy().shouldFixFabricParticleApi(); } + @Deprecated(forRemoval = true) public void setFixFabricParticleApi(final boolean fixFabricParticleApi) { - this.fixFabricParticleApi = fixFabricParticleApi; - this.save(); + this.getProxy().setFixFabricParticleApi(fixFabricParticleApi); } + @Deprecated(forRemoval = true) public boolean shouldFakeAcceptResourcePacks() { - return this.fakeAcceptResourcePacks; + return this.getProxy().shouldFakeAcceptResourcePacks(); } + @Deprecated(forRemoval = true) public void setFakeAcceptResourcePacks(final boolean fakeAcceptResourcePacks) { - this.fakeAcceptResourcePacks = fakeAcceptResourcePacks; - this.save(); + this.getProxy().setFakeAcceptResourcePacks(fakeAcceptResourcePacks); } + @Deprecated(forRemoval = true) public boolean shouldSkipConfigStatePacketQueue() { - return this.skipConfigStatePacketQueue; + return this.getProxy().shouldSkipConfigStatePacketQueue(); } + @Deprecated(forRemoval = true) public void setSkipConfigStatePacketQueue(final boolean skipConfigStatePacketQueue) { - this.skipConfigStatePacketQueue = skipConfigStatePacketQueue; - this.save(); + this.getProxy().setSkipConfigStatePacketQueue(skipConfigStatePacketQueue); } + @Deprecated(forRemoval = true) public boolean shouldLogIps() { - return this.logIps; + return this.getProxy().shouldLogIps(); } + @Deprecated(forRemoval = true) public void setLogIps(final boolean logIps) { - this.logIps = logIps; - this.save(); + this.getProxy().setLogIps(logIps); } + @Deprecated(forRemoval = true) public boolean shouldLogClientStatusRequests() { - return this.logClientStatusRequests; + return this.getFrontend().shouldLogClientStatusRequests(); } + @Deprecated(forRemoval = true) public void setLogClientStatusRequests(final boolean logClientStatusRequests) { - this.logClientStatusRequests = logClientStatusRequests; - this.save(); - } - - @Validator("target-version") - private ProtocolVersion validateTargetVersion(final ProtocolVersion targetVersion) { - if (targetVersion == null) { - Logger.LOGGER.warn("Invalid target server version. Defaulting to auto detect."); - Logger.LOGGER.warn("=== Supported Protocol Versions ==="); - for (ProtocolVersion version : ProtocolVersion.getProtocols()) { - Logger.LOGGER.warn(version.getName()); - } - Logger.LOGGER.warn("==================================="); - return ProtocolTranslator.AUTO_DETECT_PROTOCOL; - } - return targetVersion; - } - - public enum AuthMethod { - - /** - * Use an account for joining the target server (Has to be configured in ViaProxy GUI) - */ - ACCOUNT("tab.general.minecraft_account.option_select_account"), - /** - * No authentication (Offline mode) - */ - NONE("tab.general.minecraft_account.option_no_account"); - - private final String guiTranslationKey; - - AuthMethod(String guiTranslationKey) { - this.guiTranslationKey = guiTranslationKey; - } - - public String getGuiTranslationKey() { - return this.guiTranslationKey; - } - - } - - public enum WildcardDomainHandling { - - /** - * No wildcard domain handling - */ - NONE, - /** - * Public wildcard domain handling - */ - PUBLIC, - /** - * Iternal wildcard domain handling - */ - INTERNAL, - + this.getFrontend().setLogClientStatusRequests(logClientStatusRequests); } } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyChannelInitializer.java b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyChannelInitializer.java index e290d365..ddca0aee 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyChannelInitializer.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyChannelInitializer.java @@ -51,11 +51,11 @@ protected void initChannel(Channel channel) { return; } - if (ViaProxy.getConfig().useFrontendHaProxy()) { + if (ViaProxy.getConfig().getFrontend().useHaProxy()) { channel.pipeline().addLast(VIAPROXY_HAPROXY_DECODER_NAME, new HAProxyMessageDecoder()); channel.pipeline().addLast(VIAPROXY_HAPROXY_HANDLER_NAME, new HAProxyHandler()); } - if (ViaProxy.getConfig().shouldAllowLegacyClientPassthrough()) { + if (ViaProxy.getConfig().getProxy().shouldAllowLegacyClientPassthrough()) { channel.pipeline().addLast(LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new LegacyPassthroughInitialHandler()); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyHandler.java index de78860b..e625fa05 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyHandler.java @@ -49,7 +49,6 @@ import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.UserOptions; import net.raphimc.viaproxy.proxy.util.*; -import net.raphimc.viaproxy.saves.impl.accounts.ClassicAccount; import net.raphimc.viaproxy.util.*; import net.raphimc.viaproxy.util.logging.Logger; @@ -124,17 +123,16 @@ private void handleHandshake(final C2SHandshakingClientIntentionPacket packet) { } final String[] handshakeParts; - if (ViaProxy.getConfig().shouldPassthroughBungeecordPlayerInfo()) { + if (ViaProxy.getConfig().getProxy().shouldPassthroughBungeeCordPlayerInfo()) { handshakeParts = packet.address.split("\0"); } else { handshakeParts = new String[]{packet.address}; } - SocketAddress serverAddress = ViaProxy.getConfig().getTargetAddress(); - ProtocolVersion serverVersion = ViaProxy.getConfig().getTargetVersion(); - String classicMpPass = ViaProxy.getConfig().getAccount() instanceof ClassicAccount classicAccount ? classicAccount.getMppass() : null; + SocketAddress serverAddress = ViaProxy.getConfig().getBackend().getAddress(); + ProtocolVersion serverVersion = ViaProxy.getConfig().getBackend().getVersion(); - if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.PUBLIC) { + if (ViaProxy.getConfig().getFrontend().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.PUBLIC) { if (handshakeParts[0].toLowerCase().contains("f2.viaproxy.")) { // Format 2: address.
.port..version..f2.viaproxy.hostname WildcardDomainParser.ParsedDomain parsedDomain = WildcardDomainParser.parseFormat2(handshakeParts[0]); if (parsedDomain == null) { @@ -158,16 +156,13 @@ private void handleHandshake(final C2SHandshakingClientIntentionPacket packet) { } else { this.proxyConnection.kickClient("§cWrong domain syntax! §6Please use:\n§7address_port_version.viaproxy.hostname"); } - } else if (ViaProxy.getConfig().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.INTERNAL) { + } else if (ViaProxy.getConfig().getFrontend().getWildcardDomainHandling() == ViaProxyConfig.WildcardDomainHandling.INTERNAL) { final ArrayHelper arrayHelper = ArrayHelper.instanceOf(handshakeParts[0].split("\7")); handshakeParts[0] = arrayHelper.get(0); // Restore the original address final String versionString = arrayHelper.get(2); serverVersion = ProtocolVersionUtil.fromNameLenient(versionString); if (serverVersion == null) throw CloseAndReturn.INSTANCE; serverAddress = AddressUtil.parse(arrayHelper.get(1), serverVersion); - if (arrayHelper.isIndexValid(3)) { - classicMpPass = arrayHelper.getString(3); - } } if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && TransferDataHolder.hasTempRedirect(this.proxyConnection.getC2P())) { @@ -191,16 +186,16 @@ private void handleHandshake(final C2SHandshakingClientIntentionPacket packet) { serverAddress = preConnectEvent.getServerAddress(); serverVersion = preConnectEvent.getServerVersion(); - final boolean isJavaBetaPing = packet.intendedState.getConnectionState() == ConnectionState.STATUS && serverVersion.olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3) && !ViaProxy.getConfig().shouldAllowBetaPinging(); + final boolean isJavaBetaPing = packet.intendedState.getConnectionState() == ConnectionState.STATUS && serverVersion.olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3) && !ViaProxy.getConfig().getBackend().shouldAllowBetaPinging(); final boolean isBedrockNetherNetPing = packet.intendedState.getConnectionState() == ConnectionState.STATUS && serverVersion.equals(BedrockProtocolVersion.bedrockLatest) && serverAddress instanceof NetherNetAddress; if (isJavaBetaPing || isBedrockNetherNetPing) { - if (!ViaProxy.getConfig().getCustomMotd().isBlank()) { - this.proxyConnection.kickClient(ViaProxy.getConfig().getCustomMotd()); + if (!ViaProxy.getConfig().getFrontend().getMotd().getDescription().isBlank()) { + this.proxyConnection.kickClient(ViaProxy.getConfig().getFrontend().getMotd().getDescription()); } this.proxyConnection.kickClient("§7ViaProxy is working!\n§7Connect to join the configured server"); } - final UserOptions userOptions = new UserOptions(classicMpPass, ViaProxy.getConfig().getAccount()); + final UserOptions userOptions = new UserOptions(ViaProxy.getConfig().getBackend().getAuthMethod() == ViaProxyConfig.AuthMethod.ACCOUNT ? ViaProxy.getConfig().getProxy().getAccount() : null); ChannelUtil.disableAutoRead(this.proxyConnection.getC2P()); if (packet.intendedState.getConnectionState() == ConnectionState.LOGIN && serverVersion.equals(ProtocolTranslator.AUTO_DETECT_PROTOCOL)) { @@ -236,14 +231,16 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se this.proxyConnection.setClientHandshakeAddress(clientHandshakeAddress); this.proxyConnection.setUserOptions(userOptions); this.proxyConnection.setC2pConnectionState(intendedState.getConnectionState()); - this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection)); - if (ViaProxy.getConfig().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_14) && clientVersion.newerThan(ProtocolVersion.v1_14)) { + if (ViaProxy.getConfig().getFrontend().getMotd().hasAnyNonBlankOption()) { + this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection)); + } + if (ViaProxy.getConfig().getProxy().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_14) && clientVersion.newerThan(ProtocolVersion.v1_14)) { this.proxyConnection.getPacketHandlers().add(new SimpleVoiceChatPacketHandler(this.proxyConnection)); } - if (ViaProxy.getConfig().shouldFixFabricParticleApi() && serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_5) && clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_5) && !serverVersion.equals(clientVersion)) { + if (ViaProxy.getConfig().getProxy().shouldFixFabricParticleApi() && serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_5) && clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_5) && !serverVersion.equals(clientVersion)) { this.proxyConnection.getPacketHandlers().add(new FabricParticleApiFixPacketHandler(this.proxyConnection)); } - if (ViaProxy.getConfig().shouldFakeAcceptResourcePacks() && serverVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2)) { + if (ViaProxy.getConfig().getProxy().shouldFakeAcceptResourcePacks() && serverVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2)) { this.proxyConnection.getPacketHandlers().add(new ResourcePackSpooferPacketHandler(this.proxyConnection)); } if (clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_8)) { @@ -252,7 +249,7 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se this.proxyConnection.getPacketHandlers().add(new CompressionPacketHandler(this.proxyConnection)); this.proxyConnection.getPacketHandlers().add(new LoginPacketHandler(this.proxyConnection)); this.proxyConnection.getPacketHandlers().add(new DisconnectPacketHandler(this.proxyConnection)); - if (ViaProxy.getConfig().shouldRewriteTransferPackets() && clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_5)) { + if (ViaProxy.getConfig().getProxy().shouldRewriteTransferPackets() && clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_5)) { this.proxyConnection.getPacketHandlers().add(new TransferPacketHandler(this.proxyConnection)); } if (clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_2) || serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_2)) { @@ -261,7 +258,7 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se if (clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_19_3) && serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_19_3)) { this.proxyConnection.getPacketHandlers().add(new ChatSignaturePacketHandler(this.proxyConnection)); } - if (!ViaProxy.getConfig().getResourcePackUrl().isBlank()) { + if (!ViaProxy.getConfig().getFrontend().getResourcePackUrl().isBlank()) { this.proxyConnection.getPacketHandlers().add(new ResourcePackPacketHandler(this.proxyConnection)); } if (Via.getConfig().sendPlayerDetails() || Via.getConfig().sendServerDetails()) { @@ -269,13 +266,13 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se } this.proxyConnection.getPacketHandlers().add(new UnexpectedPacketHandler(this.proxyConnection)); - if (ViaProxy.getConfig().shouldLogClientStatusRequests() || intendedState != IntendedState.STATUS) { + if (ViaProxy.getConfig().getFrontend().shouldLogClientStatusRequests() || intendedState != IntendedState.STATUS) { Logger.u_info("connect", this.proxyConnection, "[" + clientVersion.getName() + " <-> " + serverVersion.getName() + "] Connecting to " + AddressUtil.toString(serverAddress)); } ViaProxy.EVENT_MANAGER.call(new ConnectEvent(this.proxyConnection)); final int handshakePort; - if (ViaProxy.getConfig().shouldRewriteHandshakePacket()) { + if (ViaProxy.getConfig().getProxy().shouldRewriteHandshakePacket()) { if (serverAddress instanceof InetSocketAddress inetSocketAddress) { handshakeParts[0] = inetSocketAddress.getHostString(); handshakePort = inetSocketAddress.getPort(); @@ -290,7 +287,7 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se this.proxyConnection.connectToServer(serverAddress, serverVersion).addListeners((ThrowingChannelFutureListener) f -> { if (f.isSuccess()) { f.channel().eventLoop().submit(() -> { // Reschedule so the packets get sent after the channel is fully initialized and active - if (ViaProxy.getConfig().useBackendHaProxy()) { + if (ViaProxy.getConfig().getBackend().useHaProxy()) { this.proxyConnection.getChannel().writeAndFlush(HAProxyUtil.createMessage(this.proxyConnection.getC2P(), this.proxyConnection.getChannel(), clientVersion)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/passthrough/PassthroughClient2ProxyHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/passthrough/PassthroughClient2ProxyHandler.java index 7afa6ff1..c2d0441d 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/passthrough/PassthroughClient2ProxyHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/client2proxy/passthrough/PassthroughClient2ProxyHandler.java @@ -86,7 +86,7 @@ protected void connectToServer(final Channel c2pChannel) { this.proxyConnection.connect(serverAddress).addListeners((ThrowingChannelFutureListener) f -> { if (f.isSuccess()) { f.channel().eventLoop().submit(() -> { // Reschedule so the packets get sent after the channel is fully initialized and active - if (ViaProxy.getConfig().useBackendHaProxy()) { + if (ViaProxy.getConfig().getBackend().useHaProxy()) { this.proxyConnection.getChannel().writeAndFlush(HAProxyUtil.createMessage(this.proxyConnection.getC2P(), this.proxyConnection.getChannel(), null)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } @@ -103,7 +103,7 @@ protected void connectToServer(final Channel c2pChannel) { } protected SocketAddress getServerAddress() { - return ViaProxy.getConfig().getTargetAddress(); + return ViaProxy.getConfig().getBackend().getAddress(); } } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/external_interface/ExternalInterface.java b/src/main/java/net/raphimc/viaproxy/proxy/external_interface/ExternalInterface.java index 6dfed08c..b9e83ee5 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/external_interface/ExternalInterface.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/external_interface/ExternalInterface.java @@ -63,7 +63,7 @@ public static void fillPlayerData(final ProxyConnection proxyConnection) { proxyConnection.setGameProfile(account.getGameProfile()); final UserConnection user = proxyConnection.getUserConnection(); - if (ViaProxy.getConfig().shouldSignChat() && proxyConnection.getServerVersion().newerThanOrEqualTo(ProtocolVersion.v1_19) && account instanceof MicrosoftAccount microsoftAccount) { + if (ViaProxy.getConfig().getProxy().useChatSigning() && proxyConnection.getServerVersion().newerThanOrEqualTo(ProtocolVersion.v1_19) && account instanceof MicrosoftAccount microsoftAccount) { final MinecraftPlayerCertificates playerCertificates = microsoftAccount.getAuthManager().getMinecraftPlayerCertificates().getUpToDate(); final Instant expiresAt = Instant.ofEpochMilli(playerCertificates.getExpireTimeMs()); final long expiresAtMillis = playerCertificates.getExpireTimeMs(); @@ -105,10 +105,10 @@ public static void joinServer(final String serverIdHash, final ProxyConnection p try { if (proxyConnection.getUserOptions().account() instanceof MicrosoftAccount microsoftAccount) { try { - if (ViaProxy.getConfig().getBackendProxy() == null) { + if (ViaProxy.getConfig().getBackend().getProxy() == null) { AuthLibServices.SESSION_SERVICE.joinServer(microsoftAccount.getGameProfile().id(), microsoftAccount.getAuthManager().getMinecraftToken().getUpToDate().getToken(), serverIdHash); } else { - final Proxy proxy = ViaProxy.getConfig().getBackendProxy(); + final Proxy proxy = ViaProxy.getConfig().getBackend().getProxy(); final MinecraftSessionService sessionService = new YggdrasilAuthenticationService(proxy.toJavaProxy()).createMinecraftSessionService(); Authenticator prevAuthenticator = Authenticator.getDefault(); try { diff --git a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/CompressionPacketHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/CompressionPacketHandler.java index b6e6f846..ab4a4602 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/CompressionPacketHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/CompressionPacketHandler.java @@ -43,11 +43,12 @@ public boolean handleP2S(Packet packet, List listeners) { return false; } else if (packet instanceof S2CLoginGameProfilePacket) { if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_8)) { - if (ViaProxy.getConfig().getCompressionThreshold() > -1 && this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).get() == -1) { + final int compressionThreshold = ViaProxy.getConfig().getFrontend().getCompressionThreshold(); + if (compressionThreshold > -1 && this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).get() == -1) { ChannelUtil.disableAutoRead(this.proxyConnection.getChannel()); - this.proxyConnection.getC2P().writeAndFlush(new S2CLoginCompressionPacket(ViaProxy.getConfig().getCompressionThreshold())).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f -> { + this.proxyConnection.getC2P().writeAndFlush(new S2CLoginCompressionPacket(compressionThreshold)).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f -> { if (f.isSuccess()) { - this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(ViaProxy.getConfig().getCompressionThreshold()); + this.proxyConnection.getC2P().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(compressionThreshold); ChannelUtil.restoreAutoRead(this.proxyConnection.getChannel()); } }); diff --git a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/DisconnectPacketHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/DisconnectPacketHandler.java index 20fd2fab..50d10813 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/DisconnectPacketHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/DisconnectPacketHandler.java @@ -36,9 +36,9 @@ public DisconnectPacketHandler(ProxyConnection proxyConnection) { @Override public boolean handleP2S(Packet packet, List listeners) throws Exception { if (packet instanceof S2CLoginDisconnectPacket loginDisconnectPacket) { - Logger.u_info("server disconnect", this.proxyConnection, ConsoleFormatter.convert(loginDisconnectPacket.reason.asLegacyFormatString())); + Logger.u_info("server disconnect", this.proxyConnection, ConsoleFormatter.convert(loginDisconnectPacket.reason)); } else if (packet instanceof S2CDisconnectPacket disconnectPacket) { - Logger.u_info("server disconnect", this.proxyConnection, ConsoleFormatter.convert(disconnectPacket.reason.asLegacyFormatString())); + Logger.u_info("server disconnect", this.proxyConnection, ConsoleFormatter.convert(disconnectPacket.reason)); } return super.handleP2S(packet, listeners); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/LoginPacketHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/LoginPacketHandler.java index bad8a5e8..a21df13b 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/LoginPacketHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/LoginPacketHandler.java @@ -89,7 +89,7 @@ public boolean handleC2P(Packet packet, List listeners) t proxyConnection.setGameProfile(new GameProfile(GameProfileUtil.getOfflinePlayerUuid(loginHelloPacket.name), loginHelloPacket.name)); } - if (ViaProxy.getConfig().isProxyOnlineMode() && !ViaProxy.EVENT_MANAGER.call(new ShouldVerifyOnlineModeEvent(this.proxyConnection)).isCancelled()) { + if (ViaProxy.getConfig().getFrontend().isOnlineMode() && !ViaProxy.EVENT_MANAGER.call(new ShouldVerifyOnlineModeEvent(this.proxyConnection)).isCancelled()) { this.proxyConnection.getC2P().writeAndFlush(new S2CLoginHelloPacket("", KEY_PAIR.getPublic().getEncoded(), this.verifyToken, true)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } else { ViaProxy.EVENT_MANAGER.call(new ClientLoggedInEvent(this.proxyConnection)); diff --git a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/ResourcePackPacketHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/ResourcePackPacketHandler.java index 4807a0d9..54a0c481 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/ResourcePackPacketHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/ResourcePackPacketHandler.java @@ -66,7 +66,7 @@ public boolean handleP2S(Packet packet, List listeners) { private void sendResourcePack() { this.proxyConnection.getChannel().eventLoop().schedule(() -> { try { - final String url = ViaProxy.getConfig().getResourcePackUrl(); + final String url = ViaProxy.getConfig().getFrontend().getResourcePackUrl(); final boolean required = Via.getConfig().isForcedUse1_17ResourcePack(); final TextComponent message; if (Via.getConfig().get1_17ResourcePackPrompt() != null) { diff --git a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/StatusPacketHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/StatusPacketHandler.java index f3d34fce..f8cc66fe 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/packethandler/StatusPacketHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/packethandler/StatusPacketHandler.java @@ -44,19 +44,19 @@ public StatusPacketHandler(ProxyConnection proxyConnection) { public boolean handleP2S(Packet packet, List listeners) { if (packet instanceof S2CStatusPongResponsePacket) { listeners.add(ChannelFutureListener.CLOSE); - } else if (packet instanceof S2CStatusResponsePacket statusResponsePacket && (!ViaProxy.getConfig().getCustomMotd().isBlank() || !ViaProxy.getConfig().getCustomFaviconPath().isBlank())) { + } else if (packet instanceof S2CStatusResponsePacket statusResponsePacket) { try { final JsonObject obj = JsonParser.parseString(statusResponsePacket.statusJson).getAsJsonObject(); - if (!ViaProxy.getConfig().getCustomMotd().isBlank()) { - obj.addProperty("description", ViaProxy.getConfig().getCustomMotd()); + if (!ViaProxy.getConfig().getFrontend().getMotd().getDescription().isBlank()) { + obj.addProperty("description", ViaProxy.getConfig().getFrontend().getMotd().getDescription()); } - if (!ViaProxy.getConfig().getCustomFaviconPath().isBlank()) { + if (!ViaProxy.getConfig().getFrontend().getMotd().getFaviconPath().isBlank()) { if (FAVICON_BASE_64 == null) { try { - final byte[] faviconBytes = Files.readAllBytes(new File(ViaProxy.getCwd(), ViaProxy.getConfig().getCustomFaviconPath()).toPath()); + final byte[] faviconBytes = Files.readAllBytes(new File(ViaProxy.getCwd(), ViaProxy.getConfig().getFrontend().getMotd().getFaviconPath()).toPath()); FAVICON_BASE_64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(faviconBytes); } catch (Throwable e) { - Logger.LOGGER.error("Failed to load custom favicon from path: " + ViaProxy.getConfig().getCustomFaviconPath(), e); + Logger.LOGGER.error("Failed to load custom favicon from path: " + ViaProxy.getConfig().getFrontend().getMotd().getFaviconPath(), e); FAVICON_BASE_64 = ""; } } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerChannelInitializer.java b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerChannelInitializer.java index 51aa9aa0..e3eef2ca 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerChannelInitializer.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerChannelInitializer.java @@ -65,10 +65,10 @@ protected void initChannel(Channel channel) { final ProxyConnection proxyConnection = ProxyConnection.fromChannel(channel); - if (ViaProxy.getConfig().getBackendProxy() != null && !proxyConnection.getServerVersion().equals(BedrockProtocolVersion.bedrockLatest)) { - channel.pipeline().addLast(VIAPROXY_PROXY_HANDLER_NAME, ViaProxy.getConfig().getBackendProxy().createNettyProxyHandler()); + if (ViaProxy.getConfig().getBackend().getProxy() != null && !proxyConnection.getServerVersion().equals(BedrockProtocolVersion.bedrockLatest)) { + channel.pipeline().addLast(VIAPROXY_PROXY_HANDLER_NAME, ViaProxy.getConfig().getBackend().getProxy().createNettyProxyHandler()); } - if (ViaProxy.getConfig().useBackendHaProxy()) { + if (ViaProxy.getConfig().getBackend().useHaProxy()) { channel.pipeline().addLast(VIAPROXY_HAPROXY_ENCODER_NAME, HAProxyMessageEncoder.INSTANCE); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerHandler.java b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerHandler.java index 06e79d2c..62906a4f 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerHandler.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerHandler.java @@ -46,7 +46,7 @@ public void channelRegistered(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); - if (ViaProxy.getConfig().shouldLogClientStatusRequests() || this.proxyConnection.getP2sConnectionState() != ConnectionState.STATUS) { + if (ViaProxy.getConfig().getFrontend().shouldLogClientStatusRequests() || this.proxyConnection.getP2sConnectionState() != ConnectionState.STATUS) { Logger.u_info("disconnect", this.proxyConnection, "Connection closed"); } try { diff --git a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/passthrough/PassthroughProxy2ServerChannelInitializer.java b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/passthrough/PassthroughProxy2ServerChannelInitializer.java index d7e9219b..14a6626b 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/passthrough/PassthroughProxy2ServerChannelInitializer.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/proxy2server/passthrough/PassthroughProxy2ServerChannelInitializer.java @@ -41,10 +41,10 @@ protected void initChannel(Channel channel) { return; } - if (ViaProxy.getConfig().getBackendProxy() != null) { - channel.pipeline().addLast(VIAPROXY_PROXY_HANDLER_NAME, ViaProxy.getConfig().getBackendProxy().createNettyProxyHandler()); + if (ViaProxy.getConfig().getBackend().getProxy() != null) { + channel.pipeline().addLast(VIAPROXY_PROXY_HANDLER_NAME, ViaProxy.getConfig().getBackend().getProxy().createNettyProxyHandler()); } - if (ViaProxy.getConfig().useBackendHaProxy()) { + if (ViaProxy.getConfig().getBackend().useHaProxy()) { channel.pipeline().addLast(VIAPROXY_HAPROXY_ENCODER_NAME, HAProxyMessageEncoder.INSTANCE); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/session/BedrockProxyConnection.java b/src/main/java/net/raphimc/viaproxy/proxy/session/BedrockProxyConnection.java index d8914a6b..82763679 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/session/BedrockProxyConnection.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/session/BedrockProxyConnection.java @@ -58,7 +58,7 @@ public BedrockProxyConnection(final ChannelInitializer channelInitializ @Override public void initialize(final TransportType transportType, final Bootstrap bootstrap) { bootstrap - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getConnectTimeout()) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getBackend().getConnectTimeout()) .attr(ProxyConnection.PROXY_CONNECTION_ATTRIBUTE_KEY, this) .handler(this.channelInitializer); @@ -103,7 +103,7 @@ protected void initializeRakNet(TransportType transportType, final Bootstrap boo .option(RakChannelOption.RAK_COMPATIBILITY_MODE, true) .option(RakChannelOption.RAK_CLIENT_INTERNAL_ADDRESSES, 20) .option(RakChannelOption.RAK_TIME_BETWEEN_SEND_CONNECTION_ATTEMPTS_MS, 500) - .option(RakChannelOption.RAK_CONNECT_TIMEOUT, (long) ViaProxy.getConfig().getConnectTimeout()) + .option(RakChannelOption.RAK_CONNECT_TIMEOUT, (long) ViaProxy.getConfig().getBackend().getConnectTimeout()) .option(RakChannelOption.RAK_SESSION_TIMEOUT, 30_000L) .option(RakChannelOption.RAK_GUID, ThreadLocalRandom.current().nextLong()); } @@ -130,7 +130,7 @@ protected void initializeNetherNet(final TransportType transportType, final Boot bootstrap .group(EventLoops.getClientEventLoop(TransportType.NIO)) .channelFactory(NetherNetChannelFactory.client(new PeerConnectionFactory(), netherNetSignaling)) - .option(NetherChannelOption.NETHER_CLIENT_HANDSHAKE_TIMEOUT_MS, ViaProxy.getConfig().getConnectTimeout()) + .option(NetherChannelOption.NETHER_CLIENT_HANDSHAKE_TIMEOUT_MS, ViaProxy.getConfig().getBackend().getConnectTimeout()) .option(NetherChannelOption.NETHER_CLIENT_MAX_HANDSHAKE_ATTEMPTS, 1) .handler(new ChannelInitializer<>() { @Override diff --git a/src/main/java/net/raphimc/viaproxy/proxy/session/LegacyProxyConnection.java b/src/main/java/net/raphimc/viaproxy/proxy/session/LegacyProxyConnection.java index 610f9a74..e40aa89f 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/session/LegacyProxyConnection.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/session/LegacyProxyConnection.java @@ -47,7 +47,7 @@ public static LegacyProxyConnection fromChannel(final Channel channel) { @Override public void initialize(final TransportType transportType, final Bootstrap bootstrap) { - bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getConnectTimeout()); + bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getBackend().getConnectTimeout()); bootstrap.attr(LEGACY_PROXY_CONNECTION_ATTRIBUTE_KEY, this); super.initialize(transportType, bootstrap); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/session/ProxyConnection.java b/src/main/java/net/raphimc/viaproxy/proxy/session/ProxyConnection.java index 17fc58db..26194fce 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/session/ProxyConnection.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/session/ProxyConnection.java @@ -93,7 +93,7 @@ public ChannelFuture connect(final SocketAddress address) { @Override public void initialize(final TransportType transportType, final Bootstrap bootstrap) { - bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getConnectTimeout()); + bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getBackend().getConnectTimeout()); bootstrap.attr(PROXY_CONNECTION_ATTRIBUTE_KEY, this); super.initialize(transportType, bootstrap); } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/session/UserOptions.java b/src/main/java/net/raphimc/viaproxy/proxy/session/UserOptions.java index 0d75de9b..f7033446 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/session/UserOptions.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/session/UserOptions.java @@ -18,6 +18,20 @@ package net.raphimc.viaproxy.proxy.session; import net.raphimc.viaproxy.saves.impl.accounts.Account; +import net.raphimc.viaproxy.saves.impl.accounts.ClassicAccount; + +public record UserOptions(Account account) { + + @Deprecated(forRemoval = true) + public UserOptions(final String classicMpPass, final Account account) { + this(migrateClassicMpPass(classicMpPass, account)); + } + + private static Account migrateClassicMpPass(final String classicMpPass, final Account account) { + if (classicMpPass != null && account != null) { + return new ClassicAccount(account.getName(), classicMpPass); + } + return account; + } -public record UserOptions(String classicMpPass, Account account) { } diff --git a/src/main/java/net/raphimc/viaproxy/proxy/util/ExceptionUtil.java b/src/main/java/net/raphimc/viaproxy/proxy/util/ExceptionUtil.java index f00ae7ec..78275f33 100644 --- a/src/main/java/net/raphimc/viaproxy/proxy/util/ExceptionUtil.java +++ b/src/main/java/net/raphimc/viaproxy/proxy/util/ExceptionUtil.java @@ -35,7 +35,7 @@ public static void handleNettyException(ChannelHandlerContext ctx, Throwable cau ctx.channel().close(); return; } - if (!client2Proxy || !ViaProxy.getConfig().shouldSuppressClientProtocolErrors()) { + if (!client2Proxy || !ViaProxy.getConfig().getFrontend().shouldSuppressPacketErrors()) { Logger.LOGGER.error("Caught unhandled netty exception", cause); try { if (proxyConnection != null) { diff --git a/src/main/java/net/raphimc/viaproxy/ui/impl/AccountsTab.java b/src/main/java/net/raphimc/viaproxy/ui/impl/AccountsTab.java index db0fbabd..4120a810 100644 --- a/src/main/java/net/raphimc/viaproxy/ui/impl/AccountsTab.java +++ b/src/main/java/net/raphimc/viaproxy/ui/impl/AccountsTab.java @@ -103,7 +103,7 @@ public void keyPressed(KeyEvent e) { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { DefaultListCellRenderer component = (DefaultListCellRenderer) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); Account account = (Account) value; - if (ViaProxy.getConfig().getAccount() == account) { + if (ViaProxy.getConfig().getProxy().getAccount() == account) { component.setText("" + account.getDisplayString() + ""); } else { component.setText(account.getDisplayString()); @@ -129,7 +129,7 @@ public Component getListCellRendererComponent(JList list, Object value, int i Account removed = model.remove(index); ViaProxy.getSaveManager().accountsSave.removeAccount(removed); ViaProxy.getSaveManager().save(); - if (ViaProxy.getConfig().getAccount() == removed) { + if (ViaProxy.getConfig().getProxy().getAccount() == removed) { if (model.isEmpty()) this.markSelected(-1); else this.markSelected(0); } @@ -224,11 +224,11 @@ private void addAccount(final Account account) { public void markSelected(final int index) { if (index < 0 || index >= this.accountsList.getModel().getSize()) { - ViaProxy.getConfig().setAccount(null); + ViaProxy.getConfig().getProxy().setAccount(null); return; } - ViaProxy.getConfig().setAccount(ViaProxy.getSaveManager().accountsSave.getAccounts().get(index)); + ViaProxy.getConfig().getProxy().setAccount(ViaProxy.getSaveManager().accountsSave.getAccounts().get(index)); this.accountsList.repaint(); } diff --git a/src/main/java/net/raphimc/viaproxy/ui/impl/AdvancedTab.java b/src/main/java/net/raphimc/viaproxy/ui/impl/AdvancedTab.java index 62305035..645e03b0 100644 --- a/src/main/java/net/raphimc/viaproxy/ui/impl/AdvancedTab.java +++ b/src/main/java/net/raphimc/viaproxy/ui/impl/AdvancedTab.java @@ -99,7 +99,7 @@ private void addBody(final Container parent) { { this.proxyOnlineMode = new JCheckBox(I18n.get("tab.advanced.proxy_online_mode.label")); this.proxyOnlineMode.setToolTipText(I18n.get("tab.advanced.proxy_online_mode.tooltip")); - this.proxyOnlineMode.setSelected(ViaProxy.getConfig().isProxyOnlineMode()); + this.proxyOnlineMode.setSelected(ViaProxy.getConfig().getFrontend().isOnlineMode()); checkboxes.add(this.proxyOnlineMode); } { @@ -111,35 +111,35 @@ private void addBody(final Container parent) { { this.chatSigning = new JCheckBox(I18n.get("tab.advanced.chat_signing.label")); this.chatSigning.setToolTipText(I18n.get("tab.advanced.chat_signing.tooltip")); - this.chatSigning.setSelected(ViaProxy.getConfig().shouldSignChat()); + this.chatSigning.setSelected(ViaProxy.getConfig().getProxy().useChatSigning()); checkboxes.add(this.chatSigning); } { this.ignorePacketTranslationErrors = new JCheckBox(I18n.get("tab.advanced.ignore_packet_translation_errors.label")); this.ignorePacketTranslationErrors.setToolTipText(I18n.get("tab.advanced.ignore_packet_translation_errors.tooltip")); this.ignorePacketTranslationErrors.setSelected(false); - this.ignorePacketTranslationErrors.setSelected(ViaProxy.getConfig().shouldIgnoreProtocolTranslationErrors()); + this.ignorePacketTranslationErrors.setSelected(ViaProxy.getConfig().getAdvanced().shouldIgnoreProtocolTranslationErrors()); checkboxes.add(this.ignorePacketTranslationErrors); } { this.allowBetaPinging = new JCheckBox(I18n.get("tab.advanced.allow_beta_pinging.label")); this.allowBetaPinging.setToolTipText(I18n.get("tab.advanced.allow_beta_pinging.tooltip")); this.allowBetaPinging.setSelected(false); - this.allowBetaPinging.setSelected(ViaProxy.getConfig().shouldAllowBetaPinging()); + this.allowBetaPinging.setSelected(ViaProxy.getConfig().getBackend().shouldAllowBetaPinging()); checkboxes.add(this.allowBetaPinging); } { this.simpleVoiceChatSupport = new JCheckBox(I18n.get("tab.advanced.simple_voice_chat_support.label")); this.simpleVoiceChatSupport.setToolTipText(I18n.get("tab.advanced.simple_voice_chat_support.tooltip")); this.simpleVoiceChatSupport.setSelected(false); - this.simpleVoiceChatSupport.setSelected(ViaProxy.getConfig().shouldSupportSimpleVoiceChat()); + this.simpleVoiceChatSupport.setSelected(ViaProxy.getConfig().getProxy().shouldSupportSimpleVoiceChat()); checkboxes.add(this.simpleVoiceChatSupport); } { this.fakeAcceptResourcePacks = new JCheckBox(I18n.get("tab.advanced.fake_accept_resource_packs.label")); this.fakeAcceptResourcePacks.setToolTipText(I18n.get("tab.advanced.fake_accept_resource_packs.tooltip")); this.fakeAcceptResourcePacks.setSelected(false); - this.fakeAcceptResourcePacks.setSelected(ViaProxy.getConfig().shouldFakeAcceptResourcePacks()); + this.fakeAcceptResourcePacks.setSelected(ViaProxy.getConfig().getProxy().shouldFakeAcceptResourcePacks()); checkboxes.add(this.fakeAcceptResourcePacks); } GBC.create(body).grid(0, gridy++).insets(BODY_BLOCK_PADDING, BORDER_PADDING, 0, BODY_BLOCK_PADDING).fill(GBC.BOTH).weight(1, 1).add(checkboxes); @@ -215,13 +215,13 @@ private void addFooter(final Container container) { void applyGuiState() { ViaProxy.getSaveManager().uiSave.put("bind_address", this.bindAddress.getText()); ViaProxy.getSaveManager().uiSave.put("proxy", this.proxy.getText()); - ViaProxy.getConfig().setProxyOnlineMode(this.proxyOnlineMode.isSelected()); + ViaProxy.getConfig().getFrontend().setOnlineMode(this.proxyOnlineMode.isSelected()); ViaProxy.getSaveManager().uiSave.put("legacy_skin_loading", String.valueOf(this.legacySkinLoading.isSelected())); - ViaProxy.getConfig().setChatSigning(this.chatSigning.isSelected()); - ViaProxy.getConfig().setIgnoreProtocolTranslationErrors(this.ignorePacketTranslationErrors.isSelected()); - ViaProxy.getConfig().setAllowBetaPinging(this.allowBetaPinging.isSelected()); - ViaProxy.getConfig().setSimpleVoiceChatSupport(this.simpleVoiceChatSupport.isSelected()); - ViaProxy.getConfig().setFakeAcceptResourcePacks(this.fakeAcceptResourcePacks.isSelected()); + ViaProxy.getConfig().getProxy().setChatSigning(this.chatSigning.isSelected()); + ViaProxy.getConfig().getAdvanced().setIgnoreProtocolTranslationErrors(this.ignorePacketTranslationErrors.isSelected()); + ViaProxy.getConfig().getBackend().setAllowBetaPinging(this.allowBetaPinging.isSelected()); + ViaProxy.getConfig().getProxy().setSimpleVoiceChatSupport(this.simpleVoiceChatSupport.isSelected()); + ViaProxy.getConfig().getProxy().setFakeAcceptResourcePacks(this.fakeAcceptResourcePacks.isSelected()); } } diff --git a/src/main/java/net/raphimc/viaproxy/ui/impl/GeneralTab.java b/src/main/java/net/raphimc/viaproxy/ui/impl/GeneralTab.java index b199144a..6b684e73 100644 --- a/src/main/java/net/raphimc/viaproxy/ui/impl/GeneralTab.java +++ b/src/main/java/net/raphimc/viaproxy/ui/impl/GeneralTab.java @@ -128,7 +128,7 @@ public Component getListCellRendererComponent(JList list, Object value, int i this.betaCraftAuth.setSelected(false); } }); - this.serverVersion.setSelectedItem(ViaProxy.getConfig().getTargetVersion()); + this.serverVersion.setSelectedItem(ViaProxy.getConfig().getBackend().getVersion()); GBC.create(body).grid(0, gridy++).weightx(1).insets(0, BORDER_PADDING, 0, BORDER_PADDING).fill(GBC.HORIZONTAL).add(this.serverVersion); } { @@ -145,13 +145,13 @@ public Component getListCellRendererComponent(JList list, Object value, int i return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } }); - this.authMethod.setSelectedItem(ViaProxy.getConfig().getAuthMethod()); + this.authMethod.setSelectedItem(ViaProxy.getConfig().getBackend().getAuthMethod()); GBC.create(body).grid(0, gridy++).weightx(1).insets(0, BORDER_PADDING, 0, BORDER_PADDING).fill(GBC.HORIZONTAL).add(this.authMethod); } { this.betaCraftAuth = new JCheckBox(I18n.get("tab.general.betacraft_auth.label")); this.betaCraftAuth.setToolTipText(I18n.get("tab.general.betacraft_auth.tooltip")); - this.betaCraftAuth.setSelected(ViaProxy.getConfig().useBetacraftAuth()); + this.betaCraftAuth.setSelected(ViaProxy.getConfig().getBackend().useBetaCraftAuth()); GBC.create(body).grid(0, gridy++).insets(BODY_BLOCK_PADDING, BORDER_PADDING, 0, 0).anchor(GBC.NORTHWEST).add(this.betaCraftAuth); // Simulate user action on serverVersion to update betaCraftAuth final ActionEvent fakeAction = new ActionEvent(this.serverVersion, ActionEvent.ACTION_PERFORMED, ""); @@ -214,10 +214,10 @@ private void setComponentsEnabled(final boolean state) { } private void updateStateLabel() { - if (ViaProxy.getConfig().getBindAddress() instanceof InetSocketAddress inetSocketAddress) { + if (ViaProxy.getConfig().getFrontend().getBindAddress() instanceof InetSocketAddress inetSocketAddress) { this.stateLabel.setText(I18n.get("tab.general.state.running", "1.7+", "127.0.0.1:" + inetSocketAddress.getPort())); } else { - this.stateLabel.setText(I18n.get("tab.general.state.running", "1.7+", AddressUtil.toString(ViaProxy.getConfig().getBindAddress()))); + this.stateLabel.setText(I18n.get("tab.general.state.running", "1.7+", AddressUtil.toString(ViaProxy.getConfig().getFrontend().getBindAddress()))); } this.stateLabel.setForeground(Color.GREEN); this.stateLabel.setVisible(true); @@ -263,36 +263,34 @@ private void start() { throw new IllegalArgumentException(I18n.get("tab.general.error.invalid_classicube_url")); } - ViaProxy.getConfig().setTargetAddress(new InetSocketAddress(uri.getHost(), uri.getPort())); - ViaProxy.getConfig().setAccount(new ClassicAccount(path[0], path[1])); + ViaProxy.getConfig().getBackend().setAddress(new InetSocketAddress(uri.getHost(), uri.getPort())); + ViaProxy.getConfig().getProxy().setAccount(new ClassicAccount(path[0], path[1])); } else { try { - ViaProxy.getConfig().setTargetAddress(AddressUtil.parse(serverAddress, serverVersion)); + ViaProxy.getConfig().getBackend().setAddress(AddressUtil.parse(serverAddress, serverVersion)); } catch (Throwable t) { throw new IllegalArgumentException(I18n.get("tab.general.error.invalid_server_address")); } if (authMethod == ViaProxyConfig.AuthMethod.ACCOUNT) { - if (ViaProxy.getConfig().getAccount() == null) { + if (ViaProxy.getConfig().getProxy().getAccount() == null) { this.viaProxyWindow.accountsTab.markSelected(0); } - } else { - ViaProxy.getConfig().setAccount(null); } } try { - ViaProxy.getConfig().setBindAddress(AddressUtil.parse(bindAddress, null)); + ViaProxy.getConfig().getFrontend().setBindAddress(AddressUtil.parse(bindAddress, null)); } catch (Throwable t) { throw new IllegalArgumentException(I18n.get("tab.general.error.invalid_bind_address")); } if (!proxyUrl.isBlank()) { try { - ViaProxy.getConfig().setBackendProxy(new Proxy(new URI(proxyUrl))); + ViaProxy.getConfig().getBackend().setProxy(new Proxy(new URI(proxyUrl))); } catch (URISyntaxException e) { throw new IllegalArgumentException(I18n.get("tab.general.error.invalid_proxy_url")); } } else { - ViaProxy.getConfig().setBackendProxy(null); + ViaProxy.getConfig().getBackend().setProxy(null); } this.applyGuiState(); this.viaProxyWindow.advancedTab.applyGuiState(); @@ -339,12 +337,12 @@ private void stop() { void applyGuiState() { ViaProxy.getSaveManager().uiSave.put("server_address", this.serverAddress.getText()); if (this.serverVersion.getSelectedItem() instanceof ProtocolVersion version) { - ViaProxy.getConfig().setTargetVersion(version); + ViaProxy.getConfig().getBackend().setVersion(version); } if (this.authMethod.getSelectedItem() instanceof ViaProxyConfig.AuthMethod authMethod) { - ViaProxy.getConfig().setAuthMethod(authMethod); + ViaProxy.getConfig().getBackend().setAuthMethod(authMethod); } - ViaProxy.getConfig().setBetacraftAuth(this.betaCraftAuth.isSelected()); + ViaProxy.getConfig().getBackend().setBetaCraftAuth(this.betaCraftAuth.isSelected()); } } diff --git a/src/main/java/net/raphimc/viaproxy/ui/impl/RealmsTab.java b/src/main/java/net/raphimc/viaproxy/ui/impl/RealmsTab.java index 9d818a6c..9fc81e5a 100644 --- a/src/main/java/net/raphimc/viaproxy/ui/impl/RealmsTab.java +++ b/src/main/java/net/raphimc/viaproxy/ui/impl/RealmsTab.java @@ -78,8 +78,8 @@ public RealmsTab(final ViaProxyWindow frame) { @Override protected void onTabOpened() { - if (ViaProxy.getConfig().getAccount() != this.currentAccount) { - this.currentAccount = ViaProxy.getConfig().getAccount(); + if (ViaProxy.getConfig().getProxy().getAccount() != this.currentAccount) { + this.currentAccount = ViaProxy.getConfig().getProxy().getAccount(); this.reinit(); } } diff --git a/src/main/java/net/raphimc/viaproxy/util/config/AccountTypeSerializer.java b/src/main/java/net/raphimc/viaproxy/util/config/AccountTypeSerializer.java index 92c59b4f..f38f3d87 100644 --- a/src/main/java/net/raphimc/viaproxy/util/config/AccountTypeSerializer.java +++ b/src/main/java/net/raphimc/viaproxy/util/config/AccountTypeSerializer.java @@ -18,23 +18,20 @@ package net.raphimc.viaproxy.util.config; import net.lenni0451.optconfig.serializer.ConfigTypeSerializer; +import net.lenni0451.optconfig.serializer.info.DeserializerInfo; +import net.lenni0451.optconfig.serializer.info.SerializerInfo; import net.raphimc.viaproxy.ViaProxy; -import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; import net.raphimc.viaproxy.saves.impl.accounts.Account; import java.util.List; -public class AccountTypeSerializer extends ConfigTypeSerializer { - - public AccountTypeSerializer(final ViaProxyConfig config) { - super(config); - } +public class AccountTypeSerializer implements ConfigTypeSerializer { @Override - public Account deserialize(final Class typeClass, final Object serializedObject) { + public Account deserialize(final DeserializerInfo info) { final List accounts = ViaProxy.getSaveManager().accountsSave.getAccounts(); - final int accountIndex = (int) serializedObject; - if (this.config.getAuthMethod() == ViaProxyConfig.AuthMethod.ACCOUNT && accountIndex >= 0 && accountIndex < accounts.size()) { + final int accountIndex = (int) info.value(); + if (accountIndex >= 0 && accountIndex < accounts.size()) { return accounts.get(accountIndex); } else { return null; @@ -42,11 +39,11 @@ public Account deserialize(final Class typeClass, final Object serializ } @Override - public Object serialize(final Account object) { - if (object != null) { - return ViaProxy.getSaveManager().accountsSave.getAccounts().indexOf(object); + public Object serialize(final SerializerInfo info) { + if (info.value() != null) { + return ViaProxy.getSaveManager().accountsSave.getAccounts().indexOf(info.value()); } else { - return 0; + return -1; } } diff --git a/src/main/java/net/raphimc/viaproxy/util/config/TargetAddressTypeSerializer.java b/src/main/java/net/raphimc/viaproxy/util/config/BackendAddressTypeSerializer.java similarity index 64% rename from src/main/java/net/raphimc/viaproxy/util/config/TargetAddressTypeSerializer.java rename to src/main/java/net/raphimc/viaproxy/util/config/BackendAddressTypeSerializer.java index ec3c95da..5781572a 100644 --- a/src/main/java/net/raphimc/viaproxy/util/config/TargetAddressTypeSerializer.java +++ b/src/main/java/net/raphimc/viaproxy/util/config/BackendAddressTypeSerializer.java @@ -18,25 +18,24 @@ package net.raphimc.viaproxy.util.config; import net.lenni0451.optconfig.serializer.ConfigTypeSerializer; +import net.lenni0451.optconfig.serializer.info.DeserializerInfo; +import net.lenni0451.optconfig.serializer.info.SerializerInfo; import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; import net.raphimc.viaproxy.util.AddressUtil; import java.net.SocketAddress; -public class TargetAddressTypeSerializer extends ConfigTypeSerializer { - - public TargetAddressTypeSerializer(final ViaProxyConfig config) { - super(config); - } +public class BackendAddressTypeSerializer implements ConfigTypeSerializer { @Override - public SocketAddress deserialize(final Class typeClass, final Object serializedObject) { - return AddressUtil.parse((String) serializedObject, this.config.getTargetVersion()); + public SocketAddress deserialize(final DeserializerInfo info) { + final ViaProxyConfig config = (ViaProxyConfig) info.configInstance(); + return AddressUtil.parse((String) info.value(), config.getBackend().getVersion()); } @Override - public Object serialize(final SocketAddress object) { - return AddressUtil.toString(object); + public Object serialize(final SerializerInfo info) { + return AddressUtil.toString(info.value()); } } diff --git a/src/main/java/net/raphimc/viaproxy/util/config/ProtocolVersionTypeSerializer.java b/src/main/java/net/raphimc/viaproxy/util/config/ProtocolVersionTypeSerializer.java index 2ed7af9a..a5fbf82e 100644 --- a/src/main/java/net/raphimc/viaproxy/util/config/ProtocolVersionTypeSerializer.java +++ b/src/main/java/net/raphimc/viaproxy/util/config/ProtocolVersionTypeSerializer.java @@ -19,22 +19,19 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import net.lenni0451.optconfig.serializer.ConfigTypeSerializer; -import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; +import net.lenni0451.optconfig.serializer.info.DeserializerInfo; +import net.lenni0451.optconfig.serializer.info.SerializerInfo; -public class ProtocolVersionTypeSerializer extends ConfigTypeSerializer { - - public ProtocolVersionTypeSerializer(final ViaProxyConfig config) { - super(config); - } +public class ProtocolVersionTypeSerializer implements ConfigTypeSerializer { @Override - public ProtocolVersion deserialize(final Class typeClass, final Object serializedObject) { - return ProtocolVersion.getClosest((String) serializedObject); + public ProtocolVersion deserialize(final DeserializerInfo info) { + return ProtocolVersion.getClosest((String) info.value()); } @Override - public Object serialize(final ProtocolVersion object) { - return object.getName(); + public Object serialize(final SerializerInfo info) { + return info.value().getName(); } } diff --git a/src/main/java/net/raphimc/viaproxy/util/config/ProxyTypeSerializer.java b/src/main/java/net/raphimc/viaproxy/util/config/ProxyTypeSerializer.java index 7814364f..19bab5d0 100644 --- a/src/main/java/net/raphimc/viaproxy/util/config/ProxyTypeSerializer.java +++ b/src/main/java/net/raphimc/viaproxy/util/config/ProxyTypeSerializer.java @@ -18,21 +18,18 @@ package net.raphimc.viaproxy.util.config; import net.lenni0451.optconfig.serializer.ConfigTypeSerializer; -import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; +import net.lenni0451.optconfig.serializer.info.DeserializerInfo; +import net.lenni0451.optconfig.serializer.info.SerializerInfo; import net.raphimc.viaproxy.util.Proxy; import java.net.URI; import java.net.URISyntaxException; -public class ProxyTypeSerializer extends ConfigTypeSerializer { - - public ProxyTypeSerializer(final ViaProxyConfig config) { - super(config); - } +public class ProxyTypeSerializer implements ConfigTypeSerializer { @Override - public Proxy deserialize(final Class typeClass, final Object serializedObject) { - final String proxyUrl = (String) serializedObject; + public Proxy deserialize(final DeserializerInfo info) { + final String proxyUrl = (String) info.value(); if (!proxyUrl.isBlank()) { try { return new Proxy(new URI(proxyUrl)); @@ -44,9 +41,9 @@ public Proxy deserialize(final Class typeClass, final Object serializedOb } @Override - public Object serialize(final Proxy object) { - if (object != null) { - return object.toURI().toString(); + public Object serialize(final SerializerInfo info) { + if (info.value() != null) { + return info.value().toURI().toString(); } else { return ""; } diff --git a/src/main/java/net/raphimc/viaproxy/util/config/SocketAddressTypeSerializer.java b/src/main/java/net/raphimc/viaproxy/util/config/SocketAddressTypeSerializer.java index aa276a71..8ec62905 100644 --- a/src/main/java/net/raphimc/viaproxy/util/config/SocketAddressTypeSerializer.java +++ b/src/main/java/net/raphimc/viaproxy/util/config/SocketAddressTypeSerializer.java @@ -18,25 +18,22 @@ package net.raphimc.viaproxy.util.config; import net.lenni0451.optconfig.serializer.ConfigTypeSerializer; -import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; +import net.lenni0451.optconfig.serializer.info.DeserializerInfo; +import net.lenni0451.optconfig.serializer.info.SerializerInfo; import net.raphimc.viaproxy.util.AddressUtil; import java.net.SocketAddress; -public class SocketAddressTypeSerializer extends ConfigTypeSerializer { - - public SocketAddressTypeSerializer(final ViaProxyConfig config) { - super(config); - } +public class SocketAddressTypeSerializer implements ConfigTypeSerializer { @Override - public SocketAddress deserialize(final Class typeClass, final Object serializedObject) { - return AddressUtil.parse((String) serializedObject, null); + public SocketAddress deserialize(final DeserializerInfo info) { + return AddressUtil.parse((String) info.value(), null); } @Override - public Object serialize(final SocketAddress object) { - return AddressUtil.toString(object); + public Object serialize(final SerializerInfo info) { + return AddressUtil.toString(info.value()); } } diff --git a/src/main/java/net/raphimc/viaproxy/util/logging/IpRedactor.java b/src/main/java/net/raphimc/viaproxy/util/logging/IpRedactor.java index d8005600..175d9181 100644 --- a/src/main/java/net/raphimc/viaproxy/util/logging/IpRedactor.java +++ b/src/main/java/net/raphimc/viaproxy/util/logging/IpRedactor.java @@ -43,7 +43,7 @@ private IpRedactor() { @Override public void format(final LogEvent event, final StringBuilder toAppendTo) { - if (ViaProxy.getConfig() != null && !ViaProxy.getConfig().shouldLogIps()) { + if (ViaProxy.getConfig() != null && !ViaProxy.getConfig().getProxy().shouldLogIps()) { String message = toAppendTo.toString(); message = IPV4_REGEX.matcher(message).replaceAll("REDACTED_IP"); message = IPV6_REGEX.matcher(message).replaceAll("REDACTED_IP"); diff --git a/src/main/java/net/raphimc/viaproxy/util/logging/Logger.java b/src/main/java/net/raphimc/viaproxy/util/logging/Logger.java index 268932f4..d2d49167 100644 --- a/src/main/java/net/raphimc/viaproxy/util/logging/Logger.java +++ b/src/main/java/net/raphimc/viaproxy/util/logging/Logger.java @@ -41,9 +41,7 @@ public class Logger { public static final PrintStream SYSERR = System.err; public static void setup() { - if (System.console() != null) { // jANSI is the best lib. If there is no console it just segfaults the JVM process. Thanks! - AnsiConsole.systemInstall(); - } + AnsiConsole.systemInstall(); System.setErr(new LoggerPrintStream("STDERR", SYSERR)); System.setOut(new LoggerPrintStream("STDOUT", SYSOUT)); }