diff --git a/pom.xml b/pom.xml index b8d37ffb3..5c9c047d9 100644 --- a/pom.xml +++ b/pom.xml @@ -99,10 +99,5 @@ jcl-core 2.8 - - io.netty - netty-all - 4.1.52.Final - diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/netty/NettyNetwork.java b/src/main/java/de/bixilon/minosoft/protocol/network/netty/NettyNetwork.java deleted file mode 100644 index f7f7b272d..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/network/netty/NettyNetwork.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.network.netty; - -import de.bixilon.minosoft.logging.Log; -import de.bixilon.minosoft.protocol.network.Connection; -import de.bixilon.minosoft.protocol.network.Network; -import de.bixilon.minosoft.protocol.packets.ServerboundPacket; -import de.bixilon.minosoft.protocol.protocol.ConnectionStates; -import de.bixilon.minosoft.util.ServerAddress; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.ChannelFuture; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; - -import javax.crypto.SecretKey; - -public class NettyNetwork implements Network { - final Connection connection; - NioSocketChannel nioSocketChannel; - int compressionThreshold = -1; - - public NettyNetwork(Connection connection) { - this.connection = connection; - } - - @Override - public void connect(ServerAddress address) { - EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); - - Bootstrap clientBootstrap = new Bootstrap(); - clientBootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new TCPClientChannelInitializer(connection, this)); - - try { - ChannelFuture channelFuture = clientBootstrap.connect(address.getHostname(), address.getPort()).sync(); - if (channelFuture.isSuccess()) { - connection.setConnectionState(ConnectionStates.HANDSHAKING); - } - channelFuture.channel().closeFuture().sync(); - } catch (InterruptedException e) { - Log.info(String.format("connection failed: %s", e)); - connection.setConnectionState(ConnectionStates.FAILED); - } finally { - connection.setConnectionState(ConnectionStates.DISCONNECTED); - eventLoopGroup.shutdownGracefully(); - } - } - - @Override - public void sendPacket(ServerboundPacket packet) { - if (this.nioSocketChannel.eventLoop().inEventLoop()) { - this.nioSocketChannel.writeAndFlush(packet); - return; - } - this.nioSocketChannel.eventLoop().execute(() -> NettyNetwork.this.nioSocketChannel.writeAndFlush(packet)); - } - - @Override - public void disconnect() { - - } - - @Override - public Exception getLastException() { - return null; - } - - public int getCompressionThreshold() { - return compressionThreshold; - } - - public void setNioChannel(NioSocketChannel nioSocketChannel) { - this.nioSocketChannel = nioSocketChannel; - } - - public void enableEncryption(SecretKey key) { - /* - this.nioSocketChannel.pipeline().addBefore("decoder", "decrypt", new EncryptionHandler(key)); - this.nioSocketChannel.pipeline().addBefore("encoder", "encrypt", new DecryptionHandler(key)); - Log.debug("Encryption enabled!"); - */ - //ToDo - Log.fatal("Encryption is not implemented in netty yet!"); - disconnect(); - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketDecoder.java b/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketDecoder.java deleted file mode 100644 index 1369535d4..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketDecoder.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.network.netty; - -import de.bixilon.minosoft.logging.Log; -import de.bixilon.minosoft.logging.LogLevels; -import de.bixilon.minosoft.protocol.network.Connection; -import de.bixilon.minosoft.protocol.packets.ClientboundPacket; -import de.bixilon.minosoft.protocol.packets.clientbound.interfaces.PacketCompressionInterface; -import de.bixilon.minosoft.protocol.packets.clientbound.login.PacketEncryptionRequest; -import de.bixilon.minosoft.protocol.packets.clientbound.login.PacketLoginSuccess; -import de.bixilon.minosoft.protocol.protocol.*; -import de.bixilon.minosoft.util.Util; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; - -import java.lang.reflect.InvocationTargetException; -import java.util.List; - -public class PacketDecoder extends ByteToMessageDecoder { - final Connection connection; - final NettyNetwork nettyNetwork; - - public PacketDecoder(Connection connection, NettyNetwork nettyNetwork) { - this.connection = connection; - this.nettyNetwork = nettyNetwork; - } - - @Override - protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) { - byteBuf.markReaderIndex(); - int numRead = 0; - int length = 0; - byte read; - do - { - if (!byteBuf.isReadable()) { - byteBuf.resetReaderIndex(); - return; - } - read = byteBuf.readByte(); - int value = (read & 0b01111111); - length |= (value << (7 * numRead)); - - numRead++; - if (numRead > 5) { - throw new RuntimeException("VarInt is too big"); - } - } while ((read & 0b10000000) != 0); - if (length > ProtocolDefinition.PROTOCOL_PACKET_MAX_SIZE) { - Log.protocol(String.format("Server sent us a to big packet (%d bytes > %d bytes)", length, ProtocolDefinition.PROTOCOL_PACKET_MAX_SIZE)); - byteBuf.skipBytes(length); - return; - } - if (byteBuf.readableBytes() < length) { - byteBuf.resetReaderIndex(); - return; - } - - byte[] data; - ByteBuf dataBuf = byteBuf.readBytes(length); - if (dataBuf.hasArray()) { - data = dataBuf.array(); - } else { - data = new byte[length]; - dataBuf.getBytes(0, data); - } - - if (nettyNetwork.getCompressionThreshold() >= 0) { - // compression is enabled - // check if there is a need to decompress it and if so, do it! - InByteBuffer rawBuffer = new InByteBuffer(data, connection); - int packetSize = rawBuffer.readVarInt(); - byte[] left = rawBuffer.readBytesLeft(); - if (packetSize == 0) { - // no need - data = left; - } else { - // need to decompress data - data = Util.decompress(left, connection).readBytesLeft(); - } - } - - InPacketBuffer inPacketBuffer = new InPacketBuffer(data, connection); - Packets.Clientbound packet = null; - try { - packet = connection.getPacketByCommand(connection.getConnectionState(), inPacketBuffer.getCommand()); - if (packet == null) { - Log.fatal(String.format("Packet mapping does not contain a packet with id 0x%x. The server sends bullshit or your versions.json broken!", inPacketBuffer.getCommand())); - nettyNetwork.disconnect(); - throw new RuntimeException(String.format("Invalid packet 0x%x", inPacketBuffer.getCommand())); - } - Class clazz = packet.getClazz(); - - if (clazz == null) { - Log.warn(String.format("[IN] Received unknown packet (id=0x%x, name=%s, length=%d, dataLength=%d, version=%s, state=%s)", inPacketBuffer.getCommand(), packet, inPacketBuffer.getLength(), inPacketBuffer.getBytesLeft(), connection.getVersion(), connection.getConnectionState())); - return; - } - try { - ClientboundPacket packetInstance = clazz.getConstructor().newInstance(); - boolean success = packetInstance.read(inPacketBuffer); - if (inPacketBuffer.getBytesLeft() > 0 || !success) { - // warn not all data used - Log.warn(String.format("[IN] Could not parse packet %s (used=%d, available=%d, total=%d, success=%s)", packet, inPacketBuffer.getPosition(), inPacketBuffer.getBytesLeft(), inPacketBuffer.getLength(), success)); - return; - } - - //set special settings to avoid miss timing issues - if (packetInstance instanceof PacketLoginSuccess) { - connection.setConnectionState(ConnectionStates.PLAY); - } else if (packetInstance instanceof PacketCompressionInterface) { - nettyNetwork.compressionThreshold = ((PacketCompressionInterface) packetInstance).getThreshold(); - } else if (packetInstance instanceof PacketEncryptionRequest) { - // wait until response is ready - list.add(packetInstance); - return; - } - list.add(packetInstance); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - // safety first, but will not occur - e.printStackTrace(); - } - } catch (Exception e) { - Log.protocol(String.format("An error occurred while parsing an packet (%s): %s", packet, e)); - if (Log.getLevel().ordinal() >= LogLevels.DEBUG.ordinal()) { - e.printStackTrace(); - } - } - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketEncoder.java b/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketEncoder.java deleted file mode 100644 index 818f52fa2..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketEncoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.network.netty; - -import de.bixilon.minosoft.protocol.network.Connection; -import de.bixilon.minosoft.protocol.packets.ServerboundPacket; -import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionResponse; -import de.bixilon.minosoft.protocol.protocol.OutByteBuffer; -import de.bixilon.minosoft.util.Util; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; - -public class PacketEncoder extends MessageToByteEncoder { - final Connection connection; - final NettyNetwork nettyNetwork; - - public PacketEncoder(Connection connection, NettyNetwork nettyNetwork) { - this.connection = connection; - this.nettyNetwork = nettyNetwork; - } - - @Override - protected void encode(ChannelHandlerContext channelHandlerContext, ServerboundPacket packet, ByteBuf byteBuf) throws Exception { - packet.log(); - byte[] data = packet.write(connection).getOutBytes(); - if (nettyNetwork.getCompressionThreshold() >= 0) { - // compression is enabled - // check if there is a need to compress it and if so, do it! - OutByteBuffer outRawBuffer = new OutByteBuffer(connection); - if (data.length >= nettyNetwork.getCompressionThreshold()) { - // compress it - OutByteBuffer compressedBuffer = new OutByteBuffer(connection); - byte[] compressed = Util.compress(data); - compressedBuffer.writeVarInt(data.length); - compressedBuffer.writeBytes(compressed); - outRawBuffer.prefixVarInt(compressedBuffer.getOutBytes().length); - } else { - outRawBuffer.prefixVarInt(0); - outRawBuffer.writeVarInt(data.length + 1); // 1 for the compressed length (0) - } - data = outRawBuffer.getOutBytes(); - } else { - // append packet length - OutByteBuffer bufferWithLengthPrefix = new OutByteBuffer(connection); - bufferWithLengthPrefix.writeVarInt(data.length); - bufferWithLengthPrefix.writeBytes(data); - data = bufferWithLengthPrefix.getOutBytes(); - } - byteBuf.writeBytes(data); - if (packet instanceof PacketEncryptionResponse) { - // enable encryption - nettyNetwork.enableEncryption(((PacketEncryptionResponse) packet).getSecretKey()); - } - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketReceiver.java b/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketReceiver.java deleted file mode 100644 index b077b48dc..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/network/netty/PacketReceiver.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.network.netty; - -import de.bixilon.minosoft.logging.Log; -import de.bixilon.minosoft.logging.LogLevels; -import de.bixilon.minosoft.protocol.network.Connection; -import de.bixilon.minosoft.protocol.packets.ClientboundPacket; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - -public class PacketReceiver extends SimpleChannelInboundHandler { - final Connection connection; - - public PacketReceiver(Connection connection) { - this.connection = connection; - } - - @Override - protected void channelRead0(ChannelHandlerContext channelHandlerContext, ClientboundPacket packet) { - try { - packet.log(); - packet.handle(connection.getHandler()); - } catch (Exception e) { - if (Log.getLevel().ordinal() >= LogLevels.DEBUG.ordinal()) { - e.printStackTrace(); - } - } - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/netty/TCPClientChannelInitializer.java b/src/main/java/de/bixilon/minosoft/protocol/network/netty/TCPClientChannelInitializer.java deleted file mode 100644 index 18b7d71da..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/network/netty/TCPClientChannelInitializer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.network.netty; - -import de.bixilon.minosoft.protocol.network.Connection; -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.handler.timeout.ReadTimeoutHandler; - -import java.util.concurrent.TimeUnit; - -public class TCPClientChannelInitializer extends ChannelInitializer { - final Connection connection; - final NettyNetwork nettyNetwork; - - public TCPClientChannelInitializer(Connection connection, NettyNetwork nettyNetwork) { - this.connection = connection; - this.nettyNetwork = nettyNetwork; - } - - @Override - protected void initChannel(NioSocketChannel socketChannel) { - nettyNetwork.setNioChannel(socketChannel); - socketChannel.pipeline().addLast("timeout", new ReadTimeoutHandler(ProtocolDefinition.SOCKET_TIMEOUT, TimeUnit.MILLISECONDS)); - socketChannel.pipeline().addLast("decoder", new PacketDecoder(connection, nettyNetwork)); - socketChannel.pipeline().addLast("encoder", new PacketEncoder(connection, nettyNetwork)); - socketChannel.pipeline().addLast(new PacketReceiver(connection)); - } -}