Last active
September 9, 2018 07:34
-
-
Save Proximyst/1db53b4ee8bc7a5aa0a89488960029f1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Defines different encodings to use for packet handling. | |
*/ | |
enum class PacketEncoding { | |
/** | |
* Handle the packet with no compression whatsoever. | |
*/ | |
UNCOMPRESSED { | |
override fun decode(data : ByteBuf) : ByteBuf { | |
return data | |
} | |
override fun encode(data : ByteBuf) : ByteBuf { | |
return data | |
} | |
}, | |
/** | |
* Conform to the compression format, but handle the packet with no compression. | |
* This is used when it doesn't hit the threshold for compression or when | |
* the incoming packet is 100% sure to not be compressed. | |
*/ | |
UNCOMPRESSED_WITH_COMPRESSION_ENABLED { | |
override fun decode(data : ByteBuf) : ByteBuf { | |
VarInt.decode(data) | |
return data | |
} | |
override fun encode(data : ByteBuf) : ByteBuf { | |
val buf = 0.toVarInt().encode() | |
buf.writeBytes(data) | |
return buf | |
} | |
}, | |
/** | |
* Handles the packet with ZLIB compression. | |
* | |
* The only time it handles it without compression is decoding packets | |
* which have an uncompressed length of 0. | |
*/ | |
COMPRESSED { | |
override fun decode(data : ByteBuf) : ByteBuf { | |
val uncompressedLength = VarInt.decode(data)?.contained() ?: return Unpooled.buffer() | |
if (uncompressedLength == 0) | |
return data | |
val inflater = Inflater() | |
val byteArray = ByteArray(data.readableBytes()) | |
data.readBytes(byteArray) | |
inflater.setInput(byteArray) | |
val result = ByteArray(uncompressedLength) | |
if (inflater.inflate(result) != uncompressedLength) | |
throw IllegalArgumentException("the uncompressed data is not correctly labelled") | |
return Unpooled.copiedBuffer(result) | |
} | |
override fun encode(data : ByteBuf) : ByteBuf { | |
val size = data.readableBytes() | |
val compressedData = ByteArrayOutputStream().also { | |
it.write(size) | |
DeflaterOutputStream(it).use { | |
val array = ByteArray(size) | |
data.readBytes(array) | |
it.write(array) | |
} | |
}.toByteArray() | |
val ret = compressedData.size.toVarInt().encode() | |
ret.writeBytes(compressedData) | |
return ret | |
} | |
}, | |
; | |
/** | |
* Encodes the [data] together to a [ByteBuf] per the enum constant. | |
* | |
* @param data | |
* The data of the packet. | |
* | |
* @return | |
* The encoded [ByteBuf], which may be ZLIB compressed per the enum constant. | |
*/ | |
abstract fun encode(data : ByteBuf) : ByteBuf | |
/** | |
* Decodes the [data] from the [ByteBuf] and returns its ID and data as [ByteBuf]. | |
* | |
* @throws IllegalArgumentException | |
* If the uncompressed data is not correctly labelled, this is thrown. | |
* | |
* @param data | |
* The [ByteBuf] of the incoming packet. Its readableBytes will be modified. | |
* | |
* @return | |
* The [ByteBuf] of the ID and data of the enclosed packet. | |
*/ | |
abstract fun decode(data : ByteBuf) : ByteBuf | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment