@vaitosoi/minejs 0.2.1 → 0.2.2

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.
Files changed (80) hide show
  1. package/dist/base/aabb.d.ts +197 -0
  2. package/dist/base/aabb.d.ts.map +1 -0
  3. package/dist/base/aabb.js +576 -0
  4. package/dist/base/aabb.js.map +1 -0
  5. package/dist/base/bitset.d.ts +9 -0
  6. package/dist/base/bitset.d.ts.map +1 -0
  7. package/dist/base/bitset.js +46 -0
  8. package/dist/base/bitset.js.map +1 -0
  9. package/dist/base/block.d.ts +86 -0
  10. package/dist/base/block.d.ts.map +1 -0
  11. package/dist/base/block.js +232 -0
  12. package/dist/base/block.js.map +1 -0
  13. package/dist/base/direction.d.ts +153 -0
  14. package/dist/base/direction.d.ts.map +1 -0
  15. package/dist/base/direction.js +288 -0
  16. package/dist/base/direction.js.map +1 -0
  17. package/dist/base/entity.d.ts +43 -0
  18. package/dist/base/entity.d.ts.map +1 -0
  19. package/dist/base/entity.js +97 -0
  20. package/dist/base/entity.js.map +1 -0
  21. package/dist/base/error.d.ts +76 -0
  22. package/dist/base/error.d.ts.map +1 -0
  23. package/dist/base/error.js +141 -0
  24. package/dist/base/error.js.map +1 -0
  25. package/dist/base/event.d.ts +7 -0
  26. package/dist/base/event.d.ts.map +1 -0
  27. package/dist/base/event.js +3 -0
  28. package/dist/base/event.js.map +1 -0
  29. package/dist/base/math.d.ts +25 -0
  30. package/dist/base/math.d.ts.map +1 -0
  31. package/dist/base/math.js +69 -0
  32. package/dist/base/math.js.map +1 -0
  33. package/dist/base/player.d.ts +107 -0
  34. package/dist/base/player.d.ts.map +1 -0
  35. package/dist/base/player.js +543 -0
  36. package/dist/base/player.js.map +1 -0
  37. package/dist/base/registry.d.ts +50 -0
  38. package/dist/base/registry.d.ts.map +1 -0
  39. package/dist/base/registry.js +89 -0
  40. package/dist/base/registry.js.map +1 -0
  41. package/dist/base/tick.d.ts +19 -0
  42. package/dist/base/tick.d.ts.map +1 -0
  43. package/dist/base/tick.js +49 -0
  44. package/dist/base/tick.js.map +1 -0
  45. package/dist/base/typing.d.ts +3 -0
  46. package/dist/base/typing.d.ts.map +1 -0
  47. package/dist/base/typing.js +3 -0
  48. package/dist/base/typing.js.map +1 -0
  49. package/dist/client/auth.d.ts +39 -0
  50. package/dist/client/auth.d.ts.map +1 -0
  51. package/dist/client/auth.js +307 -0
  52. package/dist/client/auth.js.map +1 -0
  53. package/dist/client/client.d.ts +62 -0
  54. package/dist/client/client.d.ts.map +1 -0
  55. package/dist/client/client.js +98 -0
  56. package/dist/client/client.js.map +1 -0
  57. package/dist/client/static.d.ts +28 -0
  58. package/dist/client/static.d.ts.map +1 -0
  59. package/dist/client/static.js +43 -0
  60. package/dist/client/static.js.map +1 -0
  61. package/dist/client/tcp.d.ts +269 -0
  62. package/dist/client/tcp.d.ts.map +1 -0
  63. package/dist/client/tcp.js +838 -0
  64. package/dist/client/tcp.js.map +1 -0
  65. package/dist/index.d.ts +21 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/translator/decoder.d.ts +293 -0
  69. package/dist/translator/decoder.d.ts.map +1 -0
  70. package/dist/translator/decoder.js +668 -0
  71. package/dist/translator/decoder.js.map +1 -0
  72. package/dist/translator/encoder.d.ts +162 -0
  73. package/dist/translator/encoder.d.ts.map +1 -0
  74. package/dist/translator/encoder.js +430 -0
  75. package/dist/translator/encoder.js.map +1 -0
  76. package/dist/translator/static.d.ts +33 -0
  77. package/dist/translator/static.d.ts.map +1 -0
  78. package/dist/translator/static.js +42 -0
  79. package/dist/translator/static.js.map +1 -0
  80. package/package.json +1 -1
@@ -0,0 +1,838 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TCPClient = exports.ClientState = exports.ClientStatus = exports.GameMode = void 0;
4
+ const node_net_1 = require("node:net");
5
+ const node_events_1 = require("node:events");
6
+ const node_crypto_1 = require("node:crypto");
7
+ const node_zlib_1 = require("node:zlib");
8
+ const decoder_1 = require("../translator/decoder");
9
+ const encoder_1 = require("../translator/encoder");
10
+ const error_1 = require("../base/error");
11
+ const math_1 = require("../base/math");
12
+ const static_1 = require("./static");
13
+ const auth_1 = require("./auth");
14
+ var GameMode;
15
+ (function (GameMode) {
16
+ GameMode[GameMode["Survival"] = 0] = "Survival";
17
+ GameMode[GameMode["Creative"] = 1] = "Creative";
18
+ GameMode[GameMode["Adventure"] = 2] = "Adventure";
19
+ GameMode[GameMode["Spectator"] = 3] = "Spectator";
20
+ })(GameMode || (exports.GameMode = GameMode = {}));
21
+ var ClientStatus;
22
+ (function (ClientStatus) {
23
+ ClientStatus[ClientStatus["Disconnected"] = 0] = "Disconnected";
24
+ ClientStatus[ClientStatus["Connecting"] = 1] = "Connecting";
25
+ ClientStatus[ClientStatus["Logining"] = 2] = "Logining";
26
+ ClientStatus[ClientStatus["Ready"] = 3] = "Ready";
27
+ })(ClientStatus || (exports.ClientStatus = ClientStatus = {}));
28
+ var ClientState;
29
+ (function (ClientState) {
30
+ ClientState[ClientState["Disconnected"] = 0] = "Disconnected";
31
+ ClientState[ClientState["Handshake"] = 1] = "Handshake";
32
+ ClientState[ClientState["Login"] = 2] = "Login";
33
+ ClientState[ClientState["Configure"] = 3] = "Configure";
34
+ ClientState[ClientState["Play"] = 4] = "Play";
35
+ })(ClientState || (exports.ClientState = ClientState = {}));
36
+ // export enum TCPServerIntent {
37
+ // Status = 1,
38
+ // Login = 2,
39
+ // Transfer = 3,
40
+ // }
41
+ /**
42
+ * Low-level client. You SHOULD NOT use this client unless you know what are you doing
43
+ *
44
+ * @see https://minecraft.wiki/w/Java_Edition_protocol/Packets?oldid=3445844
45
+ */
46
+ class TCPClient extends node_events_1.EventEmitter {
47
+ option;
48
+ socket;
49
+ server = undefined;
50
+ // Internal var
51
+ /**
52
+ * | Value | Meaning |
53
+ * |-------|---------|
54
+ * | 0 | not set yet |
55
+ * | -1 | dont compress |
56
+ * | > 0 | compression threshold |
57
+ */
58
+ compressionThreshold = 0;
59
+ bufferPool = Buffer.alloc(0);
60
+ status = ClientStatus.Disconnected;
61
+ state = ClientState.Disconnected;
62
+ // Encryption
63
+ sharedSecret = undefined;
64
+ cipher = undefined;
65
+ decipher = undefined;
66
+ // Play data
67
+ world;
68
+ player;
69
+ registry;
70
+ // Initial data
71
+ playerUUID;
72
+ constructor(option, socketOption) {
73
+ super();
74
+ this.option = option;
75
+ this.socket = new node_net_1.Socket(socketOption);
76
+ this.wipePlayData();
77
+ if (!option.isOffline && !option.auth)
78
+ throw new error_1.MissingAuthOption();
79
+ }
80
+ wipePlayData() {
81
+ this.world = null;
82
+ this.player = null;
83
+ this.registry = null;
84
+ }
85
+ /**
86
+ * Connect to server
87
+ */
88
+ async connect() {
89
+ if (!this.playerUUID) {
90
+ if (this.option.auth) {
91
+ const authClient = new auth_1.AuthClient(this.option.auth);
92
+ const { uuid } = await authClient.auth();
93
+ this.playerUUID = Buffer.from(uuid);
94
+ }
95
+ else
96
+ this.playerUUID = (0, math_1.computeUUID)(this.option.playerName);
97
+ }
98
+ this.status = ClientStatus.Connecting;
99
+ const connection = this.socket.connect({
100
+ host: this.option.host,
101
+ port: this.option.port
102
+ });
103
+ connection.on("connect", () => {
104
+ this.emit("connect");
105
+ this.wipePlayData();
106
+ this.sendHandshake();
107
+ this.sendLoginStart();
108
+ });
109
+ connection.on("data", (data) => {
110
+ let buf = Buffer.from(data);
111
+ if (this.decipher) {
112
+ buf = this.decipher.update(buf);
113
+ }
114
+ this.emit("raw", Buffer.from(buf));
115
+ this.bufferPool = Buffer.concat([this.bufferPool, buf]);
116
+ this.handlePacket();
117
+ });
118
+ connection.once("end", () => {
119
+ if (this.status === ClientStatus.Disconnected)
120
+ return;
121
+ this.status = ClientStatus.Disconnected;
122
+ this.state = ClientState.Disconnected;
123
+ this.emit("disconnect", "socket close");
124
+ });
125
+ connection.once("close", () => {
126
+ if (this.status === ClientStatus.Disconnected)
127
+ return;
128
+ this.status = ClientStatus.Disconnected;
129
+ this.state = ClientState.Disconnected;
130
+ this.emit("disconnect", "socket close");
131
+ });
132
+ }
133
+ disconnect() {
134
+ if (!this.socket.closed)
135
+ this.socket.destroy();
136
+ }
137
+ isReady() {
138
+ return this.status === ClientStatus.Ready;
139
+ }
140
+ checkReady() {
141
+ if (!this.isReady())
142
+ throw new error_1.ClientNotReady();
143
+ return true;
144
+ }
145
+ /*
146
+ * Read packet
147
+ */
148
+ handlePacket() {
149
+ while (true) {
150
+ if (this.bufferPool.length === 0)
151
+ break;
152
+ let decoder = new decoder_1.BinaryDecoder(this.bufferPool);
153
+ let packetLength;
154
+ try {
155
+ packetLength = decoder.readVarInt();
156
+ }
157
+ catch (e) {
158
+ break; // Not enough data to read VarInt
159
+ }
160
+ if (this.bufferPool.length - decoder.offset < packetLength)
161
+ break;
162
+ const expectedPacketEnd = decoder.offset + packetLength;
163
+ let packetID;
164
+ if (this.compressionThreshold === 0)
165
+ packetID = decoder.readVarInt();
166
+ else if (this.compressionThreshold === -1) {
167
+ decoder.readVarInt();
168
+ packetID = decoder.readVarInt();
169
+ }
170
+ else {
171
+ const dataLength = decoder.readVarInt();
172
+ if (dataLength === 0) {
173
+ packetID = decoder.readVarInt();
174
+ }
175
+ else {
176
+ const dataBuffer = this.bufferPool.subarray(decoder.offset, expectedPacketEnd);
177
+ const decompressed = (0, node_zlib_1.inflateSync)(dataBuffer);
178
+ decoder = new decoder_1.BinaryDecoder(decompressed);
179
+ packetID = decoder.readVarInt();
180
+ }
181
+ }
182
+ // Debug
183
+ if (this.option.debug?.packetLogger)
184
+ console.dir({
185
+ state: ClientState[this.state],
186
+ packetID: "0x" + packetID.toString(16),
187
+ length: decoder.buffer.length
188
+ });
189
+ switch (packetID) {
190
+ case 0x00:
191
+ if (this.state === ClientState.Login)
192
+ this.handleLoginDisconnect(decoder);
193
+ break;
194
+ case 0x01:
195
+ if (this.state === ClientState.Login)
196
+ this.handleEncryption(decoder);
197
+ if (this.state === ClientState.Play)
198
+ this.handleSpawnEntity(decoder);
199
+ break;
200
+ case 0x02:
201
+ if (this.state === ClientState.Configure)
202
+ this.handleConfiguarionPlayDisconnect(decoder);
203
+ if (this.state === ClientState.Login)
204
+ this.handleLoginSucess(decoder);
205
+ break;
206
+ case 0x03:
207
+ if (this.state === ClientState.Login)
208
+ this.handleSetCompression(decoder);
209
+ if (this.state === ClientState.Configure)
210
+ this.sendConfigureAck();
211
+ break;
212
+ case 0x06:
213
+ if (this.state === ClientState.Play)
214
+ this.handleBlockEntityData(decoder);
215
+ break;
216
+ case 0x07:
217
+ if (this.state === ClientState.Configure)
218
+ this.handleRegistryData(decoder);
219
+ break;
220
+ case 0x0A:
221
+ if (this.state === ClientState.Play)
222
+ this.handleChangeGameMode(decoder);
223
+ break;
224
+ case 0x0E:
225
+ if (this.state === ClientState.Configure)
226
+ this.handleKnownPack(decoder);
227
+ break;
228
+ case 0x20:
229
+ if (this.state === ClientState.Play)
230
+ this.handleConfiguarionPlayDisconnect(decoder);
231
+ break;
232
+ case 0x21:
233
+ if (this.state === ClientState.Play)
234
+ this.handleDisguisedChatMessage(decoder);
235
+ break;
236
+ case 0x23:
237
+ if (this.state === ClientState.Play)
238
+ this.handleTeleportEntity(decoder);
239
+ break;
240
+ case 0x25:
241
+ if (this.state === ClientState.Play)
242
+ this.handleUnloadChunk(decoder);
243
+ break;
244
+ case 0x2D:
245
+ if (this.state === ClientState.Play)
246
+ this.handleChunkData(decoder);
247
+ break;
248
+ case 0x2C:
249
+ if (this.state === ClientState.Play)
250
+ this.handleKeepAlive(decoder);
251
+ break;
252
+ case 0x31:
253
+ if (this.state === ClientState.Play)
254
+ this.handlePlayLogin(decoder);
255
+ break;
256
+ case 0x35:
257
+ if (this.state === ClientState.Play)
258
+ this.handleUpdateEntityPosition(decoder);
259
+ break;
260
+ case 0x36:
261
+ if (this.state === ClientState.Play)
262
+ this.handleUpdateEntityPositionRotation(decoder);
263
+ break;
264
+ case 0x41:
265
+ if (this.state === ClientState.Play)
266
+ this.handlePlayerChat(decoder);
267
+ break;
268
+ case 0x48:
269
+ if (this.state === ClientState.Play)
270
+ this.handleSynchronizePlayerPosition(decoder);
271
+ break;
272
+ case 0x4D:
273
+ if (this.state === ClientState.Play)
274
+ this.handleRemoveEntity(decoder);
275
+ break;
276
+ case 0x57:
277
+ if (this.state === ClientState.Play)
278
+ this.handleSetActionBar(decoder);
279
+ break;
280
+ case 0x65:
281
+ if (this.state === ClientState.Play)
282
+ this.handleSetEntityVelocity(decoder);
283
+ break;
284
+ case 0x79:
285
+ if (this.state === ClientState.Play)
286
+ this.handleSystemMessage(decoder);
287
+ break;
288
+ }
289
+ this.bufferPool = this.bufferPool.subarray(expectedPacketEnd);
290
+ }
291
+ }
292
+ // Login
293
+ handleLoginDisconnect(decoder) {
294
+ const reason = JSON.parse(decoder.readString());
295
+ const text = (0, decoder_1.getTextFromTextComponent)(reason);
296
+ this.status = ClientStatus.Disconnected;
297
+ this.state = ClientState.Disconnected;
298
+ this.wipePlayData();
299
+ this.emit("disconnect", text.toString());
300
+ this.emit("disconnectRaw", reason);
301
+ this.disconnect();
302
+ }
303
+ handleEncryption(decoder) {
304
+ const serverId = decoder.readString(); // Should be ignored in 1.7+ server
305
+ const publicKey = decoder.readRawPrefixedArray(8);
306
+ const verifyToken = decoder.readRawPrefixedArray(8);
307
+ const shoudlCallMojang = decoder.readBoolean(); // I'm too lazy to do this D:
308
+ const sharedSecret = (0, node_crypto_1.randomBytes)(16);
309
+ this.sharedSecret = sharedSecret;
310
+ this.cipher = (0, node_crypto_1.createCipheriv)("aes-128-cfb8", this.sharedSecret, this.sharedSecret);
311
+ this.decipher = (0, node_crypto_1.createDecipheriv)("aes-128-cfb8", this.sharedSecret, this.sharedSecret);
312
+ this.sendEncryptionResponse(publicKey, verifyToken);
313
+ }
314
+ handleSetCompression(decoder) {
315
+ const threshold = decoder.readVarInt();
316
+ if (threshold < 0)
317
+ this.compressionThreshold = -1;
318
+ else
319
+ this.compressionThreshold = threshold;
320
+ }
321
+ handleLoginSucess(decoder) {
322
+ const uuid = decoder.readUUID();
323
+ const username = decoder.readString();
324
+ this.player = {
325
+ uuid,
326
+ username,
327
+ entityId: 0,
328
+ dimension: "",
329
+ gameMode: GameMode.Survival,
330
+ position: {
331
+ x: 0,
332
+ y: 0,
333
+ z: 0,
334
+ },
335
+ velocity: {
336
+ x: 0,
337
+ y: 0,
338
+ z: 0,
339
+ },
340
+ angle: {
341
+ yaw: 0,
342
+ pitch: 0,
343
+ }
344
+ };
345
+ this.sendLoginAck();
346
+ }
347
+ // Configure
348
+ handleKnownPack(decoder) {
349
+ const packs = decoder.readPrefixedArray((decoder) => ({
350
+ namespace: decoder.readString(),
351
+ id: decoder.readString(),
352
+ version: decoder.readString()
353
+ }));
354
+ this.server.knownPacks = packs;
355
+ // this.sendKnownPack(this.option.loadRegistry === true ? [] : packs);
356
+ this.sendKnownPack([]);
357
+ }
358
+ handleRegistryData(decoder) {
359
+ const id = decoder.readString();
360
+ const entries = decoder.readPrefixedArray((decoder) => ({
361
+ id: decoder.readString(),
362
+ data: decoder.readPrefixedOptional((decoder) => decoder.readNBT())
363
+ }));
364
+ if (!this.registry)
365
+ this.registry = {};
366
+ const registry = this.registry;
367
+ if (!(id in registry))
368
+ registry[id] = [];
369
+ registry[id].push(...entries);
370
+ }
371
+ handleConfiguarionPlayDisconnect(decoder) {
372
+ const reason = decoder.readNBT();
373
+ const text = (0, decoder_1.getTextFromTextComponent)(reason);
374
+ this.status = ClientStatus.Disconnected;
375
+ this.state = ClientState.Disconnected;
376
+ this.wipePlayData();
377
+ this.emit("disconnect", text.toString());
378
+ this.emit("disconnectRaw", reason);
379
+ this.disconnect();
380
+ }
381
+ // Play
382
+ handlePlayLogin(decoder) {
383
+ const entityId = decoder.readInt(), isHardcore = decoder.readBoolean(), dimensions = decoder.readPrefixedArray((decoder) => decoder.readString()), maxPlayers = decoder.readVarInt(), viewDistance = decoder.readVarInt(), simulationDistance = decoder.readVarInt();
384
+ decoder.readBoolean(); // Reduced Debug Info
385
+ decoder.readBoolean(); // Enable respawn screen
386
+ decoder.readBoolean(); // Do limited crafting
387
+ decoder.readVarInt(); // Dimension Type
388
+ const dimensionName = decoder.readString();
389
+ decoder.readLong(); // Hashed seed
390
+ const gameMode = decoder.readUByte();
391
+ this.world = {
392
+ hardcore: isHardcore,
393
+ dimensions,
394
+ maxPlayers,
395
+ viewDistance,
396
+ simulationDistance,
397
+ chunks: {},
398
+ entities: {}
399
+ }; // To avoid type conflict
400
+ this.player.dimension = dimensionName;
401
+ this.player.entityId = entityId;
402
+ this.player.gameMode = gameMode;
403
+ this.status = ClientStatus.Ready;
404
+ this.emit("ready", this);
405
+ }
406
+ handleSynchronizePlayerPosition(decoder) {
407
+ const teleportId = decoder.readVarInt();
408
+ const x = decoder.readDouble(), y = decoder.readDouble(), z = decoder.readDouble(), velX = decoder.readDouble(), velY = decoder.readDouble(), velZ = decoder.readDouble(), yaw = decoder.readFloat() % 360, pitch = decoder.readFloat() % 360;
409
+ const flag = decoder.readTeleportFlag();
410
+ const { position, velocity, angle } = this.player;
411
+ let { x: newPosX, y: newPosY, z: newPosZ } = position;
412
+ let { x: newVelX, y: newVelY, z: newVelZ } = velocity;
413
+ let { yaw: newYaw, pitch: newPitch } = angle;
414
+ if (flag.x)
415
+ newPosX += x;
416
+ else
417
+ newPosX = x;
418
+ if (flag.y)
419
+ newPosY += y;
420
+ else
421
+ newPosY = y;
422
+ if (flag.z)
423
+ newPosZ += z;
424
+ else
425
+ newPosZ = z;
426
+ if (flag.velX)
427
+ newVelX += velX;
428
+ else
429
+ newVelX = velX;
430
+ if (flag.velY)
431
+ newVelY += velY;
432
+ else
433
+ newVelY = velY;
434
+ if (flag.velZ)
435
+ newVelZ += velZ;
436
+ else
437
+ newVelZ = velZ;
438
+ if (flag.yaw)
439
+ newYaw += yaw;
440
+ else
441
+ newYaw = yaw;
442
+ if (flag.pitch)
443
+ newPitch += pitch;
444
+ else
445
+ newPitch = pitch;
446
+ const newPosition = { x: newPosX, y: newPosY, z: newPosZ }, newVelocity = { x: newVelX, y: newVelY, z: newVelZ }, newAngle = { yaw: newYaw, pitch: newPitch };
447
+ this.player = {
448
+ ...this.player,
449
+ position: newPosition,
450
+ velocity: newVelocity,
451
+ angle: newAngle,
452
+ };
453
+ this.emit("playerPosition", { x: newPosX, y: newPosY, z: newPosZ });
454
+ this.sendConfirmTeleportation(teleportId);
455
+ this.sendPlayerPosRot(newPosition, newAngle, true, false);
456
+ }
457
+ handleKeepAlive(decoder) {
458
+ const aliveID = decoder.readLong();
459
+ this.sendKeepAlive(aliveID);
460
+ }
461
+ handleChangeGameMode(decoder) {
462
+ const gameMode = decoder.readUByte();
463
+ this.player.gameMode = gameMode;
464
+ }
465
+ // Chunk
466
+ handleChunkData(decoder) {
467
+ const chunkX = decoder.readInt(), chunkZ = decoder.readInt(), heightMaps = decoder.readPrefixedArray(decoder => ({
468
+ type: decoder.readVarInt(),
469
+ data: decoder.readPrefixedArray(decoder => decoder.readLong())
470
+ })), // Not used yet
471
+ chunkData = decoder.readPrefixedArray(decoder => decoder.readByte()), blockEntities = decoder.readPrefixedArray(decoder => {
472
+ const packedXZ = decoder.readByte(), y = decoder.readShort(), type = decoder.readVarInt(), nbt = decoder.readNBT();
473
+ const x = (packedXZ >> 4) & 15, z = packedXZ & 15;
474
+ const packedPosition = (0, static_1.packBlockPos)(x, y, z);
475
+ return { packedPosition, type, nbt };
476
+ });
477
+ // this.world!.chunks[`${this.player!.dimension}:${chunkX}:${chunkZ}`] = [];
478
+ const chunkSections = {};
479
+ const chunkDataDecoder = new decoder_1.BinaryDecoder(Buffer.from(chunkData));
480
+ for (let height = 0; height < (static_1.SectionsPerChunk[this.player.dimension] || 0); height++) {
481
+ const blockCount = chunkDataDecoder.readShort();
482
+ const fluidCount = chunkDataDecoder.readShort();
483
+ // Blocks
484
+ let blockStateBPE = chunkDataDecoder.readUByte();
485
+ let blockStatePalettes = [];
486
+ if (blockStateBPE === 0) {
487
+ blockStatePalettes = [chunkDataDecoder.readVarInt()];
488
+ }
489
+ else if (blockStateBPE <= 8) {
490
+ // Indirect palette
491
+ if (blockStateBPE < 4)
492
+ blockStateBPE = 4; // BPE smaller than 4 will be rounđe up to 4
493
+ blockStatePalettes = chunkDataDecoder.readPrefixedArray(decoder => decoder.readVarInt());
494
+ }
495
+ else {
496
+ // Direct palette (no palette array)
497
+ }
498
+ const blockEntriesPerSection = 4096;
499
+ const blockEntriesPerLong = Math.floor(64 / blockStateBPE);
500
+ let blockDataArray = null;
501
+ if (blockStateBPE !== 0) {
502
+ const blockDataArrayLength = Math.floor((blockEntriesPerSection + blockEntriesPerLong - 1) / blockEntriesPerLong);
503
+ blockDataArray = new BigInt64Array(chunkDataDecoder.readArray(blockDataArrayLength, (decoder) => decoder.readLong()));
504
+ }
505
+ // Biomes - Not used yet, but need to be read to advance decoder
506
+ const biomeBPE = chunkDataDecoder.readUByte();
507
+ let biomePalettes = [];
508
+ if (biomeBPE === 0) {
509
+ biomePalettes = [chunkDataDecoder.readVarInt()]; // Palette value
510
+ }
511
+ else if (biomeBPE <= 3) {
512
+ // Indirect palette
513
+ biomePalettes = chunkDataDecoder.readPrefixedArray(decoder => decoder.readVarInt());
514
+ }
515
+ else {
516
+ // Direct palette (no palette array)
517
+ }
518
+ const biomeEntriesPerSection = 64;
519
+ const biomeEntriesPerLong = Math.floor(64 / biomeBPE);
520
+ let biomeDataArray = null;
521
+ if (biomeBPE !== 0) {
522
+ const biomeDataArrayLength = Math.floor((biomeEntriesPerSection + biomeEntriesPerLong - 1) / biomeEntriesPerLong);
523
+ biomeDataArray = new BigInt64Array(chunkDataDecoder.readArray(biomeDataArrayLength, (decoder) => decoder.readLong()));
524
+ }
525
+ chunkSections[height] = {
526
+ block: {
527
+ bpe: blockStateBPE,
528
+ palette: blockStatePalettes,
529
+ data: blockDataArray
530
+ },
531
+ biome: {
532
+ bpe: biomeBPE,
533
+ palette: biomePalettes,
534
+ data: biomeDataArray
535
+ }
536
+ };
537
+ this.emit("loadChunk", chunkX, height, chunkZ);
538
+ }
539
+ const blockEntitiesObj = Object.fromEntries(blockEntities.map(val => [val.packedPosition, { type: val.type, data: val.nbt }]));
540
+ this.world.chunks[`${this.player.dimension}:${chunkX}:${chunkZ}`] = {
541
+ sections: chunkSections,
542
+ blockEntities: blockEntitiesObj
543
+ };
544
+ }
545
+ handleUnloadChunk(decoder) {
546
+ const chunkZ = decoder.readInt(), chunkX = decoder.readInt();
547
+ delete this.world.chunks[`${this.player.dimension}:${chunkX}:${chunkZ}`];
548
+ this.emit("unloadChunk", chunkX, chunkZ);
549
+ }
550
+ handleBlockEntityData(decoder) {
551
+ const location = decoder.readPosition(), type = decoder.readVarInt(), data = decoder.readNBT();
552
+ const chunkX = Math.floor(location.x / 16), chunkZ = Math.floor(location.z / 16);
553
+ const xWitinChunk = location.x % 16, zWitinChunk = location.z % 16;
554
+ const packedPosition = (0, static_1.packBlockPos)(xWitinChunk, location.y, zWitinChunk);
555
+ if (`${this.player.dimension}:${chunkX}:${chunkZ}` in this.world.chunks)
556
+ this.world.chunks[`${this.player.dimension}:${chunkX}:${chunkZ}`].blockEntities[packedPosition] = {
557
+ type,
558
+ data
559
+ };
560
+ }
561
+ // Entity
562
+ handleSpawnEntity(decoder) {
563
+ const id = decoder.readVarInt(), UUID = decoder.readUUID(), type = decoder.readVarInt(), x = decoder.readDouble(), y = decoder.readDouble(), z = decoder.readDouble(), velocity = decoder.readLpVec3(), pitch = decoder.readAngle(), yaw = decoder.readAngle(), headYaw = decoder.readAngle(), data = decoder.readVarInt();
564
+ this.world.entities[id] = {
565
+ id,
566
+ type,
567
+ position: { x, y, z },
568
+ velocity,
569
+ angle: {
570
+ pitch,
571
+ yaw
572
+ },
573
+ data
574
+ };
575
+ this.emit("spawnEntity", this.world.entities[id]);
576
+ }
577
+ handleTeleportEntity(decoder) {
578
+ const id = decoder.readVarInt(), x = decoder.readDouble(), y = decoder.readDouble(), z = decoder.readDouble(), velX = decoder.readDouble(), velY = decoder.readDouble(), velZ = decoder.readDouble(), pitch = decoder.readAngle(), yaw = decoder.readAngle();
579
+ if (id in this.world.entities) {
580
+ this.world.entities[id].position = { x, y, z };
581
+ this.world.entities[id].velocity = { x: velX, y: velY, z: velZ };
582
+ this.world.entities[id].angle = { pitch, yaw };
583
+ this.emit("updateEntity", this.world.entities[id]);
584
+ }
585
+ }
586
+ handleUpdateEntityPosition(decoder) {
587
+ const id = decoder.readVarInt(), delX = decoder.readFixedPoint(decoder.readShort(), 12), delY = decoder.readFixedPoint(decoder.readShort(), 12), delZ = decoder.readFixedPoint(decoder.readShort(), 12);
588
+ if (id in this.world.entities) {
589
+ let { x, y, z } = this.world.entities[id].position;
590
+ x += delX;
591
+ y += delY;
592
+ z += delZ;
593
+ this.world.entities[id].position = { x, y, z };
594
+ this.emit("updateEntity", this.world.entities[id]);
595
+ }
596
+ }
597
+ handleUpdateEntityPositionRotation(decoder) {
598
+ const id = decoder.readVarInt(), delX = decoder.readFixedPoint(decoder.readShort(), 12), delY = decoder.readFixedPoint(decoder.readShort(), 12), delZ = decoder.readFixedPoint(decoder.readShort(), 12), pitch = decoder.readAngle(), yaw = decoder.readAngle();
599
+ if (id in this.world.entities) {
600
+ let { x, y, z } = this.world.entities[id].position;
601
+ x += delX;
602
+ y += delY;
603
+ z += delZ;
604
+ this.world.entities[id].position = { x, y, z };
605
+ this.world.entities[id].angle = { yaw, pitch };
606
+ this.emit("updateEntity", this.world.entities[id]);
607
+ }
608
+ }
609
+ handleSetEntityVelocity(decoder) {
610
+ const entityId = decoder.readVarInt(), velocity = decoder.readLpVec3();
611
+ if (entityId in this.world.entities)
612
+ this.world.entities[entityId].velocity = velocity;
613
+ }
614
+ handleRemoveEntity(decoder) {
615
+ const entities = decoder.readPrefixedArray((decoder) => decoder.readVarInt());
616
+ for (const entityId of entities) {
617
+ delete this.world.entities[entityId];
618
+ this.emit("removeEntity", entityId);
619
+ }
620
+ }
621
+ // Chat
622
+ handlePlayerChat(decoder) {
623
+ const globalIndex = decoder.readVarInt(), senderUUID = decoder.readUUID(), index = decoder.readVarInt(), messageSignature = decoder.readPrefixedOptional(decoder => decoder.readArray(256, decoder => decoder.readByte())), message = decoder.readString(), timestamp = decoder.readLong(), salt = decoder.readLong(), previousMessages = decoder.readPrefixedArray(decoder => {
624
+ const id = decoder.readVarInt();
625
+ let signature;
626
+ if (id === 0)
627
+ signature = decoder.readArray(256, decoder => decoder.readByte());
628
+ return { id, signature };
629
+ }), unsignedContent = decoder.readPrefixedOptional(decoder => decoder.readNBT()), // Text component
630
+ filterType = decoder.readVarInt(), filterTypeBits = filterType === 1 ? decoder.readPrefixedArray(decoder => decoder.readLong()) : undefined, chatType = decoder.readIdOrX(decoder => decoder.readChatType()), senderName = decoder.readNBT(), targetName = decoder.readPrefixedOptional(decoder => decoder.readNBT());
631
+ const senderNameText = (0, decoder_1.getTextFromTextComponent)(senderName).toString(), targetNameText = targetName ?? (0, decoder_1.getTextFromTextComponent)(targetName).toString();
632
+ this.emit("message", {
633
+ sender: senderNameText,
634
+ target: targetNameText,
635
+ content: message,
636
+ raw: {
637
+ sender: senderName,
638
+ target: targetName,
639
+ content: unsignedContent,
640
+ }
641
+ });
642
+ }
643
+ handleSystemMessage(decoder) {
644
+ const content = decoder.readNBT(), isActionbar = decoder.readBoolean();
645
+ const text = (0, decoder_1.getTextFromTextComponent)(content);
646
+ if (isActionbar) {
647
+ this.emit("actionBar", text.toString());
648
+ this.emit("actionBarRaw", content);
649
+ }
650
+ else {
651
+ this.emit("systemMessage", text.toString());
652
+ this.emit("systemMessageRaw", content);
653
+ }
654
+ }
655
+ handleSetActionBar(decoder) {
656
+ const content = decoder.readNBT();
657
+ const text = (0, decoder_1.getTextFromTextComponent)(content);
658
+ this.emit("actionBar", text.toString());
659
+ this.emit("actionBarRaw", content);
660
+ }
661
+ handleDisguisedChatMessage(decoder) {
662
+ const message = decoder.readNBT(), chatType = decoder.readChatType(), senderName = decoder.readNBT(), targetName = decoder.readPrefixedOptional(decoder => decoder.readNBT());
663
+ const messageText = (0, decoder_1.getTextFromTextComponent)(message).toString(), senderNameText = (0, decoder_1.getTextFromTextComponent)(senderName).toString(), targetNameText = targetName ?? (0, decoder_1.getTextFromTextComponent)(targetName).toString();
664
+ this.emit("message", {
665
+ sender: senderNameText,
666
+ target: targetNameText,
667
+ content: messageText,
668
+ raw: {
669
+ sender: senderName,
670
+ target: targetName,
671
+ content: message,
672
+ }
673
+ });
674
+ }
675
+ /*
676
+ * Send packet
677
+ */
678
+ write(buf) {
679
+ if (this.status == ClientStatus.Disconnected || !this.socket.writable)
680
+ throw new error_1.SockerIsNotWritable();
681
+ let sendBuffer = buf;
682
+ if (this.cipher)
683
+ sendBuffer = this.cipher.update(sendBuffer);
684
+ this.socket.write(sendBuffer);
685
+ }
686
+ sendPacket(packetId, content) {
687
+ const encodePacketId = new encoder_1.BinaryEncoder();
688
+ encodePacketId.writeVarInt(packetId);
689
+ const sendData = Buffer.concat([encodePacketId.getBuffer(), content]);
690
+ let packet;
691
+ if (this.compressionThreshold !== 0) {
692
+ let data;
693
+ let uncompressedLength;
694
+ if (this.compressionThreshold > 0 && sendData.length > this.compressionThreshold) {
695
+ uncompressedLength = sendData.length;
696
+ data = (0, node_zlib_1.deflateSync)(sendData);
697
+ }
698
+ else {
699
+ uncompressedLength = 0;
700
+ data = sendData;
701
+ }
702
+ const dataLengthEncoder = new encoder_1.BinaryEncoder();
703
+ dataLengthEncoder.writeVarInt(uncompressedLength);
704
+ const dataLengthBuf = dataLengthEncoder.getBuffer();
705
+ const packetLengthEncoder = new encoder_1.BinaryEncoder();
706
+ packetLengthEncoder.writeVarInt(dataLengthBuf.length + data.length);
707
+ packet = Buffer.concat([packetLengthEncoder.getBuffer(), dataLengthBuf, data]);
708
+ }
709
+ else {
710
+ const packetLengthEncoder = new encoder_1.BinaryEncoder();
711
+ packetLengthEncoder.writeVarInt(sendData.length);
712
+ packet = Buffer.concat([packetLengthEncoder.getBuffer(), sendData]);
713
+ }
714
+ this.write(packet);
715
+ }
716
+ // Login
717
+ sendHandshake() {
718
+ this.state = ClientState.Handshake;
719
+ const encoder = new encoder_1.BinaryEncoder();
720
+ encoder.writeVarInt(this.option.protocolVersion);
721
+ encoder.writeString(this.option.host);
722
+ encoder.writeUShort(this.option.port);
723
+ encoder.writeVarInt(2);
724
+ this.sendPacket(0x00, encoder.getBuffer());
725
+ }
726
+ sendLoginStart() {
727
+ this.state = ClientState.Login;
728
+ this.status = ClientStatus.Logining;
729
+ const encoder = new encoder_1.BinaryEncoder();
730
+ const playerName = this.option.playerName;
731
+ const playerUUID = this.playerUUID;
732
+ encoder.writeString(playerName);
733
+ encoder.concat(playerUUID);
734
+ this.sendPacket(0x00, encoder.getBuffer());
735
+ }
736
+ sendEncryptionResponse(publicKey, verifyToken) {
737
+ const encryptedSecret = (0, node_crypto_1.publicEncrypt)({
738
+ key: (0, node_crypto_1.createPublicKey)({ key: publicKey, format: 'der', type: 'spki' }),
739
+ padding: node_crypto_1.constants.RSA_PKCS1_PADDING
740
+ }, this.sharedSecret);
741
+ const encryptedVerifyToken = (0, node_crypto_1.publicEncrypt)({
742
+ key: (0, node_crypto_1.createPublicKey)({ key: publicKey, format: 'der', type: 'spki' }),
743
+ padding: node_crypto_1.constants.RSA_PKCS1_PADDING
744
+ }, verifyToken);
745
+ const encoder = new encoder_1.BinaryEncoder();
746
+ encoder.writeRawPrefixedArray(encryptedSecret, 8);
747
+ encoder.writeRawPrefixedArray(encryptedVerifyToken, 8);
748
+ this.sendPacket(0x01, encoder.getBuffer());
749
+ }
750
+ sendLoginAck() {
751
+ this.state = ClientState.Configure;
752
+ this.server = {};
753
+ this.sendPacket(0x03, Buffer.alloc(0));
754
+ }
755
+ // Configuring
756
+ sendKnownPack(knownPacks) {
757
+ const encoder = new encoder_1.BinaryEncoder();
758
+ encoder.writePrefixedArray(knownPacks.length, (encoder, ind) => {
759
+ const pack = knownPacks[ind];
760
+ return encoder
761
+ .writeString(pack.namespace)
762
+ .writeString(pack.id)
763
+ .writeString(pack.version);
764
+ });
765
+ this.sendPacket(0x07, encoder.getBuffer());
766
+ }
767
+ sendConfigureAck() {
768
+ this.state = ClientState.Play;
769
+ this.sendPacket(0x3, Buffer.alloc(0));
770
+ }
771
+ // Play
772
+ sendConfirmTeleportation(teleportId) {
773
+ const encoder = new encoder_1.BinaryEncoder();
774
+ encoder.writeVarInt(teleportId);
775
+ this.sendPacket(0, encoder.getBuffer());
776
+ }
777
+ sendKeepAlive(id) {
778
+ const encoder = new encoder_1.BinaryEncoder();
779
+ encoder.writeLong(id);
780
+ this.sendPacket(0x1C, encoder.getBuffer());
781
+ }
782
+ sendPlayerPosRot(pos, rot, onGround, pushingWall) {
783
+ let flag = 0;
784
+ if (onGround)
785
+ flag |= 1;
786
+ if (pushingWall)
787
+ flag |= 1 << 2;
788
+ // // console.log({ pos, rot, flag });
789
+ const encoder = new encoder_1.BinaryEncoder();
790
+ encoder.writeDouble(pos.x);
791
+ encoder.writeDouble(pos.y);
792
+ encoder.writeDouble(pos.z);
793
+ encoder.writeFloat(rot.yaw);
794
+ encoder.writeFloat(rot.pitch);
795
+ encoder.writeByte(flag);
796
+ this.sendPacket(0x1F, encoder.getBuffer());
797
+ }
798
+ sendPlayerPos(pos, onGround, pushingWall) {
799
+ let flag = 0;
800
+ if (onGround)
801
+ flag &= 1;
802
+ if (pushingWall)
803
+ flag |= 1 << 2;
804
+ // // console.log({ pos, flag });
805
+ const encoder = new encoder_1.BinaryEncoder();
806
+ encoder.writeDouble(pos.x);
807
+ encoder.writeDouble(pos.y);
808
+ encoder.writeDouble(pos.z);
809
+ encoder.writeByte(flag);
810
+ this.sendPacket(0x1E, encoder.getBuffer());
811
+ }
812
+ sendPlayerRot(rot, onGround, pushingWall) {
813
+ let flag = 0;
814
+ if (onGround)
815
+ flag &= 1;
816
+ if (pushingWall)
817
+ flag |= 1 << 2;
818
+ // // console.log({ rot, flag });
819
+ const encoder = new encoder_1.BinaryEncoder();
820
+ encoder.writeFloat(rot.yaw);
821
+ encoder.writeFloat(rot.pitch);
822
+ encoder.writeByte(flag);
823
+ this.sendPacket(0x20, encoder.getBuffer());
824
+ }
825
+ sendPlayerStatus(onGround, pushingWall) {
826
+ let flag = 0;
827
+ if (onGround)
828
+ flag &= 1;
829
+ if (pushingWall)
830
+ flag |= 1 << 2;
831
+ // // console.log({ flag });
832
+ const encoder = new encoder_1.BinaryEncoder();
833
+ encoder.writeByte(flag);
834
+ this.sendPacket(0x21, encoder.getBuffer());
835
+ }
836
+ }
837
+ exports.TCPClient = TCPClient;
838
+ //# sourceMappingURL=tcp.js.map