avocado-old/packages/net/packet/bundle.packet.js
2019-05-16 00:56:54 -05:00

69 lines
1.9 KiB
JavaScript

import {Packet} from './packet';
import {idFromPacket, packetFromId} from './registry';
export class BundlePacket extends Packet {
static pack(packet) {
const packets = packet.data[1];
// Pack up all the packets.
const packedPackets = new Array(packets.length);
for (let i = 0; i < packets.length; i++) {
const packet = packets[i];
const Packet_ = packet.constructor;
const id = idFromPacket(Packet_);
packedPackets[i] = Packet_.pack({
data: [id, packet.data],
});
}
// Calculate total length. All packed + 4 (int) for each.
let length = 0;
for (let i = 0; i < packedPackets.length; i++) {
length += 4 + packedPackets[i].length;
}
// Allocate buffer.
const buffer = Buffer.allocUnsafe(length);
let caret = 0;
for (let i = 0; i < packedPackets.length; i++) {
const packedPacket = packedPackets[i];
// Write packed length.
buffer.writeUInt32LE(packedPacket.length, caret);
caret += 4;
// Write packed data.
packedPacket.copy(buffer, caret, 0);
caret += packedPacket.length;
}
return this.builder.encode({
_id: packet.data[0],
data: buffer,
});
}
static get schema() {
return {
...super.schema,
data: 'buffer',
};
}
static unpack(packet) {
const {data} = this.builder.decode(packet);
const packets = [];
let caret = 0;
while (caret < data.length) {
// Read packed length.
const length = data.readUInt32LE(caret);
caret += 4;
// Read packed data.
const packedPacket = Buffer.from(data.buffer, caret, length);
caret += length;
// Lookup packet.
const packetId = packedPacket.readUInt8(0);
const Packet = packetFromId(packetId);
// Unpack and instantiate the packet.
const unpacked = Packet.unpack(packedPacket);
packets.push(new Packet(unpacked));
}
return packets;
}
}