Skip to content

Commit

Permalink
Add support for encoding custom crafted packets with UnknownPacket
Browse files Browse the repository at this point in the history
  • Loading branch information
SupremeMortal committed Dec 7, 2019
1 parent 8e1dd77 commit a6cf11a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import gnu.trove.map.hash.TIntObjectHashMap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import lombok.AccessLevel;
Expand All @@ -32,7 +33,7 @@ public final class BedrockPacketCodec {
@Getter
private final String minecraftVersion;
private final PacketSerializer<BedrockPacket>[] serializers;
private final TIntHashBiMap<Class<BedrockPacket>> idBiMap;
private final TIntHashBiMap<Class<? extends BedrockPacket>> idBiMap;
private final PacketSerializer<PacketHeader> headerSerializer;

public static Builder builder() {
Expand Down Expand Up @@ -64,28 +65,35 @@ public BedrockPacket tryDecode(ByteBuf buf) throws PacketSerializeException {
return packet;
}

@SuppressWarnings("unchecked")
public ByteBuf tryEncode(BedrockPacket packet) throws PacketSerializeException {
PacketHeader header = packet.getHeader();
if (header == null) {
header = new PacketHeader();
}
int packetId = getId(packet);
header.setPacketId(packetId);

ByteBuf buf = PooledByteBufAllocator.DEFAULT.directBuffer();
try {
PacketHeader header = packet.getHeader();
if (header == null) {
header = new PacketHeader();
}

PacketSerializer<BedrockPacket> serializer;
if (packet instanceof UnknownPacket) {
serializer = (PacketSerializer<BedrockPacket>) packet;
} else {
int packetId = getId(packet.getClass());
header.setPacketId(packetId);
serializer = serializers[packetId];
}
headerSerializer.serialize(buf, header);
serializers[packetId].serialize(buf, packet);
serializer.serialize(buf, packet);
} catch (Exception e) {
buf.release();
throw new PacketSerializeException("Error whilst serializing " + packet.getClass().getSimpleName(), e);
} finally {
ReferenceCountUtil.release(packet);
}
return buf;
}

@SuppressWarnings("unchecked")
public int getId(BedrockPacket packet) {
Class<BedrockPacket> clazz = (Class<BedrockPacket>) packet.getClass();
public int getId(Class<? extends BedrockPacket> clazz) {
int id = idBiMap.get(clazz);
if (id == -1) {
throw new IllegalArgumentException("Packet ID for " + clazz.getName() + " does not exist.");
Expand All @@ -97,7 +105,7 @@ public int getId(BedrockPacket packet) {
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder {
private final TIntObjectMap<PacketSerializer<BedrockPacket>> serializers = new TIntObjectHashMap<>();
private final TIntHashBiMap<Class<BedrockPacket>> idBiMap = new TIntHashBiMap<>((Class) UnknownPacket.class);
private final TIntHashBiMap<Class<? extends BedrockPacket>> idBiMap = new TIntHashBiMap<>((Class) UnknownPacket.class);
private int protocolVersion = -1;
private String minecraftVersion = null;
private PacketSerializer<PacketHeader> headerSerializer = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void checkPacket(BedrockPacket packet) {
Preconditions.checkState(this.packetCodec != BedrockCompat.COMPAT_CODEC, "No PacketCodec is set!");

// Verify that the packet ID exists.
this.packetCodec.getId(packet);
this.packetCodec.getId(packet.getClass());
}

public void sendWrapped(Collection<BedrockPacket> packets, boolean encrypt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import com.nukkitx.protocol.serializer.PacketSerializer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.util.ReferenceCounted;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = true)
public final class UnknownPacket extends BedrockPacket implements PacketSerializer<UnknownPacket> {
public final class UnknownPacket extends BedrockPacket implements PacketSerializer<UnknownPacket>, ReferenceCounted {
private ByteBuf payload;

@Override
Expand All @@ -32,4 +33,54 @@ public String toString() {
public final boolean handle(BedrockPacketHandler handler) {
return false;
}

@Override
public int refCnt() {
if (this.payload == null) {
return 0;
}
return payload.refCnt();
}

@Override
public UnknownPacket retain() {
if (this.payload != null) {
this.payload.retain();
}
return this;
}

@Override
public UnknownPacket retain(int increment) {
if (this.payload != null) {
this.payload.retain(increment);
}
return this;
}

@Override
public UnknownPacket touch() {
if (this.payload != null) {
this.payload.touch();
}
return this;
}

@Override
public UnknownPacket touch(Object hint) {
if (this.payload != null) {
this.payload.touch(hint);
}
return this;
}

@Override
public boolean release() {
return this.payload == null || this.payload.release();
}

@Override
public boolean release(int decrement) {
return this.payload == null || this.payload.release(decrement);
}
}

0 comments on commit a6cf11a

Please sign in to comment.