Skip to content

Commit 14cc714

Browse files
committed
Database Visualizations Demo
Looking into explaining how to parse the keys of the database! Working with @PMK744
1 parent f0dd6ee commit 14cc714

File tree

3 files changed

+53
-69
lines changed

3 files changed

+53
-69
lines changed

src/database.ts

Lines changed: 34 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,59 @@
11
import { LevelDB } from "leveldb-zlib";
2-
import { DimensionID } from "../Region-Types/dist/bedrock/index.js";
32
import { readEntry } from "./entry.js";
43

5-
import type { ChunkKeyNameMap, WorldKeyNameMap, SuffixKeyNameMap } from "../Region-Types/dist/bedrock/index.js";
6-
7-
export type Entries = {
8-
overworld: Chunk[];
9-
nether: Chunk[];
10-
end: Chunk[];
11-
} & {
12-
[K in keyof WorldKeyNameMap]?: WorldKeyNameMap[K];
13-
} & {
14-
[K in keyof SuffixKeyNameMap as `${K}${string}`]?: SuffixKeyNameMap[K];
15-
}
16-
17-
export type Chunk = {
18-
x: number;
19-
y: number;
20-
subchunks: Buffer[];
21-
} & {
22-
[K in keyof ChunkKeyNameMap]?: ChunkKeyNameMap[K];
23-
}
4+
import type { Key } from "../Region-Types/dist/bedrock/index.js";
245

256
// not sure about the indexing here yet, still messy with these fancy types now
26-
export async function readDatabase(path: string): Promise<Entries> {
7+
export async function readDatabase(path: string): Promise<Key[]> {
278
const db = new LevelDB(path,{ createIfMissing: false });
289
await db.open();
2910

30-
const entries: Entries = {
31-
overworld: [],
32-
nether: [],
33-
end: [],
34-
};
11+
const entries: Key[] = [];
3512

3613
// for await (const [keyBuffer] of db.getIterator({ keys: true, values: false })){
3714
// const key = (await import("./entry.js")).readKey(keyBuffer);
3815
// console.log(key);
3916
// }
4017

41-
for await (const entry of (db.getIterator() as AsyncIterable<[Buffer, Buffer]>)){
42-
const result = await readEntry(entry);
43-
// console.log(result);
18+
// for await (const entry of (db.getIterator() as AsyncIterable<[Buffer, Buffer]>)){
19+
// const result = await readEntry(entry);
20+
// // console.log(result);
4421

45-
const [key, value] = result;
22+
// const [key, value] = result;
4623

47-
if (typeof key !== "object"){
48-
entries[key] = value as any;
49-
// console.log(key,value);
50-
continue;
51-
}
24+
// if (typeof key !== "object"){
25+
// entries[key] = value as any;
26+
// // console.log(key,value);
27+
// continue;
28+
// }
5229

53-
// continue;
30+
// // continue;
5431

55-
if (!("x" in key) || !("y" in key)){
56-
entries[key.key.toString() as `${keyof SuffixKeyNameMap}${string}`] = value as any;
57-
continue;
58-
}
32+
// if (!("x" in key) || !("y" in key)){
33+
// entries[key.key.toString() as `${keyof SuffixKeyNameMap}${string}`] = value as any;
34+
// continue;
35+
// }
5936

60-
const { x, y, type, dimension, subchunk } = key;
61-
let chunk: Chunk | undefined = entries[DimensionID[dimension] as keyof typeof DimensionID].find(entry => entry.x === x && entry.y === y);
37+
// const { x, y, type, dimension, subchunk } = key;
38+
// let chunk: Chunk | undefined = entries[DimensionID[dimension] as keyof typeof DimensionID].find(entry => entry.x === x && entry.y === y);
6239

63-
if (chunk === undefined){
64-
chunk = { x, y, subchunks: [] };
65-
entries[DimensionID[dimension] as keyof typeof DimensionID].push(chunk);
66-
}
40+
// if (chunk === undefined){
41+
// chunk = { x, y, subchunks: [] };
42+
// entries[DimensionID[dimension] as keyof typeof DimensionID].push(chunk);
43+
// }
6744

68-
if (type === "SubChunkPrefix"){
69-
chunk.subchunks[subchunk!] = value as Buffer;
70-
continue;
71-
}
45+
// if (type === "SubChunkPrefix"){
46+
// chunk.subchunks[subchunk!] = value as Buffer;
47+
// continue;
48+
// }
7249

73-
chunk[type] = value as any;
50+
// chunk[type] = value as any;
51+
// }
52+
53+
for await (const entry of (db.getIterator() as AsyncIterable<[Buffer, Buffer]>)){
54+
const result = await readEntry(entry);
55+
// console.log(result);
56+
entries.push(result);
7457
}
7558

7659
await db.close();

src/entry.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import type { ActorDigestVersion, ActorPrefix, AutonomousEntities, BiomeData, Bi
66

77
export type Entry = [Key, Value];
88

9-
export async function readEntry(entry: [Buffer, Buffer]): Promise<Entry> {
9+
export async function readEntry(entry: [Buffer, Buffer]): Promise<Key> {
1010
const key: Key = readKey(entry[0]);
11-
const value: Value = await readValue(key,entry[1]);
12-
return [key,value];
11+
// const value: Value = await readValue(key,entry[1]);
12+
return key;
1313
}
1414

1515
export function readKey(key: Buffer): Key {
@@ -53,17 +53,17 @@ export function readSuffixKey(key: Buffer): SuffixKeyEntry | null {
5353
}
5454

5555
switch (keyType){
56-
case "actorprefix": return { type: keyType, key };
57-
case "digp": return { type: keyType, key };
58-
case "posTrackDB": return { type: keyType, key };
59-
case "player": return { type: keyType, key };
60-
case "player_server": return { type: keyType, key };
61-
case "tickingarea": return { type: keyType, key };
62-
case "VILLAGE_DWELLERS": return { type: keyType, key };
63-
case "VILLAGE_INFO": return { type: keyType, key };
64-
case "VILLAGE_PLAYERS": return { type: keyType, key };
65-
case "VILLAGE_POI": return { type: keyType, key };
66-
case "map": return { type: keyType, key };
56+
case "actorprefix":
57+
case "digp":
58+
case "posTrackDB":
59+
case "player":
60+
case "player_server":
61+
case "tickingarea":
62+
case "VILLAGE_DWELLERS":
63+
case "VILLAGE_INFO":
64+
case "VILLAGE_PLAYERS":
65+
case "VILLAGE_POI":
66+
case "map": return `${keyType}@0x${key.subarray(keyType.length).toString("hex")}`;
6767
default: return null;
6868
}
6969
}

test/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { fileURLToPath } from "node:url";
2-
import { DimensionID } from "../Region-Types/src/bedrock/index.js";
32
import { readDatabase } from "../src/index.js";
43

54
const WORLD = fileURLToPath(new URL("../test/world/My World/db",import.meta.url));
65

76
const data = await readDatabase(WORLD);
8-
console.log(data["~local_player"]?.data.abilities);
9-
console.log(DimensionID[data["~local_player"]?.data.DimensionId.valueOf()!]);
10-
console.log(data.portals?.data.data.PortalRecords.map(portal => DimensionID[portal.DimId.valueOf()]));
7+
8+
for (const key of data) {
9+
if (typeof key === "object" && "x" in key && "y" in key) continue;
10+
console.log(key);
11+
}

0 commit comments

Comments
 (0)