bedrock-protocol/src/transforms/framer.js
extremeheat 14af5fe04f
Switch to sync zlib with 512k chunks, adjustable compression level (#174)
* Switch to sync zlib with 512k chunks, adjustable compression level

* update serverPlayer
2022-02-04 20:30:21 -05:00

74 lines
2 KiB
JavaScript

const [readVarInt, writeVarInt, sizeOfVarInt] = require('protodef').types.varint
const zlib = require('zlib')
// Concatenates packets into one batch packet, and adds length prefixs.
class Framer {
constructor (compressionLevel) {
// Encoding
this.packets = []
this.compressionLevel = compressionLevel
}
static decode (buf) {
// Read header
if (buf[0] !== 0xfe) throw Error('bad batch packet header ' + buf[0])
const buffer = buf.slice(1)
// Decode the payload with 512kb buffer
try {
const inflated = zlib.inflateRawSync(buffer, { chunkSize: 512000 })
return Framer.getPackets(inflated)
} catch (e) { // Try to decode without compression
return Framer.getPackets(buffer)
}
}
encode () {
const buf = Buffer.concat(this.packets)
const def = zlib.deflateRawSync(buf, { level: this.compressionLevel })
return Buffer.concat([Buffer.from([0xfe]), def])
}
addEncodedPacket (chunk) {
const varIntSize = sizeOfVarInt(chunk.byteLength)
const buffer = Buffer.allocUnsafe(varIntSize + chunk.byteLength)
writeVarInt(chunk.length, buffer, 0)
chunk.copy(buffer, varIntSize)
this.packets.push(buffer)
}
addEncodedPackets (packets) {
let allocSize = 0
for (const packet of packets) {
allocSize += sizeOfVarInt(packet.byteLength)
allocSize += packet.byteLength
}
const buffer = Buffer.allocUnsafe(allocSize)
let offset = 0
for (const chunk of packets) {
offset = writeVarInt(chunk.length, buffer, offset)
offset += chunk.copy(buffer, offset, 0)
}
this.packets.push(buffer)
}
getBuffer () {
return Buffer.concat(this.packets)
}
static getPackets (buffer) {
const packets = []
let offset = 0
while (offset < buffer.byteLength) {
const { value, size } = readVarInt(buffer, offset)
const dec = Buffer.allocUnsafe(value)
offset += size
offset += buffer.copy(dec, 0, offset, offset + value)
packets.push(dec)
}
return packets
}
}
module.exports = Framer