mca-json 1.1.0 → 1.1.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.
- package/dist/bin/mca-find-signs.js +1 -1
- package/dist/bin/mca-find-signs.js.map +1 -1
- package/dist/lib/chunk.d.ts +3 -1
- package/dist/lib/chunk.d.ts.map +1 -1
- package/dist/lib/chunk.js +10 -8
- package/dist/lib/chunk.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/mca-find-signs.ts +1 -1
- package/src/lib/chunk.ts +12 -10
|
@@ -93,7 +93,7 @@ function processChunk(chunk) {
|
|
|
93
93
|
const foundSigns = [];
|
|
94
94
|
for (const blockName of blockNames) {
|
|
95
95
|
if (blockName.match(/^minecraft:.+_sign$/)) {
|
|
96
|
-
debugLog(`
|
|
96
|
+
debugLog(`Chunk lists sign name: ${blockName}`);
|
|
97
97
|
const listOfBlockCoordinates = chunk.findBlocksByName(blockName);
|
|
98
98
|
if (listOfBlockCoordinates.length === 0) {
|
|
99
99
|
debugLog(`Possible corruption - no blocks found for sign: ${blockName}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mca-find-signs.js","sourceRoot":"","sources":["../../src/bin/mca-find-signs.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport debug from 'debug';\nimport neodoc from 'neodoc';\nimport { Anvil } from '../lib/anvil';\nimport { Chunk } from '../lib/chunk';\nimport { Sign } from '../block/sign';\nimport { readFile } from 'node:fs/promises';\n\ninterface SignInfo {\n chunkX: number;\n chunkZ: number;\n x: number;\n y: number;\n z: number;\n front: string[];\n back: string[] | null;\n}\n\ninterface Args {\n '--blank'?: boolean;\n '--generated'?: boolean;\n '--first'?: boolean;\n '--user'?: boolean;\n '--verbose'?: boolean;\n MCA_FILE?: string[];\n}\n\nconst debugLog = debug('mca-find-signs');\nconst args: Args = neodoc.run(\n `Usage: mca-find-signs [OPTIONS] MCA_FILE...\n\nExtracts sign coordinates from MCA files. This is designed to find different\ncategories of signs.\n\n* Blank signs are blank on both sides.\n* Generated signs can be blank or have any non-numeric and non-alphabetic\n characters. This is so igloos with \"<----\" and \"---->\" are included.\n* User-created signs must have at least a number or a letter on the front or\n the back. There's no way to tell from the block data that a user placed a\n sign, but this is a good heuristic.\n\nThe default output is a JSON array that shows the following information:\n\n[\n {\n \"chunkX\": 0,\n \"chunkZ\": 3,\n \"x\": 12,\n \"y\": 34,\n \"z\": 56,\n \"front\": [\"Line 1\", \"Line 2\", \"Line 3\", \"Line 4\"],\n \"back\": [\"Line 1\", \"Line 2\", \"Line 3\", \"Line 4\"]\n },\n ...\n]\n\nOptions:\n --blank Only show blank signs. Conflicts with --generated and --user.\n --generated Only show generated signs. Conflicts with --blank and --user.\n --user Only show user-created signs. Conflicts with --blank and --generated.\n --first Stop scanning a chunk after the first sign is found.\n -h, --help Show this message.\n -v, --verbose Show more information during processing.\n`,\n {\n argv: [...process.argv].slice(2),\n laxPlacement: true,\n }\n);\n\nif (!args.MCA_FILE?.length) {\n console.error('No files specified.');\n process.exit(1);\n}\n\nif (\n (args['--blank'] ? 1 : 0) +\n (args['--generated'] ? 1 : 0) +\n (args['--user'] ? 1 : 0) >\n 1\n) {\n console.error(\n 'Conflicting options specified. Please choose only one of --blank, --generated, or --user.'\n );\n process.exit(1);\n}\n\nconst signs: SignInfo[] = [];\n\nfor (const file of args.MCA_FILE) {\n try {\n const moreSigns = await processFile(file);\n signs.push(...moreSigns);\n } catch (e) {\n console.error(`Error processing file ${file}: ${e}`);\n\n process.exit(1);\n }\n}\n\nconsole.log(JSON.stringify(signs, null, 4));\n\nasync function processFile(filename: string): Promise<SignInfo[]> {\n debugLog(`Reading file: ${filename}`);\n\n if (args['--verbose']) {\n console.log(`Reading file: ${filename}`);\n }\n\n const contents = await readFile(filename);\n const anvil = Anvil.fromBuffer(contents.buffer);\n const chunks = anvil.getAllChunks();\n const allSignsFound: SignInfo[] = [];\n\n for (const chunk of chunks) {\n const chunkKey = chunk.chunkKey() || '';\n const signs = processChunk(chunk);\n\n if (signs.length > 0) {\n debugLog(`Found ${signs.length} signs in chunk ${chunkKey}.`);\n\n if (args['--verbose']) {\n console.log(\n `Found ${signs.length} signs in chunk ${chunkKey}.`\n );\n }\n\n allSignsFound.push(...signs);\n }\n }\n\n return allSignsFound;\n}\n\nfunction processChunk(chunk: Chunk): SignInfo[] {\n const blockNames = chunk.uniqueBlockNames();\n const foundSigns: SignInfo[] = [];\n\n for (const blockName of blockNames) {\n if (blockName.match(/^minecraft:.+_sign$/)) {\n debugLog(`Found sign: ${blockName}`);\n\n const listOfBlockCoordinates = chunk.findBlocksByName(blockName);\n\n if (listOfBlockCoordinates.length === 0) {\n debugLog(\n `Possible corruption - no blocks found for sign: ${blockName}`\n );\n }\n\n for (const coords of listOfBlockCoordinates) {\n debugLog(`Checking block at coordinates: ${coords}`);\n const block = chunk.getBlock(coords);\n\n if (!(block instanceof Sign)) {\n throw new Error(\n `Block is supposed to be a sign: ${block.name}`\n );\n }\n\n const front = block.frontText();\n const back = block.backText();\n const text = [...front, ...(back ?? [])].join('');\n debugLog(`Front: ${JSON.stringify(front)}`);\n debugLog(`Back: ${JSON.stringify(back)}`);\n\n if (args['--blank'] && text.length !== 0) {\n debugLog(`Skipping non-blank sign.`);\n continue;\n }\n\n if (args['--generated'] && !text.match(/^[^a-z0-9]*$/i)) {\n debugLog(`Skipping user-created sign.`);\n }\n\n if (args['--user'] && !text.match(/[a-z0-9]/i)) {\n debugLog(`Skipping a possible generated sign.`);\n continue;\n }\n\n debugLog(`Found a matching sign.`);\n\n if (args['--verbose']) {\n console.log(\n `Found a matching sign: ${JSON.stringify(front)} and ${JSON.stringify(back)}`\n );\n }\n\n const chunkCoordinates = chunk.chunkCoordinates();\n\n if (!chunkCoordinates) {\n throw new Error('Chunk coordinates not found.');\n }\n\n foundSigns.push({\n chunkX: chunkCoordinates[0],\n chunkZ: chunkCoordinates[1],\n x: coords[0],\n y: coords[1],\n z: coords[2],\n front,\n back: back ?? null,\n });\n\n if (args['--first']) {\n return foundSigns;\n }\n }\n }\n }\n\n return foundSigns;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mca-find-signs.js","sourceRoot":"","sources":["../../src/bin/mca-find-signs.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport debug from 'debug';\nimport neodoc from 'neodoc';\nimport { Anvil } from '../lib/anvil';\nimport { Chunk } from '../lib/chunk';\nimport { Sign } from '../block/sign';\nimport { readFile } from 'node:fs/promises';\n\ninterface SignInfo {\n chunkX: number;\n chunkZ: number;\n x: number;\n y: number;\n z: number;\n front: string[];\n back: string[] | null;\n}\n\ninterface Args {\n '--blank'?: boolean;\n '--generated'?: boolean;\n '--first'?: boolean;\n '--user'?: boolean;\n '--verbose'?: boolean;\n MCA_FILE?: string[];\n}\n\nconst debugLog = debug('mca-find-signs');\nconst args: Args = neodoc.run(\n `Usage: mca-find-signs [OPTIONS] MCA_FILE...\n\nExtracts sign coordinates from MCA files. This is designed to find different\ncategories of signs.\n\n* Blank signs are blank on both sides.\n* Generated signs can be blank or have any non-numeric and non-alphabetic\n characters. This is so igloos with \"<----\" and \"---->\" are included.\n* User-created signs must have at least a number or a letter on the front or\n the back. There's no way to tell from the block data that a user placed a\n sign, but this is a good heuristic.\n\nThe default output is a JSON array that shows the following information:\n\n[\n {\n \"chunkX\": 0,\n \"chunkZ\": 3,\n \"x\": 12,\n \"y\": 34,\n \"z\": 56,\n \"front\": [\"Line 1\", \"Line 2\", \"Line 3\", \"Line 4\"],\n \"back\": [\"Line 1\", \"Line 2\", \"Line 3\", \"Line 4\"]\n },\n ...\n]\n\nOptions:\n --blank Only show blank signs. Conflicts with --generated and --user.\n --generated Only show generated signs. Conflicts with --blank and --user.\n --user Only show user-created signs. Conflicts with --blank and --generated.\n --first Stop scanning a chunk after the first sign is found.\n -h, --help Show this message.\n -v, --verbose Show more information during processing.\n`,\n {\n argv: [...process.argv].slice(2),\n laxPlacement: true,\n }\n);\n\nif (!args.MCA_FILE?.length) {\n console.error('No files specified.');\n process.exit(1);\n}\n\nif (\n (args['--blank'] ? 1 : 0) +\n (args['--generated'] ? 1 : 0) +\n (args['--user'] ? 1 : 0) >\n 1\n) {\n console.error(\n 'Conflicting options specified. Please choose only one of --blank, --generated, or --user.'\n );\n process.exit(1);\n}\n\nconst signs: SignInfo[] = [];\n\nfor (const file of args.MCA_FILE) {\n try {\n const moreSigns = await processFile(file);\n signs.push(...moreSigns);\n } catch (e) {\n console.error(`Error processing file ${file}: ${e}`);\n\n process.exit(1);\n }\n}\n\nconsole.log(JSON.stringify(signs, null, 4));\n\nasync function processFile(filename: string): Promise<SignInfo[]> {\n debugLog(`Reading file: ${filename}`);\n\n if (args['--verbose']) {\n console.log(`Reading file: ${filename}`);\n }\n\n const contents = await readFile(filename);\n const anvil = Anvil.fromBuffer(contents.buffer);\n const chunks = anvil.getAllChunks();\n const allSignsFound: SignInfo[] = [];\n\n for (const chunk of chunks) {\n const chunkKey = chunk.chunkKey() || '';\n const signs = processChunk(chunk);\n\n if (signs.length > 0) {\n debugLog(`Found ${signs.length} signs in chunk ${chunkKey}.`);\n\n if (args['--verbose']) {\n console.log(\n `Found ${signs.length} signs in chunk ${chunkKey}.`\n );\n }\n\n allSignsFound.push(...signs);\n }\n }\n\n return allSignsFound;\n}\n\nfunction processChunk(chunk: Chunk): SignInfo[] {\n const blockNames = chunk.uniqueBlockNames();\n const foundSigns: SignInfo[] = [];\n\n for (const blockName of blockNames) {\n if (blockName.match(/^minecraft:.+_sign$/)) {\n debugLog(`Chunk lists sign name: ${blockName}`);\n\n const listOfBlockCoordinates = chunk.findBlocksByName(blockName);\n\n if (listOfBlockCoordinates.length === 0) {\n debugLog(\n `Possible corruption - no blocks found for sign: ${blockName}`\n );\n }\n\n for (const coords of listOfBlockCoordinates) {\n debugLog(`Checking block at coordinates: ${coords}`);\n const block = chunk.getBlock(coords);\n\n if (!(block instanceof Sign)) {\n throw new Error(\n `Block is supposed to be a sign: ${block.name}`\n );\n }\n\n const front = block.frontText();\n const back = block.backText();\n const text = [...front, ...(back ?? [])].join('');\n debugLog(`Front: ${JSON.stringify(front)}`);\n debugLog(`Back: ${JSON.stringify(back)}`);\n\n if (args['--blank'] && text.length !== 0) {\n debugLog(`Skipping non-blank sign.`);\n continue;\n }\n\n if (args['--generated'] && !text.match(/^[^a-z0-9]*$/i)) {\n debugLog(`Skipping user-created sign.`);\n }\n\n if (args['--user'] && !text.match(/[a-z0-9]/i)) {\n debugLog(`Skipping a possible generated sign.`);\n continue;\n }\n\n debugLog(`Found a matching sign.`);\n\n if (args['--verbose']) {\n console.log(\n `Found a matching sign: ${JSON.stringify(front)} and ${JSON.stringify(back)}`\n );\n }\n\n const chunkCoordinates = chunk.chunkCoordinates();\n\n if (!chunkCoordinates) {\n throw new Error('Chunk coordinates not found.');\n }\n\n foundSigns.push({\n chunkX: chunkCoordinates[0],\n chunkZ: chunkCoordinates[1],\n x: coords[0],\n y: coords[1],\n z: coords[2],\n front,\n back: back ?? null,\n });\n\n if (args['--first']) {\n return foundSigns;\n }\n }\n }\n }\n\n return foundSigns;\n}\n"]}
|
package/dist/lib/chunk.d.ts
CHANGED
|
@@ -105,7 +105,9 @@ export declare class Chunk {
|
|
|
105
105
|
*/
|
|
106
106
|
private sectionsTag;
|
|
107
107
|
/**
|
|
108
|
-
* Returns the Y coordinate of a section, which goes from
|
|
108
|
+
* Returns the Y coordinate of a section, which goes from -4 to 19. If you
|
|
109
|
+
* want the world coordinate, pass true to get -64 to 304. The maximum supported
|
|
110
|
+
* range is -128 to 127 (chunk coordinates) or -2048 to 2032 (world coordinates).
|
|
109
111
|
*/
|
|
110
112
|
private sectionY;
|
|
111
113
|
}
|
package/dist/lib/chunk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/lib/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAS,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/lib/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAS,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM1C,qBAAa,KAAK;IACd,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,OAAO,CAAc;IAE7B;;;;OAIG;gBACS,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;IAW9B;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS;IASjD;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS;IAc1D;;;;OAIG;IACH,gBAAgB,IAAI,QAAQ,GAAG,SAAS;IA0BxC;;;OAGG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAU9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,aAAa;IAuCzC;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE;IAoC1C;;;;;;;OAOG;IACH,aAAa,IAAI,MAAM,GAAG,SAAS;IASnC;;OAEG;IACH,QAAQ,IAAI,GAAG;IAIf;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,CAAC;IAoB/B;;;;;;OAMG;IACH,gBAAgB,IAAI,QAAQ,GAAG,SAAS;IAUxC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IA2BpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,WAAW;IAcnB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CAcnB"}
|
package/dist/lib/chunk.js
CHANGED
|
@@ -111,7 +111,7 @@ export class Chunk {
|
|
|
111
111
|
}
|
|
112
112
|
const index = blockData.chunkCoordinatesToIndex([
|
|
113
113
|
xChunk,
|
|
114
|
-
coords[1] % 16,
|
|
114
|
+
((coords[1] % 16) + 16) % 16, // Handle negative Y coordinates
|
|
115
115
|
zChunk,
|
|
116
116
|
]);
|
|
117
117
|
const name = blockData.getBlockByIndex(index);
|
|
@@ -287,18 +287,20 @@ export class Chunk {
|
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
289
289
|
/**
|
|
290
|
-
* Returns the Y coordinate of a section, which goes from
|
|
290
|
+
* Returns the Y coordinate of a section, which goes from -4 to 19. If you
|
|
291
|
+
* want the world coordinate, pass true to get -64 to 304. The maximum supported
|
|
292
|
+
* range is -128 to 127 (chunk coordinates) or -2048 to 2032 (world coordinates).
|
|
291
293
|
*/
|
|
292
294
|
sectionY(section, useWorldCoordinate = false) {
|
|
293
|
-
|
|
295
|
+
let ySection = section.findChild('Y')?.data || 0;
|
|
296
|
+
// If the high bit is on, it's negative because this byte is a signed short.
|
|
297
|
+
if (ySection >= 128) {
|
|
298
|
+
ySection -= 256;
|
|
299
|
+
}
|
|
294
300
|
if (!useWorldCoordinate) {
|
|
295
301
|
return ySection;
|
|
296
302
|
}
|
|
297
|
-
|
|
298
|
-
if (yWorld >= 4032) {
|
|
299
|
-
yWorld -= 4096;
|
|
300
|
-
}
|
|
301
|
-
return yWorld;
|
|
303
|
+
return ySection * 16;
|
|
302
304
|
}
|
|
303
305
|
}
|
|
304
306
|
//# sourceMappingURL=chunk.js.map
|
package/dist/lib/chunk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.js","sourceRoot":"","sources":["../../src/lib/chunk.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A Chunk is a 16 x 383 x 16 portion of a Minecraft world. It's stored as NBT\n * data in sections of 16 blocks in the Y axis. The Y axis range is from -64 to\n * 320.\n *\n * This class helps manipulate the chunk data.\n */\n\nimport { Block, BlockInstance } from '../block/block';\nimport { BlockData } from './block-data';\nimport { Coords2d, Coords3d } from '../types/coords';\nimport { NbtBase } from '../nbt/nbt-base';\nimport { NbtCompound } from '../nbt/nbt-compound';\nimport { NbtInt } from '../nbt/nbt-int';\nimport { NbtIntArray } from '../nbt/nbt-int-array';\nimport { NbtList } from '../nbt/nbt-list';\nimport { NbtLong } from '../nbt/nbt-long';\nimport { NbtLongArray } from '../nbt/nbt-long-array';\nimport { NbtString } from '../nbt/nbt-string';\nimport { NbtTagType } from '../nbt/nbt-tag-type';\n\nexport class Chunk {\n private dataVersion: number;\n private parsedSections = new Map<NbtCompound, BlockData>();\n private rootNbt: NbtCompound;\n\n /**\n * Constructs a new chunk object from a given NBT tag.\n *\n * @param root the NBT tag containing the chunk's data\n */\n constructor(root: NbtBase<any>) {\n if (!this.isValidChunkRoot(root)) {\n throw new Error('Invalid chunk root tag');\n }\n\n this.rootNbt = root;\n\n // 1.2.1 does not have this tag.\n this.dataVersion = root.findChild<NbtInt>('DataVersion')?.data ?? 0;\n }\n\n /**\n * Gets the block entity list tag.\n */\n blockEntities(): NbtList<NbtCompound> | undefined {\n return (\n // 1.18+\n this.rootNbt.findChild<NbtList<NbtCompound>>('block_entities') ||\n // up to 1.17\n this.rootNbt.findChild<NbtList<NbtCompound>>('Level/TileEntities')\n );\n }\n\n /**\n * Gets a block's entity data\n */\n blockEntityData(coords: Coords3d): NbtCompound | undefined {\n return this.blockEntities()?.data.find((tag: NbtCompound) => {\n const x = tag.findChild<NbtInt>('x');\n const y = tag.findChild<NbtInt>('y');\n const z = tag.findChild<NbtInt>('z');\n\n return (\n x?.data === coords[0] &&\n y?.data === coords[1] &&\n z?.data === coords[2]\n );\n });\n }\n\n /**\n * Gets the chunk's location in chunk coordinates.\n *\n * Returns a tuple of the chunk's X and Z coordinates.\n */\n chunkCoordinates(): Coords2d | undefined {\n const x =\n // 1.18+ region chunks\n this.rootNbt.findChild<NbtInt>('xPos') ||\n // up to 1.17 region chunks\n this.rootNbt.findChild<NbtInt>('Level/xPos');\n const z =\n // 1.18+ region chunks\n this.rootNbt.findChild<NbtInt>('zPos') ||\n // up to 1.17 region chunks\n this.rootNbt.findChild<NbtInt>('Level/zPos');\n\n if (typeof x?.data === 'number' && typeof z?.data === 'number') {\n return [x.data, z.data];\n }\n\n // Check for entity chunks\n const position = this.rootNbt.findChild<NbtIntArray>('Position');\n\n if (position && position.data.length === 2) {\n return [position.data[0], position.data[1]];\n }\n\n return;\n }\n\n /**\n * Returns a unique id for this chunk. It's just the chunk's X and Z\n * coordinates in number of chunks from the world's origin.\n */\n chunkKey(): string | undefined {\n const coords = this.chunkCoordinates();\n\n if (!coords) {\n return;\n }\n\n return `${coords[0]},${coords[1]}`;\n }\n\n /**\n * Returns an instance of a block at a given location using world\n * coordinates.\n */\n getBlock(coords: Coords3d): BlockInstance {\n const sectionY = Math.floor(coords[1] / 16);\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n throw new Error('Invalid chunk - no sections found');\n }\n\n const section = sectionsTag.data.find(\n (section) => this.sectionY(section) === sectionY\n );\n\n if (!section) {\n throw new Error('Block not found in any sections');\n }\n\n const blockData = this.parseSection(section);\n const [xWorld, zWorld] = this.worldCoordinates() || [0, 0];\n const xChunk = coords[0] - xWorld;\n const zChunk = coords[2] - zWorld;\n\n if (xChunk < 0 || xChunk > 15) {\n throw new Error('X coordinate out of bounds');\n }\n\n if (zChunk < 0 || zChunk > 15) {\n throw new Error('Z coordinate out of bounds');\n }\n\n const index = blockData.chunkCoordinatesToIndex([\n xChunk,\n coords[1] % 16,\n zChunk,\n ]);\n const name = blockData.getBlockByIndex(index);\n\n return Block.create(name, coords, this.blockEntityData(coords));\n }\n\n /**\n * Finds all blocks by a given name. Provides [X, Y, Z] real-world coordinates.\n */\n findBlocksByName(name: string): Coords3d[] {\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n return [];\n }\n\n return sectionsTag.data.flatMap((section) => {\n const yWorld = this.sectionY(section, true);\n const [xWorld, zWorld] = this.worldCoordinates() || [0, 0];\n const palette = this.sectionPalette(section);\n\n if (palette === undefined) {\n return [];\n }\n\n // // If it's not in the palette, we can skip processing.\n if (!this.paletteNameList(palette).includes(name)) {\n return [];\n }\n\n const blockData = this.parseSection(section);\n\n return blockData.findBlocksByName(name).map((index): Coords3d => {\n const chunkCoordinates =\n blockData.indexToChunkCoordinates(index);\n\n return [\n xWorld + chunkCoordinates[0],\n yWorld + chunkCoordinates[1],\n zWorld + chunkCoordinates[2],\n ];\n });\n });\n }\n\n /**\n * See how long the chunk has been inhabited. This number increases by 1\n * for each game tick, which is 20 times per second when a player is\n * nearby. It can also advance slowly when players are farther away.\n *\n * On newly created chunks, this value does not match what is expected. Use\n * this with caution.\n */\n inhabitedTime(): bigint | undefined {\n return (\n // 1.18+\n this.rootNbt.findChild<NbtLong>('InhabitedTime')?.data ||\n // up to 1.17\n this.rootNbt.findChild<NbtLong>('Level/InhabitedTime')?.data\n );\n }\n\n /**\n * Converts the chunk data to a JSON object.\n */\n toObject(): any {\n return this.rootNbt.toObject();\n }\n\n /**\n * Returns a list of unique block names in the chunk as a Set.\n */\n uniqueBlockNames(): Set<string> {\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n return new Set();\n }\n\n const names = sectionsTag.data.flatMap((section) => {\n const palette = this.sectionPalette(section);\n\n if (!palette) {\n return [];\n }\n\n return this.paletteNameList(palette);\n });\n\n return new Set(names);\n }\n\n /**\n * Gets the chunk's location in real-world coordinates.\n *\n * Returns a tuple of the starting block's world X and Z coordinates. The\n * chunk contains the range from X to X+15 (going East), Y to Y+15 (going\n * up), and Z to Z+15 (going South).\n */\n worldCoordinates(): Coords2d | undefined {\n const result = this.chunkCoordinates();\n\n if (!result) {\n return;\n }\n\n return [result[0] * 16, result[1] * 16];\n }\n\n /**\n * Checks if the given NBT tag is a valid chunk root tag.\n * @param tag the tag to check.\n */\n private isValidChunkRoot(nbt: NbtBase<any>): nbt is NbtCompound {\n return nbt.isCompound('');\n }\n\n /**\n * Checks if the given NBT tag is a valid chunk section tag, containing a list of chunk sections.\n */\n private isValidChunkSection(\n nbt: NbtBase<any>\n ): nbt is NbtList<NbtCompound> {\n if (!nbt.isList(NbtTagType.COMPOUND)) {\n return false;\n }\n\n // Java uses \"sections\", unsure what uses \"Sections\"\n if (nbt.name.toLowerCase() === 'sections') {\n return true;\n }\n\n return false;\n }\n\n /**\n * Returns a list of names within a palette tag.\n */\n private paletteNameList(palette: NbtBase<any>): string[] {\n if (!palette.isList(NbtTagType.COMPOUND)) {\n return [];\n }\n\n return (palette as NbtList<NbtCompound>).data.map((tag) => {\n const name = tag.findChild<NbtString>('Name');\n\n return name?.data ?? '';\n });\n }\n\n /**\n * Parses a section tag into BlockData.\n *\n * Uses a cached version if available;\n */\n private parseSection(section: NbtCompound): BlockData {\n if (this.parsedSections.has(section)) {\n return this.parsedSections.get(section)!;\n }\n\n const palette = this.sectionPalette(section);\n\n if (!palette) {\n throw new Error('Invalid chunk section - no palette found');\n }\n\n const blockStates = this.sectionBlockStates(section);\n\n if (!blockStates) {\n throw new Error('Invalid chunk section - no block states found');\n }\n\n const blockData = BlockData.fromPaletteBlockStates(\n this.dataVersion,\n palette,\n blockStates\n );\n this.parsedSections.set(section, blockData);\n\n return blockData;\n }\n\n /**\n * Finds the BlockStates tag in a section.\n */\n private sectionBlockStates(section: NbtCompound): NbtLongArray | undefined {\n return (\n // 1.18+\n section.findChild<NbtLongArray>('block_states/data') ||\n // up to 1.17\n section.findChild<NbtLongArray>('BlockStates')\n );\n }\n\n /**\n * Finds the block palette in a section.\n */\n private sectionPalette(\n section: NbtCompound\n ): NbtList<NbtCompound> | undefined {\n return (\n // 1.18+\n section.findChild<NbtList<NbtCompound>>('block_states/palette') ||\n // up to 1.17\n section.findChild<NbtList<NbtCompound>>('Palette')\n );\n }\n\n /**\n * Returns all sections\n */\n private sectionsTag(): NbtList<NbtCompound> | undefined {\n const section =\n // 1.18+\n this.rootNbt.findChild<NbtList<NbtCompound>>('sections') ||\n // up to 1.17\n this.rootNbt.findChild<NbtList<NbtCompound>>('Level/Sections');\n\n if (section && this.isValidChunkSection(section)) {\n return section;\n }\n\n return;\n }\n\n /**\n * Returns the Y coordinate of a section, which goes from 0 to 256. If you want the world coordinate, pass true to get -128 to 4031.\n */\n private sectionY(section: NbtCompound, useWorldCoordinate = false): number {\n const ySection = section.findChild<NbtInt>('Y')?.data || 0;\n\n if (!useWorldCoordinate) {\n return ySection;\n }\n\n let yWorld = ySection * 16;\n\n if (yWorld >= 4032) {\n yWorld -= 4096;\n }\n\n return yWorld;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chunk.js","sourceRoot":"","sources":["../../src/lib/chunk.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A Chunk is a 16 x 383 x 16 portion of a Minecraft world. It's stored as NBT\n * data in sections of 16 blocks in the Y axis. The Y axis range is from -64 to\n * 320.\n *\n * This class helps manipulate the chunk data.\n */\n\nimport { Block, BlockInstance } from '../block/block';\nimport { BlockData } from './block-data';\nimport { Coords2d, Coords3d } from '../types/coords';\nimport { NbtBase } from '../nbt/nbt-base';\nimport { NbtByte } from '../nbt/nbt-byte';\nimport { NbtCompound } from '../nbt/nbt-compound';\nimport { NbtInt } from '../nbt/nbt-int';\nimport { NbtIntArray } from '../nbt/nbt-int-array';\nimport { NbtList } from '../nbt/nbt-list';\nimport { NbtLong } from '../nbt/nbt-long';\nimport { NbtLongArray } from '../nbt/nbt-long-array';\nimport { NbtString } from '../nbt/nbt-string';\nimport { NbtTagType } from '../nbt/nbt-tag-type';\n\nexport class Chunk {\n private dataVersion: number;\n private parsedSections = new Map<NbtCompound, BlockData>();\n private rootNbt: NbtCompound;\n\n /**\n * Constructs a new chunk object from a given NBT tag.\n *\n * @param root the NBT tag containing the chunk's data\n */\n constructor(root: NbtBase<any>) {\n if (!this.isValidChunkRoot(root)) {\n throw new Error('Invalid chunk root tag');\n }\n\n this.rootNbt = root;\n\n // 1.2.1 does not have this tag.\n this.dataVersion = root.findChild<NbtInt>('DataVersion')?.data ?? 0;\n }\n\n /**\n * Gets the block entity list tag.\n */\n blockEntities(): NbtList<NbtCompound> | undefined {\n return (\n // 1.18+\n this.rootNbt.findChild<NbtList<NbtCompound>>('block_entities') ||\n // up to 1.17\n this.rootNbt.findChild<NbtList<NbtCompound>>('Level/TileEntities')\n );\n }\n\n /**\n * Gets a block's entity data\n */\n blockEntityData(coords: Coords3d): NbtCompound | undefined {\n return this.blockEntities()?.data.find((tag: NbtCompound) => {\n const x = tag.findChild<NbtInt>('x');\n const y = tag.findChild<NbtInt>('y');\n const z = tag.findChild<NbtInt>('z');\n\n return (\n x?.data === coords[0] &&\n y?.data === coords[1] &&\n z?.data === coords[2]\n );\n });\n }\n\n /**\n * Gets the chunk's location in chunk coordinates.\n *\n * Returns a tuple of the chunk's X and Z coordinates.\n */\n chunkCoordinates(): Coords2d | undefined {\n const x =\n // 1.18+ region chunks\n this.rootNbt.findChild<NbtInt>('xPos') ||\n // up to 1.17 region chunks\n this.rootNbt.findChild<NbtInt>('Level/xPos');\n const z =\n // 1.18+ region chunks\n this.rootNbt.findChild<NbtInt>('zPos') ||\n // up to 1.17 region chunks\n this.rootNbt.findChild<NbtInt>('Level/zPos');\n\n if (typeof x?.data === 'number' && typeof z?.data === 'number') {\n return [x.data, z.data];\n }\n\n // Check for entity chunks\n const position = this.rootNbt.findChild<NbtIntArray>('Position');\n\n if (position && position.data.length === 2) {\n return [position.data[0], position.data[1]];\n }\n\n return;\n }\n\n /**\n * Returns a unique id for this chunk. It's just the chunk's X and Z\n * coordinates in number of chunks from the world's origin.\n */\n chunkKey(): string | undefined {\n const coords = this.chunkCoordinates();\n\n if (!coords) {\n return;\n }\n\n return `${coords[0]},${coords[1]}`;\n }\n\n /**\n * Returns an instance of a block at a given location using world\n * coordinates.\n */\n getBlock(coords: Coords3d): BlockInstance {\n const sectionY = Math.floor(coords[1] / 16);\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n throw new Error('Invalid chunk - no sections found');\n }\n\n const section = sectionsTag.data.find(\n (section) => this.sectionY(section) === sectionY\n );\n\n if (!section) {\n throw new Error('Block not found in any sections');\n }\n\n const blockData = this.parseSection(section);\n const [xWorld, zWorld] = this.worldCoordinates() || [0, 0];\n const xChunk = coords[0] - xWorld;\n const zChunk = coords[2] - zWorld;\n\n if (xChunk < 0 || xChunk > 15) {\n throw new Error('X coordinate out of bounds');\n }\n\n if (zChunk < 0 || zChunk > 15) {\n throw new Error('Z coordinate out of bounds');\n }\n\n const index = blockData.chunkCoordinatesToIndex([\n xChunk,\n ((coords[1] % 16) + 16) % 16, // Handle negative Y coordinates\n zChunk,\n ]);\n const name = blockData.getBlockByIndex(index);\n\n return Block.create(name, coords, this.blockEntityData(coords));\n }\n\n /**\n * Finds all blocks by a given name. Provides [X, Y, Z] real-world coordinates.\n */\n findBlocksByName(name: string): Coords3d[] {\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n return [];\n }\n\n return sectionsTag.data.flatMap((section) => {\n const yWorld = this.sectionY(section, true);\n const [xWorld, zWorld] = this.worldCoordinates() || [0, 0];\n const palette = this.sectionPalette(section);\n\n if (palette === undefined) {\n return [];\n }\n\n // // If it's not in the palette, we can skip processing.\n if (!this.paletteNameList(palette).includes(name)) {\n return [];\n }\n\n const blockData = this.parseSection(section);\n\n return blockData.findBlocksByName(name).map((index): Coords3d => {\n const chunkCoordinates =\n blockData.indexToChunkCoordinates(index);\n\n return [\n xWorld + chunkCoordinates[0],\n yWorld + chunkCoordinates[1],\n zWorld + chunkCoordinates[2],\n ];\n });\n });\n }\n\n /**\n * See how long the chunk has been inhabited. This number increases by 1\n * for each game tick, which is 20 times per second when a player is\n * nearby. It can also advance slowly when players are farther away.\n *\n * On newly created chunks, this value does not match what is expected. Use\n * this with caution.\n */\n inhabitedTime(): bigint | undefined {\n return (\n // 1.18+\n this.rootNbt.findChild<NbtLong>('InhabitedTime')?.data ||\n // up to 1.17\n this.rootNbt.findChild<NbtLong>('Level/InhabitedTime')?.data\n );\n }\n\n /**\n * Converts the chunk data to a JSON object.\n */\n toObject(): any {\n return this.rootNbt.toObject();\n }\n\n /**\n * Returns a list of unique block names in the chunk as a Set.\n */\n uniqueBlockNames(): Set<string> {\n const sectionsTag = this.sectionsTag();\n\n if (!sectionsTag) {\n return new Set();\n }\n\n const names = sectionsTag.data.flatMap((section) => {\n const palette = this.sectionPalette(section);\n\n if (!palette) {\n return [];\n }\n\n return this.paletteNameList(palette);\n });\n\n return new Set(names);\n }\n\n /**\n * Gets the chunk's location in real-world coordinates.\n *\n * Returns a tuple of the starting block's world X and Z coordinates. The\n * chunk contains the range from X to X+15 (going East), Y to Y+15 (going\n * up), and Z to Z+15 (going South).\n */\n worldCoordinates(): Coords2d | undefined {\n const result = this.chunkCoordinates();\n\n if (!result) {\n return;\n }\n\n return [result[0] * 16, result[1] * 16];\n }\n\n /**\n * Checks if the given NBT tag is a valid chunk root tag.\n * @param tag the tag to check.\n */\n private isValidChunkRoot(nbt: NbtBase<any>): nbt is NbtCompound {\n return nbt.isCompound('');\n }\n\n /**\n * Checks if the given NBT tag is a valid chunk section tag, containing a list of chunk sections.\n */\n private isValidChunkSection(\n nbt: NbtBase<any>\n ): nbt is NbtList<NbtCompound> {\n if (!nbt.isList(NbtTagType.COMPOUND)) {\n return false;\n }\n\n // Java uses \"sections\", unsure what uses \"Sections\"\n if (nbt.name.toLowerCase() === 'sections') {\n return true;\n }\n\n return false;\n }\n\n /**\n * Returns a list of names within a palette tag.\n */\n private paletteNameList(palette: NbtBase<any>): string[] {\n if (!palette.isList(NbtTagType.COMPOUND)) {\n return [];\n }\n\n return (palette as NbtList<NbtCompound>).data.map((tag) => {\n const name = tag.findChild<NbtString>('Name');\n\n return name?.data ?? '';\n });\n }\n\n /**\n * Parses a section tag into BlockData.\n *\n * Uses a cached version if available;\n */\n private parseSection(section: NbtCompound): BlockData {\n if (this.parsedSections.has(section)) {\n return this.parsedSections.get(section)!;\n }\n\n const palette = this.sectionPalette(section);\n\n if (!palette) {\n throw new Error('Invalid chunk section - no palette found');\n }\n\n const blockStates = this.sectionBlockStates(section);\n\n if (!blockStates) {\n throw new Error('Invalid chunk section - no block states found');\n }\n\n const blockData = BlockData.fromPaletteBlockStates(\n this.dataVersion,\n palette,\n blockStates\n );\n this.parsedSections.set(section, blockData);\n\n return blockData;\n }\n\n /**\n * Finds the BlockStates tag in a section.\n */\n private sectionBlockStates(section: NbtCompound): NbtLongArray | undefined {\n return (\n // 1.18+\n section.findChild<NbtLongArray>('block_states/data') ||\n // up to 1.17\n section.findChild<NbtLongArray>('BlockStates')\n );\n }\n\n /**\n * Finds the block palette in a section.\n */\n private sectionPalette(\n section: NbtCompound\n ): NbtList<NbtCompound> | undefined {\n return (\n // 1.18+\n section.findChild<NbtList<NbtCompound>>('block_states/palette') ||\n // up to 1.17\n section.findChild<NbtList<NbtCompound>>('Palette')\n );\n }\n\n /**\n * Returns all sections\n */\n private sectionsTag(): NbtList<NbtCompound> | undefined {\n const section =\n // 1.18+\n this.rootNbt.findChild<NbtList<NbtCompound>>('sections') ||\n // up to 1.17\n this.rootNbt.findChild<NbtList<NbtCompound>>('Level/Sections');\n\n if (section && this.isValidChunkSection(section)) {\n return section;\n }\n\n return;\n }\n\n /**\n * Returns the Y coordinate of a section, which goes from -4 to 19. If you\n * want the world coordinate, pass true to get -64 to 304. The maximum supported\n * range is -128 to 127 (chunk coordinates) or -2048 to 2032 (world coordinates).\n */\n private sectionY(section: NbtCompound, useWorldCoordinate = false): number {\n let ySection = section.findChild<NbtByte>('Y')?.data || 0;\n\n // If the high bit is on, it's negative because this byte is a signed short.\n if (ySection >= 128) {\n ySection -= 256;\n }\n\n if (!useWorldCoordinate) {\n return ySection;\n }\n\n return ySection * 16;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mca-json",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Convert Minecraft MCA (Anvil files) and NBT into JSON and back, or modify directly in memory. Works on region files and player data.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mca-chunks": "dist/bin/mca-chunks.js",
|
|
@@ -139,7 +139,7 @@ function processChunk(chunk: Chunk): SignInfo[] {
|
|
|
139
139
|
|
|
140
140
|
for (const blockName of blockNames) {
|
|
141
141
|
if (blockName.match(/^minecraft:.+_sign$/)) {
|
|
142
|
-
debugLog(`
|
|
142
|
+
debugLog(`Chunk lists sign name: ${blockName}`);
|
|
143
143
|
|
|
144
144
|
const listOfBlockCoordinates = chunk.findBlocksByName(blockName);
|
|
145
145
|
|
package/src/lib/chunk.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { Block, BlockInstance } from '../block/block';
|
|
|
10
10
|
import { BlockData } from './block-data';
|
|
11
11
|
import { Coords2d, Coords3d } from '../types/coords';
|
|
12
12
|
import { NbtBase } from '../nbt/nbt-base';
|
|
13
|
+
import { NbtByte } from '../nbt/nbt-byte';
|
|
13
14
|
import { NbtCompound } from '../nbt/nbt-compound';
|
|
14
15
|
import { NbtInt } from '../nbt/nbt-int';
|
|
15
16
|
import { NbtIntArray } from '../nbt/nbt-int-array';
|
|
@@ -149,7 +150,7 @@ export class Chunk {
|
|
|
149
150
|
|
|
150
151
|
const index = blockData.chunkCoordinatesToIndex([
|
|
151
152
|
xChunk,
|
|
152
|
-
coords[1] % 16,
|
|
153
|
+
((coords[1] % 16) + 16) % 16, // Handle negative Y coordinates
|
|
153
154
|
zChunk,
|
|
154
155
|
]);
|
|
155
156
|
const name = blockData.getBlockByIndex(index);
|
|
@@ -377,21 +378,22 @@ export class Chunk {
|
|
|
377
378
|
}
|
|
378
379
|
|
|
379
380
|
/**
|
|
380
|
-
* Returns the Y coordinate of a section, which goes from
|
|
381
|
+
* Returns the Y coordinate of a section, which goes from -4 to 19. If you
|
|
382
|
+
* want the world coordinate, pass true to get -64 to 304. The maximum supported
|
|
383
|
+
* range is -128 to 127 (chunk coordinates) or -2048 to 2032 (world coordinates).
|
|
381
384
|
*/
|
|
382
385
|
private sectionY(section: NbtCompound, useWorldCoordinate = false): number {
|
|
383
|
-
|
|
386
|
+
let ySection = section.findChild<NbtByte>('Y')?.data || 0;
|
|
384
387
|
|
|
385
|
-
|
|
386
|
-
|
|
388
|
+
// If the high bit is on, it's negative because this byte is a signed short.
|
|
389
|
+
if (ySection >= 128) {
|
|
390
|
+
ySection -= 256;
|
|
387
391
|
}
|
|
388
392
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
if (yWorld >= 4032) {
|
|
392
|
-
yWorld -= 4096;
|
|
393
|
+
if (!useWorldCoordinate) {
|
|
394
|
+
return ySection;
|
|
393
395
|
}
|
|
394
396
|
|
|
395
|
-
return
|
|
397
|
+
return ySection * 16;
|
|
396
398
|
}
|
|
397
399
|
}
|