* Switch to sync zlib with 512k chunks, adjustable compression level * update serverPlayer
74 lines
2 KiB
JavaScript
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
|