This commit is contained in:
ayunami2000 2023-10-03 13:33:17 -04:00
parent a5eac20833
commit a923d84bd9
5 changed files with 93 additions and 97 deletions

View File

@ -1,6 +1,7 @@
package me.ayunami2000.ayunViaProxyEagUtils; package me.ayunami2000.ayunViaProxyEagUtils;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.viaversion.viaversion.util.ChatColorUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@ -14,10 +15,10 @@ import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ClientboundP
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ServerboundPackets1_5_2; import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ServerboundPackets1_5_2;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.types.Types1_6_4; import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.types.Types1_6_4;
import net.raphimc.vialoader.util.VersionEnum; import net.raphimc.vialoader.util.VersionEnum;
import net.raphimc.viaproxy.proxy.session.LegacyProxyConnection;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.ExceptionUtil; import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -25,7 +26,6 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
private final VersionEnum version; private final VersionEnum version;
private final String password; private final String password;
private final NetClient proxyConnection; private final NetClient proxyConnection;
private final Map<UUID, String> uuidStringMap = new HashMap<>();
private final List<UUID> skinsBeingFetched = new ArrayList<>(); private final List<UUID> skinsBeingFetched = new ArrayList<>();
private ByteBuf serverBoundPartialPacket = Unpooled.EMPTY_BUFFER; private ByteBuf serverBoundPartialPacket = Unpooled.EMPTY_BUFFER;
private ByteBuf clientBoundPartialPacket = Unpooled.EMPTY_BUFFER; private ByteBuf clientBoundPartialPacket = Unpooled.EMPTY_BUFFER;
@ -96,11 +96,8 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
} }
public void encodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { public void encodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
if (handshakeState == 0) { if (in.readableBytes() >= 2 && in.getUnsignedByte(0) == 2) {
handshakeState = 1; in.setByte(1, in.getUnsignedByte(1) + 8);
if (in.readableBytes() >= 2 && in.getUnsignedByte(0) == 2) {
in.setByte(1, in.getUnsignedByte(1) + 8);
}
} }
if (in.readableBytes() >= 1 && in.getUnsignedByte(0) == 0xFD) { if (in.readableBytes() >= 1 && in.getUnsignedByte(0) == 0xFD) {
return; return;
@ -108,42 +105,9 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
if (in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) { if (in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) {
in.skipBytes(1); in.skipBytes(1);
String tag; String tag;
byte[] msg;
try { try {
tag = Types1_6_4.STRING.read(in); tag = Types1_6_4.STRING.read(in);
if (tag.equals("EAG|Skins-1.8")) { if (tag.equals("EAG|Skins-1.8")) {
msg = new byte[in.readShort()];
in.readBytes(msg);
if (msg.length == 0) {
throw new IOException("Zero-length packet recieved");
}
final int packetId = msg[0] & 0xFF;
switch (packetId) {
case 3: {
if (msg.length != 17) {
throw new IOException("Invalid length " + msg.length + " for skin request packet");
}
final UUID searchUUID = SkinPackets.bytesToUUID(msg, 1);
if (uuidStringMap.containsKey(searchUUID)) {
// skinsBeingFetched.add(searchUUID);
String name = uuidStringMap.get(searchUUID);
ByteBuf bb = ctx.alloc().buffer();
bb.writeByte((byte) 250);
Types1_6_4.STRING.write(bb, "EAG|FetchSkin"); // todo: get to work
bb.writeByte((byte) 0);
bb.writeByte((byte) 0);
bb.writeBytes(name.getBytes(StandardCharsets.UTF_8));
out.add(new BinaryWebSocketFrame(bb));
}
break;
}
case 6: {
break;
}
default: {
throw new IOException("Unknown packet type " + packetId);
}
}
return; return;
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -228,7 +192,18 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
try { try {
String name = Types1_6_4.STRING.read(in); String name = Types1_6_4.STRING.read(in);
UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)); UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8));
uuidStringMap.put(uuid, name); skinsBeingFetched.add(uuid);
ByteBuf bb = ctx.alloc().buffer();
bb.writeByte((byte) 250);
Types1_6_4.STRING.write(bb, "EAG|FetchSkin");
ByteBuf bbb = ctx.alloc().buffer();
bbb.writeByte((byte) 0);
bbb.writeByte((byte) 0);
bbb.writeBytes(name.getBytes(StandardCharsets.UTF_8));
bb.writeShort(bbb.readableBytes());
bb.writeBytes(bbb);
bbb.release();
ctx.writeAndFlush(new BinaryWebSocketFrame(bb));
} catch (Exception ignored) { } catch (Exception ignored) {
} }
in.resetReaderIndex(); in.resetReaderIndex();
@ -240,20 +215,25 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
ctx.writeAndFlush(new BinaryWebSocketFrame(in.retain())); ctx.writeAndFlush(new BinaryWebSocketFrame(in.retain()));
return; return;
} }
if (!skinsBeingFetched.isEmpty() && in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) { if (in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) {
in.skipBytes(1); in.skipBytes(1);
String tag; String tag;
byte[] msg; byte[] msg;
try { try {
tag = Types1_6_4.STRING.read(in); tag = Types1_6_4.STRING.read(in);
// System.out.println(tag);
if (tag.equals("EAG|UserSkin")) { if (tag.equals("EAG|UserSkin")) {
if (skinsBeingFetched.isEmpty()) {
return;
}
msg = new byte[in.readShort()]; msg = new byte[in.readShort()];
in.readBytes(msg); in.readBytes(msg);
System.out.println(msg.length); if (msg.length < 8192) {
byte[] res = new byte[msg.length - 1]; return;
}
// TODO: FIX LOL!!
byte[] res = new byte[msg.length > 16384 ? 16384 : 8192];
System.arraycopy(msg, 1, res, 0, res.length); System.arraycopy(msg, 1, res, 0, res.length);
if (res.length == 8192) { if (res.length < 16384) {
final int[] tmp1 = new int[2048]; final int[] tmp1 = new int[2048];
final int[] tmp2 = new int[4096]; final int[] tmp2 = new int[4096];
for (int i = 0; i < tmp1.length; ++i) { for (int i = 0; i < tmp1.length; ++i) {
@ -273,11 +253,27 @@ public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFr
res[j] = tmp3; res[j] = tmp3;
} }
} }
in.writerIndex(1); ByteBuf bb = ctx.alloc().buffer();
Types1_6_4.STRING.write(in, "EAG|Skins-1.8"); bb.writeByte((byte) 250);
Types1_6_4.STRING.write(bb, "EAG|Skins-1.8");
byte[] data = SkinPackets.makeCustomResponse(skinsBeingFetched.remove(0), 0, res); byte[] data = SkinPackets.makeCustomResponse(skinsBeingFetched.remove(0), 0, res);
in.writeShort(data.length); bb.writeShort(data.length);
in.writeBytes(data); bb.writeBytes(data);
out.add(bb);
return;
} else if (tag.equals("EAG|Reconnect")) {
msg = new byte[in.readShort()];
in.readBytes(msg);
in.resetReaderIndex();
in.resetWriterIndex();
in.writeByte((byte) 0xFF);
Types1_6_4.STRING.write(in, "Please use the IP: " + ChatColorUtil.COLOR_CHAR + "n" + new String(msg, StandardCharsets.UTF_8));
in.resetReaderIndex();
ctx.fireChannelRead(in.retain()).close();
if (!(proxyConnection instanceof ProxyConnection)) {
((LegacyProxyConnection) proxyConnection).getC2P().close();
}
return;
} }
} catch (Exception ignored) { } catch (Exception ignored) {
} }

View File

@ -16,9 +16,9 @@ import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.viaproxy.plugins.PluginManager; import net.raphimc.viaproxy.plugins.PluginManager;
import net.raphimc.viaproxy.plugins.events.Client2ProxyHandlerCreationEvent; import net.raphimc.viaproxy.plugins.events.Client2ProxyHandlerCreationEvent;
import net.raphimc.viaproxy.proxy.client2proxy.Client2ProxyChannelInitializer; import net.raphimc.viaproxy.proxy.client2proxy.Client2ProxyChannelInitializer;
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.LegacyPassthroughInitialHandler;
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyChannelInitializer; import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyChannelInitializer;
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyHandler; import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyHandler;
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughInitialHandler;
import net.raphimc.viaproxy.proxy.util.ExceptionUtil; import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
import java.io.File; import java.io.File;
@ -52,7 +52,7 @@ public class EaglercraftInitialHandler extends ByteToMessageDecoder {
ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-handler", new WebSocketServerProtocolHandler("/", null, true)); ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-handler", new WebSocketServerProtocolHandler("/", null, true));
ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-active-notifier", new WebSocketActiveNotifier()); ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-active-notifier", new WebSocketActiveNotifier());
ctx.pipeline().addBefore("eaglercraft-initial-handler", "eaglercraft-handler", new EaglercraftHandler()); ctx.pipeline().addBefore("eaglercraft-initial-handler", "eaglercraft-handler", new EaglercraftHandler());
ctx.pipeline().replace(Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new PassthroughInitialHandler() { ctx.pipeline().replace(Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new LegacyPassthroughInitialHandler() {
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
if (ctx.channel().isOpen()) { if (ctx.channel().isOpen()) {

View File

@ -10,7 +10,6 @@ import java.util.Map;
public class FunnyConfig extends Config { public class FunnyConfig extends Config {
public static boolean premiumSkins = false; public static boolean premiumSkins = false;
public static boolean eaglerUtils = true;
public static boolean eaglerSkins = true; public static boolean eaglerSkins = true;
public static boolean eaglerVoice = true; public static boolean eaglerVoice = true;
@ -29,10 +28,6 @@ public class FunnyConfig extends Config {
if (item instanceof Boolean) { if (item instanceof Boolean) {
premiumSkins = (Boolean) item; premiumSkins = (Boolean) item;
} }
item = map.get("eagler-utils");
if (item instanceof Boolean) {
eaglerUtils = (Boolean) item;
}
item = map.get("eagler-skins"); item = map.get("eagler-skins");
if (item instanceof Boolean) { if (item instanceof Boolean) {
eaglerSkins = (Boolean) item; eaglerSkins = (Boolean) item;

View File

@ -20,6 +20,7 @@ import net.raphimc.viaproxy.plugins.events.Proxy2ServerChannelInitializeEvent;
import net.raphimc.viaproxy.plugins.events.types.ITyped; import net.raphimc.viaproxy.plugins.events.types.ITyped;
import net.raphimc.viaproxy.proxy.session.LegacyProxyConnection; import net.raphimc.viaproxy.proxy.session.LegacyProxyConnection;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.proxy.util.ChannelUtil;
import net.raphimc.viaproxy.proxy.util.ExceptionUtil; import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
import javax.net.ssl.*; import javax.net.ssl.*;
@ -97,53 +98,57 @@ public class Main extends ViaProxyPlugin {
if (c2p.hasAttr(secureWs)) { if (c2p.hasAttr(secureWs)) {
ch.attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(-2); doWsServerStuff(ch, proxyConnection, c2p, addr);
if (proxyConnection instanceof ProxyConnection && ((ProxyConnection) proxyConnection).getServerVersion().isNewerThan(VersionEnum.r1_6_4)) {
ch.pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
} else if (ch.pipeline().get(MCPipeline.ENCRYPTION_HANDLER_NAME) != null) {
ch.pipeline().remove(MCPipeline.ENCRYPTION_HANDLER_NAME);
}
StringBuilder url = new StringBuilder("ws");
boolean secure = c2p.attr(secureWs).get();
if (secure) {
final SSLEngine sslEngine = sc.createSSLEngine(addr.getAddress(), addr.getPort());
sslEngine.setUseClientMode(true);
sslEngine.setNeedClientAuth(false);
ch.pipeline().addFirst("eag-server-ssl", new SslHandler(sslEngine));
url.append("s");
ch.pipeline().addAfter("eag-server-ssl", "eag-server-http-codec", new HttpClientCodec());
} else {
ch.pipeline().addFirst("eag-server-http-codec", new HttpClientCodec());
}
url.append("://").append(addr.getAddress());
boolean addPort = (secure && addr.getPort() != 443) || (!secure && addr.getPort() != 80);
if (addPort) {
url.append(":").append(addr.getPort());
}
String path = c2p.attr(wsPath).get();
if (path != null) {
url.append("/").append(path);
}
URI uri = new URI(url.toString());
HttpHeaders headers = new DefaultHttpHeaders();
headers.set(HttpHeaderNames.HOST, uri.getHost() + (addPort ? ":" + uri.getPort() : ""));
headers.set(HttpHeaderNames.ORIGIN, "via.shhnowisnottheti.me");
ch.pipeline().addAfter("eag-server-http-codec", "eag-server-http-aggregator", new HttpObjectAggregator(2097152, true));
ch.pipeline().addAfter("eag-server-http-aggregator", "eag-server-ws-compression", WebSocketClientCompressionHandler.INSTANCE);
ch.pipeline().addAfter("eag-server-ws-compression", "eag-server-ws-handshaker", new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, headers, 2097152)));
ch.pipeline().addAfter("eag-server-ws-handshaker", "eag-server-ws-ready", new WebSocketConnectedNotifier());
ch.pipeline().addAfter("eag-server-ws-ready", "eag-server-handler", new EaglerServerHandler(proxyConnection, c2p.attr(eagxPass).get()));
} }
} }
} }
private static void doWsServerStuff(Channel ch, NetClient proxyConnection, Channel c2p, ServerAddress addr) throws URISyntaxException {
ch.attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(-2);
if (proxyConnection instanceof ProxyConnection && ((ProxyConnection) proxyConnection).getServerVersion().isNewerThan(VersionEnum.r1_6_4)) {
ch.pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
} else if (ch.pipeline().get(MCPipeline.ENCRYPTION_HANDLER_NAME) != null) {
ch.pipeline().remove(MCPipeline.ENCRYPTION_HANDLER_NAME);
}
StringBuilder url = new StringBuilder("ws");
boolean secure = c2p.attr(secureWs).get();
if (secure) {
final SSLEngine sslEngine = sc.createSSLEngine(addr.getAddress(), addr.getPort());
sslEngine.setUseClientMode(true);
sslEngine.setNeedClientAuth(false);
ch.pipeline().addFirst("eag-server-ssl", new SslHandler(sslEngine));
url.append("s");
ch.pipeline().addAfter("eag-server-ssl", "eag-server-http-codec", new HttpClientCodec());
} else {
ch.pipeline().addFirst("eag-server-http-codec", new HttpClientCodec());
}
url.append("://").append(addr.getAddress());
boolean addPort = (secure && addr.getPort() != 443) || (!secure && addr.getPort() != 80);
if (addPort) {
url.append(":").append(addr.getPort());
}
String path = c2p.attr(wsPath).get();
if (path != null) {
url.append("/").append(path);
}
URI uri = new URI(url.toString());
HttpHeaders headers = new DefaultHttpHeaders();
headers.set(HttpHeaderNames.HOST, uri.getHost() + (addPort ? ":" + uri.getPort() : ""));
headers.set(HttpHeaderNames.ORIGIN, "via.shhnowisnottheti.me");
ch.pipeline().addAfter("eag-server-http-codec", "eag-server-http-aggregator", new HttpObjectAggregator(2097152, true));
ch.pipeline().addAfter("eag-server-http-aggregator", "eag-server-ws-compression", WebSocketClientCompressionHandler.INSTANCE);
ch.pipeline().addAfter("eag-server-ws-compression", "eag-server-ws-handshaker", new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, headers, 2097152)));
ch.pipeline().addAfter("eag-server-ws-handshaker", "eag-server-ws-ready", new WebSocketConnectedNotifier());
ch.pipeline().addAfter("eag-server-ws-ready", "eag-server-handler", new EaglerServerHandler(proxyConnection, c2p.attr(eagxPass).get()));
}
@EventHandler @EventHandler
public void onEvent(final Client2ProxyChannelInitializeEvent event) { public void onEvent(final Client2ProxyChannelInitializeEvent event) {
if (event.isLegacyPassthrough()) return; if (event.isLegacyPassthrough()) return;
if (event.getType() == ITyped.Type.PRE) { if (event.getType() == ITyped.Type.PRE) {
event.getChannel().pipeline().addLast("eaglercraft-initial-handler", new EaglercraftInitialHandler()); event.getChannel().pipeline().addLast("eaglercraft-initial-handler", new EaglercraftInitialHandler());
} }
if (event.getType() == ITyped.Type.POST && FunnyConfig.eaglerUtils) { if (event.getType() == ITyped.Type.POST) {
event.getChannel().pipeline().addAfter("eaglercraft-initial-handler", "ayun-eag-detector", new EaglerConnectionHandler()); event.getChannel().pipeline().addAfter("eaglercraft-initial-handler", "ayun-eag-detector", new EaglerConnectionHandler());
} }
} }
@ -154,7 +159,9 @@ public class Main extends ViaProxyPlugin {
super.userEventTriggered(ctx, evt); super.userEventTriggered(ctx, evt);
if (evt instanceof EaglercraftInitialHandler.EaglercraftClientConnected) { if (evt instanceof EaglercraftInitialHandler.EaglercraftClientConnected) {
ctx.pipeline().remove("ayun-eag-detector"); ctx.pipeline().remove("ayun-eag-detector");
ctx.pipeline().addBefore("eaglercraft-handler", "ayun-eag-utils-init", new EaglerUtilsInitHandler()); if (!ctx.channel().hasAttr(secureWs)) {
ctx.pipeline().addBefore("eaglercraft-handler", "ayun-eag-utils-init", new EaglerUtilsInitHandler());
}
} }
} }

View File

@ -1,7 +1,5 @@
# Use premium skins # Use premium skins
premium-skins: false premium-skins: false
# Handle Eagler skins and voice on the proxy side
eagler-utils: true
# Sync Eagler skins # Sync Eagler skins
eagler-skins: true eagler-skins: true
# Enable Eagler voice chat # Enable Eagler voice chat