использованы костыли для предотвращения "рваных" пакетоов
Пакеты иногда могут приходить не полностью, а кусками. Раньше из-за этого возникали ошибки декода пакетов, у которых данные обрывались.
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user