close #160, close #149 velocity native

This commit is contained in:
creeper123123321 2021-06-25 20:40:51 -03:00
parent ba844c1698
commit 4de1948ac8
4 changed files with 60 additions and 42 deletions

View File

@ -51,6 +51,7 @@ repositories {
maven("https://repo.viaversion.com/") maven("https://repo.viaversion.com/")
maven("https://repo.aikar.co/content/groups/aikar/") maven("https://repo.aikar.co/content/groups/aikar/")
maven("https://jitpack.io") maven("https://jitpack.io")
maven("https://nexus.velocitypowered.com/repository/maven-public/")
mavenLocal() mavenLocal()
} }
@ -69,6 +70,7 @@ dependencies {
implementation("io.netty:netty-tcnative-boringssl-static:2.0.40.Final") implementation("io.netty:netty-tcnative-boringssl-static:2.0.40.Final")
implementation("com.google.guava:guava:30.1.1-jre") implementation("com.google.guava:guava:30.1.1-jre")
implementation("com.velocitypowered:velocity-native:1.1.0-SNAPSHOT")
implementation("org.powernukkit.fastutil:fastutil-lite:8.1.1") implementation("org.powernukkit.fastutil:fastutil-lite:8.1.1")
implementation("org.yaml:snakeyaml:1.29") implementation("org.yaml:snakeyaml:1.29")

View File

@ -1,6 +1,7 @@
package com.viaversion.aas package com.viaversion.aas
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.velocitypowered.natives.util.Natives
import com.viaversion.aas.command.VIAaaSConsole import com.viaversion.aas.command.VIAaaSConsole
import com.viaversion.aas.command.ViaAspirinCommand import com.viaversion.aas.command.ViaAspirinCommand
import com.viaversion.aas.config.VIAaaSConfig import com.viaversion.aas.config.VIAaaSConfig
@ -150,6 +151,7 @@ private fun bindPorts(args: Array<String>) {
.childOption(ChannelOption.TCP_NODELAY, true) .childOption(ChannelOption.TCP_NODELAY, true)
.bind(InetAddress.getByName(VIAaaSConfig.bindAddress), VIAaaSConfig.port) .bind(InetAddress.getByName(VIAaaSConfig.bindAddress), VIAaaSConfig.port)
viaaasLogger.info("Using compression: ${Natives.compress.loadedVariant}")
viaaasLogger.info("Binded minecraft into " + chFuture!!.sync().channel().localAddress()) viaaasLogger.info("Binded minecraft into " + chFuture!!.sync().channel().localAddress())
ktorServer = embeddedServer(Netty, commandLineEnvironment(args)) {}.start(false) ktorServer = embeddedServer(Netty, commandLineEnvironment(args)) {}.start(false)
} }

View File

@ -1,72 +1,84 @@
package com.viaversion.aas.codec package com.viaversion.aas.codec
import com.viaversion.aas.util.StacklessException import com.velocitypowered.natives.compression.VelocityCompressor
import com.velocitypowered.natives.util.MoreByteBufUtils
import com.velocitypowered.natives.util.Natives
import com.viaversion.viaversion.api.type.Type import com.viaversion.viaversion.api.type.Type
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.DecoderException
import io.netty.handler.codec.MessageToMessageCodec import io.netty.handler.codec.MessageToMessageCodec
import java.util.zip.Deflater
import java.util.zip.Inflater
class CompressionCodec(val threshold: Int) : MessageToMessageCodec<ByteBuf, ByteBuf>() { class CompressionCodec(val threshold: Int) : MessageToMessageCodec<ByteBuf, ByteBuf>() {
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java // stolen from Krypton (GPL) and modified
private val inflater: Inflater = Inflater() // https://github.com/astei/krypton/blob/master/src/main/java/me/steinborn/krypton/mod/shared/network/compression/MinecraftCompressEncoder.java
private val deflater: Deflater = Deflater() private val VANILLA_MAXIMUM_UNCOMPRESSED_SIZE = 2 * 1024 * 1024 // 2MiB
private val HARD_MAXIMUM_UNCOMPRESSED_SIZE = 16 * 1024 * 1024 // 16MiB
private val UNCOMPRESSED_CAP =
if (java.lang.Boolean.getBoolean("velocity.increased-compression-cap")) HARD_MAXIMUM_UNCOMPRESSED_SIZE else VANILLA_MAXIMUM_UNCOMPRESSED_SIZE
private lateinit var compressor: VelocityCompressor
@Throws(Exception::class) override fun handlerAdded(ctx: ChannelHandlerContext) {
override fun encode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) { compressor = Natives.compress.get().create(threshold)
val frameLength = input.readableBytes() }
val outBuf = ctx.alloc().buffer()
override fun handlerRemoved(ctx: ChannelHandlerContext) {
compressor.close()
}
override fun encode(ctx: ChannelHandlerContext, msg: ByteBuf, out: MutableList<Any>) {
if (!ctx.channel().isActive) return
val outBuf = allocateBuffer(ctx, msg)
try { try {
if (frameLength < threshold) { val uncompressedSize = msg.readableBytes()
if (uncompressedSize < threshold) { // Not compressed
outBuf.writeByte(0) outBuf.writeByte(0)
outBuf.writeBytes(input) outBuf.writeBytes(msg)
out.add(outBuf.retain()) } else {
return Type.VAR_INT.writePrimitive(outBuf, uncompressedSize)
} val compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, msg)
Type.VAR_INT.writePrimitive(outBuf, frameLength) try {
deflater.setInput(input.nioBuffer()) compressor.deflate(compatibleIn, outBuf)
deflater.finish() } finally {
while (!deflater.finished()) { compatibleIn.release()
outBuf.ensureWritable(8192) }
val wIndex = outBuf.writerIndex()
outBuf.writerIndex(wIndex + deflater.deflate(outBuf.nioBuffer(wIndex, outBuf.writableBytes())))
} }
out.add(outBuf.retain()) out.add(outBuf.retain())
} finally { } finally {
outBuf.release() outBuf.release()
deflater.reset()
} }
} }
@Throws(Exception::class) private fun allocateBuffer(ctx: ChannelHandlerContext, msg: ByteBuf): ByteBuf {
val initialBufferSize = msg.readableBytes() + 1
return MoreByteBufUtils.preferredBuffer(ctx.alloc(), compressor, initialBufferSize)
}
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) { override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
if (!input.isReadable || !ctx.channel().isActive) return if (!input.isReadable || !ctx.channel().isActive) return
val outLength = Type.VAR_INT.readPrimitive(input)
if (outLength == 0) { val claimedUncompressedSize = Type.VAR_INT.readPrimitive(input)
if (claimedUncompressedSize == 0) { // Uncompressed
out.add(input.retain()) out.add(input.retain())
return return
} }
if (outLength < threshold) { if (claimedUncompressedSize < threshold) {
throw StacklessException("Badly compressed packet - size of $outLength is below server threshold of $threshold") throw DecoderException("Badly compressed packet - size of $claimedUncompressedSize is below server threshold of $threshold")
} }
if (outLength > 2097152) { if (claimedUncompressedSize > UNCOMPRESSED_CAP) {
throw StacklessException("Badly compressed packet - size of $outLength is larger than protocol maximum of 2097152") throw DecoderException("Badly compressed packet - size of $claimedUncompressedSize is larger than maximum of $UNCOMPRESSED_CAP")
} }
val compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, input)
inflater.setInput(input.nioBuffer()) val decompressed = MoreByteBufUtils.preferredBuffer(ctx.alloc(), compressor, claimedUncompressedSize)
val output = ctx.alloc().buffer(outLength, outLength)
try { try {
output.writerIndex( compressor.inflate(compatibleIn, decompressed, claimedUncompressedSize)
output.writerIndex() + inflater.inflate(output.nioBuffer(output.writerIndex(), output.writableBytes())) input.clear()
) out.add(decompressed.retain())
out.add(output.retain())
} finally { } finally {
inflater.reset() decompressed.release()
output.release() compatibleIn.release()
} }
} }
} }

View File

@ -57,7 +57,7 @@ object PacketRegistry {
ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.DISCONNECT.id, ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.DISCONNECT.id,
ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.DISCONNECT.id, ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.DISCONNECT.id,
ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.DISCONNECT.id, ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.DISCONNECT.id,
Range.singleton(ProtocolVersion.v1_17.originalVersion) to ClientboundPackets1_17.DISCONNECT.id ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.DISCONNECT.id
) )
) )
@ -70,7 +70,7 @@ object PacketRegistry {
ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.PLUGIN_MESSAGE.id, ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.PLUGIN_MESSAGE.id, ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.PLUGIN_MESSAGE.id, ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.PLUGIN_MESSAGE.id,
Range.singleton(ProtocolVersion.v1_17.originalVersion) to ClientboundPackets1_17.PLUGIN_MESSAGE.id ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.PLUGIN_MESSAGE.id
) )
) )
} }
@ -79,6 +79,8 @@ object PacketRegistry {
return Range.closed(this.originalVersion, o.originalVersion) return Range.closed(this.originalVersion, o.originalVersion)
} }
val ProtocolVersion.singleton get() = Range.singleton(this.originalVersion)
inline fun <reified P : Packet> register( inline fun <reified P : Packet> register(
state: State, state: State,
direction: Direction, direction: Direction,