Migrate to optconfig instead of VV config system

This commit is contained in:
RaphiMC 2024-07-30 23:42:26 +02:00
parent de31a10d2a
commit ed68b7d203
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
9 changed files with 446 additions and 314 deletions

View File

@ -98,6 +98,7 @@ dependencies {
exclude group: "io.netty"
}
include "gs.mclo:api:3.0.1"
include "net.lenni0451:optconfig:1.0.0-SNAPSHOT"
includeJ8(compileOnly("xyz.wagyourtail.jvmdowngrader:jvmdowngrader:0.9.1"))
includeJ8 "xyz.wagyourtail.jvmdowngrader:jvmdowngrader-java-api:0.9.1:downgraded-8"

View File

@ -30,6 +30,8 @@ import net.lenni0451.classtransform.utils.loader.InjectionClassLoader;
import net.lenni0451.classtransform.utils.tree.IClassProvider;
import net.lenni0451.lambdaevents.LambdaManager;
import net.lenni0451.lambdaevents.generator.LambdaMetaFactoryGenerator;
import net.lenni0451.optconfig.ConfigLoader;
import net.lenni0451.optconfig.provider.ConfigProvider;
import net.lenni0451.reflect.Agents;
import net.lenni0451.reflect.ClassLoaders;
import net.lenni0451.reflect.JavaBypass;
@ -229,8 +231,13 @@ public class ViaProxy {
progressConsumer.accept("Loading Saves");
SAVE_MANAGER = new SaveManager();
progressConsumer.accept("Loading Config");
CONFIG = new ViaProxyConfig(viaProxyConfigFile);
CONFIG.reload();
final ConfigLoader<ViaProxyConfig> configLoader = new ConfigLoader<>(ViaProxyConfig.class);
configLoader.getConfigOptions().setResetInvalidOptions(true).setRewriteConfig(true).setCommentSpacing(1);
try {
CONFIG = configLoader.load(ConfigProvider.file(viaProxyConfigFile)).getConfigInstance();
} catch (Throwable e) {
throw new RuntimeException("Failed to load config", e);
}
if (useUI) {
progressConsumer.accept("Loading GUI");
@ -253,7 +260,11 @@ public class ViaProxy {
if (useCLI) {
final String[] cliArgs = new String[args.length - 1];
System.arraycopy(args, 1, cliArgs, 0, cliArgs.length);
try {
CONFIG.loadFromArguments(cliArgs);
} catch (Throwable e) {
throw new RuntimeException("Failed to load CLI arguments", e);
}
} else if (firstStart) {
Logger.LOGGER.info("This is the first start of ViaProxy. Please configure the settings in the " + viaProxyConfigFile.getName() + " file and restart ViaProxy.");
System.exit(0);

View File

@ -18,223 +18,236 @@
package net.raphimc.viaproxy.protocoltranslator.viaproxy;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.Config;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import net.raphimc.vialoader.util.JLoggerToSLF4J;
import net.lenni0451.optconfig.ConfigContext;
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.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.cli.BetterHelpFormatter;
import net.raphimc.viaproxy.cli.HelpRequestedException;
import net.raphimc.viaproxy.cli.ProtocolVersionConverter;
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.config.*;
import net.raphimc.viaproxy.util.logging.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class ViaProxyConfig extends Config implements com.viaversion.viaversion.api.configuration.Config {
@OptConfig(header = "ViaProxy configuration file", version = 1)
public class ViaProxyConfig {
private static final java.util.logging.Logger LOGGER = new JLoggerToSLF4J(LoggerFactory.getLogger("ViaProxy"));
private final OptionParser optionParser;
private final OptionSpec<Void> optionHelp;
private final OptionSpec<String> optionBindAddress;
private final OptionSpec<String> optionTargetAddress;
private final OptionSpec<ProtocolVersion> optionTargetVersion;
private final OptionSpec<Boolean> optionProxyOnlineMode;
private final OptionSpec<Integer> optionConnectTimeout;
private final OptionSpec<AuthMethod> optionAuthMethod;
private final OptionSpec<Integer> optionMinecraftAccountIndex;
private final OptionSpec<Boolean> optionBetacraftAuth;
private final OptionSpec<String> optionBackendProxyUrl;
private final OptionSpec<Boolean> optionBackendHaProxy;
private final OptionSpec<Boolean> optionFrontendHaProxy;
private final OptionSpec<Boolean> optionChatSigning;
private final OptionSpec<Integer> optionCompressionThreshold;
private final OptionSpec<Boolean> optionAllowBetaPinging;
private final OptionSpec<Boolean> optionIgnoreProtocolTranslationErrors;
private final OptionSpec<Boolean> optionSuppressClientProtocolErrors;
private final OptionSpec<Boolean> optionAllowLegacyClientPassthrough;
private final OptionSpec<Boolean> optionBungeecordPlayerInfoPassthrough;
private final OptionSpec<String> optionCustomMotd;
private final OptionSpec<String> optionResourcePackUrl;
private final OptionSpec<WildcardDomainHandling> optionWildcardDomainHandling;
private final OptionSpec<Boolean> optionSimpleVoiceChatSupport;
private final OptionSpec<Boolean> optionFakeAcceptResourcePacks;
private ConfigContext<ViaProxyConfig> 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)",
"openauthmod: Requires the OpenAuthMod client mod (https://modrinth.com/mod/openauthmod)",
"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(ProxyUriTypeSerializer.class)
private URI backendProxyUrl = 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("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("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("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;
public ViaProxyConfig(final File configFile) {
super(configFile, LOGGER);
@SuppressWarnings("UnstableApiUsage")
public void loadFromArguments(final String[] args) throws Exception {
final OptionParser optionParser = new OptionParser();
final OptionSpec<Void> optionHelp = optionParser.accepts("help").forHelp();
this.optionParser = new OptionParser();
this.optionHelp = this.optionParser.accepts("help").forHelp();
this.optionBindAddress = this.optionParser.accepts("bind-address").withRequiredArg().ofType(String.class).defaultsTo(AddressUtil.toString(this.bindAddress));
this.optionTargetAddress = this.optionParser.accepts("target-address").withRequiredArg().ofType(String.class).defaultsTo(AddressUtil.toString(this.targetAddress));
this.optionTargetVersion = this.optionParser.accepts("target-version").withRequiredArg().withValuesConvertedBy(new ProtocolVersionConverter()).defaultsTo(this.targetVersion);
this.optionProxyOnlineMode = this.optionParser.accepts("proxy-online-mode").withRequiredArg().ofType(Boolean.class).defaultsTo(this.proxyOnlineMode);
this.optionConnectTimeout = this.optionParser.accepts("connect-timeout").withRequiredArg().ofType(Integer.class).defaultsTo(this.connectTimeout);
this.optionAuthMethod = this.optionParser.accepts("auth-method").withRequiredArg().ofType(AuthMethod.class).defaultsTo(this.authMethod);
this.optionMinecraftAccountIndex = this.optionParser.accepts("minecraft-account-index").withRequiredArg().ofType(Integer.class).defaultsTo(0);
this.optionBetacraftAuth = this.optionParser.accepts("betacraft-auth").withRequiredArg().ofType(Boolean.class).defaultsTo(this.betacraftAuth);
this.optionBackendProxyUrl = this.optionParser.accepts("backend-proxy-url").withRequiredArg().ofType(String.class).defaultsTo("");
this.optionBackendHaProxy = this.optionParser.accepts("backend-haproxy").withRequiredArg().ofType(Boolean.class).defaultsTo(this.backendHaProxy);
this.optionFrontendHaProxy = this.optionParser.accepts("frontend-haproxy").withRequiredArg().ofType(Boolean.class).defaultsTo(this.frontendHaProxy);
this.optionChatSigning = this.optionParser.accepts("chat-signing").withRequiredArg().ofType(Boolean.class).defaultsTo(this.chatSigning);
this.optionCompressionThreshold = this.optionParser.accepts("compression-threshold").withRequiredArg().ofType(Integer.class).defaultsTo(this.compressionThreshold);
this.optionAllowBetaPinging = this.optionParser.accepts("allow-beta-pinging").withRequiredArg().ofType(Boolean.class).defaultsTo(this.allowBetaPinging);
this.optionIgnoreProtocolTranslationErrors = this.optionParser.accepts("ignore-protocol-translation-errors").withRequiredArg().ofType(Boolean.class).defaultsTo(this.ignoreProtocolTranslationErrors);
this.optionSuppressClientProtocolErrors = this.optionParser.accepts("suppress-client-protocol-errors").withRequiredArg().ofType(Boolean.class).defaultsTo(this.suppressClientProtocolErrors);
this.optionAllowLegacyClientPassthrough = this.optionParser.accepts("allow-legacy-client-passthrough").withRequiredArg().ofType(Boolean.class).defaultsTo(this.allowLegacyClientPassthrough);
this.optionBungeecordPlayerInfoPassthrough = this.optionParser.accepts("bungeecord-player-info-passthrough").withRequiredArg().ofType(Boolean.class).defaultsTo(this.bungeecordPlayerInfoPassthrough);
this.optionCustomMotd = this.optionParser.accepts("custom-motd").withRequiredArg().ofType(String.class).defaultsTo(this.customMotd);
this.optionResourcePackUrl = this.optionParser.accepts("resource-pack-url").withRequiredArg().ofType(String.class).defaultsTo(this.resourcePackUrl);
this.optionWildcardDomainHandling = this.optionParser.accepts("wildcard-domain-handling").withRequiredArg().ofType(WildcardDomainHandling.class).defaultsTo(this.wildcardDomainHandling);
this.optionSimpleVoiceChatSupport = this.optionParser.accepts("simple-voice-chat-support").withRequiredArg().ofType(Boolean.class).defaultsTo(this.simpleVoiceChatSupport);
this.optionFakeAcceptResourcePacks = this.optionParser.accepts("fake-accept-resource-packs").withRequiredArg().ofType(Boolean.class).defaultsTo(this.fakeAcceptResourcePacks);
final Map<OptionSpec<Object>, ConfigOption> optionMap = new HashMap<>();
final Stack<SectionIndex> stack = new Stack<>();
stack.push(ClassIndexer.indexClass(ConfigType.INSTANCED, ViaProxyConfig.class));
while (!stack.isEmpty()) {
final SectionIndex index = stack.pop();
stack.addAll(index.getSubSections().values());
for (ConfigOption option : index.getOptions()) {
if (index.getSubSections().containsKey(option)) continue;
Object defaultValue = option.getField().get(this);
if (option.getTypeSerializer() != null) {
defaultValue = option.createTypeSerializer(null, ViaProxyConfig.class, this).serialize(defaultValue);
}
final OptionSpec<Object> cliOption = optionParser.accepts(option.getName()).withRequiredArg().ofType((Class<Object>) defaultValue.getClass()).defaultsTo(defaultValue);
optionMap.put(cliOption, option);
}
}
@Override
public void reload() {
super.reload();
this.bindAddress = AddressUtil.parse(this.getString("bind-address", AddressUtil.toString(this.bindAddress)), null);
this.targetVersion = ProtocolVersion.getClosest(this.getString("target-version", this.targetVersion.getName()));
this.checkTargetVersion();
this.targetAddress = AddressUtil.parse(this.getString("target-address", AddressUtil.toString(this.targetAddress)), this.targetVersion);
this.connectTimeout = this.getInt("connect-timeout", this.connectTimeout);
this.proxyOnlineMode = this.getBoolean("proxy-online-mode", this.proxyOnlineMode);
this.authMethod = AuthMethod.byName(this.getString("auth-method", this.authMethod.name()));
final List<Account> accounts = ViaProxy.getSaveManager().accountsSave.getAccounts();
final int accountIndex = this.getInt("minecraft-account-index", 0);
if (this.authMethod == AuthMethod.ACCOUNT && accountIndex >= 0 && accountIndex < accounts.size()) {
this.account = accounts.get(accountIndex);
} else {
this.account = null;
}
this.betacraftAuth = this.getBoolean("betacraft-auth", this.betacraftAuth);
this.backendProxyUrl = this.parseProxyUrl(this.getString("backend-proxy-url", ""));
this.backendHaProxy = this.getBoolean("backend-haproxy", this.backendHaProxy);
this.frontendHaProxy = this.getBoolean("frontend-haproxy", this.frontendHaProxy);
this.chatSigning = this.getBoolean("chat-signing", this.chatSigning);
this.compressionThreshold = this.getInt("compression-threshold", this.compressionThreshold);
this.allowBetaPinging = this.getBoolean("allow-beta-pinging", this.allowBetaPinging);
this.ignoreProtocolTranslationErrors = this.getBoolean("ignore-protocol-translation-errors", this.ignoreProtocolTranslationErrors);
this.suppressClientProtocolErrors = this.getBoolean("suppress-client-protocol-errors", this.suppressClientProtocolErrors);
this.allowLegacyClientPassthrough = this.getBoolean("allow-legacy-client-passthrough", this.allowLegacyClientPassthrough);
this.bungeecordPlayerInfoPassthrough = this.getBoolean("bungeecord-player-info-passthrough", this.bungeecordPlayerInfoPassthrough);
this.customMotd = this.getString("custom-motd", this.customMotd);
this.resourcePackUrl = this.getString("resource-pack-url", this.resourcePackUrl);
this.wildcardDomainHandling = WildcardDomainHandling.byName(this.getString("wildcard-domain-handling", this.wildcardDomainHandling.name()));
this.simpleVoiceChatSupport = this.getBoolean("simple-voice-chat-support", this.simpleVoiceChatSupport);
this.fakeAcceptResourcePacks = this.getBoolean("fake-accept-resource-packs", this.fakeAcceptResourcePacks);
}
public void loadFromArguments(final String[] args) throws IOException {
try {
ViaProxy.EVENT_MANAGER.call(new PreOptionsParseEvent(this.optionParser));
final OptionSet options = this.optionParser.parse(args);
if (options.has(this.optionHelp)) {
ViaProxy.EVENT_MANAGER.call(new PreOptionsParseEvent(optionParser));
final OptionSet options = optionParser.parse(args);
if (options.has(optionHelp)) {
throw new HelpRequestedException();
}
this.bindAddress = AddressUtil.parse(options.valueOf(this.optionBindAddress), null);
this.targetVersion = options.valueOf(this.optionTargetVersion);
this.checkTargetVersion();
this.targetAddress = AddressUtil.parse(options.valueOf(this.optionTargetAddress), this.targetVersion);
this.connectTimeout = options.valueOf(this.optionConnectTimeout);
this.proxyOnlineMode = options.valueOf(this.optionProxyOnlineMode);
this.authMethod = options.valueOf(this.optionAuthMethod);
final List<Account> accounts = ViaProxy.getSaveManager().accountsSave.getAccounts();
final int accountIndex = options.valueOf(this.optionMinecraftAccountIndex);
if (options.has(this.optionMinecraftAccountIndex) && accountIndex >= 0 && accountIndex < accounts.size()) {
if (options.has("minecraft-account-index")) {
this.authMethod = AuthMethod.ACCOUNT;
this.account = accounts.get(accountIndex);
} else {
this.account = null;
}
this.betacraftAuth = options.valueOf(this.optionBetacraftAuth);
this.backendProxyUrl = this.parseProxyUrl(options.valueOf(this.optionBackendProxyUrl));
this.backendHaProxy = options.valueOf(this.optionBackendHaProxy);
this.frontendHaProxy = options.valueOf(this.optionFrontendHaProxy);
this.chatSigning = options.valueOf(this.optionChatSigning);
this.compressionThreshold = options.valueOf(this.optionCompressionThreshold);
this.allowBetaPinging = options.valueOf(this.optionAllowBetaPinging);
this.ignoreProtocolTranslationErrors = options.valueOf(this.optionIgnoreProtocolTranslationErrors);
this.suppressClientProtocolErrors = options.valueOf(this.optionSuppressClientProtocolErrors);
this.allowLegacyClientPassthrough = options.valueOf(this.optionAllowLegacyClientPassthrough);
this.bungeecordPlayerInfoPassthrough = options.valueOf(this.optionBungeecordPlayerInfoPassthrough);
this.customMotd = options.valueOf(this.optionCustomMotd);
this.resourcePackUrl = options.valueOf(this.optionResourcePackUrl);
this.wildcardDomainHandling = options.valueOf(this.optionWildcardDomainHandling);
this.simpleVoiceChatSupport = options.valueOf(this.optionSimpleVoiceChatSupport);
this.fakeAcceptResourcePacks = options.valueOf(this.optionFakeAcceptResourcePacks);
for (Map.Entry<OptionSpec<Object>, 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(null, ViaProxyConfig.class, this).deserialize((Class<Object>) option.getField().getType(), value);
}
if (option.getValidator() != null) {
value = option.getValidator().invoke(this, value);
}
option.getField().set(this, value);
}
}
ViaProxy.EVENT_MANAGER.call(new PostOptionsParseEvent(options));
return;
} catch (OptionException e) {
this.logger.severe("Error parsing CLI options: " + e.getMessage());
Logger.LOGGER.fatal("Error parsing CLI options: " + e.getMessage());
} catch (HelpRequestedException ignored) {
}
this.optionParser.formatHelpWith(new BetterHelpFormatter());
this.optionParser.printHelpOn(Logger.SYSOUT);
this.logger.info("For a more detailed description of the options, please refer to the viaproxy.yml file.");
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);
}
@Override
public URL getDefaultConfigURL() {
return this.getClass().getClassLoader().getResource("assets/viaproxy/viaproxy.yml");
public void save() {
try {
this.configContext.save();
} catch (Throwable e) {
throw new RuntimeException("Failed to save config", e);
}
@Override
protected void handleConfig(Map<String, Object> map) {
}
@Override
public List<String> getUnsupportedOptions() {
return Collections.emptyList();
}
@Override
public void set(String path, Object value) {
super.set(path, value);
}
public SocketAddress getBindAddress() {
@ -243,7 +256,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setBindAddress(final SocketAddress bindAddress) {
this.bindAddress = bindAddress;
this.set("bind-address", AddressUtil.toString(bindAddress));
this.save();
}
public SocketAddress getTargetAddress() {
@ -252,7 +265,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setTargetAddress(final SocketAddress targetAddress) {
this.targetAddress = targetAddress;
this.set("target-address", AddressUtil.toString(targetAddress));
this.save();
}
public ProtocolVersion getTargetVersion() {
@ -261,7 +274,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setTargetVersion(final ProtocolVersion targetVersion) {
this.targetVersion = targetVersion;
this.set("target-version", targetVersion.getName());
this.save();
}
public int getConnectTimeout() {
@ -270,7 +283,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setConnectTimeout(final int connectTimeout) {
this.connectTimeout = connectTimeout;
this.set("connect-timeout", connectTimeout);
this.save();
}
public boolean isProxyOnlineMode() {
@ -279,7 +292,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setProxyOnlineMode(final boolean proxyOnlineMode) {
this.proxyOnlineMode = proxyOnlineMode;
this.set("proxy-online-mode", proxyOnlineMode);
this.save();
}
public AuthMethod getAuthMethod() {
@ -288,7 +301,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setAuthMethod(final AuthMethod authMethod) {
this.authMethod = authMethod;
this.set("auth-method", authMethod.name().toLowerCase(Locale.ROOT));
this.save();
}
public Account getAccount() {
@ -297,7 +310,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setAccount(final Account account) {
this.account = account;
this.set("minecraft-account-index", ViaProxy.getSaveManager().accountsSave.getAccounts().indexOf(account));
this.save();
}
public boolean useBetacraftAuth() {
@ -306,7 +319,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setBetacraftAuth(final boolean betacraftAuth) {
this.betacraftAuth = betacraftAuth;
this.set("betacraft-auth", betacraftAuth);
this.save();
}
public URI getBackendProxyUrl() {
@ -315,11 +328,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setBackendProxyUrl(final URI backendProxyUrl) {
this.backendProxyUrl = backendProxyUrl;
if (backendProxyUrl != null) {
this.set("backend-proxy-url", backendProxyUrl.toString());
} else {
this.set("backend-proxy-url", "");
}
this.save();
}
public boolean useBackendHaProxy() {
@ -328,7 +337,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setBackendHaProxy(final boolean backendHaProxy) {
this.backendHaProxy = backendHaProxy;
this.set("backend-haproxy", backendHaProxy);
this.save();
}
public boolean useFrontendHaProxy() {
@ -337,7 +346,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setFrontendHaProxy(final boolean frontendHaProxy) {
this.frontendHaProxy = frontendHaProxy;
this.set("frontend-haproxy", frontendHaProxy);
this.save();
}
public boolean shouldSignChat() {
@ -346,7 +355,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setChatSigning(final boolean chatSigning) {
this.chatSigning = chatSigning;
this.set("chat-signing", chatSigning);
this.save();
}
public int getCompressionThreshold() {
@ -355,7 +364,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setCompressionThreshold(final int compressionThreshold) {
this.compressionThreshold = compressionThreshold;
this.set("compression-threshold", compressionThreshold);
this.save();
}
public boolean shouldAllowBetaPinging() {
@ -364,7 +373,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setAllowBetaPinging(final boolean allowBetaPinging) {
this.allowBetaPinging = allowBetaPinging;
this.set("allow-beta-pinging", allowBetaPinging);
this.save();
}
public boolean shouldIgnoreProtocolTranslationErrors() {
@ -373,7 +382,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setIgnoreProtocolTranslationErrors(final boolean ignoreProtocolTranslationErrors) {
this.ignoreProtocolTranslationErrors = ignoreProtocolTranslationErrors;
this.set("ignore-protocol-translation-errors", ignoreProtocolTranslationErrors);
this.save();
}
public boolean shouldSuppressClientProtocolErrors() {
@ -382,7 +391,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setSuppressClientProtocolErrors(final boolean suppressClientProtocolErrors) {
this.suppressClientProtocolErrors = suppressClientProtocolErrors;
this.set("suppress-client-protocol-errors", suppressClientProtocolErrors);
this.save();
}
public boolean shouldAllowLegacyClientPassthrough() {
@ -391,7 +400,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setAllowLegacyClientPassthrough(final boolean allowLegacyClientPassthrough) {
this.allowLegacyClientPassthrough = allowLegacyClientPassthrough;
this.set("allow-legacy-client-passthrough", allowLegacyClientPassthrough);
this.save();
}
public boolean shouldPassthroughBungeecordPlayerInfo() {
@ -400,7 +409,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setPassthroughBungeecordPlayerInfo(final boolean bungeecordPlayerInfoPassthrough) {
this.bungeecordPlayerInfoPassthrough = bungeecordPlayerInfoPassthrough;
this.set("bungeecord-player-info-passthrough", bungeecordPlayerInfoPassthrough);
this.save();
}
public String getCustomMotd() {
@ -409,7 +418,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setCustomMotd(final String customMotd) {
this.customMotd = customMotd;
this.set("custom-motd", customMotd);
this.save();
}
public String getResourcePackUrl() {
@ -418,7 +427,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setResourcePackUrl(final String resourcePackUrl) {
this.resourcePackUrl = resourcePackUrl;
this.set("resource-pack-url", resourcePackUrl);
this.save();
}
public WildcardDomainHandling getWildcardDomainHandling() {
@ -427,7 +436,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setWildcardDomainHandling(final WildcardDomainHandling wildcardDomainHandling) {
this.wildcardDomainHandling = wildcardDomainHandling;
this.set("wildcard-domain-handling", wildcardDomainHandling.name().toLowerCase(Locale.ROOT));
this.save();
}
public boolean shouldSupportSimpleVoiceChat() {
@ -436,7 +445,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setSimpleVoiceChatSupport(final boolean simpleVoiceChatSupport) {
this.simpleVoiceChatSupport = simpleVoiceChatSupport;
this.set("simple-voice-chat-support", simpleVoiceChatSupport);
this.save();
}
public boolean shouldFakeAcceptResourcePacks() {
@ -445,31 +454,21 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
public void setFakeAcceptResourcePacks(final boolean fakeAcceptResourcePacks) {
this.fakeAcceptResourcePacks = fakeAcceptResourcePacks;
this.set("fake-accept-resource-packs", fakeAcceptResourcePacks);
this.save();
}
private void checkTargetVersion() {
if (this.targetVersion == null) {
this.targetVersion = ProtocolTranslator.AUTO_DETECT_PROTOCOL;
this.logger.info("Invalid target version: " + this.getString("target-version", "") + ". Defaulting to auto detect.");
this.logger.info("=== Supported Protocol Versions ===");
@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()) {
this.logger.info(version.getName());
Logger.LOGGER.warn(version.getName());
}
this.logger.info("===================================");
Logger.LOGGER.warn("===================================");
return ProtocolTranslator.AUTO_DETECT_PROTOCOL;
}
}
private URI parseProxyUrl(final String proxyUrl) {
if (!proxyUrl.isBlank()) {
try {
return new URI(proxyUrl);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid proxy url: " + proxyUrl + ". Proxy url format: type://address:port or type://username:password@address:port");
}
}
return null;
return targetVersion;
}
public enum AuthMethod {
@ -493,16 +492,6 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
this.guiTranslationKey = guiTranslationKey;
}
public static AuthMethod byName(String name) {
for (AuthMethod mode : values()) {
if (mode.name().equalsIgnoreCase(name)) {
return mode;
}
}
return NONE;
}
public String getGuiTranslationKey() {
return this.guiTranslationKey;
}
@ -522,17 +511,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
/**
* Iternal wildcard domain handling
*/
INTERNAL;
public static WildcardDomainHandling byName(String name) {
for (WildcardDomainHandling mode : values()) {
if (mode.name().equalsIgnoreCase(name)) {
return mode;
}
}
return NONE;
}
INTERNAL,
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.util.config;
import net.lenni0451.optconfig.serializer.ConfigTypeSerializer;
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<ViaProxyConfig, Account> {
public AccountTypeSerializer(final ViaProxyConfig config) {
super(config);
}
@Override
public Account deserialize(final Class<Account> typeClass, final Object serializedObject) {
final List<Account> accounts = ViaProxy.getSaveManager().accountsSave.getAccounts();
final int accountIndex = (int) serializedObject;
if (this.config.getAuthMethod() == ViaProxyConfig.AuthMethod.ACCOUNT && accountIndex >= 0 && accountIndex < accounts.size()) {
return accounts.get(accountIndex);
} else {
return null;
}
}
@Override
public Object serialize(final Account object) {
if (object != null) {
return ViaProxy.getSaveManager().accountsSave.getAccounts().indexOf(object);
} else {
return 0;
}
}
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.util.config;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.lenni0451.optconfig.serializer.ConfigTypeSerializer;
import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig;
public class ProtocolVersionTypeSerializer extends ConfigTypeSerializer<ViaProxyConfig, ProtocolVersion> {
public ProtocolVersionTypeSerializer(final ViaProxyConfig config) {
super(config);
}
@Override
public ProtocolVersion deserialize(final Class<ProtocolVersion> typeClass, final Object serializedObject) {
return ProtocolVersion.getClosest((String) serializedObject);
}
@Override
public Object serialize(final ProtocolVersion object) {
return object.getName();
}
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.util.config;
import net.lenni0451.optconfig.serializer.ConfigTypeSerializer;
import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig;
import java.net.URI;
import java.net.URISyntaxException;
public class ProxyUriTypeSerializer extends ConfigTypeSerializer<ViaProxyConfig, URI> {
public ProxyUriTypeSerializer(final ViaProxyConfig config) {
super(config);
}
@Override
public URI deserialize(final Class<URI> typeClass, final Object serializedObject) {
final String proxyUrl = (String) serializedObject;
if (!proxyUrl.isBlank()) {
try {
return new URI(proxyUrl);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid proxy url: " + proxyUrl + ". Proxy url format: type://address:port or type://username:password@address:port");
}
}
return null;
}
@Override
public Object serialize(final URI object) {
if (object != null) {
return object.toString();
} else {
return "";
}
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.util.config;
import net.lenni0451.optconfig.serializer.ConfigTypeSerializer;
import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig;
import net.raphimc.viaproxy.util.AddressUtil;
import java.net.SocketAddress;
public class SocketAddressTypeSerializer extends ConfigTypeSerializer<ViaProxyConfig, SocketAddress> {
public SocketAddressTypeSerializer(final ViaProxyConfig config) {
super(config);
}
@Override
public SocketAddress deserialize(final Class<SocketAddress> typeClass, final Object serializedObject) {
return AddressUtil.parse((String) serializedObject, null);
}
@Override
public Object serialize(final SocketAddress object) {
return AddressUtil.toString(object);
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 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 <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.util.config;
import net.lenni0451.optconfig.serializer.ConfigTypeSerializer;
import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig;
import net.raphimc.viaproxy.util.AddressUtil;
import java.net.SocketAddress;
public class TargetAddressTypeSerializer extends ConfigTypeSerializer<ViaProxyConfig, SocketAddress> {
public TargetAddressTypeSerializer(final ViaProxyConfig config) {
super(config);
}
@Override
public SocketAddress deserialize(final Class<SocketAddress> typeClass, final Object serializedObject) {
return AddressUtil.parse((String) serializedObject, this.config.getTargetVersion());
}
@Override
public Object serialize(final SocketAddress object) {
return AddressUtil.toString(object);
}
}

View File

@ -1,90 +0,0 @@
# ViaProxy configuration file
#
# The address ViaProxy should listen for connections.
bind-address: "0.0.0.0:25568"
#
# The address of the server ViaProxy should connect to.
target-address: "127.0.0.1:25565"
#
# The version ViaProxy should translate to. (See ViaProxy GUI for a list of versions)
target-version: "Auto Detect (1.7+ servers)"
#
# The connect timeout for backend server connections in milliseconds.
connect-timeout: 8000
#
# 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.
proxy-online-mode: false
#
# The authentication method to use for joining the target server.
# none: No authentication (Offline mode)
# openauthmod: Requires the OpenAuthMod client mod (https://modrinth.com/mod/openauthmod)
# account: Use an account for joining the target server. (Has to be configured in ViaProxy GUI)
auth-method: "none"
#
# The GUI account list index (0 indexed) of the account if the auth method is set to account.
minecraft-account-index: 0
#
# Use BetaCraft authentication for classic servers.
# Enabling BetaCraft Auth allows you to join classic servers which have online mode enabled.
betacraft-auth: false
#
# 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
backend-proxy-url: ""
#
# Send HAProxy protocol messages to the target server.
backend-haproxy: false
#
# Read HAProxy protocol messages from client connections.
frontend-haproxy: false
#
# Enables sending signed chat messages on >= 1.19 servers.
chat-signing: true
#
# The threshold for packet compression. Packets larger than this size will be compressed. (-1 to disable)
compression-threshold: 256
#
# Enabling this will allow you to ping <= b1.7.3 servers. This may cause issues with servers that block too frequent connections.
allow-beta-pinging: false
#
# 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.
ignore-protocol-translation-errors: false
#
# 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.
suppress-client-protocol-errors: false
#
# Allow <= 1.6.4 clients to connect through ViaProxy to the target server. (No protocol translation or packet handling)
allow-legacy-client-passthrough: false
#
# 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.
bungeecord-player-info-passthrough: false
#
# Custom MOTD to send when clients ping the proxy. Leave empty to use the target server's MOTD.
custom-motd: ""
#
# 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
resource-pack-url: ""
#
# 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)
wildcard-domain-handling: "none"
#
# Enables handling and rewriting of Simple Voice Chat mod packets.
simple-voice-chat-support: false
#
# 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.
fake-accept-resource-packs: false
#
# Configuration version. Do not change this.
config-version: 1