diff --git a/build.gradle b/build.gradle index 9a2ed62..676a480 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,8 @@ subprojects { } dependencies { + compile (group: 'org.jetbrains', name: 'annotations', version: '16.0.3') + /* Logger */ compile (group: 'org.slf4j', name: 'slf4j-api', version: slf4j_version) compile (group: 'org.slf4j', name: 'jcl-over-slf4j', version: slf4j_version) diff --git a/core/src/main/java/mc/core/network/NetInputStream.java b/core/src/main/java/mc/core/network/NetInputStream.java index 79a5cfc..9262610 100644 --- a/core/src/main/java/mc/core/network/NetInputStream.java +++ b/core/src/main/java/mc/core/network/NetInputStream.java @@ -3,10 +3,11 @@ package mc.core.network; import com.flowpowered.nbt.Tag; import lombok.Getter; import lombok.Setter; +import org.jetbrains.annotations.NotNull; -import java.io.IOException; import java.io.InputStream; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; public abstract class NetInputStream extends InputStream { @Getter @@ -24,7 +25,7 @@ public abstract class NetInputStream extends InputStream { public abstract short readShort(); public abstract int readInt(); public abstract int readVarInt(); - public abstract int readVarInt(int[] countReadBytes); + public abstract int readVarInt(AtomicInteger countReadBytes); public abstract long readLong(); public abstract float readFloat(); public abstract double readDouble(); @@ -35,22 +36,22 @@ public abstract class NetInputStream extends InputStream { public abstract void skipBytes(int count); @Override - public int read() throws IOException { + public int read() { return readByte(); } @Override - public int read(byte[] b) throws IOException { + public int read(@NotNull byte[] b) { return readBytes(b); } @Override - public int read(byte[] b, int off, int len) throws IOException { + public int read(@NotNull byte[] b, int off, int len) { return readBytes(b, off, len); } @Override - public long skip(long n) throws IOException { + public long skip(long n) { skipBytes((int) n); return n; } diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/NetInputStream_p340.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/NetInputStream_p340.java index 53472f7..6be6f48 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/NetInputStream_p340.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/NetInputStream_p340.java @@ -8,13 +8,14 @@ import mc.core.network.NetInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; @Slf4j public abstract class NetInputStream_p340 extends NetInputStream { private NBTInputStream nbtInputStream; @Override - public int readVarInt(int[] countReadBytes) { + public int readVarInt(AtomicInteger countReadBytes) { int numRead = 0; int result = 0; byte read; @@ -30,7 +31,10 @@ public abstract class NetInputStream_p340 extends NetInputStream { numRead++; } while ((read & 0b10000000) != 0); - if (countReadBytes != null && countReadBytes.length == 1) countReadBytes[0] = numRead; + if (countReadBytes != null) { + countReadBytes.set(numRead); + } + return result; } diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketDecoder.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketDecoder.java index 6115ced..585a88d 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketDecoder.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketDecoder.java @@ -10,21 +10,21 @@ import mc.core.network.proto_1_12_2.State; import mc.core.network.proto_1_12_2.netty.wrappers.WrapperNetInputStream; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import static mc.core.network.proto_1_12_2.netty.NettyServer.ATTR_STATE; @Slf4j public class PacketDecoder extends ReplayingDecoder { - private int[] countReadBytes = new int[]{0}; @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(ChannelHandlerContext ctx) { ctx.channel().attr(ATTR_STATE).set(State.HANDSHAKE); ctx.fireChannelActive(); } @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(ChannelHandlerContext ctx) { ctx.channel().attr(ATTR_STATE).set(null); ctx.fireChannelInactive(); } @@ -38,11 +38,12 @@ public class PacketDecoder extends ReplayingDecoder { log.debug("Packet size: {}", packetSize); int leftDataPacket = packetSize; + final AtomicInteger countReadBytes = new AtomicInteger(0); int packetId = netStream.readVarInt(countReadBytes); String hexPacketId = Integer.toHexString(packetId).toUpperCase(); if (hexPacketId.length() == 1) hexPacketId = "0" + hexPacketId; log.debug("Packet id: 0x{}", hexPacketId); - leftDataPacket = leftDataPacket - countReadBytes[0]; + leftDataPacket = leftDataPacket - countReadBytes.get(); Class packetClass = state.getClientSidePacket(packetId); if (packetClass == null) { diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketEncoder.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketEncoder.java index 324b9f7..9dbc4a9 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketEncoder.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketEncoder.java @@ -10,27 +10,14 @@ import io.netty.handler.codec.MessageToByteEncoder; import lombok.extern.slf4j.Slf4j; import mc.core.network.NetOutputStream; import mc.core.network.SCPacket; -import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream; import mc.core.network.proto_1_12_2.State; import mc.core.network.proto_1_12_2.netty.wrappers.WrapperNetOutputStream; -import org.slf4j.helpers.MessageFormatter; import static mc.core.network.proto_1_12_2.netty.NettyServer.ATTR_STATE; import static org.slf4j.helpers.MessageFormatter.format; @Slf4j public class PacketEncoder extends MessageToByteEncoder { - private static int sizeVarInt(final int value) { - byte size = 0; - int v = value; - - do { - v >>>= 7; - size++; - } while (v != 0); - - return size; - } @Override protected void encode(ChannelHandlerContext ctx, SCPacket packet, ByteBuf out) { @@ -44,14 +31,9 @@ public class PacketEncoder extends MessageToByteEncoder { log.debug("Send {}:{}", state, packet); try { - NetOutputStream netStream = new ByteArrayOutputNetStream(); - packet.writeSelf(netStream); - byte[] bytes = ((ByteArrayOutputNetStream) netStream).toByteArray(); - netStream = new WrapperNetOutputStream(out); - - netStream.writeVarInt(bytes.length + sizeVarInt(id)); + NetOutputStream netStream = new WrapperNetOutputStream(out); netStream.writeVarInt(id); - netStream.writeBytes(bytes); + packet.writeSelf(netStream); } catch (Throwable t) { log.error(format("Error encoding packet {}:{}", state, packet).getMessage(), t); } diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketPostEncoder.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketPostEncoder.java new file mode 100644 index 0000000..7e7b848 --- /dev/null +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PacketPostEncoder.java @@ -0,0 +1,38 @@ +package mc.core.network.proto_1_12_2.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import lombok.extern.slf4j.Slf4j; +import mc.core.network.proto_1_12_2.netty.wrappers.WrapperNetOutputStream; + +/** + * Подсчет размера отправляемого пакета + */ +@Slf4j +public class PacketPostEncoder extends MessageToByteEncoder { + + private static int getVarIntSize(int input) { + for (int i = 1; i < 5; ++i) { + if ((input & -1 << i * 7) == 0) { + return i; + } + } + + return 5; + } + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { + final int pktSize = msg.readableBytes(); + final int sizeOfPktSize = getVarIntSize(pktSize); + + if (sizeOfPktSize > 3) { + log.warn("unable to fit {} into {}", pktSize, 3); + } + + out.ensureWritable(sizeOfPktSize + pktSize); + (new WrapperNetOutputStream(out)).writeVarInt(pktSize); + out.writeBytes(msg); + } +}