diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java index 6d37520b4..dfe230e31 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java @@ -68,6 +68,7 @@ import com.velocitypowered.proxy.protocol.packet.TransferPacket; import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket; import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; import com.velocitypowered.proxy.protocol.packet.config.StartUpdatePacket; +import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder; import com.velocitypowered.proxy.protocol.util.PluginMessageUtil; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; @@ -91,6 +92,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { Boolean.getBoolean("velocity.log-server-backpressure"); private static final int MAXIMUM_PACKETS_TO_FLUSH = Integer.getInteger("velocity.max-packets-per-flush", 8192); + private static final int LARGE_PACKET_THRESHOLD = 1024 * 128; private final VelocityServer server; private final VelocityServerConnection serverConn; @@ -455,8 +457,9 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { if (packet instanceof PluginMessagePacket pluginMessage) { pluginMessage.retain(); } + boolean huge = packet instanceof DeferredByteBufHolder def && def.content().readableBytes() > LARGE_PACKET_THRESHOLD; playerConnection.delayedWrite(packet); - if (++packetsFlushed >= MAXIMUM_PACKETS_TO_FLUSH) { + if (huge || ++packetsFlushed >= MAXIMUM_PACKETS_TO_FLUSH) { playerConnection.flush(); packetsFlushed = 0; } @@ -464,8 +467,9 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { @Override public void handleUnknown(ByteBuf buf) { + boolean huge = buf.readableBytes() > LARGE_PACKET_THRESHOLD; playerConnection.delayedWrite(buf.retain()); - if (++packetsFlushed >= MAXIMUM_PACKETS_TO_FLUSH) { + if (huge || ++packetsFlushed >= MAXIMUM_PACKETS_TO_FLUSH) { playerConnection.flush(); packetsFlushed = 0; } 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 e2da28de1..e779ab961 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 @@ -31,7 +31,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; public class PluginMessagePacket extends DeferredByteBufHolder implements MinecraftPacket { - private static final int MAX_PAYLOAD_SIZE = Integer.getInteger("velocity.max-plugin-message-payload-size", 32767); + private static final int MAX_PAYLOAD_SIZE_CLIENTBOUND = getPayloadLimit(Direction.CLIENTBOUND); + private static final int MAX_PAYLOAD_SIZE_SERVERBOUND = getPayloadLimit(Direction.SERVERBOUND); private @Nullable String channel; @@ -52,6 +53,19 @@ public class PluginMessagePacket extends DeferredByteBufHolder implements Minecr return channel; } + private static int getPayloadLimit(Direction direction) { + if (System.getProperty("velocity.max-plugin-message-payload-size") != null) { + return Integer.getInteger("velocity.max-plugin-message-payload-size"); + } + if (direction == Direction.SERVERBOUND) { + return Integer.getInteger("velocity.max-plugin-message-payload-size.serverbound", 32767); + } else { + // This is the vanilla expected limit, a payload this large feels like a nightmare given the trust + // we give to servers... + return Integer.getInteger("velocity.max-plugin-message-payload-size.clientbound", 1048576); + } + } + public void setChannel(String channel) { this.channel = channel; } @@ -104,7 +118,8 @@ public class PluginMessagePacket extends DeferredByteBufHolder implements Minecr @Override public int decodeExpectedMaxLength(ByteBuf buf, Direction direction, ProtocolVersion version) { - return ProtocolUtils.DEFAULT_MAX_STRING_BYTES + MAX_PAYLOAD_SIZE; + return ProtocolUtils.DEFAULT_MAX_STRING_BYTES + + (direction == Direction.CLIENTBOUND ? MAX_PAYLOAD_SIZE_CLIENTBOUND : MAX_PAYLOAD_SIZE_SERVERBOUND); } @Override