@vaitosoi/minejs 0.4.2 → 0.5.0

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 (106) hide show
  1. package/README.md +53 -5
  2. package/assets/doc/rejected.png +0 -0
  3. package/assets/minecraft/26.2/effects.json +42 -0
  4. package/assets/minecraft/26.2/packets.json +3 -2
  5. package/dist/base/bitset.d.ts +43 -4
  6. package/dist/base/bitset.d.ts.map +1 -1
  7. package/dist/base/bitset.js +251 -30
  8. package/dist/base/bitset.js.map +1 -1
  9. package/dist/base/cache.d.ts +24 -0
  10. package/dist/base/cache.d.ts.map +1 -0
  11. package/dist/base/cache.js +58 -0
  12. package/dist/base/cache.js.map +1 -0
  13. package/dist/base/error.d.ts +13 -0
  14. package/dist/base/error.d.ts.map +1 -1
  15. package/dist/base/error.js +19 -1
  16. package/dist/base/error.js.map +1 -1
  17. package/dist/base/math.d.ts +12 -0
  18. package/dist/base/math.d.ts.map +1 -1
  19. package/dist/base/math.js +39 -0
  20. package/dist/base/math.js.map +1 -1
  21. package/dist/base/typing.d.ts +7 -0
  22. package/dist/base/typing.d.ts.map +1 -1
  23. package/dist/{packet → binary}/decoder.d.ts.map +1 -1
  24. package/dist/{packet → binary}/decoder.js.map +1 -1
  25. package/dist/{packet → binary}/encoder.d.ts +2 -2
  26. package/dist/binary/encoder.d.ts.map +1 -0
  27. package/dist/{packet → binary}/encoder.js +6 -2
  28. package/dist/binary/encoder.js.map +1 -0
  29. package/dist/{packet → binary}/static.d.ts.map +1 -1
  30. package/dist/{packet → binary}/static.js.map +1 -1
  31. package/dist/client/client.d.ts +23 -2
  32. package/dist/client/client.d.ts.map +1 -1
  33. package/dist/client/client.js +34 -19
  34. package/dist/client/client.js.map +1 -1
  35. package/dist/index.d.ts +12 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +12 -4
  38. package/dist/index.js.map +1 -1
  39. package/dist/{client → net}/tcp.d.ts +2 -2
  40. package/dist/net/tcp.d.ts.map +1 -0
  41. package/dist/{client → net}/tcp.js +4 -2
  42. package/dist/net/tcp.js.map +1 -0
  43. package/dist/packet/{dispatcher.d.ts → listener.d.ts} +7 -18
  44. package/dist/packet/listener.d.ts.map +1 -0
  45. package/dist/packet/{dispatcher.js → listener.js} +73 -139
  46. package/dist/packet/listener.js.map +1 -0
  47. package/dist/packet/sender.d.ts +25 -0
  48. package/dist/packet/sender.d.ts.map +1 -0
  49. package/dist/packet/sender.js +144 -0
  50. package/dist/packet/sender.js.map +1 -0
  51. package/dist/physics/aabb.d.ts.map +1 -1
  52. package/dist/physics/aabb.js +9 -8
  53. package/dist/physics/aabb.js.map +1 -1
  54. package/dist/physics/player.d.ts +1 -0
  55. package/dist/physics/player.d.ts.map +1 -1
  56. package/dist/physics/player.js +22 -4
  57. package/dist/physics/player.js.map +1 -1
  58. package/dist/version/codec.d.ts +1 -1
  59. package/dist/version/codec.d.ts.map +1 -1
  60. package/dist/version/codec.js +28 -6
  61. package/dist/version/codec.js.map +1 -1
  62. package/dist/version/registry.d.ts +19 -2
  63. package/dist/version/registry.d.ts.map +1 -1
  64. package/dist/version/registry.js +35 -3
  65. package/dist/version/registry.js.map +1 -1
  66. package/dist/world/block.d.ts +5 -0
  67. package/dist/world/block.d.ts.map +1 -1
  68. package/dist/world/block.js +56 -0
  69. package/dist/world/block.js.map +1 -1
  70. package/dist/world/state.d.ts +22 -3
  71. package/dist/world/state.d.ts.map +1 -1
  72. package/dist/world/state.js +36 -12
  73. package/dist/world/state.js.map +1 -1
  74. package/package.json +8 -10
  75. package/src/base/bitset.ts +312 -31
  76. package/src/base/cache.ts +62 -0
  77. package/src/base/error.ts +16 -0
  78. package/src/base/math.ts +43 -1
  79. package/src/base/typing.ts +5 -0
  80. package/src/{packet → binary}/encoder.ts +6 -2
  81. package/src/client/client.ts +56 -23
  82. package/src/index.ts +12 -4
  83. package/src/{client → net}/tcp.ts +5 -3
  84. package/src/packet/{dispatcher.ts → listener.ts} +92 -177
  85. package/src/packet/sender.ts +176 -0
  86. package/src/physics/aabb.ts +9 -8
  87. package/src/physics/player.ts +20 -5
  88. package/src/version/codec.ts +29 -8
  89. package/src/version/registry.ts +58 -5
  90. package/src/world/block.ts +72 -2
  91. package/src/world/state.ts +59 -14
  92. package/test/bitset/index.ts +3 -8
  93. package/test/client/index.ts +23 -13
  94. package/test/state/index.ts +7 -0
  95. package/dist/client/tcp.d.ts.map +0 -1
  96. package/dist/client/tcp.js.map +0 -1
  97. package/dist/packet/dispatcher.d.ts.map +0 -1
  98. package/dist/packet/dispatcher.js.map +0 -1
  99. package/dist/packet/encoder.d.ts.map +0 -1
  100. package/dist/packet/encoder.js.map +0 -1
  101. /package/dist/{packet → binary}/decoder.d.ts +0 -0
  102. /package/dist/{packet → binary}/decoder.js +0 -0
  103. /package/dist/{packet → binary}/static.d.ts +0 -0
  104. /package/dist/{packet → binary}/static.js +0 -0
  105. /package/src/{packet → binary}/decoder.ts +0 -0
  106. /package/src/{packet → binary}/static.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaitosoi/minejs",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "A Minecraft client package",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -28,19 +28,17 @@
28
28
  "@clean-jsdoc-theme/typedoc": "5.0.5",
29
29
  "@eslint/js": "^10.0.1",
30
30
  "@stylistic/eslint-plugin": "^5.10.0",
31
- "@types/bun": "latest",
32
- "@types/node": "^26.1.1",
31
+ "@types/node": "^26.4.0",
33
32
  "@typescript/native": "npm:typescript@^7.0.2",
34
- "eslint": "^10.4.1",
35
- "globals": "^17.6.0",
36
- "tsx": "^4.22.4",
33
+ "eslint": "^10.9.1",
34
+ "globals": "^17.11.0",
35
+ "tsx": "^4.23.12",
37
36
  "typedoc": "^0.28.20",
38
37
  "typescript": "npm:@typescript/typescript6@^6.0.2",
39
- "typescript-eslint": "^8.60.1"
38
+ "typescript-eslint": "^8.68.0"
40
39
  },
41
40
  "dependencies": {
42
- "bitset": "^5.2.3",
43
- "zod": "^4.4.3"
41
+ "zod": "^4.5.2"
44
42
  },
45
- "packageManager": "pnpm@11.15.1+sha512.81350b07e53c9538a02f1f2303b4290fa2d7be04e56e2a970c4cc4b417dc761de196edabd49d55c7dc9580db81007c44143e4e3d7e462b3000d23c255122d065"
43
+ "packageManager": "pnpm@11.24.0"
46
44
  }
@@ -1,42 +1,323 @@
1
- import BitSet_ from "bitset";
1
+ import assert from "node:assert";
2
+ import { UnexpectedValue } from "./error";
3
+ import { numberOfLeadingZeros, numberOfTrailingZeros } from "./math";
4
+
2
5
 
3
6
  /**
4
- * Custom implementation of BitSet to implement missing method
7
+ * Simplified implementation of the Java's BitSet class
8
+ *
9
+ * @see https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/BitSet.java
10
+ * @hidden
5
11
  */
6
- export class BitSet extends BitSet_ {
7
- public nextClearBit(fromIndex: number) {
8
- fromIndex = fromIndex || 0;
9
- const data = (this as any)['data'];
10
- let wordIndex = fromIndex >>> 5;
12
+ export class BitSet {
13
+ public static readonly ADDRESS_BITS_PER_WORD = 6;
14
+ public static readonly BITS_PER_WORD = 1 << this.ADDRESS_BITS_PER_WORD;
15
+ public static readonly WORD_MASK = 0xffffffffffffffffn;
16
+
17
+ public words: BigUint64Array;
18
+ public wordsInUse: number = 0;
19
+
20
+ private static wordIndex(bitIndex: number) {
21
+ return bitIndex >> this.ADDRESS_BITS_PER_WORD;
22
+ }
23
+
24
+ private static bitIndexInWord(bitIndex: number) {
25
+ return bitIndex & (this.BITS_PER_WORD - 1); // should be bitIndex & 63
26
+ }
27
+
28
+ /**
29
+ * Create a mask with lowest `n` bits set to 1
30
+ *
31
+ * For example:
32
+ * * n = 0 -> `0b0n`
33
+ * * n = 3 -> `0b111n`
34
+ * * n = 5 -> `0b11111n`
35
+ *
36
+ * @param nBits
37
+ * @returns
38
+ */
39
+ private static lowBits(nBits: number) {
40
+ return (1n << BigInt(nBits)) - 1n;
41
+ }
42
+
43
+ private initWords(nBits: number) {
44
+ return new BigUint64Array(BitSet.wordIndex(nBits - 1) + 1);
45
+ }
46
+
47
+ private static checkRange(fromIndex: number, toIndex: number) {
48
+ if (fromIndex < 0)
49
+ throw new UnexpectedValue("value of fromIndex", fromIndex.toString(), "non-negative number");
50
+ if (toIndex < 0)
51
+ throw new UnexpectedValue("value of toIndex", toIndex.toString(), "non-negative number");
52
+ if (fromIndex > toIndex)
53
+ throw new UnexpectedValue("fromIndex and toIndex", `fromIndex ${fromIndex}; toIndex ${toIndex}`, "fromIndex has to be smaller than toIndex");
54
+ }
55
+
56
+
57
+ constructor(nBits?: number) {
58
+ if (nBits && nBits < 0)
59
+ throw new UnexpectedValue("length of bitset", nBits.toString(), "non-negative number");
60
+ this.words = this.initWords(nBits ?? BitSet.BITS_PER_WORD);
61
+ }
62
+
63
+ public clone() {
64
+ const bitset = new BitSet(0);
65
+ bitset.words = structuredClone(this.words);
66
+ bitset.wordsInUse = this.wordsInUse;
67
+ bitset.checkInvariants();
68
+ return bitset;
69
+ }
11
70
 
12
- if (wordIndex >= data.length) {
13
- // Past the stored words — depends on the infinite tail bit
14
- return (this as any)['_'] === 0 ? fromIndex : Infinity;
71
+ private expandTo(wordIndex: number) {
72
+ const wordsRequired = wordIndex + 1;
73
+ if (this.wordsInUse < wordsRequired) {
74
+ this.ensureCapacity(wordsRequired);
75
+ this.wordsInUse = wordsRequired;
15
76
  }
77
+ }
16
78
 
17
- // ~word marks clear bits; mask off anything before fromIndex.
18
- // JS's << only uses the low 5 bits of the shift amount, so
19
- // `-1 << fromIndex` masks correctly even when fromIndex > 31.
20
- let word = ~data[wordIndex] & (-1 << fromIndex);
79
+ private ensureCapacity(wordsRequired: number) {
80
+ if (wordsRequired > this.words.length) {
81
+ // Allocate larger of doubled size or required size
82
+ const request = Math.max(2 * this.words.length, wordsRequired);
83
+ const newWords = new BigUint64Array(request);
84
+ newWords.set(this.words);
85
+ this.words = newWords;
86
+ }
87
+ }
21
88
 
22
- while (true) {
23
- if (word !== 0) {
24
- const lowestSet = word & -word; // isolate lowest set bit
25
- let c = 0;
26
- for (let v = lowestSet; (v >>>= 1); c++) {
27
- //
28
- }
29
- return wordIndex * 32 + c;
30
- }
31
- wordIndex++;
32
- if (wordIndex >= data.length) {
33
- return (this as any)['_'] === 0 ? wordIndex * 32 : Infinity;
89
+ private recalculateWordsInUse() {
90
+ let i = this.wordsInUse - 1;
91
+ while (i >= 0 && this.words[i] === 0n) i--;
92
+ this.wordsInUse = i + 1; // The new logical size
93
+ }
94
+
95
+ private checkInvariants() {
96
+ assert(this.wordsInUse === 0 || this.words[this.wordsInUse - 1] !== 0n);
97
+ assert(this.wordsInUse >= 0 && this.wordsInUse <= this.words.length);
98
+ assert(this.wordsInUse === this.words.length || this.words[this.wordsInUse] === 0n);
99
+ }
100
+
101
+
102
+ public toByteArray() {
103
+ const n = this.wordsInUse;
104
+ if (n == 0)
105
+ return [];
106
+
107
+ const bytes: number[] = [];
108
+ for (const word of this.words) {
109
+ let coppiedWord = structuredClone(word);
110
+ // Slice a 64-bit (or 8-byte word) into 8 8-bit (or 1-byte) slices
111
+ for (let i = 0; i < 8; i++) {
112
+ bytes.push(Number(coppiedWord & 0xffn));
113
+ coppiedWord >>= 8n;
34
114
  }
35
- word = ~data[wordIndex];
36
115
  }
37
- };
38
116
 
39
- public override clone(): BitSet {
40
- return new BitSet(this.toString());
117
+ while (bytes.length > 0 && bytes.at(-1) === 0) bytes.pop();
118
+ return bytes;
119
+ }
120
+
121
+ public flip(bitIndex: number) {
122
+ if (bitIndex < 0)
123
+ throw new UnexpectedValue("value of bitIndex", bitIndex.toString(), "non-negative number");
124
+
125
+ const wordIndex = BitSet.wordIndex(bitIndex);
126
+ this.expandTo(wordIndex);
127
+
128
+ this.words[wordIndex]! ^= BigInt(BitSet.bitIndexInWord(bitIndex));
129
+
130
+ this.recalculateWordsInUse();
131
+ this.checkInvariants();
41
132
  }
42
- }
133
+
134
+ public set(bitIndex: number) {
135
+ if (bitIndex < 0)
136
+ throw new UnexpectedValue("value of bitIndex", bitIndex.toString(), "non-negative number");
137
+
138
+ const wordIndex = BitSet.wordIndex(bitIndex);
139
+ this.expandTo(wordIndex);
140
+
141
+ this.words[wordIndex]! |= 1n << BigInt(BitSet.bitIndexInWord(bitIndex)); // Restores invariants
142
+
143
+ this.checkInvariants();
144
+ }
145
+ public setRange(fromIndex: number, toIndex: number) {
146
+ BitSet.checkRange(fromIndex, toIndex);
147
+
148
+ if (fromIndex == toIndex)
149
+ return;
150
+
151
+ // Increase capacity if necessary
152
+ const startWordIndex = BitSet.wordIndex(fromIndex);
153
+ const endWordIndex = BitSet.wordIndex(toIndex - 1);
154
+ this.expandTo(endWordIndex);
155
+
156
+ const fromBit = BitSet.bitIndexInWord(fromIndex),
157
+ toBitInclusive = BitSet.bitIndexInWord(toIndex - 1) + 1,
158
+
159
+ /**
160
+ * The NOT (~) bitwise meaning:
161
+ *
162
+ * Let say we want to set 2 to 6:
163
+ * ```
164
+ * 110010100
165
+ * ^ ^
166
+ * | +-- this is the 2nd bit
167
+ * and this is the 6th bit
168
+ * ```
169
+ *
170
+ * So we call lowBits(2) and it return `...0011`
171
+ *
172
+ * Then we have to flip it to `...1100` to access the '2nd bit and the bits after it'
173
+ */
174
+ firstWordMask = ~BitSet.lowBits(fromBit),
175
+ lastWordMask = BitSet.lowBits(toBitInclusive);
176
+ if (startWordIndex == endWordIndex) {
177
+ // Case 1: One word
178
+ this.words[startWordIndex]! |= (firstWordMask & lastWordMask);
179
+ } else {
180
+ // Case 2: Multiple words
181
+ // Handle first word
182
+ this.words[startWordIndex]! |= firstWordMask;
183
+
184
+ // Handle intermediate words, if any
185
+ for (let i = startWordIndex + 1; i < endWordIndex; i++)
186
+ this.words[i] = BitSet.WORD_MASK;
187
+
188
+ // Handle last word (restores invariants)
189
+ this.words[endWordIndex]! |= lastWordMask;
190
+ }
191
+
192
+ this.checkInvariants();
193
+ }
194
+
195
+
196
+ public clear(bitIndex: number) {
197
+ if (bitIndex < 0)
198
+ throw new UnexpectedValue("value of bitIndex", bitIndex.toString(), "non-negative number");
199
+
200
+ const wordIndex = BitSet.wordIndex(bitIndex);
201
+ if (wordIndex >= this.wordsInUse)
202
+ return;
203
+
204
+ this.words[wordIndex]! &= ~(1n << BigInt(bitIndex));
205
+
206
+ this.recalculateWordsInUse();
207
+ this.checkInvariants();
208
+ }
209
+ public clearRange(fromIndex: number, toIndex: number) {
210
+ BitSet.checkRange(fromIndex, toIndex);
211
+
212
+ if (fromIndex == toIndex)
213
+ return;
214
+
215
+ const startWordIndex = BitSet.wordIndex(fromIndex);
216
+ if (startWordIndex >= this.wordsInUse)
217
+ return;
218
+
219
+ let endWordIndex = BitSet.wordIndex(toIndex - 1);
220
+ if (endWordIndex >= this.wordsInUse) {
221
+ toIndex = this.length();
222
+ endWordIndex = this.wordsInUse - 1;
223
+ }
224
+
225
+ const fromBit = BitSet.bitIndexInWord(fromIndex),
226
+ toBitInclusive = BitSet.bitIndexInWord(toIndex - 1) + 1,
227
+ /**
228
+ * See the explaination in the setRange function
229
+ */
230
+ firstWordMask = ~BitSet.lowBits(fromBit),
231
+ lastWordMask = BitSet.lowBits(toBitInclusive);
232
+ if (startWordIndex == endWordIndex) {
233
+ // Case 1: One word
234
+ this.words[startWordIndex]! &= ~(firstWordMask & lastWordMask);
235
+ } else {
236
+ // Case 2: Multiple words
237
+ // Handle first word
238
+ this.words[startWordIndex]! &= ~firstWordMask;
239
+
240
+ // Handle intermediate words, if any
241
+ for (let i = startWordIndex + 1; i < endWordIndex; i++)
242
+ this.words[i]! = 0n;
243
+
244
+ // Handle last word
245
+ this.words[endWordIndex]! &= ~lastWordMask;
246
+ }
247
+
248
+ this.recalculateWordsInUse();
249
+ this.checkInvariants();
250
+ }
251
+
252
+
253
+ public get(bitIndex: number) {
254
+ if (bitIndex < 0)
255
+ throw new UnexpectedValue("value of bitIndex", bitIndex.toString(), "non-negative number");
256
+
257
+ this.checkInvariants();
258
+
259
+ const wordIndex = BitSet.wordIndex(bitIndex);
260
+ if (wordIndex >= this.wordsInUse) return false;
261
+
262
+ const bit = 1n << BigInt(BitSet.bitIndexInWord(bitIndex));
263
+ return (Number(this.words[wordIndex]! & bit) != 0);
264
+ }
265
+
266
+ public nextSetBit(fromIndex: number) {
267
+ if (fromIndex < 0)
268
+ throw new UnexpectedValue("value of fromIndex", fromIndex.toString(), "non-negative number");
269
+
270
+ this.checkInvariants();
271
+
272
+ let u = BitSet.wordIndex(fromIndex);
273
+ if (u >= this.wordsInUse)
274
+ return -1;
275
+
276
+ let word = this.words[u]! & (~0n << BigInt(BitSet.bitIndexInWord(fromIndex)));
277
+
278
+ while (true) {
279
+ if (word != 0n)
280
+ return (u * BitSet.BITS_PER_WORD) + numberOfTrailingZeros(word);
281
+ if (++u == this.wordsInUse)
282
+ return -1;
283
+ word = this.words[u]!;
284
+ }
285
+ }
286
+
287
+ public nextClearBit(fromIndex: number) {
288
+ // Neither spec nor implementation handle bitsets of maximal length.
289
+ // See 4816253.
290
+ if (fromIndex < 0)
291
+ throw new UnexpectedValue("value of fromIndex", fromIndex.toString(), "non-negative number");
292
+
293
+ this.checkInvariants();
294
+
295
+ let u = BitSet.wordIndex(fromIndex);
296
+ if (u >= this.wordsInUse)
297
+ return fromIndex;
298
+
299
+ let word = ~this.words[u]! & (BitSet.WORD_MASK << BigInt(fromIndex));
300
+
301
+ while (true) {
302
+ if (word != 0n)
303
+ return (u * BitSet.BITS_PER_WORD) + numberOfTrailingZeros(word);
304
+ if (++u == this.wordsInUse)
305
+ return this.wordsInUse * BitSet.BITS_PER_WORD;
306
+ word = ~this.words[u]!;
307
+ }
308
+ }
309
+
310
+ public length() {
311
+ if (this.wordsInUse == 0)
312
+ return 0;
313
+
314
+ return BitSet.BITS_PER_WORD * (this.wordsInUse - 1) +
315
+ (BitSet.BITS_PER_WORD - numberOfLeadingZeros(this.words[this.wordsInUse - 1]!));
316
+ }
317
+
318
+ public isEmpty() {
319
+ return this.wordsInUse == 0;
320
+ }
321
+ }
322
+
323
+ export default BitSet;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The base implementation for the Cache class
3
+ */
4
+ export abstract class CacheImplementation<T = any> {
5
+ public abstract put(key: string, item: T): void;
6
+ public abstract get(key: string): T | undefined;
7
+ public abstract del(key: string): void;
8
+ }
9
+
10
+ /**
11
+ * The LRU cache implementation.
12
+ *
13
+ * @see https://en.wikipedia.org/wiki/Cache_replacement_policies#Time-Aware,_Least_Recently_Used_(TLRU)
14
+ */
15
+ export class LRUCache<T> extends CacheImplementation<T> {
16
+ private hash: Map<string, T> = new Map();
17
+ private list: string[] = [];
18
+
19
+ constructor(private capacity: number) {
20
+ super();
21
+ }
22
+
23
+ public put(key: string, item: T): void {
24
+ if (this.hash.has(key)) {
25
+ const oldIndex = this.list.indexOf(key);
26
+ if (oldIndex > -1)
27
+ this.list.splice(oldIndex, 1);
28
+ }
29
+
30
+ this.hash.set(key, item);
31
+ this.list.push(key);
32
+
33
+ this.truncateHash();
34
+ }
35
+
36
+ public get(key: string) {
37
+ if (!this.hash.has(key)) return undefined;
38
+
39
+ const item = this.hash.get(key);
40
+ const oldIndex = this.list.indexOf(key);
41
+ if (oldIndex > -1)
42
+ this.list.splice(oldIndex, 1);
43
+ this.list.push(key);
44
+
45
+ return item;
46
+ }
47
+
48
+ public del(key: string): void {
49
+ const oldIndex = this.list.indexOf(key);
50
+ if (oldIndex > -1)
51
+ this.list.splice(oldIndex, 1);
52
+ this.hash.delete(key);
53
+ }
54
+
55
+ private truncateHash() {
56
+ while (this.list.length > this.capacity) {
57
+ const popping = this.list.pop();
58
+ if (popping)
59
+ this.hash.delete(popping);
60
+ }
61
+ }
62
+ }
package/src/base/error.ts CHANGED
@@ -131,6 +131,7 @@ export class MissingAuthOption extends Error {
131
131
  }
132
132
  }
133
133
 
134
+ /** @hidden */
134
135
  export class AuthRelatedNotFound extends Error {
135
136
  constructor(public component: string) {
136
137
  super(`auth option is enabled, but the auth related component (${component}) is not found`);
@@ -190,18 +191,33 @@ export class NotImplemented extends Error {
190
191
  }
191
192
  }
192
193
 
194
+
195
+ /** @hidden */
196
+ export class SkippableNotImplemented extends Error {}
197
+
193
198
  /*
194
199
  * Messages
195
200
  */
196
201
 
202
+ /** @hidden */
197
203
  export class MessageLinkNotFound extends Error {
198
204
  constructor(public senderUUID: string) {
199
205
  super(`message link of sender ${senderUUID} not found, maybe because server has sent out of order packet`);
200
206
  }
201
207
  }
202
208
 
209
+ /** @hidden */
203
210
  export class HaveSignatureButNotIndex extends Error {
204
211
  constructor() {
205
212
  super (`expecting both shouldVerifyMessageOrder set to true when shouldVerifyMessageSignature set to true`);
206
213
  }
214
+ }
215
+
216
+ /**
217
+ * @hidden
218
+ */
219
+ export class MessageTooLong extends Error {
220
+ constructor(public message: string) {
221
+ super(`your message is exceeding the 256 characters long limit, got ${message.length} characters`);
222
+ }
207
223
  }
package/src/base/math.ts CHANGED
@@ -112,4 +112,46 @@ export function minecraftSha1(
112
112
  function mcHexDigest(digest: Buffer | Uint8Array): string {
113
113
  const bigint = BigInt(`0x${digest.toString('hex')}`);
114
114
  return BigInt.asIntN(digest.length * 8, bigint).toString(16);
115
- }
115
+ }
116
+
117
+ /**
118
+ * Simplified implementation of Java's Long.numberOfTrailingZeros
119
+ * @param n
120
+ * @returns
121
+ */
122
+ export function numberOfTrailingZeros(n: bigint): number {
123
+ if (n === 0n) {
124
+ return 64;
125
+ }
126
+
127
+ let count = 0;
128
+ while ((n & 1n) === 0n) {
129
+ count++;
130
+ n >>= 1n;
131
+ }
132
+
133
+ return count;
134
+ }
135
+
136
+ /**
137
+ * Simplified implementation of Java's Long.numberOfLeadingZeros
138
+ * @param n
139
+ * @returns
140
+ */
141
+ export function numberOfLeadingZeros(n: bigint): number {
142
+ if (n === 0n) {
143
+ return 64;
144
+ }
145
+
146
+ let count = 0;
147
+ // Start checking from bit 63 (the most significant bit)
148
+ for (let i = 63; i >= 0; i--) {
149
+ if ((n & (1n << BigInt(i))) === 0n) {
150
+ count++;
151
+ } else {
152
+ break; // Stop at the first 1 bit
153
+ }
154
+ }
155
+
156
+ return count;
157
+ }
@@ -8,3 +8,8 @@ export type If<Condition extends boolean, True, False = null> = Condition extend
8
8
  * @see https://minecraft.wiki/w/Text_component_format
9
9
  */
10
10
  export type TextComponent = Record<string, any>;
11
+
12
+ export interface RegistryData {
13
+ registry_id: string,
14
+ entries: { entry_id: string, data: Record<string, any> | null }[]
15
+ }
@@ -62,9 +62,13 @@ export class BinaryEncoder {
62
62
  */
63
63
  public writeInt(val: number) { return this.write(4, val, (buf) => buf.writeInt32BE); }
64
64
  /**
65
- * Write 6 bytes singed integer
65
+ * Write 8 bytes singed integer
66
66
  */
67
- public writeLong(val: bigint) { return this.write(8, val, (buf) => buf.writeBigInt64BE); }
67
+ public writeLong(val: bigint | number) {
68
+ // Cast to BigInt
69
+ const v = typeof val === "bigint" ? val : BigInt(val);
70
+ return this.write(8, v, (buf) => buf.writeBigInt64BE);
71
+ }
68
72
  /**
69
73
  * Write 4 bytes float
70
74
  */