Ping
This commit is contained in:
@@ -7,17 +7,22 @@ package mc.core.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.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import mc.core.Packet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
import static mc.core.netty.Utils.readVarInt;
|
import static mc.core.netty.Utils.readVarInt;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class PacketDecoder extends ReplayingDecoder<NettyPacket> {
|
public class PacketDecoder extends ReplayingDecoder<NettyPacket> {
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List<Object> list) throws Exception {
|
protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List<Object> list) throws Exception {
|
||||||
int length = readVarInt(byteBuf);
|
int length = readVarInt(byteBuf);
|
||||||
int id = readVarInt(byteBuf);
|
int id = readVarInt(byteBuf);
|
||||||
|
log.debug("PktLEN: {} | PktID: {}", length, id);
|
||||||
|
|
||||||
Optional<Class<? extends NettyPacket>> packetClass = context.channel().attr(State.ATTR_STATE).get().getPacketClass(id);
|
Optional<Class<? extends NettyPacket>> packetClass = context.channel().attr(State.ATTR_STATE).get().getPacketClass(id);
|
||||||
|
|
||||||
@@ -25,9 +30,16 @@ public class PacketDecoder extends ReplayingDecoder<NettyPacket> {
|
|||||||
NettyPacket packet = packetClass.get().newInstance();
|
NettyPacket packet = packetClass.get().newInstance();
|
||||||
packet.fillFromByteBuf(byteBuf);
|
packet.fillFromByteBuf(byteBuf);
|
||||||
list.add(packet);
|
list.add(packet);
|
||||||
|
if (length < packet.getSize()) {
|
||||||
|
log.warn("WTF?! length < packet.getSize() !!");
|
||||||
|
log.warn("Packet size: {}", packet.getSize());
|
||||||
|
} else if (length > packet.getSize()) {
|
||||||
|
log.debug("skipBytes {}", length - packet.getSize());
|
||||||
|
byteBuf.skipBytes(length - packet.getSize());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
list.add(new UnknownPacket(length, id));
|
list.add(new UnknownPacket(length, id));
|
||||||
byteBuf.skipBytes(length);
|
byteBuf.skipBytes(length-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ package mc.core.netty;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import mc.core.netty.packets.HandshakeRequestPacket;
|
||||||
|
import mc.core.netty.packets.HandshakeResponsePacket;
|
||||||
|
|
||||||
import static mc.core.netty.Utils.equalsPacket;
|
import static mc.core.netty.Utils.equalsPacket;
|
||||||
|
|
||||||
@@ -24,6 +26,8 @@ public class PacketHandler extends SimpleChannelInboundHandler<NettyPacket> {
|
|||||||
packet.toString());
|
packet.toString());
|
||||||
|
|
||||||
if (equalsPacket(packet, "HandshakeRequestPacket")) {
|
if (equalsPacket(packet, "HandshakeRequestPacket")) {
|
||||||
|
HandshakeRequestPacket pkt = (HandshakeRequestPacket) packet;
|
||||||
|
context.channel().attr(State.ATTR_STATE).set(pkt.getNextState());
|
||||||
context.channel().writeAndFlush(new HandshakeResponsePacket());
|
context.channel().writeAndFlush(new HandshakeResponsePacket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,19 @@ package mc.core.netty;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import mc.core.netty.packets.HandshakeRequestPacket;
|
||||||
|
import mc.core.netty.packets.PingPacket;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
Handshaking(1, ImmutableMap.of(0, HandshakeRequestPacket.class));
|
Handshaking(1, ImmutableMap.of(
|
||||||
|
0, HandshakeRequestPacket.class,
|
||||||
|
1, PingPacket.class
|
||||||
|
)),
|
||||||
|
Status(0, ImmutableMap.of(1, PingPacket.class));
|
||||||
|
|
||||||
public static final AttributeKey<State> ATTR_STATE = AttributeKey.newInstance("ATTR_STATE");
|
public static final AttributeKey<State> ATTR_STATE = AttributeKey.newInstance("ATTR_STATE");
|
||||||
|
|
||||||
|
|||||||
@@ -32,18 +32,45 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void writeVarInt(int value, ByteBuf byteBuf) {
|
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 {
|
do {
|
||||||
byte temp = (byte)(value & 0b01111111);
|
byte temp = (byte)(value & 0b01111111);
|
||||||
value >>>= 7;
|
value >>>= 7;
|
||||||
if (value != 0) {
|
if (value != 0) {
|
||||||
temp |= 0b10000000;
|
temp |= 0b10000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuf.writeByte(temp);
|
byteBuf.writeByte(temp);
|
||||||
} while (value != 0);
|
} while (value != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lengthVarInt(int value) {
|
public static int lengthVarLong(long value) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -54,8 +81,19 @@ public class Utils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lengthString(String value) {
|
public static int readUnsignedShort(ByteBuf byteBuf) {
|
||||||
return lengthVarInt(value.length()) + value.length();
|
return byteBuf.readUnsignedShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int lengthUnsignedShort(int value) {
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
value >>>= 8;
|
||||||
|
result++;
|
||||||
|
} while (value != 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String readString(ByteBuf byteBuf) {
|
public static String readString(ByteBuf byteBuf) {
|
||||||
@@ -69,15 +107,15 @@ public class Utils {
|
|||||||
return new String(buffer, StandardCharsets.UTF_8);
|
return new String(buffer, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int readUnsignedShort(ByteBuf byteBuf) {
|
|
||||||
return byteBuf.readUnsignedShort();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void writeString(String value, ByteBuf byteBuf) {
|
public static void writeString(String value, ByteBuf byteBuf) {
|
||||||
writeVarInt(value.length(), byteBuf);
|
writeVarInt(value.length(), byteBuf);
|
||||||
byteBuf.writeBytes(value.getBytes());
|
byteBuf.writeBytes(value.getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int lengthString(String value) {
|
||||||
|
return lengthVarInt(value.length()) + value.length();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean equalsPacket(NettyPacket packet, String name) {
|
public static boolean equalsPacket(NettyPacket packet, String name) {
|
||||||
return packet.getClass().getSimpleName().equals(name);
|
return packet.getClass().getSimpleName().equals(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@
|
|||||||
* DmitriyMX <dimon550@gmail.com>
|
* DmitriyMX <dimon550@gmail.com>
|
||||||
* 2018-03-25
|
* 2018-03-25
|
||||||
*/
|
*/
|
||||||
package mc.core.netty;
|
package mc.core.netty.packets;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import mc.core.NotSupportException;
|
import mc.core.NotSupportException;
|
||||||
|
import mc.core.netty.NettyPacket;
|
||||||
|
import mc.core.netty.State;
|
||||||
|
import mc.core.netty.UnknowState;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -35,11 +38,12 @@ public class HandshakeRequestPacket implements NettyPacket {
|
|||||||
serverPort = readUnsignedShort(byteBuf);
|
serverPort = readUnsignedShort(byteBuf);
|
||||||
final int nextStateInt = readVarInt(byteBuf);
|
final int nextStateInt = readVarInt(byteBuf);
|
||||||
nextState = State.getById(nextStateInt).orElseThrow(() -> new UnknowState(nextStateInt));
|
nextState = State.getById(nextStateInt).orElseThrow(() -> new UnknowState(nextStateInt));
|
||||||
|
byteBuf.skipBytes(2); //TODO magic
|
||||||
|
|
||||||
size = lengthVarInt(id)
|
size = lengthVarInt(id)
|
||||||
+ lengthVarInt(protocolVersion)
|
+ lengthVarInt(protocolVersion)
|
||||||
+ lengthString(serverAddress)
|
+ lengthString(serverAddress)
|
||||||
+ lengthVarInt(serverPort)
|
+ lengthUnsignedShort(serverPort)
|
||||||
+ lengthVarInt(nextState.getId());
|
+ lengthVarInt(nextState.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,11 +2,12 @@
|
|||||||
* DmitriyMX <dimon550@gmail.com>
|
* DmitriyMX <dimon550@gmail.com>
|
||||||
* 2018-03-25
|
* 2018-03-25
|
||||||
*/
|
*/
|
||||||
package mc.core.netty;
|
package mc.core.netty.packets;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import mc.core.NotSupportException;
|
import mc.core.NotSupportException;
|
||||||
|
import mc.core.netty.NettyPacket;
|
||||||
|
|
||||||
import static mc.core.netty.Utils.*;
|
import static mc.core.netty.Utils.*;
|
||||||
|
|
||||||
45
src/main/java/mc/core/netty/packets/PingPacket.java
Normal file
45
src/main/java/mc/core/netty/packets/PingPacket.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dimon550@gmail.com>
|
||||||
|
* 2018-03-26
|
||||||
|
*/
|
||||||
|
package mc.core.netty.packets;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.ToString;
|
||||||
|
import mc.core.netty.NettyPacket;
|
||||||
|
|
||||||
|
import static mc.core.netty.Utils.*;
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
public class PingPacket implements NettyPacket {
|
||||||
|
private static final int id = 1;
|
||||||
|
private long payload;
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSelf(ByteBuf byteBuf) {
|
||||||
|
long payload = System.currentTimeMillis();
|
||||||
|
int size = lengthVarLong(payload);
|
||||||
|
|
||||||
|
writeVarInt(size, byteBuf);
|
||||||
|
writeVarInt(id, byteBuf);
|
||||||
|
writeVarLong(payload, byteBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillFromByteBuf(ByteBuf byteBuf) {
|
||||||
|
payload = readVarLong(byteBuf);
|
||||||
|
size = lengthVarInt(id)
|
||||||
|
+ lengthVarLong(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user