@vaitosoi/minejs 0.2.2 → 0.3.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.
Files changed (118) hide show
  1. package/assets/minecraft/26.2/packets.json +4741 -0
  2. package/dist/base/error.d.ts +29 -0
  3. package/dist/base/error.d.ts.map +1 -1
  4. package/dist/base/error.js +54 -1
  5. package/dist/base/error.js.map +1 -1
  6. package/dist/base/typing.d.ts +7 -1
  7. package/dist/base/typing.d.ts.map +1 -1
  8. package/dist/client/client.d.ts +25 -14
  9. package/dist/client/client.d.ts.map +1 -1
  10. package/dist/client/client.js +73 -35
  11. package/dist/client/client.js.map +1 -1
  12. package/dist/client/tcp.d.ts +16 -201
  13. package/dist/client/tcp.d.ts.map +1 -1
  14. package/dist/client/tcp.js +41 -706
  15. package/dist/client/tcp.js.map +1 -1
  16. package/dist/index.d.ts +12 -12
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +12 -12
  19. package/dist/index.js.map +1 -1
  20. package/dist/{translator → packet}/decoder.d.ts +1 -1
  21. package/dist/packet/decoder.d.ts.map +1 -0
  22. package/dist/{translator → packet}/decoder.js +3 -3
  23. package/dist/packet/decoder.js.map +1 -0
  24. package/dist/packet/dispatcher.d.ts +46 -0
  25. package/dist/packet/dispatcher.d.ts.map +1 -0
  26. package/dist/packet/dispatcher.js +626 -0
  27. package/dist/packet/dispatcher.js.map +1 -0
  28. package/dist/{translator → packet}/encoder.d.ts +4 -3
  29. package/dist/packet/encoder.d.ts.map +1 -0
  30. package/dist/{translator → packet}/encoder.js +18 -7
  31. package/dist/packet/encoder.js.map +1 -0
  32. package/dist/packet/static.d.ts.map +1 -0
  33. package/dist/packet/static.js.map +1 -0
  34. package/dist/{base → physics}/aabb.d.ts +2 -2
  35. package/dist/physics/aabb.d.ts.map +1 -0
  36. package/dist/{base → physics}/aabb.js +5 -5
  37. package/dist/physics/aabb.js.map +1 -0
  38. package/dist/physics/direction.d.ts.map +1 -0
  39. package/dist/physics/direction.js.map +1 -0
  40. package/dist/{base → physics}/player.d.ts +8 -5
  41. package/dist/physics/player.d.ts.map +1 -0
  42. package/dist/{base → physics}/player.js +40 -25
  43. package/dist/physics/player.js.map +1 -0
  44. package/dist/version/codec.d.ts +18 -0
  45. package/dist/version/codec.d.ts.map +1 -0
  46. package/dist/version/codec.js +214 -0
  47. package/dist/version/codec.js.map +1 -0
  48. package/dist/version/registry.d.ts +236 -0
  49. package/dist/version/registry.d.ts.map +1 -0
  50. package/dist/version/registry.js +289 -0
  51. package/dist/version/registry.js.map +1 -0
  52. package/dist/{base → world}/block.d.ts +5 -5
  53. package/dist/world/block.d.ts.map +1 -0
  54. package/dist/{base → world}/block.js +13 -13
  55. package/dist/world/block.js.map +1 -0
  56. package/dist/{base → world}/entity.d.ts +4 -4
  57. package/dist/world/entity.d.ts.map +1 -0
  58. package/dist/{base → world}/entity.js +6 -6
  59. package/dist/world/entity.js.map +1 -0
  60. package/dist/world/state.d.ts +151 -0
  61. package/dist/world/state.d.ts.map +1 -0
  62. package/dist/world/state.js +108 -0
  63. package/dist/world/state.js.map +1 -0
  64. package/dist/world/tick.d.ts.map +1 -0
  65. package/dist/world/tick.js.map +1 -0
  66. package/package.json +7 -2
  67. package/src/base/error.ts +36 -0
  68. package/src/base/typing.ts +9 -1
  69. package/src/client/client.ts +99 -42
  70. package/src/client/tcp.ts +49 -954
  71. package/src/index.ts +12 -12
  72. package/src/{translator → packet}/decoder.ts +3 -3
  73. package/src/packet/dispatcher.ts +785 -0
  74. package/src/{translator → packet}/encoder.ts +20 -9
  75. package/src/{base → physics}/aabb.ts +5 -5
  76. package/src/{base → physics}/player.ts +41 -25
  77. package/src/version/codec.ts +227 -0
  78. package/src/version/registry.ts +333 -0
  79. package/src/{base → world}/block.ts +12 -11
  80. package/src/{base → world}/entity.ts +5 -5
  81. package/src/world/state.ts +232 -0
  82. package/test/adapter/index.ts +14 -0
  83. package/test/client/index.ts +1 -1
  84. package/test/json/index.ts +3 -0
  85. package/dist/base/aabb.d.ts.map +0 -1
  86. package/dist/base/aabb.js.map +0 -1
  87. package/dist/base/block.d.ts.map +0 -1
  88. package/dist/base/block.js.map +0 -1
  89. package/dist/base/direction.d.ts.map +0 -1
  90. package/dist/base/direction.js.map +0 -1
  91. package/dist/base/entity.d.ts.map +0 -1
  92. package/dist/base/entity.js.map +0 -1
  93. package/dist/base/player.d.ts.map +0 -1
  94. package/dist/base/player.js.map +0 -1
  95. package/dist/base/registry.d.ts +0 -50
  96. package/dist/base/registry.d.ts.map +0 -1
  97. package/dist/base/registry.js +0 -89
  98. package/dist/base/registry.js.map +0 -1
  99. package/dist/base/tick.d.ts.map +0 -1
  100. package/dist/base/tick.js.map +0 -1
  101. package/dist/translator/decoder.d.ts.map +0 -1
  102. package/dist/translator/decoder.js.map +0 -1
  103. package/dist/translator/encoder.d.ts.map +0 -1
  104. package/dist/translator/encoder.js.map +0 -1
  105. package/dist/translator/static.d.ts.map +0 -1
  106. package/dist/translator/static.js.map +0 -1
  107. package/src/base/registry.ts +0 -87
  108. /package/assets/minecraft/{blocks.json → 26.2/blocks.json} +0 -0
  109. /package/assets/minecraft/{entities.json → 26.2/entities.json} +0 -0
  110. /package/dist/{translator → packet}/static.d.ts +0 -0
  111. /package/dist/{translator → packet}/static.js +0 -0
  112. /package/dist/{base → physics}/direction.d.ts +0 -0
  113. /package/dist/{base → physics}/direction.js +0 -0
  114. /package/dist/{base → world}/tick.d.ts +0 -0
  115. /package/dist/{base → world}/tick.js +0 -0
  116. /package/src/{translator → packet}/static.ts +0 -0
  117. /package/src/{base → physics}/direction.ts +0 -0
  118. /package/src/{base → world}/tick.ts +0 -0
@@ -1,38 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TCPClient = exports.ClientState = exports.ClientStatus = exports.GameMode = void 0;
3
+ exports.TCPClient = void 0;
4
4
  const node_net_1 = require("node:net");
5
5
  const node_events_1 = require("node:events");
6
- const node_crypto_1 = require("node:crypto");
7
6
  const node_zlib_1 = require("node:zlib");
8
- const decoder_1 = require("../translator/decoder");
9
- const encoder_1 = require("../translator/encoder");
7
+ const decoder_1 = require("../packet/decoder");
8
+ const encoder_1 = require("../packet/encoder");
9
+ const state_1 = require("../world/state");
10
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
11
  // export enum TCPServerIntent {
37
12
  // Status = 1,
38
13
  // Login = 2,
@@ -44,9 +19,9 @@ var ClientState;
44
19
  * @see https://minecraft.wiki/w/Java_Edition_protocol/Packets?oldid=3445844
45
20
  */
46
21
  class TCPClient extends node_events_1.EventEmitter {
22
+ state;
47
23
  option;
48
24
  socket;
49
- server = undefined;
50
25
  // Internal var
51
26
  /**
52
27
  * | Value | Meaning |
@@ -55,93 +30,61 @@ class TCPClient extends node_events_1.EventEmitter {
55
30
  * | -1 | dont compress |
56
31
  * | > 0 | compression threshold |
57
32
  */
58
- compressionThreshold = 0;
59
33
  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) {
34
+ constructor(state, option, socketOption) {
73
35
  super();
36
+ this.state = state;
74
37
  this.option = option;
75
38
  this.socket = new node_net_1.Socket(socketOption);
76
- this.wipePlayData();
77
39
  if (!option.isOffline && !option.auth)
78
40
  throw new error_1.MissingAuthOption();
79
41
  }
80
- wipePlayData() {
81
- this.world = null;
82
- this.player = null;
83
- this.registry = null;
84
- }
42
+ sendInitPacket = () => { throw new Error("method not implemented"); };
43
+ forwardPacket = (...args) => { throw new Error("method not implemented"); };
44
+ parsePacket = (...args) => { throw new Error("method not implemented"); };
85
45
  /**
86
46
  * Connect to server
87
47
  */
88
48
  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;
49
+ this.state.status = state_1.ClientStatus.Connecting;
99
50
  const connection = this.socket.connect({
100
51
  host: this.option.host,
101
52
  port: this.option.port
102
53
  });
103
54
  connection.on("connect", () => {
104
55
  this.emit("connect");
105
- this.wipePlayData();
106
- this.sendHandshake();
107
- this.sendLoginStart();
56
+ this.sendInitPacket();
108
57
  });
109
58
  connection.on("data", (data) => {
110
59
  let buf = Buffer.from(data);
111
- if (this.decipher) {
112
- buf = this.decipher.update(buf);
60
+ if (this.state.decipher) {
61
+ buf = this.state.decipher.update(buf);
113
62
  }
114
63
  this.emit("raw", Buffer.from(buf));
115
64
  this.bufferPool = Buffer.concat([this.bufferPool, buf]);
116
65
  this.handlePacket();
117
66
  });
118
67
  connection.once("end", () => {
119
- if (this.status === ClientStatus.Disconnected)
68
+ this.emit("destroy");
69
+ if (this.state.status === state_1.ClientStatus.Disconnected)
120
70
  return;
121
- this.status = ClientStatus.Disconnected;
122
- this.state = ClientState.Disconnected;
123
- this.emit("disconnect", "socket close");
71
+ this.state.status = state_1.ClientStatus.Disconnected;
72
+ this.state.state = state_1.ConnectionState.Disconnected;
73
+ // this.emit("disconnect", "socket close");
124
74
  });
125
75
  connection.once("close", () => {
126
- if (this.status === ClientStatus.Disconnected)
76
+ this.emit("destroy");
77
+ if (this.state.status === state_1.ClientStatus.Disconnected)
127
78
  return;
128
- this.status = ClientStatus.Disconnected;
129
- this.state = ClientState.Disconnected;
130
- this.emit("disconnect", "socket close");
79
+ this.state.status = state_1.ClientStatus.Disconnected;
80
+ this.state.state = state_1.ConnectionState.Disconnected;
81
+ // this.emit("disconnect", "socket close");
131
82
  });
132
83
  }
133
84
  disconnect() {
134
85
  if (!this.socket.closed)
135
86
  this.socket.destroy();
136
87
  }
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
88
  /*
146
89
  * Read packet
147
90
  */
@@ -161,9 +104,9 @@ class TCPClient extends node_events_1.EventEmitter {
161
104
  break;
162
105
  const expectedPacketEnd = decoder.offset + packetLength;
163
106
  let packetID;
164
- if (this.compressionThreshold === 0)
107
+ if (this.state.compressionThreshold === 0)
165
108
  packetID = decoder.readVarInt();
166
- else if (this.compressionThreshold === -1) {
109
+ else if (this.state.compressionThreshold === -1) {
167
110
  decoder.readVarInt();
168
111
  packetID = decoder.readVarInt();
169
112
  }
@@ -179,519 +122,31 @@ class TCPClient extends node_events_1.EventEmitter {
179
122
  packetID = decoder.readVarInt();
180
123
  }
181
124
  }
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
- }
125
+ this.forwardPacket(packetID, decoder);
289
126
  this.bufferPool = this.bufferPool.subarray(expectedPacketEnd);
290
127
  }
291
128
  }
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
129
  /*
676
- * Send packet
677
- */
130
+ * Send packet
131
+ */
678
132
  write(buf) {
679
- if (this.status == ClientStatus.Disconnected || !this.socket.writable)
133
+ if (!this.socket.writable)
680
134
  throw new error_1.SockerIsNotWritable();
681
135
  let sendBuffer = buf;
682
- if (this.cipher)
683
- sendBuffer = this.cipher.update(sendBuffer);
136
+ if (this.state.cipher)
137
+ sendBuffer = this.state.cipher.update(sendBuffer);
684
138
  this.socket.write(sendBuffer);
685
139
  }
686
- sendPacket(packetId, content) {
140
+ sendPacket(packetId, data) {
141
+ const { buffer: content, packet } = this.parsePacket(packetId, data);
687
142
  const encodePacketId = new encoder_1.BinaryEncoder();
688
- encodePacketId.writeVarInt(packetId);
143
+ encodePacketId.writeVarInt(packet.id);
689
144
  const sendData = Buffer.concat([encodePacketId.getBuffer(), content]);
690
- let packet;
691
- if (this.compressionThreshold !== 0) {
145
+ let sendingPacket;
146
+ if (this.state.compressionThreshold !== 0) {
692
147
  let data;
693
148
  let uncompressedLength;
694
- if (this.compressionThreshold > 0 && sendData.length > this.compressionThreshold) {
149
+ if (this.state.compressionThreshold > 0 && sendData.length > this.state.compressionThreshold) {
695
150
  uncompressedLength = sendData.length;
696
151
  data = (0, node_zlib_1.deflateSync)(sendData);
697
152
  }
@@ -704,134 +159,14 @@ class TCPClient extends node_events_1.EventEmitter {
704
159
  const dataLengthBuf = dataLengthEncoder.getBuffer();
705
160
  const packetLengthEncoder = new encoder_1.BinaryEncoder();
706
161
  packetLengthEncoder.writeVarInt(dataLengthBuf.length + data.length);
707
- packet = Buffer.concat([packetLengthEncoder.getBuffer(), dataLengthBuf, data]);
162
+ sendingPacket = Buffer.concat([packetLengthEncoder.getBuffer(), dataLengthBuf, data]);
708
163
  }
709
164
  else {
710
165
  const packetLengthEncoder = new encoder_1.BinaryEncoder();
711
166
  packetLengthEncoder.writeVarInt(sendData.length);
712
- packet = Buffer.concat([packetLengthEncoder.getBuffer(), sendData]);
167
+ sendingPacket = Buffer.concat([packetLengthEncoder.getBuffer(), sendData]);
713
168
  }
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());
169
+ this.write(sendingPacket);
835
170
  }
836
171
  }
837
172
  exports.TCPClient = TCPClient;