diff --git a/packages/shared-packets/src/GameMessageHeader.ts b/packages/shared-packets/src/GameMessageHeader.ts index 002fdca71..09095023e 100644 --- a/packages/shared-packets/src/GameMessageHeader.ts +++ b/packages/shared-packets/src/GameMessageHeader.ts @@ -73,7 +73,7 @@ export class GameMessageHeader } override serialize(): Buffer { - return this.version === 0 ? this.serializeV0() : this.serializeV1(); + return this.version === 257 ? this.serializeV1() : this.serializeV0(); } private deserializeV0(data: Buffer): void { @@ -96,10 +96,10 @@ export class GameMessageHeader ); } - if (this.version === 0) { - this.deserializeV0(data); - } else { + if (this.version === 257) { this.deserializeV1(data); + } else { + this.deserializeV0(data); } } @@ -124,5 +124,4 @@ export class GameMessageHeader override toString(): string { return `GameMessageHeader {id: ${this.id}, length: ${this.length}, version: ${this.version}}`; } - } diff --git a/packages/shared-packets/src/GameMessagePayload.ts b/packages/shared-packets/src/GameMessagePayload.ts index 2e5654f9b..baffa4301 100644 --- a/packages/shared-packets/src/GameMessagePayload.ts +++ b/packages/shared-packets/src/GameMessagePayload.ts @@ -5,44 +5,25 @@ export class GameMessagePayload extends BufferSerializer implements SerializableInterface { - public messageId: number = 0; // 2 bytes - private isEncrypted: boolean = false; // Not serialized static copy(payload: GameMessagePayload): GameMessagePayload { const newPayload = new GameMessagePayload(); - newPayload.messageId = payload.messageId; newPayload._data = Buffer.from(payload._data); return newPayload; } override getByteSize(): number { - return 2 + this._data.length; + return this._data.length; } override serialize(): Buffer { - const buffer = Buffer.alloc(this.getByteSize()); - buffer.writeUInt16LE(this.messageId, 0); - this._data.copy(buffer, 2); - - return buffer; + return this._data; } override deserialize(data: Buffer): GameMessagePayload { - this._assertEnoughData(data, 2); - - this.messageId = data.readUInt16LE(0); - this._data = data.subarray(2); - - return this; - } - - getMessageId(): number { - return this.messageId; - } + this._data = data; - setMessageId(messageId: number): GameMessagePayload { - this.messageId = messageId; return this; } diff --git a/packages/shared-packets/src/GamePacket.ts b/packages/shared-packets/src/GamePacket.ts index 1b2e9b1d8..62c99fda1 100644 --- a/packages/shared-packets/src/GamePacket.ts +++ b/packages/shared-packets/src/GamePacket.ts @@ -36,6 +36,11 @@ export class GamePacket extends BasePacket implements SerializableMessage { override getDataBuffer(): Buffer { return this.data.serialize(); } + + getVersion(): number { + return this.header.getVersion(); + } + override setDataBuffer(data: Buffer): GamePacket { if (this.data.getByteSize() > 2) { throw new Error( @@ -63,7 +68,7 @@ export class GamePacket extends BasePacket implements SerializableMessage { } getMessageId(): number { - return this.data.getMessageId(); + return this.header.getId(); } getLength(): number { diff --git a/packages/shared-packets/test/GamePacket.test.ts b/packages/shared-packets/test/GamePacket.test.ts new file mode 100644 index 000000000..44f40cad6 --- /dev/null +++ b/packages/shared-packets/test/GamePacket.test.ts @@ -0,0 +1,83 @@ +import { describe, it, expect } from "vitest"; +import { Buffer } from "buffer"; +import { GamePacket } from "../src/GamePacket.js"; + +describe("GamePacket", () => { + it("should deserialize correctly v0 correctly", () => { + const buffer = Buffer.alloc(11); + buffer.writeUInt16BE(1234, 0); // Message ID + buffer.writeUInt16BE(11, 2); // Length + + buffer.write("test da", 4); // Data + + const packet = new GamePacket(); + packet.deserialize(buffer); + + expect(packet.getMessageId()).toBe(1234); + expect(packet.getDataBuffer().toString("hex")).equals( + Buffer.from("test da").toString("hex"), + ); + }); + + it("should deserialize correctly v1 correctly", () => { + const buffer = Buffer.alloc(26); + buffer.writeUInt16BE(1234, 0); // Message ID + buffer.writeUInt16BE(11, 2); // Length + buffer.writeUInt16BE(0x101, 4); // Version + buffer.writeUInt32BE(11, 8); // Checksum + buffer.write("test data", 12); // Data + + const packet = new GamePacket(); + packet.deserialize(buffer); + + expect(packet.getMessageId()).toBe(1234); + expect(packet.getDataBuffer().toString("hex")).equals( + Buffer.from("test data\u0000\u0000\u0000\u0000\u0000").toString("hex"), + ); + }); + + it("should throw error if data is insufficient for header", () => { + const buffer = Buffer.alloc(5); // Less than required for header + + const packet = new GamePacket(); + expect(() => packet.deserialize(buffer)).toThrow( + "Data is too short. Expected at least 6 bytes, got 5 bytes", + ); + }); + + it("should throw error if data is insufficient for full packet", () => { + const buffer = Buffer.alloc(10); // Less than required for full packet + buffer.writeUInt16BE(0x101, 4); // Version + + const packet = new GamePacket(); + expect(() => packet.deserialize(buffer)).toThrow( + "Data is too short. Expected at least 12 bytes, got 10 bytes", + ); + }); + + it("should identify version correctly", () => { + const buffer = Buffer.alloc(15); + buffer.writeUInt16BE(11, 0); // Length + buffer.writeUInt16BE(0x101, 4); // Version + buffer.writeUInt16BE(1234, 6); // Message ID + buffer.write("test data", 8, "utf8"); // Data + + const packet = new GamePacket(); + packet.deserialize(buffer); + + expect(packet.getVersion()).toBe(257); + }); + + it("should handle version 0 correctly", () => { + const buffer = Buffer.alloc(15); + buffer.writeUInt16BE(1234, 0); // Message ID + buffer.writeUInt16BE(11, 4); // Length + buffer.writeUInt16BE(0x100, 4); // Version + buffer.write("test data", 8, "utf8"); // Data + + const packet = new GamePacket(); + packet.deserialize(buffer); + + expect(packet.getVersion()).toBe(0); + }); +});