@vaitosoi/minejs 0.2.1 → 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/bitset.d.ts +9 -0
  3. package/dist/base/bitset.d.ts.map +1 -0
  4. package/dist/base/bitset.js +46 -0
  5. package/dist/base/bitset.js.map +1 -0
  6. package/dist/base/error.d.ts +105 -0
  7. package/dist/base/error.d.ts.map +1 -0
  8. package/dist/base/error.js +194 -0
  9. package/dist/base/error.js.map +1 -0
  10. package/dist/base/event.d.ts +7 -0
  11. package/dist/base/event.d.ts.map +1 -0
  12. package/dist/base/event.js +3 -0
  13. package/dist/base/event.js.map +1 -0
  14. package/dist/base/math.d.ts +25 -0
  15. package/dist/base/math.d.ts.map +1 -0
  16. package/dist/base/math.js +69 -0
  17. package/dist/base/math.js.map +1 -0
  18. package/dist/base/typing.d.ts +9 -0
  19. package/dist/base/typing.d.ts.map +1 -0
  20. package/dist/base/typing.js +3 -0
  21. package/dist/base/typing.js.map +1 -0
  22. package/dist/client/auth.d.ts +39 -0
  23. package/dist/client/auth.d.ts.map +1 -0
  24. package/dist/client/auth.js +307 -0
  25. package/dist/client/auth.js.map +1 -0
  26. package/dist/client/client.d.ts +73 -0
  27. package/dist/client/client.d.ts.map +1 -0
  28. package/dist/client/client.js +136 -0
  29. package/dist/client/client.js.map +1 -0
  30. package/dist/client/static.d.ts +28 -0
  31. package/dist/client/static.d.ts.map +1 -0
  32. package/dist/client/static.js +43 -0
  33. package/dist/client/static.js.map +1 -0
  34. package/dist/client/tcp.d.ts +84 -0
  35. package/dist/client/tcp.d.ts.map +1 -0
  36. package/dist/client/tcp.js +173 -0
  37. package/dist/client/tcp.js.map +1 -0
  38. package/dist/index.d.ts +21 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +12 -12
  41. package/dist/index.js.map +1 -0
  42. package/dist/packet/decoder.d.ts +293 -0
  43. package/dist/packet/decoder.d.ts.map +1 -0
  44. package/dist/packet/decoder.js +668 -0
  45. package/dist/packet/decoder.js.map +1 -0
  46. package/dist/packet/dispatcher.d.ts +46 -0
  47. package/dist/packet/dispatcher.d.ts.map +1 -0
  48. package/dist/packet/dispatcher.js +626 -0
  49. package/dist/packet/dispatcher.js.map +1 -0
  50. package/dist/packet/encoder.d.ts +163 -0
  51. package/dist/packet/encoder.d.ts.map +1 -0
  52. package/dist/packet/encoder.js +441 -0
  53. package/dist/packet/encoder.js.map +1 -0
  54. package/dist/packet/static.d.ts +33 -0
  55. package/dist/packet/static.d.ts.map +1 -0
  56. package/dist/packet/static.js +42 -0
  57. package/dist/packet/static.js.map +1 -0
  58. package/dist/physics/aabb.d.ts +197 -0
  59. package/dist/physics/aabb.d.ts.map +1 -0
  60. package/dist/physics/aabb.js +576 -0
  61. package/dist/physics/aabb.js.map +1 -0
  62. package/dist/physics/direction.d.ts +153 -0
  63. package/dist/physics/direction.d.ts.map +1 -0
  64. package/dist/physics/direction.js +288 -0
  65. package/dist/physics/direction.js.map +1 -0
  66. package/dist/physics/player.d.ts +110 -0
  67. package/dist/physics/player.d.ts.map +1 -0
  68. package/dist/physics/player.js +558 -0
  69. package/dist/physics/player.js.map +1 -0
  70. package/dist/version/codec.d.ts +18 -0
  71. package/dist/version/codec.d.ts.map +1 -0
  72. package/dist/version/codec.js +214 -0
  73. package/dist/version/codec.js.map +1 -0
  74. package/dist/version/registry.d.ts +236 -0
  75. package/dist/version/registry.d.ts.map +1 -0
  76. package/dist/version/registry.js +289 -0
  77. package/dist/version/registry.js.map +1 -0
  78. package/dist/world/block.d.ts +86 -0
  79. package/dist/world/block.d.ts.map +1 -0
  80. package/dist/world/block.js +232 -0
  81. package/dist/world/block.js.map +1 -0
  82. package/dist/world/entity.d.ts +43 -0
  83. package/dist/world/entity.d.ts.map +1 -0
  84. package/dist/world/entity.js +97 -0
  85. package/dist/world/entity.js.map +1 -0
  86. package/dist/world/state.d.ts +151 -0
  87. package/dist/world/state.d.ts.map +1 -0
  88. package/dist/world/state.js +108 -0
  89. package/dist/world/state.js.map +1 -0
  90. package/dist/world/tick.d.ts +19 -0
  91. package/dist/world/tick.d.ts.map +1 -0
  92. package/dist/world/tick.js +49 -0
  93. package/dist/world/tick.js.map +1 -0
  94. package/package.json +7 -2
  95. package/src/base/error.ts +36 -0
  96. package/src/base/typing.ts +9 -1
  97. package/src/client/client.ts +99 -42
  98. package/src/client/tcp.ts +49 -954
  99. package/src/index.ts +12 -12
  100. package/src/{translator → packet}/decoder.ts +3 -3
  101. package/src/packet/dispatcher.ts +785 -0
  102. package/src/{translator → packet}/encoder.ts +20 -9
  103. package/src/{base → physics}/aabb.ts +5 -5
  104. package/src/{base → physics}/player.ts +41 -25
  105. package/src/version/codec.ts +227 -0
  106. package/src/version/registry.ts +333 -0
  107. package/src/{base → world}/block.ts +12 -11
  108. package/src/{base → world}/entity.ts +5 -5
  109. package/src/world/state.ts +232 -0
  110. package/test/adapter/index.ts +14 -0
  111. package/test/client/index.ts +1 -1
  112. package/test/json/index.ts +3 -0
  113. package/src/base/registry.ts +0 -87
  114. /package/assets/minecraft/{blocks.json → 26.2/blocks.json} +0 -0
  115. /package/assets/minecraft/{entities.json → 26.2/entities.json} +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
@@ -0,0 +1,668 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SNBTDecoder = exports.NBTDecoder = exports.BinaryDecoder = void 0;
4
+ exports.getTextFromTextComponent = getTextFromTextComponent;
5
+ const direction_1 = require("../physics/direction");
6
+ const static_1 = require("./static");
7
+ const error_1 = require("../base/error");
8
+ const static_2 = require("./static");
9
+ const zlib_1 = require("zlib");
10
+ const math_1 = require("../base/math");
11
+ const util_1 = require("util");
12
+ function getTextFromTextComponent(component) {
13
+ if (component === null || component === undefined)
14
+ return "null";
15
+ switch (typeof component) {
16
+ case "string":
17
+ return component;
18
+ case "object": {
19
+ if (Array.isArray(component))
20
+ return component.map(val => getTextFromTextComponent(val)).join();
21
+ else if ("text" in component) {
22
+ if ("extra" in component && Array.isArray(component["extra"]))
23
+ return component["text"] + component["extra"].map(val => getTextFromTextComponent(val)).join("");
24
+ else
25
+ return component["text"];
26
+ }
27
+ if ("translate" in component) {
28
+ if ("fallback" in component)
29
+ return component["fallback"];
30
+ else
31
+ return component["translate"];
32
+ }
33
+ else if ("keybind" in component)
34
+ return component["keybind"];
35
+ else
36
+ throw new error_1.UnexpectedValue("value of component", "text component object", (0, util_1.inspect)(component, undefined, null));
37
+ }
38
+ default:
39
+ throw new error_1.UnexpectedValue("type of component", "string or object", typeof component);
40
+ }
41
+ }
42
+ class BinaryDecoder {
43
+ buffer = Buffer.alloc(0);
44
+ offset = 0;
45
+ constructor(buffer, needDecompress = false) {
46
+ if (!needDecompress)
47
+ this.buffer = buffer;
48
+ else
49
+ this.buffer = (0, zlib_1.unzipSync)(buffer);
50
+ }
51
+ /**
52
+ * Read shortcut
53
+ *
54
+ * Read `size` bytes, use readFunc, then add `size` to internal offset
55
+ */
56
+ read(size, readFunc) {
57
+ const val = readFunc(this.buffer).bind(this.buffer)(this.offset);
58
+ this.offset += size;
59
+ return val;
60
+ }
61
+ /**
62
+ * Read 1 byte
63
+ * @returns signed 1-byte integer
64
+ */
65
+ readByte() { return this.read(1, (buffer) => buffer.readInt8); }
66
+ /**
67
+ * Read 1 byte
68
+ * @returns unsigned 1-byte integer
69
+ */
70
+ readUByte() { return this.read(1, (buffer) => buffer.readUint8); }
71
+ /**
72
+ * Read 2 bytes
73
+ * @returns signed 2-byte integer
74
+ */
75
+ readShort() { return this.read(2, (buffer) => buffer.readInt16BE); }
76
+ /**
77
+ * Read 2 bytes
78
+ * @returns unsigned 2-byte integer
79
+ */
80
+ readUShort() { return this.read(2, (buffer) => buffer.readUint16BE); }
81
+ /**
82
+ * Read 4 bytes
83
+ * @returns signed 4-byte integer
84
+ */
85
+ readInt() { return this.read(4, (buffer) => buffer.readInt32BE); }
86
+ /**
87
+ * Read 8 bytes
88
+ * @returns signed 8-byte integer
89
+ */
90
+ readLong() { return this.read(8, (buffer) => buffer.readBigInt64BE); }
91
+ /**
92
+ * Read 4 bytes
93
+ * @returns signed 4-bytes decimal
94
+ */
95
+ readFloat() { return this.read(4, (buffer) => buffer.readFloatBE); }
96
+ /**
97
+ * Read 8 bytes
98
+ * @returns signed 8-byte decimal
99
+ */
100
+ readDouble() { return this.read(8, (buffer) => buffer.readDoubleBE); }
101
+ /**
102
+ * Read 1 byte
103
+ * @returns a boolean
104
+ */
105
+ readBoolean() {
106
+ const value = this.readByte();
107
+ switch (value) {
108
+ case 0x01: return true;
109
+ case 0x00: return false;
110
+ default: throw new Error(`unexpect value of boolean type: ${value}`);
111
+ }
112
+ }
113
+ // Source: https://minecraft.wiki/w/Java_Edition_protocol/Packets#VarInt_and_VarLong
114
+ /**
115
+ * Read n bytes of integer
116
+ *
117
+ * A VarInt packet would look like this:
118
+ *
119
+ * `[7 bits of data][1 bit indicate if the VarInt ended here]`
120
+ *
121
+ * @returns signed n-bit integer
122
+ */
123
+ readVarInt() {
124
+ let value = 0;
125
+ let position = 0;
126
+ let currentByte;
127
+ while (true) {
128
+ currentByte = this.readUByte();
129
+ value |= (currentByte & static_1.SEGMENT_BITS) << position;
130
+ if ((currentByte & static_1.CONTINUE_BIT) == 0)
131
+ break;
132
+ position += 7;
133
+ if (position >= 32)
134
+ throw new Error("VarInt is too big");
135
+ }
136
+ return value;
137
+ }
138
+ /**
139
+ * Read n bytes of integer
140
+ *
141
+ * Similar to VarInt, A VarLong packet would look like this:
142
+ *
143
+ * `[7 bits of data][1 bit indicate if the VarLong ended here]`
144
+ *
145
+ * @returns signed n-bit integer
146
+ */
147
+ readVarLong() {
148
+ let value = BigInt(0);
149
+ let position = 0;
150
+ let currentByte;
151
+ while (true) {
152
+ currentByte = this.readUByte();
153
+ value |= BigInt((currentByte & static_1.SEGMENT_BITS) << position);
154
+ if ((currentByte & static_1.CONTINUE_BIT) == 0)
155
+ break;
156
+ position += 7;
157
+ if (position >= 64)
158
+ throw new Error("VarLong is too big");
159
+ }
160
+ return value;
161
+ }
162
+ /**
163
+ * Read a string
164
+ *
165
+ * A string packet would look like this:
166
+ *
167
+ * `[VarInt as length, if not provided][N bits of data]`
168
+ *
169
+ * @returns a string
170
+ */
171
+ readString(length) {
172
+ length ||= this.readVarInt();
173
+ if (length == 0)
174
+ return "";
175
+ if (this.offset + length > this.buffer.length)
176
+ throw new error_1.StringSizeExceedLimit();
177
+ const string = this.buffer.subarray(this.offset, this.offset + length);
178
+ this.offset += length;
179
+ return string.toString("utf-8");
180
+ }
181
+ /**
182
+ * Read a 16-byte UUID
183
+ */
184
+ readUUID() {
185
+ const buffer = this.buffer.subarray(this.offset, this.offset + 16);
186
+ this.offset += 16;
187
+ return buffer.toString('hex');
188
+ }
189
+ /**
190
+ * Read a Position
191
+ *
192
+ * A position packet is a 64-bit value, split into three signed integer parts:
193
+ * ```
194
+ * x: 26 MSBs
195
+ * z: 26 middle bits
196
+ * y: 12 LSBs
197
+ * ```
198
+ *
199
+ * @returns a Position
200
+ */
201
+ readPosition() {
202
+ const val = this.readLong(), x = val >> BigInt(38), y = val << BigInt(52) >> BigInt(52), z = val << BigInt(26) >> BigInt(38);
203
+ return {
204
+ x: Number(x),
205
+ y: Number(y),
206
+ z: Number(z),
207
+ };
208
+ }
209
+ /**
210
+ * Read an array with known length
211
+ *
212
+ * @returns an array
213
+ */
214
+ readArray(length, readFunc) {
215
+ return Array.from({ length }).map((_, ind) => readFunc(this, ind));
216
+ }
217
+ /**
218
+ * Read a length-prefixed array
219
+ *
220
+ * An array packet would look like this:
221
+ * `[VarInt as length][N bytes of data]`
222
+ *
223
+ * @returns a length-prefixed array
224
+ */
225
+ readPrefixedArray(readFunc) {
226
+ const length = this.readVarInt();
227
+ return this.readArray(length, readFunc);
228
+ }
229
+ /**
230
+ * Read an array with known length and return Buffer
231
+ *
232
+ * @param size size of the item, in byte
233
+ * @returns an array
234
+ */
235
+ readRawArray(length, size) {
236
+ const buffer = this.buffer.subarray(this.offset, this.offset + size * length);
237
+ this.offset += size * length;
238
+ return buffer;
239
+ }
240
+ /**
241
+ * Read a length-prefixed array and return the raw buffer
242
+ *
243
+ * An array packet would look like this:
244
+ * `[VarInt as length][N bytes of data]`
245
+ *
246
+ * @param size size of the item, in byte
247
+ * @returns a length-prefixed array
248
+ */
249
+ readRawPrefixedArray(size) {
250
+ const length = this.readVarInt();
251
+ return this.readRawArray(length, size);
252
+ }
253
+ /**
254
+ * Read a Teleport Flag packet
255
+ *
256
+ * A Teleport Flag packet, which is bit mask represented as an int, would look like this:
257
+ * | Hex Mask | Field |
258
+ * |----------|------------------------|
259
+ * | 0x0001 | Is X relative |
260
+ * | 0x0002 | Is Y relative |
261
+ * | 0x0004 | Is Z relative |
262
+ * | 0x0008 | Is Yaw relative |
263
+ * | 0x0010 | Is Pitch relative |
264
+ * | 0x0020 | Is Velocity X relative |
265
+ * | 0x0040 | Is Velocity Y relative |
266
+ * | 0x0080 | Is Velocity Z relative |
267
+ * | 0x0100 | Rotate velocity |
268
+ */
269
+ readTeleportFlag() {
270
+ const flags = this.readInt();
271
+ const x = (flags & 0x0001) === 1, y = (flags & 0x0002) === 1, z = (flags & 0x0004) === 1, yaw = (flags & 0x0008) === 1, pitch = (flags & 0x0010) === 1, velX = (flags & 0x0020) === 1, velY = (flags & 0x0040) === 1, velZ = (flags & 0x0080) === 1, rotateVelocity = (flags & 0x0100) === 1;
272
+ return {
273
+ x,
274
+ y,
275
+ z,
276
+ yaw,
277
+ pitch,
278
+ velX,
279
+ velY,
280
+ velZ,
281
+ rotateVelocity,
282
+ };
283
+ }
284
+ /**
285
+ * Read a Prefixed Optional field
286
+ *
287
+ * A Prefixed Optional would look like this:
288
+ * `[Boolean to indicate whenether the following field is presented][N bytes of data if the boolean before is true, or else empty]`
289
+ *
290
+ * @returns
291
+ */
292
+ readPrefixedOptional(readFunc) {
293
+ const isPresent = this.readBoolean();
294
+ if (!isPresent)
295
+ return null;
296
+ return readFunc(this);
297
+ }
298
+ /**
299
+ * Read a NBT
300
+ */
301
+ readNBT() {
302
+ const remainData = this.buffer.subarray(this.offset);
303
+ const nbtDecoder = new NBTDecoder(remainData);
304
+ const val = nbtDecoder.decode();
305
+ this.offset += nbtDecoder.offset;
306
+ return val;
307
+ }
308
+ // For reading LpVec3
309
+ unpack(value) {
310
+ return (0, math_1.minBigInt)(BigInt(BigInt(value) & 32767n), BigInt(static_1.MAX_QUANTIZED_VALUE)) * BigInt(2.0) / BigInt(static_1.MAX_QUANTIZED_VALUE) - 1n;
311
+ }
312
+ /**
313
+ * Read LpVec3
314
+ *
315
+ * Read this article for more information: https://minecraft.wiki/w/Java_Edition_protocol/Data_types#LpVec3
316
+ */
317
+ readLpVec3() {
318
+ const byte1 = this.readUByte();
319
+ if (byte1 === 0) {
320
+ return direction_1.Vec3.Zero;
321
+ }
322
+ const byte2 = this.readUByte();
323
+ const bytes3To6 = this.readInt(); // Should be UInt
324
+ const packed = BigInt(bytes3To6 << 16) | BigInt(byte2 << 8) | BigInt(byte1);
325
+ let scaleFactor = BigInt(byte1) & static_1.SCALE_BITS;
326
+ if ((BigInt(byte1) & static_1.CONTINUATION_FLAG) != 0n)
327
+ scaleFactor |= BigInt(this.readVarInt()) << 2n;
328
+ const scaleFactorD = BigInt(scaleFactor);
329
+ return new direction_1.Vec3(Number(this.unpack(packed >> 3n) * scaleFactorD), Number(this.unpack(packed >> 18n) * scaleFactorD), Number(this.unpack(packed >> 33n) * scaleFactorD));
330
+ }
331
+ /**
332
+ * Resolve a fixed point to a double
333
+ *
334
+ * A fixed point is a certain number of bits represent the signed integer part (number to the left of the decimal point)
335
+ * and the rest represent the fractional part (to the right).
336
+ *
337
+ * @param x number to resole
338
+ * @param n n fraction bits
339
+ */
340
+ readFixedPoint(x, n) {
341
+ return x / (1 << n);
342
+ }
343
+ /**
344
+ * Read an angle.
345
+ *
346
+ * An angle is a rotation angle in steps of 1/256 of a full turn
347
+ */
348
+ readAngle() {
349
+ return this.readByte();
350
+ }
351
+ /**
352
+ * Represents a data record of type X, either inline, or by reference to a registry implied by context
353
+ */
354
+ readIdOrX(readX) {
355
+ const id = this.readVarInt();
356
+ if (id !== 0)
357
+ return id;
358
+ return readX(this);
359
+ }
360
+ /**
361
+ * Read Chat Type Decoration
362
+ *
363
+ * The chat type decorations look like:
364
+ * | Name | Type | Description |
365
+ * |-----------------|-------------------------------|----------------------------------|
366
+ * | Translation Key | String | |
367
+ * | Parameters | Prefixed Array of VarInt Enum | 0: sender, 1: target, 2: content |
368
+ * | Style | NBT | |
369
+ */
370
+ readChatTypeDecoration() {
371
+ const translationKey = this.readString(), parameters = this.readPrefixedArray(decoder => decoder.readVarInt()), style = this.readNBT();
372
+ return { translationKey, parameters, style };
373
+ }
374
+ /**
375
+ * Read Chat Type
376
+ */
377
+ readChatType() {
378
+ return {
379
+ chat: this.readChatTypeDecoration(),
380
+ narration: this.readChatTypeDecoration()
381
+ };
382
+ }
383
+ }
384
+ exports.BinaryDecoder = BinaryDecoder;
385
+ class NBTDecoder extends BinaryDecoder {
386
+ /**
387
+ * Read a Compound string
388
+ *
389
+ * A string packet would look like this:
390
+ *
391
+ * `[2 bytes as length][N bits of data]`
392
+ *
393
+ * @returns a string
394
+ */
395
+ readCompoundString() {
396
+ const length = this.readUShort();
397
+ if (length == 0)
398
+ return "";
399
+ return this.readString(length);
400
+ }
401
+ /**
402
+ * Read a list / array of tag
403
+ *
404
+ * A list / array packet should look like this:
405
+ * [1 byte of type, if not provided][4 bytes of length][N bits of data]
406
+ *
407
+ * @returns
408
+ */
409
+ readCompoundList(type) {
410
+ type ||= this.readByte();
411
+ const length = this.readInt();
412
+ const array = Array.from({ length })
413
+ .map(() => this.readCompoundValue(type));
414
+ return array;
415
+ }
416
+ /**
417
+ * Read compound value base on provided tag
418
+ */
419
+ readCompoundValue(tag) {
420
+ switch (tag) {
421
+ case static_2.Tag.Byte: return this.readByte();
422
+ case static_2.Tag.Short: return this.readShort();
423
+ case static_2.Tag.Int: return this.readInt();
424
+ case static_2.Tag.Long: return this.readLong();
425
+ case static_2.Tag.Float: return this.readFloat();
426
+ case static_2.Tag.Double: return this.readDouble();
427
+ case static_2.Tag.ByteArray: return this.readCompoundList(static_2.Tag.Byte);
428
+ case static_2.Tag.String: return this.readCompoundString();
429
+ case static_2.Tag.List: return this.readCompoundList();
430
+ case static_2.Tag.Compound: return this.readCompound();
431
+ case static_2.Tag.IntArray: return this.readCompoundList(static_2.Tag.Int);
432
+ case static_2.Tag.LongArray: return this.readCompoundList(static_2.Tag.Long);
433
+ default: throw new error_1.UnexpectedValue("compound tag", tag.toString());
434
+ }
435
+ }
436
+ /**
437
+ * Read n bits
438
+ *
439
+ * A Compound entry would look like this:
440
+ *
441
+ * [1 byte of Type][2 byte of field name length][N bits of field length][N bits of data]
442
+ *
443
+ * @returns signed n-bit integer
444
+ */
445
+ readCompound() {
446
+ const obj = {};
447
+ while (true) {
448
+ const type = this.readByte();
449
+ if (type === static_2.Tag.End)
450
+ return obj;
451
+ const name = this.readCompoundString();
452
+ const value = this.readCompoundValue(type);
453
+ obj[name] = value;
454
+ }
455
+ }
456
+ /**
457
+ * Read an NBT
458
+ *
459
+ * Note that Network NBT slice some root data so I have to specified it through `isNetwork` param
460
+ *
461
+ * @param isNetwork
462
+ * @returns
463
+ */
464
+ decode(isNetwork = true) {
465
+ const type = this.readByte();
466
+ if (type === static_2.Tag.Compound || type === static_2.Tag.List) {
467
+ if (!isNetwork)
468
+ this.readCompoundString();
469
+ const value = this.readCompoundValue(type);
470
+ return value;
471
+ }
472
+ else if (type === static_2.Tag.End)
473
+ return {};
474
+ else {
475
+ if (!isNetwork)
476
+ this.readCompoundString();
477
+ const value = this.readCompoundValue(type);
478
+ return value;
479
+ }
480
+ }
481
+ }
482
+ exports.NBTDecoder = NBTDecoder;
483
+ class SNBTDecoder {
484
+ source;
485
+ offset = 0;
486
+ constructor(source) {
487
+ this.source = source;
488
+ }
489
+ skipWhiteSpace() {
490
+ while (this.offset < this.source.length) {
491
+ // console.log({
492
+ // off: this.offset,
493
+ // ch: this.source[this.offset],
494
+ // a: this.source[this.offset] !== " ",
495
+ // b: this.source[this.offset] !== "\n"
496
+ // });
497
+ if (this.source[this.offset] !== " " &&
498
+ this.source[this.offset] !== "," &&
499
+ this.source[this.offset] !== "\n")
500
+ return;
501
+ this.offset += 1;
502
+ }
503
+ throw new error_1.UnexpectedValue("end of SNBT", "white space");
504
+ }
505
+ convertValue(val) {
506
+ if ((!isNaN(Number(val))) ||
507
+ val.endsWith("b") || val.endsWith("B") ||
508
+ val.endsWith("s") || val.endsWith("S") ||
509
+ val.endsWith("i") || val.endsWith("I") ||
510
+ val.endsWith("F") || val.endsWith("F"))
511
+ return Number(val);
512
+ if (val.endsWith("l") || val.endsWith("L") ||
513
+ val.endsWith("d") || val.endsWith("D") ||
514
+ BigInt(val) % BigInt(1) !== BigInt(0))
515
+ return BigInt(val);
516
+ if (val === "true")
517
+ return true;
518
+ if (val === "false")
519
+ return false;
520
+ if ((val.startsWith("'") && val.endsWith("'")) ||
521
+ (val.startsWith('"') && val.endsWith("'")))
522
+ return String(val.slice(1, -1));
523
+ return val;
524
+ }
525
+ // eoc = End Of Compound
526
+ seek() {
527
+ this.skipWhiteSpace();
528
+ if (this.source[this.offset] == "}")
529
+ return undefined;
530
+ let fieldName = "";
531
+ let sliceQuote = undefined;
532
+ let ch;
533
+ if (this.source[this.offset] === "'" || this.source[this.offset] === '"') {
534
+ sliceQuote = this.source[this.offset];
535
+ this.offset++;
536
+ }
537
+ while (true) {
538
+ ch = this.source[this.offset];
539
+ if (((sliceQuote == undefined && ch === ":") ||
540
+ (sliceQuote && ch === sliceQuote)) ||
541
+ this.offset >= this.source.length) {
542
+ this.offset++;
543
+ break;
544
+ }
545
+ fieldName += ch;
546
+ this.offset++;
547
+ }
548
+ if (sliceQuote)
549
+ this.offset++;
550
+ this.skipWhiteSpace();
551
+ let stringtifiedVal = "", convertedVal = undefined, type = "number";
552
+ outer: while (true) {
553
+ ch = this.source[this.offset];
554
+ switch (ch) {
555
+ case "[":
556
+ type = "list";
557
+ break;
558
+ // End of Array or Line
559
+ case "]":
560
+ if (type === "array" || type === "list") {
561
+ this.offset++;
562
+ break outer;
563
+ }
564
+ stringtifiedVal += ch;
565
+ break;
566
+ case ",":
567
+ if (type !== "array" && type !== "list") {
568
+ this.offset++;
569
+ break outer;
570
+ }
571
+ stringtifiedVal += ch;
572
+ break;
573
+ // String indicator, if found repeated mean it is the end of the string
574
+ case "'":
575
+ if (stringtifiedVal.endsWith("\\") || type == "list") {
576
+ stringtifiedVal += ch;
577
+ break;
578
+ }
579
+ if (type == "string_1") {
580
+ this.offset++;
581
+ break outer;
582
+ }
583
+ type = "string_1";
584
+ break;
585
+ case '"':
586
+ if (stringtifiedVal.endsWith("\\") || type == "list") {
587
+ stringtifiedVal += ch;
588
+ break;
589
+ }
590
+ if (type == "string_2") {
591
+ this.offset++;
592
+ break outer;
593
+ }
594
+ type = "string_2";
595
+ break;
596
+ // Array type indicator
597
+ case "B":
598
+ case "I":
599
+ case "L":
600
+ type = "array";
601
+ this.offset++;
602
+ break;
603
+ case "{":
604
+ if (type != "list") {
605
+ convertedVal = this.obj();
606
+ break outer;
607
+ }
608
+ else {
609
+ stringtifiedVal += ch;
610
+ break;
611
+ }
612
+ default:
613
+ if (ch === " " && type == "number")
614
+ break outer;
615
+ stringtifiedVal += ch;
616
+ break;
617
+ }
618
+ this.offset++;
619
+ }
620
+ if (stringtifiedVal !== "" && !convertedVal) {
621
+ if (type == "array")
622
+ convertedVal = stringtifiedVal.split(",")
623
+ .map(val => this.convertValue(val.trim()));
624
+ else if (type == "list") {
625
+ convertedVal = stringtifiedVal.split(",")
626
+ .map(val => {
627
+ val = val.trim();
628
+ if (val.startsWith("{") && val.endsWith("}")) {
629
+ const decoder = new SNBTDecoder(val);
630
+ const obj = decoder.decode();
631
+ if (Object.keys(obj).length != 1 ||
632
+ !("" in obj))
633
+ return obj;
634
+ return obj[""];
635
+ }
636
+ else
637
+ return this.convertValue(val);
638
+ });
639
+ }
640
+ else {
641
+ if (type == "string_1" || type == "string_2")
642
+ convertedVal = stringtifiedVal;
643
+ else
644
+ convertedVal = this.convertValue(stringtifiedVal);
645
+ }
646
+ }
647
+ return [fieldName, convertedVal];
648
+ }
649
+ obj() {
650
+ if (this.source[this.offset] !== "{")
651
+ throw new error_1.UnexpectedValue("start of compound", "{", this.source[this.offset]);
652
+ this.offset++;
653
+ const obj = {};
654
+ while (this.offset < this.source.length) {
655
+ const val = this.seek();
656
+ if (!val)
657
+ break;
658
+ const [fieldName, fieldVal] = val;
659
+ obj[fieldName] = fieldVal;
660
+ }
661
+ return obj;
662
+ }
663
+ decode() {
664
+ return this.obj();
665
+ }
666
+ }
667
+ exports.SNBTDecoder = SNBTDecoder;
668
+ //# sourceMappingURL=decoder.js.map