diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/MinecraftPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/MinecraftPacket.java index e54ee770..1722f42b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/MinecraftPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/MinecraftPacket.java @@ -32,13 +32,18 @@ public interface MinecraftPacket { boolean handle(MinecraftSessionHandler handler); - default int expectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, + default int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return -1; } - default int expectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction, + default int decodeExpectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 0; } + + default int encodeSizeHint(ProtocolUtils.Direction direction, + ProtocolVersion version) { + return -1; + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java index 6e8ba6ac..efc0ed17 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java @@ -292,6 +292,17 @@ public enum ProtocolUtils { return str; } + /** + * Determines the size of the written {@code str} if encoded as a VarInt-prefixed UTF-8 string. + * + * @param str the string to write + * @return the encoded size + */ + public static int stringSizeHint(CharSequence str) { + int size = ByteBufUtil.utf8Bytes(str); + return varIntBytes(size) + size; + } + /** * Writes the specified {@code str} to the {@code buf} with a VarInt prefix. * diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftDecoder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftDecoder.java index 5389de73..35ddccd5 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftDecoder.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftDecoder.java @@ -96,8 +96,8 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter { } private void doLengthSanityChecks(ByteBuf buf, MinecraftPacket packet) throws Exception { - int expectedMinLen = packet.expectedMinLength(buf, direction, registry.version); - int expectedMaxLen = packet.expectedMaxLength(buf, direction, registry.version); + int expectedMinLen = packet.decodeExpectedMinLength(buf, direction, registry.version); + int expectedMaxLen = packet.decodeExpectedMaxLength(buf, direction, registry.version); if (expectedMaxLen != -1 && buf.readableBytes() > expectedMaxLen) { throw handleOverflow(packet, expectedMaxLen, buf.readableBytes()); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftEncoder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftEncoder.java index 7133f1d2..4af366ce 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftEncoder.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftEncoder.java @@ -54,6 +54,19 @@ public class MinecraftEncoder extends MessageToByteEncoder { msg.encode(out, direction, registry.version); } + @Override + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, MinecraftPacket msg, + boolean preferDirect) throws Exception { + int hint = msg.encodeSizeHint(direction, registry.version); + if (hint < 0) { + return super.allocateBuffer(ctx, msg, preferDirect); + } + + int packetId = this.registry.getPacketId(msg); + int totalHint = ProtocolUtils.varIntBytes(packetId) + hint; + return preferDirect ? ctx.alloc().ioBuffer(totalHint) : ctx.alloc().heapBuffer(totalHint); + } + public void setProtocolVersion(final ProtocolVersion protocolVersion) { this.registry = state.getProtocolRegistry(direction, protocolVersion); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java index 1301ed5b..7d4d8d6d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftVarintFrameDecoder.java @@ -131,8 +131,8 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder { // We 'technically' have the incoming bytes of a payload here, and so, these can actually parse // the packet if needed, so, we'll take advantage of the existing methods - int expectedMinLen = packet.expectedMinLength(in, direction, registry.version); - int expectedMaxLen = packet.expectedMaxLength(in, direction, registry.version); + int expectedMinLen = packet.decodeExpectedMinLength(in, direction, registry.version); + int expectedMaxLen = packet.decodeExpectedMaxLength(in, direction, registry.version); if (expectedMaxLen != -1 && payloadLength > expectedMaxLen) { throw handleOverflow(packet, expectedMaxLen, in.readableBytes()); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java index 08fe23b2..d3fc3a82 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/AvailableCommandsPacket.java @@ -362,4 +362,12 @@ public class AvailableCommandsPacket implements MinecraftPacket { return builder.buildFuture(); } } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + // This is a very complex packet to encode. Paper 1.21.10 + Velocity with Spark has a size of + // 30,334, but this is likely on the lower side. We'll use 128KiB as a more realistically-sized + // amount. + return 128 * 1024; + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java index d6591e7b..fedb67a5 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/EncryptionResponsePacket.java @@ -107,7 +107,7 @@ public class EncryptionResponsePacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + public int decodeExpectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { // It turns out these come out to the same length, whether we're talking >=1.8 or not. // The length prefix always winds up being 2 bytes. int base = 256 + 2 + 2; @@ -123,8 +123,8 @@ public class EncryptionResponsePacket implements MinecraftPacket { } @Override - public int expectedMinLength(ByteBuf buf, Direction direction, ProtocolVersion version) { - int base = expectedMaxLength(buf, direction, version); + public int decodeExpectedMinLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + int base = decodeExpectedMaxLength(buf, direction, version); if (version.noLessThan(ProtocolVersion.MINECRAFT_1_19)) { // These are "optional" base -= 128 + 8; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java index 9eb7a93e..88cb3688 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HandshakePacket.java @@ -24,6 +24,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import io.netty.buffer.ByteBuf; public class HandshakePacket implements MinecraftPacket { @@ -108,14 +109,21 @@ public class HandshakePacket implements MinecraftPacket { } @Override - public int expectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction, + public int decodeExpectedMinLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 7; } @Override - public int expectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, + public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 9 + (MAXIMUM_HOSTNAME_LENGTH * 3); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + // We could compute an exact size, but 4KiB ought to be enough to encode all reasonable + // sizes of this packet. + return 4 * 1024; + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java index dad9e08d..16cf519b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginAcknowledgedPacket.java @@ -36,7 +36,7 @@ public class LoginAcknowledgedPacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, + public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 0; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java index 682785eb..2fa82e92 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -86,4 +87,9 @@ public class LoginPluginMessagePacket extends DeferredByteBufHolder implements M public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java index dee33c13..e7d9443d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginResponsePacket.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -88,4 +89,9 @@ public class LoginPluginResponsePacket extends DeferredByteBufHolder implements public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java index d78ed833..ecf2887f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/PluginMessagePacket.java @@ -23,6 +23,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @@ -143,4 +144,9 @@ public class PluginMessagePacket extends DeferredByteBufHolder implements Minecr public PluginMessagePacket touch(Object hint) { return (PluginMessagePacket) super.touch(hint); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java index 610462a9..325a3c9d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerDataPacket.java @@ -22,6 +22,7 @@ import com.velocitypowered.api.util.Favicon; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.Nullable; @@ -121,4 +122,9 @@ public class ServerDataPacket implements MinecraftPacket { public void setSecureChatEnforced(boolean secureChatEnforced) { this.secureChatEnforced = secureChatEnforced; } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return 8 * 1024; + } } \ No newline at end of file diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java index 74eabb5c..65693cd8 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginPacket.java @@ -150,7 +150,7 @@ public class ServerLoginPacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + public int decodeExpectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { // Accommodate the rare (but likely malicious) use of UTF-8 usernames, since it is technically // legal on the protocol level. int base = 1 + (16 * 3); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java index 1e70568f..322cd9b1 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java @@ -23,6 +23,7 @@ import com.velocitypowered.api.util.UuidUtils; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.util.VelocityProperties; import io.netty.buffer.ByteBuf; import java.util.List; @@ -132,4 +133,11 @@ public class ServerLoginSuccessPacket implements MinecraftPacket { public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + // We could compute an exact size, but 4KiB ought to be enough to encode all reasonable + // sizes of this packet. + return 4 * 1024; + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java index 2092b260..6b846c23 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerboundCustomClickActionPacket.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import io.netty.buffer.ByteBuf; @@ -45,4 +46,8 @@ public class ServerboundCustomClickActionPacket extends DeferredByteBufHolder im return handler.handle(this); } + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java index 15999e61..30236704 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusPingPacket.java @@ -44,12 +44,12 @@ public class StatusPingPacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + public int decodeExpectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { return 8; } @Override - public int expectedMinLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + public int decodeExpectedMinLength(ByteBuf buf, Direction direction, ProtocolVersion version) { return 8; } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java index 46dc0401..870d9909 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusRequestPacket.java @@ -53,7 +53,7 @@ public class StatusRequestPacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { + public int decodeExpectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { return 0; } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java index 8591fa03..20fada4b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/StatusResponsePacket.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import io.netty.buffer.ByteBuf; import org.checkerframework.checker.nullness.qual.Nullable; @@ -66,4 +67,9 @@ public class StatusResponsePacket implements MinecraftPacket { public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return ProtocolUtils.stringSizeHint(this.status); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java index 35bf4a96..9ef40ef0 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/UpsertPlayerInfoPacket.java @@ -36,6 +36,8 @@ import org.jetbrains.annotations.Nullable; public class UpsertPlayerInfoPacket implements MinecraftPacket { + private static final Action[] ALL_ACTIONS = Action.class.getEnumConstants(); + private final EnumSet actions; private final List entries; @@ -85,14 +87,13 @@ public class UpsertPlayerInfoPacket implements MinecraftPacket { @Override public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - Action[] actions = Action.class.getEnumConstants(); - byte[] bytes = new byte[-Math.floorDiv(-actions.length, 8)]; + byte[] bytes = new byte[-Math.floorDiv(-ALL_ACTIONS.length, 8)]; buf.readBytes(bytes); BitSet actionSet = BitSet.valueOf(bytes); - for (int idx = 0; idx < actions.length; idx++) { + for (int idx = 0; idx < ALL_ACTIONS.length; idx++) { if (actionSet.get(idx)) { - addAction(actions[idx]); + addAction(ALL_ACTIONS[idx]); } } @@ -109,14 +110,13 @@ public class UpsertPlayerInfoPacket implements MinecraftPacket { @Override public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - Action[] actions = Action.class.getEnumConstants(); - BitSet set = new BitSet(actions.length); - for (int idx = 0; idx < actions.length; idx++) { - set.set(idx, this.actions.contains(actions[idx])); + BitSet set = new BitSet(ALL_ACTIONS.length); + for (int idx = 0; idx < ALL_ACTIONS.length; idx++) { + set.set(idx, this.actions.contains(ALL_ACTIONS[idx])); } byte[] bytes = set.toByteArray(); - buf.writeBytes(Arrays.copyOf(bytes, -Math.floorDiv(-actions.length, 8))); + buf.writeBytes(Arrays.copyOf(bytes, -Math.floorDiv(-ALL_ACTIONS.length, 8))); ProtocolUtils.writeVarInt(buf, this.entries.size()); for (Entry entry : this.entries) { @@ -133,12 +133,6 @@ public class UpsertPlayerInfoPacket implements MinecraftPacket { return handler.handle(this); } - public BitSet readFixedBitSet(ByteBuf buf, int param0) { - byte[] var0 = new byte[-Math.floorDiv(-param0, 8)]; - buf.readBytes(var0); - return BitSet.valueOf(var0); - } - public enum Action { ADD_PLAYER((ignored, buf, info) -> { // read info.profile = new GameProfile( diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java index 44adb743..41433307 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/CodeOfConductPacket.java @@ -44,4 +44,9 @@ public class CodeOfConductPacket extends DeferredByteBufHolder implements Minecr public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java index b4d93ec4..20d40fd4 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/FinishedUpdatePacket.java @@ -40,7 +40,7 @@ public class FinishedUpdatePacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, + public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 0; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java index ef0ee47a..2d9ed230 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/RegistrySyncPacket.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import io.netty.buffer.ByteBuf; @@ -47,4 +48,9 @@ public class RegistrySyncPacket extends DeferredByteBufHolder implements Minecra public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + return content().readableBytes(); + } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java index 8d4585d8..d41265ce 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/StartUpdatePacket.java @@ -40,7 +40,7 @@ public class StartUpdatePacket implements MinecraftPacket { } @Override - public int expectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, + public int decodeExpectedMaxLength(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { return 0; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java index 6d462fb2..c0cf414e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/config/TagsUpdatePacket.java @@ -22,6 +22,7 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import io.netty.buffer.ByteBuf; import java.util.Map; @@ -79,4 +80,22 @@ public class TagsUpdatePacket implements MinecraftPacket { public boolean handle(MinecraftSessionHandler handler) { return handler.handle(this); } + + @Override + public int encodeSizeHint(Direction direction, ProtocolVersion version) { + int size = ProtocolUtils.varIntBytes(tags.size()); + for (Map.Entry> entry : tags.entrySet()) { + size += ProtocolUtils.stringSizeHint(entry.getKey()); + size += ProtocolUtils.varIntBytes(entry.getValue().size()); + for (Map.Entry innerEntry : entry.getValue().entrySet()) { + size += ProtocolUtils.stringSizeHint(innerEntry.getKey()); + size += ProtocolUtils.varIntBytes(innerEntry.getValue().length); + for (int innerEntryValue : innerEntry.getValue()) { + size += ProtocolUtils.varIntBytes(innerEntryValue); + } + } + } + + return size; + } }