Added option to send resource pack on join

This commit is contained in:
RaphiMC 2023-02-17 11:24:29 +01:00
parent 40fd7dc9c0
commit a9f8ad27d0
2 changed files with 67 additions and 9 deletions

View file

@ -34,24 +34,24 @@ public class Options {
public static String BIND_ADDRESS = "0.0.0.0";
public static int BIND_PORT = 25568;
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 ONLINE_MODE;
public static int NETTY_THREADS = 0;
public static int COMPRESSION_THRESHOLD = 256;
public static String CONNECT_ADDRESS;
public static int CONNECT_PORT = 25565;
public static VersionEnum PROTOCOL_VERSION;
public static boolean ONLINE_MODE;
public static boolean OPENAUTHMOD_AUTH;
public static boolean LOCAL_SOCKET_AUTH;
public static boolean BETACRAFT_AUTH;
// GUI only config options
public static Account MC_ACCOUNT;
// CLI only config options
public static int NETTY_THREADS = 0;
public static int COMPRESSION_THRESHOLD = 256;
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 void parse(final String[] args) throws IOException {
final OptionParser parser = new OptionParser();
final OptionSpec<Void> help = parser.acceptsAll(asList("help", "h", "?"), "Get a list of all arguments").forHelp();
@ -69,6 +69,7 @@ public class Options {
final OptionSpec<Void> openAuthModAuth = parser.acceptsAll(asList("openauthmod_auth", "oam_auth"), "Enable OpenAuthMod authentication");
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 OptionSet options = parser.parse(args);
if (options.has(help)) {
@ -94,6 +95,9 @@ public class Options {
OPENAUTHMOD_AUTH = options.has(openAuthModAuth);
LOCAL_SOCKET_AUTH = options.has(localSocketAuth);
BETACRAFT_AUTH = options.has(betaCraftAuth);
if (options.has(resourcePackUrl)) {
RESOURCE_PACK_URL = options.valueOf(resourcePackUrl);
}
}
}

View file

@ -18,14 +18,21 @@
package net.raphimc.viaproxy.proxy.proxy2server;
import com.mojang.authlib.GameProfile;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.libs.gson.JsonElement;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.crypto.AESEncryption;
import net.raphimc.netminecraft.netty.crypto.CryptUtil;
import net.raphimc.netminecraft.packet.IPacket;
import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.login.*;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.ProtocolMetadataStorage;
import net.raphimc.viaprotocolhack.util.VersionEnum;
@ -37,19 +44,25 @@ import net.raphimc.viaproxy.util.logging.Logger;
import javax.crypto.SecretKey;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> {
private ProxyConnection proxyConnection;
private int joinGamePacketId = -1;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.proxyConnection = ProxyConnection.fromChannel(ctx.channel());
this.joinGamePacketId = MCPackets.S2C_JOIN_GAME.getId(this.proxyConnection.getClientVersion().getVersion());
}
@Override
@ -75,6 +88,14 @@ public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> {
else break;
return;
case PLAY:
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.joinGamePacketId) {
this.proxyConnection.getC2P().writeAndFlush(packet).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
this.sendResourcePack();
return;
}
break;
}
this.proxyConnection.getC2P().writeAndFlush(packet).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
@ -133,4 +154,37 @@ public class Proxy2ServerHandler extends SimpleChannelInboundHandler<IPacket> {
this.proxyConnection.getChannel().attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(packet.compressionThreshold);
}
private void sendResourcePack() {
if (Options.RESOURCE_PACK_URL != null) {
this.proxyConnection.getChannel().eventLoop().schedule(() -> {
if (this.proxyConnection.getClientVersion().isNewerThanOrEqualTo(VersionEnum.r1_8)) {
final ByteBuf resourcePackPacket = Unpooled.buffer();
PacketTypes.writeVarInt(resourcePackPacket, MCPackets.S2C_RESOURCE_PACK.getId(this.proxyConnection.getClientVersion().getVersion()));
PacketTypes.writeString(resourcePackPacket, Options.RESOURCE_PACK_URL); // url
PacketTypes.writeString(resourcePackPacket, ""); // hash
if (this.proxyConnection.getClientVersion().isNewerThanOrEqualTo(VersionEnum.r1_17)) {
resourcePackPacket.writeBoolean(Via.getConfig().isForcedUse1_17ResourcePack()); // required
final JsonElement promptMessage = Via.getConfig().get1_17ResourcePackPrompt();
if (promptMessage != null) {
resourcePackPacket.writeBoolean(true); // has message
PacketTypes.writeString(resourcePackPacket, promptMessage.toString()); // message
} else {
resourcePackPacket.writeBoolean(false); // has message
}
}
this.proxyConnection.getC2P().writeAndFlush(resourcePackPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else if (this.proxyConnection.getClientVersion().isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
final byte[] data = Options.RESOURCE_PACK_URL.getBytes(StandardCharsets.UTF_8);
final ByteBuf customPayloadPacket = Unpooled.buffer();
PacketTypes.writeVarInt(customPayloadPacket, MCPackets.S2C_PLUGIN_MESSAGE.getId(this.proxyConnection.getClientVersion().getVersion()));
PacketTypes.writeString(customPayloadPacket, "MC|RPack"); // channel
customPayloadPacket.writeShort(data.length); // length
customPayloadPacket.writeBytes(data); // data
this.proxyConnection.getC2P().writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
}, 250, TimeUnit.MILLISECONDS);
}
}
}