mcbe-leveldb 1.13.1 → 1.14.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.
package/Changelog.md CHANGED
@@ -1,3 +1,30 @@
1
+ # v1.14.0
2
+
3
+ ## Additions
4
+
5
+ - Added custom dimension support for chunk keys, and the `getChunkKeyIndices` and `generateChunkKeyFromIndices` functions.
6
+ - Added the following functions:
7
+ - `dimensionVectorDimensionToInt`
8
+ - `dimensionVectorDimensionToId`
9
+ - `dimensionVectorDimensionToIdSync`
10
+ - `dimensionIdToDimensionVectorDimension`
11
+ - `dimensionIdToDimensionVectorDimensionSync`
12
+ - `intToDimensionVectorDimension`
13
+ - `getDimensionTypes`
14
+ - `getDimensionTypesSync`
15
+ - `getDimensionIds`
16
+ - `getDimensionIdsSync`
17
+ - `getDimensionNumericIds`
18
+ - `getDimensionNumericIdsSync`
19
+
20
+ ## Changes
21
+
22
+ - The `dimension` field of dimension vectors is now a union of `Dimension` and `number` instead of just `Dimension`.
23
+
24
+ ## Fixes
25
+
26
+ - Fixed a bug where the `entries` field of the `DimensionNameIdTable` NBT schema was marked as optional.
27
+
1
28
  # v1.13.1
2
29
 
3
30
  ## Fixes
package/LevelUtils.d.ts CHANGED
@@ -2,6 +2,8 @@ import NBT from "prismarine-nbt";
2
2
  import BiomeData from "./__biome_data__.ts";
3
3
  import type { LevelDB } from "@8crafter/leveldb-zlib";
4
4
  import type { NBTSchemas } from "./nbtSchemas.ts";
5
+ import type { LooseAutocomplete } from "./types.js";
6
+ import type { DimensionNameIdTable } from "./test/nbtSchemaTypeScriptInterfaces.js";
5
7
  /**
6
8
  * A tuple of length 16.
7
9
  *
@@ -1539,7 +1541,7 @@ export interface DimensionLocation extends Vector3 {
1539
1541
  /**
1540
1542
  * Dimension that this coordinate is associated with.
1541
1543
  */
1542
- dimension: Dimension;
1544
+ dimension: Dimension | number;
1543
1545
  }
1544
1546
  /**
1545
1547
  * Represents a two-directional vector with an associated dimension.
@@ -1548,7 +1550,7 @@ export interface DimensionVector2 extends Vector2 {
1548
1550
  /**
1549
1551
  * Dimension that this coordinate is associated with.
1550
1552
  */
1551
- dimension: Dimension;
1553
+ dimension: Dimension | number;
1552
1554
  }
1553
1555
  /**
1554
1556
  * Represents a two-directional vector with X and Z components and an associated dimension.
@@ -1557,7 +1559,7 @@ export interface DimensionVectorXZ extends VectorXZ {
1557
1559
  /**
1558
1560
  * Dimension that this coordinate is associated with.
1559
1561
  */
1560
- dimension: Dimension;
1562
+ dimension: Dimension | number;
1561
1563
  }
1562
1564
  /**
1563
1565
  * Represents a two-directional vector with X and Z components and an associated dimension and a sub-chunk index.
@@ -1750,6 +1752,118 @@ export declare function splitRange([min, max]: [min: number, max: number], size:
1750
1752
  * @param blocksPerWord How many blocks fit inside one 32-bit integer.
1751
1753
  */
1752
1754
  export declare function writeBlockIndices(buffer: Buffer, blockDataOffset: number, block_indices: number[], bitsPerBlock: number, blocksPerWord: number): void;
1755
+ /**
1756
+ * Converts the dimension of a dimension vector to a numeric ID.
1757
+ *
1758
+ * @param dimension The dimension to convert.
1759
+ * @returns The numeric ID of the dimension.
1760
+ */
1761
+ export declare function dimensionVectorDimensionToInt(dimension: Dimension | number): number;
1762
+ /**
1763
+ * Converts the dimension of a dimension vector to a ID.
1764
+ *
1765
+ * Vanilla dimensions will not include a namespace.
1766
+ *
1767
+ * @param dimension The dimension to convert.
1768
+ * @param db The LevelDB to use.
1769
+ * @returns The ID of the dimension.
1770
+ *
1771
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
1772
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
1773
+ */
1774
+ export declare function dimensionVectorDimensionToId(dimension: Dimension | number, db: LevelDB): Promise<LooseAutocomplete<Dimension>>;
1775
+ /**
1776
+ * Converts the dimension of a dimension vector to a ID synchronously.
1777
+ *
1778
+ * Vanilla dimensions will not include a namespace.
1779
+ *
1780
+ * @param dimension The dimension to convert.
1781
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
1782
+ * @returns The ID of the dimension.
1783
+ *
1784
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
1785
+ */
1786
+ export declare function dimensionVectorDimensionToIdSync(dimension: Dimension | number, dimensionNameIdTable: DimensionNameIdTable): LooseAutocomplete<Dimension>;
1787
+ /**
1788
+ * Converts the ID of a dimension of a dimension vector.
1789
+ *
1790
+ * Vanilla dimensions do not require a namespace.
1791
+ *
1792
+ * @param dimension The dimension to convert. Case-sensitive.
1793
+ * @param db The LevelDB to use.
1794
+ * @returns The ID of the dimension.
1795
+ *
1796
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
1797
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
1798
+ */
1799
+ export declare function dimensionIdToDimensionVectorDimension(dimension: LooseAutocomplete<Dimension>, db: LevelDB): Promise<Dimension | number>;
1800
+ /**
1801
+ * Converts the ID of a dimension of a dimension vector synchronously.
1802
+ *
1803
+ * Vanilla dimensions do not require a namespace.
1804
+ *
1805
+ * @param dimension The dimension to convert. Case-sensitive.
1806
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
1807
+ * @returns The ID of the dimension.
1808
+ *
1809
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
1810
+ */
1811
+ export declare function dimensionIdToDimensionVectorDimensionSync(dimension: LooseAutocomplete<Dimension>, dimensionNameIdTable: DimensionNameIdTable): Dimension | number;
1812
+ /**
1813
+ * Converts a dimension's numeric ID to a dimension vector dimension.
1814
+ *
1815
+ * @param dimension The numeric ID of the dimension.
1816
+ * @returns The dimension vector dimension.
1817
+ */
1818
+ export declare function intToDimensionVectorDimension(dimension: number): Dimension | number;
1819
+ /**
1820
+ * Gets the dimension types from the DimensionNameIdTable.
1821
+ *
1822
+ * @param db The LevelDB to use.
1823
+ * @returns The dimension types.
1824
+ *
1825
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
1826
+ */
1827
+ export declare function getDimensionTypes(db: LevelDB): Promise<Record<Dimension | `${string}:${string}`, number>>;
1828
+ /**
1829
+ * Gets the dimension types from the DimensionNameIdTable synchronously.
1830
+ *
1831
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
1832
+ * @returns The dimension types.
1833
+ */
1834
+ export declare function getDimensionTypesSync(dimensionNameIdTable: DimensionNameIdTable): Record<Dimension | `${string}:${string}`, number>;
1835
+ /**
1836
+ * Gets the dimension IDs from the DimensionNameIdTable.
1837
+ *
1838
+ * @param db The LevelDB to use.
1839
+ * @returns The dimension IDs.
1840
+ *
1841
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
1842
+ */
1843
+ export declare function getDimensionIds(db: LevelDB): Promise<(Dimension | `${string}:${string}`)[]>;
1844
+ /**
1845
+ * Gets the dimension IDs from the DimensionNameIdTable synchronously.
1846
+ *
1847
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
1848
+ * @returns The dimension IDs.
1849
+ */
1850
+ export declare function getDimensionIdsSync(dimensionNameIdTable: DimensionNameIdTable): (Dimension | `${string}:${string}`)[];
1851
+ /**
1852
+ * Gets the dimension numeric IDs from the DimensionNameIdTable.
1853
+ *
1854
+ * @param db The LevelDB to use.
1855
+ * @returns The dimension numeric IDs.
1856
+ *
1857
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
1858
+ */
1859
+ export declare function getDimensionNumericIds(db: LevelDB): Promise<number[]>;
1860
+ /**
1861
+ * Gets the dimension numeric IDs from the DimensionNameIdTable synchronously.
1862
+ *
1863
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
1864
+ * @returns The dimension numeric IDs.
1865
+ */
1866
+ export declare function getDimensionNumericIdsSync(dimensionNameIdTable: DimensionNameIdTable): number[];
1753
1867
  /**
1754
1868
  * Gets the chunk indices from a LevelDB key.
1755
1869
  *
package/LevelUtils.js CHANGED
@@ -2509,6 +2509,190 @@ export function writeBlockIndices(buffer, blockDataOffset, block_indices, bitsPe
2509
2509
  setInt32Val(buffer, blockDataOffset + wordIndex * 4, maskVal);
2510
2510
  }
2511
2511
  }
2512
+ /**
2513
+ * Converts the dimension of a dimension vector to a numeric ID.
2514
+ *
2515
+ * @param dimension The dimension to convert.
2516
+ * @returns The numeric ID of the dimension.
2517
+ */
2518
+ export function dimensionVectorDimensionToInt(dimension) {
2519
+ return typeof dimension === "string" ? dimensions.indexOf(dimension) : dimension;
2520
+ }
2521
+ /**
2522
+ * Converts the dimension of a dimension vector to a ID.
2523
+ *
2524
+ * Vanilla dimensions will not include a namespace.
2525
+ *
2526
+ * @param dimension The dimension to convert.
2527
+ * @param db The LevelDB to use.
2528
+ * @returns The ID of the dimension.
2529
+ *
2530
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
2531
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
2532
+ */
2533
+ export async function dimensionVectorDimensionToId(dimension, db) {
2534
+ if (typeof dimension === "string")
2535
+ return dimension;
2536
+ const rawDimensionNameIdTable = await db.get("DimensionNameIdTable");
2537
+ if (rawDimensionNameIdTable === null)
2538
+ throw new ReferenceError("DimensionNameIdTable not found.");
2539
+ const dimensionNameIdTable = NBT.parseUncompressed(rawDimensionNameIdTable, "little");
2540
+ const dimensionNamespacedId = Object.entries(dimensionNameIdTable.value.entries.value).find(([_namespacedId, numericId]) => numericId.value === dimension)?.[0];
2541
+ if (dimensionNamespacedId === undefined)
2542
+ throw new ReferenceError(`Dimension ${dimension} not found in DimensionNameIdTable.`);
2543
+ return dimensionNamespacedId;
2544
+ }
2545
+ /**
2546
+ * Converts the dimension of a dimension vector to a ID synchronously.
2547
+ *
2548
+ * Vanilla dimensions will not include a namespace.
2549
+ *
2550
+ * @param dimension The dimension to convert.
2551
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
2552
+ * @returns The ID of the dimension.
2553
+ *
2554
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
2555
+ */
2556
+ export function dimensionVectorDimensionToIdSync(dimension, dimensionNameIdTable) {
2557
+ if (typeof dimension === "string")
2558
+ return dimension;
2559
+ const dimensionNamespacedId = Object.entries(dimensionNameIdTable.value.entries.value).find(([_namespacedId, numericId]) => numericId.value === dimension)?.[0];
2560
+ if (dimensionNamespacedId === undefined)
2561
+ throw new ReferenceError(`Dimension ${dimension} not found in DimensionNameIdTable.`);
2562
+ return dimensionNamespacedId;
2563
+ }
2564
+ /**
2565
+ * Converts the ID of a dimension of a dimension vector.
2566
+ *
2567
+ * Vanilla dimensions do not require a namespace.
2568
+ *
2569
+ * @param dimension The dimension to convert. Case-sensitive.
2570
+ * @param db The LevelDB to use.
2571
+ * @returns The ID of the dimension.
2572
+ *
2573
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
2574
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
2575
+ */
2576
+ export async function dimensionIdToDimensionVectorDimension(dimension, db) {
2577
+ if (dimensions.includes(dimension.replace(/^minecraft:/, "")))
2578
+ return dimension.replace(/^minecraft:/, "");
2579
+ const rawDimensionNameIdTable = await db.get("DimensionNameIdTable");
2580
+ if (rawDimensionNameIdTable === null)
2581
+ throw new ReferenceError("DimensionNameIdTable not found.");
2582
+ const dimensionNameIdTable = NBT.parseUncompressed(rawDimensionNameIdTable, "little");
2583
+ const dimensionNumericId = Object.entries(dimensionNameIdTable.value.entries.value).find(([namespacedId, _numericId]) => namespacedId === dimension)?.[1].value;
2584
+ if (dimensionNumericId === undefined)
2585
+ throw new ReferenceError(`Dimension ${dimension} not found in DimensionNameIdTable.`);
2586
+ return dimensionNumericId;
2587
+ }
2588
+ /**
2589
+ * Converts the ID of a dimension of a dimension vector synchronously.
2590
+ *
2591
+ * Vanilla dimensions do not require a namespace.
2592
+ *
2593
+ * @param dimension The dimension to convert. Case-sensitive.
2594
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
2595
+ * @returns The ID of the dimension.
2596
+ *
2597
+ * @throws {ReferenceError} If the dimension is not found in the DimensionNameIdTable.
2598
+ */
2599
+ export function dimensionIdToDimensionVectorDimensionSync(dimension, dimensionNameIdTable) {
2600
+ if (dimensions.includes(dimension.replace(/^minecraft:/, "")))
2601
+ return dimension.replace(/^minecraft:/, "");
2602
+ const dimensionNumericId = Object.entries(dimensionNameIdTable.value.entries.value).find(([namespacedId, _numericId]) => namespacedId === dimension)?.[1].value;
2603
+ if (dimensionNumericId === undefined)
2604
+ throw new ReferenceError(`Dimension ${dimension} not found in DimensionNameIdTable.`);
2605
+ return dimensionNumericId;
2606
+ }
2607
+ /**
2608
+ * Converts a dimension's numeric ID to a dimension vector dimension.
2609
+ *
2610
+ * @param dimension The numeric ID of the dimension.
2611
+ * @returns The dimension vector dimension.
2612
+ */
2613
+ export function intToDimensionVectorDimension(dimension) {
2614
+ return dimensions[dimension] ?? dimension;
2615
+ }
2616
+ /**
2617
+ * Gets the dimension types from the DimensionNameIdTable.
2618
+ *
2619
+ * @param db The LevelDB to use.
2620
+ * @returns The dimension types.
2621
+ *
2622
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
2623
+ */
2624
+ export async function getDimensionTypes(db) {
2625
+ const rawDimensionNameIdTable = await db.get("DimensionNameIdTable");
2626
+ if (rawDimensionNameIdTable === null)
2627
+ throw new ReferenceError("DimensionNameIdTable not found.");
2628
+ const dimensionNameIdTable = NBT.parseUncompressed(rawDimensionNameIdTable, "little");
2629
+ return getDimensionTypesSync(dimensionNameIdTable);
2630
+ }
2631
+ /**
2632
+ * Gets the dimension types from the DimensionNameIdTable synchronously.
2633
+ *
2634
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
2635
+ * @returns The dimension types.
2636
+ */
2637
+ export function getDimensionTypesSync(dimensionNameIdTable) {
2638
+ return {
2639
+ ...Object.fromEntries(dimensions.map((dimension, i) => [dimension, i])),
2640
+ ...Object.fromEntries(Object.entries(dimensionNameIdTable.value.entries.value).map(([namespacedId, numericId]) => [namespacedId, numericId.value])),
2641
+ };
2642
+ }
2643
+ /**
2644
+ * Gets the dimension IDs from the DimensionNameIdTable.
2645
+ *
2646
+ * @param db The LevelDB to use.
2647
+ * @returns The dimension IDs.
2648
+ *
2649
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
2650
+ */
2651
+ export async function getDimensionIds(db) {
2652
+ const rawDimensionNameIdTable = await db.get("DimensionNameIdTable");
2653
+ if (rawDimensionNameIdTable === null)
2654
+ throw new ReferenceError("DimensionNameIdTable not found.");
2655
+ const dimensionNameIdTable = NBT.parseUncompressed(rawDimensionNameIdTable, "little");
2656
+ return getDimensionIdsSync(dimensionNameIdTable);
2657
+ }
2658
+ /**
2659
+ * Gets the dimension IDs from the DimensionNameIdTable synchronously.
2660
+ *
2661
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
2662
+ * @returns The dimension IDs.
2663
+ */
2664
+ export function getDimensionIdsSync(dimensionNameIdTable) {
2665
+ return [...new Set([...dimensions, ...Object.keys(dimensionNameIdTable.value.entries.value)])];
2666
+ }
2667
+ /**
2668
+ * Gets the dimension numeric IDs from the DimensionNameIdTable.
2669
+ *
2670
+ * @param db The LevelDB to use.
2671
+ * @returns The dimension numeric IDs.
2672
+ *
2673
+ * @throws {ReferenceError} If the DimensionNameIdTable is not found.
2674
+ */
2675
+ export async function getDimensionNumericIds(db) {
2676
+ const rawDimensionNameIdTable = await db.get("DimensionNameIdTable");
2677
+ if (rawDimensionNameIdTable === null)
2678
+ throw new ReferenceError("DimensionNameIdTable not found.");
2679
+ const dimensionNameIdTable = NBT.parseUncompressed(rawDimensionNameIdTable, "little");
2680
+ return getDimensionNumericIdsSync(dimensionNameIdTable);
2681
+ }
2682
+ /**
2683
+ * Gets the dimension numeric IDs from the DimensionNameIdTable synchronously.
2684
+ *
2685
+ * @param dimensionNameIdTable The DimensionNameIdTable to use.
2686
+ * @returns The dimension numeric IDs.
2687
+ */
2688
+ export function getDimensionNumericIdsSync(dimensionNameIdTable) {
2689
+ return [
2690
+ ...new Set([
2691
+ ...dimensions.map((_dimension, i) => i),
2692
+ ...Object.values(dimensionNameIdTable.value.entries.value).map((numericId) => numericId.value),
2693
+ ]),
2694
+ ];
2695
+ }
2512
2696
  /**
2513
2697
  * Gets the chunk indices from a LevelDB key.
2514
2698
  *
@@ -2521,7 +2705,7 @@ export function getChunkKeyIndices(key) {
2521
2705
  return {
2522
2706
  x: getInt32Val(key, 0),
2523
2707
  z: getInt32Val(key, 4),
2524
- dimension: [13, 14].includes(key.length) ? (dimensions[getInt32Val(key, 8)] ?? "overworld") : "overworld",
2708
+ dimension: [13, 14].includes(key.length) ? (dimensions[getInt32Val(key, 8)] ?? getInt32Val(key, 8)) : "overworld",
2525
2709
  ...([10, 14].includes(key.length) ? { subChunkIndex: (key.at(-1) << 24) >> 24 } : undefined),
2526
2710
  };
2527
2711
  }
@@ -2533,11 +2717,13 @@ export function getChunkKeyIndices(key) {
2533
2717
  * @returns The raw chunk key.
2534
2718
  */
2535
2719
  export function generateChunkKeyFromIndices(indices, chunkKeyType) {
2720
+ if (typeof indices.dimension === "string" && dimensions.indexOf(indices.dimension) === -1)
2721
+ throw new TypeError(`Invalid dimension: ${indices.dimension}. For custom dimensions please provide the numeric ID instead.`);
2536
2722
  const buffer = Buffer.alloc((indices.dimension === "overworld" ? 9 : 13) + +("subChunkIndex" in indices && indices.subChunkIndex !== undefined));
2537
2723
  setInt32Val(buffer, 0, indices.x);
2538
2724
  setInt32Val(buffer, 4, indices.z);
2539
2725
  if (indices.dimension !== "overworld")
2540
- setInt32Val(buffer, 8, dimensions.indexOf(indices.dimension) ?? 0);
2726
+ setInt32Val(buffer, 8, typeof indices.dimension === "string" ? dimensions.indexOf(indices.dimension) : indices.dimension);
2541
2727
  buffer[8 + +(indices.dimension !== "overworld") * 4] = getIntFromChunkKeyType(chunkKeyType);
2542
2728
  if ("subChunkIndex" in indices && indices.subChunkIndex !== undefined)
2543
2729
  buffer[9 + +(indices.dimension !== "overworld") * 4] = indices.subChunkIndex;