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; } }