diff --git a/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 5fe481589..7e0ddd0a7 100644 --- a/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -3,6 +3,7 @@ package com.velocitypowered.proxy.connection.backend; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packets.Disconnect; +import com.velocitypowered.proxy.protocol.packets.EncryptionRequest; import com.velocitypowered.proxy.protocol.packets.ServerLoginSuccess; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.packets.SetCompression; @@ -16,6 +17,10 @@ public class LoginSessionHandler implements MinecraftSessionHandler { @Override public void handle(MinecraftPacket packet) { + if (packet instanceof EncryptionRequest) { + throw new IllegalStateException("Backend server is online-mode!"); + } + if (packet instanceof Disconnect) { Disconnect disconnect = (Disconnect) packet; connection.disconnect(); @@ -35,4 +40,9 @@ public class LoginSessionHandler implements MinecraftSessionHandler { connection.getChannel().setSessionHandler(new PlaySessionHandler(connection)); } } + + @Override + public void exception(Throwable throwable) { + connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), throwable); + } } diff --git a/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java index b9eb04723..1f68f3066 100644 --- a/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java +++ b/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java @@ -49,4 +49,21 @@ public enum ProtocolUtils { ; writeVarInt(buf, asUtf8.length); buf.writeBytes(asUtf8); } + + public static byte[] readByteArray(ByteBuf buf) { + return readByteArray(buf, DEFAULT_MAX_STRING_SIZE); + } + + public static byte[] readByteArray(ByteBuf buf, int cap) { + int length = readVarInt(buf); + Preconditions.checkArgument(length <= cap, "Bad string size (got %s, maximum is %s)", length, cap); + byte[] array = new byte[length]; + buf.readBytes(array); + return array; + } + + public static void writeByteArray(ByteBuf buf, byte[] array) { + writeVarInt(buf, array.length); + buf.writeBytes(array); + } } diff --git a/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index b16b224f4..89df63337 100644 --- a/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -36,7 +36,7 @@ public enum StateRegistry { TO_SERVER.register(0x00, ServerLogin.class, ServerLogin::new); TO_CLIENT.register(0x00, Disconnect.class, Disconnect::new); - // Encryption Success will follow once Mojang auth/encryption is done + TO_CLIENT.register(0x01, EncryptionRequest.class, EncryptionRequest::new); TO_CLIENT.register(0x02, ServerLoginSuccess.class, ServerLoginSuccess::new); TO_CLIENT.register(0x03, SetCompression.class, SetCompression::new); } diff --git a/src/main/java/com/velocitypowered/proxy/protocol/packets/EncryptionRequest.java b/src/main/java/com/velocitypowered/proxy/protocol/packets/EncryptionRequest.java new file mode 100644 index 000000000..509621dca --- /dev/null +++ b/src/main/java/com/velocitypowered/proxy/protocol/packets/EncryptionRequest.java @@ -0,0 +1,51 @@ +package com.velocitypowered.proxy.protocol.packets; + +import com.velocitypowered.proxy.protocol.MinecraftPacket; +import com.velocitypowered.proxy.protocol.ProtocolConstants; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import io.netty.buffer.ByteBuf; + +import java.util.Arrays; + +public class EncryptionRequest implements MinecraftPacket { + private byte[] publicKey; + private byte[] verifyToken; + + public byte[] getPublicKey() { + return publicKey; + } + + public void setPublicKey(byte[] publicKey) { + this.publicKey = publicKey; + } + + public byte[] getVerifyToken() { + return verifyToken; + } + + public void setVerifyToken(byte[] verifyToken) { + this.verifyToken = verifyToken; + } + + @Override + public String toString() { + return "EncryptionRequest{" + + "publicKey=" + Arrays.toString(publicKey) + + ", verifyToken=" + Arrays.toString(verifyToken) + + '}'; + } + + @Override + public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { + ProtocolUtils.readString(buf); // Server ID, can be ignored since it is an empty string + publicKey = ProtocolUtils.readByteArray(buf, 256); + verifyToken = ProtocolUtils.readByteArray(buf, 16); + } + + @Override + public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { + ProtocolUtils.writeString(buf, ""); // Server ID + ProtocolUtils.writeByteArray(buf, publicKey); + ProtocolUtils.writeByteArray(buf, verifyToken); + } +}