Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-25 07:40:13 +01:00
New compression stuff (this is broken)
Dieser Commit ist enthalten in:
Ursprung
3c8a52aeb0
Commit
ee1cddc6a0
@ -0,0 +1,60 @@
|
||||
package io.minimum.minecraft.velocity.protocol.compression;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
public class JavaVelocityCompressor implements VelocityCompressor {
|
||||
private final Deflater deflater;
|
||||
private final Inflater inflater;
|
||||
private final byte[] buf;
|
||||
private boolean disposed = false;
|
||||
|
||||
public JavaVelocityCompressor() {
|
||||
this.deflater = new Deflater();
|
||||
this.inflater = new Inflater();
|
||||
this.buf = new byte[8192];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
|
||||
ensureNotDisposed();
|
||||
|
||||
byte[] inData = new byte[source.readableBytes()];
|
||||
source.readBytes(inData);
|
||||
inflater.setInput(inData);
|
||||
while (!inflater.finished()) {
|
||||
int read = inflater.inflate(buf);
|
||||
destination.writeBytes(buf, 0, read);
|
||||
}
|
||||
inflater.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
|
||||
ensureNotDisposed();
|
||||
|
||||
byte[] inData = new byte[source.readableBytes()];
|
||||
source.readBytes(inData);
|
||||
deflater.setInput(inData);
|
||||
deflater.finish();
|
||||
while (!deflater.finished()) {
|
||||
int bytes = deflater.deflate(buf);
|
||||
destination.writeBytes(buf, 0, bytes);
|
||||
}
|
||||
deflater.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
ensureNotDisposed();
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
private void ensureNotDisposed() {
|
||||
Preconditions.checkState(!disposed, "Object already disposed");
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.minimum.minecraft.velocity.protocol.compression;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
public interface VelocityCompressor {
|
||||
void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||
|
||||
void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||
|
||||
void dispose();
|
||||
}
|
@ -2,20 +2,22 @@ package io.minimum.minecraft.velocity.protocol.netty;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.minimum.minecraft.velocity.protocol.ProtocolUtils;
|
||||
import io.minimum.minecraft.velocity.protocol.compression.VelocityCompressor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
private static final int MAXIMUM_INITIAL_BUFFER_SIZE = 65536; // 64KiB
|
||||
|
||||
private final int threshold;
|
||||
private final VelocityCompressor compressor;
|
||||
|
||||
public MinecraftCompressDecoder(int threshold) {
|
||||
public MinecraftCompressDecoder(int threshold, VelocityCompressor compressor) {
|
||||
this.threshold = threshold;
|
||||
this.compressor = compressor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,22 +26,14 @@ public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
if (uncompressedSize == 0) {
|
||||
// Strip the now-useless uncompressed size, this message is already uncompressed.
|
||||
out.add(msg.slice().retain());
|
||||
msg.skipBytes(msg.readableBytes());
|
||||
return;
|
||||
}
|
||||
|
||||
Preconditions.checkState(uncompressedSize >= threshold, "Uncompressed size %s doesn't make sense with threshold %s", uncompressedSize, threshold);
|
||||
ByteBuf uncompressed = ctx.alloc().buffer(Math.min(uncompressedSize, MAXIMUM_INITIAL_BUFFER_SIZE));
|
||||
try {
|
||||
byte[] compressed = new byte[msg.readableBytes()];
|
||||
msg.readBytes(compressed);
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.setInput(compressed);
|
||||
|
||||
byte[] decompressed = new byte[8192];
|
||||
while (!inflater.finished()) {
|
||||
int inflatedBytes = inflater.inflate(decompressed);
|
||||
uncompressed.writeBytes(decompressed, 0, inflatedBytes);
|
||||
}
|
||||
|
||||
compressor.inflate(msg, uncompressed);
|
||||
Preconditions.checkState(uncompressedSize == uncompressed.readableBytes(), "Mismatched compression sizes");
|
||||
out.add(uncompressed);
|
||||
} catch (Exception e) {
|
||||
|
@ -1,17 +1,18 @@
|
||||
package io.minimum.minecraft.velocity.protocol.netty;
|
||||
|
||||
import io.minimum.minecraft.velocity.protocol.ProtocolUtils;
|
||||
import io.minimum.minecraft.velocity.protocol.compression.VelocityCompressor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||
private final int threshold;
|
||||
private final VelocityCompressor compressor;
|
||||
|
||||
public MinecraftCompressEncoder(int threshold) {
|
||||
public MinecraftCompressEncoder(int threshold, VelocityCompressor compressor) {
|
||||
this.threshold = threshold;
|
||||
this.compressor = compressor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -23,20 +24,10 @@ public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||
return;
|
||||
}
|
||||
|
||||
Deflater deflater = new Deflater();
|
||||
byte[] buf = new byte[msg.readableBytes()];
|
||||
msg.readBytes(buf);
|
||||
deflater.setInput(buf);
|
||||
deflater.finish();
|
||||
|
||||
ByteBuf compressedBuffer = ctx.alloc().buffer();
|
||||
try {
|
||||
byte[] deflated = new byte[8192];
|
||||
while (!deflater.finished()) {
|
||||
int bytes = deflater.deflate(deflated);
|
||||
compressedBuffer.writeBytes(deflated, 0, bytes);
|
||||
}
|
||||
ProtocolUtils.writeVarInt(out, buf.length);
|
||||
compressor.deflate(msg, compressedBuffer);
|
||||
ProtocolUtils.writeVarInt(out, msg.readableBytes());
|
||||
out.writeBytes(compressedBuffer);
|
||||
} finally {
|
||||
compressedBuffer.release();
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.minimum.minecraft.velocity.protocol.netty;
|
||||
|
||||
import io.minimum.minecraft.velocity.protocol.ProtocolConstants;
|
||||
import io.minimum.minecraft.velocity.protocol.compression.JavaVelocityCompressor;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
public class MinecraftPipelineUtils {
|
||||
@ -29,8 +30,9 @@ public class MinecraftPipelineUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftCompressEncoder encoder = new MinecraftCompressEncoder(threshold);
|
||||
MinecraftCompressDecoder decoder = new MinecraftCompressDecoder(threshold);
|
||||
JavaVelocityCompressor compressor = new JavaVelocityCompressor();
|
||||
MinecraftCompressEncoder encoder = new MinecraftCompressEncoder(threshold, compressor);
|
||||
MinecraftCompressDecoder decoder = new MinecraftCompressDecoder(threshold, compressor);
|
||||
|
||||
ch.pipeline().addBefore("minecraft-decoder", "compress-decoder", decoder);
|
||||
ch.pipeline().addBefore("minecraft-encoder", "compress-encoder", encoder);
|
||||
|
@ -1,27 +1,13 @@
|
||||
package io.minimum.minecraft.velocity.proxy;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.minimum.minecraft.velocity.data.ServerPing;
|
||||
import io.minimum.minecraft.velocity.protocol.MinecraftPacket;
|
||||
import io.minimum.minecraft.velocity.protocol.PacketWrapper;
|
||||
import io.minimum.minecraft.velocity.protocol.StateRegistry;
|
||||
import io.minimum.minecraft.velocity.protocol.netty.MinecraftDecoder;
|
||||
import io.minimum.minecraft.velocity.protocol.netty.MinecraftEncoder;
|
||||
import io.minimum.minecraft.velocity.protocol.packets.*;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.serializer.GsonComponentSerializer;
|
||||
|
||||
public class MinecraftClientSessionHandler extends ChannelInboundHandlerAdapter {
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(Component.class, new GsonComponentSerializer())
|
||||
.create();
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
InboundMinecraftConnection connection = ctx.channel().attr(InboundMinecraftConnection.CONNECTION).get();
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren