13
0
geforkt von Mirrors/Velocity

New compression stuff (this is broken)

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-07-25 11:58:12 -04:00
Ursprung 3c8a52aeb0
Commit ee1cddc6a0
6 geänderte Dateien mit 90 neuen und 44 gelöschten Zeilen

Datei anzeigen

@ -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");
}
}

Datei anzeigen

@ -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();
}

Datei anzeigen

@ -2,20 +2,22 @@ package io.minimum.minecraft.velocity.protocol.netty;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import io.minimum.minecraft.velocity.protocol.ProtocolUtils; import io.minimum.minecraft.velocity.protocol.ProtocolUtils;
import io.minimum.minecraft.velocity.protocol.compression.VelocityCompressor;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List; import java.util.List;
import java.util.zip.Inflater;
public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> { public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
private static final int MAXIMUM_INITIAL_BUFFER_SIZE = 65536; // 64KiB private static final int MAXIMUM_INITIAL_BUFFER_SIZE = 65536; // 64KiB
private final int threshold; private final int threshold;
private final VelocityCompressor compressor;
public MinecraftCompressDecoder(int threshold) { public MinecraftCompressDecoder(int threshold, VelocityCompressor compressor) {
this.threshold = threshold; this.threshold = threshold;
this.compressor = compressor;
} }
@Override @Override
@ -24,22 +26,14 @@ public class MinecraftCompressDecoder extends MessageToMessageDecoder<ByteBuf> {
if (uncompressedSize == 0) { if (uncompressedSize == 0) {
// Strip the now-useless uncompressed size, this message is already uncompressed. // Strip the now-useless uncompressed size, this message is already uncompressed.
out.add(msg.slice().retain()); out.add(msg.slice().retain());
msg.skipBytes(msg.readableBytes());
return; 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)); ByteBuf uncompressed = ctx.alloc().buffer(Math.min(uncompressedSize, MAXIMUM_INITIAL_BUFFER_SIZE));
try { try {
byte[] compressed = new byte[msg.readableBytes()]; compressor.inflate(msg, uncompressed);
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);
}
Preconditions.checkState(uncompressedSize == uncompressed.readableBytes(), "Mismatched compression sizes"); Preconditions.checkState(uncompressedSize == uncompressed.readableBytes(), "Mismatched compression sizes");
out.add(uncompressed); out.add(uncompressed);
} catch (Exception e) { } catch (Exception e) {

Datei anzeigen

@ -1,17 +1,18 @@
package io.minimum.minecraft.velocity.protocol.netty; package io.minimum.minecraft.velocity.protocol.netty;
import io.minimum.minecraft.velocity.protocol.ProtocolUtils; import io.minimum.minecraft.velocity.protocol.ProtocolUtils;
import io.minimum.minecraft.velocity.protocol.compression.VelocityCompressor;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder; import io.netty.handler.codec.MessageToByteEncoder;
import java.util.zip.Deflater;
public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> { public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
private final int threshold; private final int threshold;
private final VelocityCompressor compressor;
public MinecraftCompressEncoder(int threshold) { public MinecraftCompressEncoder(int threshold, VelocityCompressor compressor) {
this.threshold = threshold; this.threshold = threshold;
this.compressor = compressor;
} }
@Override @Override
@ -23,20 +24,10 @@ public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
return; return;
} }
Deflater deflater = new Deflater();
byte[] buf = new byte[msg.readableBytes()];
msg.readBytes(buf);
deflater.setInput(buf);
deflater.finish();
ByteBuf compressedBuffer = ctx.alloc().buffer(); ByteBuf compressedBuffer = ctx.alloc().buffer();
try { try {
byte[] deflated = new byte[8192]; compressor.deflate(msg, compressedBuffer);
while (!deflater.finished()) { ProtocolUtils.writeVarInt(out, msg.readableBytes());
int bytes = deflater.deflate(deflated);
compressedBuffer.writeBytes(deflated, 0, bytes);
}
ProtocolUtils.writeVarInt(out, buf.length);
out.writeBytes(compressedBuffer); out.writeBytes(compressedBuffer);
} finally { } finally {
compressedBuffer.release(); compressedBuffer.release();

Datei anzeigen

@ -1,6 +1,7 @@
package io.minimum.minecraft.velocity.protocol.netty; package io.minimum.minecraft.velocity.protocol.netty;
import io.minimum.minecraft.velocity.protocol.ProtocolConstants; import io.minimum.minecraft.velocity.protocol.ProtocolConstants;
import io.minimum.minecraft.velocity.protocol.compression.JavaVelocityCompressor;
import io.netty.channel.Channel; import io.netty.channel.Channel;
public class MinecraftPipelineUtils { public class MinecraftPipelineUtils {
@ -29,8 +30,9 @@ public class MinecraftPipelineUtils {
return; return;
} }
MinecraftCompressEncoder encoder = new MinecraftCompressEncoder(threshold); JavaVelocityCompressor compressor = new JavaVelocityCompressor();
MinecraftCompressDecoder decoder = new MinecraftCompressDecoder(threshold); MinecraftCompressEncoder encoder = new MinecraftCompressEncoder(threshold, compressor);
MinecraftCompressDecoder decoder = new MinecraftCompressDecoder(threshold, compressor);
ch.pipeline().addBefore("minecraft-decoder", "compress-decoder", decoder); ch.pipeline().addBefore("minecraft-decoder", "compress-decoder", decoder);
ch.pipeline().addBefore("minecraft-encoder", "compress-encoder", encoder); ch.pipeline().addBefore("minecraft-encoder", "compress-encoder", encoder);

Datei anzeigen

@ -1,27 +1,13 @@
package io.minimum.minecraft.velocity.proxy; 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.data.ServerPing;
import io.minimum.minecraft.velocity.protocol.MinecraftPacket;
import io.minimum.minecraft.velocity.protocol.PacketWrapper; 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.minimum.minecraft.velocity.protocol.packets.*;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.serializer.GsonComponentSerializer;
public class MinecraftClientSessionHandler extends ChannelInboundHandlerAdapter { public class MinecraftClientSessionHandler extends ChannelInboundHandlerAdapter {
private static final Gson GSON = new GsonBuilder()
.registerTypeHierarchyAdapter(Component.class, new GsonComponentSerializer())
.create();
@Override @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
InboundMinecraftConnection connection = ctx.channel().attr(InboundMinecraftConnection.CONNECTION).get(); InboundMinecraftConnection connection = ctx.channel().attr(InboundMinecraftConnection.CONNECTION).get();