diff --git a/native/src/main/java/com/velocitypowered/natives/compression/JavaVelocityCompressor.java b/native/src/main/java/com/velocitypowered/natives/compression/JavaVelocityCompressor.java index 4186570c5..2fdd91bab 100644 --- a/native/src/main/java/com/velocitypowered/natives/compression/JavaVelocityCompressor.java +++ b/native/src/main/java/com/velocitypowered/natives/compression/JavaVelocityCompressor.java @@ -8,13 +8,15 @@ import java.util.zip.Deflater; import java.util.zip.Inflater; public class JavaVelocityCompressor implements VelocityCompressor { + public static final VelocityCompressorFactory FACTORY = JavaVelocityCompressor::new; + private final Deflater deflater; private final Inflater inflater; private final byte[] buf; private boolean disposed = false; - public JavaVelocityCompressor() { - this.deflater = new Deflater(); + private JavaVelocityCompressor(int level) { + this.deflater = new Deflater(level); this.inflater = new Inflater(); this.buf = new byte[ZLIB_BUFFER_SIZE]; } diff --git a/native/src/main/java/com/velocitypowered/natives/compression/NativeVelocityCompressor.java b/native/src/main/java/com/velocitypowered/natives/compression/NativeVelocityCompressor.java index 77ae9a935..90b96ec04 100644 --- a/native/src/main/java/com/velocitypowered/natives/compression/NativeVelocityCompressor.java +++ b/native/src/main/java/com/velocitypowered/natives/compression/NativeVelocityCompressor.java @@ -4,18 +4,19 @@ import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; import java.util.zip.DataFormatException; -import java.util.zip.Deflater; public class NativeVelocityCompressor implements VelocityCompressor { + public static final VelocityCompressorFactory FACTORY = NativeVelocityCompressor::new; + private final NativeZlibInflate inflate = new NativeZlibInflate(); private final long inflateCtx; private final NativeZlibDeflate deflate = new NativeZlibDeflate(); private final long deflateCtx; private boolean disposed = false; - public NativeVelocityCompressor() { + private NativeVelocityCompressor(int level) { this.inflateCtx = inflate.init(); - this.deflateCtx = deflate.init(Deflater.DEFAULT_COMPRESSION); + this.deflateCtx = deflate.init(level); } @Override diff --git a/native/src/main/java/com/velocitypowered/natives/compression/VelocityCompressorFactory.java b/native/src/main/java/com/velocitypowered/natives/compression/VelocityCompressorFactory.java new file mode 100644 index 000000000..493bdee24 --- /dev/null +++ b/native/src/main/java/com/velocitypowered/natives/compression/VelocityCompressorFactory.java @@ -0,0 +1,5 @@ +package com.velocitypowered.natives.compression; + +public interface VelocityCompressorFactory { + VelocityCompressor create(int level); +} diff --git a/native/src/main/java/com/velocitypowered/natives/util/NativeCodeLoader.java b/native/src/main/java/com/velocitypowered/natives/util/NativeCodeLoader.java index 10a281573..2f07378c8 100644 --- a/native/src/main/java/com/velocitypowered/natives/util/NativeCodeLoader.java +++ b/native/src/main/java/com/velocitypowered/natives/util/NativeCodeLoader.java @@ -19,7 +19,7 @@ public class NativeCodeLoader implements Supplier { if (selected == null) { selected = select(); } - return selected.supplier.get(); + return selected.object; } private Variant select() { @@ -44,14 +44,14 @@ public class NativeCodeLoader implements Supplier { private boolean available; private final Runnable setup; private final String name; - private final Supplier supplier; + private final T object; private boolean hasBeenSetup = false; - Variant(BooleanSupplier available, Runnable setup, String name, Supplier supplier) { + Variant(BooleanSupplier available, Runnable setup, String name, T object) { this.available = available.getAsBoolean(); this.setup = setup; this.name = name; - this.supplier = supplier; + this.object = object; } private void setup() { @@ -71,7 +71,7 @@ public class NativeCodeLoader implements Supplier { } if (available) { - return supplier.get(); + return object; } return null; diff --git a/native/src/main/java/com/velocitypowered/natives/util/Natives.java b/native/src/main/java/com/velocitypowered/natives/util/Natives.java index 86fb3651f..af26c300f 100644 --- a/native/src/main/java/com/velocitypowered/natives/util/Natives.java +++ b/native/src/main/java/com/velocitypowered/natives/util/Natives.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList; import com.velocitypowered.natives.compression.JavaVelocityCompressor; import com.velocitypowered.natives.compression.NativeVelocityCompressor; import com.velocitypowered.natives.compression.VelocityCompressor; +import com.velocitypowered.natives.compression.VelocityCompressorFactory; import java.io.IOException; import java.nio.file.Files; @@ -34,15 +35,15 @@ public class Natives { }; } - public static final NativeCodeLoader compressor = new NativeCodeLoader<>( + public static final NativeCodeLoader compressor = new NativeCodeLoader<>( ImmutableList.of( new NativeCodeLoader.Variant<>(NativeCodeLoader.MACOS, copyAndLoadNative("/macosx/velocity-compress.dylib"), "native compression (macOS)", - NativeVelocityCompressor::new), + NativeVelocityCompressor.FACTORY), new NativeCodeLoader.Variant<>(NativeCodeLoader.LINUX, copyAndLoadNative("/linux_x64/velocity-compress.so"), "native compression (Linux amd64)", - NativeVelocityCompressor::new), - new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {}, "Java compression", JavaVelocityCompressor::new) + NativeVelocityCompressor.FACTORY), + new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {}, "Java compression", JavaVelocityCompressor.FACTORY) ) ); } diff --git a/native/src/test/java/com/velocitypowered/natives/compression/VelocityCompressorTest.java b/native/src/test/java/com/velocitypowered/natives/compression/VelocityCompressorTest.java index 5ccf070dc..27d6fd498 100644 --- a/native/src/test/java/com/velocitypowered/natives/compression/VelocityCompressorTest.java +++ b/native/src/test/java/com/velocitypowered/natives/compression/VelocityCompressorTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.condition.EnabledOnOs; import java.util.Random; import java.util.function.Supplier; import java.util.zip.DataFormatException; +import java.util.zip.Deflater; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -26,7 +27,7 @@ class VelocityCompressorTest { @Test @EnabledOnOs({ MAC, LINUX }) void nativeIntegrityCheck() throws DataFormatException { - VelocityCompressor compressor = Natives.compressor.get(); + VelocityCompressor compressor = Natives.compressor.get().create(Deflater.DEFAULT_COMPRESSION); if (compressor instanceof JavaVelocityCompressor) { fail("Loaded regular compressor"); } @@ -35,7 +36,7 @@ class VelocityCompressorTest { @Test void javaIntegrityCheck() throws DataFormatException { - JavaVelocityCompressor compressor = new JavaVelocityCompressor(); + VelocityCompressor compressor = JavaVelocityCompressor.FACTORY.create(Deflater.DEFAULT_COMPRESSION); check(compressor); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftConnection.java index fff678070..fa8b51268 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftConnection.java @@ -20,6 +20,7 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.GeneralSecurityException; +import java.util.zip.Deflater; import static com.velocitypowered.network.Connections.CIPHER_DECODER; import static com.velocitypowered.network.Connections.CIPHER_ENCODER; @@ -192,7 +193,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter { return; } - VelocityCompressor compressor = Natives.compressor.get(); + VelocityCompressor compressor = Natives.compressor.get().create(Deflater.DEFAULT_COMPRESSION); MinecraftCompressEncoder encoder = new MinecraftCompressEncoder(threshold, compressor); MinecraftCompressDecoder decoder = new MinecraftCompressDecoder(threshold, compressor); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/http/SimpleHttpResponseCollector.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/http/SimpleHttpResponseCollector.java index b39488827..236ccb9ef 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/http/SimpleHttpResponseCollector.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/http/SimpleHttpResponseCollector.java @@ -6,6 +6,7 @@ import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.LastHttpContent; +import io.netty.util.ReferenceCountUtil; import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; @@ -20,22 +21,25 @@ class SimpleHttpResponseCollector extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof HttpResponse) { - HttpResponseStatus status = ((HttpResponse) msg).status(); - if (status != HttpResponseStatus.OK) { - ctx.close(); - reply.completeExceptionally(new RuntimeException("Unexpected status code " + status.code())); + try { + if (msg instanceof HttpResponse) { + HttpResponseStatus status = ((HttpResponse) msg).status(); + if (status != HttpResponseStatus.OK) { + ctx.close(); + reply.completeExceptionally(new RuntimeException("Unexpected status code " + status.code())); + } } - } - if (msg instanceof HttpContent) { - buffer.append(((HttpContent) msg).content().toString(StandardCharsets.UTF_8)); - ((HttpContent) msg).release(); + if (msg instanceof HttpContent) { + buffer.append(((HttpContent) msg).content().toString(StandardCharsets.UTF_8)); - if (msg instanceof LastHttpContent) { - ctx.close(); - reply.complete(buffer.toString()); + if (msg instanceof LastHttpContent) { + ctx.close(); + reply.complete(buffer.toString()); + } } + } finally { + ReferenceCountUtil.release(msg); } } }