diff --git a/src/main/java/mc/core/NetStream.java b/src/main/java/mc/core/NetStream.java new file mode 100644 index 0000000..da1db3b --- /dev/null +++ b/src/main/java/mc/core/NetStream.java @@ -0,0 +1,29 @@ +/* + * DmitriyMX + * 2018-03-28 + */ +package mc.core; + +public interface NetStream { + byte readByte(); + void writeByte(byte value); + + int readBytes(byte[] buffer); + void writeBytes(byte[] buffer); + + int readBytes(byte[] buffer, int offset, int length); + void writeBytes(byte[] buffer, int offset, int length); + + int readVarInt(); + void writeVarInt(int value); + + long readVarLong(); + void writeVarLong(long value); + + String readString(); + void writeString(String value); + + int readUnsignedShort(); + + void skipBytes(int count); +} diff --git a/src/main/java/mc/core/netty/PacketDecoder.java b/src/main/java/mc/core/netty/PacketDecoder.java index b8a8933..9e75969 100644 --- a/src/main/java/mc/core/netty/PacketDecoder.java +++ b/src/main/java/mc/core/netty/PacketDecoder.java @@ -8,20 +8,19 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ReplayingDecoder; import lombok.extern.slf4j.Slf4j; -import mc.core.Packet; +import mc.core.NetStream; import java.util.List; import java.util.Optional; -import java.util.StringJoiner; - -import static mc.core.netty.Utils.readVarInt; @Slf4j public class PacketDecoder extends ReplayingDecoder { @Override protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List list) throws Exception { - int length = readVarInt(byteBuf); - int id = readVarInt(byteBuf); + NetStream netStream = new WrapperByteBufNetStream(byteBuf); + + int length = netStream.readVarInt(); + int id = netStream.readVarInt(); log.debug("PktLEN: {} | PktID: {}", length, id); Optional> packetClass = context.channel().attr(State.ATTR_STATE).get().getPacketClass(id); diff --git a/src/main/java/mc/core/netty/Utils.java b/src/main/java/mc/core/netty/Utils.java index 115f274..c248151 100644 --- a/src/main/java/mc/core/netty/Utils.java +++ b/src/main/java/mc/core/netty/Utils.java @@ -4,72 +4,14 @@ */ package mc.core.netty; -import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import java.nio.charset.StandardCharsets; - @Slf4j public class Utils { - public static int readVarInt(ByteBuf byteBuf) { - int result = 0; - byte read; - int numRead = 0; - - do { - read = byteBuf.readByte(); - int value = (read & 0b01111111); - result |= (value << (7 * numRead)); - - numRead++; - if (numRead > 5) { - log.warn("VarInt is too big"); - break; - } - } while ((read & 0b10000000) != 0); - - return result; - } - - public static void writeVarInt(int value, ByteBuf byteBuf) { - writeVarLong(value, byteBuf); - } - public static int lengthVarInt(int value) { return lengthVarLong(value); } - public static long readVarLong(ByteBuf byteBuf) { - long result = 0; - byte read; - int numRead = 0; - - do { - read = byteBuf.readByte(); - int value = (read & 0b01111111); - result |= (value << (7 * numRead)); - - numRead++; - if (numRead > 10) { - log.warn("VarLong is too big"); - break; - } - } while ((read & 0b10000000) != 0); - - return result; - } - - public static void writeVarLong(long value, ByteBuf byteBuf) { - do { - byte temp = (byte)(value & 0b01111111); - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - byteBuf.writeByte(temp); - } while (value != 0); - } - public static int lengthVarLong(long value) { int result = 0; @@ -81,10 +23,6 @@ public class Utils { return result; } - public static int readUnsignedShort(ByteBuf byteBuf) { - return byteBuf.readUnsignedShort(); - } - public static int lengthUnsignedShort(int value) { int result = 0; @@ -96,22 +34,6 @@ public class Utils { return result; } - public static String readString(ByteBuf byteBuf) { - int length = readVarInt(byteBuf); - byte[] buffer = new byte[length]; - int i = 0; - do { - buffer[i++] = byteBuf.readByte(); - } while (i < length); - - return new String(buffer, StandardCharsets.UTF_8); - } - - public static void writeString(String value, ByteBuf byteBuf) { - writeVarInt(value.length(), byteBuf); - byteBuf.writeBytes(value.getBytes()); - } - public static int lengthString(String value) { return lengthVarInt(value.length()) + value.length(); } diff --git a/src/main/java/mc/core/netty/WrapperByteBufNetStream.java b/src/main/java/mc/core/netty/WrapperByteBufNetStream.java new file mode 100644 index 0000000..331d0ef --- /dev/null +++ b/src/main/java/mc/core/netty/WrapperByteBufNetStream.java @@ -0,0 +1,139 @@ +/* + * DmitriyMX + * 2018-03-28 + */ +package mc.core.netty; + +import io.netty.buffer.ByteBuf; +import lombok.RequiredArgsConstructor; +import mc.core.NetStream; + +import java.nio.charset.StandardCharsets; + +@RequiredArgsConstructor +public class WrapperByteBufNetStream implements NetStream { + private final ByteBuf byteBuf; + + @Override + public byte readByte() { + return byteBuf.readByte(); + } + + @Override + public void writeByte(byte value) { + byteBuf.writeByte(value); + } + + @Override + public int readBytes(byte[] buffer) { + return byteBuf.readBytes(buffer).readableBytes(); + } + + @Override + public void writeBytes(byte[] buffer) { + byteBuf.writeBytes(buffer); + } + + @Override + public int readBytes(byte[] buffer, int offset, int length) { + return byteBuf.writeBytes(buffer, offset, length).readableBytes(); + } + + @Override + public void writeBytes(byte[] buffer, int offset, int length) { + byteBuf.writeBytes(buffer, offset, length); + } + + @Override + public int readVarInt() { + int result = 0; + byte read; + int numRead = 0; + + do { + read = byteBuf.readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + if (++numRead > 5) { + break; + } + } while ((read & 0b10000000) != 0); + + return result; + } + + @Override + public void writeVarInt(final int value) { + int v = value; + do { + byte write = (byte)(v & 0b01111111); + v >>>= 7; + if (v != 0) { + write |= 0b10000000; + } + byteBuf.writeByte(write); + } while (v != 0); + } + + @Override + public long readVarLong() { + long result = 0; + byte read; + int numRead = 0; + + do { + read = byteBuf.readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 10) { + break; + } + } while ((read & 0b10000000) != 0); + + return result; + } + + @Override + public void writeVarLong(final long value) { + long v = value; + do { + byte write = (byte)(v & 0b01111111); + v >>>= 7; + if (v != 0) { + write |= 0b10000000; + } + byteBuf.writeByte(write); + } while (v != 0); + } + + @Override + public String readString() { + int length = readVarInt(); + byte[] buffer = new byte[length]; + int i = 0; + do { + buffer[i++] = byteBuf.readByte(); + } while (i < length); + + return new String(buffer, StandardCharsets.UTF_8); + } + + @Override + public void writeString(String value) { + writeVarInt(value.length()); + byteBuf.writeBytes(value.getBytes()); + } + + @Override + public int readUnsignedShort() { + return byteBuf.readUnsignedShort(); + } + + @Override + public void skipBytes(int count) { + byteBuf.skipBytes(count); + } +} diff --git a/src/main/java/mc/core/netty/packets/HandshakeRequestPacket.java b/src/main/java/mc/core/netty/packets/HandshakeRequestPacket.java index 5f18c84..a401c19 100644 --- a/src/main/java/mc/core/netty/packets/HandshakeRequestPacket.java +++ b/src/main/java/mc/core/netty/packets/HandshakeRequestPacket.java @@ -7,12 +7,12 @@ package mc.core.netty.packets; import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.ToString; +import mc.core.NetStream; import mc.core.NotSupportException; import mc.core.netty.NettyPacket; import mc.core.netty.State; import mc.core.netty.UnknowState; - -import java.util.Optional; +import mc.core.netty.WrapperByteBufNetStream; import static mc.core.netty.Utils.*; @@ -33,10 +33,12 @@ public class HandshakeRequestPacket implements NettyPacket { @Override public void fillFromByteBuf(ByteBuf byteBuf) { - protocolVersion = readVarInt(byteBuf); - serverAddress = readString(byteBuf); - serverPort = readUnsignedShort(byteBuf); - final int nextStateInt = readVarInt(byteBuf); + NetStream netStream = new WrapperByteBufNetStream(byteBuf); + + protocolVersion = netStream.readVarInt(); + serverAddress = netStream.readString(); + serverPort = netStream.readUnsignedShort(); + final int nextStateInt = netStream.readVarInt(); nextState = State.getById(nextStateInt).orElseThrow(() -> new UnknowState(nextStateInt)); byteBuf.skipBytes(2); //TODO magic diff --git a/src/main/java/mc/core/netty/packets/HandshakeResponsePacket.java b/src/main/java/mc/core/netty/packets/HandshakeResponsePacket.java index f89fa0c..3c4074b 100644 --- a/src/main/java/mc/core/netty/packets/HandshakeResponsePacket.java +++ b/src/main/java/mc/core/netty/packets/HandshakeResponsePacket.java @@ -6,8 +6,10 @@ package mc.core.netty.packets; import com.google.gson.JsonObject; import io.netty.buffer.ByteBuf; +import mc.core.NetStream; import mc.core.NotSupportException; import mc.core.netty.NettyPacket; +import mc.core.netty.WrapperByteBufNetStream; import static mc.core.netty.Utils.*; @@ -41,9 +43,11 @@ public class HandshakeResponsePacket implements NettyPacket { @Override public void writeSelf(ByteBuf byteBuf) { - writeVarInt(getSize(), byteBuf); - writeVarInt(getId(), byteBuf); - writeString(json, byteBuf); + NetStream netStream = new WrapperByteBufNetStream(byteBuf); + + netStream.writeVarInt(getSize()); + netStream.writeVarInt(getId()); + netStream.writeString(json); } @Override diff --git a/src/main/java/mc/core/netty/packets/PingPacket.java b/src/main/java/mc/core/netty/packets/PingPacket.java index e16eff9..2485118 100644 --- a/src/main/java/mc/core/netty/packets/PingPacket.java +++ b/src/main/java/mc/core/netty/packets/PingPacket.java @@ -6,7 +6,9 @@ package mc.core.netty.packets; import io.netty.buffer.ByteBuf; import lombok.ToString; +import mc.core.NetStream; import mc.core.netty.NettyPacket; +import mc.core.netty.WrapperByteBufNetStream; import static mc.core.netty.Utils.*; @@ -18,17 +20,21 @@ public class PingPacket implements NettyPacket { @Override public void writeSelf(ByteBuf byteBuf) { + NetStream netStream = new WrapperByteBufNetStream(byteBuf); + long payload = System.currentTimeMillis(); int size = lengthVarLong(payload); - writeVarInt(size, byteBuf); - writeVarInt(id, byteBuf); - writeVarLong(payload, byteBuf); + netStream.writeVarInt(size); + netStream.writeVarInt(id); + netStream.writeVarLong(payload); } @Override public void fillFromByteBuf(ByteBuf byteBuf) { - payload = readVarLong(byteBuf); + NetStream netStream = new WrapperByteBufNetStream(byteBuf); + + payload = netStream.readVarLong(); size = lengthVarInt(id) + lengthVarLong(payload); }