Skip to content

Commit a923d84

Browse files
committed
wa hoo
1 parent a5eac20 commit a923d84

File tree

5 files changed

+93
-97
lines changed

5 files changed

+93
-97
lines changed

src/main/java/me/ayunami2000/ayunViaProxyEagUtils/EaglerServerHandler.java

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package me.ayunami2000.ayunViaProxyEagUtils;
22

33
import com.google.common.primitives.Ints;
4+
import com.viaversion.viaversion.util.ChatColorUtil;
45
import io.netty.buffer.ByteBuf;
56
import io.netty.buffer.ByteBufUtil;
67
import io.netty.buffer.Unpooled;
@@ -14,18 +15,17 @@
1415
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ServerboundPackets1_5_2;
1516
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.types.Types1_6_4;
1617
import net.raphimc.vialoader.util.VersionEnum;
18+
import net.raphimc.viaproxy.proxy.session.LegacyProxyConnection;
1719
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
1820
import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
1921

20-
import java.io.IOException;
2122
import java.nio.charset.StandardCharsets;
2223
import java.util.*;
2324

2425
public class EaglerServerHandler extends MessageToMessageCodec<BinaryWebSocketFrame, ByteBuf> {
2526
private final VersionEnum version;
2627
private final String password;
2728
private final NetClient proxyConnection;
28-
private final Map<UUID, String> uuidStringMap = new HashMap<>();
2929
private final List<UUID> skinsBeingFetched = new ArrayList<>();
3030
private ByteBuf serverBoundPartialPacket = Unpooled.EMPTY_BUFFER;
3131
private ByteBuf clientBoundPartialPacket = Unpooled.EMPTY_BUFFER;
@@ -96,54 +96,18 @@ public void encode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
9696
}
9797

9898
public void encodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
99-
if (handshakeState == 0) {
100-
handshakeState = 1;
101-
if (in.readableBytes() >= 2 && in.getUnsignedByte(0) == 2) {
102-
in.setByte(1, in.getUnsignedByte(1) + 8);
103-
}
99+
if (in.readableBytes() >= 2 && in.getUnsignedByte(0) == 2) {
100+
in.setByte(1, in.getUnsignedByte(1) + 8);
104101
}
105102
if (in.readableBytes() >= 1 && in.getUnsignedByte(0) == 0xFD) {
106103
return;
107104
}
108105
if (in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) {
109106
in.skipBytes(1);
110107
String tag;
111-
byte[] msg;
112108
try {
113109
tag = Types1_6_4.STRING.read(in);
114110
if (tag.equals("EAG|Skins-1.8")) {
115-
msg = new byte[in.readShort()];
116-
in.readBytes(msg);
117-
if (msg.length == 0) {
118-
throw new IOException("Zero-length packet recieved");
119-
}
120-
final int packetId = msg[0] & 0xFF;
121-
switch (packetId) {
122-
case 3: {
123-
if (msg.length != 17) {
124-
throw new IOException("Invalid length " + msg.length + " for skin request packet");
125-
}
126-
final UUID searchUUID = SkinPackets.bytesToUUID(msg, 1);
127-
if (uuidStringMap.containsKey(searchUUID)) {
128-
// skinsBeingFetched.add(searchUUID);
129-
String name = uuidStringMap.get(searchUUID);
130-
ByteBuf bb = ctx.alloc().buffer();
131-
bb.writeByte((byte) 250);
132-
Types1_6_4.STRING.write(bb, "EAG|FetchSkin"); // todo: get to work
133-
bb.writeByte((byte) 0);
134-
bb.writeByte((byte) 0);
135-
bb.writeBytes(name.getBytes(StandardCharsets.UTF_8));
136-
out.add(new BinaryWebSocketFrame(bb));
137-
}
138-
break;
139-
}
140-
case 6: {
141-
break;
142-
}
143-
default: {
144-
throw new IOException("Unknown packet type " + packetId);
145-
}
146-
}
147111
return;
148112
}
149113
} catch (Exception ignored) {
@@ -228,7 +192,18 @@ public void decodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
228192
try {
229193
String name = Types1_6_4.STRING.read(in);
230194
UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8));
231-
uuidStringMap.put(uuid, name);
195+
skinsBeingFetched.add(uuid);
196+
ByteBuf bb = ctx.alloc().buffer();
197+
bb.writeByte((byte) 250);
198+
Types1_6_4.STRING.write(bb, "EAG|FetchSkin");
199+
ByteBuf bbb = ctx.alloc().buffer();
200+
bbb.writeByte((byte) 0);
201+
bbb.writeByte((byte) 0);
202+
bbb.writeBytes(name.getBytes(StandardCharsets.UTF_8));
203+
bb.writeShort(bbb.readableBytes());
204+
bb.writeBytes(bbb);
205+
bbb.release();
206+
ctx.writeAndFlush(new BinaryWebSocketFrame(bb));
232207
} catch (Exception ignored) {
233208
}
234209
in.resetReaderIndex();
@@ -240,20 +215,25 @@ public void decodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
240215
ctx.writeAndFlush(new BinaryWebSocketFrame(in.retain()));
241216
return;
242217
}
243-
if (!skinsBeingFetched.isEmpty() && in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) {
218+
if (in.readableBytes() >= 3 && in.getUnsignedByte(0) == 250) {
244219
in.skipBytes(1);
245220
String tag;
246221
byte[] msg;
247222
try {
248223
tag = Types1_6_4.STRING.read(in);
249-
// System.out.println(tag);
250224
if (tag.equals("EAG|UserSkin")) {
225+
if (skinsBeingFetched.isEmpty()) {
226+
return;
227+
}
251228
msg = new byte[in.readShort()];
252229
in.readBytes(msg);
253-
System.out.println(msg.length);
254-
byte[] res = new byte[msg.length - 1];
230+
if (msg.length < 8192) {
231+
return;
232+
}
233+
// TODO: FIX LOL!!
234+
byte[] res = new byte[msg.length > 16384 ? 16384 : 8192];
255235
System.arraycopy(msg, 1, res, 0, res.length);
256-
if (res.length == 8192) {
236+
if (res.length < 16384) {
257237
final int[] tmp1 = new int[2048];
258238
final int[] tmp2 = new int[4096];
259239
for (int i = 0; i < tmp1.length; ++i) {
@@ -273,11 +253,27 @@ public void decodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
273253
res[j] = tmp3;
274254
}
275255
}
276-
in.writerIndex(1);
277-
Types1_6_4.STRING.write(in, "EAG|Skins-1.8");
256+
ByteBuf bb = ctx.alloc().buffer();
257+
bb.writeByte((byte) 250);
258+
Types1_6_4.STRING.write(bb, "EAG|Skins-1.8");
278259
byte[] data = SkinPackets.makeCustomResponse(skinsBeingFetched.remove(0), 0, res);
279-
in.writeShort(data.length);
280-
in.writeBytes(data);
260+
bb.writeShort(data.length);
261+
bb.writeBytes(data);
262+
out.add(bb);
263+
return;
264+
} else if (tag.equals("EAG|Reconnect")) {
265+
msg = new byte[in.readShort()];
266+
in.readBytes(msg);
267+
in.resetReaderIndex();
268+
in.resetWriterIndex();
269+
in.writeByte((byte) 0xFF);
270+
Types1_6_4.STRING.write(in, "Please use the IP: " + ChatColorUtil.COLOR_CHAR + "n" + new String(msg, StandardCharsets.UTF_8));
271+
in.resetReaderIndex();
272+
ctx.fireChannelRead(in.retain()).close();
273+
if (!(proxyConnection instanceof ProxyConnection)) {
274+
((LegacyProxyConnection) proxyConnection).getC2P().close();
275+
}
276+
return;
281277
}
282278
} catch (Exception ignored) {
283279
}

src/main/java/me/ayunami2000/ayunViaProxyEagUtils/EaglercraftInitialHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
import net.raphimc.viaproxy.plugins.PluginManager;
1717
import net.raphimc.viaproxy.plugins.events.Client2ProxyHandlerCreationEvent;
1818
import net.raphimc.viaproxy.proxy.client2proxy.Client2ProxyChannelInitializer;
19+
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.LegacyPassthroughInitialHandler;
1920
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyChannelInitializer;
2021
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughClient2ProxyHandler;
21-
import net.raphimc.viaproxy.proxy.client2proxy.passthrough.PassthroughInitialHandler;
2222
import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
2323

2424
import java.io.File;
@@ -52,7 +52,7 @@ protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final L
5252
ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-handler", new WebSocketServerProtocolHandler("/", null, true));
5353
ctx.pipeline().addBefore("eaglercraft-initial-handler", "ws-active-notifier", new WebSocketActiveNotifier());
5454
ctx.pipeline().addBefore("eaglercraft-initial-handler", "eaglercraft-handler", new EaglercraftHandler());
55-
ctx.pipeline().replace(Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new PassthroughInitialHandler() {
55+
ctx.pipeline().replace(Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, Client2ProxyChannelInitializer.LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new LegacyPassthroughInitialHandler() {
5656
@Override
5757
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
5858
if (ctx.channel().isOpen()) {

src/main/java/me/ayunami2000/ayunViaProxyEagUtils/FunnyConfig.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
public class FunnyConfig extends Config {
1212
public static boolean premiumSkins = false;
13-
public static boolean eaglerUtils = true;
1413
public static boolean eaglerSkins = true;
1514
public static boolean eaglerVoice = true;
1615

@@ -29,10 +28,6 @@ protected void handleConfig(Map<String, Object> map) {
2928
if (item instanceof Boolean) {
3029
premiumSkins = (Boolean) item;
3130
}
32-
item = map.get("eagler-utils");
33-
if (item instanceof Boolean) {
34-
eaglerUtils = (Boolean) item;
35-
}
3631
item = map.get("eagler-skins");
3732
if (item instanceof Boolean) {
3833
eaglerSkins = (Boolean) item;

src/main/java/me/ayunami2000/ayunViaProxyEagUtils/Main.java

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import net.raphimc.viaproxy.plugins.events.types.ITyped;
2121
import net.raphimc.viaproxy.proxy.session.LegacyProxyConnection;
2222
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
23+
import net.raphimc.viaproxy.proxy.util.ChannelUtil;
2324
import net.raphimc.viaproxy.proxy.util.ExceptionUtil;
2425

2526
import javax.net.ssl.*;
@@ -97,53 +98,57 @@ public void onEvent(final Proxy2ServerChannelInitializeEvent event) throws URISy
9798

9899

99100
if (c2p.hasAttr(secureWs)) {
100-
ch.attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(-2);
101-
if (proxyConnection instanceof ProxyConnection && ((ProxyConnection) proxyConnection).getServerVersion().isNewerThan(VersionEnum.r1_6_4)) {
102-
ch.pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
103-
} else if (ch.pipeline().get(MCPipeline.ENCRYPTION_HANDLER_NAME) != null) {
104-
ch.pipeline().remove(MCPipeline.ENCRYPTION_HANDLER_NAME);
105-
}
106-
StringBuilder url = new StringBuilder("ws");
107-
boolean secure = c2p.attr(secureWs).get();
108-
if (secure) {
109-
final SSLEngine sslEngine = sc.createSSLEngine(addr.getAddress(), addr.getPort());
110-
sslEngine.setUseClientMode(true);
111-
sslEngine.setNeedClientAuth(false);
112-
ch.pipeline().addFirst("eag-server-ssl", new SslHandler(sslEngine));
113-
url.append("s");
114-
ch.pipeline().addAfter("eag-server-ssl", "eag-server-http-codec", new HttpClientCodec());
115-
} else {
116-
ch.pipeline().addFirst("eag-server-http-codec", new HttpClientCodec());
117-
}
118-
url.append("://").append(addr.getAddress());
119-
boolean addPort = (secure && addr.getPort() != 443) || (!secure && addr.getPort() != 80);
120-
if (addPort) {
121-
url.append(":").append(addr.getPort());
122-
}
123-
String path = c2p.attr(wsPath).get();
124-
if (path != null) {
125-
url.append("/").append(path);
126-
}
127-
URI uri = new URI(url.toString());
128-
HttpHeaders headers = new DefaultHttpHeaders();
129-
headers.set(HttpHeaderNames.HOST, uri.getHost() + (addPort ? ":" + uri.getPort() : ""));
130-
headers.set(HttpHeaderNames.ORIGIN, "via.shhnowisnottheti.me");
131-
ch.pipeline().addAfter("eag-server-http-codec", "eag-server-http-aggregator", new HttpObjectAggregator(2097152, true));
132-
ch.pipeline().addAfter("eag-server-http-aggregator", "eag-server-ws-compression", WebSocketClientCompressionHandler.INSTANCE);
133-
ch.pipeline().addAfter("eag-server-ws-compression", "eag-server-ws-handshaker", new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, headers, 2097152)));
134-
ch.pipeline().addAfter("eag-server-ws-handshaker", "eag-server-ws-ready", new WebSocketConnectedNotifier());
135-
ch.pipeline().addAfter("eag-server-ws-ready", "eag-server-handler", new EaglerServerHandler(proxyConnection, c2p.attr(eagxPass).get()));
101+
doWsServerStuff(ch, proxyConnection, c2p, addr);
136102
}
137103
}
138104
}
139105

106+
private static void doWsServerStuff(Channel ch, NetClient proxyConnection, Channel c2p, ServerAddress addr) throws URISyntaxException {
107+
ch.attr(MCPipeline.COMPRESSION_THRESHOLD_ATTRIBUTE_KEY).set(-2);
108+
if (proxyConnection instanceof ProxyConnection && ((ProxyConnection) proxyConnection).getServerVersion().isNewerThan(VersionEnum.r1_6_4)) {
109+
ch.pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
110+
} else if (ch.pipeline().get(MCPipeline.ENCRYPTION_HANDLER_NAME) != null) {
111+
ch.pipeline().remove(MCPipeline.ENCRYPTION_HANDLER_NAME);
112+
}
113+
StringBuilder url = new StringBuilder("ws");
114+
boolean secure = c2p.attr(secureWs).get();
115+
if (secure) {
116+
final SSLEngine sslEngine = sc.createSSLEngine(addr.getAddress(), addr.getPort());
117+
sslEngine.setUseClientMode(true);
118+
sslEngine.setNeedClientAuth(false);
119+
ch.pipeline().addFirst("eag-server-ssl", new SslHandler(sslEngine));
120+
url.append("s");
121+
ch.pipeline().addAfter("eag-server-ssl", "eag-server-http-codec", new HttpClientCodec());
122+
} else {
123+
ch.pipeline().addFirst("eag-server-http-codec", new HttpClientCodec());
124+
}
125+
url.append("://").append(addr.getAddress());
126+
boolean addPort = (secure && addr.getPort() != 443) || (!secure && addr.getPort() != 80);
127+
if (addPort) {
128+
url.append(":").append(addr.getPort());
129+
}
130+
String path = c2p.attr(wsPath).get();
131+
if (path != null) {
132+
url.append("/").append(path);
133+
}
134+
URI uri = new URI(url.toString());
135+
HttpHeaders headers = new DefaultHttpHeaders();
136+
headers.set(HttpHeaderNames.HOST, uri.getHost() + (addPort ? ":" + uri.getPort() : ""));
137+
headers.set(HttpHeaderNames.ORIGIN, "via.shhnowisnottheti.me");
138+
ch.pipeline().addAfter("eag-server-http-codec", "eag-server-http-aggregator", new HttpObjectAggregator(2097152, true));
139+
ch.pipeline().addAfter("eag-server-http-aggregator", "eag-server-ws-compression", WebSocketClientCompressionHandler.INSTANCE);
140+
ch.pipeline().addAfter("eag-server-ws-compression", "eag-server-ws-handshaker", new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, headers, 2097152)));
141+
ch.pipeline().addAfter("eag-server-ws-handshaker", "eag-server-ws-ready", new WebSocketConnectedNotifier());
142+
ch.pipeline().addAfter("eag-server-ws-ready", "eag-server-handler", new EaglerServerHandler(proxyConnection, c2p.attr(eagxPass).get()));
143+
}
144+
140145
@EventHandler
141146
public void onEvent(final Client2ProxyChannelInitializeEvent event) {
142147
if (event.isLegacyPassthrough()) return;
143148
if (event.getType() == ITyped.Type.PRE) {
144149
event.getChannel().pipeline().addLast("eaglercraft-initial-handler", new EaglercraftInitialHandler());
145150
}
146-
if (event.getType() == ITyped.Type.POST && FunnyConfig.eaglerUtils) {
151+
if (event.getType() == ITyped.Type.POST) {
147152
event.getChannel().pipeline().addAfter("eaglercraft-initial-handler", "ayun-eag-detector", new EaglerConnectionHandler());
148153
}
149154
}
@@ -154,7 +159,9 @@ public void userEventTriggered(final ChannelHandlerContext ctx, final Object evt
154159
super.userEventTriggered(ctx, evt);
155160
if (evt instanceof EaglercraftInitialHandler.EaglercraftClientConnected) {
156161
ctx.pipeline().remove("ayun-eag-detector");
157-
ctx.pipeline().addBefore("eaglercraft-handler", "ayun-eag-utils-init", new EaglerUtilsInitHandler());
162+
if (!ctx.channel().hasAttr(secureWs)) {
163+
ctx.pipeline().addBefore("eaglercraft-handler", "ayun-eag-utils-init", new EaglerUtilsInitHandler());
164+
}
158165
}
159166
}
160167

src/main/resources/vpeagutils.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Use premium skins
22
premium-skins: false
3-
# Handle Eagler skins and voice on the proxy side
4-
eagler-utils: true
53
# Sync Eagler skins
64
eagler-skins: true
75
# Enable Eagler voice chat

0 commit comments

Comments
 (0)