smart-buffer icon indicating copy to clipboard operation
smart-buffer copied to clipboard

Convenience method to skip bytes?

Open lukehorvat opened this issue 2 years ago • 1 comments

Hi, I just started using SmartBuffer to wrap client/server packets and so far it's working splendidly. 👌

That said, I just reached a point where I need to skip a few bytes when reading/writing a packet, because these bytes are "reserved" for something that isn't implemented yet. So I did the following to keep my read/write functions as concise as possible:

type PacketData = {
  type: number;
  playerId: number;
  position: number;
  command: string;
  flags: number;
  timestamp: number;
};

function readPacket(packet: SmartBuffer): PacketData {
  return {
    type: packet.readUInt8(),
    playerId: packet.readUInt32LE(),
    position: packet.readUInt16LE(),
    command: packet.readStringNT(),
    flags: (packet.readOffset += 2) && packet.readUInt8(), // skip and read.
    timestamp: packet.readUInt32LE(),
  };
}

function writePacket({ type, playerId, position, command, flags, timestamp }: PacketData): SmartBuffer {
  return new SmartBuffer()
    .writeUInt8(type)
    .writeUInt32LE(playerId)
    .writeUInt16LE(position)
    .writeStringNT(command)
    .writeBuffer(Buffer.alloc(2)) // skip by writing an empty buffer. can't set writeOffset since we don't have a reference to the buffer.
    .writeUInt8(flags)
    .writeUInt32LE(timestamp);
}

As you can see from my efforts to keep things concise, the lines where I need to skip bytes are a little clunky.

I saw in v3 there was a skip method, but it was dropped in v4. What was the reason for dropping it and would you be open to the idea of adding it back in?

Also - just throwing this out there even though I don't think it would be as nice as a skip method - one idea I had as an alternative to skip was to add another param to the read/write methods. It would be a boolean that, if set to true, would make the offset you specified relative to the readOffset/writeOffset (and would also auto-increment them so you can chain further calls). Example:

function writePacket({ type, playerId, position, command, flags, timestamp }: PacketData): SmartBuffer {
  return new SmartBuffer()
    .writeUInt8(type)
    .writeUInt32LE(playerId)
    .writeUInt16LE(position)
    .writeStringNT(command)
    .writeUInt8(flags, 2, true) // skip and write.
    .writeUInt32LE(timestamp);
}

wdyt? Thanks.

lukehorvat avatar May 02 '22 12:05 lukehorvat

I think it sounds like a good idea. Are you able to make a PR?

JoshGlazebrook avatar May 03 '22 03:05 JoshGlazebrook