protocol-classicube 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Packet 0x03 - Level Data Chunk (Server -> Client)
3
+ *
4
+ * Sends a chunk of gzipped level data.
5
+ * The level data itself is: Int (block count) + raw block IDs,
6
+ * all gzipped, then split into 1024-byte chunks.
7
+ *
8
+ * Layout:
9
+ * Byte - Packet ID (0x03)
10
+ * Short - Chunk length (number of meaningful bytes in this chunk, 0–1024)
11
+ * ByteArray - 1024 bytes of chunk data (padded with 0x00 if needed)
12
+ * Byte - Percent complete (0–100)
13
+ *
14
+ * Total: 1028 bytes
15
+ */
16
+
17
+ const { BinaryWriter, BinaryReader } = require('../Binary');
18
+ const PacketIDs = require('../PacketIDs');
19
+
20
+ /**
21
+ * @param {object} opts
22
+ * @param {Buffer} opts.chunkData - Raw chunk bytes (up to 1024)
23
+ * @param {number} opts.chunkLength - Actual meaningful bytes in chunkData
24
+ * @param {number} opts.percent - 0-100 completion percent
25
+ */
26
+ function serialize({ chunkData, chunkLength, percent }) {
27
+ return new BinaryWriter()
28
+ .writeByte(PacketIDs.SERVER.LEVEL_DATA_CHUNK)
29
+ .writeShort(chunkLength)
30
+ .writeByteArray(chunkData)
31
+ .writeByte(percent)
32
+ .toBuffer();
33
+ }
34
+
35
+ function deserialize(buf) {
36
+ const r = new BinaryReader(buf);
37
+ const packetId = r.readByte();
38
+ if (packetId !== PacketIDs.SERVER.LEVEL_DATA_CHUNK) {
39
+ throw new Error(`Expected LevelDataChunk (0x03), got 0x${packetId.toString(16)}`);
40
+ }
41
+ const chunkLength = r.readShort();
42
+ const chunkData = r.readByteArray();
43
+ const percent = r.readByte();
44
+ return { packetId, chunkLength, chunkData, percent };
45
+ }
46
+
47
+ module.exports = { serialize, deserialize, PACKET_SIZE: 1028 };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Packet 0x04 - Level Finalize (Server -> Client)
3
+ *
4
+ * Sent after all LevelDataChunk packets. Gives the world dimensions.
5
+ * Layout:
6
+ * Byte - Packet ID (0x04)
7
+ * Short - X size (width)
8
+ * Short - Y size (height)
9
+ * Short - Z size (depth)
10
+ *
11
+ * Total: 7 bytes
12
+ */
13
+
14
+ const { BinaryWriter, BinaryReader } = require('../Binary');
15
+ const PacketIDs = require('../PacketIDs');
16
+
17
+ /**
18
+ * @param {object} opts
19
+ * @param {number} opts.xSize
20
+ * @param {number} opts.ySize
21
+ * @param {number} opts.zSize
22
+ */
23
+ function serialize({ xSize, ySize, zSize }) {
24
+ return new BinaryWriter()
25
+ .writeByte(PacketIDs.SERVER.LEVEL_FINALIZE)
26
+ .writeShort(xSize)
27
+ .writeShort(ySize)
28
+ .writeShort(zSize)
29
+ .toBuffer();
30
+ }
31
+
32
+ function deserialize(buf) {
33
+ const r = new BinaryReader(buf);
34
+ const packetId = r.readByte();
35
+ if (packetId !== PacketIDs.SERVER.LEVEL_FINALIZE) {
36
+ throw new Error(`Expected LevelFinalize (0x04), got 0x${packetId.toString(16)}`);
37
+ }
38
+ const xSize = r.readShort();
39
+ const ySize = r.readShort();
40
+ const zSize = r.readShort();
41
+ return { packetId, xSize, ySize, zSize };
42
+ }
43
+
44
+ module.exports = { serialize, deserialize, PACKET_SIZE: 7 };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Packet 0x02 - Level Initialize (Server -> Client)
3
+ *
4
+ * Tells the client that level data is about to be sent.
5
+ * Layout:
6
+ * Byte - Packet ID (0x02)
7
+ *
8
+ * Total: 1 byte
9
+ */
10
+
11
+ const { BinaryWriter, BinaryReader } = require('../Binary');
12
+ const PacketIDs = require('../PacketIDs');
13
+
14
+ function serialize() {
15
+ return new BinaryWriter()
16
+ .writeByte(PacketIDs.SERVER.LEVEL_INITIALIZE)
17
+ .toBuffer();
18
+ }
19
+
20
+ function deserialize(buf) {
21
+ const r = new BinaryReader(buf);
22
+ const packetId = r.readByte();
23
+ if (packetId !== PacketIDs.SERVER.LEVEL_INITIALIZE) {
24
+ throw new Error(`Expected LevelInitialize (0x02), got 0x${packetId.toString(16)}`);
25
+ }
26
+ return { packetId };
27
+ }
28
+
29
+ module.exports = { serialize, deserialize, PACKET_SIZE: 1 };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Packet 0x01 - Ping (Server -> Client)
3
+ *
4
+ * A single-byte keep-alive packet. No payload.
5
+ * Layout:
6
+ * Byte - Packet ID (0x01)
7
+ *
8
+ * Total: 1 byte
9
+ */
10
+
11
+ const { BinaryWriter, BinaryReader } = require('../Binary');
12
+ const PacketIDs = require('../PacketIDs');
13
+
14
+ function serialize() {
15
+ return new BinaryWriter()
16
+ .writeByte(PacketIDs.SERVER.PING)
17
+ .toBuffer();
18
+ }
19
+
20
+ function deserialize(buf) {
21
+ const r = new BinaryReader(buf);
22
+ const packetId = r.readByte();
23
+ if (packetId !== PacketIDs.SERVER.PING) {
24
+ throw new Error(`Expected Ping (0x01), got 0x${packetId.toString(16)}`);
25
+ }
26
+ return { packetId };
27
+ }
28
+
29
+ module.exports = { serialize, deserialize, PACKET_SIZE: 1 };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Packet 0x00 - Player Identification (Client -> Server)
3
+ *
4
+ * Primer paquete que envia el cliente al conectar.
5
+ * Layout:
6
+ * Byte - Packet ID (0x00)
7
+ * Byte - Protocol version (siempre 7)
8
+ * String - Username (64 bytes)
9
+ * String - Verification key (64 bytes, '-' si no hay auth)
10
+ * Byte - Unused (siempre 0x00)
11
+ *
12
+ * Total: 131 bytes
13
+ */
14
+
15
+ const { BinaryWriter, BinaryReader } = require('../Binary');
16
+ const PacketIDs = require('../PacketIDs');
17
+
18
+ const PROTOCOL_VERSION = 7;
19
+
20
+ /**
21
+ * @param {object} opts
22
+ * @param {string} opts.username
23
+ * @param {string} [opts.verificationKey]
24
+ */
25
+ function serialize({ username, verificationKey = '-' }) {
26
+ return new BinaryWriter()
27
+ .writeByte(PacketIDs.CLIENT.PLAYER_IDENTIFICATION)
28
+ .writeByte(PROTOCOL_VERSION)
29
+ .writeString(username)
30
+ .writeString(verificationKey)
31
+ .writeByte(0x00)
32
+ .toBuffer();
33
+ }
34
+
35
+ function deserialize(buf) {
36
+ const r = new BinaryReader(buf);
37
+ const packetId = r.readByte();
38
+ if (packetId !== PacketIDs.CLIENT.PLAYER_IDENTIFICATION) {
39
+ throw new Error(`Expected PlayerIdentification (0x00), got 0x${packetId.toString(16)}`);
40
+ }
41
+ const protocolVersion = r.readByte();
42
+ const username = r.readString();
43
+ const verificationKey = r.readString();
44
+ r.readByte(); // unused
45
+ return { packetId, protocolVersion, username, verificationKey };
46
+ }
47
+
48
+ module.exports = { serialize, deserialize, PACKET_SIZE: 131, PROTOCOL_VERSION };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Packet 0x0A - Player Move (Server -> Client)
3
+ *
4
+ * Movimiento relativo (delta) de posicion SIN cambio de orientacion.
5
+ * Mas eficiente que PlayerUpdate cuando el jugador no gira.
6
+ *
7
+ * Los deltas son SByte en fixed-point: valor / 32
8
+ *
9
+ * Layout:
10
+ * Byte - Packet ID (0x0A)
11
+ * SByte - Player ID
12
+ * SByte - Delta X (fixed-point * 32)
13
+ * SByte - Delta Y (fixed-point * 32)
14
+ * SByte - Delta Z (fixed-point * 32)
15
+ *
16
+ * Total: 5 bytes
17
+ */
18
+
19
+ const { BinaryWriter, BinaryReader } = require('../Binary');
20
+ const PacketIDs = require('../PacketIDs');
21
+
22
+ /**
23
+ * @param {object} opts
24
+ * @param {number} opts.playerId
25
+ * @param {number} opts.dx
26
+ * @param {number} opts.dy
27
+ * @param {number} opts.dz
28
+ */
29
+ function serialize({ playerId, dx, dy, dz }) {
30
+ return new BinaryWriter()
31
+ .writeByte(PacketIDs.SERVER.PLAYER_MOVE)
32
+ .writeSByte(playerId)
33
+ .writeSByte(Math.round(dx * 32))
34
+ .writeSByte(Math.round(dy * 32))
35
+ .writeSByte(Math.round(dz * 32))
36
+ .toBuffer();
37
+ }
38
+
39
+ function deserialize(buf) {
40
+ const r = new BinaryReader(buf);
41
+ const packetId = r.readByte();
42
+ if (packetId !== PacketIDs.SERVER.PLAYER_MOVE) {
43
+ throw new Error(`Expected PlayerMove (0x0A), got 0x${packetId.toString(16)}`);
44
+ }
45
+ const playerId = r.readSByte();
46
+ const dx = r.readSByte() / 32;
47
+ const dy = r.readSByte() / 32;
48
+ const dz = r.readSByte() / 32;
49
+ return { packetId, playerId, dx, dy, dz };
50
+ }
51
+
52
+ module.exports = { serialize, deserialize, PACKET_SIZE: 5 };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Packet 0x0B - Player Rotate (Server -> Client)
3
+ *
4
+ * Cambio de orientacion SIN movimiento de posicion.
5
+ * Mas eficiente que PlayerUpdate cuando el jugador solo gira en sitio.
6
+ *
7
+ * Layout:
8
+ * Byte - Packet ID (0x0B)
9
+ * SByte - Player ID
10
+ * Byte - Yaw (0-255 = 0-360 grados)
11
+ * Byte - Pitch (0-255 = 0-360 grados)
12
+ *
13
+ * Total: 4 bytes
14
+ */
15
+
16
+ const { BinaryWriter, BinaryReader } = require('../Binary');
17
+ const PacketIDs = require('../PacketIDs');
18
+
19
+ /**
20
+ * @param {object} opts
21
+ * @param {number} opts.playerId
22
+ * @param {number} opts.yaw - 0-255
23
+ * @param {number} opts.pitch - 0-255
24
+ */
25
+ function serialize({ playerId, yaw, pitch }) {
26
+ return new BinaryWriter()
27
+ .writeByte(PacketIDs.SERVER.PLAYER_ROTATE)
28
+ .writeSByte(playerId)
29
+ .writeByte(yaw & 0xFF)
30
+ .writeByte(pitch & 0xFF)
31
+ .toBuffer();
32
+ }
33
+
34
+ function deserialize(buf) {
35
+ const r = new BinaryReader(buf);
36
+ const packetId = r.readByte();
37
+ if (packetId !== PacketIDs.SERVER.PLAYER_ROTATE) {
38
+ throw new Error(`Expected PlayerRotate (0x0B), got 0x${packetId.toString(16)}`);
39
+ }
40
+ const playerId = r.readSByte();
41
+ const yaw = r.readByte();
42
+ const pitch = r.readByte();
43
+ return { packetId, playerId, yaw, pitch };
44
+ }
45
+
46
+ module.exports = { serialize, deserialize, PACKET_SIZE: 4 };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Packet 0x08 - Player Teleport (Server -> Client / Client -> Server)
3
+ *
4
+ * Teleports a player to an absolute position.
5
+ * When sent by the client, Player ID is always 255 (0xFF = self).
6
+ * When sent by the server, Player ID identifies which player to move.
7
+ *
8
+ * Layout:
9
+ * Byte - Packet ID (0x08)
10
+ * SByte - Player ID
11
+ * Short - X (fixed-point * 32)
12
+ * Short - Y (fixed-point * 32)
13
+ * Short - Z (fixed-point * 32)
14
+ * Byte - Yaw
15
+ * Byte - Pitch
16
+ *
17
+ * Total: 10 bytes
18
+ */
19
+
20
+ const { BinaryWriter, BinaryReader } = require('../Binary');
21
+ const PacketIDs = require('../PacketIDs');
22
+
23
+ /**
24
+ * @param {object} opts
25
+ * @param {number} opts.playerId
26
+ * @param {number} opts.x
27
+ * @param {number} opts.y
28
+ * @param {number} opts.z
29
+ * @param {number} opts.yaw
30
+ * @param {number} opts.pitch
31
+ */
32
+ function serialize({ playerId, x, y, z, yaw, pitch }) {
33
+ return new BinaryWriter()
34
+ .writeByte(PacketIDs.SERVER.PLAYER_TELEPORT)
35
+ .writeSByte(playerId)
36
+ .writeShort(Math.round(x * 32))
37
+ .writeShort(Math.round(y * 32))
38
+ .writeShort(Math.round(z * 32))
39
+ .writeByte(yaw & 0xFF)
40
+ .writeByte(pitch & 0xFF)
41
+ .toBuffer();
42
+ }
43
+
44
+ function deserialize(buf) {
45
+ const r = new BinaryReader(buf);
46
+ const packetId = r.readByte();
47
+ if (packetId !== PacketIDs.SERVER.PLAYER_TELEPORT) {
48
+ throw new Error(`Expected PlayerTeleport (0x08), got 0x${packetId.toString(16)}`);
49
+ }
50
+ const playerId = r.readSByte();
51
+ const x = r.readShort() / 32;
52
+ const y = r.readShort() / 32;
53
+ const z = r.readShort() / 32;
54
+ const yaw = r.readByte();
55
+ const pitch = r.readByte();
56
+ return { packetId, playerId, x, y, z, yaw, pitch };
57
+ }
58
+
59
+ module.exports = { serialize, deserialize, PACKET_SIZE: 10 };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Packet 0x09 - Player Update (Server -> Client)
3
+ *
4
+ * Movimiento relativo (delta) de posicion + cambio de orientacion.
5
+ * Se usa para actualizaciones pequenas de posicion (< 4 bloques).
6
+ * Para movimientos grandes usar PlayerTeleport (0x08).
7
+ *
8
+ * Los deltas son SByte en fixed-point: valor / 32
9
+ * Rango util: -4 a +3.96875 bloques por eje.
10
+ *
11
+ * Layout:
12
+ * Byte - Packet ID (0x09)
13
+ * SByte - Player ID
14
+ * SByte - Delta X (fixed-point * 32)
15
+ * SByte - Delta Y (fixed-point * 32)
16
+ * SByte - Delta Z (fixed-point * 32)
17
+ * Byte - Yaw (0-255)
18
+ * Byte - Pitch (0-255)
19
+ *
20
+ * Total: 7 bytes
21
+ */
22
+
23
+ const { BinaryWriter, BinaryReader } = require('../Binary');
24
+ const PacketIDs = require('../PacketIDs');
25
+
26
+ /**
27
+ * @param {object} opts
28
+ * @param {number} opts.playerId
29
+ * @param {number} opts.dx - Delta X en bloques (se multiplica * 32)
30
+ * @param {number} opts.dy - Delta Y en bloques
31
+ * @param {number} opts.dz - Delta Z en bloques
32
+ * @param {number} opts.yaw - 0-255
33
+ * @param {number} opts.pitch - 0-255
34
+ */
35
+ function serialize({ playerId, dx, dy, dz, yaw, pitch }) {
36
+ return new BinaryWriter()
37
+ .writeByte(PacketIDs.SERVER.PLAYER_UPDATE)
38
+ .writeSByte(playerId)
39
+ .writeSByte(Math.round(dx * 32))
40
+ .writeSByte(Math.round(dy * 32))
41
+ .writeSByte(Math.round(dz * 32))
42
+ .writeByte(yaw & 0xFF)
43
+ .writeByte(pitch & 0xFF)
44
+ .toBuffer();
45
+ }
46
+
47
+ function deserialize(buf) {
48
+ const r = new BinaryReader(buf);
49
+ const packetId = r.readByte();
50
+ if (packetId !== PacketIDs.SERVER.PLAYER_UPDATE) {
51
+ throw new Error(`Expected PlayerUpdate (0x09), got 0x${packetId.toString(16)}`);
52
+ }
53
+ const playerId = r.readSByte();
54
+ const dx = r.readSByte() / 32;
55
+ const dy = r.readSByte() / 32;
56
+ const dz = r.readSByte() / 32;
57
+ const yaw = r.readByte();
58
+ const pitch = r.readByte();
59
+ return { packetId, playerId, dx, dy, dz, yaw, pitch };
60
+ }
61
+
62
+ module.exports = { serialize, deserialize, PACKET_SIZE: 7 };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Packet 0x00 - Server Identification (Server -> Client)
3
+ *
4
+ * Sent immediately after client connects.
5
+ * Layout:
6
+ * Byte - Packet ID (0x00)
7
+ * Byte - Protocol version (always 7)
8
+ * String - Server name (64 bytes)
9
+ * String - Server MOTD (64 bytes)
10
+ * Byte - User type (0x00 = normal, 0x64 = op)
11
+ *
12
+ * Total: 131 bytes
13
+ */
14
+
15
+ const { BinaryWriter, BinaryReader } = require('../Binary');
16
+ const PacketIDs = require('../PacketIDs');
17
+
18
+ const PROTOCOL_VERSION = 7;
19
+
20
+ /**
21
+ * Serialize a ServerIdentification packet into a Buffer.
22
+ * @param {object} opts
23
+ * @param {string} opts.name - Server name
24
+ * @param {string} opts.motd - Server MOTD
25
+ * @param {boolean} [opts.op] - Is the connecting player an operator?
26
+ * @returns {Buffer}
27
+ */
28
+ function serialize({ name, motd, op = false }) {
29
+ return new BinaryWriter()
30
+ .writeByte(PacketIDs.SERVER.SERVER_IDENTIFICATION)
31
+ .writeByte(PROTOCOL_VERSION)
32
+ .writeString(name)
33
+ .writeString(motd)
34
+ .writeByte(op ? 0x64 : 0x00)
35
+ .toBuffer();
36
+ }
37
+
38
+ /**
39
+ * Deserialize a ServerIdentification packet from a Buffer.
40
+ * Expects the packet ID byte to already be consumed or present at offset 0.
41
+ * @param {Buffer} buf
42
+ * @returns {{ protocolVersion: number, name: string, motd: string, op: boolean }}
43
+ */
44
+ function deserialize(buf) {
45
+ const r = new BinaryReader(buf);
46
+ const packetId = r.readByte(); // 0x00
47
+ if (packetId !== PacketIDs.SERVER.SERVER_IDENTIFICATION) {
48
+ throw new Error(`Expected ServerIdentification (0x00), got 0x${packetId.toString(16)}`);
49
+ }
50
+ const protocolVersion = r.readByte();
51
+ const name = r.readString();
52
+ const motd = r.readString();
53
+ const userTypeByte = r.readByte();
54
+ return {
55
+ packetId,
56
+ protocolVersion,
57
+ name,
58
+ motd,
59
+ op: userTypeByte === 0x64,
60
+ };
61
+ }
62
+
63
+ module.exports = { serialize, deserialize, PACKET_SIZE: 131 };
@@ -0,0 +1,93 @@
1
+ /**
2
+ * SetBlock packets
3
+ *
4
+ * There are TWO different SetBlock packets:
5
+ *
6
+ * --- SERVER -> CLIENT (0x06) ---
7
+ * Tells the client a block changed.
8
+ * Byte - Packet ID (0x06)
9
+ * Short - X
10
+ * Short - Y
11
+ * Short - Z
12
+ * Byte - Block type
13
+ * Total: 8 bytes
14
+ *
15
+ * --- CLIENT -> SERVER (0x05) ---
16
+ * Client requests placing/destroying a block.
17
+ * Byte - Packet ID (0x05)
18
+ * Short - X
19
+ * Short - Y
20
+ * Short - Z
21
+ * Byte - Mode (0x00 = destroy, 0x01 = create)
22
+ * Byte - Block type
23
+ * Total: 9 bytes
24
+ */
25
+
26
+ const { BinaryWriter, BinaryReader } = require('../Binary');
27
+ const PacketIDs = require('../PacketIDs');
28
+
29
+ // Block placement modes
30
+ const Mode = {
31
+ DESTROY: 0x00,
32
+ CREATE: 0x01,
33
+ };
34
+
35
+ /**
36
+ * Server->Client: notify block change
37
+ */
38
+ function serializeServer({ x, y, z, blockType }) {
39
+ return new BinaryWriter()
40
+ .writeByte(PacketIDs.SERVER.SET_BLOCK)
41
+ .writeShort(x)
42
+ .writeShort(y)
43
+ .writeShort(z)
44
+ .writeByte(blockType)
45
+ .toBuffer();
46
+ }
47
+
48
+ function deserializeServer(buf) {
49
+ const r = new BinaryReader(buf);
50
+ const packetId = r.readByte();
51
+ if (packetId !== PacketIDs.SERVER.SET_BLOCK) {
52
+ throw new Error(`Expected SetBlock server (0x06), got 0x${packetId.toString(16)}`);
53
+ }
54
+ const x = r.readShort();
55
+ const y = r.readShort();
56
+ const z = r.readShort();
57
+ const blockType = r.readByte();
58
+ return { packetId, x, y, z, blockType };
59
+ }
60
+
61
+ /**
62
+ * Client->Server: request block change
63
+ */
64
+ function serializeClient({ x, y, z, mode, blockType }) {
65
+ return new BinaryWriter()
66
+ .writeByte(PacketIDs.CLIENT.SET_BLOCK)
67
+ .writeShort(x)
68
+ .writeShort(y)
69
+ .writeShort(z)
70
+ .writeByte(mode)
71
+ .writeByte(blockType)
72
+ .toBuffer();
73
+ }
74
+
75
+ function deserializeClient(buf) {
76
+ const r = new BinaryReader(buf);
77
+ const packetId = r.readByte();
78
+ if (packetId !== PacketIDs.CLIENT.SET_BLOCK) {
79
+ throw new Error(`Expected SetBlock client (0x05), got 0x${packetId.toString(16)}`);
80
+ }
81
+ const x = r.readShort();
82
+ const y = r.readShort();
83
+ const z = r.readShort();
84
+ const mode = r.readByte();
85
+ const blockType = r.readByte();
86
+ return { packetId, x, y, z, mode, blockType };
87
+ }
88
+
89
+ module.exports = {
90
+ Mode,
91
+ server: { serialize: serializeServer, deserialize: deserializeServer, PACKET_SIZE: 8 },
92
+ client: { serialize: serializeClient, deserialize: deserializeClient, PACKET_SIZE: 9 },
93
+ };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Packet 0x07 - Spawn Player (Server -> Client)
3
+ *
4
+ * Spawns a player entity in the world.
5
+ * Player ID -1 (0xFF) = the local player.
6
+ *
7
+ * Layout:
8
+ * Byte - Packet ID (0x07)
9
+ * SByte - Player ID (-1 for self)
10
+ * String - Player name (64 bytes)
11
+ * Short - X (fixed-point: value / 32)
12
+ * Short - Y (fixed-point: value / 32)
13
+ * Short - Z (fixed-point: value / 32)
14
+ * Byte - Yaw (0-255 maps to 0-360°)
15
+ * Byte - Pitch (0-255 maps to 0-360°)
16
+ *
17
+ * Total: 74 bytes
18
+ */
19
+
20
+ const { BinaryWriter, BinaryReader } = require('../Binary');
21
+ const PacketIDs = require('../PacketIDs');
22
+
23
+ /**
24
+ * @param {object} opts
25
+ * @param {number} opts.playerId - -1 for self, 0-127 for others
26
+ * @param {string} opts.name - Player name
27
+ * @param {number} opts.x - Block-space X (will be multiplied by 32)
28
+ * @param {number} opts.y - Block-space Y
29
+ * @param {number} opts.z - Block-space Z
30
+ * @param {number} opts.yaw - 0-255
31
+ * @param {number} opts.pitch - 0-255
32
+ */
33
+ function serialize({ playerId, name, x, y, z, yaw, pitch }) {
34
+ return new BinaryWriter()
35
+ .writeByte(PacketIDs.SERVER.SPAWN_PLAYER)
36
+ .writeSByte(playerId)
37
+ .writeString(name)
38
+ .writeShort(Math.round(x * 32))
39
+ .writeShort(Math.round(y * 32))
40
+ .writeShort(Math.round(z * 32))
41
+ .writeByte(yaw & 0xFF)
42
+ .writeByte(pitch & 0xFF)
43
+ .toBuffer();
44
+ }
45
+
46
+ function deserialize(buf) {
47
+ const r = new BinaryReader(buf);
48
+ const packetId = r.readByte();
49
+ if (packetId !== PacketIDs.SERVER.SPAWN_PLAYER) {
50
+ throw new Error(`Expected SpawnPlayer (0x07), got 0x${packetId.toString(16)}`);
51
+ }
52
+ const playerId = r.readSByte();
53
+ const name = r.readString();
54
+ const x = r.readShort() / 32;
55
+ const y = r.readShort() / 32;
56
+ const z = r.readShort() / 32;
57
+ const yaw = r.readByte();
58
+ const pitch = r.readByte();
59
+ return { packetId, playerId, name, x, y, z, yaw, pitch };
60
+ }
61
+
62
+ module.exports = { serialize, deserialize, PACKET_SIZE: 74 };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Packet 0x0F - Update User Type (Server -> Client)
3
+ *
4
+ * Actualiza los permisos del jugador en tiempo real.
5
+ * Usado para dar/quitar rango de operador sin reconectar.
6
+ *
7
+ * User type values:
8
+ * 0x00 = jugador normal
9
+ * 0x64 = operador (puede borrar bloques de bedrock, etc.)
10
+ *
11
+ * Layout:
12
+ * Byte - Packet ID (0x0F)
13
+ * Byte - User type (0x00 normal | 0x64 op)
14
+ *
15
+ * Total: 2 bytes
16
+ */
17
+
18
+ const { BinaryWriter, BinaryReader } = require('../Binary');
19
+ const PacketIDs = require('../PacketIDs');
20
+
21
+ const UserType = {
22
+ NORMAL: 0x00,
23
+ OPERATOR: 0x64,
24
+ };
25
+
26
+ /**
27
+ * @param {object} opts
28
+ * @param {boolean} opts.op - true = operador, false = normal
29
+ */
30
+ function serialize({ op }) {
31
+ return new BinaryWriter()
32
+ .writeByte(PacketIDs.SERVER.UPDATE_USER_TYPE)
33
+ .writeByte(op ? UserType.OPERATOR : UserType.NORMAL)
34
+ .toBuffer();
35
+ }
36
+
37
+ function deserialize(buf) {
38
+ const r = new BinaryReader(buf);
39
+ const packetId = r.readByte();
40
+ if (packetId !== PacketIDs.SERVER.UPDATE_USER_TYPE) {
41
+ throw new Error(`Expected UpdateUserType (0x0F), got 0x${packetId.toString(16)}`);
42
+ }
43
+ const userType = r.readByte();
44
+ return {
45
+ packetId,
46
+ userType,
47
+ op: userType === UserType.OPERATOR,
48
+ };
49
+ }
50
+
51
+ module.exports = { serialize, deserialize, PACKET_SIZE: 2, UserType };