Added support for connecting through proxies

This commit is contained in:
RaphiMC 2023-03-18 17:26:13 +01:00
parent ec73966a3d
commit bfe70507bc
2 changed files with 48 additions and 1 deletions

View File

@ -29,6 +29,8 @@ import net.raphimc.viaproxy.saves.impl.accounts.Account;
import net.raphimc.viaproxy.util.logging.Logger;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import static java.util.Arrays.asList;
@ -51,7 +53,8 @@ public class Options {
public static boolean SRV_MODE; // Example: lenni0451.net_25565_1.8.x.viaproxy.127.0.0.1.nip.io
public static boolean INTERNAL_SRV_MODE; // Example: ip\7port\7version\7mppass
public static boolean LOCAL_SOCKET_AUTH;
public static String RESOURCE_PACK_URL;
public static String RESOURCE_PACK_URL; // Example: http://example.com/resourcepack.zip
public static URI PROXY_URL; // Example: type://address:port or type://username:password@address:port
public static void parse(final String[] args) throws IOException {
final OptionParser parser = new OptionParser();
@ -70,6 +73,7 @@ public class Options {
final OptionSpec<Void> localSocketAuth = parser.accepts("local_socket_auth", "Enable authentication over a local socket");
final OptionSpec<Void> betaCraftAuth = parser.accepts("betacraft_auth", "Use BetaCraft authentication servers for classic");
final OptionSpec<String> resourcePackUrl = parser.acceptsAll(asList("resource_pack_url", "resource_pack", "rpu", "rp"), "URL of a resource pack which all connecting clients can optionally download").withRequiredArg().ofType(String.class);
final OptionSpec<String> proxyUrl = parser.acceptsAll(asList("proxy_url", "proxy"), "URL of a SOCKS(4/5)/HTTP(S) proxy which will be used for TCP connections").withRequiredArg().ofType(String.class);
PluginManager.EVENT_MANAGER.call(new PreOptionsParseEvent(parser));
final OptionSet options = parser.parse(args);
@ -98,6 +102,15 @@ public class Options {
if (options.has(resourcePackUrl)) {
RESOURCE_PACK_URL = options.valueOf(resourcePackUrl);
}
if (options.has(proxyUrl)) {
try {
PROXY_URL = new URI(options.valueOf(proxyUrl));
} catch (URISyntaxException e) {
Logger.LOGGER.error("Invalid proxy url: " + options.valueOf(proxyUrl));
Logger.LOGGER.error("Proxy url format: type://address:port or type://username:password@address:port");
System.exit(1);
}
}
PluginManager.EVENT_MANAGER.call(new PostOptionsParseEvent(options));
}

View File

@ -22,6 +22,10 @@ import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.handler.proxy.HttpProxyHandler;
import io.netty.handler.proxy.ProxyHandler;
import io.netty.handler.proxy.Socks4ProxyHandler;
import io.netty.handler.proxy.Socks5ProxyHandler;
import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil;
@ -31,12 +35,16 @@ import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.baseprotoc
import net.raphimc.viaprotocolhack.netty.VPHEncodeHandler;
import net.raphimc.viaprotocolhack.netty.VPHPipeline;
import net.raphimc.viaprotocolhack.util.VersionEnum;
import net.raphimc.viaproxy.cli.options.Options;
import net.raphimc.viaproxy.plugins.PluginManager;
import net.raphimc.viaproxy.plugins.events.Proxy2ServerChannelInitializeEvent;
import net.raphimc.viaproxy.plugins.events.types.ITyped;
import net.raphimc.viaproxy.protocolhack.impl.ViaProxyViaDecodeHandler;
import net.raphimc.viaproxy.proxy.ProxyConnection;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Locale;
import java.util.function.Supplier;
public class Proxy2ServerChannelInitializer extends MinecraftChannelInitializer {
@ -67,9 +75,35 @@ public class Proxy2ServerChannelInitializer extends MinecraftChannelInitializer
channel.pipeline().addBefore(MCPipeline.SIZER_HANDLER_NAME, VPHPipeline.PRE_NETTY_DECODER_HANDLER_NAME, new PreNettyDecoder(user));
}
if (Options.PROXY_URL != null) {
channel.pipeline().addFirst("viaproxy-proxy-handler", this.getProxyHandler());
}
if (PluginManager.EVENT_MANAGER.call(new Proxy2ServerChannelInitializeEvent(ITyped.Type.POST, channel)).isCancelled()) {
channel.close();
}
}
protected ProxyHandler getProxyHandler() {
final URI proxyUrl = Options.PROXY_URL;
final InetSocketAddress proxyAddress = new InetSocketAddress(proxyUrl.getHost(), proxyUrl.getPort());
final String username = proxyUrl.getUserInfo() != null ? proxyUrl.getUserInfo().split(":")[0] : null;
final String password = proxyUrl.getUserInfo() != null && proxyUrl.getUserInfo().contains(":") ? proxyUrl.getUserInfo().split(":")[1] : null;
switch (proxyUrl.getScheme().toUpperCase(Locale.ROOT)) {
case "HTTP":
case "HTTPS":
if (username != null && password != null) return new HttpProxyHandler(proxyAddress, username, password);
else return new HttpProxyHandler(proxyAddress);
case "SOCKS4":
if (username != null) return new Socks4ProxyHandler(proxyAddress, username);
else return new Socks4ProxyHandler(proxyAddress);
case "SOCKS5":
if (username != null && password != null) return new Socks5ProxyHandler(proxyAddress, username, password);
else return new Socks5ProxyHandler(proxyAddress);
}
throw new IllegalArgumentException("Unknown proxy type: " + proxyUrl.getScheme());
}
}