использованы костыли для предотвращения "рваных" пакетоов
Пакеты иногда могут приходить не полностью, а кусками. Раньше из-за этого возникали ошибки декода пакетов, у которых данные обрывались.
This commit is contained in:
@@ -22,6 +22,7 @@ public abstract class NetInputStream {
|
||||
public abstract short readShort();
|
||||
public abstract int readInt();
|
||||
public abstract int readVarInt();
|
||||
public abstract int readVarInt(int[] countReadBytes);
|
||||
public abstract long readLong();
|
||||
public abstract float readFloat();
|
||||
public abstract double readDouble();
|
||||
|
||||
@@ -13,25 +13,31 @@ import java.util.UUID;
|
||||
@Slf4j
|
||||
public abstract class NetInputStream_p340 extends NetInputStream {
|
||||
@Override
|
||||
public int readVarInt() {
|
||||
public int readVarInt(int[] countReadBytes) {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
if ((numRead+1) > 5) {
|
||||
log.warn("VarInt is too big");
|
||||
break;
|
||||
}
|
||||
read = readByte();
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
log.warn("VarInt is too big");
|
||||
break;
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
if (countReadBytes != null && countReadBytes.length == 1) countReadBytes[0] = numRead;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readVarInt() {
|
||||
return readVarInt(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString() {
|
||||
int size = readVarInt();
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/*
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2018-06-10
|
||||
*/
|
||||
package mc.core.network.proto_1_12_2.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.ReplayingDecoder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.network.CSPacket;
|
||||
import mc.core.network.NetInputStream;
|
||||
@@ -18,7 +14,9 @@ import java.util.List;
|
||||
import static mc.core.network.proto_1_12_2.netty.NettyServer.ATTR_STATE;
|
||||
|
||||
@Slf4j
|
||||
public class PacketDecoder extends ByteToMessageDecoder {
|
||||
public class PacketDecoder extends ReplayingDecoder<CSPacket> {
|
||||
private int[] countReadBytes = new int[]{0};
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
ctx.channel().attr(ATTR_STATE).set(State.HANDSHAKE);
|
||||
@@ -33,27 +31,25 @@ public class PacketDecoder extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
log.debug("ByteBuf readableBytes: {}", in.readableBytes());
|
||||
|
||||
State state = ctx.channel().attr(ATTR_STATE).get();
|
||||
NetInputStream netStream = new WrapperNetInputStream(in);
|
||||
|
||||
int packetSize = netStream.readVarInt();
|
||||
log.debug("Packet size: {}", packetSize);
|
||||
int rb = in.readableBytes();
|
||||
int leftDataPacket = packetSize;
|
||||
|
||||
int packetId = netStream.readVarInt();
|
||||
int packetId = netStream.readVarInt(countReadBytes);
|
||||
String hexPacketId = Integer.toHexString(packetId).toUpperCase();
|
||||
if (hexPacketId.length() == 1) hexPacketId = "0" + hexPacketId;
|
||||
log.debug("Packet id: 0x{}", hexPacketId);
|
||||
rb = rb - in.readableBytes();
|
||||
leftDataPacket = leftDataPacket - countReadBytes[0];
|
||||
|
||||
Class<? extends CSPacket> packetClass = state.getClientSidePacket(packetId);
|
||||
if (packetClass == null) {
|
||||
log.warn("Unknown packet: {}:0x{}", state.name(), hexPacketId);
|
||||
in.skipBytes(in.readableBytes());
|
||||
in.skipBytes(leftDataPacket);
|
||||
} else {
|
||||
netStream.setDataSize(packetSize - rb);
|
||||
netStream.setDataSize(leftDataPacket);
|
||||
CSPacket packet = packetClass.newInstance();
|
||||
try {
|
||||
packet.readSelf(netStream);
|
||||
@@ -62,7 +58,7 @@ public class PacketDecoder extends ByteToMessageDecoder {
|
||||
} catch (Exception e) {
|
||||
log.warn("Known packet: {}:{}. But throw exception. See debug log.", state.name(), packet.getClass().getSimpleName());
|
||||
log.debug("Read packet", e);
|
||||
in.skipBytes(in.readableBytes());
|
||||
in.skipBytes(leftDataPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user