avocado-old/packages/net/packet/bundle.packet.js
2020-06-29 06:04:31 -05:00

73 lines
2.1 KiB
JavaScript

import {Packet} from './packet';
export default class BundlePacket extends Packet {
static pack(packet) {
const packets = packet.data[1];
const {idFrom} = require('./registrar');
// 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 = idFrom(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;
}
packet.data[1] = buffer;
return super.pack(packet);
}
static get schema() {
return {
...super.schema,
data: 'buffer',
};
}
static unpack(packet) {
const unpacked = super.unpack(packet);
const {data} = unpacked;
const {fromId} = require('./packets.scwp');
const packets = [];
let caret = 0;
while (caret < data.length) {
// Read packed length.
const length = data.readUInt32LE(caret);
caret += 4;
// Read packed data. TODO: manual blitting sucks...
const packedPacket = Buffer.allocUnsafe(length);
let i = 0;
while (i < length) {
packedPacket.writeUInt8(data.readUInt8(caret++), i++);
}
// Lookup packet.
const packetId = packedPacket.readUInt8(0);
const {default: Packet} = fromId(packetId);
// Unpack and instantiate the packet.
const unpacked = Packet.unpack(packedPacket);
packets.push(new Packet(unpacked.data));
}
unpacked.data = packets;
return unpacked;
}
}