mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2024-11-29 13:15:15 +01:00
parent
ba844c1698
commit
4de1948ac8
@ -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")
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user