Archived
0

использованы костыли для предотвращения "рваных" пакетоов

Пакеты иногда могут приходить не полностью, а кусками. Раньше из-за этого
возникали ошибки декода пакетов, у которых данные обрывались.
This commit is contained in:
2018-09-16 22:18:36 +03:00
parent 3ee1b16c92
commit 30d15cfa0f
3 changed files with 22 additions and 19 deletions

View File

@@ -22,6 +22,7 @@ public abstract class NetInputStream {
public abstract short readShort(); public abstract short readShort();
public abstract int readInt(); public abstract int readInt();
public abstract int readVarInt(); public abstract int readVarInt();
public abstract int readVarInt(int[] countReadBytes);
public abstract long readLong(); public abstract long readLong();
public abstract float readFloat(); public abstract float readFloat();
public abstract double readDouble(); public abstract double readDouble();

View File

@@ -13,25 +13,31 @@ import java.util.UUID;
@Slf4j @Slf4j
public abstract class NetInputStream_p340 extends NetInputStream { public abstract class NetInputStream_p340 extends NetInputStream {
@Override @Override
public int readVarInt() { public int readVarInt(int[] countReadBytes) {
int numRead = 0; int numRead = 0;
int result = 0; int result = 0;
byte read; byte read;
do { do {
if ((numRead+1) > 5) {
log.warn("VarInt is too big");
break;
}
read = readByte(); read = readByte();
int value = (read & 0b01111111); int value = (read & 0b01111111);
result |= (value << (7 * numRead)); result |= (value << (7 * numRead));
numRead++; numRead++;
if (numRead > 5) {
log.warn("VarInt is too big");
break;
}
} while ((read & 0b10000000) != 0); } while ((read & 0b10000000) != 0);
if (countReadBytes != null && countReadBytes.length == 1) countReadBytes[0] = numRead;
return result; return result;
} }
@Override
public int readVarInt() {
return readVarInt(null);
}
@Override @Override
public String readString() { public String readString() {
int size = readVarInt(); int size = readVarInt();

View File

@@ -1,12 +1,8 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-06-10
*/
package mc.core.network.proto_1_12_2.netty; package mc.core.network.proto_1_12_2.netty;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ReplayingDecoder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.network.CSPacket; import mc.core.network.CSPacket;
import mc.core.network.NetInputStream; 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; import static mc.core.network.proto_1_12_2.netty.NettyServer.ATTR_STATE;
@Slf4j @Slf4j
public class PacketDecoder extends ByteToMessageDecoder { public class PacketDecoder extends ReplayingDecoder<CSPacket> {
private int[] countReadBytes = new int[]{0};
@Override @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.channel().attr(ATTR_STATE).set(State.HANDSHAKE); ctx.channel().attr(ATTR_STATE).set(State.HANDSHAKE);
@@ -33,27 +31,25 @@ public class PacketDecoder extends ByteToMessageDecoder {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { 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(); State state = ctx.channel().attr(ATTR_STATE).get();
NetInputStream netStream = new WrapperNetInputStream(in); NetInputStream netStream = new WrapperNetInputStream(in);
int packetSize = netStream.readVarInt(); int packetSize = netStream.readVarInt();
log.debug("Packet size: {}", packetSize); 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(); String hexPacketId = Integer.toHexString(packetId).toUpperCase();
if (hexPacketId.length() == 1) hexPacketId = "0" + hexPacketId; if (hexPacketId.length() == 1) hexPacketId = "0" + hexPacketId;
log.debug("Packet id: 0x{}", hexPacketId); log.debug("Packet id: 0x{}", hexPacketId);
rb = rb - in.readableBytes(); leftDataPacket = leftDataPacket - countReadBytes[0];
Class<? extends CSPacket> packetClass = state.getClientSidePacket(packetId); Class<? extends CSPacket> packetClass = state.getClientSidePacket(packetId);
if (packetClass == null) { if (packetClass == null) {
log.warn("Unknown packet: {}:0x{}", state.name(), hexPacketId); log.warn("Unknown packet: {}:0x{}", state.name(), hexPacketId);
in.skipBytes(in.readableBytes()); in.skipBytes(leftDataPacket);
} else { } else {
netStream.setDataSize(packetSize - rb); netStream.setDataSize(leftDataPacket);
CSPacket packet = packetClass.newInstance(); CSPacket packet = packetClass.newInstance();
try { try {
packet.readSelf(netStream); packet.readSelf(netStream);
@@ -62,7 +58,7 @@ public class PacketDecoder extends ByteToMessageDecoder {
} catch (Exception e) { } catch (Exception e) {
log.warn("Known packet: {}:{}. But throw exception. See debug log.", state.name(), packet.getClass().getSimpleName()); log.warn("Known packet: {}:{}. But throw exception. See debug log.", state.name(), packet.getClass().getSimpleName());
log.debug("Read packet", e); log.debug("Read packet", e);
in.skipBytes(in.readableBytes()); in.skipBytes(leftDataPacket);
} }
} }
} }