diff --git a/build.gradle b/build.gradle index 64eacd530..0a5100995 100644 --- a/build.gradle +++ b/build.gradle @@ -36,9 +36,6 @@ allprojects { name 'sponge' url 'https://repo.spongepowered.org/maven' } - maven { - url "https://repo.velocitypowered.com/snapshots/" - } } javadoc { options { @@ -153,9 +150,6 @@ dependencies { api "org.ow2.asm:asm-commons:${asmVersion}" api "org.spongepowered:mixin:${mixinVersion}" - // Compression - implementation "com.velocitypowered:velocity-native:1.1.0-SNAPSHOT" - // Path finding api 'com.github.MadMartian:hydrazine-path-finding:1.6.0' diff --git a/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java b/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java index 7f12b84a9..4ba5b0ef0 100644 --- a/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java +++ b/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java @@ -16,10 +16,8 @@ package net.minestom.server.network.netty.codec; -import com.velocitypowered.natives.compression.VelocityCompressor; -import com.velocitypowered.natives.util.MoreByteBufUtils; -import com.velocitypowered.natives.util.Natives; import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageCodec; import io.netty.handler.codec.DecoderException; @@ -27,6 +25,8 @@ import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.Utils; import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.Inflater; public class PacketCompressor extends ByteToMessageCodec { @@ -34,7 +34,8 @@ public class PacketCompressor extends ByteToMessageCodec { private final int threshold; - private final VelocityCompressor compressor = Natives.compress.get().create(4); + private final Deflater deflater = new Deflater(); + private final Inflater inflater = new Inflater(); public PacketCompressor(int threshold) { this.threshold = threshold; @@ -42,7 +43,7 @@ public class PacketCompressor extends ByteToMessageCodec { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf from, ByteBuf to) { - PacketUtils.compressBuffer(compressor, from, to); + PacketUtils.compressBuffer(deflater, from, to); } @Override @@ -61,19 +62,17 @@ public class PacketCompressor extends ByteToMessageCodec { throw new DecoderException("Badly compressed packet - size of " + claimedUncompressedSize + " is larger than protocol maximum of " + MAX_SIZE); } + // TODO optimize to do not initialize arrays each time - ByteBuf compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, in); - ByteBuf uncompressed = MoreByteBufUtils.preferredBuffer(ctx.alloc(), compressor, claimedUncompressedSize); - try { - compressor.inflate(compatibleIn, uncompressed, claimedUncompressedSize); - out.add(uncompressed); - in.clear(); - } catch (Exception e) { - uncompressed.release(); - throw e; - } finally { - compatibleIn.release(); - } + byte[] input = new byte[in.readableBytes()]; + in.readBytes(input); + + inflater.setInput(input); + byte[] output = new byte[claimedUncompressedSize]; + inflater.inflate(output); + inflater.reset(); + + out.add(Unpooled.wrappedBuffer(output)); } } } diff --git a/src/main/java/net/minestom/server/utils/PacketUtils.java b/src/main/java/net/minestom/server/utils/PacketUtils.java index ddf5eb29c..a0e4e7f5b 100644 --- a/src/main/java/net/minestom/server/utils/PacketUtils.java +++ b/src/main/java/net/minestom/server/utils/PacketUtils.java @@ -1,12 +1,9 @@ package net.minestom.server.utils; -import com.velocitypowered.natives.compression.VelocityCompressor; -import com.velocitypowered.natives.util.Natives; import io.netty.buffer.ByteBuf; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.ForwardingAudience; import net.minestom.server.MinecraftServer; -import net.minestom.server.adventure.AdventureSerializer; import net.minestom.server.adventure.MinestomAdventure; import net.minestom.server.adventure.audience.PacketGroupingAudience; import net.minestom.server.entity.Player; @@ -21,8 +18,9 @@ import net.minestom.server.utils.callback.validator.PlayerValidator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.nio.ByteBuffer; import java.util.Collection; -import java.util.zip.DataFormatException; +import java.util.zip.Deflater; /** * Utils class for packets. Including writing a {@link ServerPacket} into a {@link ByteBuf} @@ -31,7 +29,7 @@ import java.util.zip.DataFormatException; public final class PacketUtils { private static final PacketListenerManager PACKET_LISTENER_MANAGER = MinecraftServer.getPacketListenerManager(); - private static final ThreadLocal COMPRESSOR = ThreadLocal.withInitial(() -> Natives.compress.get().create(4)); + private static final ThreadLocal COMPRESSOR = ThreadLocal.withInitial(Deflater::new); private PacketUtils() { } @@ -189,27 +187,35 @@ public final class PacketUtils { *

* {@code packetBuffer} needs to be the packet content without any header (if you want to use it to write a Minecraft packet). * - * @param compressor the deflater for zlib compression + * @param deflater the deflater for zlib compression * @param packetBuffer the buffer containing all the packet fields * @param compressionTarget the buffer which will receive the compressed version of {@code packetBuffer} */ - public static void compressBuffer(@NotNull VelocityCompressor compressor, @NotNull ByteBuf packetBuffer, @NotNull ByteBuf compressionTarget) { + public static void compressBuffer(@NotNull Deflater deflater, @NotNull ByteBuf packetBuffer, @NotNull ByteBuf compressionTarget) { final int packetLength = packetBuffer.readableBytes(); final boolean compression = packetLength > MinecraftServer.getCompressionThreshold(); Utils.writeVarInt(compressionTarget, compression ? packetLength : 0); if (compression) { - compress(compressor, packetBuffer, compressionTarget); + compress(deflater, packetBuffer, compressionTarget); } else { compressionTarget.writeBytes(packetBuffer); } } - private static void compress(@NotNull VelocityCompressor compressor, @NotNull ByteBuf uncompressed, @NotNull ByteBuf compressed) { - try { - compressor.deflate(uncompressed, compressed); - } catch (DataFormatException e) { - e.printStackTrace(); + private static void compress(@NotNull Deflater deflater, @NotNull ByteBuf uncompressed, @NotNull ByteBuf compressed) { + deflater.setInput(uncompressed.nioBuffer()); + deflater.finish(); + + while (!deflater.finished()) { + ByteBuffer nioBuffer = compressed.nioBuffer(compressed.writerIndex(), compressed.writableBytes()); + compressed.writerIndex(deflater.deflate(nioBuffer) + compressed.writerIndex()); + + if (compressed.writableBytes() == 0) { + compressed.ensureWritable(8192); + } } + + deflater.reset(); } public static void writeFramedPacket(@NotNull ByteBuf buffer,